bustapi 0.12.0__tar.gz → 0.13.0__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 (264) hide show
  1. bustapi-0.13.0/.github/FUNDING.yml +3 -0
  2. {bustapi-0.12.0 → bustapi-0.13.0}/CHANGELOG.md +18 -0
  3. {bustapi-0.12.0 → bustapi-0.13.0}/Cargo.lock +17 -15
  4. {bustapi-0.12.0 → bustapi-0.13.0}/Cargo.toml +1 -1
  5. {bustapi-0.12.0 → bustapi-0.13.0}/PKG-INFO +14 -13
  6. {bustapi-0.12.0 → bustapi-0.13.0}/README.md +9 -8
  7. {bustapi-0.12.0 → bustapi-0.13.0}/docs/changelog.md +18 -0
  8. {bustapi-0.12.0 → bustapi-0.13.0}/docs/complete-api-reference.md +71 -10
  9. {bustapi-0.12.0 → bustapi-0.13.0}/docs/examples-guide.md +9 -2
  10. {bustapi-0.12.0 → bustapi-0.13.0}/docs/index.md +3 -1
  11. {bustapi-0.12.0 → bustapi-0.13.0}/docs/quickstart.md +4 -0
  12. {bustapi-0.12.0 → bustapi-0.13.0}/docs/user-guide/authentication.md +3 -0
  13. bustapi-0.13.0/docs/user-guide/documentation.md +144 -0
  14. {bustapi-0.12.0 → bustapi-0.13.0}/docs/user-guide/error_handling.md +30 -0
  15. bustapi-0.13.0/docs/user-guide/jwt.md +203 -0
  16. {bustapi-0.12.0 → bustapi-0.13.0}/docs/user-guide/responses.md +63 -0
  17. {bustapi-0.12.0 → bustapi-0.13.0}/examples/security/17_jwt_auth.py +1 -1
  18. bustapi-0.13.0/examples/security/18_jwt_cookies.py +99 -0
  19. {bustapi-0.12.0 → bustapi-0.13.0}/pyproject.toml +6 -6
  20. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/__init__.py +4 -1
  21. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/app.py +32 -148
  22. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/auth/decorators.py +23 -0
  23. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/auth/login.py +6 -1
  24. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/core/exceptions.py +3 -1
  25. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/dispatch.py +120 -119
  26. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/hooks.py +15 -3
  27. bustapi-0.13.0/python/bustapi/http/response.py +284 -0
  28. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/jwt.py +122 -97
  29. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/server/wsgi.py +44 -13
  30. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/testing/client.py +62 -172
  31. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/utils.py +51 -1
  32. bustapi-0.13.0/scratch/test_abort.py +20 -0
  33. bustapi-0.13.0/scratch/test_headers.py +9 -0
  34. {bustapi-0.12.0 → bustapi-0.13.0}/src/bindings/app.rs +4 -22
  35. {bustapi-0.12.0 → bustapi-0.13.0}/src/bindings/converters.rs +75 -158
  36. {bustapi-0.12.0 → bustapi-0.13.0}/src/response/builders.rs +6 -9
  37. bustapi-0.13.0/src/response/methods.rs +82 -0
  38. {bustapi-0.12.0 → bustapi-0.13.0}/src/router/handlers.rs +1 -1
  39. {bustapi-0.12.0 → bustapi-0.13.0}/src/router/middleware.rs +6 -6
  40. {bustapi-0.12.0 → bustapi-0.13.0}/src/server/handlers.rs +3 -3
  41. bustapi-0.13.0/tests/test_async_hooks.py +56 -0
  42. bustapi-0.13.0/tests/test_async_login.py +82 -0
  43. bustapi-0.13.0/tests/test_jwt_cookies.py +70 -0
  44. bustapi-0.13.0/tests/test_orm_conflict.py +75 -0
  45. bustapi-0.12.0/.github/FUNDING.yml +0 -4
  46. bustapi-0.12.0/docs/user-guide/documentation.md +0 -32
  47. bustapi-0.12.0/docs/user-guide/jwt.md +0 -174
  48. bustapi-0.12.0/python/bustapi/core/wsgi.py +0 -136
  49. bustapi-0.12.0/python/bustapi/http/response.py +0 -513
  50. bustapi-0.12.0/src/response/methods.rs +0 -44
  51. {bustapi-0.12.0 → bustapi-0.13.0}/- +0 -0
  52. {bustapi-0.12.0 → bustapi-0.13.0}/.github/workflows/ci-multiplatform.yml +0 -0
  53. {bustapi-0.12.0 → bustapi-0.13.0}/.github/workflows/ci.yml +0 -0
  54. {bustapi-0.12.0 → bustapi-0.13.0}/.github/workflows/docs.yml +0 -0
  55. {bustapi-0.12.0 → bustapi-0.13.0}/.github/workflows/manual-publish.yml +0 -0
  56. {bustapi-0.12.0 → bustapi-0.13.0}/.gitignore +0 -0
  57. {bustapi-0.12.0 → bustapi-0.13.0}/.python-version +0 -0
  58. {bustapi-0.12.0 → bustapi-0.13.0}/Dockerfile +0 -0
  59. {bustapi-0.12.0 → bustapi-0.13.0}/LICENSE +0 -0
  60. {bustapi-0.12.0 → bustapi-0.13.0}/benchmarks/CACHE_BENCHMARK.md +0 -0
  61. {bustapi-0.12.0 → bustapi-0.13.0}/benchmarks/README.md +0 -0
  62. {bustapi-0.12.0 → bustapi-0.13.0}/benchmarks/app.py +0 -0
  63. {bustapi-0.12.0 → bustapi-0.13.0}/benchmarks/benchmark_all.py +0 -0
  64. {bustapi-0.12.0 → bustapi-0.13.0}/benchmarks/benchmark_avg.py +0 -0
  65. {bustapi-0.12.0 → bustapi-0.13.0}/benchmarks/benchmark_cache.py +0 -0
  66. {bustapi-0.12.0 → bustapi-0.13.0}/benchmarks/benchmark_combined.png +0 -0
  67. {bustapi-0.12.0 → bustapi-0.13.0}/benchmarks/bustapi.md +0 -0
  68. {bustapi-0.12.0 → bustapi-0.13.0}/benchmarks/bustapi_bench.py +0 -0
  69. {bustapi-0.12.0 → bustapi-0.13.0}/benchmarks/bustapi_internal.py +0 -0
  70. {bustapi-0.12.0 → bustapi-0.13.0}/benchmarks/comparison_bench.py +0 -0
  71. {bustapi-0.12.0 → bustapi-0.13.0}/benchmarks/comprehensive_benchmark.py +0 -0
  72. {bustapi-0.12.0 → bustapi-0.13.0}/benchmarks/gen_graph.py +0 -0
  73. {bustapi-0.12.0 → bustapi-0.13.0}/benchmarks/quick_bench.py +0 -0
  74. {bustapi-0.12.0 → bustapi-0.13.0}/benchmarks/resource_bench.py +0 -0
  75. {bustapi-0.12.0 → bustapi-0.13.0}/benchmarks/rps_comparison.png +0 -0
  76. {bustapi-0.12.0 → bustapi-0.13.0}/benchmarks/run_comparison_auto.py +0 -0
  77. {bustapi-0.12.0 → bustapi-0.13.0}/benchmarks/ws_benchmark.py +0 -0
  78. {bustapi-0.12.0 → bustapi-0.13.0}/check_path.py +0 -0
  79. {bustapi-0.12.0 → bustapi-0.13.0}/create_issues.sh +0 -0
  80. {bustapi-0.12.0 → bustapi-0.13.0}/docs/advanced/async.md +0 -0
  81. {bustapi-0.12.0 → bustapi-0.13.0}/docs/advanced/blueprints.md +0 -0
  82. {bustapi-0.12.0 → bustapi-0.13.0}/docs/advanced/dependency_injection.md +0 -0
  83. {bustapi-0.12.0 → bustapi-0.13.0}/docs/advanced/deployment.md +0 -0
  84. {bustapi-0.12.0 → bustapi-0.13.0}/docs/advanced/middleware.md +0 -0
  85. {bustapi-0.12.0 → bustapi-0.13.0}/docs/advanced/security.md +0 -0
  86. {bustapi-0.12.0 → bustapi-0.13.0}/docs/advanced/validation.md +0 -0
  87. {bustapi-0.12.0 → bustapi-0.13.0}/docs/api-reference.md +0 -0
  88. {bustapi-0.12.0 → bustapi-0.13.0}/docs/assets/logo.png +0 -0
  89. {bustapi-0.12.0 → bustapi-0.13.0}/docs/deployment-performance-guide.md +0 -0
  90. {bustapi-0.12.0 → bustapi-0.13.0}/docs/deployment.md +0 -0
  91. {bustapi-0.12.0 → bustapi-0.13.0}/docs/installation.md +0 -0
  92. {bustapi-0.12.0 → bustapi-0.13.0}/docs/overrides/.gitkeep +0 -0
  93. {bustapi-0.12.0 → bustapi-0.13.0}/docs/release_track.md +0 -0
  94. {bustapi-0.12.0 → bustapi-0.13.0}/docs/site/advanced/async_support.html +0 -0
  95. {bustapi-0.12.0 → bustapi-0.13.0}/docs/site/advanced/blueprints.html +0 -0
  96. {bustapi-0.12.0 → bustapi-0.13.0}/docs/site/advanced/dependency_injection.html +0 -0
  97. {bustapi-0.12.0 → bustapi-0.13.0}/docs/site/advanced/middleware.html +0 -0
  98. {bustapi-0.12.0 → bustapi-0.13.0}/docs/site/advanced/validation.html +0 -0
  99. {bustapi-0.12.0 → bustapi-0.13.0}/docs/site/api/all.html +0 -0
  100. {bustapi-0.12.0 → bustapi-0.13.0}/docs/site/api/app.html +0 -0
  101. {bustapi-0.12.0 → bustapi-0.13.0}/docs/site/api/context.html +0 -0
  102. {bustapi-0.12.0 → bustapi-0.13.0}/docs/site/api/utilities.html +0 -0
  103. {bustapi-0.12.0 → bustapi-0.13.0}/docs/site/assets/logo.png +0 -0
  104. {bustapi-0.12.0 → bustapi-0.13.0}/docs/site/changelog.html +0 -0
  105. {bustapi-0.12.0 → bustapi-0.13.0}/docs/site/core_concepts/request_data.html +0 -0
  106. {bustapi-0.12.0 → bustapi-0.13.0}/docs/site/core_concepts/responses.html +0 -0
  107. {bustapi-0.12.0 → bustapi-0.13.0}/docs/site/core_concepts/routing.html +0 -0
  108. {bustapi-0.12.0 → bustapi-0.13.0}/docs/site/core_concepts/templates.html +0 -0
  109. {bustapi-0.12.0 → bustapi-0.13.0}/docs/site/examples/index.html +0 -0
  110. {bustapi-0.12.0 → bustapi-0.13.0}/docs/site/getting_started/index.html +0 -0
  111. {bustapi-0.12.0 → bustapi-0.13.0}/docs/site/getting_started/quickstart.html +0 -0
  112. {bustapi-0.12.0 → bustapi-0.13.0}/docs/site/index.html +0 -0
  113. {bustapi-0.12.0 → bustapi-0.13.0}/docs/site/script.js +0 -0
  114. {bustapi-0.12.0 → bustapi-0.13.0}/docs/site/style.css +0 -0
  115. {bustapi-0.12.0 → bustapi-0.13.0}/docs/stylesheets/extra.css +0 -0
  116. {bustapi-0.12.0 → bustapi-0.13.0}/docs/user-guide/caching.md +0 -0
  117. {bustapi-0.12.0 → bustapi-0.13.0}/docs/user-guide/cli.md +0 -0
  118. {bustapi-0.12.0 → bustapi-0.13.0}/docs/user-guide/database.md +0 -0
  119. {bustapi-0.12.0 → bustapi-0.13.0}/docs/user-guide/logging.md +0 -0
  120. {bustapi-0.12.0 → bustapi-0.13.0}/docs/user-guide/multiprocessing.md +0 -0
  121. {bustapi-0.12.0 → bustapi-0.13.0}/docs/user-guide/request_data.md +0 -0
  122. {bustapi-0.12.0 → bustapi-0.13.0}/docs/user-guide/routing.md +0 -0
  123. {bustapi-0.12.0 → bustapi-0.13.0}/docs/user-guide/sessions.md +0 -0
  124. {bustapi-0.12.0 → bustapi-0.13.0}/docs/user-guide/static_files.md +0 -0
  125. {bustapi-0.12.0 → bustapi-0.13.0}/docs/user-guide/templates.md +0 -0
  126. {bustapi-0.12.0 → bustapi-0.13.0}/docs/user-guide/turbo-routes.md +0 -0
  127. {bustapi-0.12.0 → bustapi-0.13.0}/docs/user-guide/video-streaming.md +0 -0
  128. {bustapi-0.12.0 → bustapi-0.13.0}/docs/websockets.md +0 -0
  129. {bustapi-0.12.0 → bustapi-0.13.0}/examples/advanced/08_auto_docs.py +0 -0
  130. {bustapi-0.12.0 → bustapi-0.13.0}/examples/advanced/12_test_modes.py +0 -0
  131. {bustapi-0.12.0 → bustapi-0.13.0}/examples/advanced/13_error_handling.py +0 -0
  132. {bustapi-0.12.0 → bustapi-0.13.0}/examples/advanced/14_middleware.py +0 -0
  133. {bustapi-0.12.0 → bustapi-0.13.0}/examples/advanced/16_middleware_session.py +0 -0
  134. {bustapi-0.12.0 → bustapi-0.13.0}/examples/advanced/20_file_uploads.py +0 -0
  135. {bustapi-0.12.0 → bustapi-0.13.0}/examples/advanced/24_body_and_depends.py +0 -0
  136. {bustapi-0.12.0 → bustapi-0.13.0}/examples/advanced/27_video_stream.py +0 -0
  137. {bustapi-0.12.0 → bustapi-0.13.0}/examples/advanced/28_websocket.py +0 -0
  138. {bustapi-0.12.0 → bustapi-0.13.0}/examples/advanced/29_turbo_websocket.py +0 -0
  139. {bustapi-0.12.0 → bustapi-0.13.0}/examples/basics/01_hello_world.py +0 -0
  140. {bustapi-0.12.0 → bustapi-0.13.0}/examples/basics/02_parameters.py +0 -0
  141. {bustapi-0.12.0 → bustapi-0.13.0}/examples/basics/03_async.py +0 -0
  142. {bustapi-0.12.0 → bustapi-0.13.0}/examples/basics/04_request_data.py +0 -0
  143. {bustapi-0.12.0 → bustapi-0.13.0}/examples/basics/19_all_types.py +0 -0
  144. {bustapi-0.12.0 → bustapi-0.13.0}/examples/database/07_database_raw.py +0 -0
  145. {bustapi-0.12.0 → bustapi-0.13.0}/examples/database/10_database_sqlmodel.py +0 -0
  146. {bustapi-0.12.0 → bustapi-0.13.0}/examples/routing/06_blueprints.py +0 -0
  147. {bustapi-0.12.0 → bustapi-0.13.0}/examples/routing/09_complex_routing.py +0 -0
  148. {bustapi-0.12.0 → bustapi-0.13.0}/examples/routing/21_path_validation.py +0 -0
  149. {bustapi-0.12.0 → bustapi-0.13.0}/examples/routing/22_path_docs.py +0 -0
  150. {bustapi-0.12.0 → bustapi-0.13.0}/examples/routing/23_query_validation.py +0 -0
  151. {bustapi-0.12.0 → bustapi-0.13.0}/examples/routing/blueprint_with_jwt.py +0 -0
  152. {bustapi-0.12.0 → bustapi-0.13.0}/examples/security/10_rate_limit_demo.py +0 -0
  153. {bustapi-0.12.0 → bustapi-0.13.0}/examples/security/11_security_demo.py +0 -0
  154. {bustapi-0.12.0 → bustapi-0.13.0}/examples/security/17_safe_features.py +0 -0
  155. {bustapi-0.12.0 → bustapi-0.13.0}/examples/security/18_safe_advanced.py +0 -0
  156. {bustapi-0.12.0 → bustapi-0.13.0}/examples/security/18_session_login.py +0 -0
  157. {bustapi-0.12.0 → bustapi-0.13.0}/examples/templates/05_templates.py +0 -0
  158. {bustapi-0.12.0 → bustapi-0.13.0}/examples/templates/26_complex_template.py +0 -0
  159. {bustapi-0.12.0 → bustapi-0.13.0}/examples/templates/templates/index.html +0 -0
  160. {bustapi-0.12.0 → bustapi-0.13.0}/examples/turbo/cache_test.py +0 -0
  161. {bustapi-0.12.0 → bustapi-0.13.0}/examples/turbo/fair_benchmark.py +0 -0
  162. {bustapi-0.12.0 → bustapi-0.13.0}/examples/turbo/typed_turbo_example.py +0 -0
  163. {bustapi-0.12.0 → bustapi-0.13.0}/examples/ws/app.py +0 -0
  164. {bustapi-0.12.0 → bustapi-0.13.0}/examples/ws/templates/index.html +0 -0
  165. {bustapi-0.12.0 → bustapi-0.13.0}/examples/ws/websockets_demo.py +0 -0
  166. {bustapi-0.12.0 → bustapi-0.13.0}/examples/ws/ws_limit.py +0 -0
  167. {bustapi-0.12.0 → bustapi-0.13.0}/mkdocs.yml +0 -0
  168. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/auth/__init__.py +0 -0
  169. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/auth/csrf.py +0 -0
  170. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/auth/password.py +0 -0
  171. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/auth/tokens.py +0 -0
  172. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/auth/user.py +0 -0
  173. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/cli/__init__.py +0 -0
  174. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/cli/main.py +0 -0
  175. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/context.py +0 -0
  176. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/core/__init__.py +0 -0
  177. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/core/asgi.py +0 -0
  178. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/core/helpers.py +0 -0
  179. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/core/logging.py +0 -0
  180. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/dependencies.py +0 -0
  181. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/documentation/__init__.py +0 -0
  182. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/documentation/generator.py +0 -0
  183. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/extraction.py +0 -0
  184. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/fastapi_compat.py +0 -0
  185. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/http/__init__.py +0 -0
  186. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/http/request.py +0 -0
  187. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/logging.py +0 -0
  188. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/middleware.py +0 -0
  189. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/multiprocess.py +0 -0
  190. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/params.py +0 -0
  191. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/py.typed +0 -0
  192. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/responses.py +0 -0
  193. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/routing/__init__.py +0 -0
  194. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/routing/blueprints.py +0 -0
  195. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/routing/decorators.py +0 -0
  196. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/safe/__init__.py +0 -0
  197. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/safe/concurrency.py +0 -0
  198. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/safe/types.py +0 -0
  199. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/security/__init__.py +0 -0
  200. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/security/extension.py +0 -0
  201. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/security/rate_limit.py +0 -0
  202. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/server/__init__.py +0 -0
  203. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/server/runner.py +0 -0
  204. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/sessions.py +0 -0
  205. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/templating/__init__.py +0 -0
  206. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/templating/engine.py +0 -0
  207. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/templating/mixin.py +0 -0
  208. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/testing/__init__.py +0 -0
  209. {bustapi-0.12.0 → bustapi-0.13.0}/python/bustapi/websocket.py +0 -0
  210. {bustapi-0.12.0 → bustapi-0.13.0}/run_all_examples.py +0 -0
  211. {bustapi-0.12.0 → bustapi-0.13.0}/src/bindings/handlers.rs +0 -0
  212. {bustapi-0.12.0 → bustapi-0.13.0}/src/bindings/mod.rs +0 -0
  213. {bustapi-0.12.0 → bustapi-0.13.0}/src/bindings/request.rs +0 -0
  214. {bustapi-0.12.0 → bustapi-0.13.0}/src/bindings/typed_turbo.rs +0 -0
  215. {bustapi-0.12.0 → bustapi-0.13.0}/src/bindings/websocket.rs +0 -0
  216. {bustapi-0.12.0 → bustapi-0.13.0}/src/crypto.rs +0 -0
  217. {bustapi-0.12.0 → bustapi-0.13.0}/src/jwt.rs +0 -0
  218. {bustapi-0.12.0 → bustapi-0.13.0}/src/lib.rs +0 -0
  219. {bustapi-0.12.0 → bustapi-0.13.0}/src/logger.rs +0 -0
  220. {bustapi-0.12.0 → bustapi-0.13.0}/src/rate_limiter.rs +0 -0
  221. {bustapi-0.12.0 → bustapi-0.13.0}/src/request/methods.rs +0 -0
  222. {bustapi-0.12.0 → bustapi-0.13.0}/src/request/mod.rs +0 -0
  223. {bustapi-0.12.0 → bustapi-0.13.0}/src/request/tests.rs +0 -0
  224. {bustapi-0.12.0 → bustapi-0.13.0}/src/response/mod.rs +0 -0
  225. {bustapi-0.12.0 → bustapi-0.13.0}/src/router/matching.rs +0 -0
  226. {bustapi-0.12.0 → bustapi-0.13.0}/src/router/mod.rs +0 -0
  227. {bustapi-0.12.0 → bustapi-0.13.0}/src/router/tests.rs +0 -0
  228. {bustapi-0.12.0 → bustapi-0.13.0}/src/server/mod.rs +0 -0
  229. {bustapi-0.12.0 → bustapi-0.13.0}/src/server/startup.rs +0 -0
  230. {bustapi-0.12.0 → bustapi-0.13.0}/src/server/stream.rs +0 -0
  231. {bustapi-0.12.0 → bustapi-0.13.0}/src/static_files.rs +0 -0
  232. {bustapi-0.12.0 → bustapi-0.13.0}/src/templating.rs +0 -0
  233. {bustapi-0.12.0 → bustapi-0.13.0}/src/watcher.rs +0 -0
  234. {bustapi-0.12.0 → bustapi-0.13.0}/src/websocket/config.rs +0 -0
  235. {bustapi-0.12.0 → bustapi-0.13.0}/src/websocket/mod.rs +0 -0
  236. {bustapi-0.12.0 → bustapi-0.13.0}/src/websocket/session.rs +0 -0
  237. {bustapi-0.12.0 → bustapi-0.13.0}/src/websocket/turbo.rs +0 -0
  238. {bustapi-0.12.0 → bustapi-0.13.0}/static/style.css +0 -0
  239. {bustapi-0.12.0 → bustapi-0.13.0}/templates/base.html +0 -0
  240. {bustapi-0.12.0 → bustapi-0.13.0}/templates/complex.html +0 -0
  241. {bustapi-0.12.0 → bustapi-0.13.0}/test_trim.rs +0 -0
  242. {bustapi-0.12.0 → bustapi-0.13.0}/tests/docs_test_all.py +0 -0
  243. {bustapi-0.12.0 → bustapi-0.13.0}/tests/docs_test_api_reference.py +0 -0
  244. {bustapi-0.12.0 → bustapi-0.13.0}/tests/docs_test_installation.py +0 -0
  245. {bustapi-0.12.0 → bustapi-0.13.0}/tests/docs_test_quickstart.py +0 -0
  246. {bustapi-0.12.0 → bustapi-0.13.0}/tests/docs_test_simple.py +0 -0
  247. {bustapi-0.12.0 → bustapi-0.13.0}/tests/test_050_features.py +0 -0
  248. {bustapi-0.12.0 → bustapi-0.13.0}/tests/test_auth.py +0 -0
  249. {bustapi-0.12.0 → bustapi-0.13.0}/tests/test_examples.py +0 -0
  250. {bustapi-0.12.0 → bustapi-0.13.0}/tests/test_hot_reload.py +0 -0
  251. {bustapi-0.12.0 → bustapi-0.13.0}/tests/test_issue_18.py +0 -0
  252. {bustapi-0.12.0 → bustapi-0.13.0}/tests/test_jwt.py +0 -0
  253. {bustapi-0.12.0 → bustapi-0.13.0}/tests/test_login_manager.py +0 -0
  254. {bustapi-0.12.0 → bustapi-0.13.0}/tests/test_middleware.py +0 -0
  255. {bustapi-0.12.0 → bustapi-0.13.0}/tests/test_multiprocess_stability.py +0 -0
  256. {bustapi-0.12.0 → bustapi-0.13.0}/tests/test_new_examples.py +0 -0
  257. {bustapi-0.12.0 → bustapi-0.13.0}/tests/test_path_standalone.py +0 -0
  258. {bustapi-0.12.0 → bustapi-0.13.0}/tests/test_path_validation.py +0 -0
  259. {bustapi-0.12.0 → bustapi-0.13.0}/tests/test_rate_limit_rust.py +0 -0
  260. {bustapi-0.12.0 → bustapi-0.13.0}/tests/test_safe.py +0 -0
  261. {bustapi-0.12.0 → bustapi-0.13.0}/tests/test_security_unit.py +0 -0
  262. {bustapi-0.12.0 → bustapi-0.13.0}/tests/test_sessions.py +0 -0
  263. {bustapi-0.12.0 → bustapi-0.13.0}/tests/test_zero_copy.py +0 -0
  264. {bustapi-0.12.0 → bustapi-0.13.0}/tests/verify_router.py +0 -0
