{ "info": { "author": "Meeshkan Dev Team", "author_email": "dev@meeshkan.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Framework :: Pytest", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: Software Development :: Testing", "Topic :: Software Development :: Testing :: Mocking" ], "description": "\n# [Unmock](https://www.unmock.io/) (Python SDK)\n[![CircleCI](https://circleci.com/gh/unmock/unmock-python.svg?style=shield)](https://circleci.com/gh/unmock/unmock-python) \n[![codecov](https://codecov.io/gh/unmock/unmock-python/branch/dev/graph/badge.svg)](https://codecov.io/gh/unmock/unmock-python)\n[![PyPI version](https://badge.fury.io/py/unmock.svg)](https://badge.fury.io/py/unmock)\n\nPublic API mocking for Python.\n\nUnmock can be used to test modules that perform requests to third-party\nAPIs like Hubspot, SendGrid, Behance, and hundreds of other public APIs.\n\nUnmock can also be used to mock these APIs in a development environment,\ni.e. an express server on a local machine or in a staging environment.\n\nThe Unmock Python package offers intuitive, hassle-free SDK to the\nUnmock service with minimal setup steps.\n\nThe ultimate goal of unmock is to provide a semantically and\nfunctionally adequate mock of the internet.\n\nUnmock also provides access via other languages, all with similar\ninterface. We have [unmock-js](https://github.com/unmock/unmock-js)\nalready publicly available, and we are working on .Net, PHP and Java.\nWe're open to more requests - just [let us know](mailto:contact@unmock.io)!\n\n**Table of Contents**\n\n\n\n- [Unmock](#unmock)\n - [How does it work?](#how-does-it-work)\n - [Install](#install)\n - [Usage](#usage)\n - [Tests](#tests)\n - [Development](#development)\n - [unmock.io](#unmockio)\n - [Scoping](#scoping)\n - [Saving mocks](#saving-mocks)\n - [Ignoring aspects of a mock](#ignoring-aspects-of-a-mock)\n - [Adding a signature](#adding-a-signature)\n - [Whitelisting API](#whitelisting-api)\n - [unmock.io tokens](#unmockio-tokens)\n - [Contributing](#contributing)\n - [License](#license)\n\n\n\n## How does it work?\n\nUnmock works by overriding Python's low-level `HTTPConnection`'s and\n`HTTPRequest`'s functions, thereby capturing calls\nmade by popular packages such as `requests` and `urllib3`.\n\nUnmock works out of the box for most APIs that it mocks and does not\nrequire any additional configuration. For APIs that it does not mock\nyet, or to tweak return values from the unmock service, you can consult\nthe URLs printed to the command line by unmock.\n\nWe intend to offer Python2.7 support quite soon, along with other common\nlibraries such as `aiohttp`, `pycurl`, etc. \n\n## Install\n\n```sh\n$ pip install unmock\n```\n\n## Usage\n\n### Tests\n\nIn your unit tests, you can invoke unmock in several ways:\n\n1. If you're using pytest for your tests, you can either use the unmock\nfixture (you don't even need to import unmock!) -\n\n```python\nimport pytest\nimport requests\n\ndef test_behance(unmock_local):\n response = requests.get(\"https://www.behance.net/v2/projects/5456?api_key=u_n_m_o_c_k_200\")\n assert response.json().get(\"project\").get(\"id\") == 5456\n```\n\n... or you may want to use unmock for all your tests, in which case you\ncan simply use the `--unmock` flag for pytest:\n```bash\npytest tests --unmock\n```\n\n2. You can control use unmock in a scoped manner using context managers:\n```\n# do stuff\nwith unmock.patch():\n response = requests.get(\"https://www.example.com/\")\n# do stuff with mocked response\nreal_response = requests.get(\"https://www.example.com/\") # won't be mocked\n\n# You can also access the returned object to modify certain runtime behaviour:\nwith unmock.patch() as opts:\n # can modify certain behaviour aspects via `opts` object now too\n response = requests.get(\"https://www.example.com/\")\n``` \n\n3. You can have fine grained control over unmock using the `init` and\n`reset` methods, and modify the `UnmockOptions` object during runtime:\n```python\nimport unmock\n\n# do stuff\nopts = unmock.init()\nres1 = requests.get(\"https://www.example.com\") # will be mocked\nopts.save = True\nres2 = requests.get(\"https://www.example.com\") # will be mocked and response will be saved\nunmock.reset()\nres3 = requests.get(\"https://www.example.com\") # will not be mocked\n```\n\n\nUnmock will then either serve JIT semantically functionally correct\nmocks from its database or an empty JSON object for unmocked APIs that\ncan be filled in by the user. The address of these editable objects is\nprinted to the command line during tests.\n\n### Development\n\nAfter you create your flask, django, or own server, call\n\n\n```python\nunmock_options = unmock.init()\nunmock_options.ignore(\"story\")\n\n# equivalent to calling:\nunmock.init(ignore=\"story\")\n```\n\nThis has the same effect as activating unmock in your tests.\nIt will intercept HTTP traffic and serve semantically and functionally\nadequate mocks of the APIs in the unmock catalogue.\nThe main difference is the result of `ignore(\"story\")` passed to unmock\noptions, which tells the service to ignore the order of mocked requests.\nAlways use this option when the order of mocked data does not matter,\ni.e. when you are in sandbox or development mode.\nFor users of the [unmock.io](https://www.unmock.io) service, this will\nhelp unmock better organize your mocks in its web dashboard.\n\n### unmock.io\n\nThe URLs printed to the command line are hosted by unmock.io. You can\nconsult the documentation about that service\n[here](https://www.unmock.io/docs).\n\n### Scoping\nAs a handy shortcut to initializing and reseting the capturing of API\ncalls, we also offer the use of context manager via `unmock.patch()`.\n`patch` accepts as parameters anything that `init` accepts.\n\n### Saving mocks\n\nAll mocks can be saved to a folder called `.unmock` in your user's home\ndirectory by adding a `save` field to the unmock options object like so:\n\n```python\nunmock_options = unmock.init(save=True)\n```\nYou can also specify a specific location to save the directory:\n```python\nunmock_options = unmock.init(save=True, path=\".\") # Saves in current path\n```\nUnmock refers to every mock by a unique hash. Individual mocks or groups\nof mocks can be saved by setting save to either a single hash or an\narray of hashes like so:\n\n```python\nunmock_options = unmock.init(save=[\"ahash\", \"anotherhash\", \"yetanotherhash\"])\n```\n\n### Ignoring aspects of a mock\n\nSometimes, you would like for two mocks of slightly API calls to be\ntreated as equivalent by unmock. For example, you may want all `GET`\ncalls to the same path with different headers to be served the same\nmock. To do this, use the `ignore` field of the unmock options object.\nYou can do this while initializing unmock or afterwards (as shown before\nwith ignoring `\"story\"`):\n\n```python\n# Option A:\nunmock_options = unmock.init()\nunmock_options.ignore(\"headers\", \"story\")\n# Option B:\nunmock.init(ignore=[\"headers\", \"story\"])\n```\n\nThe following fields may be ignored:\n\n* `headers`: the headers of the request\n* `hostname`: the hostname of the request\n* `method`: the method of the request (ie GET, POST, PUT, DELETE).\nNote that this is *case insensitive*!\n* `path`: the path of the request\n* `story`: the story of the request, meaning its order in a series of requests\n\nIgnore evaluates regular expressions, so you can also pass\n`\"headers|path\"` instead of `[\"headers\", \"path\"]`. Furthermore, to\nignore nested headers, pass a dictionary such as\n`{\"headers\": \"Authorization\" }`, or to match against the value of a\nheader, `{\"headers\": { Authorization: \"Bearer *\" }}`. When using the\nignore _method_ on the `UnmockOptions` object (returned from a call to `init`),\nyou may pass either a list (`*args`) or a dictionary (`**kwargs`).\n\n### Adding a signature\n\nSometimes, it is useful to sign a mock with a unique signature. This is\nuseful, for example, when AB testing code that should serve two\ndifferent mocks for the same endpoint in otherwise similar conditions.\nTo do this, use the `signature` field of the unmock options object:\n\n```python\nunmock_options = unmock.init()\nunmock_options.signature = \"signature-for-this-particular-test\"\n# Equivalent to\nunmock.init(signature=\"signature-for-this-particular-test\")\n```\n\n### Whitelisting API\n\nIf you do not want a particular API to be mocked, whitelist it.\n\n```python\nunmock_options = unmock.init()\nunmock_options.whitelist = [\"api.hubspot.com\", \"api.typeform.com\"]\n# Equivalent to:\nunmock.init(whitelist=[\"api.hubspot.com\", \"api.typeform.com\"])\n```\n\n### unmock.io tokens\n\nIf you are subscribed to the [unmock.io](https://www.unmock.io) service,\nyou can pass your unmock token directly to the unmock object.\n\n```\nunmock.init(token=\"my-token\")\n```\n\nAt a certain point this becomes a bit tedious, (even if very readable),\nat which point you will want to create a credentials file. See\n[unmock.io/docs](https://www.unmock.io/docs) for more information on\ncredential files.\nBehind the scenes, we automatically create a credentials file for you,\nfor caching purposes. With this, subsequent calls to `unmock.init()`\nwill read the token from the credential files. \n\n## Contributing\n\nThanks for wanting to contribute! We will soon have a contributing page\ndetaling how to contribute. Meanwhile, star this repository, open issues\nand ask for more features and support!\n\nPlease note that this project is released with a\n[Contributor Code of Conduct](CODE_OF_CONDUCT.md). By participating in\nthis project you agree to abide by its terms.\n\n## License\n\n[MIT](LICENSE)\n\nCopyright (c) 2018\u20132019 [Meeshkan](http://meeshkan.com) and other\n[contributors](https://github.com/unmock/unmock/graphs/contributors).\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://www.unmock.io/", "keywords": "", "license": "Apache 2.0", "maintainer": "", "maintainer_email": "", "name": "unmock", "package_url": "https://pypi.org/project/unmock/", "platform": "", "project_url": "https://pypi.org/project/unmock/", "project_urls": { "Homepage": "https://www.unmock.io/" }, "release_url": "https://pypi.org/project/unmock/0.1.2/", "requires_dist": [ "requests", "PyYAML", "six", "twine ; extra == 'dev'", "wheel ; extra == 'dev'", "pytest ; extra == 'dev'", "coverage ; extra == 'dev'" ], "requires_python": ">=2.7.0,!=3.0*,!=3.1*,!=3.2*,!=3.3*", "summary": "The Unmock Python clent", "version": "0.1.2" }, "last_serial": 5118570, "releases": { "0.0.0": [ { "comment_text": "", "digests": { "md5": "4c94f3c81ef1957ba7003ce722056ccf", "sha256": "170dfdce9bb352e09c43842ed2e843a082723373c2da9438cd52cb9cdd139f2d" }, "downloads": -1, "filename": "unmock-0.0.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "4c94f3c81ef1957ba7003ce722056ccf", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=3.6.0", "size": 1694, "upload_time": "2019-01-21T07:16:38", "url": "https://files.pythonhosted.org/packages/d6/ec/4d2134995e377387c6b3f20f81be288bb66f44d459a8902cc9ad7e95087e/unmock-0.0.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "96e838df3f89deee62456998165e3829", "sha256": "d12afc838f2b261f9aedcf94e3aaa1658452da4b55f89991183382f3d239fe0d" }, "downloads": -1, "filename": "unmock-0.0.0.tar.gz", "has_sig": false, "md5_digest": "96e838df3f89deee62456998165e3829", "packagetype": "sdist", "python_version": "source", "requires_python": ">=3.6.0", "size": 2232, "upload_time": "2019-01-21T07:16:40", "url": "https://files.pythonhosted.org/packages/89/b0/e926f382b5130280fd8bcfb99afe3e27aceff80ded7eed8af0acc5118499/unmock-0.0.0.tar.gz" } ], "0.1.0": [ { "comment_text": "", "digests": { "md5": "fc241350b1277983400f07d747473cbb", "sha256": "9f2248bdb1cbcefa13a2aca561eb01ff8951606ccf2a025e417de3b39719ad44" }, "downloads": -1, "filename": "unmock-0.1.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "fc241350b1277983400f07d747473cbb", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=2.7.0,!=3.0*,!=3.1*,!=3.2*,!=3.3*", "size": 20353, "upload_time": "2019-03-22T15:03:34", "url": "https://files.pythonhosted.org/packages/f2/6c/9040fabefe74abc59e95ec8d0a278e120d1577d2110cd8bb4b94c9d24071/unmock-0.1.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "dbddb0fdb9e99c7599931c99b508c928", "sha256": "83aa89c62049455a85229e38f004964654fd5433fc9dc0c69bd831adf6fcfa49" }, "downloads": -1, "filename": "unmock-0.1.0.tar.gz", "has_sig": false, "md5_digest": "dbddb0fdb9e99c7599931c99b508c928", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7.0,!=3.0*,!=3.1*,!=3.2*,!=3.3*", "size": 21611, "upload_time": "2019-03-22T15:03:36", "url": "https://files.pythonhosted.org/packages/ab/52/528091a4803d2fbf71bbcb48d1a1449d2ecab786d99e8710af9033f9b5d9/unmock-0.1.0.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "13f5a4243688a2f2d42ae6ad0bcfa379", "sha256": "294d950f47e029fa258ab705be2aee1f809124a391df3326deb43cc565e166b0" }, "downloads": -1, "filename": "unmock-0.1.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "13f5a4243688a2f2d42ae6ad0bcfa379", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=2.7.0,!=3.0*,!=3.1*,!=3.2*,!=3.3*", "size": 20370, "upload_time": "2019-04-08T16:28:03", "url": "https://files.pythonhosted.org/packages/5c/d2/fc83b0bf3cd98d0470538c8aa439a26634f026376933d01f70ceef8cd149/unmock-0.1.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "ef9fcc2eadfca3a0f140150430e47a9a", "sha256": "c6990d4276b72ac7bea61446c2ac5c1e9ebff4a0e47fb48e90b361325e6d8c32" }, "downloads": -1, "filename": "unmock-0.1.1.tar.gz", "has_sig": false, "md5_digest": "ef9fcc2eadfca3a0f140150430e47a9a", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7.0,!=3.0*,!=3.1*,!=3.2*,!=3.3*", "size": 17872, "upload_time": "2019-04-08T16:28:04", "url": "https://files.pythonhosted.org/packages/93/72/5d2cf6f03a9dcb1eeaa8f6e8f38e2a8e82acb758e5eb650ba6381ac1bdd2/unmock-0.1.1.tar.gz" } ], "0.1.2": [ { "comment_text": "", "digests": { "md5": "ddbc9b9802fedaa60a66af2d55ce6f80", "sha256": "976326c897e8df5eff792116aecfc3bd6e0f7a81d5d42beb84c7ce0917bf4ae5" }, "downloads": -1, "filename": "unmock-0.1.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "ddbc9b9802fedaa60a66af2d55ce6f80", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=2.7.0,!=3.0*,!=3.1*,!=3.2*,!=3.3*", "size": 20920, "upload_time": "2019-04-09T12:25:40", "url": "https://files.pythonhosted.org/packages/c6/e4/8163d153d5724ee85436981d5ed132d2eb86904437c56b640731337f7f67/unmock-0.1.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "0d2a4b3e5ae21fa0f4ac1bc54fdcaa76", "sha256": "4fa24aabb2e24760cfc6ac38c49e3c4d65cd264e4b335c1247ddb6c1953d49a2" }, "downloads": -1, "filename": "unmock-0.1.2.tar.gz", "has_sig": false, "md5_digest": "0d2a4b3e5ae21fa0f4ac1bc54fdcaa76", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7.0,!=3.0*,!=3.1*,!=3.2*,!=3.3*", "size": 21414, "upload_time": "2019-04-09T12:25:41", "url": "https://files.pythonhosted.org/packages/f9/53/ff8a1a623b71bce3c84a57b0fa3984789c393314795c239a6a2cbfe41e68/unmock-0.1.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "ddbc9b9802fedaa60a66af2d55ce6f80", "sha256": "976326c897e8df5eff792116aecfc3bd6e0f7a81d5d42beb84c7ce0917bf4ae5" }, "downloads": -1, "filename": "unmock-0.1.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "ddbc9b9802fedaa60a66af2d55ce6f80", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": ">=2.7.0,!=3.0*,!=3.1*,!=3.2*,!=3.3*", "size": 20920, "upload_time": "2019-04-09T12:25:40", "url": "https://files.pythonhosted.org/packages/c6/e4/8163d153d5724ee85436981d5ed132d2eb86904437c56b640731337f7f67/unmock-0.1.2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "0d2a4b3e5ae21fa0f4ac1bc54fdcaa76", "sha256": "4fa24aabb2e24760cfc6ac38c49e3c4d65cd264e4b335c1247ddb6c1953d49a2" }, "downloads": -1, "filename": "unmock-0.1.2.tar.gz", "has_sig": false, "md5_digest": "0d2a4b3e5ae21fa0f4ac1bc54fdcaa76", "packagetype": "sdist", "python_version": "source", "requires_python": ">=2.7.0,!=3.0*,!=3.1*,!=3.2*,!=3.3*", "size": 21414, "upload_time": "2019-04-09T12:25:41", "url": "https://files.pythonhosted.org/packages/f9/53/ff8a1a623b71bce3c84a57b0fa3984789c393314795c239a6a2cbfe41e68/unmock-0.1.2.tar.gz" } ] }