pax_global_header 0000666 0000000 0000000 00000000064 14601102147 0014506 g ustar 00root root 0000000 0000000 52 comment=1f55faa934ed821cdc0f29186d28ad4614493673 respx-0.21.1/ 0000775 0000000 0000000 00000000000 14601102147 0012730 5 ustar 00root root 0000000 0000000 respx-0.21.1/.github/ 0000775 0000000 0000000 00000000000 14601102147 0014270 5 ustar 00root root 0000000 0000000 respx-0.21.1/.github/workflows/ 0000775 0000000 0000000 00000000000 14601102147 0016325 5 ustar 00root root 0000000 0000000 respx-0.21.1/.github/workflows/check-docs.yml 0000664 0000000 0000000 00000000605 14601102147 0021054 0 ustar 00root root 0000000 0000000 name: check-docs on: pull_request: paths: - 'docs/**' - '.github/workflows/check-docs.yml' jobs: check-docs: name: Check Docs runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-python@v4 with: python-version: "3.10" - run: pip install nox - name: Run mypy run: nox -N -s docs respx-0.21.1/.github/workflows/lint.yml 0000664 0000000 0000000 00000000214 14601102147 0020013 0 ustar 00root root 0000000 0000000 name: lint on: pull_request: jobs: lint: name: Check Linting uses: less-action/reusables/.github/workflows/pre-commit.yaml@v8 respx-0.21.1/.github/workflows/publish-docs.yml 0000664 0000000 0000000 00000001306 14601102147 0021444 0 ustar 00root root 0000000 0000000 name: publish-docs on: push: branches: - master paths: - 'docs/**' - '.github/workflows/docs.yml' jobs: build: name: Build & Publish runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-python@v4 with: python-version: "3.10" - run: pip install nox - name: Build run: nox -N -s docs - name: Publish if: github.repository_owner == 'lundberg' run: | git config user.email ${{ secrets.GITHUB_EMAIL }} git remote set-url origin https://${{ secrets.GITHUB_USER }}:${{ secrets.GITHUB_PAGES_TOKEN }}@github.com/lundberg/respx.git ./.nox/docs/bin/mkdocs gh-deploy --force respx-0.21.1/.github/workflows/test.yml 0000664 0000000 0000000 00000002170 14601102147 0020027 0 ustar 00root root 0000000 0000000 name: test on: push: branches: - master paths-ignore: - 'docs/**' pull_request: paths-ignore: - 'docs/**' env: FORCE_COLOR: 1 jobs: test: name: Test Python ${{ matrix.python-version }} runs-on: ubuntu-latest strategy: max-parallel: 4 matrix: python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"] steps: - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - run: pip install nox - name: Test run: nox -N -s test-${{ matrix.python-version }} -- -v - name: Upload coverage report uses: codecov/codecov-action@v3 with: name: Python ${{ matrix.python-version }} files: ./coverage.xml fail_ci_if_error: true check-types: name: Check Typing runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-python@v4 with: python-version: "3.7" - run: pip install nox - name: Run mypy run: nox -N -s mypy respx-0.21.1/.gitignore 0000664 0000000 0000000 00000000373 14601102147 0014723 0 ustar 00root root 0000000 0000000 # Byte-compiled __pycache__/ *.py[cod] # Distribution / packaging .env/ env/ venv/ build/ dist/ site/ eggs/ *.egg-info/ # Unit test / coverage reports .nox/ .coverage .coverage.* .mypy_cache/ .pytest_cache/ coverage.xml # Editor config .idea .tags respx-0.21.1/.pre-commit-config.yaml 0000664 0000000 0000000 00000004441 14601102147 0017214 0 ustar 00root root 0000000 0000000 default_language_version: python: python3.11 repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.4.0 hooks: - id: check-added-large-files - id: check-case-conflict - id: check-merge-conflict - id: check-toml - id: end-of-file-fixer - id: trailing-whitespace - id: debug-statements - id: detect-private-key - repo: https://github.com/asottile/pyupgrade rev: v3.4.0 hooks: - id: pyupgrade args: - --py37-plus - --keep-runtime-typing - repo: https://github.com/pycqa/autoflake rev: v2.1.1 hooks: - id: autoflake args: - --in-place - --remove-all-unused-imports - --ignore-init-module-imports - repo: https://github.com/pycqa/isort rev: 5.12.0 hooks: - id: isort - repo: https://github.com/psf/black rev: 23.3.0 hooks: - id: black - repo: https://github.com/PyCQA/flake8 rev: 6.0.0 hooks: - id: flake8 additional_dependencies: - flake8-bugbear - flake8-comprehensions - flake8-tidy-imports - flake8-print - flake8-pytest-style - flake8-datetimez - repo: https://github.com/sirosen/check-jsonschema rev: 0.23.0 hooks: - id: check-github-workflows - repo: https://github.com/asottile/yesqa rev: v1.4.0 hooks: - id: yesqa additional_dependencies: - flake8-bugbear - flake8-comprehensions - flake8-tidy-imports - flake8-print - flake8-pytest-style - flake8-datetimez - repo: https://github.com/pre-commit/mirrors-prettier rev: "v3.0.0-alpha.9-for-vscode" hooks: - id: prettier alias: format-markdown types: [markdown] args: - --parser=markdown - --print-width=88 - --prose-wrap=always - repo: https://github.com/mgedmin/check-manifest rev: "0.49" hooks: - id: check-manifest args: ["--no-build-isolation"] exclude: | (?x)( /( \.eggs | \.git | \.hg | \.mypy_cache | \.pytest_cache | \.nox | \.tox | \.venv | _build | buck-out | build | dist )/ | docs | LICENSE\.md ) respx-0.21.1/CHANGELOG.md 0000664 0000000 0000000 00000034330 14601102147 0014544 0 ustar 00root root 0000000 0000000 # Changelog All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [0.21.1] - 2024-03-27 ### Fixed - Fix `files` pattern not handling `str` and `BytesIO`, thanks @pierremonico for input (#260) ### Added - Add support for `None` values in `data` pattern, thanks @slingshotvfx for issue (#259) ## [0.21.0] - 2024-03-19 ### Fixed - Fix matching request data when files are provided, thanks @ziima for input (#252) ### Added - Add support for data\_\_contains lookup (#252) - Add `files` pattern to support matching on uploads, thanks @ziima for input (#253) - Add `SetCookie` utility for easier mocking of response cookie headers (#254) ### Changed - Enhance documentation on iterable side effects (#255) - Enhance documentation on named routes and add tip about a catch-all route (#257) ## [0.20.2] - 2023-07-21 ### Fixed - Better assertion output for `assert_all_called`, thanks @sileht (#224) - Support for quoted path pattern matching, thanks @alexdrydew for input (#240) ### Added - Enable content\_\_contains pattern, thanks @rjprins (#236) - Added initial `CONTRIBUTING.md`, thanks @morenoh149 (#238) ### Changed - Docs about retrieving mocked calls, thanks @tomhamiltonstubber (#230) - Docs about `Router.assert_all_called()`, thanks @BeyondEvil for input (#241) ## [0.20.1] - 2022-11-18 ### Fixed - Support HTTPX 0.23.1, thanks @g-as for input (#223) ### Added - Officially support Python 3.11 (#223) - Run pre-commit hooks in CI workflow (#219) ### Changed - Bump autoflake, thanks @antonagestam (#220) ### Removed - Drop support for Python 3.6 (#218) ## [0.20.0] - 2022-09-16 ### Changed - Type `Router.__getitem__` to not return optional routes, thanks @flaeppe (#216) - Change `Call.response` to raise instead of returning optional response (#217) - Change `CallList.last` to raise instead of return optional call (#217) - Type `M()` to not return optional pattern, by introducing a `Noop` pattern (#217) - Type `Route.pattern` to not be optional (#217) ### Fixed - Correct type hints for side effects (#217) ### Added - Runs `mypy` on both tests and respx (#217) - Added nox test session for python 3.11 (#217) - Added `Call.has_response` helper, now that `.response` raises (#217) ## [0.19.3] - 2022-09-14 ### Fixed - Fix typing for Route modulos arg - Respect patterns with empty value when using equal lookup (#206) - Use pytest asyncio auto mode (#212) - Fix mock decorator to work together with pytest fixtures (#213) - Wrap pytest function correctly, i.e. don't hide real function name (#213) ### Changed - Enable mypy strict_optional (#201) ## [0.19.2] - 2022-02-03 ### Fixed - Better cleanup before building egg, thanks @nebularazer (#198) ## [0.19.1] - 2022-01-10 ### Fixed - Allow first path segments containing colons, thanks @hannseman. (#192) - Fix license classifier, thanks @shadchin (#195) - Fix typos, thanks @kianmeng (#194) ## [0.19.0] - 2021-11-15 ### Fixed - Support HTTPX 0.21.0. (#189) - Use Session.notify when chaining nox sessions, thanks @flaeppe. (#188) - Add overloads to `MockRouter.__call__`, thanks @flaeppe. (#187) - Enhance AND pattern evaluation to fail fast. (#185) - Fix CallList assertion error message. (#178) ### Changed - Prevent method and url as lookups in HTTP method helpers, thanks @flaeppe. (#183) - Fail pattern match when JSON path not found. (#184) ## [0.18.2] - 2021-10-22 ### Fixed - Include extensions when instantiating request in HTTPCoreMocker. (#176) ## [0.18.1] - 2021-10-20 ### Fixed - Respect ordered param values. (#172) ### Changed - Raise custom error types for assertion checks. (#174) ## [0.18.0] - 2021-10-14 ### Fixed - Downgrade `HTTPX` requirement to 0.20.0. (#170) ### Added - Add support for matching param with _ANY_ value. (#167) ## [0.18.0b0] - 2021-09-15 ### Changed - Deprecate RESPX MockTransport in favour of HTTPX MockTransport. (#152) ### Fixed - Support `HTTPX` 1.0.0b0. (#164) - Allow tuples as params to align with httpx, thanks @shelbylsmith. (#151) - Fix xfail marked tests. (#153) - Only publish docs for upstream repo, thanks @hugovk. (#161) ### Added - Add optional route arg to side effects. (#158) ## [0.17.1] - 2021-06-05 ### Added - Implement support for async side effects in router. (#147) - Support mocking responses using asgi/wsgi apps. (#146) - Added pytest fixture and configuration marker. (#150) ### Fixed - Typo in import from examples.md, thanks @shelbylsmith. (#148) - Fix pass-through test case. (#149) ## [0.17.0] - 2021-04-27 ### Changed - Require `HTTPX` 0.18.0 and implement the new transport API. (PR #142) - Removed ASGI and WSGI transports from httpcore patch list. (PR #131) - Don't pre-read mocked async response streams. (PR #136) ### Fixed - Fixed syntax highlighting in docs, thanks @florimondmanca. (PR #134) - Type check `route.return_value`, thanks @tzing. (PR #133) - Fixed a typo in the docs, thanks @lewoudar. (PR #139) ### Added - Added support for adding/removing patch targets. (PR #131) - Added test session for python 3.10. (PR #140) - Added RESPX Mock Swallowtail to README. (PR #128) ## [0.16.3] - 2020-12-14 ### Fixed - Fixed decorator `respx_mock` kwarg, mistreated as a `pytest` fixture. (PR #117) - Fixed `JSON` pattern sometimes causing a `JSONDecodeError`. (PR #124) ### Added - Snapshot and rollback of routes' pattern and name. (PR #120) - Internally extracted a `RouteList` from `Router`. (PR #120) - Auto registration of `Mocker` implementations and their `using` name. (PR #121) - Added `HTTPXMocker`, optionally patching `HTTPX`. (PR #122) ### Changed - Protected a routes' pattern to be modified. (PR #120) ## [0.16.2] - 2020-11-26 ### Added - Easier support for using HTTPX MockTransport. (PR #118) - Support mixed case for `method__in` and `scheme__in` pattern lookups. (PR #113) ### Fixed - Handle missing path in URL pattern (PR #113) ### Changed - Refactored internal mocking vs `MockTransport`. (PR #112) ### Removed - Dropped raw request support when parsing patterns (PR #113) ## [0.16.1] - 2020-11-16 ### Added - Extended `url` pattern with support for `HTTPX` proxy url format. (PR #110) - Extended `host` pattern with support for regex lookup. (PR #110) - Added `respx.request(...)`. (PR #111) ### Changed - Deprecated old `MockTransport` in favour of `respx.mock(...)`. (PR #109) - Wrapping actual `MockTransport` in `MockRouter`, instead of extending. (PR #109) - Extracted a `HTTPXMock`, for transport patching, from `MockRouter`. (PR #109) ## [0.16.0] - 2020-11-13 One year since first release, yay! ### Removed - Dropped all deprecated APIs and models, see `0.15.0` Changed section. (PR #105) ### Added - Added support for content, data and json patterns. (PR #106) - Automatic pattern registration when subclassing Pattern. (PR #108) ### Fixed - Multiple snapshots to support nested mock routers. (PR #107) ## [0.15.1] - 2020-11-10 ### Added - Snapshot routes and mocks when starting router, rollback when stopping. (PR #102) - Added support for base_url combined with pattern lookups. (PR #103) - Added support for patterns/lookups to the HTTP method helpers. (PR #104) ### Fixed - Fix to not clear routes added outside mock context when stopping router. (PR #102) ## [0.15.0] - 2020-11-09 ### Added - Added `respx.route(...)` with enhanced request pattern matching. (PR #96) - Added support for AND/OR when request pattern matching. (PR #96) - Added support for adding responses to a route using % operator. (PR #96) - Added support for both `httpx.Response` and `MockResponse`. (PR #96) - Enhanced Route (RequestPattern) with `.respond(...)` response details. (PR #96) - Enhanced Route (RequestPattern) with `.pass_through()`. (PR #96) - Add support for using route as side effect decorator. (PR #98) - Add `headers` and `cookies` patterns. (PR #99) - Add `contains` and `in` lookups. (PR #99) - Introduced Route `.mock(...)` in favour of callbacks. (PR #101) - Introduced Route `.return_value` and `.side_effect` setters. (PR #101) ### Changed - Deprecated mixing of request pattern and response details in all API's. (PR #96) - Deprecated passing http method as arg in `respx.add` in favour of `method=`. (PR #96) - Deprecated `alias=...` in favour of `name=...` when adding routes. (PR #96) - Deprecated `respx.aliases` in favour of `respx.routes`. (PR #96) - Deprecated `RequestPattern` in favour of `Route`. (PR #96) - Deprecated `ResponseTemplate` in favour of `MockResponse`. (PR #96) - Deprecated `pass_through=` in HTTP method API's (PR #96) - Deprecated `response` arg in side effects (callbacks). (PR #97) - Stacked responses are now recorded on same route calls. (PR #96) - Pass-through routes no longer capture real response in call stats. (PR #97) - Stacked responses no longer keeps and repeats last response. (PR #101) ### Removed - Removed support for regex `base_url`. (PR #96) - Dropped support for `async` side effects (callbacks). (PR #97) - Dropped support for mixing side effect (callback) and response details. (PR #97) ## [0.14.0] - 2020-10-15 ### Added - Added `text`, `html` and `json` content shorthands to ResponseTemplate. (PR #82) - Added `text`, `html` and `json` content shorthands to high level API. (PR #93) - Added support to set `http_version` for a mocked response. (PR #82) - Added support for mocking by lowercase http methods, thanks @lbillinghamtn. (PR #80) - Added query `params` to align with HTTPX API, thanks @jocke-l. (PR #81) - Easier API to get request/response from call stats, thanks @SlavaSkvortsov. (PR #85) - Enhanced test to verify better content encoding by HTTPX. (PR #78) - Added Python 3.9 to supported versions and test suite, thanks @jairhenrique. (PR #89) ### Changed - `ResponseTemplate.content` as proper getter, i.e. no resolve/encode to bytes. (PR #82) - Enhanced headers by using HTTPX Response when encoding raw responses. (PR #82) - Deprecated `respx.stats` in favour of `respx.calls`, thanks @SlavaSkvortsov. (PR #92) ### Fixed - Recorded requests in call stats are pre-read like the responses. (PR #86) - Postponed request decoding for enhanced performance. (PR #91) - Lazy call history for enhanced performance, thanks @SlavaSkvortsov. (PR #92) ### Removed - Removed auto setting the `Content-Type: text/plain` header. (PR #82) ## [0.13.0] - 2020-09-30 ### Fixed - Fixed support for `HTTPX` 0.15. (PR #77) ### Added - Added global `respx.pop` api, thanks @paulineribeyre. (PR #72) ### Removed - Dropped deprecated `HTTPXMock` in favour of `MockTransport`. - Dropped deprecated `respx.request` in favour of `respx.add`. - Removed `HTTPX` max version requirement in setup.py. ## [0.12.1] - 2020-08-21 ### Fixed - Fixed non-iterable pass-through responses. (PR #68) ## [0.12.0] - 2020-08-17 ### Changed - Dropped no longer needed `asynctest` dependency, in favour of built-in mock. (PR #69) ## [0.11.3] - 2020-08-13 ### Fixed - Fixed support for `HTTPX` 0.14.0. (PR #45) ## [0.11.2] - 2020-06-25 ### Added - Added support for pop'ing a request pattern by alias, thanks @radeklat. (PR #60) ## [0.11.1] - 2020-06-01 ### Fixed - Fixed mocking `HTTPX` clients instantiated with proxies. (PR #58) - Fixed matching URL patterns with missing path. (PR #59) ## [0.11.0] - 2020-05-29 ### Fixed - Fixed support for `HTTPX` 0.13. (PR #57) ### Added - Added support for mocking out `HTTP Core`. - Added support for using mock transports with `HTTPX` clients without patching. - Include LICENSE.md in source distribution, thanks @synapticarbors. ### Changed - Renamed passed mock to decorated functions from `httpx_mock` to `respx_mock`. - Renamed `HTTPXMock` to `MockTransport`, but kept a deprecated `HTTPXMock` subclass. - Deprecated `respx.request()` in favour of `respx.add()`. ## [0.10.1] - 2020-03-11 ### Fixed - Fixed support for `HTTPX` 0.12.0. (PR #45) ## [0.10.0] - 2020-01-30 ### Changed - Refactored high level and internal api for better editor autocompletion. (PR #44) ## [0.9.0] - 2020-01-22 ### Fixed - Fixed usage of nested or parallel mock instances. (PR #39) ## [0.8.3] - 2020-01-10 ### Fixed - Fixed support for `HTTPX` 0.11.0 sync api. (PR #38) ## [0.8.2] - 2020-01-07 ### Fixed - Renamed refactored httpx internals. (PR #37) ## [0.8.1] - 2019-12-09 ### Added - Added support for configuring patterns `base_url`. (PR #34) - Added manifest and `py.typed` files. ### Fixed - Fixed support for `HTTPX` 0.9.3 refactorizations. (PR #35) ## [0.8] - 2019-11-27 ### Added - Added documentation built with `mkdocs`. (PR #30) ### Changed - Dropped sync support and now requires `HTTPX` version 0.8+. (PR #32) - Renamed `respx.mock` module to `respx.api`. (PR #29) - Refactored tests- and checks-runner to `nox`. (PR #31) ## [0.7.4] - 2019-11-24 ### Added - Allowing assertions to be configured through decorator and context manager. (PR #28) ## [0.7.3] - 2019-11-21 ### Added - Allows `mock` decorator to be used as sync or async context manager. (PR #27) ## [0.7.2] - 2019-11-21 ### Added - Added `stats` to high level API and patterns, along with `call_count`. (PR #25) ### Fixed - Allowing headers to be modified within a pattern match callback. (PR #26) ## [0.7.1] - 2019-11-20 ### Fixed - Fixed responses in call stats when using synchronous `HTTPX` client. (PR #23) ## [0.7] - 2019-11-19 ### Added - Added support for `pass_through` patterns. (PR #20) - Added `assert_all_mocked` feature and setting. (PR #21) ### Changed - Requires all `HTTPX` requests to be mocked. ## [0.6] - 2019-11-18 ### Changed - Renamed `activate` decorator to `mock`. (PR #15) ## [0.5] - 2019-11-18 ### Added - Added `assert_all_called` feature and setting. (PR #14) ### Changed - Clears call stats when exiting decorator. ## [0.4] - 2019-11-16 ### Changed - Renamed python package to `respx`. (PR #12) - Renamed `add()` to `request()` and added HTTP method shorthands. (PR #13) ## [0.3.1] - 2019-11-16 ### Changed - Renamed PyPI package to `respx`. ## [0.3] - 2019-11-15 ### Added - Exposes `responsex` high level API along with a `activate` decorator. (PR #5) - Added support for custom pattern match callback function. (PR #7) - Added support for repeated patterns. (PR #8) ## [0.2] - 2019-11-14 ### Added - Added support for any `HTTPX` concurrency backend. ## [0.1] - 2019-11-13 ### Added - Initial POC. respx-0.21.1/CONTRIBUTING.md 0000664 0000000 0000000 00000001047 14601102147 0015163 0 ustar 00root root 0000000 0000000 # Contributing to RESPX As an open source project, RESPX welcomes contributions of many forms. Examples of contributions include: - Code patches - Documentation improvements - Bug reports and patch reviews ## Running Tests Tests reside in the `tests/` directory. You can run tests with the [Task](https://taskfile.dev/installation/) tool from the root of the project. - `task test` ## Linting Any contributions should pass the linters setup in this project. - `task lint` Linters will also be run through github CI on your PR automatically. respx-0.21.1/LICENSE.md 0000664 0000000 0000000 00000002767 14601102147 0014350 0 ustar 00root root 0000000 0000000 BSD 3-Clause License Copyright (c) 2019, 5 Monkeys Agency AB All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. respx-0.21.1/MANIFEST.in 0000664 0000000 0000000 00000000370 14601102147 0014466 0 ustar 00root root 0000000 0000000 recursive-exclude .github * recursive-exclude docs * recursive-exclude tests * exclude *.yaml exclude *.xml exclude flake.* exclude noxfile.py exclude CONTRIBUTING.md include README.md include CHANGELOG.md include LICENSE.md include respx/py.typed respx-0.21.1/README.md 0000664 0000000 0000000 00000005521 14601102147 0014212 0 ustar 00root root 0000000 0000000
RESPX - Mock HTTPX with awesome request patterns and response side effects.
--- [](https://github.com/lundberg/respx/actions/workflows/test.yml) [](https://codecov.io/gh/lundberg/respx) [](https://pypi.org/project/respx/) [](https://pypi.org/project/respx/) ## Documentation Full documentation is available at [lundberg.github.io/respx](https://lundberg.github.io/respx/) ## QuickStart RESPX is a simple, _yet powerful_, utility for mocking out the [HTTPX](https://www.python-httpx.org/), _and [HTTP Core](https://www.encode.io/httpcore/)_, libraries. Start by [patching](https://lundberg.github.io/respx/guide/#mock-httpx) `HTTPX`, using `respx.mock`, then add request [routes](https://lundberg.github.io/respx/guide/#routing-requests) to mock [responses](https://lundberg.github.io/respx/guide/#mocking-responses). ```python import httpx import respx from httpx import Response @respx.mock def test_example(): my_route = respx.get("https://example.org/").mock(return_value=Response(204)) response = httpx.get("https://example.org/") assert my_route.called assert response.status_code == 204 ``` > Read the [User Guide](https://lundberg.github.io/respx/guide/) for a complete > walk-through. ### pytest + httpx For a neater `pytest` experience, RESPX includes a `respx_mock` _fixture_ for easy `HTTPX` mocking, along with an optional `respx` _marker_ to fine-tune the mock [settings](https://lundberg.github.io/respx/api/#configuration). ```python import httpx import pytest def test_default(respx_mock): respx_mock.get("https://foo.bar/").mock(return_value=httpx.Response(204)) response = httpx.get("https://foo.bar/") assert response.status_code == 204 @pytest.mark.respx(base_url="https://foo.bar") def test_with_marker(respx_mock): respx_mock.get("/baz/").mock(return_value=httpx.Response(204)) response = httpx.get("https://foo.bar/baz/") assert response.status_code == 204 ``` ## Installation Install with pip: ```console $ pip install respx ``` Requires Python 3.7+ and HTTPX 0.21+. See [Changelog](https://github.com/lundberg/respx/blob/master/CHANGELOG.md) for older HTTPX compatibility. respx-0.21.1/Taskfile.yaml 0000664 0000000 0000000 00000002641 14601102147 0015361 0 ustar 00root root 0000000 0000000 version: "3" tasks: default: cmds: [task: all] all: desc: Run test suite, mypy & linting label: all -- [nox options] silent: true deps: [tools] cmds: - .venv/bin/nox -k "test + mypy" {{.CLI_ARGS | default "-R"}} - task: lint test: desc: Run test suite against latest python label: test -- [pytest options] silent: true deps: [tools] cmds: [".venv/bin/nox -R -s test-3.11 -- {{.CLI_ARGS}}"] mypy: desc: Statically type check python files silent: true deps: [tools] cmds: [.venv/bin/nox -R -s mypy] lint: desc: Lint project files silent: true deps: [tools] cmds: [.venv/bin/pre-commit run --all-files] docs: desc: Start docs server, in watch mode silent: true deps: [tools] cmds: [.venv/bin/nox -R -s docs -- serve] reset: desc: Delete environment and artifacts silent: true cmds: - echo Deleting environment and artifacts ... - rm -rf \ .venv .nox .mypy_cache .pytest_cache respx.egg-info .coverage coverage.xml tools: internal: true silent: true run: once deps: [venv] cmds: [.venv/bin/python -m pip install nox pre-commit] status: - test -f .venv/bin/nox - test -f .venv/bin/pre-commit venv: internal: true silent: true run: once cmds: [python -m venv --copies --upgrade-deps .venv > /dev/null] status: [test -d .venv] respx-0.21.1/docs/ 0000775 0000000 0000000 00000000000 14601102147 0013660 5 ustar 00root root 0000000 0000000 respx-0.21.1/docs/api.md 0000664 0000000 0000000 00000031670 14601102147 0014762 0 ustar 00root root 0000000 0000000 # API Reference ## Router ### Configuration Creates a mock `Router` instance, ready to be used as decorator/manager for activation. >respx.mock(assert_all_mocked=True, *assert_all_called=True, base_url=None*)
>
> **Parameters:**
>
> * **assert_all_mocked** - *(optional) bool - default: `True`*
> Asserts that all sent and captured `HTTPX` requests are routed and mocked.
> If disabled, all non-routed requests will be auto mocked with status code `200`.
> * **assert_all_called** - *(optional) bool - default: `True`*
> Asserts that all added and mocked routes were called when exiting context.
> * **base_url** - *(optional) str*
> Base URL to match, on top of each route specific pattern *and/or* side effect.
>
> **Returns:** `Router`
!!! note "NOTE"
When using the *default* mock router `respx.mock`, *without settings*, `assert_all_called` is **disabled**.
!!! tip "pytest"
Use the `@pytest.mark.respx(...)` marker with these parameters to configure the `respx_mock` [pytest fixture](examples.md#built-in-marker).
### .route()
Adds a new, *optionally named*, `Route` with given [patterns](#patterns) *and/or* [lookups](#lookups) combined, using the [AND](#and) operator.
> respx.route(*\*patterns, name=None, \*\*lookups*)
>
> **Parameters:**
>
> * **patterns** - *(optional) args*
> One or more [pattern](#patterns) objects.
> * **lookups** - *(optional) kwargs*
> One or more [pattern](#patterns) keyword [lookups](#lookups), given as `respx.get(*url, name=None, \*\*lookups*)
> respx.options(...)
> respx.head(...)
> respx.post(...)
> respx.put(...)
> respx.patch(...)
> respx.delete(...)
>
> **Parameters:**
>
> * **url** - *(optional) str | compiled regex | tuple (httpcore) | httpx.URL*
> Request URL to match, *full or partial*, turned into a [URL](#url) pattern.
> * **name** - *(optional) str*
> Name this route.
> * **lookups** - *(optional) kwargs*
> One or more [pattern](#patterns) keyword [lookups](#lookups), given as `respx.request(*method, url, name=None, \*\*lookups*)
>
> **Parameters:**
>
> * **method** - *str*
> Request HTTP method to match.
> * **url** - *(optional) str | compiled regex | tuple (httpcore) | httpx.URL*
> Request URL to match, *full or partial*, turned into a [URL](#url) pattern.
> * **name** - *(optional) str*
> Name this route.
> * **lookups** - *(optional) kwargs*
> One or more [pattern](#patterns) keyword [lookups](#lookups), given as `route.mock(*return_value=None, side_effect=None*)
>
> **Parameters:**
>
> * **return_value** - *(optional) [Response](#response)*
> HTTPX Response to mock and return.
> * **side_effect** - *(optional) Callable | Exception | Iterable of httpx.Response/Exception*
> [Side effect](guide.md#mock-with-a-side-effect) to call, exception to raise or stacked responses to respond with in order.
>
> **Returns:** `Route`
### .return_value
Setter for the `HTTPX` [Response](#response) to return.
> route.**return_value** = Response(204)
### .side_effect
Setter for the [side effect](guide.md#mock-with-a-side-effect) to trigger.
> route.**side_effect** = ...
>
> See [route.mock()](#mock) for valid side effect types.
### .respond()
Shortcut for creating and mocking a `HTTPX` [Response](#response).
> route.respond(*status_code=200, headers=None, cookies=None, content=None, text=None, html=None, json=None, stream=None, content_type=None*)
>
> **Parameters:**
>
> * **status_code** - *(optional) int - default: `200`*
> Response status code to mock.
> * **headers** - *(optional) dict | Sequence[tuple[str, str]]*
> Response headers to mock.
> * **cookies** - *(optional) dict | Sequence[tuple[str, str]] | Sequence[SetCookie]*
> Response cookies to mock as `Set-Cookie` headers. See [SetCookie](#setcookie).
> * **content** - *(optional) bytes | str | Iterable[bytes]*
> Response raw content to mock.
> * **text** - *(optional) str*
> Response *text* content to mock, with automatic content-type header added.
> * **html** - *(optional) str*
> Response *HTML* content to mock, with automatic content-type header added.
> * **json** - *(optional) str | list | dict*
> Response *JSON* content to mock, with automatic content-type header added.
> * **stream** - *(optional) Iterable[bytes]*
> Response *stream* to mock.
> * **content_type** - *(optional) str*
> Response `Content-Type` header to mock.
>
> **Returns:** `Route`
### .pass_through()
> route.pass_through(*value=True*)
>
> **Parameters:**
>
> * **value** - *(optional) bool - default: `True`*
> Mark route to pass through, sending matched requests to real server, *e.g. don't mock*.
>
> **Returns:** `Route`
---
## Response
!!! note "NOTE"
This is a partial reference for how to the instantiate the **HTTPX** `Response`class, e.g. *not* a RESPX class.
> httpx.Response(*status_code, headers=None, content=None, text=None, html=None, json=None, stream=None*)
>
> **Parameters:**
>
> * **status_code** - *int*
> HTTP status code.
> * **headers** - *(optional) dict | httpx.Headers*
> HTTP headers.
> * **content** - *(optional) bytes | str | Iterable[bytes]*
> Raw content.
> * **text** - *(optional) str*
> Text content, with automatic content-type header added.
> * **html** - *(optional) str*
> HTML content, with automatic content-type header added.
> * **json** - *(optional) str | list | dict*
> JSON content, with automatic content-type header added.
> * **stream** - *(optional) Iterable[bytes]*
> Content *stream*.
!!! tip "Cookies"
Use [respx.SetCookie(...)](#setcookie) to produce `Set-Cookie` headers.
---
## SetCookie
A utility to render a `("Set-Cookie", respx.SetCookie(*name, value, path=None, domain=None, expires=None, max_age=None, http_only=False, same_site=None, secure=False, partitioned=False*)
``` python
import respx
respx.post("https://example.org/").mock(
return_value=httpx.Response(200, headers=[SetCookie("foo", "bar")])
)
```
---
## Patterns
### M()
Creates a reusable pattern, combining multiple arguments using the [AND](#and) operator.
> M(*\*patterns, \*\*lookups*)
>
> **Parameters:**
>
> * **patterns** - *(optional) args*
> One or more [pattern](#patterns) objects.
> * **lookups** - *(optional) kwargs*
> One or more [pattern](#patterns) keyword [lookups](#lookups), given as `[eq](#eq)
as default lookup.
> Key: `method`
> Lookups: [eq](#eq), [in](#in)
``` python
respx.route(method="GET")
respx.route(method__in=["PUT", "PATCH"])
```
### Scheme
Matches request *URL scheme*, using [eq](#eq)
as default lookup.
> Key: `scheme`
> Lookups: [eq](#eq), [in](#in)
``` python
respx.route(scheme="https")
respx.route(scheme__in=["http", "https"])
```
### Host
Matches request *URL host*, using [eq](#eq)
as default lookup.
> Key: `host`
> Lookups: [eq](#eq), [regex](#regex), [in](#in)
``` python
respx.route(host="example.org")
respx.route(host__regex=r"example\.(org|com)")
respx.route(host__in=["example.org", "example.com"])
```
### Port
Matches request *URL port*, using [eq](#eq)
as default lookup.
> Key: `port`
> Lookups: [eq](#eq), [in](#in)
``` python
respx.route(port=8000)
respx.route(port__in=[2375, 2376])
```
### Path
Matches request *URL path*, using [eq](#eq)
as default lookup.
> Key: `path`
> Lookups: [eq](#eq), [regex](#regex), [startswith](#startswith), [in](#in)
``` python
respx.route(path="/api/foobar/")
respx.route(path__regex=r"^/api/(?P[contains](#contains)
as default lookup.
> Key: `params`
> Lookups: [contains](#contains), [eq](#eq)
``` python
respx.route(params={"foo": "bar", "ham": "spam"})
respx.route(params=[("foo", "bar"), ("ham", "spam")])
respx.route(params=(("foo", "bar"), ("ham", "spam")))
respx.route(params="foo=bar&ham=spam")
```
!!! note "NOTE"
A request querystring with multiple parameters of the same name is treated as an ordered list when matching.
!!! tip "ANY value"
Use `mock.ANY` as value to only match on parameter presence, e.g. `respx.route(params={"foo": ANY})`.
### URL
Matches request *URL*.
When no *lookup* is given, `url` works as a *shorthand* pattern, combining individual request *URL* parts, using the [AND](#and) operator.
> Key: `url`
> Lookups: [eq](#eq), [regex](#regex), [startswith](#startswith)
``` python
respx.get("//example.org/foo/") # == M(host="example.org", path="/foo/")
respx.get(url__eq="https://example.org:8080/foobar/?ham=spam")
respx.get(url__regex=r"https://example.org/(?P