Add rate limiting middleware example and introduce tests for examples#11969
Add rate limiting middleware example and introduce tests for examples#11969rodrigobnogueira wants to merge 46 commits intoaio-libs:masterfrom
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #11969 +/- ##
========================================
Coverage 98.76% 98.77%
========================================
Files 127 128 +1
Lines 44655 44881 +226
Branches 2367 2382 +15
========================================
+ Hits 44102 44329 +227
Misses 393 393
+ Partials 160 159 -1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
|
@Dreamsorcerer do we have any guidance on the examples folder? Some of those files are decade-old and I, for example, never really look in there. @rodrigobnogueira would you be interested in trying to get pytest to run the examples and getting code coverage as acceptance tests? |
Yes @webknjaz , I can try that to get pytest to run the examples, but I suppose the examples guidance should be the first step, because some examples may not comply. Guidance draft:
Potential tweaks of the rule above: if an example must use an external dep (e.g., for integrating with a database like asyncpg in a real-world demo), it should include a clear setup section at the top, like a requirements.txt snippet or install command.
|
This comment was marked as outdated.
This comment was marked as outdated.
Not particularly. This PR is still open on my computer to review, will get back to it soon enough.
I guess the question is whether all examples should be cluttered with tests? We have mypy running on them which atleast avoids regular API breakage like we often had in the past. |
@Dreamsorcerer I was mostly thinking of having them run as something like subprocess invocations (maybe in containers). The tests would be just invoking them and checking they completed fine, didn't have warnings, smoke mainly, not adding assertions inside. We could have them have own pytest mark so we'd only invoke them in a single CI job. |
This example demonstrates how to implement client-side rate limiting using the token bucket algorithm with support for: - Configurable rate and burst size - Per-domain rate limiting for multi-host scenarios - Automatic Retry-After header handling Includes a self-contained test server for demonstration.
Per maintainer feedback, add subprocess-based smoke tests for examples. Tests verify examples complete without errors. - Add 'example' pytest marker excluded from default run - Create tests/test_examples.py with parametrized tests - Test 7 self-contained middleware examples - Tests must run with --numprocesses=0 due to port conflicts
9f7a307 to
4d6c2c4
Compare
…unctional testing and enhance example smoke tests to check for warnings.
…d suppress flake8 I900 for local imports
This comment was marked as outdated.
This comment was marked as outdated.
|
The regex test issue (#11992) has just shown up here. macos, python 3.10 FAILED tests/test_client_middleware_digest_auth.py::test_regex_performance - assert (216.348098916 - 216.338082958) < 0.01 |
Fixed flaky test where websocket client closed before server echo responses arrived. Added asyncio.sleep(0.1) to allow pending messages to be received before assertions.
…rocesses for testing.
|
Standardizing Example Tests to Self-Contained Smoke Tests Every example now follows a 3-function pattern:
For server-only examples (web_srv, server_simple, web_cookies, etc.), the test code exercises the existing routes using aiohttp.ClientSession. For client examples (client_json, client_auth, curl, client_ws), we embed a lightweight mock server inside the example itself, then point the existing client logic at it. |
for more information, see https://pre-commit.ci
…igest auth example.
for more information, see https://pre-commit.ci
|
All test logic that previously lived in tests/test_examples.py as functional tests (using aiohttp_client and importing from examples/) was moved INTO each example file. tests/test_examples.py now has a single parametrized test that runs each example as a subprocess. I think having the test logic embedded in each example file adds value:
|
|
@webknjaz , I've gone through the example files in this PR and checked them against the originals on master. I believe they correspond in intent to the original examples — the core handler logic, route definitions, and middleware implementations are preserved across the board. 🙏 I'm aware this PR has grown quite a bit and may be harder to review than ideal. I think there's room for simplification. In particular, there is a ~12-line boilerplate block ( I hope this is headed in the right direction. If you have suggestions on how we could wrap this PR up sooner, I'm happy to work on improvements in follow-up PRs. For example, I still haven't worked on exposing the actual bound port through the runners/sites public interface, as you previously mentioned. I can try this here as well. Let me know your thoughts. Thanks |
There was a problem hiding this comment.
I think this makes the examples too complex for my liking.
If we want to proceed with actual tests for the examples, I would suggest adding separate test files under examples/tests/. These could atleast provide examples to users on how to do proper testing of their application. If we go with this, I'd suggest a separate PR for each example, it will significantly accelerate the speed we can review and merge the changes.
At the same time, I kind of feel that these examples should be small and trivial enough, that they don't really need tests. Anything complex enough to need proper testing likely goes to https://github.com/aio-libs/aiohttp-demos/
- Strip rate_limit_middleware.py to just TokenBucket + RateLimitMiddleware classes and a minimal main() demo using base_url - Add examples/tests/test_rate_limit_middleware.py with unit tests - Add examples/tests/pytest.ini for pythonpath config - Update CHANGES/11969.doc.rst to reflect simplified scope
for more information, see https://pre-commit.ci
…demo output to include request elapsed time.
|
Hey @Dreamsorcerer @webknjaz, the PR looks manageable now. I've kept just my original example with some improvements and created a test file for it in examples/tests/test_rate_limit_middleware.py Added examples/tests/pytest.ini so tests are runnable locally without affecting project config. Kept scope minimal—no touches to existing examples. This keeps examples clear for learning while providing dedicated tests in a separate dir. Let me know if we can apply the same idea to other examples. This way I could check the other examples and submit maybe 2 or 3 adjusted examples with tests in subsequent PRs. 🙏 |
…or fair rate limiting, and update associated tests and demo to use a local web server.
for more information, see https://pre-commit.ci
What do these changes do?
Adds a new example (
examples/rate_limit_middleware.py) demonstrating rate limiting middleware for the aiohttp client using the token bucket algorithm.Introduced
tests/test_examples.pywith subprocess-based smoke tests for self-contained examples (e.g., middlewares) and in-process functional tests for importable server examples. This validates examples run without errors, addressing potential bit rot.Refactoring of examples to make them pytestable.
Are there changes in behavior for the user?
No changes to the aiohttp library code.
Is it a substantial burden for the maintainers to support this?
No.
Related issue number
N/A — New example contribution.
Checklist
CONTRIBUTORS.txtCHANGES/folder