@@ -0,0 +1,3 @@
1
+ # These are supported funding model platforms
2
+
3
+ custom: ["https://ej.grandpaacademy.org/"]
@@ -2,6 +2,24 @@
2
2
 
3
3
  All notable changes to this project will be documented here.
4
4
 
5
+ ## [0.13.0] - 2026-05-02
6
+
7
+ ### Added
8
+ - **Robust Header Infrastructure**:
9
+ - Refactored `Headers` class to use `collections.UserDict` for better standard library compatibility.
10
+ - Implemented full case-insensitivity for all header operations (get, set, delete).
11
+ - Added native support for multi-value headers via `headers.add(key, value)` and `headers.getlist(key)`.
12
+ - **WSGI Adapter Enhancements**:
13
+ - Refactored `WSGIAdapter` to correctly handle multi-value headers.
14
+ - Integrated application-level error handling (including custom 404/500 handlers) into the WSGI layer.
15
+
16
+ ### Fixed
17
+ - **JWT & Cookie Security**:
18
+ - Updated `Response.delete_cookie()` signature to accept `secure`, `httponly`, and `samesite` arguments, fixing crashes in JWT logout flows.
19
+ - Improved cookie attribute handling to ensure consistency between Python and Rust layers.
20
+ - **Response Unwrapping**: Fixed a bug where returning a `Response` object inside another `Response` (common in error handlers using `render_template`) resulted in the object's string representation being sent as the body.
21
+ - **FFI Stability**: Standardized the Python-to-Rust response conversion to ensure reliable header serialization.
22
+
5
23
  ## [0.12.0] - 2026-04-27
