{"id":13813742,"url":"https://github.com/h2non/pook","last_synced_at":"2025-05-14T19:10:04.333Z","repository":{"id":44719041,"uuid":"68802946","full_name":"h2non/pook","owner":"h2non","description":"HTTP traffic mocking and testing made easy in Python","archived":false,"fork":false,"pushed_at":"2024-12-23T04:00:59.000Z","size":440,"stargazers_count":353,"open_issues_count":11,"forks_count":39,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-04-13T13:38:24.674Z","etag":null,"topics":["assertion","expectations","http","http-mocking","mock","mocking","python","testing"],"latest_commit_sha":null,"homepage":"http://pook.rtfd.io","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/h2non.png","metadata":{"files":{"readme":"README.rst","changelog":"History.rst","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-09-21T09:44:39.000Z","updated_at":"2025-03-07T13:27:30.000Z","dependencies_parsed_at":"2024-01-01T00:39:34.723Z","dependency_job_id":"770f27e9-8b48-44ae-9ce6-31afc899479c","html_url":"https://github.com/h2non/pook","commit_stats":{"total_commits":301,"total_committers":21,"mean_commits":"14.333333333333334","dds":0.2790697674418605,"last_synced_commit":"5ead2a8d9bac9beb01de02fe6b02ba144965e07d"},"previous_names":[],"tags_count":41,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/h2non%2Fpook","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/h2non%2Fpook/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/h2non%2Fpook/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/h2non%2Fpook/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/h2non","download_url":"https://codeload.github.com/h2non/pook/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254209859,"owners_count":22032897,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["assertion","expectations","http","http-mocking","mock","mocking","python","testing"],"created_at":"2024-08-04T04:01:28.223Z","updated_at":"2025-05-14T19:10:01.928Z","avatar_url":"https://github.com/h2non.png","language":"Python","readme":"pook |PyPI| |Coverage Status| |Documentation Status| |Stability| |Quality| |Versions|\n=====================================================================================\n\nVersatile, expressive and hackable utility library for HTTP traffic mocking\nand expectations made easy in `Python`_. Heavily inspired by `gock`_.\n\nTo get started, read the `documentation`_, `how it works`_, `FAQ`_ or `examples`_.\n\nFeatures\n--------\n\n-  Simple, expressive and fluent API.\n-  Provides both Pythonic and chainable DSL API styles.\n-  Full-featured HTTP response definitions and expectations.\n-  Matches any HTTP protocol primitive (URL, method, query params, headers, body...).\n-  Full regular expressions capable mock expectations matching.\n-  Supports most popular HTTP clients via interceptor adapters.\n-  Configurable volatile, persistent or TTL limited mocks.\n-  Works with unittest and pytest.\n-  First-class JSON \u0026 XML support matching and responses.\n-  Supports JSON Schema body matching.\n-  Works in both runtime and testing environments.\n-  Can be used as decorator and/or via context managers.\n-  Supports real networking mode with optional traffic filtering.\n-  Map/filter mocks easily for generic or custom mock expectations.\n-  Custom user-defined mock matcher functions.\n-  Simulated raised error exceptions.\n-  Network delay simulation (only available for ``aiohttp``).\n-  Pluggable and hackable API.\n-  Customizable HTTP traffic mock interceptor engine.\n-  Supports third-party mocking engines, such as `mocket`_.\n-  Fits good for painless test doubles.\n-  Does not support WebSocket traffic mocking.\n-  Works with +3.9 (including PyPy).\n-  Dependency-less: just 3 small dependencies for JSONSchema, XML tree comparison, and URL parsing.\n\n\nSupported HTTP clients\n----------------------\n\n``pook`` can work with multiple mock engines, however it provides a\nbuilt-in one by default, which currently supports traffic mocking in\nthe following HTTP clients:\n\n-  ✔  `urllib3`_ v1+\n-  ✔  `requests`_ v2+\n-  ✔  `aiohttp`_ v3+\n-  ✔  `urllib`_ / `http.client`_\n-  ✔  `httpx`_\n\nMore HTTP clients can be supported progressively.\n\n**Note**: only recent HTTP client package versions were tested.\n\nInstallation\n------------\n\nUsing ``pip`` package manager (requires pip 1.8+):\n\n.. code:: bash\n\n    pip install --upgrade pook\n\nOr install the latest sources from GitHub:\n\n.. code:: bash\n\n    pip install -e git+git://github.com/h2non/pook.git#egg=pook\n\n\nGetting started\n---------------\n\nSee ReadTheDocs documentation:\n\n|Documentation Status|\n\n\nAPI\n---\n\nSee `annotated API reference`_ documention.\n\n\nExamples\n--------\n\nSee `examples`_ documentation for full featured code and use case examples.\n\nBasic mocking:\n\n.. code:: python\n\n    import pook\n    import requests\n\n    @pook.on\n    def test_my_api():\n        mock = pook.get('http://twitter.com/api/1/foobar', reply=404, response_json={'error': 'not found'})\n\n        resp = requests.get('http://twitter.com/api/1/foobar')\n        assert resp.status_code == 404\n        assert resp.json() == {\"error\": \"not found\"}\n        assert mock.calls == 1\n\nUsing the chainable API DSL:\n\n.. code:: python\n\n    import pook\n    import requests\n\n    @pook.on\n    def test_my_api():\n        mock = (pook.get('http://twitter.com/api/1/foobar')\n                  .reply(404)\n                  .json({'error': 'not found'}))\n\n        resp = requests.get('http://twitter.com/api/1/foobar')\n        assert resp.json() == {\"error\": \"not found\"}\n        assert mock.calls == 1\n\nUsing the decorator:\n\n.. code:: python\n\n    import pook\n    import requests\n\n    @pook.get('http://httpbin.org/status/500', reply=204)\n    @pook.get('http://httpbin.org/status/400', reply=200)\n    def fetch(url):\n        return requests.get(url)\n\n    res = fetch('http://httpbin.org/status/400')\n    print('#1 status:', res.status_code)\n\n    res = fetch('http://httpbin.org/status/500')\n    print('#2 status:', res.status_code)\n\n\nSimple ``unittest`` integration:\n\n.. code:: python\n\n    import pook\n    import unittest\n    import requests\n\n\n    class TestUnitTestEngine(unittest.TestCase):\n\n        @pook.on\n        def test_request(self):\n            pook.get('server.com/foo').reply(204)\n            res = requests.get('http://server.com/foo')\n            self.assertEqual(res.status_code, 204)\n\n        def test_request_with_context_manager(self):\n            with pook.use():\n                pook.get('server.com/bar', reply=204)\n                res = requests.get('http://server.com/bar')\n                self.assertEqual(res.status_code, 204)\n\n\nUsing the context manager for isolated HTTP traffic interception blocks:\n\n.. code:: python\n\n    import pook\n    import requests\n\n    # Enable HTTP traffic interceptor\n    with pook.use():\n        pook.get('http://httpbin.org/status/500', reply=204)\n\n        res = requests.get('http://httpbin.org/status/500')\n        print('#1 status:', res.status_code)\n\n    # Interception-free HTTP traffic\n    res = requests.get('http://httpbin.org/status/200')\n    print('#2 status:', res.status_code)\n\nExample using `mocket`_ Python library as underlying mock engine:\n\n.. code:: python\n\n    import pook\n    import requests\n    from mocket.plugins.pook_mock_engine import MocketEngine\n\n    # Use mocket library as underlying mock engine\n    pook.set_mock_engine(MocketEngine)\n\n    # Explicitly enable pook HTTP mocking (optional)\n    pook.on()\n\n    # Target server URL to mock out\n    url = 'http://twitter.com/api/1/foobar'\n\n    # Define your mock\n    mock = pook.get(url,\n                    reply=404, times=2,\n                    headers={'content-type': 'application/json'},\n                    response_json={'error': 'foo'})\n\n    # Run first HTTP request\n    requests.get(url)\n    assert mock.calls == 1\n\n    # Run second HTTP request\n    res = requests.get(url)\n    assert mock.calls == 2\n\n    # Assert response data\n    assert res.status_code == 404\n    assert res.json() == {'error': 'foo'}\n\n    # Explicitly disable pook (optional)\n    pook.off()\n\n\nExample using Hy language (Lisp dialect for Python):\n\n.. code:: hy\n\n    (import [pook])\n    (import [requests])\n\n    (defn request [url \u0026optional [status 404]]\n      (doto (.mock pook url) (.reply status))\n      (let [res (.get requests url)]\n        (. res status_code)))\n\n    (defn run []\n      (with [(.use pook)]\n        (print \"Status:\" (request \"http://server.com/foo\" :status 204))))\n\n    ;; Run test program\n    (defmain [\u0026args] (run))\n\n\nContributing\n------------\n\nSee `contributing \u003c./CONTRIBUTING.md\u003e`_ for how to contribute to Pook.\n\nLicense\n-------\n\nMIT - Tomas Aparicio\n\n.. _Go: https://golang.org\n.. _Python: http://python.org\n.. _gock: https://github.com/h2non/gock\n.. _annotated API reference: http://pook.readthedocs.io/en/latest/api.html\n.. _examples: http://pook.readthedocs.io/en/latest/examples.html\n.. _aiohttp: https://github.com/KeepSafe/aiohttp\n.. _httpx: https://www.python-httpx.org/\n.. _requests: http://docs.python-requests.org/en/master/\n.. _urllib3: https://github.com/shazow/urllib3\n.. _urllib: https://docs.python.org/3/library/urllib.html\n.. _http.client: https://docs.python.org/3/library/http.client.html\n.. _documentation: http://pook.readthedocs.io/en/latest/\n.. _FAQ: http://pook.readthedocs.io/en/latest/faq.html\n.. _how it works: http://pook.readthedocs.io/en/latest/how_it_works.html\n.. _mocket: https://github.com/mindflayer/python-mocket\n\n.. |PyPI| image:: https://img.shields.io/pypi/v/pook.svg?maxAge=2592000?style=flat-square\n   :target: https://pypi.python.org/pypi/pook\n.. |Coverage Status| image:: https://coveralls.io/repos/github/h2non/pook/badge.svg?branch=master\n   :target: https://coveralls.io/github/h2non/pook?branch=master\n.. |Documentation Status| image:: https://readthedocs.org/projects/pook/badge/?version=latest\n   :target: https://pook.readthedocs.io/en/latest/?badge=latest\n   :alt: Documentation Status\n.. |Quality| image:: https://codeclimate.com/github/h2non/pook/badges/gpa.svg\n   :target: https://codeclimate.com/github/h2non/pook\n   :alt: Code Climate\n.. |Stability| image:: https://img.shields.io/pypi/status/pook.svg\n   :target: https://pypi.python.org/pypi/pook\n   :alt: Stability\n.. |Versions| image:: https://img.shields.io/pypi/pyversions/pook.svg\n   :target: https://pypi.python.org/pypi/pook\n   :alt: Python Versions\n","funding_links":[],"categories":["Python"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fh2non%2Fpook","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fh2non%2Fpook","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fh2non%2Fpook/lists"}