bustapi 0.12.0__tar.gz → 0.13.1__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.
- {bustapi-0.12.0 → bustapi-0.13.1}/.github/FUNDING.yml +1 -1
- {bustapi-0.12.0 → bustapi-0.13.1}/CHANGELOG.md +24 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/Cargo.lock +31 -55
- {bustapi-0.12.0 → bustapi-0.13.1}/Cargo.toml +12 -12
- {bustapi-0.12.0 → bustapi-0.13.1}/PKG-INFO +19 -18
- {bustapi-0.12.0 → bustapi-0.13.1}/README.md +9 -8
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/changelog.md +24 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/complete-api-reference.md +71 -10
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/examples-guide.md +9 -2
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/index.md +3 -1
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/quickstart.md +4 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/user-guide/authentication.md +3 -0
- bustapi-0.13.1/docs/user-guide/documentation.md +144 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/user-guide/error_handling.md +30 -0
- bustapi-0.13.1/docs/user-guide/jwt.md +203 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/user-guide/responses.md +63 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/examples/security/17_jwt_auth.py +1 -1
- bustapi-0.13.1/examples/security/18_jwt_cookies.py +99 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/pyproject.toml +11 -11
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/__init__.py +4 -1
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/app.py +36 -146
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/auth/decorators.py +23 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/auth/login.py +6 -1
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/core/exceptions.py +3 -1
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/dispatch.py +120 -119
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/hooks.py +15 -3
- bustapi-0.13.1/python/bustapi/http/response.py +284 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/jwt.py +122 -97
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/server/wsgi.py +44 -13
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/testing/client.py +62 -172
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/utils.py +51 -1
- bustapi-0.13.1/scratch/test_abort.py +20 -0
- bustapi-0.13.1/scratch/test_headers.py +9 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/src/bindings/app.rs +4 -22
- {bustapi-0.12.0 → bustapi-0.13.1}/src/bindings/converters.rs +75 -158
- {bustapi-0.12.0 → bustapi-0.13.1}/src/bindings/request.rs +2 -2
- {bustapi-0.12.0 → bustapi-0.13.1}/src/bindings/websocket.rs +2 -2
- {bustapi-0.12.0 → bustapi-0.13.1}/src/rate_limiter.rs +1 -1
- {bustapi-0.12.0 → bustapi-0.13.1}/src/response/builders.rs +6 -9
- bustapi-0.13.1/src/response/methods.rs +82 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/src/router/handlers.rs +1 -1
- {bustapi-0.12.0 → bustapi-0.13.1}/src/router/middleware.rs +6 -6
- {bustapi-0.12.0 → bustapi-0.13.1}/src/server/handlers.rs +3 -3
- {bustapi-0.12.0 → bustapi-0.13.1}/src/server/stream.rs +35 -42
- {bustapi-0.12.0 → bustapi-0.13.1}/src/websocket/config.rs +1 -1
- bustapi-0.13.1/tests/test_async_hooks.py +56 -0
- bustapi-0.13.1/tests/test_async_login.py +82 -0
- bustapi-0.13.1/tests/test_jwt_cookies.py +70 -0
- bustapi-0.13.1/tests/test_orm_conflict.py +75 -0
- bustapi-0.12.0/docs/user-guide/documentation.md +0 -32
- bustapi-0.12.0/docs/user-guide/jwt.md +0 -174
- bustapi-0.12.0/python/bustapi/core/wsgi.py +0 -136
- bustapi-0.12.0/python/bustapi/http/response.py +0 -513
- bustapi-0.12.0/src/response/methods.rs +0 -44
- {bustapi-0.12.0 → bustapi-0.13.1}/- +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/.github/workflows/ci-multiplatform.yml +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/.github/workflows/ci.yml +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/.github/workflows/docs.yml +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/.github/workflows/manual-publish.yml +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/.gitignore +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/.python-version +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/Dockerfile +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/LICENSE +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/benchmarks/CACHE_BENCHMARK.md +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/benchmarks/README.md +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/benchmarks/app.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/benchmarks/benchmark_all.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/benchmarks/benchmark_avg.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/benchmarks/benchmark_cache.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/benchmarks/benchmark_combined.png +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/benchmarks/bustapi.md +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/benchmarks/bustapi_bench.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/benchmarks/bustapi_internal.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/benchmarks/comparison_bench.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/benchmarks/comprehensive_benchmark.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/benchmarks/gen_graph.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/benchmarks/quick_bench.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/benchmarks/resource_bench.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/benchmarks/rps_comparison.png +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/benchmarks/run_comparison_auto.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/benchmarks/ws_benchmark.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/check_path.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/create_issues.sh +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/advanced/async.md +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/advanced/blueprints.md +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/advanced/dependency_injection.md +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/advanced/deployment.md +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/advanced/middleware.md +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/advanced/security.md +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/advanced/validation.md +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/api-reference.md +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/assets/logo.png +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/deployment-performance-guide.md +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/deployment.md +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/installation.md +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/overrides/.gitkeep +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/release_track.md +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/site/advanced/async_support.html +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/site/advanced/blueprints.html +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/site/advanced/dependency_injection.html +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/site/advanced/middleware.html +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/site/advanced/validation.html +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/site/api/all.html +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/site/api/app.html +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/site/api/context.html +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/site/api/utilities.html +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/site/assets/logo.png +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/site/changelog.html +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/site/core_concepts/request_data.html +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/site/core_concepts/responses.html +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/site/core_concepts/routing.html +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/site/core_concepts/templates.html +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/site/examples/index.html +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/site/getting_started/index.html +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/site/getting_started/quickstart.html +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/site/index.html +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/site/script.js +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/site/style.css +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/stylesheets/extra.css +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/user-guide/caching.md +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/user-guide/cli.md +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/user-guide/database.md +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/user-guide/logging.md +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/user-guide/multiprocessing.md +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/user-guide/request_data.md +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/user-guide/routing.md +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/user-guide/sessions.md +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/user-guide/static_files.md +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/user-guide/templates.md +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/user-guide/turbo-routes.md +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/user-guide/video-streaming.md +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/docs/websockets.md +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/examples/advanced/08_auto_docs.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/examples/advanced/12_test_modes.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/examples/advanced/13_error_handling.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/examples/advanced/14_middleware.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/examples/advanced/16_middleware_session.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/examples/advanced/20_file_uploads.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/examples/advanced/24_body_and_depends.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/examples/advanced/27_video_stream.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/examples/advanced/28_websocket.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/examples/advanced/29_turbo_websocket.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/examples/basics/01_hello_world.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/examples/basics/02_parameters.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/examples/basics/03_async.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/examples/basics/04_request_data.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/examples/basics/19_all_types.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/examples/database/07_database_raw.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/examples/database/10_database_sqlmodel.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/examples/routing/06_blueprints.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/examples/routing/09_complex_routing.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/examples/routing/21_path_validation.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/examples/routing/22_path_docs.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/examples/routing/23_query_validation.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/examples/routing/blueprint_with_jwt.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/examples/security/10_rate_limit_demo.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/examples/security/11_security_demo.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/examples/security/17_safe_features.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/examples/security/18_safe_advanced.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/examples/security/18_session_login.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/examples/templates/05_templates.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/examples/templates/26_complex_template.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/examples/templates/templates/index.html +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/examples/turbo/cache_test.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/examples/turbo/fair_benchmark.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/examples/turbo/typed_turbo_example.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/examples/ws/app.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/examples/ws/templates/index.html +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/examples/ws/websockets_demo.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/examples/ws/ws_limit.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/mkdocs.yml +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/auth/__init__.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/auth/csrf.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/auth/password.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/auth/tokens.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/auth/user.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/cli/__init__.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/cli/main.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/context.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/core/__init__.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/core/asgi.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/core/helpers.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/core/logging.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/dependencies.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/documentation/__init__.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/documentation/generator.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/extraction.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/fastapi_compat.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/http/__init__.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/http/request.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/logging.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/middleware.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/multiprocess.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/params.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/py.typed +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/responses.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/routing/__init__.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/routing/blueprints.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/routing/decorators.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/safe/__init__.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/safe/concurrency.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/safe/types.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/security/__init__.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/security/extension.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/security/rate_limit.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/server/__init__.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/server/runner.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/sessions.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/templating/__init__.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/templating/engine.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/templating/mixin.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/testing/__init__.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/python/bustapi/websocket.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/run_all_examples.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/src/bindings/handlers.rs +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/src/bindings/mod.rs +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/src/bindings/typed_turbo.rs +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/src/crypto.rs +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/src/jwt.rs +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/src/lib.rs +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/src/logger.rs +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/src/request/methods.rs +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/src/request/mod.rs +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/src/request/tests.rs +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/src/response/mod.rs +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/src/router/matching.rs +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/src/router/mod.rs +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/src/router/tests.rs +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/src/server/mod.rs +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/src/server/startup.rs +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/src/static_files.rs +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/src/templating.rs +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/src/watcher.rs +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/src/websocket/mod.rs +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/src/websocket/session.rs +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/src/websocket/turbo.rs +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/static/style.css +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/templates/base.html +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/templates/complex.html +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/test_trim.rs +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/tests/docs_test_all.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/tests/docs_test_api_reference.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/tests/docs_test_installation.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/tests/docs_test_quickstart.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/tests/docs_test_simple.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/tests/test_050_features.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/tests/test_auth.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/tests/test_examples.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/tests/test_hot_reload.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/tests/test_issue_18.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/tests/test_jwt.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/tests/test_login_manager.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/tests/test_middleware.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/tests/test_multiprocess_stability.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/tests/test_new_examples.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/tests/test_path_standalone.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/tests/test_path_validation.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/tests/test_rate_limit_rust.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/tests/test_safe.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/tests/test_security_unit.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/tests/test_sessions.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/tests/test_zero_copy.py +0 -0
- {bustapi-0.12.0 → bustapi-0.13.1}/tests/verify_router.py +0 -0
|
@@ -2,6 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented here.
|
|
4
4
|
|
|
5
|
+
## [0.13.1] - 2026-05-03
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
- **StreamingResponse Support**: Fixed a regression in v0.13.0 where `StreamingResponse` and `FileResponse` were returning empty bodies due to over-strict Python-to-Rust conversion.
|
|
9
|
+
- **Async Streaming Stability**: Refactored async stream polling to use the global background event loop, ensuring robust support for async generators (including those using `asyncio.sleep`) within Actix-web worker threads.
|
|
10
|
+
|
|
11
|
+
## [0.13.0] - 2026-05-02
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
- **Robust Header Infrastructure**:
|
|
15
|
+
- Refactored `Headers` class to use `collections.UserDict` for better standard library compatibility.
|
|
16
|
+
- Implemented full case-insensitivity for all header operations (get, set, delete).
|
|
17
|
+
- Added native support for multi-value headers via `headers.add(key, value)` and `headers.getlist(key)`.
|
|
18
|
+
- **WSGI Adapter Enhancements**:
|
|
19
|
+
- Refactored `WSGIAdapter` to correctly handle multi-value headers.
|
|
20
|
+
- Integrated application-level error handling (including custom 404/500 handlers) into the WSGI layer.
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
- **JWT & Cookie Security**:
|
|
24
|
+
- Updated `Response.delete_cookie()` signature to accept `secure`, `httponly`, and `samesite` arguments, fixing crashes in JWT logout flows.
|
|
25
|
+
- Improved cookie attribute handling to ensure consistency between Python and Rust layers.
|
|
26
|
+
- **Response Unwrapping**: Fixed a bug where returning a `Response` object inside another `Response` (common in error handlers using `render_template`) resulted in the object's string representation being sent as the body.
|
|
27
|
+
- **FFI Stability**: Standardized the Python-to-Rust response conversion to ensure reliable header serialization.
|
|
28
|
+
|
|
5
29
|
## [0.12.0] - 2026-04-27
|
|
6
30
|
|
|
7
31
|
### Added
|
|
@@ -438,7 +438,7 @@ checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb"
|
|
|
438
438
|
|
|
439
439
|
[[package]]
|
|
440
440
|
name = "bustapi_core"
|
|
441
|
-
version = "0.
|
|
441
|
+
version = "0.13.1"
|
|
442
442
|
dependencies = [
|
|
443
443
|
"actix-files",
|
|
444
444
|
"actix-http",
|
|
@@ -488,9 +488,9 @@ checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"
|
|
|
488
488
|
|
|
489
489
|
[[package]]
|
|
490
490
|
name = "bytestring"
|
|
491
|
-
version = "1.5.
|
|
491
|
+
version = "1.5.1"
|
|
492
492
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
493
|
-
checksum = "
|
|
493
|
+
checksum = "86566c496f2f47d9b8147a4c8b02ffdb69c919fe0c2b2e7195d22cbba0e635c9"
|
|
494
494
|
dependencies = [
|
|
495
495
|
"bytes",
|
|
496
496
|
]
|
|
@@ -1262,9 +1262,9 @@ dependencies = [
|
|
|
1262
1262
|
|
|
1263
1263
|
[[package]]
|
|
1264
1264
|
name = "idna_adapter"
|
|
1265
|
-
version = "1.2.
|
|
1265
|
+
version = "1.2.2"
|
|
1266
1266
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1267
|
-
checksum = "
|
|
1267
|
+
checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714"
|
|
1268
1268
|
dependencies = [
|
|
1269
1269
|
"icu_normalizer",
|
|
1270
1270
|
"icu_properties",
|
|
@@ -1288,15 +1288,6 @@ dependencies = [
|
|
|
1288
1288
|
"serde_core",
|
|
1289
1289
|
]
|
|
1290
1290
|
|
|
1291
|
-
[[package]]
|
|
1292
|
-
name = "indoc"
|
|
1293
|
-
version = "2.0.7"
|
|
1294
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1295
|
-
checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706"
|
|
1296
|
-
dependencies = [
|
|
1297
|
-
"rustversion",
|
|
1298
|
-
]
|
|
1299
|
-
|
|
1300
1291
|
[[package]]
|
|
1301
1292
|
name = "inotify"
|
|
1302
1293
|
version = "0.11.1"
|
|
@@ -1344,10 +1335,12 @@ dependencies = [
|
|
|
1344
1335
|
|
|
1345
1336
|
[[package]]
|
|
1346
1337
|
name = "js-sys"
|
|
1347
|
-
version = "0.3.
|
|
1338
|
+
version = "0.3.97"
|
|
1348
1339
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1349
|
-
checksum = "
|
|
1340
|
+
checksum = "a1840c94c045fbcf8ba2812c95db44499f7c64910a912551aaaa541decebcacf"
|
|
1350
1341
|
dependencies = [
|
|
1342
|
+
"cfg-if",
|
|
1343
|
+
"futures-util",
|
|
1351
1344
|
"once_cell",
|
|
1352
1345
|
"wasm-bindgen",
|
|
1353
1346
|
]
|
|
@@ -1476,15 +1469,6 @@ version = "0.3.3"
|
|
|
1476
1469
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1477
1470
|
checksum = "38d1115007560874e373613744c6fba374c17688327a71c1476d1a5954cc857b"
|
|
1478
1471
|
|
|
1479
|
-
[[package]]
|
|
1480
|
-
name = "memoffset"
|
|
1481
|
-
version = "0.9.1"
|
|
1482
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1483
|
-
checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
|
|
1484
|
-
dependencies = [
|
|
1485
|
-
"autocfg",
|
|
1486
|
-
]
|
|
1487
|
-
|
|
1488
1472
|
[[package]]
|
|
1489
1473
|
name = "mimalloc"
|
|
1490
1474
|
version = "0.1.50"
|
|
@@ -1749,28 +1733,26 @@ dependencies = [
|
|
|
1749
1733
|
|
|
1750
1734
|
[[package]]
|
|
1751
1735
|
name = "pyo3"
|
|
1752
|
-
version = "0.
|
|
1736
|
+
version = "0.28.3"
|
|
1753
1737
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1754
|
-
checksum = "
|
|
1738
|
+
checksum = "91fd8e38a3b50ed1167fb981cd6fd60147e091784c427b8f7183a7ee32c31c12"
|
|
1755
1739
|
dependencies = [
|
|
1756
|
-
"indoc",
|
|
1757
1740
|
"libc",
|
|
1758
|
-
"memoffset",
|
|
1759
1741
|
"once_cell",
|
|
1760
1742
|
"portable-atomic",
|
|
1761
1743
|
"pyo3-build-config",
|
|
1762
1744
|
"pyo3-ffi",
|
|
1763
1745
|
"pyo3-macros",
|
|
1764
|
-
"unindent",
|
|
1765
1746
|
]
|
|
1766
1747
|
|
|
1767
1748
|
[[package]]
|
|
1768
1749
|
name = "pyo3-async-runtimes"
|
|
1769
|
-
version = "0.
|
|
1750
|
+
version = "0.28.0"
|
|
1770
1751
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1771
|
-
checksum = "
|
|
1752
|
+
checksum = "9e7364a95bf00e8377bbf9b0f09d7ff9715a29d8fcf93b47d1a967363b973178"
|
|
1772
1753
|
dependencies = [
|
|
1773
|
-
"futures",
|
|
1754
|
+
"futures-channel",
|
|
1755
|
+
"futures-util",
|
|
1774
1756
|
"once_cell",
|
|
1775
1757
|
"pin-project-lite",
|
|
1776
1758
|
"pyo3",
|
|
@@ -1779,18 +1761,18 @@ dependencies = [
|
|
|
1779
1761
|
|
|
1780
1762
|
[[package]]
|
|
1781
1763
|
name = "pyo3-build-config"
|
|
1782
|
-
version = "0.
|
|
1764
|
+
version = "0.28.3"
|
|
1783
1765
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1784
|
-
checksum = "
|
|
1766
|
+
checksum = "e368e7ddfdeb98c9bca7f8383be1648fd84ab466bf2bc015e94008db6d35611e"
|
|
1785
1767
|
dependencies = [
|
|
1786
1768
|
"target-lexicon",
|
|
1787
1769
|
]
|
|
1788
1770
|
|
|
1789
1771
|
[[package]]
|
|
1790
1772
|
name = "pyo3-ffi"
|
|
1791
|
-
version = "0.
|
|
1773
|
+
version = "0.28.3"
|
|
1792
1774
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1793
|
-
checksum = "
|
|
1775
|
+
checksum = "7f29e10af80b1f7ccaf7f69eace800a03ecd13e883acfacc1e5d0988605f651e"
|
|
1794
1776
|
dependencies = [
|
|
1795
1777
|
"libc",
|
|
1796
1778
|
"pyo3-build-config",
|
|
@@ -1798,9 +1780,9 @@ dependencies = [
|
|
|
1798
1780
|
|
|
1799
1781
|
[[package]]
|
|
1800
1782
|
name = "pyo3-macros"
|
|
1801
|
-
version = "0.
|
|
1783
|
+
version = "0.28.3"
|
|
1802
1784
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1803
|
-
checksum = "
|
|
1785
|
+
checksum = "df6e520eff47c45997d2fc7dd8214b25dd1310918bbb2642156ef66a67f29813"
|
|
1804
1786
|
dependencies = [
|
|
1805
1787
|
"proc-macro2",
|
|
1806
1788
|
"pyo3-macros-backend",
|
|
@@ -1810,9 +1792,9 @@ dependencies = [
|
|
|
1810
1792
|
|
|
1811
1793
|
[[package]]
|
|
1812
1794
|
name = "pyo3-macros-backend"
|
|
1813
|
-
version = "0.
|
|
1795
|
+
version = "0.28.3"
|
|
1814
1796
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1815
|
-
checksum = "
|
|
1797
|
+
checksum = "c4cdc218d835738f81c2338f822078af45b4afdf8b2e33cbb5916f108b813acb"
|
|
1816
1798
|
dependencies = [
|
|
1817
1799
|
"heck",
|
|
1818
1800
|
"proc-macro2",
|
|
@@ -2399,12 +2381,6 @@ version = "0.2.6"
|
|
|
2399
2381
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2400
2382
|
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
|
|
2401
2383
|
|
|
2402
|
-
[[package]]
|
|
2403
|
-
name = "unindent"
|
|
2404
|
-
version = "0.2.4"
|
|
2405
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2406
|
-
checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3"
|
|
2407
|
-
|
|
2408
2384
|
[[package]]
|
|
2409
2385
|
name = "universal-hash"
|
|
2410
2386
|
version = "0.5.1"
|
|
@@ -2487,9 +2463,9 @@ dependencies = [
|
|
|
2487
2463
|
|
|
2488
2464
|
[[package]]
|
|
2489
2465
|
name = "wasm-bindgen"
|
|
2490
|
-
version = "0.2.
|
|
2466
|
+
version = "0.2.120"
|
|
2491
2467
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2492
|
-
checksum = "
|
|
2468
|
+
checksum = "df52b6d9b87e0c74c9edfa1eb2d9bf85e5d63515474513aa50fa181b3c4f5db1"
|
|
2493
2469
|
dependencies = [
|
|
2494
2470
|
"cfg-if",
|
|
2495
2471
|
"once_cell",
|
|
@@ -2500,9 +2476,9 @@ dependencies = [
|
|
|
2500
2476
|
|
|
2501
2477
|
[[package]]
|
|
2502
2478
|
name = "wasm-bindgen-macro"
|
|
2503
|
-
version = "0.2.
|
|
2479
|
+
version = "0.2.120"
|
|
2504
2480
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2505
|
-
checksum = "
|
|
2481
|
+
checksum = "78b1041f495fb322e64aca85f5756b2172e35cd459376e67f2a6c9dffcedb103"
|
|
2506
2482
|
dependencies = [
|
|
2507
2483
|
"quote",
|
|
2508
2484
|
"wasm-bindgen-macro-support",
|
|
@@ -2510,9 +2486,9 @@ dependencies = [
|
|
|
2510
2486
|
|
|
2511
2487
|
[[package]]
|
|
2512
2488
|
name = "wasm-bindgen-macro-support"
|
|
2513
|
-
version = "0.2.
|
|
2489
|
+
version = "0.2.120"
|
|
2514
2490
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2515
|
-
checksum = "
|
|
2491
|
+
checksum = "9dcd0ff20416988a18ac686d4d4d0f6aae9ebf08a389ff5d29012b05af2a1b41"
|
|
2516
2492
|
dependencies = [
|
|
2517
2493
|
"bumpalo",
|
|
2518
2494
|
"proc-macro2",
|
|
@@ -2523,9 +2499,9 @@ dependencies = [
|
|
|
2523
2499
|
|
|
2524
2500
|
[[package]]
|
|
2525
2501
|
name = "wasm-bindgen-shared"
|
|
2526
|
-
version = "0.2.
|
|
2502
|
+
version = "0.2.120"
|
|
2527
2503
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2528
|
-
checksum = "
|
|
2504
|
+
checksum = "49757b3c82ebf16c57d69365a142940b384176c24df52a087fb748e2085359ea"
|
|
2529
2505
|
dependencies = [
|
|
2530
2506
|
"unicode-ident",
|
|
2531
2507
|
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "bustapi_core"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.13.1"
|
|
4
4
|
edition = "2021"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
|
|
@@ -10,20 +10,20 @@ crate-type = ["cdylib"]
|
|
|
10
10
|
|
|
11
11
|
[dependencies]
|
|
12
12
|
# Actix-web (replaces Hyper for better performance)
|
|
13
|
-
actix-web = "4"
|
|
14
|
-
actix-rt = "2"
|
|
15
|
-
actix-http = "3"
|
|
13
|
+
actix-web = "4.13"
|
|
14
|
+
actix-rt = "2.10"
|
|
15
|
+
actix-http = "3.9"
|
|
16
16
|
actix-files = "0.6"
|
|
17
17
|
actix-ws = "0.2.5"
|
|
18
18
|
|
|
19
19
|
# PyO3 with latest version for Python 3.14 support
|
|
20
|
-
pyo3 = { version = "0.
|
|
21
|
-
# Use pyo3-async-runtimes (compatible with pyo3 0.
|
|
22
|
-
pyo3-async-runtimes = { version = "0.
|
|
20
|
+
pyo3 = { version = "0.28", features = ["extension-module", "abi3-py310"] }
|
|
21
|
+
# Use pyo3-async-runtimes (compatible with pyo3 0.28)
|
|
22
|
+
pyo3-async-runtimes = { version = "0.28", features = ["tokio-runtime"] }
|
|
23
23
|
|
|
24
24
|
# Async runtime
|
|
25
|
-
tokio = { version = "1.
|
|
26
|
-
futures = "0.3"
|
|
25
|
+
tokio = { version = "1.52", features = ["full"] }
|
|
26
|
+
futures = "0.3.31"
|
|
27
27
|
cookie = { version = "0.18", features = ["signed", "secure", "percent-encode"] }
|
|
28
28
|
percent-encoding = "2.3"
|
|
29
29
|
sha2 = "0.10"
|
|
@@ -38,9 +38,9 @@ rand = "0.8"
|
|
|
38
38
|
# Utilities
|
|
39
39
|
serde = { version = "1.0", features = ["derive"] }
|
|
40
40
|
serde_json = "1.0"
|
|
41
|
-
bytes = "1.
|
|
41
|
+
bytes = "1.10"
|
|
42
42
|
http = "0.2"
|
|
43
|
-
url = "2.
|
|
43
|
+
url = "2.5"
|
|
44
44
|
tracing = "0.1"
|
|
45
45
|
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
|
46
46
|
anyhow = "1.0"
|
|
@@ -64,7 +64,7 @@ default = ["mimalloc"]
|
|
|
64
64
|
|
|
65
65
|
|
|
66
66
|
[build-dependencies]
|
|
67
|
-
pyo3-build-config = "0.
|
|
67
|
+
pyo3-build-config = "0.28"
|
|
68
68
|
|
|
69
69
|
[profile.release]
|
|
70
70
|
lto = true
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: bustapi
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.13.1
|
|
4
4
|
Classifier: Development Status :: 3 - Alpha
|
|
5
5
|
Classifier: Intended Audience :: Developers
|
|
6
6
|
Classifier: License :: OSI Approved :: MIT License
|
|
@@ -14,10 +14,10 @@ Classifier: Programming Language :: Rust
|
|
|
14
14
|
Classifier: Topic :: Internet :: WWW/HTTP
|
|
15
15
|
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
16
16
|
Requires-Dist: jinja2>=3.1.6
|
|
17
|
-
Requires-Dist: uvicorn>=0.
|
|
17
|
+
Requires-Dist: uvicorn>=0.46.0 ; extra == 'benchmarks'
|
|
18
18
|
Requires-Dist: catzilla>=0.2.0 ; extra == 'benchmarks'
|
|
19
19
|
Requires-Dist: flask>=3.1.2 ; extra == 'benchmarks'
|
|
20
|
-
Requires-Dist: fastapi>=0.
|
|
20
|
+
Requires-Dist: fastapi>=0.136.1 ; extra == 'benchmarks'
|
|
21
21
|
Requires-Dist: gunicorn>=23.0.0 ; extra == 'benchmarks'
|
|
22
22
|
Requires-Dist: httpx>=0.28.1 ; extra == 'benchmarks'
|
|
23
23
|
Requires-Dist: matplotlib>=3.10.0 ; extra == 'benchmarks'
|
|
@@ -28,16 +28,16 @@ Requires-Dist: django>=5.0.0 ; extra == 'benchmarks'
|
|
|
28
28
|
Requires-Dist: blacksheep>=2.0.8 ; extra == 'benchmarks'
|
|
29
29
|
Requires-Dist: black>=24.8.0 ; extra == 'dev'
|
|
30
30
|
Requires-Dist: isort>=5.13.2 ; extra == 'dev'
|
|
31
|
-
Requires-Dist: maturin>=1.
|
|
31
|
+
Requires-Dist: maturin>=1.13.1 ; extra == 'dev'
|
|
32
32
|
Requires-Dist: pytest>=8.3.5 ; extra == 'dev'
|
|
33
33
|
Requires-Dist: pytest-asyncio>=0.24.0 ; extra == 'dev'
|
|
34
34
|
Requires-Dist: pytest-cov>=5.0.0 ; extra == 'dev'
|
|
35
|
-
Requires-Dist: ruff>=0.12
|
|
35
|
+
Requires-Dist: ruff>=0.15.12 ; extra == 'dev'
|
|
36
36
|
Requires-Dist: mypy>=1.0 ; extra == 'dev'
|
|
37
37
|
Requires-Dist: pre-commit>=3.0 ; extra == 'dev'
|
|
38
38
|
Requires-Dist: sqlmodel>=0.0.16 ; extra == 'dev'
|
|
39
39
|
Requires-Dist: psutil>=5.9.0 ; extra == 'dev'
|
|
40
|
-
Requires-Dist: requests>=2.
|
|
40
|
+
Requires-Dist: requests>=2.33.1 ; extra == 'dev'
|
|
41
41
|
Requires-Dist: mkdocs>=1.5 ; extra == 'docs'
|
|
42
42
|
Requires-Dist: mkdocs-material>=9.0 ; extra == 'docs'
|
|
43
43
|
Requires-Dist: mkdocstrings[python]>=0.20 ; extra == 'docs'
|
|
@@ -61,10 +61,10 @@ Author-email: GrandpaEJ <>
|
|
|
61
61
|
License: MIT
|
|
62
62
|
Requires-Python: >=3.10
|
|
63
63
|
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
64
|
-
Project-URL: Documentation, https://
|
|
65
|
-
Project-URL: Homepage, https://github.com/
|
|
66
|
-
Project-URL: Issues, https://github.com/
|
|
67
|
-
Project-URL: Repository, https://github.com/
|
|
64
|
+
Project-URL: Documentation, https://RUSTxPY.github.io/BustAPI/
|
|
65
|
+
Project-URL: Homepage, https://github.com/RUSTxPY/BustAPI
|
|
66
|
+
Project-URL: Issues, https://github.com/RUSTxPY/BustAPI/issues
|
|
67
|
+
Project-URL: Repository, https://github.com/RUSTxPY/BustAPI.git
|
|
68
68
|
|
|
69
69
|
# BustAPI — High-Performance Python Web Framework
|
|
70
70
|
|
|
@@ -107,6 +107,7 @@ Under the hood, BustAPI runs on [Actix-Web](https://actix.rs/) — consistently
|
|
|
107
107
|
- 🦀 **Rust-powered** — Zero-copy JSON, mimalloc allocator, Actix-Web
|
|
108
108
|
- 🐍 **Pure Python API** — No Rust knowledge required
|
|
109
109
|
- 🔒 **Security built-in** — JWT, sessions, CSRF, rate limiting
|
|
110
|
+
- 🛡️ **Robust Header System** — Case-insensitive, multi-value support, high-performance cookie parsing
|
|
110
111
|
- 📦 **Zero config** — `pip install bustapi` and you're ready
|
|
111
112
|
- 🔥 **Hot reload** — Rust-native file watcher for instant restarts
|
|
112
113
|
|
|
@@ -510,13 +511,13 @@ CMD ["python", "app.py"]
|
|
|
510
511
|
|
|
511
512
|
## 📖 Documentation
|
|
512
513
|
|
|
513
|
-
📚 **[Full Documentation](https://
|
|
514
|
+
📚 **[Full Documentation](https://RUSTxPY.github.io/BustAPI/)**
|
|
514
515
|
|
|
515
|
-
- [Getting Started](https://
|
|
516
|
-
- [Routing Guide](https://
|
|
517
|
-
- [JWT Authentication](https://
|
|
518
|
-
- [WebSocket Guide](https://
|
|
519
|
-
- [API Reference](https://
|
|
516
|
+
- [Getting Started](https://RUSTxPY.github.io/BustAPI/quickstart/)
|
|
517
|
+
- [Routing Guide](https://RUSTxPY.github.io/BustAPI/user-guide/routing/)
|
|
518
|
+
- [JWT Authentication](https://RUSTxPY.github.io/BustAPI/user-guide/jwt/)
|
|
519
|
+
- [WebSocket Guide](https://RUSTxPY.github.io/BustAPI/user-guide/websocket/)
|
|
520
|
+
- [API Reference](https://RUSTxPY.github.io/BustAPI/api-reference/)
|
|
520
521
|
|
|
521
522
|
---
|
|
522
523
|
|
|
@@ -532,8 +533,8 @@ We welcome contributions! Here's how:
|
|
|
532
533
|
|
|
533
534
|
Found a bug? Have a feature request?
|
|
534
535
|
|
|
535
|
-
- [Open an Issue](https://github.com/
|
|
536
|
-
- [Start a Discussion](https://github.com/
|
|
536
|
+
- [Open an Issue](https://github.com/RUSTxPY/BustAPI/issues)
|
|
537
|
+
- [Start a Discussion](https://github.com/RUSTxPY/BustAPI/discussions)
|
|
537
538
|
|
|
538
539
|
---
|
|
539
540
|
|
|
@@ -39,6 +39,7 @@ Under the hood, BustAPI runs on [Actix-Web](https://actix.rs/) — consistently
|
|
|
39
39
|
- 🦀 **Rust-powered** — Zero-copy JSON, mimalloc allocator, Actix-Web
|
|
40
40
|
- 🐍 **Pure Python API** — No Rust knowledge required
|
|
41
41
|
- 🔒 **Security built-in** — JWT, sessions, CSRF, rate limiting
|
|
42
|
+
- 🛡️ **Robust Header System** — Case-insensitive, multi-value support, high-performance cookie parsing
|
|
42
43
|
- 📦 **Zero config** — `pip install bustapi` and you're ready
|
|
43
44
|
- 🔥 **Hot reload** — Rust-native file watcher for instant restarts
|
|
44
45
|
|
|
@@ -442,13 +443,13 @@ CMD ["python", "app.py"]
|
|
|
442
443
|
|
|
443
444
|
## 📖 Documentation
|
|
444
445
|
|
|
445
|
-
📚 **[Full Documentation](https://
|
|
446
|
+
📚 **[Full Documentation](https://RUSTxPY.github.io/BustAPI/)**
|
|
446
447
|
|
|
447
|
-
- [Getting Started](https://
|
|
448
|
-
- [Routing Guide](https://
|
|
449
|
-
- [JWT Authentication](https://
|
|
450
|
-
- [WebSocket Guide](https://
|
|
451
|
-
- [API Reference](https://
|
|
448
|
+
- [Getting Started](https://RUSTxPY.github.io/BustAPI/quickstart/)
|
|
449
|
+
- [Routing Guide](https://RUSTxPY.github.io/BustAPI/user-guide/routing/)
|
|
450
|
+
- [JWT Authentication](https://RUSTxPY.github.io/BustAPI/user-guide/jwt/)
|
|
451
|
+
- [WebSocket Guide](https://RUSTxPY.github.io/BustAPI/user-guide/websocket/)
|
|
452
|
+
- [API Reference](https://RUSTxPY.github.io/BustAPI/api-reference/)
|
|
452
453
|
|
|
453
454
|
---
|
|
454
455
|
|
|
@@ -464,8 +465,8 @@ We welcome contributions! Here's how:
|
|
|
464
465
|
|
|
465
466
|
Found a bug? Have a feature request?
|
|
466
467
|
|
|
467
|
-
- [Open an Issue](https://github.com/
|
|
468
|
-
- [Start a Discussion](https://github.com/
|
|
468
|
+
- [Open an Issue](https://github.com/RUSTxPY/BustAPI/issues)
|
|
469
|
+
- [Start a Discussion](https://github.com/RUSTxPY/BustAPI/discussions)
|
|
469
470
|
|
|
470
471
|
---
|
|
471
472
|
|
|
@@ -2,6 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented here.
|
|
4
4
|
|
|
5
|
+
## [0.13.1] - 2026-05-03
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
- **StreamingResponse Support**: Fixed a regression in v0.13.0 where `StreamingResponse` and `FileResponse` were returning empty bodies due to over-strict Python-to-Rust conversion.
|
|
9
|
+
- **Async Streaming Stability**: Refactored async stream polling to use the global background event loop, ensuring robust support for async generators (including those using `asyncio.sleep`) within Actix-web worker threads.
|
|
10
|
+
|
|
11
|
+
## [0.13.0] - 2026-05-02
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
- **Robust Header Infrastructure**:
|
|
15
|
+
- Refactored `Headers` class to use `collections.UserDict` for better standard library compatibility.
|
|
16
|
+
- Implemented full case-insensitivity for all header operations (get, set, delete).
|
|
17
|
+
- Added native support for multi-value headers via `headers.add(key, value)` and `headers.getlist(key)`.
|
|
18
|
+
- **WSGI Adapter Enhancements**:
|
|
19
|
+
- Refactored `WSGIAdapter` to correctly handle multi-value headers.
|
|
20
|
+
- Integrated application-level error handling (including custom 404/500 handlers) into the WSGI layer.
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
- **JWT & Cookie Security**:
|
|
24
|
+
- Updated `Response.delete_cookie()` signature to accept `secure`, `httponly`, and `samesite` arguments, fixing crashes in JWT logout flows.
|
|
25
|
+
- Improved cookie attribute handling to ensure consistency between Python and Rust layers.
|
|
26
|
+
- **Response Unwrapping**: Fixed a bug where returning a `Response` object inside another `Response` (common in error handlers using `render_template`) resulted in the object's string representation being sent as the body.
|
|
27
|
+
- **FFI Stability**: Standardized the Python-to-Rust response conversion to ensure reliable header serialization.
|
|
28
|
+
|
|
5
29
|
## [0.12.0] - 2026-04-27
|
|
6
30
|
|
|
7
31
|
### Added
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# BustAPI Complete API Reference
|
|
2
2
|
|
|
3
|
-
> **Version:** 0.
|
|
4
|
-
> **Last Updated:**
|
|
3
|
+
> **Version:** 0.13.0
|
|
4
|
+
> **Last Updated:** 2026-05-02
|
|
5
5
|
|
|
6
6
|
## Table of Contents
|
|
7
7
|
|
|
@@ -356,8 +356,29 @@ response.data # Response body as bytes
|
|
|
356
356
|
```python
|
|
357
357
|
response.set_data(data) # Set response data
|
|
358
358
|
response.get_data(as_text=False) # Get response data
|
|
359
|
-
|
|
360
|
-
|
|
359
|
+
|
|
360
|
+
# Set a cookie
|
|
361
|
+
response.set_cookie(
|
|
362
|
+
key: str,
|
|
363
|
+
value: str = '',
|
|
364
|
+
max_age: Optional[int] = None,
|
|
365
|
+
expires: Optional[Union[datetime, float]] = None,
|
|
366
|
+
path: str = '/',
|
|
367
|
+
domain: Optional[str] = None,
|
|
368
|
+
secure: bool = False,
|
|
369
|
+
httponly: bool = False,
|
|
370
|
+
samesite: Optional[str] = 'Lax'
|
|
371
|
+
)
|
|
372
|
+
|
|
373
|
+
# Delete a cookie
|
|
374
|
+
response.delete_cookie(
|
|
375
|
+
key: str,
|
|
376
|
+
path: str = '/',
|
|
377
|
+
domain: Optional[str] = None,
|
|
378
|
+
secure: bool = False,
|
|
379
|
+
httponly: bool = False,
|
|
380
|
+
samesite: Optional[str] = 'Lax'
|
|
381
|
+
)
|
|
361
382
|
```
|
|
362
383
|
|
|
363
384
|
**Example:**
|
|
@@ -371,6 +392,30 @@ def custom_response():
|
|
|
371
392
|
return resp
|
|
372
393
|
```
|
|
373
394
|
|
|
395
|
+
### Headers Object
|
|
396
|
+
|
|
397
|
+
The `response.headers` object provides a case-insensitive dictionary-like interface for managing HTTP headers.
|
|
398
|
+
|
|
399
|
+
#### Methods
|
|
400
|
+
|
|
401
|
+
- `get(key, default=None)`: Get the first value for a header (case-insensitive).
|
|
402
|
+
- `add(key, value)`: Add a value to a header, preserving existing values (multi-value support).
|
|
403
|
+
- `getlist(key)`: Get all values for a header as a list.
|
|
404
|
+
- `setlist(key, values)`: Set multiple values for a header.
|
|
405
|
+
- `items()`: Get all header key-value pairs as a list of tuples.
|
|
406
|
+
|
|
407
|
+
**Example:**
|
|
408
|
+
|
|
409
|
+
```python
|
|
410
|
+
resp.headers['Content-Type'] = 'application/json'
|
|
411
|
+
resp.headers.add('Link', '<https://example.com>; rel="next"')
|
|
412
|
+
resp.headers.add('Link', '<https://example.com>; rel="prev"')
|
|
413
|
+
|
|
414
|
+
links = resp.headers.getlist('Link') # ['...', '...']
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
---
|
|
418
|
+
|
|
374
419
|
#### Response Helper Functions
|
|
375
420
|
|
|
376
421
|
##### `jsonify(*args, **kwargs)`
|
|
@@ -1076,14 +1121,30 @@ def internal_error(error):
|
|
|
1076
1121
|
|
|
1077
1122
|
#### Exception Handlers
|
|
1078
1123
|
|
|
1079
|
-
|
|
1124
|
+
````python
|
|
1080
1125
|
class ValidationError(Exception):
|
|
1081
1126
|
pass
|
|
1082
1127
|
|
|
1083
1128
|
@app.errorhandler(ValidationError)
|
|
1084
1129
|
def handle_validation_error(error):
|
|
1085
1130
|
return {'error': str(error), 'type': 'validation_error'}, 400
|
|
1086
|
-
|
|
1131
|
+
|
|
1132
|
+
#### Catch-All Handler
|
|
1133
|
+
|
|
1134
|
+
Handle all otherwise unhandled exceptions:
|
|
1135
|
+
|
|
1136
|
+
```python
|
|
1137
|
+
@app.errorhandler(Exception)
|
|
1138
|
+
def handle_exception(e):
|
|
1139
|
+
# Pass through HTTP errors
|
|
1140
|
+
if hasattr(e, "get_response"):
|
|
1141
|
+
return e.get_response()
|
|
1142
|
+
|
|
1143
|
+
# Generic error for everything else
|
|
1144
|
+
return {"error": "Something went wrong"}, 500
|
|
1145
|
+
````
|
|
1146
|
+
|
|
1147
|
+
````
|
|
1087
1148
|
|
|
1088
1149
|
### Using `abort()`
|
|
1089
1150
|
|
|
@@ -1102,7 +1163,7 @@ def admin():
|
|
|
1102
1163
|
if not is_admin():
|
|
1103
1164
|
abort(403, 'Admin access required')
|
|
1104
1165
|
return {'message': 'Admin panel'}
|
|
1105
|
-
|
|
1166
|
+
````
|
|
1106
1167
|
|
|
1107
1168
|
### Complete Error Handling Example
|
|
1108
1169
|
|
|
@@ -1546,11 +1607,11 @@ app.run(
|
|
|
1546
1607
|
```python
|
|
1547
1608
|
import bustapi
|
|
1548
1609
|
|
|
1549
|
-
print(bustapi.__version__) # '0.
|
|
1550
|
-
print(bustapi.get_version()) # '0.
|
|
1610
|
+
print(bustapi.__version__) # '0.13.0'
|
|
1611
|
+
print(bustapi.get_version()) # '0.13.0'
|
|
1551
1612
|
print(bustapi.get_debug_info()) # Detailed version info
|
|
1552
1613
|
```
|
|
1553
1614
|
|
|
1554
1615
|
---
|
|
1555
1616
|
|
|
1556
|
-
_This documentation covers BustAPI version 0.
|
|
1617
|
+
_This documentation covers BustAPI version 0.13.0. For the latest updates, visit the [official documentation](https://rustxpy.github.io/BustAPI/)._
|
|
@@ -12,6 +12,15 @@ The `examples/` directory in the repository contains many complete scripts demon
|
|
|
12
12
|
- **03_async.py**: Using `async def` for non-blocking routes.
|
|
13
13
|
- **04_request_data.py**: accessing query args and form data.
|
|
14
14
|
|
|
15
|
+
## Security & Authentication
|
|
16
|
+
|
|
17
|
+
Learn how to protect your application.
|
|
18
|
+
|
|
19
|
+
- **17_jwt_auth.py**: Standard JWT authentication using the Authorization header.
|
|
20
|
+
- **18_jwt_cookies.py**: Secure JWT implementation using HttpOnly cookies.
|
|
21
|
+
- **11_security_demo.py**: Implementing security headers.
|
|
22
|
+
- **10_rate_limit_demo.py**: Using the built-in rate limiter to prevent abuse.
|
|
23
|
+
|
|
15
24
|
## Data & Validation
|
|
16
25
|
|
|
17
26
|
Learn how to robustly handle input.
|
|
@@ -27,8 +36,6 @@ For production-grade applications.
|
|
|
27
36
|
|
|
28
37
|
- **06_blueprints.py**: Organizing your app into modules.
|
|
29
38
|
- **14_middleware.py**: Custom request/response hooks.
|
|
30
|
-
- **10_rate_limit_demo.py**: Using the built-in rate limiter to prevent abuse.
|
|
31
|
-
- **11_security_demo.py**: Implementing security headers.
|
|
32
39
|
|
|
33
40
|
## Database & Templates
|
|
34
41
|
|
|
@@ -44,7 +44,8 @@ if __name__ == "__main__":
|
|
|
44
44
|
- **Multiprocessing** - `workers=4` for parallel request handling on Linux
|
|
45
45
|
- **JWT Authentication** - Built-in token-based auth
|
|
46
46
|
- **Templates** - Jinja2 template rendering
|
|
47
|
-
-
|
|
47
|
+
- **Blueprints** - Modular app organization
|
|
48
|
+
- **Auto-Documentation** - Instant OpenAPI/Swagger & ReDoc UI
|
|
48
49
|
|
|
49
50
|
---
|
|
50
51
|
|
|
@@ -79,3 +80,4 @@ Supports Python **3.10 - 3.14** on Linux, macOS, and Windows.
|
|
|
79
80
|
- [Turbo Routes](user-guide/turbo-routes.md) - Maximum performance
|
|
80
81
|
- [Multiprocessing](user-guide/multiprocessing.md) - Scale to 100k+ RPS
|
|
81
82
|
- [JWT Auth](user-guide/jwt.md) - Secure your API
|
|
83
|
+
- [Auto-Documentation](user-guide/documentation.md) - Swagger & ReDoc
|