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.
Files changed (282) hide show
  1. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.github/workflows/labeler.yml +1 -1
  2. fasthttp_client-1.2.3/.github/workflows/welcome.yml +59 -0
  3. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/PKG-INFO +4 -1
  4. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/reference/response.md +41 -0
  5. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/response-handling.md +22 -0
  6. fasthttp_client-1.2.3/docs/ru/reference/response.md +86 -0
  7. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/response-handling.md +22 -0
  8. fasthttp_client-1.2.3/examples/basic/extract_assets.py +24 -0
  9. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/__init__.py +3 -1
  10. fasthttp_client-1.2.3/fasthttp/__meta__.py +1 -0
  11. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/app.py +8 -5
  12. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/client.py +4 -1
  13. fasthttp_client-1.2.3/fasthttp/helpers/route_inspect.py +156 -0
  14. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/helpers/routing.py +0 -46
  15. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/openapi/routes.py +9 -9
  16. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/openapi/swagger.py +184 -8
  17. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/response.py +45 -0
  18. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/routing.py +2 -4
  19. fasthttp_client-1.2.3/fasthttp/status.py +177 -0
  20. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/pyproject.toml +4 -1
  21. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/tests/test_app.py +1 -1
  22. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/uv.lock +442 -1
  23. fasthttp_client-1.2.2/.github/workflows/welcome.yml +0 -47
  24. fasthttp_client-1.2.2/docs/ru/reference/response.md +0 -45
  25. fasthttp_client-1.2.2/fasthttp/__meta__.py +0 -1
  26. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.all-contributorsrc +0 -0
  27. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.github/DISCUSSION_TEMPLATE/general.yml +0 -0
  28. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.github/DISCUSSION_TEMPLATE/ideas.yml +0 -0
  29. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  30. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  31. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.github/ISSUE_TEMPLATE/question.yml +0 -0
  32. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  33. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.github/dependabot.yml +0 -0
  34. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.github/labeler.yml +0 -0
  35. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.github/stale.yml +0 -0
  36. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.github/workflows/all-contributors.yml +0 -0
  37. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.github/workflows/cleanup.yml +0 -0
  38. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.github/workflows/codeql.yml +0 -0
  39. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.github/workflows/codspeed.yml +0 -0
  40. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.github/workflows/coverage.yml +0 -0
  41. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.github/workflows/release.yml +0 -0
  42. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.github/workflows/scorecard.yml +0 -0
  43. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.github/workflows/tests.yml +0 -0
  44. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.gitignore +0 -0
  45. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.python-version +0 -0
  46. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/.readthedocs.yaml +0 -0
  47. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/AUTHORS.md +0 -0
  48. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/CHANGELOG.md +0 -0
  49. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/CODE_OF_CONDUCT.md +0 -0
  50. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/CONTRIBUTING.md +0 -0
  51. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/LICENSE +0 -0
  52. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/MANIFEST.in +0 -0
  53. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/README.md +0 -0
  54. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/SECURITY.md +0 -0
  55. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/blog/how-i-created-fasthttp.md +0 -0
  56. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/blog/istoriya-sozdaniya-fasthttp.md +0 -0
  57. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/about/index.md +0 -0
  58. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/api-reference.md +0 -0
  59. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/cli/commands.md +0 -0
  60. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/cli/index.md +0 -0
  61. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/cli/options.md +0 -0
  62. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/cli.md +0 -0
  63. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/configuration.md +0 -0
  64. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/dependencies.md +0 -0
  65. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/examples.md +0 -0
  66. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/graphql.md +0 -0
  67. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/http2-support.md +0 -0
  68. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/index.md +0 -0
  69. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/learn/index.md +0 -0
  70. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/learn/python-types.md +0 -0
  71. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/middleware.md +0 -0
  72. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/openapi.md +0 -0
  73. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/pydantic-validation.md +0 -0
  74. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/python-types.md +0 -0
  75. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/quick-start.md +0 -0
  76. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/reference/cli.md +0 -0
  77. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/reference/dependencies.md +0 -0
  78. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/reference/fasthttp.md +0 -0
  79. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/reference/index.md +0 -0
  80. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/reference/middleware.md +0 -0
  81. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/request-signing.md +0 -0
  82. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/security.md +0 -0
  83. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/configuration/environment.md +0 -0
  84. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/configuration/headers.md +0 -0
  85. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/configuration/http2.md +0 -0
  86. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/configuration/index.md +0 -0
  87. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/configuration/logging.md +0 -0
  88. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/configuration/proxy.md +0 -0
  89. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/configuration/settings.md +0 -0
  90. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/configuration/timeouts.md +0 -0
  91. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/dependencies.md +0 -0
  92. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/first-steps.md +0 -0
  93. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/graphql/index.md +0 -0
  94. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/graphql/mutations.md +0 -0
  95. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/graphql/queries.md +0 -0
  96. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/http-methods.md +0 -0
  97. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/index.md +0 -0
  98. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/lifespan.md +0 -0
  99. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/middleware/creating.md +0 -0
  100. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/middleware/examples.md +0 -0
  101. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/middleware/index.md +0 -0
  102. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/openapi/index.md +0 -0
  103. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/openapi/swagger-ui.md +0 -0
  104. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/parallel-execution.md +0 -0
  105. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/request-parameters.md +0 -0
  106. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/routers.md +0 -0
  107. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/security/circuit-breaker.md +0 -0
  108. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/security/index.md +0 -0
  109. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/security/secrets-masking.md +0 -0
  110. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/security/ssrf-protection.md +0 -0
  111. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/tags.md +0 -0
  112. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/validation/error-validation.md +0 -0
  113. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/validation/index.md +0 -0
  114. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/validation/pydantic-validation.md +0 -0
  115. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/en/tutorial/validation/request-validation.md +0 -0
  116. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/index.md +0 -0
  117. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/logo.png +0 -0
  118. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/photo/404_not_found.png +0 -0
  119. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/photo/swagger_ui_check_execute.png +0 -0
  120. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/photo/swagger_ui_check_web.png +0 -0
  121. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/photo/swagger_ui_home.png +0 -0
  122. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/about/index.md +0 -0
  123. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/api-reference.md +0 -0
  124. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/cli/commands.md +0 -0
  125. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/cli/index.md +0 -0
  126. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/cli/options.md +0 -0
  127. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/cli.md +0 -0
  128. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/configuration.md +0 -0
  129. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/dependencies.md +0 -0
  130. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/examples.md +0 -0
  131. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/graphql.md +0 -0
  132. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/http2-support.md +0 -0
  133. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/index.md +0 -0
  134. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/learn/index.md +0 -0
  135. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/learn/python-types.md +0 -0
  136. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/middleware.md +0 -0
  137. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/openapi.md +0 -0
  138. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/pydantic-validation.md +0 -0
  139. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/quick-start.md +0 -0
  140. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/reference/cli.md +0 -0
  141. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/reference/dependencies.md +0 -0
  142. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/reference/fasthttp.md +0 -0
  143. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/reference/index.md +0 -0
  144. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/reference/middleware.md +0 -0
  145. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/request-signing.md +0 -0
  146. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/security.md +0 -0
  147. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/configuration/environment.md +0 -0
  148. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/configuration/headers.md +0 -0
  149. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/configuration/http2.md +0 -0
  150. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/configuration/index.md +0 -0
  151. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/configuration/logging.md +0 -0
  152. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/configuration/proxy.md +0 -0
  153. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/configuration/settings.md +0 -0
  154. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/configuration/timeouts.md +0 -0
  155. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/dependencies.md +0 -0
  156. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/first-steps.md +0 -0
  157. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/graphql/index.md +0 -0
  158. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/graphql/mutations.md +0 -0
  159. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/graphql/queries.md +0 -0
  160. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/http-methods.md +0 -0
  161. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/index.md +0 -0
  162. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/lifespan.md +0 -0
  163. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/middleware/creating.md +0 -0
  164. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/middleware/examples.md +0 -0
  165. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/middleware/index.md +0 -0
  166. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/openapi/index.md +0 -0
  167. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/openapi/swagger-ui.md +0 -0
  168. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/parallel-execution.md +0 -0
  169. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/request-parameters.md +0 -0
  170. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/routers.md +0 -0
  171. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/security/circuit-breaker.md +0 -0
  172. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/security/index.md +0 -0
  173. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/security/secrets-masking.md +0 -0
  174. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/security/ssrf-protection.md +0 -0
  175. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/tags.md +0 -0
  176. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/validation/error-validation.md +0 -0
  177. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/validation/index.md +0 -0
  178. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/validation/pydantic-validation.md +0 -0
  179. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/docs/ru/tutorial/validation/request-validation.md +0 -0
  180. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/README.md +0 -0
  181. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/advanced/error_handling.py +0 -0
  182. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/advanced/redirect_test.py +0 -0
  183. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/basic/defaults_example.py +0 -0
  184. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/basic/full_crud.py +0 -0
  185. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/basic/response_request_info.py +0 -0
  186. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/basic/test_delete.py +0 -0
  187. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/basic/test_get.py +0 -0
  188. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/basic/test_patch.py +0 -0
  189. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/basic/test_post.py +0 -0
  190. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/basic/test_put.py +0 -0
  191. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/data/form_data.py +0 -0
  192. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/dependencies/basic_dependencies.py +0 -0
  193. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/dependencies/with_cache_scope.py +0 -0
  194. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/endpoints/get_ip.py +0 -0
  195. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/endpoints/jsonplaceholder_get.py +0 -0
  196. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/endpoints/jsonplaceholder_posts.py +0 -0
  197. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/endpoints/multiple_endpoints.py +0 -0
  198. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/error/bad_status_codes.py +0 -0
  199. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/error/connection_error.py +0 -0
  200. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/error/invalid_url.py +0 -0
  201. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/error/not_found_site.py +0 -0
  202. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/error/responses.py +0 -0
  203. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/error/server_errors.py +0 -0
  204. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/error/successful_request.py +0 -0
  205. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/error/timeout_error.py +0 -0
  206. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/error/validation_error.py +0 -0
  207. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/graphql/pokemon.py +0 -0
  208. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/graphql/rick_and_morty.py +0 -0
  209. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/graphql/run_examples.py +0 -0
  210. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/graphql/star_wars.py +0 -0
  211. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/headers/headers.py +0 -0
  212. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/headers/user_agent.py +0 -0
  213. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/http2/README.md +0 -0
  214. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/http2/http2_example.py +0 -0
  215. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/methods/json_post.py +0 -0
  216. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/middleware/basic_middleware.py +0 -0
  217. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/middleware/error_middleware.py +0 -0
  218. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/middleware/response_transformer.py +0 -0
  219. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/openapi/openapi_example.py +0 -0
  220. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/parameters/delay_response.py +0 -0
  221. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/parameters/query_params.py +0 -0
  222. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/parameters/query_params_example.py +0 -0
  223. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/parameters/timeout_example.py +0 -0
  224. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/pydantic/advanced_validation.py +0 -0
  225. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/pydantic/basic_validation.py +0 -0
  226. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/pydantic/create_and_validate.py +0 -0
  227. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/pydantic/crud_with_validation.py +0 -0
  228. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/pydantic/nested_models.py +0 -0
  229. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/routers/base.py +0 -0
  230. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/run_all.py +0 -0
  231. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/examples/tags/basic_tags.py +0 -0
  232. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/cli/__init__.py +0 -0
  233. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/cli/client.py +0 -0
  234. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/cli/commands.py +0 -0
  235. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/cli/main.py +0 -0
  236. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/cli/output.py +0 -0
  237. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/cli/repl.py +0 -0
  238. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/dependencies/__init__.py +0 -0
  239. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/dependencies/dependencies.py +0 -0
  240. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/exceptions/__init__.py +0 -0
  241. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/exceptions/base.py +0 -0
  242. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/exceptions/connect.py +0 -0
  243. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/exceptions/request.py +0 -0
  244. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/exceptions/status.py +0 -0
  245. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/exceptions/timeout.py +0 -0
  246. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/exceptions/types.py +0 -0
  247. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/exceptions/validator.py +0 -0
  248. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/graphql/__init__.py +0 -0
  249. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/graphql/client.py +0 -0
  250. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/graphql/types.py +0 -0
  251. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/helpers/__init__.py +0 -0
  252. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/logging.py +0 -0
  253. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/middleware.py +0 -0
  254. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/openapi/__init__.py +0 -0
  255. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/openapi/generator.py +0 -0
  256. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/openapi/urls.py +0 -0
  257. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/py.typed +0 -0
  258. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/security/__init__.py +0 -0
  259. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/security/circuit_breaker.py +0 -0
  260. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/security/headers.py +0 -0
  261. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/security/limits.py +0 -0
  262. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/security/redirect.py +0 -0
  263. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/security/response.py +0 -0
  264. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/security/secrets.py +0 -0
  265. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/security/security.py +0 -0
  266. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/security/signer.py +0 -0
  267. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/security/ssrf.py +0 -0
  268. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/fasthttp/types.py +0 -0
  269. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/mkdocs.yml +0 -0
  270. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/scripts/Makefile +0 -0
  271. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/tests/__init__.py +0 -0
  272. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/tests/conftest.py +0 -0
  273. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/tests/test_cli.py +0 -0
  274. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/tests/test_client.py +0 -0
  275. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/tests/test_dependencies.py +0 -0
  276. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/tests/test_exceptions.py +0 -0
  277. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/tests/test_graphql.py +0 -0
  278. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/tests/test_openapi.py +0 -0
  279. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/tests/test_performance.py +0 -0
  280. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/tests/test_response.py +0 -0
  281. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/tests/test_security.py +0 -0
  282. {fasthttp_client-1.2.2 → fasthttp_client-1.2.3}/tests/test_types.py +0 -0
@@ -21,5 +21,5 @@ jobs:
21
21
  - name: Run Labeler
22
22
  uses: actions/labeler@v6
23
23
  with:
24
- repo-token: ${{ secrets.GITHUB_TOKEN }}
24
+ repo-token: ${{ secrets.GH_TOKEN }}
25
25
  configuration-path: .github/labeler.yml
@@ -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.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()
@@ -1,3 +1,4 @@
1
+ from . import status
1
2
  from .__meta__ import __version__
2
3
  from .app import FastHTTP
3
4
  from .dependencies import Depends
@@ -11,5 +12,6 @@ __all__ = (
11
12
  "FastHTTP",
12
13
  "MiddlewareManager",
13
14
  "Router",
14
- "__version__"
15
+ "__version__",
16
+ "status",
15
17
  )
@@ -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
- self._check_annotated_parameters(func=func)
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
- self._check_annotated_parameters(func=func)
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
- return Response(
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=200,
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=200,
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=404,
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=400,
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=200,
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=502,
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=504,
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=500,
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
  )