6
24
 
7
25
  ### Added
@@ -438,7 +438,7 @@ checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb"
438
438
 
439
439
  [[package]]
440
440
  name = "bustapi_core"
441
- version = "0.12.0"
441
+ version = "0.13.0"
442
442
  dependencies = [
443
443
  "actix-files",
444
444
  "actix-http",
@@ -488,9 +488,9 @@ checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"
488
488
 
489
489
  [[package]]
490
490
  name = "bytestring"
491
- version = "1.5.0"
491
+ version = "1.5.1"
492
492
  source = "registry+https://github.com/rust-lang/crates.io-index"
493
- checksum = "113b4343b5f6617e7ad401ced8de3cc8b012e73a594347c307b90db3e9271289"
493
+ checksum = "86566c496f2f47d9b8147a4c8b02ffdb69c919fe0c2b2e7195d22cbba0e635c9"
494
494
  dependencies = [
495
495
  "bytes",
496
496
  ]
@@ -1262,9 +1262,9 @@ dependencies = [
1262
1262
 
1263
1263
  [[package]]
1264
1264
  name = "idna_adapter"
1265
- version = "1.2.1"
1265
+ version = "1.2.2"
1266
1266
  source = "registry+https://github.com/rust-lang/crates.io-index"
1267
- checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344"
1267
+ checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714"
1268
1268
  dependencies = [
1269
1269
  "icu_normalizer",
1270
1270
  "icu_properties",
@@ -1344,10 +1344,12 @@ dependencies = [
1344
1344
 
1345
1345
  [[package]]
1346
1346
  name = "js-sys"
1347
- version = "0.3.95"
1347
+ version = "0.3.97"
1348
1348
  source = "registry+https://github.com/rust-lang/crates.io-index"
1349
- checksum = "2964e92d1d9dc3364cae4d718d93f227e3abb088e747d92e0395bfdedf1c12ca"
1349
+ checksum = "a1840c94c045fbcf8ba2812c95db44499f7c64910a912551aaaa541decebcacf"
1350
1350
  dependencies = [
1351
+ "cfg-if",
1352
+ "futures-util",
1351
1353
  "once_cell",
1352
1354
  "wasm-bindgen",
1353
1355
  ]
@@ -2487,9 +2489,9 @@ dependencies = [
2487
2489
 
2488
2490
  [[package]]
2489
2491
  name = "wasm-bindgen"
2490
- version = "0.2.118"
2492
+ version = "0.2.120"
2491
2493
  source = "registry+https://github.com/rust-lang/crates.io-index"
2492
- checksum = "0bf938a0bacb0469e83c1e148908bd7d5a6010354cf4fb73279b7447422e3a89"
2494
+ checksum = "df52b6d9b87e0c74c9edfa1eb2d9bf85e5d63515474513aa50fa181b3c4f5db1"
2493
2495
  dependencies = [
2494
2496
  "cfg-if",
2495
2497
  "once_cell",
@@ -2500,9 +2502,9 @@ dependencies = [
2500
2502
 
2501
2503
  [[package]]
2502
2504
  name = "wasm-bindgen-macro"
2503
- version = "0.2.118"
2505
+ version = "0.2.120"
2504
2506
  source = "registry+https://github.com/rust-lang/crates.io-index"
2505
- checksum = "eeff24f84126c0ec2db7a449f0c2ec963c6a49efe0698c4242929da037ca28ed"
2507
+ checksum = "78b1041f495fb322e64aca85f5756b2172e35cd459376e67f2a6c9dffcedb103"
2506
2508
  dependencies = [
2507
2509
  "quote",
2508
2510
  "wasm-bindgen-macro-support",
@@ -2510,9 +2512,9 @@ dependencies = [
2510
2512
 
2511
2513
  [[package]]
2512
2514
  name = "wasm-bindgen-macro-support"
2513
- version = "0.2.118"
2515
+ version = "0.2.120"
2514
2516
  source = "registry+https://github.com/rust-lang/crates.io-index"
2515
- checksum = "9d08065faf983b2b80a79fd87d8254c409281cf7de75fc4b773019824196c904"
2517
+ checksum = "9dcd0ff20416988a18ac686d4d4d0f6aae9ebf08a389ff5d29012b05af2a1b41"
2516
2518
  dependencies = [
2517
2519
  "bumpalo",
2518
2520
  "proc-macro2",
@@ -2523,9 +2525,9 @@ dependencies = [
2523
2525
 
2524
2526
  [[package]]
2525
2527
  name = "wasm-bindgen-shared"
2526
- version = "0.2.118"
2528
+ version = "0.2.120"
2527
2529
  source = "registry+https://github.com/rust-lang/crates.io-index"
2528
- checksum = "5fd04d9e306f1907bd13c6361b5c6bfc7b3b3c095ed3f8a9246390f8dbdee129"
2530
+ checksum = "49757b3c82ebf16c57d69365a142940b384176c24df52a087fb748e2085359ea"
2529
2531
  dependencies = [
2530
2532
  "unicode-ident",
2531
2533
  ]
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "bustapi_core"
3
- version = "0.12.0"
3
+ version = "0.13.0"
4
4
  edition = "2021"
5
5
  readme = "README.md"
6
6
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bustapi
3
- Version: 0.12.0
3
+ Version: 0.13.0
4
4
  Classifier: Development Status :: 3 - Alpha
5
5
  Classifier: Intended Audience :: Developers
6
6
  Classifier: License :: OSI Approved :: MIT License
@@ -61,10 +61,10 @@ Author-email: GrandpaEJ <>
61
61
  License: MIT
62
62
  Requires-Python: >=3.10
63
63
  Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
64
- Project-URL: Documentation, https://grandpaej.github.io/BustAPI/
65
- Project-URL: Homepage, https://github.com/GrandpaEJ/bustapi
66
- Project-URL: Issues, https://github.com/GrandpaEJ/bustapi/issues
67
- Project-URL: Repository, https://github.com/GrandpaEJ/bustapi.git
64
+ Project-URL: Documentation, https://RUSTxPY.github.io/BustAPI/
65
+ Project-URL: Homepage, https://github.com/RUSTxPY/BustAPI
66
+ Project-URL: Issues, https://github.com/RUSTxPY/BustAPI/issues
67
+ Project-URL: Repository, https://github.com/RUSTxPY/BustAPI.git
68
68
 
69
69
  # BustAPI — High-Performance Python Web Framework
70
70
 
@@ -107,6 +107,7 @@ Under the hood, BustAPI runs on [Actix-Web](https://actix.rs/) — consistently
107
107
  - 🦀 **Rust-powered** — Zero-copy JSON, mimalloc allocator, Actix-Web
108
108
  - 🐍 **Pure Python API** — No Rust knowledge required
109
109
  - 🔒 **Security built-in** — JWT, sessions, CSRF, rate limiting
110
+ - 🛡️ **Robust Header System** — Case-insensitive, multi-value support, high-performance cookie parsing
110
111
  - 📦 **Zero config** — `pip install bustapi` and you're ready
111
112
  - 🔥 **Hot reload** — Rust-native file watcher for instant restarts
112
113
 
@@ -510,13 +511,13 @@ CMD ["python", "app.py"]
510
511
 
511
512
  ## 📖 Documentation
512
513
 
513
- 📚 **[Full Documentation](https://grandpaej.github.io/BustAPI/)**
514
+ 📚 **[Full Documentation](https://RUSTxPY.github.io/BustAPI/)**
514
515
 
515
- - [Getting Started](https://grandpaej.github.io/BustAPI/quickstart/)
516
- - [Routing Guide](https://grandpaej.github.io/BustAPI/user-guide/routing/)
517
- - [JWT Authentication](https://grandpaej.github.io/BustAPI/user-guide/jwt/)
518
- - [WebSocket Guide](https://grandpaej.github.io/BustAPI/user-guide/websocket/)
519
- - [API Reference](https://grandpaej.github.io/BustAPI/api-reference/)
516
+ - [Getting Started](https://RUSTxPY.github.io/BustAPI/quickstart/)
517
+ - [Routing Guide](https://RUSTxPY.github.io/BustAPI/user-guide/routing/)
518
+ - [JWT Authentication](https://RUSTxPY.github.io/BustAPI/user-guide/jwt/)
519
+ - [WebSocket Guide](https://RUSTxPY.github.io/BustAPI/user-guide/websocket/)
520
+ - [API Reference](https://RUSTxPY.github.io/BustAPI/api-reference/)
520
521
 
521
522
  ---
522
523
 
@@ -532,8 +533,8 @@ We welcome contributions! Here's how:
532
533
 
533
534
  Found a bug? Have a feature request?
534
535
 
535
- - [Open an Issue](https://github.com/GrandpaEJ/bustapi/issues)
536
- - [Start a Discussion](https://github.com/GrandpaEJ/bustapi/discussions)
536
+ - [Open an Issue](https://github.com/RUSTxPY/BustAPI/issues)
537
+ - [Start a Discussion](https://github.com/RUSTxPY/BustAPI/discussions)
537
538
 
538
539
  ---
539
540
 
@@ -39,6 +39,7 @@ Under the hood, BustAPI runs on [Actix-Web](https://actix.rs/) — consistently
39
39
  - 🦀 **Rust-powered** — Zero-copy JSON, mimalloc allocator, Actix-Web
40
40
  - 🐍 **Pure Python API** — No Rust knowledge required
41
41
  - 🔒 **Security built-in** — JWT, sessions, CSRF, rate limiting
42
+ - 🛡️ **Robust Header System** — Case-insensitive, multi-value support, high-performance cookie parsing
42
43
  - 📦 **Zero config** — `pip install bustapi` and you're ready
43
44
  - 🔥 **Hot reload** — Rust-native file watcher for instant restarts
44
45
 
@@ -442,13 +443,13 @@ CMD ["python", "app.py"]
442
443
 
443
444
  ## 📖 Documentation
444
445
 
445
- 📚 **[Full Documentation](https://grandpaej.github.io/BustAPI/)**
446
+ 📚 **[Full Documentation](https://RUSTxPY.github.io/BustAPI/)**
446
447
 
447
- - [Getting Started](https://grandpaej.github.io/BustAPI/quickstart/)
448
- - [Routing Guide](https://grandpaej.github.io/BustAPI/user-guide/routing/)
449
- - [JWT Authentication](https://grandpaej.github.io/BustAPI/user-guide/jwt/)
450
- - [WebSocket Guide](https://grandpaej.github.io/BustAPI/user-guide/websocket/)
451
- - [API Reference](https://grandpaej.github.io/BustAPI/api-reference/)
448
+ - [Getting Started](https://RUSTxPY.github.io/BustAPI/quickstart/)
449
+ - [Routing Guide](https://RUSTxPY.github.io/BustAPI/user-guide/routing/)
450
+ - [JWT Authentication](https://RUSTxPY.github.io/BustAPI/user-guide/jwt/)
451
+ - [WebSocket Guide](https://RUSTxPY.github.io/BustAPI/user-guide/websocket/)
452
+ - [API Reference](https://RUSTxPY.github.io/BustAPI/api-reference/)
452
453
 
453
454
  ---
454
455
 
@@ -464,8 +465,8 @@ We welcome contributions! Here's how:
464
465
 
465
466
  Found a bug? Have a feature request?
466
467
 
467
- - [Open an Issue](https://github.com/GrandpaEJ/bustapi/issues)
468
- - [Start a Discussion](https://github.com/GrandpaEJ/bustapi/discussions)
468
+ - [Open an Issue](https://github.com/RUSTxPY/BustAPI/issues)
469
+ - [Start a Discussion](https://github.com/RUSTxPY/BustAPI/discussions)
469
470
 
470
471
  ---
471
472
 
@@ -2,6 +2,24 @@
2
2
 
3
3
  All notable changes to this project will be documented here.
4
4
 
5
+ ## [0.13.0] - 2026-05-02
6
+
7
+ ### Added
8
+ - **Robust Header Infrastructure**:
9
+ - Refactored `Headers` class to use `collections.UserDict` for better standard library compatibility.
10
+ - Implemented full case-insensitivity for all header operations (get, set, delete).
11
+ - Added native support for multi-value headers via `headers.add(key, value)` and `headers.getlist(key)`.
12
+ - **WSGI Adapter Enhancements**:
13
+ - Refactored `WSGIAdapter` to correctly handle multi-value headers.
14
+ - Integrated application-level error handling (including custom 404/500 handlers) into the WSGI layer.
15
+
16
+ ### Fixed
17
+ - **JWT & Cookie Security**:
18
+ - Updated `Response.delete_cookie()` signature to accept `secure`, `httponly`, and `samesite` arguments, fixing crashes in JWT logout flows.
19
+ - Improved cookie attribute handling to ensure consistency between Python and Rust layers.
20
+ - **Response Unwrapping**: Fixed a bug where returning a `Response` object inside another `Response` (common in error handlers using `render_template`) resulted in the object's string representation being sent as the body.
21
+ - **FFI Stability**: Standardized the Python-to-Rust response conversion to ensure reliable header serialization.
22
+
5
23
  ## [0.12.0] - 2026-04-27
6
24
 
7
25
  ### Added
@@ -1,7 +1,7 @@
1
1
  # BustAPI Complete API Reference
2
2
 
3
- > **Version:** 0.3.1
4
- > **Last Updated:** 2025-12-10
3
+ > **Version:** 0.13.0
4
+ > **Last Updated:** 2026-05-02
5
5
 
6
6
  ## Table of Contents
7
7
 
@@ -356,8 +356,29 @@ response.data # Response body as bytes
356
356
  ```python
357
357
  response.set_data(data) # Set response data
358
358
  response.get_data(as_text=False) # Get response data
359
- response.set_cookie(key, value, ...) # Set a cookie
360
- response.delete_cookie(key, ...) # Delete a cookie
359
+
360
+ # Set a cookie
361
+ response.set_cookie(
362
+ key: str,
363
+ value: str = '',
364
+ max_age: Optional[int] = None,
365
+ expires: Optional[Union[datetime, float]] = None,
366
+ path: str = '/',
367
+ domain: Optional[str] = None,
368
+ secure: bool = False,
369
+ httponly: bool = False,
370
+ samesite: Optional[str] = 'Lax'
371
+ )
372
+
373
+ # Delete a cookie
374
+ response.delete_cookie(
375
+ key: str,
376
+ path: str = '/',
377
+ domain: Optional[str] = None,
378
+ secure: bool = False,
379
+ httponly: bool = False,
380
+ samesite: Optional[str] = 'Lax'
381
+ )
361
382
  ```
362
383
 
363
384
  **Example:**
@@ -371,6 +392,30 @@ def custom_response():
371
392
  return resp
372
393
  ```
373
394
 
395
+ ### Headers Object
396
+
397
+ The `response.headers` object provides a case-insensitive dictionary-like interface for managing HTTP headers.
398
+
399
+ #### Methods
400
+
401
+ - `get(key, default=None)`: Get the first value for a header (case-insensitive).
402
+ - `add(key, value)`: Add a value to a header, preserving existing values (multi-value support).
403
+ - `getlist(key)`: Get all values for a header as a list.
404
+ - `setlist(key, values)`: Set multiple values for a header.
405
+ - `items()`: Get all header key-value pairs as a list of tuples.
406
+
407
+ **Example:**
408
+
409
+ ```python
410
+ resp.headers['Content-Type'] = 'application/json'
411
+ resp.headers.add('Link', '<https://example.com>; rel="next"')
412
+ resp.headers.add('Link', '<https://example.com>; rel="prev"')
413
+
414
+ links = resp.headers.getlist('Link') # ['...', '...']
415
+ ```
416
+
417
+ ---
418
+
374
419
  #### Response Helper Functions
375
420
 
376
421
  ##### `jsonify(*args, **kwargs)`
@@ -1076,14 +1121,30 @@ def internal_error(error):
1076
1121
 
1077
1122
  #### Exception Handlers
1078
1123
 
1079
- ```python
1124
+ ````python
1080
1125
  class ValidationError(Exception):
1081
1126
  pass
1082
1127
 
1083
1128
  @app.errorhandler(ValidationError)
1084
1129
  def handle_validation_error(error):
1085
1130
  return {'error': str(error), 'type': 'validation_error'}, 400
1086
- ```
1131
+
1132
+ #### Catch-All Handler
1133
+
1134
+ Handle all otherwise unhandled exceptions:
1135
+
1136
+ ```python
1137
+ @app.errorhandler(Exception)
1138
+ def handle_exception(e):
1139
+ # Pass through HTTP errors
1140
+ if hasattr(e, "get_response"):
1141
+ return e.get_response()
1142
+
1143
+ # Generic error for everything else
1144
+ return {"error": "Something went wrong"}, 500
1145
+ ````
1146
+
1147
+ ````
1087
1148
 
1088
1149
  ### Using `abort()`
1089
1150
 
@@ -1102,7 +1163,7 @@ def admin():
1102
1163
  if not is_admin():
1103
1164
  abort(403, 'Admin access required')
1104
1165
  return {'message': 'Admin panel'}
1105
- ```
1166
+ ````
1106
1167
 
1107
1168
  ### Complete Error Handling Example
1108
1169
 
@@ -1546,11 +1607,11 @@ app.run(
1546
1607
  ```python
1547
1608
  import bustapi
1548
1609
 
1549
- print(bustapi.__version__) # '0.3.1'
1550
- print(bustapi.get_version()) # '0.3.1'
1610
+ print(bustapi.__version__) # '0.13.0'
1611
+ print(bustapi.get_version()) # '0.13.0'
1551
1612
  print(bustapi.get_debug_info()) # Detailed version info
1552
1613
  ```
1553
1614
 
1554
1615
  ---
1555
1616
 
1556
- _This documentation covers BustAPI version 0.3.1. For the latest updates, visit the [official documentation](https://grandpaej.github.io/BustAPI/)._
1617
+ _This documentation covers BustAPI version 0.13.0. For the latest updates, visit the [official documentation](https://rustxpy.github.io/BustAPI/)._
@@ -12,6 +12,15 @@ The `examples/` directory in the repository contains many complete scripts demon
12
12
  - **03_async.py**: Using `async def` for non-blocking routes.
13
13
  - **04_request_data.py**: accessing query args and form data.
14
14
 
15
+ ## Security & Authentication
16
+
17
+ Learn how to protect your application.
18
+
19
+ - **17_jwt_auth.py**: Standard JWT authentication using the Authorization header.
20
+ - **18_jwt_cookies.py**: Secure JWT implementation using HttpOnly cookies.
21
+ - **11_security_demo.py**: Implementing security headers.
22
+ - **10_rate_limit_demo.py**: Using the built-in rate limiter to prevent abuse.
23
+
15
24
  ## Data & Validation
16
25
 
17
26
  Learn how to robustly handle input.
@@ -27,8 +36,6 @@ For production-grade applications.
27
36
 
28
37
  - **06_blueprints.py**: Organizing your app into modules.
29
38
  - **14_middleware.py**: Custom request/response hooks.
30
- - **10_rate_limit_demo.py**: Using the built-in rate limiter to prevent abuse.
31
- - **11_security_demo.py**: Implementing security headers.
32
39
 
33
40
  ## Database & Templates
34
41
 
@@ -44,7 +44,8 @@ if __name__ == "__main__":
44
44
  - **Multiprocessing** - `workers=4` for parallel request handling on Linux
45
45
  - **JWT Authentication** - Built-in token-based auth
46
46
  - **Templates** - Jinja2 template rendering
47
- - **Blueprints** - Modular app organization
47
+ - **Blueprints** - Modular app organization
48
+ - **Auto-Documentation** - Instant OpenAPI/Swagger & ReDoc UI
48
49
 
49
50
  ---
50
51
 
@@ -79,3 +80,4 @@ Supports Python **3.10 - 3.14** on Linux, macOS, and Windows.
79
80
  - [Turbo Routes](user-guide/turbo-routes.md) - Maximum performance
80
81
  - [Multiprocessing](user-guide/multiprocessing.md) - Scale to 100k+ RPS
81
82
  - [JWT Auth](user-guide/jwt.md) - Secure your API
83
+ - [Auto-Documentation](user-guide/documentation.md) - Swagger & ReDoc
@@ -157,4 +157,8 @@ if __name__ == "__main__":
157
157
 
158
158
  Secure your API with tokens.
159
159
 
160
+ - [:material-book-open: **Auto-Docs**](user-guide/documentation.md)
161
+
162
+ Interactive Swagger & ReDoc UI.
163
+
160
164
  </div>
@@ -2,6 +2,9 @@
2
2
 
3
3
  Flask-Login style session-based authentication for BustAPI.
4
4
 
5
+ > [!TIP]
6
+ > For stateless APIs or mobile backends, consider using [JWT Authentication](jwt.md) instead.
7
+
5
8
  ## Quick Start
6
9
 
7
10
  ```python
@@ -0,0 +1,144 @@
1
+ # Auto-Documentation
2
+
3
+ BustAPI provides automatic OpenAPI (Swagger) and ReDoc documentation for your application via the `BustAPIDocs` extension. It extracts information from route signatures, docstrings, and parameter validators.
4
+
5
+ ## Comparison with FastAPI
6
+
7
+ BustAPI's documentation system is designed to be familiar to FastAPI users while leveraging BustAPI's high-performance Rust backend.
8
+
9
+ | Feature | FastAPI | BustAPI |
10
+ |:---|:---|:---|
11
+ | **Engine** | Starlette / Pydantic | **Actix-web / Rust-core** |
12
+ | **Setup** | Automatic in `FastAPI()` | Manual via `BustAPIDocs(app)` |
13
+ | **Parameters** | `Query()`, `Path()`, `Body()` | `Query()`, `Path()`, `Body()` |
14
+ | **Validation** | Pydantic Models | `Struct` or `dict` schemas |
15
+ | **UI Endpoints** | `/docs`, `/redoc` | `/docs`, `/redoc` |
16
+ | **Metadata** | `tags`, `summary`, `description` | `tags`, `summary`, `description` |
17
+ | **Performance** | High (Python-based) | **Extreme (Rust-core parsing)** |
18
+
19
+ ## Basic Setup
20
+
21
+ Initialize the `BustAPIDocs` extension with your application to enable the documentation endpoints.
22
+
23
+ ```python
24
+ from bustapi import BustAPI, BustAPIDocs
25
+
26
+ app = BustAPI()
27
+
28
+ # Configure auto-documentation
29
+ docs = BustAPIDocs(
30
+ app,
31
+ title="My Store API",
32
+ version="1.0.0",
33
+ description="API for managing items and users",
34
+ docs_url="/docs", # Swagger UI path
35
+ redoc_url="/redoc", # ReDoc path
36
+ openapi_url="/openapi.json"
37
+ )
38
+ ```
39
+
40
+ ## Documenting Parameters
41
+
42
+ BustAPI automatically documents parameters defined in your route handlers using `Path`, `Query`, and `Body` validators.
43
+
44
+ ### Query Parameters
45
+
46
+ Use `Query()` to add constraints and metadata to query strings.
47
+
48
+ ```python
49
+ from bustapi import Query
50
+
51
+ @app.route("/search")
52
+ def search(
53
+ q: str = Query(..., min_length=3, description="Search query"),
54
+ page: int = Query(1, ge=1, description="Page number")
55
+ ):
56
+ return {"q": q, "page": page}
57
+ ```
58
+
59
+ ### Path Parameters
60
+
61
+ `Path()` works similarly for URL path segments.
62
+
63
+ ```python
64
+ from bustapi import Path
65
+
66
+ @app.route("/items/<int:item_id>")
67
+ def get_item(item_id: int = Path(..., ge=1, title="Item ID")):
68
+ return {"id": item_id}
69
+ ```
70
+
71
+ ### Request Bodies
72
+
73
+ The `Body()` validator documents JSON request bodies. You can provide a `schema` dictionary to define fields and their constraints.
74
+
75
+ ```python
76
+ from bustapi import Body
77
+
78
+ @app.route("/items", methods=["POST"])
79
+ def create_item(
80
+ item: dict = Body(..., schema={
81
+ "name": {"type": "str", "min_length": 1, "description": "Item name"},
82
+ "price": {"type": "float", "gt": 0, "description": "Price in USD"},
83
+ "tags": {"type": "list", "required": False}
84
+ })
85
+ ):
86
+ return {"created": item}
87
+ ```
88
+
89
+ ## Route Metadata
90
+
91
+ You can further customize documentation for specific routes using decorator arguments:
92
+
93
+ ```python
94
+ @app.route(
95
+ "/protected",
96
+ methods=["GET"],
97
+ tags=["Security"],
98
+ summary="Access protected resource",
99
+ description="This endpoint requires an active session.",
100
+ deprecated=True
101
+ )
102
+ def protected_route():
103
+ return {"status": "ok"}
104
+ ```
105
+
106
+ ### Custom Responses
107
+
108
+ Define specific response codes and their descriptions:
109
+
110
+ ```python
111
+ @app.route(
112
+ "/items/<int:id>",
113
+ responses={
114
+ 200: {"description": "Item found"},
115
+ 404: {"description": "Item not in database"}
116
+ }
117
+ )
118
+ def get_item_with_docs(id):
119
+ return {"id": id}
120
+ ```
121
+
122
+ ## Response Models
123
+
124
+ If you use `Struct` from `bustapi.safe.types`, you can specify it as a `response_model` to automatically generate a reusable schema in the documentation.
125
+
126
+ ```python
127
+ from bustapi.safe.types import Struct
128
+
129
+ class Item(Struct):
130
+ id: int
131
+ name: str
132
+
133
+ @app.route("/item", response_model=Item)
134
+ def get_item_model():
135
+ return Item(id=1, name="Tool")
136
+ ```
137
+
138
+ ## UI Endpoints
139
+
140
+ Once initialized, your documentation is accessible at:
141
+
142
+ - **Swagger UI**: `http://127.0.0.1:5000/docs` (interactive "Try it out" support)
143
+ - **ReDoc**: `http://127.0.0.1:5000/redoc` (clean, readable layout)
144
+ - **OpenAPI JSON**: `http://127.0.0.1:5000/openapi.json` (raw specification)
@@ -37,3 +37,33 @@ def admin():
37
37
  abort(403, description="Admins only!")
38
38
  return "Welcome Admin"
39
39
  ```
40
+
41
+ ## Catch-All Error Handler
42
+
43
+ To handle any unhandled exception (the "else" block), you can register a handler for the base `Exception` class.
44
+
45
+ ```python
46
+ @app.errorhandler(Exception)
47
+ def handle_unexpected_error(e):
48
+ # Log the error
49
+ app.logger.error(f"Unexpected error: {e}")
50
+
51
+ # If it's already an HTTP error, let it handle itself
52
+ if hasattr(e, "get_response"):
53
+ return e.get_response()
54
+
55
+ return {"error": "An internal error occurred"}, 500
56
+ ```
57
+
58
+ ## Custom Exceptions
59
+
60
+ You can create your own exception classes and register handlers for them.
61
+
62
+ ```python
63
+ class PaymentRequired(Exception):
64
+ pass
65
+
66
+ @app.errorhandler(PaymentRequired)
67
+ def handle_payment_required(e):
68
+ return "Please pay to continue", 402
69
+ ```