aiointercept 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,53 @@
1
+ name: PR
2
+
3
+ on:
4
+ pull_request:
5
+
6
+ jobs:
7
+ lint:
8
+ runs-on: ubuntu-latest
9
+ steps:
10
+ - uses: actions/checkout@v4
11
+
12
+ - uses: actions/setup-python@v5
13
+ with:
14
+ python-version: "3.12"
15
+
16
+ - name: Install uv
17
+ uses: astral-sh/setup-uv@v5
18
+
19
+ - name: Install dependencies
20
+ run: uv sync --group dev
21
+
22
+ - name: Ruff
23
+ run: uv run ruff check .
24
+
25
+ - name: Mypy
26
+ run: uv run mypy aiointercept
27
+
28
+ test:
29
+ runs-on: ubuntu-latest
30
+ strategy:
31
+ fail-fast: false
32
+ matrix:
33
+ python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
34
+ aiohttp-version: ["3.13.3", "3.13.5"]
35
+ steps:
36
+ - uses: actions/checkout@v4
37
+
38
+ - uses: actions/setup-python@v5
39
+ with:
40
+ python-version: ${{ matrix.python-version }}
41
+ allow-prereleases: true
42
+
43
+ - name: Install uv
44
+ uses: astral-sh/setup-uv@v5
45
+
46
+ - name: Install dependencies
47
+ run: uv sync --group tests
48
+
49
+ - name: Pin aiohttp version
50
+ run: uv pip install aiohttp==${{ matrix.aiohttp-version }}
51
+
52
+ - name: Tests
53
+ run: uv run pytest tests/
@@ -0,0 +1,27 @@
1
+ name: "Publish"
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ # Publish on any tag starting with a `v`, e.g., v0.1.0
7
+ - v*
8
+
9
+ jobs:
10
+ run:
11
+ runs-on: ubuntu-latest
12
+ environment:
13
+ name: pypi
14
+ permissions:
15
+ id-token: write
16
+ contents: read
17
+ steps:
18
+ - name: Checkout
19
+ uses: actions/checkout@v6
20
+ - name: Install uv
21
+ uses: astral-sh/setup-uv@v7
22
+ - name: Install Python 3.13
23
+ run: uv python install 3.13
24
+ - name: Build
25
+ run: uv build
26
+ - name: Publish
27
+ run: uv publish
@@ -0,0 +1,3 @@
1
+ *.pyc
2
+ .vscode/settings.json
3
+ .claude/settings.local.json
@@ -0,0 +1,15 @@
1
+ repos:
2
+ - repo: https://github.com/astral-sh/ruff-pre-commit
3
+ rev: v0.11.6
4
+ hooks:
5
+ - id: ruff
6
+ args: [--fix]
7
+ - id: ruff-format
8
+
9
+ - repo: https://github.com/pre-commit/mirrors-mypy
10
+ rev: v1.15.0
11
+ hooks:
12
+ - id: mypy
13
+ additional_dependencies:
14
+ - aiohttp
15
+ - yarl
@@ -0,0 +1,70 @@
1
+ Metadata-Version: 2.4
2
+ Name: aiointercept
3
+ Version: 0.1.0
4
+ Author-email: Pablo Estevez <pablo22estevez@gmail.com>
5
+ Requires-Python: >=3.10
6
+ Requires-Dist: aiohttp<4.0.0,>=3.13.3
7
+ Requires-Dist: pytest-asyncio<2.0.0,>=1.3.0
8
+ Requires-Dist: yarl<2.0.0,>=1.23.0
9
+ Description-Content-Type: text/markdown
10
+
11
+ Proof of concept for an aioresponses-like library that uses real aiohttp server
12
+ related to this discussion: https://github.com/orgs/aio-libs/discussions/45
13
+
14
+ This is a proof of concept of how a linrary could expose aioresponses-like API
15
+ while using real aiohttp server under the hood. It works only with GET requests,
16
+ only compare the url, param and method, and only implements assert_called_with.
17
+
18
+ The breaking changes will be:
19
+ - The context manager will be async, as it will need to start the server
20
+ - the assert_called_* methods will not work with arbitrary kwargs, instead they will only work with specific args that the request was made with (e.g. url, method, headers, params, etc.)
21
+ - the fragments (after #) are not being passed on the request, so will not be compared
22
+ - on a connector exception, aiohttp could retry, so the number of request will not be the same
23
+ - pass timeout don't work
24
+ - you cant raise exceptions exception clienterror
25
+ - the decorathor need to decorate an async function
26
+ - as this mock DNS will not work to mock request to external IPs
27
+
28
+
29
+ Added a perf test to compare the performance of the POC with the original aioresponses implementation.
30
+
31
+ Results:
32
+
33
+ aioresponses (main) : 0.7223 seconds for 1000 iter (0.72 ms/iter)
34
+ aioresponses_2 (POC) : 0.8272 seconds for 1000 iter (0.83 ms/iter)
35
+
36
+ Probablly this overheard is tolerable, and could be optimized.
37
+ However, once we start adding more features, the performance will degrade.
38
+
39
+
40
+ Changing:
41
+
42
+ @pytest.fixture
43
+ def mock_aioresponse():
44
+ with aioresponses() as m:
45
+
46
+ to:
47
+
48
+ @pytest_asyncio.fixture
49
+ async def mock_aioresponse():
50
+ async with aioresponses() as m:
51
+ yield m
52
+
53
+ is passing the tests on:
54
+
55
+ https://github.com/cortega26/PDF-Text-Analyzer
56
+ https://github.com/mxr/reconciler-for-ynab
57
+ https://github.com/pratik-choudhari/Financial-news-scraper /with some unrelated changes because is broken
58
+ https://github.com/dorianrod/GitReviewLens
59
+
60
+ https://github.com/natekspencer/pylitterbot required some changes:
61
+ - there were raising a custom exception on request on test_litter_robot_5_dispatch_command_failure, and that is not supported.
62
+ - - However, they were try to mimick a 500 with certain json that was supported
63
+ - There were some calls to localhost, that should be to https://localhost. This was
64
+ also a fixable error on the tests
65
+
66
+
67
+ Broken on main
68
+ https://github.com/symphony-youri/symphony-api-client-python.git
69
+
70
+ too complex to work: https://github.com/mguidon/osparc-simcore
@@ -0,0 +1,60 @@
1
+ Proof of concept for an aioresponses-like library that uses real aiohttp server
2
+ related to this discussion: https://github.com/orgs/aio-libs/discussions/45
3
+
4
+ This is a proof of concept of how a linrary could expose aioresponses-like API
5
+ while using real aiohttp server under the hood. It works only with GET requests,
6
+ only compare the url, param and method, and only implements assert_called_with.
7
+
8
+ The breaking changes will be:
9
+ - The context manager will be async, as it will need to start the server
10
+ - the assert_called_* methods will not work with arbitrary kwargs, instead they will only work with specific args that the request was made with (e.g. url, method, headers, params, etc.)
11
+ - the fragments (after #) are not being passed on the request, so will not be compared
12
+ - on a connector exception, aiohttp could retry, so the number of request will not be the same
13
+ - pass timeout don't work
14
+ - you cant raise exceptions exception clienterror
15
+ - the decorathor need to decorate an async function
16
+ - as this mock DNS will not work to mock request to external IPs
17
+
18
+
19
+ Added a perf test to compare the performance of the POC with the original aioresponses implementation.
20
+
21
+ Results:
22
+
23
+ aioresponses (main) : 0.7223 seconds for 1000 iter (0.72 ms/iter)
24
+ aioresponses_2 (POC) : 0.8272 seconds for 1000 iter (0.83 ms/iter)
25
+
26
+ Probablly this overheard is tolerable, and could be optimized.
27
+ However, once we start adding more features, the performance will degrade.
28
+
29
+
30
+ Changing:
31
+
32
+ @pytest.fixture
33
+ def mock_aioresponse():
34
+ with aioresponses() as m:
35
+
36
+ to:
37
+
38
+ @pytest_asyncio.fixture
39
+ async def mock_aioresponse():
40
+ async with aioresponses() as m:
41
+ yield m
42
+
43
+ is passing the tests on:
44
+
45
+ https://github.com/cortega26/PDF-Text-Analyzer
46
+ https://github.com/mxr/reconciler-for-ynab
47
+ https://github.com/pratik-choudhari/Financial-news-scraper /with some unrelated changes because is broken
48
+ https://github.com/dorianrod/GitReviewLens
49
+
50
+ https://github.com/natekspencer/pylitterbot required some changes:
51
+ - there were raising a custom exception on request on test_litter_robot_5_dispatch_command_failure, and that is not supported.
52
+ - - However, they were try to mimick a 500 with certain json that was supported
53
+ - There were some calls to localhost, that should be to https://localhost. This was
54
+ also a fixable error on the tests
55
+
56
+
57
+ Broken on main
58
+ https://github.com/symphony-youri/symphony-api-client-python.git
59
+
60
+ too complex to work: https://github.com/mguidon/osparc-simcore
@@ -0,0 +1,3 @@
1
+ from .core import aiointercept, CallbackResult
2
+
3
+ __all__ = ["aiointercept", "CallbackResult"]
@@ -0,0 +1,19 @@
1
+ from multidict import MultiDict
2
+ from yarl import URL
3
+
4
+
5
+ def normalize_url(url: "URL | str") -> URL:
6
+ """Normalize url to make comparisons."""
7
+ url = URL(url)
8
+ if url.fragment:
9
+ url = url.with_fragment(None)
10
+ return url.with_query(sorted(url.query.items()))
11
+
12
+
13
+ def merge_params(url: "URL | str", params: "dict[str, str] | None" = None) -> URL:
14
+ url = URL(url)
15
+ if params:
16
+ query_params = MultiDict(url.query)
17
+ query_params.extend(url.with_query(params).query)
18
+ return url.with_query(query_params)
19
+ return url