bustapi 0.13.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.13.1/.github/FUNDING.yml +4 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/CHANGELOG.md +6 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/Cargo.lock +15 -41
- {bustapi-0.13.0 → bustapi-0.13.1}/Cargo.toml +12 -12
- {bustapi-0.13.0 → bustapi-0.13.1}/PKG-INFO +6 -6
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/changelog.md +6 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/pyproject.toml +6 -6
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/__init__.py +1 -1
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/app.py +8 -2
- {bustapi-0.13.0 → bustapi-0.13.1}/src/bindings/request.rs +2 -2
- {bustapi-0.13.0 → bustapi-0.13.1}/src/bindings/websocket.rs +2 -2
- {bustapi-0.13.0 → bustapi-0.13.1}/src/rate_limiter.rs +1 -1
- {bustapi-0.13.0 → bustapi-0.13.1}/src/server/stream.rs +35 -42
- {bustapi-0.13.0 → bustapi-0.13.1}/src/websocket/config.rs +1 -1
- bustapi-0.13.0/.github/FUNDING.yml +0 -3
- {bustapi-0.13.0 → bustapi-0.13.1}/- +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/.github/workflows/ci-multiplatform.yml +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/.github/workflows/ci.yml +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/.github/workflows/docs.yml +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/.github/workflows/manual-publish.yml +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/.gitignore +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/.python-version +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/Dockerfile +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/LICENSE +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/README.md +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/benchmarks/CACHE_BENCHMARK.md +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/benchmarks/README.md +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/benchmarks/app.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/benchmarks/benchmark_all.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/benchmarks/benchmark_avg.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/benchmarks/benchmark_cache.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/benchmarks/benchmark_combined.png +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/benchmarks/bustapi.md +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/benchmarks/bustapi_bench.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/benchmarks/bustapi_internal.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/benchmarks/comparison_bench.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/benchmarks/comprehensive_benchmark.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/benchmarks/gen_graph.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/benchmarks/quick_bench.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/benchmarks/resource_bench.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/benchmarks/rps_comparison.png +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/benchmarks/run_comparison_auto.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/benchmarks/ws_benchmark.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/check_path.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/create_issues.sh +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/advanced/async.md +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/advanced/blueprints.md +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/advanced/dependency_injection.md +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/advanced/deployment.md +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/advanced/middleware.md +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/advanced/security.md +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/advanced/validation.md +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/api-reference.md +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/assets/logo.png +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/complete-api-reference.md +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/deployment-performance-guide.md +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/deployment.md +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/examples-guide.md +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/index.md +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/installation.md +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/overrides/.gitkeep +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/quickstart.md +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/release_track.md +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/site/advanced/async_support.html +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/site/advanced/blueprints.html +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/site/advanced/dependency_injection.html +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/site/advanced/middleware.html +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/site/advanced/validation.html +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/site/api/all.html +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/site/api/app.html +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/site/api/context.html +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/site/api/utilities.html +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/site/assets/logo.png +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/site/changelog.html +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/site/core_concepts/request_data.html +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/site/core_concepts/responses.html +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/site/core_concepts/routing.html +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/site/core_concepts/templates.html +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/site/examples/index.html +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/site/getting_started/index.html +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/site/getting_started/quickstart.html +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/site/index.html +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/site/script.js +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/site/style.css +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/stylesheets/extra.css +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/user-guide/authentication.md +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/user-guide/caching.md +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/user-guide/cli.md +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/user-guide/database.md +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/user-guide/documentation.md +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/user-guide/error_handling.md +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/user-guide/jwt.md +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/user-guide/logging.md +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/user-guide/multiprocessing.md +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/user-guide/request_data.md +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/user-guide/responses.md +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/user-guide/routing.md +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/user-guide/sessions.md +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/user-guide/static_files.md +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/user-guide/templates.md +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/user-guide/turbo-routes.md +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/user-guide/video-streaming.md +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/docs/websockets.md +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/examples/advanced/08_auto_docs.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/examples/advanced/12_test_modes.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/examples/advanced/13_error_handling.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/examples/advanced/14_middleware.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/examples/advanced/16_middleware_session.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/examples/advanced/20_file_uploads.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/examples/advanced/24_body_and_depends.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/examples/advanced/27_video_stream.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/examples/advanced/28_websocket.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/examples/advanced/29_turbo_websocket.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/examples/basics/01_hello_world.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/examples/basics/02_parameters.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/examples/basics/03_async.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/examples/basics/04_request_data.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/examples/basics/19_all_types.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/examples/database/07_database_raw.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/examples/database/10_database_sqlmodel.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/examples/routing/06_blueprints.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/examples/routing/09_complex_routing.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/examples/routing/21_path_validation.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/examples/routing/22_path_docs.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/examples/routing/23_query_validation.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/examples/routing/blueprint_with_jwt.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/examples/security/10_rate_limit_demo.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/examples/security/11_security_demo.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/examples/security/17_jwt_auth.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/examples/security/17_safe_features.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/examples/security/18_jwt_cookies.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/examples/security/18_safe_advanced.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/examples/security/18_session_login.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/examples/templates/05_templates.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/examples/templates/26_complex_template.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/examples/templates/templates/index.html +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/examples/turbo/cache_test.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/examples/turbo/fair_benchmark.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/examples/turbo/typed_turbo_example.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/examples/ws/app.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/examples/ws/templates/index.html +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/examples/ws/websockets_demo.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/examples/ws/ws_limit.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/mkdocs.yml +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/auth/__init__.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/auth/csrf.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/auth/decorators.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/auth/login.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/auth/password.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/auth/tokens.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/auth/user.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/cli/__init__.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/cli/main.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/context.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/core/__init__.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/core/asgi.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/core/exceptions.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/core/helpers.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/core/logging.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/dependencies.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/dispatch.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/documentation/__init__.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/documentation/generator.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/extraction.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/fastapi_compat.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/hooks.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/http/__init__.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/http/request.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/http/response.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/jwt.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/logging.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/middleware.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/multiprocess.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/params.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/py.typed +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/responses.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/routing/__init__.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/routing/blueprints.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/routing/decorators.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/safe/__init__.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/safe/concurrency.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/safe/types.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/security/__init__.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/security/extension.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/security/rate_limit.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/server/__init__.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/server/runner.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/server/wsgi.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/sessions.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/templating/__init__.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/templating/engine.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/templating/mixin.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/testing/__init__.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/testing/client.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/utils.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/python/bustapi/websocket.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/run_all_examples.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/scratch/test_abort.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/scratch/test_headers.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/src/bindings/app.rs +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/src/bindings/converters.rs +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/src/bindings/handlers.rs +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/src/bindings/mod.rs +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/src/bindings/typed_turbo.rs +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/src/crypto.rs +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/src/jwt.rs +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/src/lib.rs +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/src/logger.rs +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/src/request/methods.rs +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/src/request/mod.rs +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/src/request/tests.rs +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/src/response/builders.rs +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/src/response/methods.rs +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/src/response/mod.rs +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/src/router/handlers.rs +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/src/router/matching.rs +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/src/router/middleware.rs +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/src/router/mod.rs +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/src/router/tests.rs +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/src/server/handlers.rs +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/src/server/mod.rs +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/src/server/startup.rs +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/src/static_files.rs +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/src/templating.rs +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/src/watcher.rs +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/src/websocket/mod.rs +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/src/websocket/session.rs +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/src/websocket/turbo.rs +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/static/style.css +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/templates/base.html +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/templates/complex.html +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/test_trim.rs +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/tests/docs_test_all.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/tests/docs_test_api_reference.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/tests/docs_test_installation.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/tests/docs_test_quickstart.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/tests/docs_test_simple.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/tests/test_050_features.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/tests/test_async_hooks.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/tests/test_async_login.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/tests/test_auth.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/tests/test_examples.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/tests/test_hot_reload.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/tests/test_issue_18.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/tests/test_jwt.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/tests/test_jwt_cookies.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/tests/test_login_manager.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/tests/test_middleware.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/tests/test_multiprocess_stability.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/tests/test_new_examples.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/tests/test_orm_conflict.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/tests/test_path_standalone.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/tests/test_path_validation.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/tests/test_rate_limit_rust.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/tests/test_safe.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/tests/test_security_unit.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/tests/test_sessions.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/tests/test_zero_copy.py +0 -0
- {bustapi-0.13.0 → bustapi-0.13.1}/tests/verify_router.py +0 -0
|
@@ -2,6 +2,12 @@
|
|
|
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
|
+
|
|
5
11
|
## [0.13.0] - 2026-05-02
|
|
6
12
|
|
|
7
13
|
### Added
|
|
@@ -438,7 +438,7 @@ checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb"
|
|
|
438
438
|
|
|
439
439
|
[[package]]
|
|
440
440
|
name = "bustapi_core"
|
|
441
|
-
version = "0.13.
|
|
441
|
+
version = "0.13.1"
|
|
442
442
|
dependencies = [
|
|
443
443
|
"actix-files",
|
|
444
444
|
"actix-http",
|
|
@@ -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"
|
|
@@ -1478,15 +1469,6 @@ version = "0.3.3"
|
|
|
1478
1469
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1479
1470
|
checksum = "38d1115007560874e373613744c6fba374c17688327a71c1476d1a5954cc857b"
|
|
1480
1471
|
|
|
1481
|
-
[[package]]
|
|
1482
|
-
name = "memoffset"
|
|
1483
|
-
version = "0.9.1"
|
|
1484
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1485
|
-
checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
|
|
1486
|
-
dependencies = [
|
|
1487
|
-
"autocfg",
|
|
1488
|
-
]
|
|
1489
|
-
|
|
1490
1472
|
[[package]]
|
|
1491
1473
|
name = "mimalloc"
|
|
1492
1474
|
version = "0.1.50"
|
|
@@ -1751,28 +1733,26 @@ dependencies = [
|
|
|
1751
1733
|
|
|
1752
1734
|
[[package]]
|
|
1753
1735
|
name = "pyo3"
|
|
1754
|
-
version = "0.
|
|
1736
|
+
version = "0.28.3"
|
|
1755
1737
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1756
|
-
checksum = "
|
|
1738
|
+
checksum = "91fd8e38a3b50ed1167fb981cd6fd60147e091784c427b8f7183a7ee32c31c12"
|
|
1757
1739
|
dependencies = [
|
|
1758
|
-
"indoc",
|
|
1759
1740
|
"libc",
|
|
1760
|
-
"memoffset",
|
|
1761
1741
|
"once_cell",
|
|
1762
1742
|
"portable-atomic",
|
|
1763
1743
|
"pyo3-build-config",
|
|
1764
1744
|
"pyo3-ffi",
|
|
1765
1745
|
"pyo3-macros",
|
|
1766
|
-
"unindent",
|
|
1767
1746
|
]
|
|
1768
1747
|
|
|
1769
1748
|
[[package]]
|
|
1770
1749
|
name = "pyo3-async-runtimes"
|
|
1771
|
-
version = "0.
|
|
1750
|
+
version = "0.28.0"
|
|
1772
1751
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1773
|
-
checksum = "
|
|
1752
|
+
checksum = "9e7364a95bf00e8377bbf9b0f09d7ff9715a29d8fcf93b47d1a967363b973178"
|
|
1774
1753
|
dependencies = [
|
|
1775
|
-
"futures",
|
|
1754
|
+
"futures-channel",
|
|
1755
|
+
"futures-util",
|
|
1776
1756
|
"once_cell",
|
|
1777
1757
|
"pin-project-lite",
|
|
1778
1758
|
"pyo3",
|
|
@@ -1781,18 +1761,18 @@ dependencies = [
|
|
|
1781
1761
|
|
|
1782
1762
|
[[package]]
|
|
1783
1763
|
name = "pyo3-build-config"
|
|
1784
|
-
version = "0.
|
|
1764
|
+
version = "0.28.3"
|
|
1785
1765
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1786
|
-
checksum = "
|
|
1766
|
+
checksum = "e368e7ddfdeb98c9bca7f8383be1648fd84ab466bf2bc015e94008db6d35611e"
|
|
1787
1767
|
dependencies = [
|
|
1788
1768
|
"target-lexicon",
|
|
1789
1769
|
]
|
|
1790
1770
|
|
|
1791
1771
|
[[package]]
|
|
1792
1772
|
name = "pyo3-ffi"
|
|
1793
|
-
version = "0.
|
|
1773
|
+
version = "0.28.3"
|
|
1794
1774
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1795
|
-
checksum = "
|
|
1775
|
+
checksum = "7f29e10af80b1f7ccaf7f69eace800a03ecd13e883acfacc1e5d0988605f651e"
|
|
1796
1776
|
dependencies = [
|
|
1797
1777
|
"libc",
|
|
1798
1778
|
"pyo3-build-config",
|
|
@@ -1800,9 +1780,9 @@ dependencies = [
|
|
|
1800
1780
|
|
|
1801
1781
|
[[package]]
|
|
1802
1782
|
name = "pyo3-macros"
|
|
1803
|
-
version = "0.
|
|
1783
|
+
version = "0.28.3"
|
|
1804
1784
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1805
|
-
checksum = "
|
|
1785
|
+
checksum = "df6e520eff47c45997d2fc7dd8214b25dd1310918bbb2642156ef66a67f29813"
|
|
1806
1786
|
dependencies = [
|
|
1807
1787
|
"proc-macro2",
|
|
1808
1788
|
"pyo3-macros-backend",
|
|
@@ -1812,9 +1792,9 @@ dependencies = [
|
|
|
1812
1792
|
|
|
1813
1793
|
[[package]]
|
|
1814
1794
|
name = "pyo3-macros-backend"
|
|
1815
|
-
version = "0.
|
|
1795
|
+
version = "0.28.3"
|
|
1816
1796
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1817
|
-
checksum = "
|
|
1797
|
+
checksum = "c4cdc218d835738f81c2338f822078af45b4afdf8b2e33cbb5916f108b813acb"
|
|
1818
1798
|
dependencies = [
|
|
1819
1799
|
"heck",
|
|
1820
1800
|
"proc-macro2",
|
|
@@ -2401,12 +2381,6 @@ version = "0.2.6"
|
|
|
2401
2381
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2402
2382
|
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
|
|
2403
2383
|
|
|
2404
|
-
[[package]]
|
|
2405
|
-
name = "unindent"
|
|
2406
|
-
version = "0.2.4"
|
|
2407
|
-
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
2408
|
-
checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3"
|
|
2409
|
-
|
|
2410
2384
|
[[package]]
|
|
2411
2385
|
name = "universal-hash"
|
|
2412
2386
|
version = "0.5.1"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "bustapi_core"
|
|
3
|
-
version = "0.13.
|
|
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.13.
|
|
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'
|
|
@@ -2,6 +2,12 @@
|
|
|
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
|
+
|
|
5
11
|
## [0.13.0] - 2026-05-02
|
|
6
12
|
|
|
7
13
|
### Added
|
|
@@ -4,7 +4,7 @@ build-backend = "maturin"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "bustapi"
|
|
7
|
-
version = "0.13.
|
|
7
|
+
version = "0.13.1"
|
|
8
8
|
description = "High-performance Python web framework with Rust backend"
|
|
9
9
|
authors = [
|
|
10
10
|
{name = "GrandpaEJ", email = ""}
|
|
@@ -36,23 +36,23 @@ dependencies = [
|
|
|
36
36
|
dev = [
|
|
37
37
|
"black>=24.8.0",
|
|
38
38
|
"isort>=5.13.2",
|
|
39
|
-
"maturin>=1.
|
|
39
|
+
"maturin>=1.13.1",
|
|
40
40
|
"pytest>=8.3.5",
|
|
41
41
|
"pytest-asyncio>=0.24.0",
|
|
42
42
|
"pytest-cov>=5.0.0",
|
|
43
|
-
"ruff>=0.12
|
|
43
|
+
"ruff>=0.15.12",
|
|
44
44
|
"mypy>=1.0",
|
|
45
45
|
"pre-commit>=3.0",
|
|
46
46
|
"sqlmodel>=0.0.16",
|
|
47
47
|
"psutil>=5.9.0",
|
|
48
|
-
"requests>=2.
|
|
48
|
+
"requests>=2.33.1",
|
|
49
49
|
]
|
|
50
50
|
|
|
51
51
|
benchmarks = [
|
|
52
|
-
"uvicorn>=0.
|
|
52
|
+
"uvicorn>=0.46.0",
|
|
53
53
|
"catzilla>=0.2.0",
|
|
54
54
|
"flask>=3.1.2",
|
|
55
|
-
"fastapi>=0.
|
|
55
|
+
"fastapi>=0.136.1",
|
|
56
56
|
"gunicorn>=23.0.0",
|
|
57
57
|
"httpx>=0.28.1",
|
|
58
58
|
|
|
@@ -223,10 +223,16 @@ class BustAPI(
|
|
|
223
223
|
self.logger.error(f"Error in 404 fallback: {e}")
|
|
224
224
|
return ("Not Found", 404, {"Content-Type": "text/plain"})
|
|
225
225
|
|
|
226
|
-
def _response_to_rust_format(self, response: Response) ->
|
|
226
|
+
def _response_to_rust_format(self, response: Response) -> Any:
|
|
227
227
|
"""
|
|
228
|
-
Convert Python Response object to format expected by Rust
|
|
228
|
+
Convert Python Response object to format expected by Rust.
|
|
229
|
+
If it's a special response (Streaming, File), return the object itself.
|
|
230
|
+
Otherwise return (body, status, headers) tuple.
|
|
229
231
|
"""
|
|
232
|
+
# Preserve special response types for Rust backend
|
|
233
|
+
if hasattr(response, "content") or hasattr(response, "path"):
|
|
234
|
+
return response
|
|
235
|
+
|
|
230
236
|
if hasattr(response, "get_data"):
|
|
231
237
|
body = response.get_data()
|
|
232
238
|
else:
|
|
@@ -9,13 +9,13 @@ use crate::bindings::converters::*;
|
|
|
9
9
|
use pyo3::types::PyBytes;
|
|
10
10
|
|
|
11
11
|
/// Python wrapper for HTTP requests
|
|
12
|
-
#[pyclass]
|
|
12
|
+
#[pyclass(skip_from_py_object)]
|
|
13
13
|
pub struct PyRequest {
|
|
14
14
|
pub(crate) inner: crate::request::RequestData,
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
/// Python wrapper for uploaded files
|
|
18
|
-
#[pyclass]
|
|
18
|
+
#[pyclass(from_py_object)]
|
|
19
19
|
#[derive(Clone)]
|
|
20
20
|
pub struct PyUploadedFile {
|
|
21
21
|
filename: String,
|
|
@@ -8,7 +8,7 @@ use tokio::sync::mpsc;
|
|
|
8
8
|
use crate::websocket::WebSocketMessage;
|
|
9
9
|
|
|
10
10
|
/// Python-accessible WebSocket session wrapper
|
|
11
|
-
#[pyclass(name = "WebSocketConnection")]
|
|
11
|
+
#[pyclass(name = "WebSocketConnection", from_py_object)]
|
|
12
12
|
#[derive(Clone)]
|
|
13
13
|
pub struct PyWebSocketConnection {
|
|
14
14
|
/// Session ID
|
|
@@ -66,7 +66,7 @@ impl PyWebSocketConnection {
|
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
/// Python callable WebSocket handler wrapper
|
|
69
|
-
#[pyclass(name = "WebSocketHandler")]
|
|
69
|
+
#[pyclass(name = "WebSocketHandler", skip_from_py_object)]
|
|
70
70
|
pub struct PyWebSocketHandler {
|
|
71
71
|
/// Python handler callback
|
|
72
72
|
handler: Py<PyAny>,
|
|
@@ -4,7 +4,7 @@ use std::sync::Arc;
|
|
|
4
4
|
use std::time::{SystemTime, UNIX_EPOCH};
|
|
5
5
|
|
|
6
6
|
/// A high-performance rate limiter using DashMap for concurrent access
|
|
7
|
-
#[pyclass(name = "PyRateLimiter")]
|
|
7
|
+
#[pyclass(name = "PyRateLimiter", from_py_object)]
|
|
8
8
|
#[derive(Clone)]
|
|
9
9
|
pub struct PyRateLimiter {
|
|
10
10
|
// key -> (timestamp, count)
|
|
@@ -20,7 +20,7 @@ pub struct PythonStream {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
// Safety: Py<PyAny> is generally Send if we hold the GIL when accessing it,
|
|
23
|
-
// and we are using spawn_blocking
|
|
23
|
+
// and we are using spawn_blocking which handles thread safety.
|
|
24
24
|
unsafe impl Send for PythonStream {}
|
|
25
25
|
|
|
26
26
|
impl PythonStream {
|
|
@@ -79,56 +79,49 @@ impl Stream for PythonStream {
|
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
StreamMode::Async => {
|
|
82
|
-
// Async Iterator: Use
|
|
82
|
+
// Async Iterator: Use BustAPI's async_to_sync to run on background loop
|
|
83
83
|
Box::pin(async move {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
// Process the item (must re-acquire GIL to inspect item?)
|
|
108
|
-
// item is PyObject (or whatever into_future returns? default is PyObject)
|
|
109
|
-
let item_obj: Py<PyAny> = item;
|
|
110
|
-
Python::attach(|py| {
|
|
111
|
-
process_item(py, item_obj.into_bound(py))
|
|
112
|
-
})
|
|
84
|
+
let res = tokio::task::spawn_blocking(move || {
|
|
85
|
+
Python::attach(|py| {
|
|
86
|
+
let iter_bound = iterator.bind(py);
|
|
87
|
+
match iter_bound.call_method0("__anext__") {
|
|
88
|
+
Ok(awaitable) => {
|
|
89
|
+
if let Ok(utils) = py.import("bustapi.utils") {
|
|
90
|
+
match utils.call_method1("async_to_sync", (awaitable,))
|
|
91
|
+
{
|
|
92
|
+
Ok(item) => process_item(py, item),
|
|
93
|
+
Err(e) => {
|
|
94
|
+
if e.is_instance_of::<PyStopAsyncIteration>(py)
|
|
95
|
+
{
|
|
96
|
+
None
|
|
97
|
+
} else {
|
|
98
|
+
Some(Err(e))
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
} else {
|
|
103
|
+
Some(Err(PyErr::new::<PyRuntimeError, _>(
|
|
104
|
+
"Could not import bustapi.utils",
|
|
105
|
+
)))
|
|
106
|
+
}
|
|
113
107
|
}
|
|
114
|
-
Err(e) =>
|
|
108
|
+
Err(e) => {
|
|
115
109
|
if e.is_instance_of::<PyStopAsyncIteration>(py) {
|
|
116
110
|
None
|
|
117
111
|
} else {
|
|
118
112
|
Some(Err(e))
|
|
119
113
|
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
Err(e) => Python::attach(|py| {
|
|
124
|
-
if e.is_instance_of::<PyStopAsyncIteration>(py) {
|
|
125
|
-
None
|
|
126
|
-
} else {
|
|
127
|
-
Some(Err(e))
|
|
114
|
+
}
|
|
128
115
|
}
|
|
129
|
-
})
|
|
116
|
+
})
|
|
117
|
+
})
|
|
118
|
+
.await;
|
|
119
|
+
|
|
120
|
+
match res {
|
|
121
|
+
Ok(ok) => ok,
|
|
122
|
+
Err(_) => Some(Err(PyErr::new::<PyRuntimeError, _>("Task Join Error"))),
|
|
130
123
|
}
|
|
131
|
-
})
|
|
124
|
+
}) as StreamFuture
|
|
132
125
|
}
|
|
133
126
|
};
|
|
134
127
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|