fasthttp-client 1.2.2__tar.gz → 1.2.3__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.
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.github/workflows/labeler.yml +1 -1
- fasthttp_client-1.2.3/.github/workflows/welcome.yml +59 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/PKG-INFO +4 -1
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/reference/response.md +41 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/response-handling.md +22 -0
- fasthttp_client-1.2.3/docs/ru/reference/response.md +86 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/response-handling.md +22 -0
- fasthttp_client-1.2.3/examples/basic/extract_assets.py +24 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/__init__.py +3 -1
- fasthttp_client-1.2.3/fasthttp/__meta__.py +1 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/app.py +8 -5
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/client.py +4 -1
- fasthttp_client-1.2.3/fasthttp/helpers/route_inspect.py +156 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/helpers/routing.py +0 -46
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/openapi/routes.py +9 -9
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/openapi/swagger.py +184 -8
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/response.py +45 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/routing.py +2 -4
- fasthttp_client-1.2.3/fasthttp/status.py +177 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/pyproject.toml +4 -1
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/tests/test_app.py +1 -1
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/uv.lock +442 -1
- fasthttp_client-1.2.2/.github/workflows/welcome.yml +0 -47
- fasthttp_client-1.2.2/docs/ru/reference/response.md +0 -45
- fasthttp_client-1.2.2/fasthttp/__meta__.py +0 -1
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.all-contributorsrc +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.github/DISCUSSION_TEMPLATE/general.yml +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.github/DISCUSSION_TEMPLATE/ideas.yml +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.github/ISSUE_TEMPLATE/question.yml +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.github/dependabot.yml +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.github/labeler.yml +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.github/stale.yml +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.github/workflows/all-contributors.yml +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.github/workflows/cleanup.yml +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.github/workflows/codeql.yml +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.github/workflows/codspeed.yml +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.github/workflows/coverage.yml +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.github/workflows/release.yml +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.github/workflows/scorecard.yml +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.github/workflows/tests.yml +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.gitignore +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.python-version +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.readthedocs.yaml +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/AUTHORS.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/CHANGELOG.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/CODE_OF_CONDUCT.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/CONTRIBUTING.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/LICENSE +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/MANIFEST.in +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/README.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/SECURITY.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/blog/how-i-created-fasthttp.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/blog/istoriya-sozdaniya-fasthttp.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/about/index.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/api-reference.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/cli/commands.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/cli/index.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/cli/options.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/cli.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/configuration.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/dependencies.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/examples.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/graphql.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/http2-support.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/index.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/learn/index.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/learn/python-types.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/middleware.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/openapi.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/pydantic-validation.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/python-types.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/quick-start.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/reference/cli.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/reference/dependencies.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/reference/fasthttp.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/reference/index.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/reference/middleware.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/request-signing.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/security.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/configuration/environment.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/configuration/headers.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/configuration/http2.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/configuration/index.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/configuration/logging.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/configuration/proxy.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/configuration/settings.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/configuration/timeouts.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/dependencies.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/first-steps.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/graphql/index.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/graphql/mutations.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/graphql/queries.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/http-methods.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/index.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/lifespan.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/middleware/creating.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/middleware/examples.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/middleware/index.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/openapi/index.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/openapi/swagger-ui.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/parallel-execution.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/request-parameters.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/routers.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/security/circuit-breaker.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/security/index.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/security/secrets-masking.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/security/ssrf-protection.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/tags.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/validation/error-validation.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/validation/index.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/validation/pydantic-validation.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/validation/request-validation.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/index.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/logo.png +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/photo/404_not_found.png +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/photo/swagger_ui_check_execute.png +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/photo/swagger_ui_check_web.png +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/photo/swagger_ui_home.png +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/about/index.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/api-reference.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/cli/commands.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/cli/index.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/cli/options.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/cli.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/configuration.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/dependencies.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/examples.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/graphql.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/http2-support.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/index.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/learn/index.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/learn/python-types.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/middleware.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/openapi.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/pydantic-validation.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/quick-start.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/reference/cli.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/reference/dependencies.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/reference/fasthttp.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/reference/index.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/reference/middleware.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/request-signing.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/security.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/configuration/environment.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/configuration/headers.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/configuration/http2.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/configuration/index.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/configuration/logging.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/configuration/proxy.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/configuration/settings.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/configuration/timeouts.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/dependencies.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/first-steps.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/graphql/index.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/graphql/mutations.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/graphql/queries.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/http-methods.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/index.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/lifespan.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/middleware/creating.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/middleware/examples.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/middleware/index.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/openapi/index.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/openapi/swagger-ui.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/parallel-execution.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/request-parameters.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/routers.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/security/circuit-breaker.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/security/index.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/security/secrets-masking.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/security/ssrf-protection.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/tags.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/validation/error-validation.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/validation/index.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/validation/pydantic-validation.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/validation/request-validation.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/README.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/advanced/error_handling.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/advanced/redirect_test.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/basic/defaults_example.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/basic/full_crud.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/basic/response_request_info.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/basic/test_delete.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/basic/test_get.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/basic/test_patch.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/basic/test_post.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/basic/test_put.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/data/form_data.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/dependencies/basic_dependencies.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/dependencies/with_cache_scope.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/endpoints/get_ip.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/endpoints/jsonplaceholder_get.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/endpoints/jsonplaceholder_posts.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/endpoints/multiple_endpoints.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/error/bad_status_codes.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/error/connection_error.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/error/invalid_url.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/error/not_found_site.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/error/responses.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/error/server_errors.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/error/successful_request.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/error/timeout_error.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/error/validation_error.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/graphql/pokemon.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/graphql/rick_and_morty.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/graphql/run_examples.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/graphql/star_wars.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/headers/headers.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/headers/user_agent.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/http2/README.md +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/http2/http2_example.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/methods/json_post.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/middleware/basic_middleware.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/middleware/error_middleware.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/middleware/response_transformer.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/openapi/openapi_example.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/parameters/delay_response.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/parameters/query_params.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/parameters/query_params_example.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/parameters/timeout_example.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/pydantic/advanced_validation.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/pydantic/basic_validation.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/pydantic/create_and_validate.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/pydantic/crud_with_validation.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/pydantic/nested_models.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/routers/base.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/run_all.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/tags/basic_tags.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/cli/__init__.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/cli/client.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/cli/commands.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/cli/main.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/cli/output.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/cli/repl.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/dependencies/__init__.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/dependencies/dependencies.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/exceptions/__init__.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/exceptions/base.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/exceptions/connect.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/exceptions/request.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/exceptions/status.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/exceptions/timeout.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/exceptions/types.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/exceptions/validator.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/graphql/__init__.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/graphql/client.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/graphql/types.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/helpers/__init__.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/logging.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/middleware.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/openapi/__init__.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/openapi/generator.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/openapi/urls.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/py.typed +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/security/__init__.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/security/circuit_breaker.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/security/headers.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/security/limits.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/security/redirect.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/security/response.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/security/secrets.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/security/security.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/security/signer.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/security/ssrf.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/types.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/mkdocs.yml +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/scripts/Makefile +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/tests/__init__.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/tests/conftest.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/tests/test_cli.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/tests/test_client.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/tests/test_dependencies.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/tests/test_exceptions.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/tests/test_graphql.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/tests/test_openapi.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/tests/test_performance.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/tests/test_response.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/tests/test_security.py +0 -0
- {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/tests/test_types.py +0 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
name: Welcome Bot
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
types: [opened, synchronize]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
pull-requests: write
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
welcome:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- name: Welcome contributor
|
|
15
|
+
uses: actions/github-script@v8
|
|
16
|
+
with:
|
|
17
|
+
script: |
|
|
18
|
+
const owner = context.repo.owner;
|
|
19
|
+
const repo = context.repo.repo;
|
|
20
|
+
const prNumber = context.payload.pull_request.number;
|
|
21
|
+
const sender = context.payload.sender.login;
|
|
22
|
+
const marker = '<!-- welcome-bot -->';
|
|
23
|
+
|
|
24
|
+
const message = `${marker}
|
|
25
|
+
👋 # Thanks for your contribution, @${sender}!
|
|
26
|
+
|
|
27
|
+
Please make sure:
|
|
28
|
+
- Code is clean and formatted
|
|
29
|
+
- Tests are passing
|
|
30
|
+
- PR description is clear
|
|
31
|
+
|
|
32
|
+
Maintainers will review it soon.
|
|
33
|
+
`;
|
|
34
|
+
|
|
35
|
+
const { data: comments } = await github.rest.issues.listComments({
|
|
36
|
+
owner,
|
|
37
|
+
repo,
|
|
38
|
+
issue_number: prNumber
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
const existingComment = comments.find(comment =>
|
|
42
|
+
comment.body.includes(marker)
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
if (existingComment) {
|
|
46
|
+
await github.rest.issues.updateComment({
|
|
47
|
+
owner,
|
|
48
|
+
repo,
|
|
49
|
+
comment_id: existingComment.id,
|
|
50
|
+
body: message
|
|
51
|
+
});
|
|
52
|
+
} else {
|
|
53
|
+
await github.rest.issues.createComment({
|
|
54
|
+
owner,
|
|
55
|
+
repo,
|
|
56
|
+
issue_number: prNumber,
|
|
57
|
+
body: message
|
|
58
|
+
});
|
|
59
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fasthttp-client
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.3
|
|
4
4
|
Summary: Fast and simple HTTP client library with async support and beautiful logging
|
|
5
5
|
Project-URL: Homepage, https://github.com/ndugram/fasthttp
|
|
6
6
|
Project-URL: Documentation, https://github.com/ndugram/fasthttp
|
|
@@ -34,8 +34,11 @@ Requires-Dist: typer>=0.24.1
|
|
|
34
34
|
Requires-Dist: uvicorn>=0.42.0
|
|
35
35
|
Provides-Extra: dev
|
|
36
36
|
Requires-Dist: aiohttp>=3.9.0; extra == 'dev'
|
|
37
|
+
Requires-Dist: mkdocs-material>=9.5.0; extra == 'dev'
|
|
38
|
+
Requires-Dist: mkdocs>=1.6.0; extra == 'dev'
|
|
37
39
|
Requires-Dist: mypy>=1.13.0; extra == 'dev'
|
|
38
40
|
Requires-Dist: pre-commit>=4.0.0; extra == 'dev'
|
|
41
|
+
Requires-Dist: pymdown-extensions>=10.2; extra == 'dev'
|
|
39
42
|
Requires-Dist: pytest-asyncio>=0.24.0; extra == 'dev'
|
|
40
43
|
Requires-Dist: pytest-codspeed>=4.3.0; extra == 'dev'
|
|
41
44
|
Requires-Dist: pytest-cov>=6.0.0; extra == 'dev'
|
|
@@ -11,6 +11,7 @@ Response object reference.
|
|
|
11
11
|
| `headers` | `dict` | Response headers |
|
|
12
12
|
| `content` | `bytes` | Raw bytes |
|
|
13
13
|
| `method` | `str` | HTTP method |
|
|
14
|
+
| `url` | `str` | Request URL |
|
|
14
15
|
|
|
15
16
|
## Methods
|
|
16
17
|
|
|
@@ -38,6 +39,46 @@ Get request body as text:
|
|
|
38
39
|
sent = resp.req_text() # Returns str or None
|
|
39
40
|
```
|
|
40
41
|
|
|
42
|
+
### assets()
|
|
43
|
+
|
|
44
|
+
Extract CSS and JavaScript asset URLs from HTML response:
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
result = resp.assets()
|
|
48
|
+
# Returns: {"css": [...], "js": [...]}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
**Parameters:**
|
|
52
|
+
|
|
53
|
+
| Parameter | Type | Default | Description |
|
|
54
|
+
|-----------|------|---------|-------------|
|
|
55
|
+
| `css` | `bool` | `True` | Include CSS links |
|
|
56
|
+
| `js` | `bool` | `True` | Include JavaScript links |
|
|
57
|
+
|
|
58
|
+
**Examples:**
|
|
59
|
+
|
|
60
|
+
```python
|
|
61
|
+
# Get all assets (CSS + JS)
|
|
62
|
+
@app.get(url="https://example.com")
|
|
63
|
+
async def handler(resp: Response):
|
|
64
|
+
return resp.assets()
|
|
65
|
+
# Returns: {"css": ["https://example.com/style.css"], "js": ["https://example.com/app.js"]}
|
|
66
|
+
|
|
67
|
+
# CSS only
|
|
68
|
+
@app.get(url="https://example.com")
|
|
69
|
+
async def handler(resp: Response):
|
|
70
|
+
return resp.assets(js=False)
|
|
71
|
+
# Returns: {"css": [...], "js": []}
|
|
72
|
+
|
|
73
|
+
# JS only
|
|
74
|
+
@app.get(url="https://example.com")
|
|
75
|
+
async def handler(resp: Response):
|
|
76
|
+
return resp.assets(css=False)
|
|
77
|
+
# Returns: {"css": [], "js": [...]}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
The method parses `<link rel="stylesheet" href="...">` for CSS and `<script src="...">` for JavaScript. All URLs are normalized using `urljoin`, so relative paths are converted to absolute URLs based on the request URL.
|
|
81
|
+
|
|
41
82
|
## Example
|
|
42
83
|
|
|
43
84
|
```python
|
|
@@ -61,6 +61,28 @@ Returns request body as text:
|
|
|
61
61
|
sent = resp.req_text() # Returns "raw data"
|
|
62
62
|
```
|
|
63
63
|
|
|
64
|
+
### assets()
|
|
65
|
+
|
|
66
|
+
Extracts CSS and JavaScript asset URLs from HTML page:
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
# Get all assets
|
|
70
|
+
result = resp.assets()
|
|
71
|
+
# Returns: {"css": [...], "js": [...]}
|
|
72
|
+
|
|
73
|
+
# CSS only
|
|
74
|
+
css_only = resp.assets(js=False)
|
|
75
|
+
|
|
76
|
+
# JS only
|
|
77
|
+
js_only = resp.assets(css=False)
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
The method parses:
|
|
81
|
+
- CSS: `<link rel="stylesheet" href="...">` tags
|
|
82
|
+
- JS: `<script src="...">` tags
|
|
83
|
+
|
|
84
|
+
All URLs are normalized relative to the request URL.
|
|
85
|
+
|
|
64
86
|
## Error Handling
|
|
65
87
|
|
|
66
88
|
FastHTTP automatically handles errors and logs them:
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Класс Response
|
|
2
|
+
|
|
3
|
+
Объект ответа.
|
|
4
|
+
|
|
5
|
+
## Атрибуты
|
|
6
|
+
|
|
7
|
+
| Атрибут | Тип | Описание |
|
|
8
|
+
|---------|-----|----------|
|
|
9
|
+
| `status` | `int` | Код статуса HTTP |
|
|
10
|
+
| `text` | `str` | Сырое тело ответа |
|
|
11
|
+
| `headers` | `dict` | Заголовки ответа |
|
|
12
|
+
| `content` | `bytes` | Сырые байты |
|
|
13
|
+
| `method` | `str` | HTTP метод |
|
|
14
|
+
| `url` | `str` | URL запроса |
|
|
15
|
+
|
|
16
|
+
## Методы
|
|
17
|
+
|
|
18
|
+
### json()
|
|
19
|
+
|
|
20
|
+
Преобразовать тело ответа в JSON:
|
|
21
|
+
|
|
22
|
+
```python
|
|
23
|
+
data = resp.json() # Возвращает dict или list
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### req_json()
|
|
27
|
+
|
|
28
|
+
Получить JSON, отправленный с запросом:
|
|
29
|
+
|
|
30
|
+
```python
|
|
31
|
+
sent = resp.req_json() # Возвращает dict или None
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### assets()
|
|
35
|
+
|
|
36
|
+
Извлечь URL-адреса CSS и JavaScript ресурсов из HTML-ответа:
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
result = resp.assets()
|
|
40
|
+
# Возвращает: {"css": [...], "js": [...]}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**Параметры:**
|
|
44
|
+
|
|
45
|
+
| Параметр | Тип | По умолчанию | Описание |
|
|
46
|
+
|----------|-----|--------------|----------|
|
|
47
|
+
| `css` | `bool` | `True` | Включать ссылки CSS |
|
|
48
|
+
| `js` | `bool` | `True` | Включать ссылки JavaScript |
|
|
49
|
+
|
|
50
|
+
**Примеры:**
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
# Получить все ресурсы (CSS + JS)
|
|
54
|
+
@app.get(url="https://example.com")
|
|
55
|
+
async def handler(resp: Response):
|
|
56
|
+
return resp.assets()
|
|
57
|
+
# Возвращает: {"css": ["https://example.com/style.css"], "js": ["https://example.com/app.js"]}
|
|
58
|
+
|
|
59
|
+
# Только CSS
|
|
60
|
+
@app.get(url="https://example.com")
|
|
61
|
+
async def handler(resp: Response):
|
|
62
|
+
return resp.assets(js=False)
|
|
63
|
+
# Возвращает: {"css": [...], "js": []}
|
|
64
|
+
|
|
65
|
+
# Только JS
|
|
66
|
+
@app.get(url="https://example.com")
|
|
67
|
+
async def handler(resp: Response):
|
|
68
|
+
return resp.assets(css=False)
|
|
69
|
+
# Возвращает: {"css": [], "js": [...]}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Метод парсит `<link rel="stylesheet" href="...">` для CSS и `<script src="...">` для JavaScript. Все URL нормализуются через `urljoin`, поэтому относительные пути преобразуются в абсолютные на основе URL запроса.
|
|
73
|
+
|
|
74
|
+
## Пример
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
from fasthttp import FastHTTP
|
|
78
|
+
from fasthttp.response import Response
|
|
79
|
+
|
|
80
|
+
app = FastHTTP(debug=True)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
@app.get(url="https://api.example.com/data")
|
|
84
|
+
async def handler(resp: Response) -> dict:
|
|
85
|
+
return {"status": resp.status, "data": resp.json(), "headers": resp.headers}
|
|
86
|
+
```
|
|
@@ -52,6 +52,28 @@ text = resp.text # Возвращает str
|
|
|
52
52
|
sent = resp.req_json() # Возвращает {"name": "John"}
|
|
53
53
|
```
|
|
54
54
|
|
|
55
|
+
### assets()
|
|
56
|
+
|
|
57
|
+
Извлекает URL-адреса CSS и JavaScript ресурсов из HTML-страницы:
|
|
58
|
+
|
|
59
|
+
```python
|
|
60
|
+
# Получить все ресурсы
|
|
61
|
+
result = resp.assets()
|
|
62
|
+
# Returns: {"css": [...], "js": [...]}
|
|
63
|
+
|
|
64
|
+
# Только CSS
|
|
65
|
+
css_only = resp.assets(js=False)
|
|
66
|
+
|
|
67
|
+
# Только JS
|
|
68
|
+
js_only = resp.assets(css=False)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Метод парсит:
|
|
72
|
+
- CSS: теги `<link rel="stylesheet" href="...">`
|
|
73
|
+
- JS: теги `<script src="...">`
|
|
74
|
+
|
|
75
|
+
Все ссылки нормализуются относительно URL запроса.
|
|
76
|
+
|
|
55
77
|
## Обработка ошибок
|
|
56
78
|
|
|
57
79
|
FastHTTP автоматически обрабатывает ошибки:
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from fasthttp import FastHTTP
|
|
2
|
+
from fasthttp.response import Response
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
app = FastHTTP(debug=True)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
@app.get(url="https://example.com")
|
|
9
|
+
async def get_assets(resp: Response) -> dict:
|
|
10
|
+
return resp.assets()
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@app.get(url="https://example.com")
|
|
14
|
+
async def get_css_only(resp: Response) -> dict:
|
|
15
|
+
return resp.assets(js=False)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@app.get(url="https://example.com")
|
|
19
|
+
async def get_js_only(resp: Response) -> dict:
|
|
20
|
+
return resp.assets(css=False)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
if __name__ == "__main__":
|
|
24
|
+
app.run()
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.2.3"
|
|
@@ -11,8 +11,13 @@ import httpx
|
|
|
11
11
|
from annotated_doc import Doc
|
|
12
12
|
|
|
13
13
|
from .client import HTTPClient
|
|
14
|
-
from .helpers.routing import apply_base_url, check_annotated_parameters, check_annotated_return, check_https_url
|
|
15
14
|
from .graphql.client import create_graphql_client
|
|
15
|
+
from .helpers.route_inspect import (
|
|
16
|
+
check_annotated_parameters,
|
|
17
|
+
check_annotated_return,
|
|
18
|
+
validate_handler,
|
|
19
|
+
)
|
|
20
|
+
from .helpers.routing import apply_base_url, check_https_url
|
|
16
21
|
from .logging import setup_logger
|
|
17
22
|
from .middleware import BaseMiddleware, MiddlewareManager
|
|
18
23
|
from .openapi.generator import generate_openapi_schema
|
|
@@ -469,8 +474,7 @@ class FastHTTP:
|
|
|
469
474
|
responses: dict[int, dict[Literal["model"], type[BaseModel]]] | None = None,
|
|
470
475
|
) -> Callable[[Callable[..., object]], Callable[..., object]]:
|
|
471
476
|
def decorator(func: Callable[..., object]) -> Callable[..., object]:
|
|
472
|
-
|
|
473
|
-
self._check_annotated_func(func=func)
|
|
477
|
+
validate_handler(func=func)
|
|
474
478
|
|
|
475
479
|
self.routes.append(
|
|
476
480
|
Route(
|
|
@@ -795,8 +799,7 @@ class FastHTTP:
|
|
|
795
799
|
```
|
|
796
800
|
"""
|
|
797
801
|
def decorator(func: Callable[..., object]) -> Callable[..., object]:
|
|
798
|
-
|
|
799
|
-
self._check_annotated_func(func=func)
|
|
802
|
+
validate_handler(func=func)
|
|
800
803
|
|
|
801
804
|
async def graphql_handler(response: Response) -> object:
|
|
802
805
|
from inspect import iscoroutinefunction
|
|
@@ -239,7 +239,7 @@ class HTTPClient:
|
|
|
239
239
|
config: dict,
|
|
240
240
|
response: httpx.Response
|
|
241
241
|
) -> Response:
|
|
242
|
-
|
|
242
|
+
resp = Response(
|
|
243
243
|
status=response.status_code,
|
|
244
244
|
text=response.text,
|
|
245
245
|
headers=dict(response.headers),
|
|
@@ -249,6 +249,8 @@ class HTTPClient:
|
|
|
249
249
|
req_json=route.json,
|
|
250
250
|
req_data=route.data,
|
|
251
251
|
)
|
|
252
|
+
resp._set_url(route.url)
|
|
253
|
+
return resp
|
|
252
254
|
|
|
253
255
|
async def _process_handler_result(
|
|
254
256
|
self,
|
|
@@ -334,6 +336,7 @@ class HTTPClient:
|
|
|
334
336
|
headers={},
|
|
335
337
|
method=route.method,
|
|
336
338
|
)
|
|
339
|
+
empty_response._set_url(route.url)
|
|
337
340
|
handler_result = await route.handler(empty_response)
|
|
338
341
|
return await self._process_handler_result(
|
|
339
342
|
empty_response,
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import inspect
|
|
4
|
+
from typing import TYPE_CHECKING, Any, Literal
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel
|
|
7
|
+
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from collections.abc import Callable
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# Route params type for HTTP methods
|
|
14
|
+
RouteParams = dict[str, Any]
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def check_annotated_parameters(*, func: Callable[..., object]) -> None:
|
|
18
|
+
"""
|
|
19
|
+
Validate that all function parameters have type annotations.
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
func: Target function to validate.
|
|
23
|
+
|
|
24
|
+
Raises:
|
|
25
|
+
TypeError: If any parameter does not have a type annotation.
|
|
26
|
+
"""
|
|
27
|
+
sig = inspect.signature(func)
|
|
28
|
+
for name, param in sig.parameters.items():
|
|
29
|
+
if param.annotation is inspect.Parameter.empty:
|
|
30
|
+
msg = (
|
|
31
|
+
f"Parameter '{name}' in function '{func.__name__}' "
|
|
32
|
+
"must have a type annotation"
|
|
33
|
+
)
|
|
34
|
+
raise TypeError(msg)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def check_annotated_return(*, func: Callable[..., object]) -> None:
|
|
38
|
+
"""
|
|
39
|
+
Validate that a function has an explicit return type annotation.
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
func: Target function to validate.
|
|
43
|
+
|
|
44
|
+
Raises:
|
|
45
|
+
TypeError: If the function does not have a return type annotation.
|
|
46
|
+
"""
|
|
47
|
+
sig = inspect.signature(func)
|
|
48
|
+
if sig.return_annotation is inspect.Signature.empty:
|
|
49
|
+
msg = (
|
|
50
|
+
f"Function '{func.__name__}' must explicitly "
|
|
51
|
+
"define return type annotation"
|
|
52
|
+
)
|
|
53
|
+
raise TypeError(msg)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def validate_handler(func: Callable[..., object]) -> None:
|
|
57
|
+
"""
|
|
58
|
+
Validate a handler function has proper type annotations.
|
|
59
|
+
|
|
60
|
+
Checks both parameters and return type annotations.
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
func: Handler function to validate.
|
|
64
|
+
|
|
65
|
+
Raises:
|
|
66
|
+
TypeError: If validation fails.
|
|
67
|
+
"""
|
|
68
|
+
check_annotated_parameters(func=func)
|
|
69
|
+
check_annotated_return(func=func)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
# Common parameters for HTTP methods
|
|
73
|
+
COMMON_PARAMS = {
|
|
74
|
+
"response_model": {
|
|
75
|
+
"type": type[BaseModel] | None,
|
|
76
|
+
"default": None,
|
|
77
|
+
"doc": "Optional Pydantic model for validating the handler result.",
|
|
78
|
+
},
|
|
79
|
+
"request_model": {
|
|
80
|
+
"type": type[BaseModel] | None,
|
|
81
|
+
"default": None,
|
|
82
|
+
"doc": "Optional Pydantic model for validating request data.",
|
|
83
|
+
},
|
|
84
|
+
"tags": {
|
|
85
|
+
"type": list[str] | None,
|
|
86
|
+
"default": None,
|
|
87
|
+
"doc": "Optional tags for grouping and filtering the route.",
|
|
88
|
+
},
|
|
89
|
+
"dependencies": {
|
|
90
|
+
"type": list | None,
|
|
91
|
+
"default": None,
|
|
92
|
+
"doc": "Optional dependencies executed before the request.",
|
|
93
|
+
},
|
|
94
|
+
"responses": {
|
|
95
|
+
"type": dict[int, dict[Literal["model"], type[BaseModel]]] | None,
|
|
96
|
+
"default": None,
|
|
97
|
+
"doc": "Optional response models for error status codes.",
|
|
98
|
+
},
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def create_route_params(
|
|
103
|
+
*,
|
|
104
|
+
method: Literal["GET", "POST", "PUT", "PATCH", "DELETE"],
|
|
105
|
+
url: str,
|
|
106
|
+
params: dict | None = None,
|
|
107
|
+
json: dict | None = None,
|
|
108
|
+
data: object | None = None,
|
|
109
|
+
response_model: type[BaseModel] | None = None,
|
|
110
|
+
request_model: type[BaseModel] | None = None,
|
|
111
|
+
tags: list[str] | None = None,
|
|
112
|
+
dependencies: list | None = None,
|
|
113
|
+
skip_request: bool = False,
|
|
114
|
+
responses: dict[int, dict[Literal["model"], type[BaseModel]]] | None = None,
|
|
115
|
+
) -> RouteParams:
|
|
116
|
+
"""
|
|
117
|
+
Create a route parameters dictionary from common arguments.
|
|
118
|
+
|
|
119
|
+
Args:
|
|
120
|
+
method: HTTP method.
|
|
121
|
+
url: Target URL.
|
|
122
|
+
params: Query parameters.
|
|
123
|
+
json: JSON body.
|
|
124
|
+
data: Raw body.
|
|
125
|
+
response_model: Response model.
|
|
126
|
+
request_model: Request model.
|
|
127
|
+
tags: Route tags.
|
|
128
|
+
dependencies: Route dependencies.
|
|
129
|
+
skip_request: Skip HTTP request flag.
|
|
130
|
+
responses: Response models for status codes.
|
|
131
|
+
|
|
132
|
+
Returns:
|
|
133
|
+
Dictionary of route parameters.
|
|
134
|
+
"""
|
|
135
|
+
return {
|
|
136
|
+
"method": method,
|
|
137
|
+
"url": url,
|
|
138
|
+
"params": params,
|
|
139
|
+
"json": json,
|
|
140
|
+
"data": data,
|
|
141
|
+
"response_model": response_model,
|
|
142
|
+
"request_model": request_model,
|
|
143
|
+
"tags": tags or [],
|
|
144
|
+
"dependencies": dependencies or [],
|
|
145
|
+
"skip_request": skip_request,
|
|
146
|
+
"responses": responses or {},
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
__all__ = (
|
|
151
|
+
"COMMON_PARAMS",
|
|
152
|
+
"check_annotated_parameters",
|
|
153
|
+
"check_annotated_return",
|
|
154
|
+
"create_route_params",
|
|
155
|
+
"validate_handler",
|
|
156
|
+
)
|
|
@@ -1,51 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import inspect
|
|
4
|
-
from typing import TYPE_CHECKING
|
|
5
3
|
from urllib.parse import urljoin
|
|
6
4
|
|
|
7
|
-
if TYPE_CHECKING:
|
|
8
|
-
from collections.abc import Callable
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
def check_annotated_parameters(*, func: Callable[..., object]) -> None:
|
|
12
|
-
"""
|
|
13
|
-
Validate that all function parameters have type annotations.
|
|
14
|
-
|
|
15
|
-
Args:
|
|
16
|
-
func: Target function to validate.
|
|
17
|
-
|
|
18
|
-
Raises:
|
|
19
|
-
TypeError: If any parameter does not have a type annotation.
|
|
20
|
-
"""
|
|
21
|
-
sig = inspect.signature(func)
|
|
22
|
-
for name, param in sig.parameters.items():
|
|
23
|
-
if param.annotation is inspect.Parameter.empty:
|
|
24
|
-
msg = (
|
|
25
|
-
f"Parameter '{name}' in function '{func.__name__}'"
|
|
26
|
-
"must have a type annotation"
|
|
27
|
-
)
|
|
28
|
-
raise TypeError(msg)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
def check_annotated_return(*, func: Callable[..., object]) -> None:
|
|
32
|
-
"""
|
|
33
|
-
Validate that a function has an explicit return type annotation.
|
|
34
|
-
|
|
35
|
-
Args:
|
|
36
|
-
func: Target function to validate.
|
|
37
|
-
|
|
38
|
-
Raises:
|
|
39
|
-
TypeError: If the function does not have a return type annotation.
|
|
40
|
-
"""
|
|
41
|
-
sig = inspect.signature(func)
|
|
42
|
-
if sig.return_annotation is inspect.Signature.empty:
|
|
43
|
-
msg = (
|
|
44
|
-
f"Function '{func.__name__}' must explicitly"
|
|
45
|
-
"define return type annotation"
|
|
46
|
-
)
|
|
47
|
-
raise TypeError(msg)
|
|
48
|
-
|
|
49
5
|
|
|
50
6
|
def check_https_url(*, url: str) -> str:
|
|
51
7
|
"""
|
|
@@ -149,8 +105,6 @@ def apply_base_url(*, url: str, base_url: str | None) -> str:
|
|
|
149
105
|
|
|
150
106
|
__all__ = (
|
|
151
107
|
"apply_base_url",
|
|
152
|
-
"check_annotated_parameters",
|
|
153
|
-
"check_annotated_return",
|
|
154
108
|
"check_https_url",
|
|
155
109
|
"join_prefix",
|
|
156
110
|
"resolve_url",
|
|
@@ -7,7 +7,7 @@ import httpx
|
|
|
7
7
|
from annotated_doc import Doc
|
|
8
8
|
|
|
9
9
|
from fasthttp.response import Response
|
|
10
|
-
|
|
10
|
+
from fasthttp import status
|
|
11
11
|
from .generator import generate_openapi_schema
|
|
12
12
|
from .swagger import get_swagger_html, get_not_found_html
|
|
13
13
|
from .urls import build_docs_urls
|
|
@@ -38,7 +38,7 @@ async def handle_docs(
|
|
|
38
38
|
request_url=urls["request_url"],
|
|
39
39
|
)
|
|
40
40
|
return Response(
|
|
41
|
-
status=
|
|
41
|
+
status=status.HTTP_200_OK,
|
|
42
42
|
text=html,
|
|
43
43
|
headers={"Content-Type": "text/html"},
|
|
44
44
|
)
|
|
@@ -64,7 +64,7 @@ async def handle_openapi_json(
|
|
|
64
64
|
schema = generate_openapi_schema(app, server_url=urls["request_url"])
|
|
65
65
|
json_str = json.dumps(schema, indent=2, ensure_ascii=False)
|
|
66
66
|
return Response(
|
|
67
|
-
status=
|
|
67
|
+
status=status.HTTP_200_OK,
|
|
68
68
|
text=json_str,
|
|
69
69
|
headers={"Content-Type": "application/json"},
|
|
70
70
|
)
|
|
@@ -92,7 +92,7 @@ async def handle_not_found(
|
|
|
92
92
|
openapi_url=urls["openapi_url"],
|
|
93
93
|
)
|
|
94
94
|
return Response(
|
|
95
|
-
status=
|
|
95
|
+
status=status.HTTP_404_NOT_FOUND,
|
|
96
96
|
text=html,
|
|
97
97
|
headers={"Content-Type": "text/html"},
|
|
98
98
|
)
|
|
@@ -127,7 +127,7 @@ async def handle_request(
|
|
|
127
127
|
|
|
128
128
|
if not url:
|
|
129
129
|
return Response(
|
|
130
|
-
status=
|
|
130
|
+
status=status.HTTP_400_BAD_REQUEST,
|
|
131
131
|
text=json.dumps({"error": "URL is required"}),
|
|
132
132
|
headers={"Content-Type": "application/json"},
|
|
133
133
|
)
|
|
@@ -160,26 +160,26 @@ async def handle_request(
|
|
|
160
160
|
pass
|
|
161
161
|
|
|
162
162
|
return Response(
|
|
163
|
-
status=
|
|
163
|
+
status=status.HTTP_200_OK,
|
|
164
164
|
text=json.dumps(result, indent=2, ensure_ascii=False),
|
|
165
165
|
headers={"Content-Type": "application/json"},
|
|
166
166
|
)
|
|
167
167
|
|
|
168
168
|
except httpx.ConnectError as e:
|
|
169
169
|
return Response(
|
|
170
|
-
status=
|
|
170
|
+
status=status.HTTP_502_BAD_GATEWAY,
|
|
171
171
|
text=json.dumps({"error": f"Connection error: {str(e)}"}),
|
|
172
172
|
headers={"Content-Type": "application/json"},
|
|
173
173
|
)
|
|
174
174
|
except httpx.TimeoutException as e:
|
|
175
175
|
return Response(
|
|
176
|
-
status=
|
|
176
|
+
status=status.HTTP_504_GATEWAY_TIMEOUT,
|
|
177
177
|
text=json.dumps({"error": f"Timeout: {str(e)}"}),
|
|
178
178
|
headers={"Content-Type": "application/json"},
|
|
179
179
|
)
|
|
180
180
|
except Exception as e:
|
|
181
181
|
return Response(
|
|
182
|
-
status=
|
|
182
|
+
status=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
183
183
|
text=json.dumps({"error": f"Request failed: {str(e)}"}),
|
|
184
184
|
headers={"Content-Type": "application/json"},
|
|
185
185
|
)
|