foghttp 0.3.6__tar.gz → 0.3.7__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 (547) hide show
  1. {foghttp-0.3.6 → foghttp-0.3.7}/.flake8 +4 -3
  2. {foghttp-0.3.6 → foghttp-0.3.7}/.github/workflows/ci.yml +2 -2
  3. {foghttp-0.3.6 → foghttp-0.3.7}/Cargo.lock +1 -1
  4. {foghttp-0.3.6 → foghttp-0.3.7}/Cargo.toml +1 -1
  5. {foghttp-0.3.6 → foghttp-0.3.7}/PKG-INFO +11 -6
  6. {foghttp-0.3.6 → foghttp-0.3.7}/README.md +10 -5
  7. {foghttp-0.3.6 → foghttp-0.3.7}/docs/index.md +8 -1
  8. {foghttp-0.3.6 → foghttp-0.3.7}/docs/limitations.md +4 -0
  9. {foghttp-0.3.6 → foghttp-0.3.7}/docs/packaging.md +5 -3
  10. foghttp-0.3.7/docs/policy-hooks.md +109 -0
  11. {foghttp-0.3.6 → foghttp-0.3.7}/docs/pyo3-boundary.md +40 -0
  12. {foghttp-0.3.6 → foghttp-0.3.7}/docs/quickstart.md +23 -1
  13. {foghttp-0.3.6 → foghttp-0.3.7}/docs/redirects.md +39 -36
  14. {foghttp-0.3.6 → foghttp-0.3.7}/docs/request-builder.md +49 -0
  15. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/__init__.py +12 -0
  16. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/config.py +5 -0
  17. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/core.py +3 -0
  18. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/options.py +2 -0
  19. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/raw/lifecycle.py +1 -0
  20. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/raw/requests.py +6 -0
  21. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/request_builder/builder.py +1 -0
  22. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/request_builder/models.py +2 -0
  23. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/response.py +12 -7
  24. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/transport.py +4 -4
  25. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/transport_requests.py +1 -0
  26. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_foghttp.pyi +5 -0
  27. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/async_client.py +29 -4
  28. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/client.py +22 -0
  29. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/models.py +2 -0
  30. foghttp-0.3.7/foghttp/policy.py +111 -0
  31. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/request.py +18 -2
  32. foghttp-0.3.7/foghttp/request_extensions.py +76 -0
  33. foghttp-0.3.7/foghttp/request_info.py +28 -0
  34. {foghttp-0.3.6 → foghttp-0.3.7}/pyproject.toml +1 -1
  35. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/mod.rs +1 -0
  36. foghttp-0.3.7/src/core/policy/error.rs +41 -0
  37. foghttp-0.3.7/src/core/policy/mod.rs +14 -0
  38. foghttp-0.3.7/src/core/policy/pipeline.rs +109 -0
  39. foghttp-0.3.7/src/core/policy/proxy.rs +58 -0
  40. foghttp-0.3.7/src/core/policy/redirect/action.rs +42 -0
  41. foghttp-0.3.7/src/core/policy/redirect/headers.rs +89 -0
  42. foghttp-0.3.7/src/core/policy/redirect/method.rs +28 -0
  43. foghttp-0.3.7/src/core/policy/redirect/mod.rs +12 -0
  44. foghttp-0.3.7/src/core/policy/redirect/policy.rs +47 -0
  45. {foghttp-0.3.6/src/py/client/redirects → foghttp-0.3.7/src/core/policy/redirect}/status.rs +1 -1
  46. foghttp-0.3.7/src/core/policy/redirect/tests.rs +306 -0
  47. {foghttp-0.3.6/src/py/client/redirects → foghttp-0.3.7/src/core/policy/redirect}/utils.rs +1 -1
  48. foghttp-0.3.7/src/core/policy/request.rs +77 -0
  49. foghttp-0.3.7/src/core/policy/tests.rs +189 -0
  50. {foghttp-0.3.6 → foghttp-0.3.7}/src/messages.rs +2 -2
  51. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/mod.rs +34 -4
  52. foghttp-0.3.7/src/py/client/policy_hooks.rs +170 -0
  53. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/transport/buffered.rs +21 -34
  54. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/transport/client.rs +11 -11
  55. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/transport/context.rs +1 -4
  56. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/transport/errors.rs +5 -0
  57. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/transport/mod.rs +0 -1
  58. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/transport/request.rs +135 -65
  59. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/transport/response.rs +50 -28
  60. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/transport/streaming.rs +20 -50
  61. foghttp-0.3.7/src/py/client/transport/tests.rs +182 -0
  62. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_lifecycle/helpers.py +1 -0
  63. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_options/test_raw_numeric_boundary.py +17 -0
  64. foghttp-0.3.7/tests/client_policy_hooks/requests.py +20 -0
  65. foghttp-0.3.7/tests/client_policy_hooks/test_async_hooks.py +150 -0
  66. foghttp-0.3.7/tests/client_policy_hooks/test_contract.py +122 -0
  67. foghttp-0.3.7/tests/client_policy_hooks/test_sync_hooks.py +241 -0
  68. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_proxy/client_options.py +1 -0
  69. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_transport/models.py +1 -0
  70. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_transport/test_transport_adapter.py +6 -0
  71. {foghttp-0.3.6 → foghttp-0.3.7}/tests/pyo3_boundary/test_raw_client_signatures.py +3 -0
  72. {foghttp-0.3.6 → foghttp-0.3.7}/tests/redirect_helpers.py +22 -0
  73. foghttp-0.3.7/tests/request_builder/test_extensions.py +88 -0
  74. {foghttp-0.3.6 → foghttp-0.3.7}/tests/request_builder/test_shortcuts.py +10 -0
  75. {foghttp-0.3.6 → foghttp-0.3.7}/tests/request_factories.py +3 -0
  76. {foghttp-0.3.6 → foghttp-0.3.7}/tests/support/raw_responses.py +31 -16
  77. {foghttp-0.3.6 → foghttp-0.3.7}/tests/support/sync_http_server.py +7 -17
  78. {foghttp-0.3.6 → foghttp-0.3.7}/tests/test_async_redirects.py +55 -13
  79. {foghttp-0.3.6 → foghttp-0.3.7}/tests/test_public_api.py +2 -0
  80. {foghttp-0.3.6 → foghttp-0.3.7}/tests/test_raw_client.py +39 -0
  81. {foghttp-0.3.6 → foghttp-0.3.7}/tests/test_raw_client_errors.py +1 -0
  82. {foghttp-0.3.6 → foghttp-0.3.7}/tests/test_redaction.py +11 -0
  83. foghttp-0.3.7/tests/test_request_extensions.py +95 -0
  84. {foghttp-0.3.6 → foghttp-0.3.7}/tests/test_sync_redirects.py +75 -13
  85. foghttp-0.3.7/tests/types/__init__.py +0 -0
  86. foghttp-0.3.7/tests/types/test_policy_contracts.py +40 -0
  87. foghttp-0.3.7/tests/types/test_request_extensions_contracts.py +30 -0
  88. {foghttp-0.3.6 → foghttp-0.3.7}/uv.lock +1 -1
  89. foghttp-0.3.6/foghttp/request_info.py +0 -18
  90. foghttp-0.3.6/src/py/client/body.rs +0 -19
  91. foghttp-0.3.6/src/py/client/redirects/action.rs +0 -42
  92. foghttp-0.3.6/src/py/client/redirects/headers.rs +0 -43
  93. foghttp-0.3.6/src/py/client/redirects/method.rs +0 -24
  94. foghttp-0.3.6/src/py/client/redirects/mod.rs +0 -12
  95. foghttp-0.3.6/src/py/client/redirects/policy.rs +0 -42
  96. foghttp-0.3.6/src/py/client/redirects/tests.rs +0 -212
  97. foghttp-0.3.6/src/py/client/transport/proxy.rs +0 -66
  98. foghttp-0.3.6/src/py/client/transport/tests.rs +0 -215
  99. {foghttp-0.3.6 → foghttp-0.3.7}/.github/workflows/release.yml +0 -0
  100. {foghttp-0.3.6 → foghttp-0.3.7}/.gitignore +0 -0
  101. {foghttp-0.3.6 → foghttp-0.3.7}/.pre-commit-config.yaml +0 -0
  102. {foghttp-0.3.6 → foghttp-0.3.7}/CODE_OF_CONDUCT.md +0 -0
  103. {foghttp-0.3.6 → foghttp-0.3.7}/CONTRIBUTING.md +0 -0
  104. {foghttp-0.3.6 → foghttp-0.3.7}/LICENSE +0 -0
  105. {foghttp-0.3.6 → foghttp-0.3.7}/SECURITY.md +0 -0
  106. {foghttp-0.3.6 → foghttp-0.3.7}/docs/benchmarks.md +0 -0
  107. {foghttp-0.3.6 → foghttp-0.3.7}/docs/lifecycle.md +0 -0
  108. {foghttp-0.3.6 → foghttp-0.3.7}/docs/proxies.md +0 -0
  109. {foghttp-0.3.6 → foghttp-0.3.7}/docs/streaming.md +0 -0
  110. {foghttp-0.3.6 → foghttp-0.3.7}/docs/telemetry.md +0 -0
  111. {foghttp-0.3.6 → foghttp-0.3.7}/docs/timeouts.md +0 -0
  112. {foghttp-0.3.6 → foghttp-0.3.7}/docs/tls.md +0 -0
  113. {foghttp-0.3.6 → foghttp-0.3.7}/docs/upload-types.md +0 -0
  114. {foghttp-0.3.6 → foghttp-0.3.7}/docs/use-cases.md +0 -0
  115. {foghttp-0.3.6 → foghttp-0.3.7}/examples/README.md +0 -0
  116. {foghttp-0.3.6 → foghttp-0.3.7}/examples/async_json_fanout.py +0 -0
  117. {foghttp-0.3.6 → foghttp-0.3.7}/examples/async_lifecycle_debug.py +0 -0
  118. {foghttp-0.3.6 → foghttp-0.3.7}/examples/async_resource_limits.py +0 -0
  119. {foghttp-0.3.6 → foghttp-0.3.7}/examples/async_streaming.py +0 -0
  120. {foghttp-0.3.6 → foghttp-0.3.7}/examples/compressed_response.py +0 -0
  121. {foghttp-0.3.6 → foghttp-0.3.7}/examples/http_proxy.py +0 -0
  122. {foghttp-0.3.6 → foghttp-0.3.7}/examples/multipart_uploads.py +0 -0
  123. {foghttp-0.3.6 → foghttp-0.3.7}/examples/prepared_requests.py +0 -0
  124. {foghttp-0.3.6 → foghttp-0.3.7}/examples/redirects.py +0 -0
  125. {foghttp-0.3.6 → foghttp-0.3.7}/examples/request_builder_compatibility.py +0 -0
  126. {foghttp-0.3.6 → foghttp-0.3.7}/examples/sync_json_api.py +0 -0
  127. {foghttp-0.3.6 → foghttp-0.3.7}/examples/sync_streaming.py +0 -0
  128. {foghttp-0.3.6 → foghttp-0.3.7}/examples/telemetry_hooks.py +0 -0
  129. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/__init__.py +0 -0
  130. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/asyncio_futures.py +0 -0
  131. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/constants.py +0 -0
  132. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/lifecycle_debug.py +0 -0
  133. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/process.py +0 -0
  134. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/proxy/__init__.py +0 -0
  135. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/proxy/auth.py +0 -0
  136. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/proxy/constants.py +0 -0
  137. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/proxy/environment.py +0 -0
  138. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/proxy/models.py +0 -0
  139. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/proxy/no_proxy.py +0 -0
  140. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/proxy/no_proxy_rule.py +0 -0
  141. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/proxy/no_proxy_tokens.py +0 -0
  142. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/proxy/resolver.py +0 -0
  143. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/proxy/transport_policy.py +0 -0
  144. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/proxy/url_parsing.py +0 -0
  145. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/raw/__init__.py +0 -0
  146. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/raw/errors.py +0 -0
  147. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/raw/timeout_errors.py +0 -0
  148. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/request_builder/__init__.py +0 -0
  149. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/request_builder/defaults.py +0 -0
  150. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/request_builder/header_policy.py +0 -0
  151. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/request_builder/merge.py +0 -0
  152. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/runtime/__init__.py +0 -0
  153. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/runtime/constants.py +0 -0
  154. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/runtime/mode.py +0 -0
  155. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/runtime/validation.py +0 -0
  156. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/runtime/workers.py +0 -0
  157. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/stats.py +0 -0
  158. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/stream_context.py +0 -0
  159. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/telemetry/__init__.py +0 -0
  160. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/telemetry/clock.py +0 -0
  161. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/telemetry/dispatcher.py +0 -0
  162. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/telemetry/emission.py +0 -0
  163. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/telemetry/request_context.py +0 -0
  164. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/telemetry/request_events.py +0 -0
  165. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/telemetry/responses.py +0 -0
  166. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/telemetry/url.py +0 -0
  167. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/tls.py +0 -0
  168. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_client/transport_snapshot_mapping.py +0 -0
  169. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_multipart/__init__.py +0 -0
  170. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_multipart/constants.py +0 -0
  171. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_multipart/content_type.py +0 -0
  172. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_multipart/encoding.py +0 -0
  173. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_multipart/fields.py +0 -0
  174. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_multipart/file_parts.py +0 -0
  175. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_multipart/iterators.py +0 -0
  176. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_multipart/length.py +0 -0
  177. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_multipart/models.py +0 -0
  178. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_multipart/normalize.py +0 -0
  179. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_multipart/parts.py +0 -0
  180. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_multipart/stream.py +0 -0
  181. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_multipart/values.py +0 -0
  182. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_redaction.py +0 -0
  183. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_request_body.py +0 -0
  184. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_response/__init__.py +0 -0
  185. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_response/encoding.py +0 -0
  186. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_response/status.py +0 -0
  187. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_streaming/__init__.py +0 -0
  188. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_streaming/text/__init__.py +0 -0
  189. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_streaming/text/async_chunks.py +0 -0
  190. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_streaming/text/iterators.py +0 -0
  191. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_streaming/text/lines.py +0 -0
  192. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_streaming/text/sync_chunks.py +0 -0
  193. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_telemetry.py +0 -0
  194. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_upload_body/__init__.py +0 -0
  195. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_upload_body/async_sending.py +0 -0
  196. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_upload_body/chunks.py +0 -0
  197. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_upload_body/feeders.py +0 -0
  198. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_upload_body/file_source.py +0 -0
  199. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_upload_body/models.py +0 -0
  200. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_upload_body/normalize.py +0 -0
  201. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_upload_body/predicates.py +0 -0
  202. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_upload_body/runtime.py +0 -0
  203. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_upload_body/thread_bridge.py +0 -0
  204. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_validation/__init__.py +0 -0
  205. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/_validation/numeric.py +0 -0
  206. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/body.py +0 -0
  207. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/errors/__init__.py +0 -0
  208. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/errors/base.py +0 -0
  209. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/errors/lifecycle.py +0 -0
  210. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/errors/response.py +0 -0
  211. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/errors/timeout.py +0 -0
  212. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/headers.py +0 -0
  213. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/lifecycle_debug.py +0 -0
  214. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/limits.py +0 -0
  215. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/messages.py +0 -0
  216. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/methods.py +0 -0
  217. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/pool_diagnostics.py +0 -0
  218. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/py.typed +0 -0
  219. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/response.py +0 -0
  220. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/stats.py +0 -0
  221. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/status_codes/__init__.py +0 -0
  222. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/status_codes/client_error.py +0 -0
  223. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/status_codes/redirect.py +0 -0
  224. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/status_codes/server_error.py +0 -0
  225. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/status_codes/success.py +0 -0
  226. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/stream_response/__init__.py +0 -0
  227. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/stream_response/async_response.py +0 -0
  228. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/stream_response/base.py +0 -0
  229. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/stream_response/bindings.py +0 -0
  230. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/stream_response/constants.py +0 -0
  231. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/stream_response/lifecycle_debug.py +0 -0
  232. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/stream_response/status.py +0 -0
  233. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/stream_response/sync_response.py +0 -0
  234. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/stream_response/telemetry.py +0 -0
  235. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/telemetry/__init__.py +0 -0
  236. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/telemetry/config.py +0 -0
  237. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/telemetry/errors.py +0 -0
  238. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/telemetry/events.py +0 -0
  239. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/telemetry/sinks.py +0 -0
  240. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/timeout_diagnostics.py +0 -0
  241. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/timeouts.py +0 -0
  242. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/tls.py +0 -0
  243. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/transport_state.py +0 -0
  244. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/transport_stats.py +0 -0
  245. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/types/__init__.py +0 -0
  246. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/types/http.py +0 -0
  247. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/types/multipart.py +0 -0
  248. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/types/request.py +0 -0
  249. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/types/streams.py +0 -0
  250. {foghttp-0.3.6 → foghttp-0.3.7}/foghttp/url.py +0 -0
  251. {foghttp-0.3.6 → foghttp-0.3.7}/logo.png +0 -0
  252. {foghttp-0.3.6 → foghttp-0.3.7}/ruff.toml +0 -0
  253. {foghttp-0.3.6 → foghttp-0.3.7}/scripts/check_all_position.py +0 -0
  254. {foghttp-0.3.6 → foghttp-0.3.7}/scripts/install_wheel_smoke.py +0 -0
  255. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/client/body.rs +0 -0
  256. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/client/connection_limit.rs +0 -0
  257. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/client/mod.rs +0 -0
  258. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/client/proxy/authorization.rs +0 -0
  259. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/client/proxy/endpoint.rs +0 -0
  260. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/client/proxy/http.rs +0 -0
  261. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/client/proxy/mod.rs +0 -0
  262. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/client/proxy/tests.rs +0 -0
  263. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/client/proxy/tunnel.rs +0 -0
  264. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/client/telemetry/mod.rs +0 -0
  265. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/client/telemetry/tests.rs +0 -0
  266. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/client/write_timeout.rs +0 -0
  267. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/headers/mod.rs +0 -0
  268. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/headers/request.rs +0 -0
  269. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/headers/response.rs +0 -0
  270. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/headers/tests.rs +0 -0
  271. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/method.rs +0 -0
  272. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/metrics/atomic.rs +0 -0
  273. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/metrics/buffered.rs +0 -0
  274. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/metrics/counters.rs +0 -0
  275. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/metrics/lifecycle.rs +0 -0
  276. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/metrics/mod.rs +0 -0
  277. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/metrics/origin/blocking.rs +0 -0
  278. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/metrics/origin/metrics.rs +0 -0
  279. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/metrics/origin/mod.rs +0 -0
  280. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/metrics/origin/registry.rs +0 -0
  281. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/metrics/origin/snapshots.rs +0 -0
  282. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/metrics/origin/tests.rs +0 -0
  283. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/metrics/origin/waiters.rs +0 -0
  284. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/metrics/snapshots.rs +0 -0
  285. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/metrics/telemetry.rs +0 -0
  286. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/metrics/tests.rs +0 -0
  287. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/numeric/mod.rs +0 -0
  288. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/numeric/tests.rs +0 -0
  289. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/request.rs +0 -0
  290. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/response/body.rs +0 -0
  291. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/response/budget.rs +0 -0
  292. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/response/decompression.rs +0 -0
  293. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/response/mod.rs +0 -0
  294. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/tls/mod.rs +0 -0
  295. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/tls/tests.rs +0 -0
  296. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/url/constants.rs +0 -0
  297. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/url/mod.rs +0 -0
  298. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/url/origin.rs +0 -0
  299. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/url/scheme.rs +0 -0
  300. {foghttp-0.3.6 → foghttp-0.3.7}/src/core/url/tests.rs +0 -0
  301. {foghttp-0.3.6 → foghttp-0.3.7}/src/errors.rs +0 -0
  302. {foghttp-0.3.6 → foghttp-0.3.7}/src/lib.rs +0 -0
  303. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/acquire/diagnostics.rs +0 -0
  304. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/acquire/gate.rs +0 -0
  305. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/acquire/mod.rs +0 -0
  306. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/acquire/origin.rs +0 -0
  307. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/acquire/pending.rs +0 -0
  308. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/acquire/permit.rs +0 -0
  309. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/acquire/telemetry.rs +0 -0
  310. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/acquire/tests.rs +0 -0
  311. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/async_requests/active.rs +0 -0
  312. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/async_requests/callback.rs +0 -0
  313. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/async_requests/mod.rs +0 -0
  314. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/async_requests/registry.rs +0 -0
  315. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/async_requests/spawn.rs +0 -0
  316. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/async_requests/stream_spawn.rs +0 -0
  317. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/future.rs +0 -0
  318. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/lifecycle/mod.rs +0 -0
  319. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/lifecycle/tests.rs +0 -0
  320. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/options.rs +0 -0
  321. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/process.rs +0 -0
  322. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/runtime/constants.rs +0 -0
  323. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/runtime/mod.rs +0 -0
  324. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/runtime/shared.rs +0 -0
  325. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/runtime/tests.rs +0 -0
  326. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/runtime/workers.rs +0 -0
  327. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/streams/callback.rs +0 -0
  328. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/streams/constants.rs +0 -0
  329. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/streams/mod.rs +0 -0
  330. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/streams/parts.rs +0 -0
  331. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/streams/read.rs +0 -0
  332. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/streams/registry.rs +0 -0
  333. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/streams/response.rs +0 -0
  334. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/streams/state.rs +0 -0
  335. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/streams/state_tests.rs +0 -0
  336. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/timeout_diagnostics.rs +0 -0
  337. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/transport/body.rs +0 -0
  338. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/client/upload_body.rs +0 -0
  339. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/mod.rs +0 -0
  340. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/pool_diagnostics.rs +0 -0
  341. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/response.rs +0 -0
  342. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/stats.rs +0 -0
  343. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/transport_state.rs +0 -0
  344. {foghttp-0.3.6 → foghttp-0.3.7}/src/py/url.rs +0 -0
  345. {foghttp-0.3.6 → foghttp-0.3.7}/tests/__init__.py +0 -0
  346. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_cancellation/__init__.py +0 -0
  347. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_cancellation/conftest.py +0 -0
  348. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_cancellation/constants.py +0 -0
  349. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_cancellation/helpers.py +0 -0
  350. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_cancellation/lifecycle_debug_actions.py +0 -0
  351. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_cancellation/lifecycle_debug_assertions.py +0 -0
  352. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_cancellation/lifecycle_debug_data.py +0 -0
  353. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_cancellation/lifecycle_debug_predicates.py +0 -0
  354. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_cancellation/test_async_cancellation.py +0 -0
  355. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_cancellation/test_async_lifecycle_debug_buffered.py +0 -0
  356. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_cancellation/test_async_lifecycle_debug_messages.py +0 -0
  357. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_cancellation/test_async_lifecycle_debug_streaming.py +0 -0
  358. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_cancellation/test_async_lifecycle_debug_strict.py +0 -0
  359. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_cancellation/test_async_telemetry.py +0 -0
  360. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_cancellation/test_asyncio_helpers.py +0 -0
  361. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_keepalive/__init__.py +0 -0
  362. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_keepalive/assertions.py +0 -0
  363. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_keepalive/conftest.py +0 -0
  364. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_keepalive/constants.py +0 -0
  365. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_keepalive/models.py +0 -0
  366. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_keepalive/server.py +0 -0
  367. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_keepalive/test_async_keepalive.py +0 -0
  368. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_keepalive/test_sync_keepalive.py +0 -0
  369. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_lifecycle/__init__.py +0 -0
  370. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_lifecycle/conftest.py +0 -0
  371. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_lifecycle/constants.py +0 -0
  372. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_lifecycle/fork_actions.py +0 -0
  373. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_lifecycle/test_async_client_lifecycle.py +0 -0
  374. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_lifecycle/test_fork_close_safety.py +0 -0
  375. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_lifecycle/test_fork_safety.py +0 -0
  376. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_lifecycle/test_fork_stream_safety.py +0 -0
  377. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_lifecycle/test_raw_client_lifecycle.py +0 -0
  378. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_lifecycle/test_sync_client_lifecycle.py +0 -0
  379. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_lifecycle/test_sync_close_race.py +0 -0
  380. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_lifecycle/test_sync_close_waits.py +0 -0
  381. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_multipart/__init__.py +0 -0
  382. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_multipart/assertions.py +0 -0
  383. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_multipart/models.py +0 -0
  384. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_multipart/sources.py +0 -0
  385. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_multipart/test_async_multipart.py +0 -0
  386. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_multipart/test_multipart_internals.py +0 -0
  387. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_multipart/test_request_builder.py +0 -0
  388. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_multipart/test_sync_multipart.py +0 -0
  389. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_options/__init__.py +0 -0
  390. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_options/test_numeric_validation.py +0 -0
  391. {foghttp-0.3.6/tests/client_proxy → foghttp-0.3.7/tests/client_policy_hooks}/__init__.py +0 -0
  392. {foghttp-0.3.6/tests/client_query → foghttp-0.3.7/tests/client_proxy}/__init__.py +0 -0
  393. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_proxy/conftest.py +0 -0
  394. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_proxy/connect_proxy_server.py +0 -0
  395. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_proxy/environment.py +0 -0
  396. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_proxy/http_proxy_server.py +0 -0
  397. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_proxy/test_client_config.py +0 -0
  398. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_proxy/test_environment.py +0 -0
  399. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_proxy/test_http_proxy_transport.py +0 -0
  400. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_proxy/test_https_proxy_connect.py +0 -0
  401. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_proxy/test_no_proxy.py +0 -0
  402. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_proxy/test_proxy_models.py +0 -0
  403. {foghttp-0.3.6/tests/client_resources → foghttp-0.3.7/tests/client_query}/__init__.py +0 -0
  404. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_query/assertions.py +0 -0
  405. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_query/constants.py +0 -0
  406. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_query/test_async_query.py +0 -0
  407. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_query/test_async_query_redirects.py +0 -0
  408. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_query/test_request_builder.py +0 -0
  409. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_query/test_sync_query.py +0 -0
  410. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_query/test_sync_query_redirects.py +0 -0
  411. {foghttp-0.3.6/tests/client_telemetry → foghttp-0.3.7/tests/client_resources}/__init__.py +0 -0
  412. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_resources/conftest.py +0 -0
  413. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_resources/constants.py +0 -0
  414. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_resources/helpers.py +0 -0
  415. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_resources/test_async_connection_limits.py +0 -0
  416. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_resources/test_async_global_limits.py +0 -0
  417. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_resources/test_async_origin_limits.py +0 -0
  418. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_resources/test_async_pool_diagnostics.py +0 -0
  419. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_resources/test_async_response_body_limits.py +0 -0
  420. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_resources/test_async_transport_state.py +0 -0
  421. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_resources/test_diagnostic_snapshot_contract.py +0 -0
  422. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_resources/test_sync_connection_limits.py +0 -0
  423. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_resources/test_sync_global_limits.py +0 -0
  424. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_resources/test_sync_origin_limits.py +0 -0
  425. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_resources/test_sync_pool_diagnostics.py +0 -0
  426. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_resources/test_sync_response_body_limits.py +0 -0
  427. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_resources/test_sync_transport_state.py +0 -0
  428. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_streaming/__init__.py +0 -0
  429. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_streaming/conftest.py +0 -0
  430. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_streaming/constants.py +0 -0
  431. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_streaming/server.py +0 -0
  432. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_streaming/stream_readers.py +0 -0
  433. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_streaming/test_async_streaming.py +0 -0
  434. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_streaming/test_async_streaming_text_lines.py +0 -0
  435. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_streaming/test_streaming_text_decoding.py +0 -0
  436. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_streaming/test_sync_streaming.py +0 -0
  437. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_streaming/test_sync_streaming_text_lines.py +0 -0
  438. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_streaming/text_decoding_sources.py +0 -0
  439. {foghttp-0.3.6/tests/client_timeouts → foghttp-0.3.7/tests/client_telemetry}/__init__.py +0 -0
  440. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_telemetry/assertions.py +0 -0
  441. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_telemetry/conftest.py +0 -0
  442. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_telemetry/constants.py +0 -0
  443. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_telemetry/models.py +0 -0
  444. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_telemetry/test_async_stream_hooks.py +0 -0
  445. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_telemetry/test_async_stream_telemetry.py +0 -0
  446. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_telemetry/test_async_telemetry.py +0 -0
  447. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_telemetry/test_concurrent_delivery.py +0 -0
  448. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_telemetry/test_event_contract.py +0 -0
  449. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_telemetry/test_sync_stream_telemetry.py +0 -0
  450. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_telemetry/test_sync_telemetry.py +0 -0
  451. {foghttp-0.3.6/tests/client_tls → foghttp-0.3.7/tests/client_timeouts}/__init__.py +0 -0
  452. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_timeouts/conftest.py +0 -0
  453. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_timeouts/constants.py +0 -0
  454. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_timeouts/helpers.py +0 -0
  455. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_timeouts/test_async_timeouts.py +0 -0
  456. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_timeouts/test_sync_timeouts.py +0 -0
  457. {foghttp-0.3.6/tests/client_upload → foghttp-0.3.7/tests/client_tls}/__init__.py +0 -0
  458. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_tls/assertions.py +0 -0
  459. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_tls/certificates.py +0 -0
  460. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_tls/conftest.py +0 -0
  461. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_tls/constants.py +0 -0
  462. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_tls/handshake_server.py +0 -0
  463. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_tls/models.py +0 -0
  464. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_tls/server.py +0 -0
  465. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_tls/test_async_tls.py +0 -0
  466. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_tls/test_async_tls_redirects.py +0 -0
  467. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_tls/test_sync_tls.py +0 -0
  468. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_tls/test_sync_tls_redirects.py +0 -0
  469. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_tls/test_tls_config.py +0 -0
  470. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_transport/__init__.py +0 -0
  471. {foghttp-0.3.6/tests/fault_injection → foghttp-0.3.7/tests/client_upload}/__init__.py +0 -0
  472. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_upload/helpers.py +0 -0
  473. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_upload/test_streaming_upload.py +0 -0
  474. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_upload/test_upload_helpers.py +0 -0
  475. {foghttp-0.3.6 → foghttp-0.3.7}/tests/client_warning_actions.py +0 -0
  476. {foghttp-0.3.6 → foghttp-0.3.7}/tests/conftest.py +0 -0
  477. {foghttp-0.3.6/tests/network_errors → foghttp-0.3.7/tests/fault_injection}/__init__.py +0 -0
  478. {foghttp-0.3.6 → foghttp-0.3.7}/tests/fault_injection/conftest.py +0 -0
  479. {foghttp-0.3.6 → foghttp-0.3.7}/tests/fault_injection/constants.py +0 -0
  480. {foghttp-0.3.6 → foghttp-0.3.7}/tests/fault_injection/models.py +0 -0
  481. {foghttp-0.3.6 → foghttp-0.3.7}/tests/fault_injection/protocol.py +0 -0
  482. {foghttp-0.3.6 → foghttp-0.3.7}/tests/fault_injection/responses.py +0 -0
  483. {foghttp-0.3.6 → foghttp-0.3.7}/tests/fault_injection/server.py +0 -0
  484. {foghttp-0.3.6 → foghttp-0.3.7}/tests/fault_injection/state.py +0 -0
  485. {foghttp-0.3.6 → foghttp-0.3.7}/tests/fault_injection/state_assertions.py +0 -0
  486. {foghttp-0.3.6 → foghttp-0.3.7}/tests/fault_injection/test_async_fault_injection.py +0 -0
  487. {foghttp-0.3.6 → foghttp-0.3.7}/tests/fault_injection/test_async_socket_shutdown.py +0 -0
  488. {foghttp-0.3.6 → foghttp-0.3.7}/tests/fault_injection/test_sync_fault_injection.py +0 -0
  489. {foghttp-0.3.6 → foghttp-0.3.7}/tests/fault_injection/test_sync_socket_shutdown.py +0 -0
  490. {foghttp-0.3.6 → foghttp-0.3.7}/tests/fault_injection/timeout_assertions.py +0 -0
  491. {foghttp-0.3.6 → foghttp-0.3.7}/tests/fault_injection/transport_waiters.py +0 -0
  492. {foghttp-0.3.6 → foghttp-0.3.7}/tests/http_body_scenarios.py +0 -0
  493. {foghttp-0.3.6/tests/request_builder → foghttp-0.3.7/tests/network_errors}/__init__.py +0 -0
  494. {foghttp-0.3.6 → foghttp-0.3.7}/tests/network_errors/conftest.py +0 -0
  495. {foghttp-0.3.6 → foghttp-0.3.7}/tests/network_errors/constants.py +0 -0
  496. {foghttp-0.3.6 → foghttp-0.3.7}/tests/network_errors/helpers.py +0 -0
  497. {foghttp-0.3.6 → foghttp-0.3.7}/tests/network_errors/test_async_network_errors.py +0 -0
  498. {foghttp-0.3.6 → foghttp-0.3.7}/tests/network_errors/test_sync_network_errors.py +0 -0
  499. {foghttp-0.3.6 → foghttp-0.3.7}/tests/pyo3_boundary/__init__.py +0 -0
  500. {foghttp-0.3.6 → foghttp-0.3.7}/tests/pyo3_boundary/async_future_server.py +0 -0
  501. {foghttp-0.3.6 → foghttp-0.3.7}/tests/pyo3_boundary/conftest.py +0 -0
  502. {foghttp-0.3.6 → foghttp-0.3.7}/tests/pyo3_boundary/constants.py +0 -0
  503. {foghttp-0.3.6 → foghttp-0.3.7}/tests/pyo3_boundary/gil_progress.py +0 -0
  504. {foghttp-0.3.6 → foghttp-0.3.7}/tests/pyo3_boundary/test_async_future_boundary.py +0 -0
  505. {foghttp-0.3.6 → foghttp-0.3.7}/tests/pyo3_boundary/test_sync_gil_boundary.py +0 -0
  506. {foghttp-0.3.6 → foghttp-0.3.7}/tests/pyo3_boundary/thread_worker.py +0 -0
  507. {foghttp-0.3.6/tests/response_decompression → foghttp-0.3.7/tests/request_builder}/__init__.py +0 -0
  508. {foghttp-0.3.6 → foghttp-0.3.7}/tests/request_builder/encoding_property_helpers.py +0 -0
  509. {foghttp-0.3.6 → foghttp-0.3.7}/tests/request_builder/test_base_url.py +0 -0
  510. {foghttp-0.3.6 → foghttp-0.3.7}/tests/request_builder/test_body.py +0 -0
  511. {foghttp-0.3.6 → foghttp-0.3.7}/tests/request_builder/test_default_headers.py +0 -0
  512. {foghttp-0.3.6 → foghttp-0.3.7}/tests/request_builder/test_default_params.py +0 -0
  513. {foghttp-0.3.6 → foghttp-0.3.7}/tests/request_builder/test_encoding_properties.py +0 -0
  514. {foghttp-0.3.6 → foghttp-0.3.7}/tests/request_builder/test_header_policy.py +0 -0
  515. {foghttp-0.3.6 → foghttp-0.3.7}/tests/request_builder/test_headers.py +0 -0
  516. {foghttp-0.3.6 → foghttp-0.3.7}/tests/request_builder/test_merge_contract.py +0 -0
  517. {foghttp-0.3.6 → foghttp-0.3.7}/tests/request_builder/test_no_mutation.py +0 -0
  518. {foghttp-0.3.6 → foghttp-0.3.7}/tests/request_builder/test_parity.py +0 -0
  519. {foghttp-0.3.6 → foghttp-0.3.7}/tests/request_builder/test_query_params.py +0 -0
  520. {foghttp-0.3.6/tests/types → foghttp-0.3.7/tests/response_decompression}/__init__.py +0 -0
  521. {foghttp-0.3.6 → foghttp-0.3.7}/tests/response_decompression/conftest.py +0 -0
  522. {foghttp-0.3.6 → foghttp-0.3.7}/tests/response_decompression/constants.py +0 -0
  523. {foghttp-0.3.6 → foghttp-0.3.7}/tests/response_decompression/helpers.py +0 -0
  524. {foghttp-0.3.6 → foghttp-0.3.7}/tests/response_decompression/payloads.py +0 -0
  525. {foghttp-0.3.6 → foghttp-0.3.7}/tests/response_decompression/server.py +0 -0
  526. {foghttp-0.3.6 → foghttp-0.3.7}/tests/response_decompression/test_async_response_decompression.py +0 -0
  527. {foghttp-0.3.6 → foghttp-0.3.7}/tests/response_decompression/test_sync_response_decompression.py +0 -0
  528. {foghttp-0.3.6 → foghttp-0.3.7}/tests/support/__init__.py +0 -0
  529. {foghttp-0.3.6 → foghttp-0.3.7}/tests/support/async_http_server.py +0 -0
  530. {foghttp-0.3.6 → foghttp-0.3.7}/tests/support/http_routes.py +0 -0
  531. {foghttp-0.3.6 → foghttp-0.3.7}/tests/support/timeout_diagnostics.py +0 -0
  532. {foghttp-0.3.6 → foghttp-0.3.7}/tests/support/transport_state.py +0 -0
  533. {foghttp-0.3.6 → foghttp-0.3.7}/tests/support/transport_stats.py +0 -0
  534. {foghttp-0.3.6 → foghttp-0.3.7}/tests/test_async_client.py +0 -0
  535. {foghttp-0.3.6 → foghttp-0.3.7}/tests/test_async_response.py +0 -0
  536. {foghttp-0.3.6 → foghttp-0.3.7}/tests/test_client_options.py +0 -0
  537. {foghttp-0.3.6 → foghttp-0.3.7}/tests/test_headers.py +0 -0
  538. {foghttp-0.3.6 → foghttp-0.3.7}/tests/test_query_params.py +0 -0
  539. {foghttp-0.3.6 → foghttp-0.3.7}/tests/test_request_model.py +0 -0
  540. {foghttp-0.3.6 → foghttp-0.3.7}/tests/test_response_encoding.py +0 -0
  541. {foghttp-0.3.6 → foghttp-0.3.7}/tests/test_response_flags.py +0 -0
  542. {foghttp-0.3.6 → foghttp-0.3.7}/tests/test_runtime_workers.py +0 -0
  543. {foghttp-0.3.6 → foghttp-0.3.7}/tests/test_sync_client.py +0 -0
  544. {foghttp-0.3.6 → foghttp-0.3.7}/tests/test_sync_response.py +0 -0
  545. {foghttp-0.3.6 → foghttp-0.3.7}/tests/test_transport_stats.py +0 -0
  546. {foghttp-0.3.6 → foghttp-0.3.7}/tests/test_url.py +0 -0
  547. {foghttp-0.3.6 → foghttp-0.3.7}/tests/types/test_upload_contracts.py +0 -0
@@ -29,10 +29,11 @@ exclude =
29
29
  per-file-ignores =
30
30
  # FogHTTP uses public __init__.py modules as explicit import/__all__ API vitrines.
31
31
  **/__init__.py: WPS412
32
- # Public/API orchestration modules naturally collect more dependencies and ergonomic kwargs.
33
- foghttp/__init__.py: WPS201, WPS412
32
+ # Root package is an explicit API vitrine; import count follows the stable public surface.
33
+ foghttp/__init__.py: WPS201, WPS203, WPS412
34
+ # Public client orchestration modules naturally collect ergonomic kwargs.
34
35
  foghttp/client.py: WPS201, WPS211, WPS214, WPS501
35
- foghttp/async_client.py: WPS201, WPS211, WPS214
36
+ foghttp/async_client.py: WPS201, WPS203, WPS211, WPS214
36
37
  # ClientCore maps Rust snapshots to TypedDict literal keys and owns the unclosed-client warning.
37
38
  foghttp/_client/core.py: WPS201, WPS211, WPS214, WPS226, WPS603
38
39
  # Public domain objects intentionally expose mapping/response/url-style APIs.
@@ -152,8 +152,8 @@ jobs:
152
152
  enable-cache: true
153
153
  cache-dependency-glob: uv.lock
154
154
 
155
- - name: Install editable package
156
- run: uv run --extra dev --with "maturin>=1.7,<2" maturin develop --locked
155
+ - name: Build extension in place
156
+ run: uv run --extra dev --with "maturin>=1.7,<2" maturin develop --locked --skip-install
157
157
 
158
158
  - name: Run tests
159
159
  if: matrix.python-version != '3.14'
@@ -110,7 +110,7 @@ dependencies = [
110
110
 
111
111
  [[package]]
112
112
  name = "foghttp"
113
- version = "0.3.6"
113
+ version = "0.3.7"
114
114
  dependencies = [
115
115
  "brotli",
116
116
  "bytes",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "foghttp"
3
- version = "0.3.6"
3
+ version = "0.3.7"
4
4
  description = "Observable Rust-powered HTTP client for Python services."
5
5
  edition = "2021"
6
6
  homepage = "https://github.com/AmberFog/foghttp"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: foghttp
3
- Version: 0.3.6
3
+ Version: 0.3.7
4
4
  Classifier: Development Status :: 3 - Alpha
5
5
  Classifier: Framework :: AsyncIO
6
6
  Classifier: License :: OSI Approved :: MIT License
@@ -92,9 +92,9 @@ Runtime requirements:
92
92
  - `orjson>=3.11,<4`
93
93
 
94
94
  Published CPython wheels use the stable `cp311-abi3` ABI: each supported
95
- OS/architecture pair has one wheel for Python 3.11 and newer. The release
96
- pipeline currently installs and exercises those wheels on GIL-enabled CPython
97
- 3.11 through 3.14. See [Packaging and Python compatibility](https://github.com/AmberFog/foghttp/blob/main/docs/packaging.md)
95
+ OS/architecture pair has one wheel for the currently validated GIL-enabled
96
+ CPython 3.11 through 3.14 range. Newer Python versions are not part of the
97
+ compatibility claim until they pass the same release checks. See [Packaging and Python compatibility](https://github.com/AmberFog/foghttp/blob/main/docs/packaging.md)
98
98
  for the complete wheel matrix and validation policy.
99
99
 
100
100
  ## Quick Start
@@ -149,12 +149,14 @@ async with foghttp.AsyncClient() as client:
149
149
  - sync and async bytes/text/line response streaming with explicit
150
150
  context-managed lifecycle
151
151
  - prepared `Request` objects with `build_request()` and `send()`
152
+ - immutable request `extensions` for policy/application metadata outside the HTTP message
152
153
  - case-insensitive `Headers` with repeated values
153
154
  - safe policy for transport-managed request headers
154
155
  - redacted repr/error surfaces for sensitive headers, URL credentials,
155
156
  token-like URL params, and buffered body bytes
156
157
  - normalized `URL` model with origin comparison and relative joins
157
- - GET/HEAD/POST/QUERY redirects with final URL, history, and conservative replay policy
158
+ - GET/HEAD/POST/QUERY redirects with final URL, history, typed same-origin and
159
+ cross-origin header policy, and no cross-origin body replay
158
160
  - HTTP proxy routing and HTTPS proxy `CONNECT` tunnelling through explicit
159
161
  `proxy=` or `trust_env=True` when the proxy endpoint uses `http://`
160
162
  - HTTPS with default WebPKI roots, explicit custom CA certificates, and
@@ -166,6 +168,8 @@ async with foghttp.AsyncClient() as client:
166
168
  acquire pressure and idle lifecycle diagnostics
167
169
  - opt-in typed telemetry event hooks for request, redirect, response headers,
168
170
  response body, and request completion lifecycle
171
+ - opt-in typed transport policy hooks for lightweight request admission and
172
+ response-head checks without default-path Python callbacks
169
173
  - versioned telemetry snapshot metadata for `stats()`, `dump_transport_state()`,
170
174
  and `dump_pool_diagnostics()`
171
175
  - opt-in async lifecycle debug mode for active request snapshots, strict leak
@@ -184,6 +188,7 @@ async with foghttp.AsyncClient() as client:
184
188
  - [Packaging and Python compatibility](https://github.com/AmberFog/foghttp/blob/main/docs/packaging.md)
185
189
  - [Timeout model](https://github.com/AmberFog/foghttp/blob/main/docs/timeouts.md)
186
190
  - [Upload typing contracts](https://github.com/AmberFog/foghttp/blob/main/docs/upload-types.md)
191
+ - [Transport policy hooks](https://github.com/AmberFog/foghttp/blob/main/docs/policy-hooks.md)
187
192
  - [Telemetry contract](https://github.com/AmberFog/foghttp/blob/main/docs/telemetry.md)
188
193
  - [Response streaming](https://github.com/AmberFog/foghttp/blob/main/docs/streaming.md)
189
194
  - [Proxy and trust_env](https://github.com/AmberFog/foghttp/blob/main/docs/proxies.md)
@@ -217,7 +222,7 @@ path. Disabling TLS verification is intentionally not supported.
217
222
  Development requires a Rust toolchain with `cargo` available in `PATH`.
218
223
 
219
224
  ```bash
220
- uv run --extra dev --with "maturin>=1.7,<2" maturin develop
225
+ uv run --extra dev --with "maturin>=1.7,<2" maturin develop --locked --skip-install
221
226
  uv run --extra dev coverage run -m pytest
222
227
  uv run --extra dev coverage report -m
223
228
  uv run --extra dev pre-commit run --all-files --show-diff-on-failure
@@ -49,9 +49,9 @@ Runtime requirements:
49
49
  - `orjson>=3.11,<4`
50
50
 
51
51
  Published CPython wheels use the stable `cp311-abi3` ABI: each supported
52
- OS/architecture pair has one wheel for Python 3.11 and newer. The release
53
- pipeline currently installs and exercises those wheels on GIL-enabled CPython
54
- 3.11 through 3.14. See [Packaging and Python compatibility](https://github.com/AmberFog/foghttp/blob/main/docs/packaging.md)
52
+ OS/architecture pair has one wheel for the currently validated GIL-enabled
53
+ CPython 3.11 through 3.14 range. Newer Python versions are not part of the
54
+ compatibility claim until they pass the same release checks. See [Packaging and Python compatibility](https://github.com/AmberFog/foghttp/blob/main/docs/packaging.md)
55
55
  for the complete wheel matrix and validation policy.
56
56
 
57
57
  ## Quick Start
@@ -106,12 +106,14 @@ async with foghttp.AsyncClient() as client:
106
106
  - sync and async bytes/text/line response streaming with explicit
107
107
  context-managed lifecycle
108
108
  - prepared `Request` objects with `build_request()` and `send()`
109
+ - immutable request `extensions` for policy/application metadata outside the HTTP message
109
110
  - case-insensitive `Headers` with repeated values
110
111
  - safe policy for transport-managed request headers
111
112
  - redacted repr/error surfaces for sensitive headers, URL credentials,
112
113
  token-like URL params, and buffered body bytes
113
114
  - normalized `URL` model with origin comparison and relative joins
114
- - GET/HEAD/POST/QUERY redirects with final URL, history, and conservative replay policy
115
+ - GET/HEAD/POST/QUERY redirects with final URL, history, typed same-origin and
116
+ cross-origin header policy, and no cross-origin body replay
115
117
  - HTTP proxy routing and HTTPS proxy `CONNECT` tunnelling through explicit
116
118
  `proxy=` or `trust_env=True` when the proxy endpoint uses `http://`
117
119
  - HTTPS with default WebPKI roots, explicit custom CA certificates, and
@@ -123,6 +125,8 @@ async with foghttp.AsyncClient() as client:
123
125
  acquire pressure and idle lifecycle diagnostics
124
126
  - opt-in typed telemetry event hooks for request, redirect, response headers,
125
127
  response body, and request completion lifecycle
128
+ - opt-in typed transport policy hooks for lightweight request admission and
129
+ response-head checks without default-path Python callbacks
126
130
  - versioned telemetry snapshot metadata for `stats()`, `dump_transport_state()`,
127
131
  and `dump_pool_diagnostics()`
128
132
  - opt-in async lifecycle debug mode for active request snapshots, strict leak
@@ -141,6 +145,7 @@ async with foghttp.AsyncClient() as client:
141
145
  - [Packaging and Python compatibility](https://github.com/AmberFog/foghttp/blob/main/docs/packaging.md)
142
146
  - [Timeout model](https://github.com/AmberFog/foghttp/blob/main/docs/timeouts.md)
143
147
  - [Upload typing contracts](https://github.com/AmberFog/foghttp/blob/main/docs/upload-types.md)
148
+ - [Transport policy hooks](https://github.com/AmberFog/foghttp/blob/main/docs/policy-hooks.md)
144
149
  - [Telemetry contract](https://github.com/AmberFog/foghttp/blob/main/docs/telemetry.md)
145
150
  - [Response streaming](https://github.com/AmberFog/foghttp/blob/main/docs/streaming.md)
146
151
  - [Proxy and trust_env](https://github.com/AmberFog/foghttp/blob/main/docs/proxies.md)
@@ -174,7 +179,7 @@ path. Disabling TLS verification is intentionally not supported.
174
179
  Development requires a Rust toolchain with `cargo` available in `PATH`.
175
180
 
176
181
  ```bash
177
- uv run --extra dev --with "maturin>=1.7,<2" maturin develop
182
+ uv run --extra dev --with "maturin>=1.7,<2" maturin develop --locked --skip-install
178
183
  uv run --extra dev coverage run -m pytest
179
184
  uv run --extra dev coverage report -m
180
185
  uv run --extra dev pre-commit run --all-files --show-diff-on-failure
@@ -60,6 +60,8 @@ FogHTTP is designed around a few engineering priorities:
60
60
  pressure, idle lifecycle snapshots, and stuck request diagnostics
61
61
  - opt-in typed telemetry event hooks with redacted request/response lifecycle
62
62
  events
63
+ - opt-in typed transport policy hooks for lightweight request admission and
64
+ response-head checks, with Rust-owned redirect safety
63
65
  - versioned telemetry snapshots that separate alert-oriented stats from
64
66
  diagnostic dump APIs
65
67
  - opt-in async lifecycle debug snapshots for tests, staging, and incident
@@ -76,6 +78,7 @@ try to keep public interfaces stable and avoid unnecessary breaking changes.
76
78
  - [Packaging and Python compatibility](./packaging.md)
77
79
  - [Timeout model](./timeouts.md)
78
80
  - [Upload typing contracts](./upload-types.md)
81
+ - [Transport policy hooks](./policy-hooks.md)
79
82
  - [Telemetry contract](./telemetry.md)
80
83
  - [Response streaming](./streaming.md)
81
84
  - [TLS trust](./tls.md)
@@ -110,6 +113,7 @@ try to keep public interfaces stable and avoid unnecessary breaking changes.
110
113
  - sync and async bytes/text/line response streaming with context-managed cleanup
111
114
  - response status flags for success, redirects, and client/server errors
112
115
  - prepared `Request` objects with `build_request()` and `send()`
116
+ - immutable request `extensions` for policy/application metadata outside the HTTP message
113
117
  - public upload typing contracts for streaming request bodies and multipart
114
118
  `files=` providers
115
119
  - case-insensitive `Headers` with repeated value support
@@ -117,7 +121,8 @@ try to keep public interfaces stable and avoid unnecessary breaking changes.
117
121
  - redacted repr/error surfaces for sensitive headers, URL credentials,
118
122
  token-like URL params, and buffered body bytes
119
123
  - normalized `URL` model with origin comparison and relative joins
120
- - GET/HEAD/POST/QUERY redirects with final URL, history, and conservative replay policy
124
+ - GET/HEAD/POST/QUERY redirects with final URL, history, typed same-origin and
125
+ cross-origin header policy, and no cross-origin body replay
121
126
  - HTTPS with default WebPKI roots, explicit custom CA certificates, and
122
127
  custom-only CA trust
123
128
  - documented lazy transport creation, graceful sync close, async request
@@ -129,6 +134,8 @@ try to keep public interfaces stable and avoid unnecessary breaking changes.
129
134
  acquire and idle lifecycle telemetry
130
135
  - opt-in typed telemetry event hooks for request, redirect, response headers,
131
136
  response body, and request completion lifecycle
137
+ - opt-in typed transport policy hooks with immutable request/response views and
138
+ no default-path Python callback
132
139
  - versioned telemetry snapshot metadata for `stats()`, `dump_transport_state()`,
133
140
  and `dump_pool_diagnostics()`
134
141
  - opt-in async lifecycle debug mode for active request snapshots and strict
@@ -34,6 +34,7 @@ try to keep public interfaces stable and avoid unnecessary breaking changes.
34
34
  `response.raise_for_status()`
35
35
  - lightweight `response.request`
36
36
  - prepared `Request` objects with `build_request()` and `send()`
37
+ - immutable request `extensions` propagated to policy hooks and `response.request`
37
38
  - case-insensitive `Headers` with repeated values
38
39
  - response header bytes exposed as Latin-1 strings, including obs-text values
39
40
  - normalized `URL` with origin comparison and relative joins
@@ -52,6 +53,8 @@ try to keep public interfaces stable and avoid unnecessary breaking changes.
52
53
  connection-acquire pressure and idle lifecycle diagnostics
53
54
  - opt-in typed telemetry event hooks for request, redirect, response headers,
54
55
  response body, and request completion lifecycle
56
+ - opt-in synchronous transport policy hooks with immutable request/response
57
+ snapshots and Rust-owned redirect safety
55
58
  - opt-in async lifecycle debug snapshots for active async request handles,
56
59
  pending transport pressure, strict test checks, and unclosed-client context
57
60
  - default per-response and aggregate buffered response memory limits
@@ -95,6 +98,7 @@ try to keep public interfaces stable and avoid unnecessary breaking changes.
95
98
  | separate read/write timeout semantics | `Timeouts.read` is implemented as a buffered and streamed response body progress timeout; `Timeouts.write` is implemented for buffered request body write progress and streaming upload chunk/write progress |
96
99
  | socket lifecycle telemetry granularity | `TransportStats` and `dump_transport_state()["origins"]` expose opened, open-failed, closed, reused, aborted, idle-timeout eviction, active, and idle tracked connection counters for the current HTTP/1 path; dedicated failed-reuse and close-reason taxonomy are not exposed yet because current connector hooks do not provide a stable reason signal |
97
100
  | telemetry hook granularity | `TelemetryConfig` currently dispatches Python-level request/response lifecycle events; lower-level Rust pool acquire and connection lifecycle event delivery is planned before Prometheus/OpenTelemetry exporters |
101
+ | transport policy hook execution | `TransportPolicyHooks` callbacks are synchronous, inline, non-reentrant, and may run on Rust transport worker threads; `after_response_body` observes only redirect bodies consumed internally, not the final response body returned to the caller |
98
102
  | diagnostic snapshot transactionality | `stats()`, `dump_transport_state()`, and `dump_pool_diagnostics()` include `schema_version` and a monotonic `snapshot_sequence`, but the `dump_*` APIs remain diagnostic snapshots rather than lock-protected SLA transactions; use `stats()` for alert-oriented low-cardinality metrics |
99
103
 
100
104
  ## Practical Guidance
@@ -2,9 +2,11 @@
2
2
 
3
3
  FogHTTP ships a Rust extension built with PyO3. Published CPython wheels target
4
4
  the stable `cp311-abi3` ABI, matching the package minimum of Python 3.11. One
5
- wheel per supported operating-system and architecture pair can therefore be
6
- installed by GIL-enabled CPython 3.11 and newer instead of building a separate
7
- wheel for every CPython minor version.
5
+ wheel per supported operating-system and architecture pair covers the
6
+ currently validated GIL-enabled CPython 3.11-3.14 range instead of requiring a
7
+ separate wheel for every supported CPython minor version. The ABI may remain
8
+ compatible with newer Python versions, but FogHTTP does not claim that support
9
+ until the full suite and exact wheel pass the release validation matrix.
8
10
 
9
11
  ## Release Matrix
10
12
 
@@ -0,0 +1,109 @@
1
+ # Transport Policy Hooks
2
+
3
+ FogHTTP exposes a small opt-in Python edge around its Rust-owned transport
4
+ policy stages. It is intended for trusted, lightweight request admission and
5
+ response-head policy checks. It is not a middleware framework and does not
6
+ expose the internal transport adapter.
7
+
8
+ The default is `policy_hooks=None`. In that mode the Rust bridge does not
9
+ resolve callback or view objects, allocate hook snapshots, call Python, or
10
+ build a runtime list of policies. Built-in proxy and redirect policies remain
11
+ statically dispatched in Rust.
12
+
13
+ ## Configuration
14
+
15
+ Hooks are configured per client and have the same contract for `Client` and
16
+ `AsyncClient`, including buffered and streaming requests:
17
+
18
+ ```python
19
+ import foghttp
20
+
21
+
22
+ def allow_service_origins(request: foghttp.TransportPolicyRequest) -> None:
23
+ if foghttp.URL(request.url).origin != "https://api.example.com":
24
+ raise PermissionError("transport target is outside the service boundary")
25
+
26
+
27
+ def reject_server_errors(response: foghttp.TransportPolicyResponse) -> None:
28
+ if response.status_code >= 500:
29
+ raise RuntimeError("upstream response rejected by transport policy")
30
+
31
+
32
+ hooks = foghttp.TransportPolicyHooks(
33
+ before_send=allow_service_origins,
34
+ on_response_headers=reject_server_errors,
35
+ )
36
+
37
+ with foghttp.Client(policy_hooks=hooks) as client:
38
+ response = client.get("https://api.example.com/resource")
39
+ ```
40
+
41
+ All callbacks are synchronous and must return `None`. Raising an exception
42
+ rejects the current request and preserves that exception for the caller.
43
+ Returning any other value raises `TypeError`; hook return values cannot mutate
44
+ or replace transport state.
45
+
46
+ ## Stage Order
47
+
48
+ | Hook | Ordering and scope |
49
+ |---|---|
50
+ | `before_send` | Runs for the initial request and every redirect hop after Rust has selected and validated the transport route, but before request-slot acquire. |
51
+ | `on_response_headers` | Runs for every response after Rust has classified any redirect action and before FogHTTP consumes or returns the response body. |
52
+ | `after_response_body` | Runs only for redirect response bodies consumed internally by FogHTTP. Rust first validates the redirect limit, replayability, scheme downgrade, header policy, and proxy boundary; the hook runs before the already validated mutation is applied. It does not run for the final body returned to the caller. |
53
+
54
+ There is deliberately no error, timeout, or cancellation hook. Those stages
55
+ remain unavailable until FogHTTP has a Rust-owned failure taxonomy and a real
56
+ retry-policy consumer.
57
+
58
+ ## Snapshot Contract
59
+
60
+ `TransportPolicyRequest` is an immutable snapshot with:
61
+
62
+ - normalized uppercase `method`;
63
+ - full normalized `url`;
64
+ - `body` as `"empty"`, `"replayable"`, or `"non_replayable"`;
65
+ - zero-based `redirect_hop`;
66
+ - immutable request-scoped `extensions` supplied by the caller.
67
+
68
+ `TransportPolicyResponse` contains the request snapshot, `status_code`, and an
69
+ immutable tuple of response header pairs. Repeated values for the same header
70
+ retain their order.
71
+
72
+ The full URL and header values are available because trusted policy code may
73
+ need them to make a decision. They can contain credentials or tokens and are
74
+ not telemetry-safe data. Their `repr()` surfaces redact URL secrets and omit
75
+ header values plus extension keys and values, but hook code must still avoid
76
+ logging the raw attributes. Extensions are metadata only and are never
77
+ serialized into HTTP headers, the URL, or the request body. Use
78
+ [`TelemetryConfig`](./telemetry.md) when the goal is observability through
79
+ redacted events rather than request admission.
80
+
81
+ Snapshots contain no socket, permit, response body, cancellation handle, pool,
82
+ or runtime reference. Their transport fields are copies: replacing those fields
83
+ through Python escape hatches cannot alter the request or bypass Rust redirect
84
+ and replayability checks. The extensions mapping is immutable, but its values
85
+ are the caller-owned shallow references described in the request builder
86
+ contract.
87
+
88
+ ## Execution And Lifecycle
89
+
90
+ Hooks run inline with transport policy evaluation. They may execute on FogHTTP
91
+ transport worker threads and may be invoked concurrently by concurrent
92
+ requests. A hook must therefore be fast, thread-safe, and independent of an
93
+ asyncio event loop, thread-local state, or `contextvars` propagation.
94
+ Extension values are shared shallow references, so hooks must treat them as
95
+ read-only and safe for concurrent observation.
96
+
97
+ Do not perform blocking I/O, call back into FogHTTP, or re-enter the same client
98
+ from a hook. Hook execution advances the wall clock used by later total-time
99
+ checks, but a running Python callback is not preempted or independently bounded
100
+ by FogHTTP timeouts. Callback failure unwinds through the normal request path
101
+ so permits, response bodies, connections, upload providers, and request metrics
102
+ retain their existing owners and cleanup behavior.
103
+
104
+ ## Stability Boundary
105
+
106
+ `TransportPolicyHooks` and its immutable views are the deliberate public
107
+ surface. `src/core/policy/`, PyO3 bridge classes, raw clients, connector types,
108
+ and internal transport adapter Protocols remain implementation details and are
109
+ not extension points.
@@ -44,6 +44,46 @@ buffered requests:
44
44
  - If a Rust stream state lock owns an active Python future handle, the lock must
45
45
  be released before scheduling cancellation or completion on the Python loop.
46
46
 
47
+ ## Internal Request/Response Policy Seam
48
+
49
+ `src/core/policy/` is an internal, unstable seam for built-in transport
50
+ policies. It is not a public middleware API. The optional
51
+ `TransportPolicyHooks` bridge observes typed copies at selected stage edges;
52
+ it does not expose the core pipeline or transport adapter. The default request
53
+ path performs no Python callback, dynamic dispatch, policy-list allocation, or
54
+ hook-snapshot construction.
55
+
56
+ Policy stages run in this order:
57
+
58
+ 1. Before send, the pipeline selects the direct or proxy transport for the
59
+ normalized request URL.
60
+ 2. After response headers, it may produce an opaque pending redirect decision.
61
+ 3. After the redirect response body has been consumed, it validates the
62
+ redirect limit, request-body replayability, and environment-derived proxy
63
+ boundary before returning a typed request mutation.
64
+ 4. `RequestState` applies the mutation before the next send. The policy layer
65
+ never owns sockets, permits, response bodies, or Python objects.
66
+
67
+ The current mutation surface can replace the method and URL, remove request
68
+ headers, and either preserve or drop the request body. A non-replayable body is
69
+ never resent. Environment-derived proxy decisions are not reused across
70
+ origins and therefore fail closed until per-hop environment resolution exists.
71
+ Responses are observed through immutable status and header views; the current
72
+ seam does not mutate response status, headers, or body content.
73
+ Policy diagnostics may include a normalized origin, but must not include URL
74
+ userinfo, path, query parameters, or fragments.
75
+
76
+ Error and timeout policy stages are intentionally absent until the retry work
77
+ defines a Rust-owned failure taxonomy. Core policy code must not accept or
78
+ return `PyErr` merely to reserve a future hook.
79
+
80
+ The PyO3 bridge lives outside `src/core/policy/`. It invokes only callbacks
81
+ resolved when `RawClient` is created, rejects non-`None` callback returns, and
82
+ passes immutable Python snapshots without transport resources. Built-in
83
+ validation runs before a Python hook can veto a redirect mutation. See
84
+ [Transport policy hooks](./policy-hooks.md) for the public execution and
85
+ threading contract.
86
+
47
87
  ## Review Checklist
48
88
 
49
89
  For PRs touching PyO3, runtime, cancellation, close/aclose, streaming, or
@@ -5,7 +5,7 @@
5
5
  Development requires a Rust toolchain with `cargo` available in `PATH`.
6
6
 
7
7
  ```bash
8
- uv run --extra dev --with "maturin>=1.7,<2" maturin develop
8
+ uv run --extra dev --with "maturin>=1.7,<2" maturin develop --locked --skip-install
9
9
  ```
10
10
 
11
11
  Runtime requirements:
@@ -713,6 +713,28 @@ monotonic `snapshot_sequence` within one Rust transport lifetime. Use
713
713
  `TransportStats` for dashboards and alert-oriented metrics; see
714
714
  [Telemetry contract](./telemetry.md) for the current guarantees.
715
715
 
716
+ For trusted lightweight admission checks, configure synchronous transport
717
+ policy hooks. The hook receives the full normalized target, may reject by
718
+ raising, and cannot mutate transport state:
719
+
720
+ ```python
721
+ def require_https(request: foghttp.TransportPolicyRequest) -> None:
722
+ if foghttp.URL(request.url).scheme != "https":
723
+ raise PermissionError("HTTPS is required")
724
+
725
+
726
+ hooks = foghttp.TransportPolicyHooks(before_send=require_https)
727
+
728
+ with foghttp.Client(policy_hooks=hooks) as client:
729
+ response = client.get("https://httpbin.org/get")
730
+ ```
731
+
732
+ Hooks run inline and can execute on transport worker threads, so they must be
733
+ fast, synchronous, thread-safe, and non-reentrant. Their snapshots are not
734
+ telemetry-safe: full URLs and response header values may contain secrets. See
735
+ [Transport policy hooks](./policy-hooks.md) for stage ordering, redirect-body
736
+ scope, error propagation, and lifecycle constraints.
737
+
716
738
  For opt-in event hooks, pass a typed telemetry config. Hooks receive redacted
717
739
  `TelemetryEvent` objects and are intended for logging/tracing bridges, not for
718
740
  mutating requests or responses. Hooks run inline, so keep sinks fast and
@@ -129,41 +129,37 @@ query at a different origin.
129
129
  ## Security Policy
130
130
 
131
131
  FogHTTP applies a conservative redirect security policy on every redirect hop.
132
-
133
- For same-origin redirects, request headers are preserved unless the redirect
134
- changes the request method and drops the body.
135
-
136
- For cross-origin redirects, FogHTTP strips sensitive headers before sending the
137
- next request:
138
-
139
- - `Authorization`
140
- - `Proxy-Authorization`
141
- - `Cookie`
142
- - `Origin`
143
- - `Referer`
144
-
145
- This is intentionally strict. It prevents credentials, manually supplied
146
- cookies, origin metadata, and referrer metadata from being forwarded to a
147
- different origin by a redirect response. `Host` is transport-managed and cannot
148
- be set manually through the safe API.
149
-
150
- When a redirect rewrites `POST` or `QUERY` to `GET`, FogHTTP drops the request
151
- body and strips body-specific headers:
152
-
153
- - `Content-Encoding`
154
- - `Content-Length`
155
- - `Content-Type`
156
- - `Transfer-Encoding`
157
-
158
- `Content-Length` and `Transfer-Encoding` are transport-managed and cannot be set
159
- manually through the safe API.
160
-
161
- For same-origin method-preserving POST and QUERY redirects, FogHTTP resends a
162
- replayable body. For cross-origin method-preserving POST and QUERY redirects,
163
- FogHTTP preserves the method but drops the body and body-specific headers
164
- before the next request. This prevents JSON payloads, tokens, form data, and
165
- other request bodies from being forwarded to a different origin by a redirect
166
- response.
132
+ The policy runs after the target URL and body action have been resolved and
133
+ before the next request is sent.
134
+
135
+ | Header category | Fields | Redirect behavior |
136
+ |---|---|---|
137
+ | Transport routing, framing, proxy, and connection | `Host`, `Content-Length`, `Transfer-Encoding`, `Connection`, `Keep-Alive`, `Proxy-Authorization`, `Proxy-Connection`, `TE`, `Trailer`, `Upgrade`, plus fields named by `Connection` | Always removed from the previous request. The transport derives fresh routing and framing fields for the new URL and body and applies proxy credentials for the selected route. |
138
+ | Conditional validators | `If-Match`, `If-None-Match`, `If-Modified-Since`, `If-Unmodified-Since`, `If-Range` | Always removed because the validator describes the previous target resource. |
139
+ | Origin-scoped credentials and metadata | `Authorization`, `Cookie`, `Origin`, `Referer` | Preserved for same-origin redirects and removed for cross-origin redirects. |
140
+ | Content metadata | Every `Content-*` field, including `Content-Type`, `Content-Encoding`, `Content-Language`, `Content-Location`, `Content-Range`, `Content-Disposition`, and `Content-Digest`; also legacy `Digest`, current `Repr-Digest`, and `Last-Modified` | Preserved only while the request body is preserved. Removed when a method rewrite or cross-origin policy drops the body. |
141
+ | Other caller headers | For example, `Accept` and application-specific fields | Preserved. |
142
+
143
+ Same-origin means that the scheme, normalized host, and effective port all
144
+ match. A change to any of those components is cross-origin.
145
+
146
+ The safe API already rejects manual transport-managed fields. Rebuilding them
147
+ inside the Rust redirect policy also protects the lower-level boundary and
148
+ prevents stale authority, framing, proxy credentials, or connection state from
149
+ crossing a hop.
150
+
151
+ The conditional and content rules follow the redirect guidance in
152
+ [RFC 9110](https://www.rfc-editor.org/rfc/rfc9110.html). FogHTTP recognizes both
153
+ the obsolete `Digest` field and its current
154
+ [RFC 9530](https://www.rfc-editor.org/rfc/rfc9530.html) replacements.
155
+
156
+ For same-origin method-preserving redirects, FogHTTP resends a replayable body.
157
+ For cross-origin method-preserving redirects, FogHTTP preserves the method but
158
+ drops any body and its content metadata before the next request. This rule also
159
+ protects bodies supplied through the generic `request()` API for methods whose
160
+ convenience helpers do not accept body arguments. It prevents JSON payloads,
161
+ tokens, form data, and other request bodies from being forwarded to a different
162
+ origin by a redirect response.
167
163
 
168
164
  FogHTTP also blocks `https -> http` redirects. Scheme downgrade redirects are
169
165
  too easy to misuse once credentials, cookies, body replay, or future auth helpers
@@ -174,6 +170,12 @@ Direct streaming bodies use the explicit non-replayable path and are not resent
174
170
  automatically. Factory-backed streams are replayable because each attempt gets
175
171
  a fresh provider.
176
172
 
173
+ Automatic redirects cannot infer whether an arbitrary application header such
174
+ as `X-API-Key` contains an origin-scoped secret. Keep automatic redirects
175
+ disabled and follow the response explicitly when custom credentials require a
176
+ different forwarding policy. This is also the explicit escape hatch for callers
177
+ that need behavior looser than the built-in matrix.
178
+
177
179
  ## Proxy Policy
178
180
 
179
181
  Redirects interact with proxy routing because a redirect target can change the
@@ -196,7 +198,8 @@ recomputation is planned separately.
196
198
  ## Redirect Limit
197
199
 
198
200
  `max_redirects` defaults to `20`. If the limit is exceeded, FogHTTP raises
199
- `RequestError`.
201
+ `RequestError`. The diagnostic identifies the normalized origin but omits URL
202
+ userinfo, path, query parameters, and fragments.
200
203
 
201
204
  ```python
202
205
  with foghttp.Client(follow_redirects=True, max_redirects=5) as client:
@@ -18,6 +18,7 @@ the current FogHTTP API. The same flow is available as a runnable example in
18
18
  | `params` | Supported | Accepts mappings, repeated pairs, and raw query strings. Existing URL query is preserved. |
19
19
  | client default `params` | Supported | Passed as `Client(params=...)` or `AsyncClient(params=...)`. Appended after URL query and before per-request params. |
20
20
  | `headers` | Supported | Accepts mappings, pairs, and `foghttp.Headers`. Lookups are case-insensitive and repeated values are preserved. |
21
+ | `extensions` | Supported | Immutable request-scoped metadata for policy and application coordination. It is never serialized into the HTTP message. |
21
22
  | client default `headers` | Supported | Passed as `Client(headers=...)` or `AsyncClient(headers=...)`. Per-request headers override defaults case-insensitively. |
22
23
  | `json` | Supported | Encoded with `orjson`. Adds `content-type: application/json` unless explicitly set. |
23
24
  | `content` | Supported | Accepts buffered `bytes` or `str`, binary file-like objects, sync bytes-like iterables, zero-arg byte-stream factories, and async bytes-like iterables/factories on `AsyncClient`. Strings are encoded as UTF-8. No semantic content type is added. |
@@ -88,6 +89,54 @@ Per-request headers override client defaults case-insensitively. Repeated
88
89
  headers from defaults are preserved when the request does not override that
89
90
  header name.
90
91
 
92
+ ## Request Extensions
93
+
94
+ Use `extensions=` for request-scoped application metadata that policy hooks,
95
+ auth, retry, proxy, or tracing integrations may need without placing service
96
+ state in HTTP headers. The name is deliberately `extensions`, not `context`:
97
+ the value belongs to a prepared request and does not imply `contextvars`, event
98
+ loop, or task-context propagation.
99
+
100
+ ```python
101
+ import foghttp
102
+ from foghttp.methods import GET
103
+
104
+
105
+ with foghttp.Client() as client:
106
+ request = client.build_request(
107
+ GET,
108
+ "https://api.example.com/resource",
109
+ extensions={"example.request_id": "request-42"},
110
+ )
111
+ response = client.send(request)
112
+ assert response.request.extensions["example.request_id"] == "request-42"
113
+ ```
114
+
115
+ `Request`, `build_request()`, `request()`, `stream()`, and every method shortcut
116
+ accept `extensions=`. FogHTTP makes a shallow immutable copy represented by
117
+ `RequestExtensions`; later changes to the source mapping do not change the
118
+ prepared request. Values remain caller-owned references, so keep them small and
119
+ treat mutable values as immutable while a request, response, or hook may retain
120
+ them. Do not attach open files, sockets, clients, tasks, or other lifecycle-owned
121
+ resources.
122
+
123
+ Keys must be non-empty strings. Libraries should use a package or reverse-domain
124
+ namespace rather than generic names. The case-insensitive `foghttp.*` namespace
125
+ is reserved for present and future internal timeout, trace, proxy, retry, and
126
+ other policy decisions; callers cannot set it. Reserved internal state is not a
127
+ public configuration API.
128
+
129
+ Extensions are available as `request.extensions`, on
130
+ `TransportPolicyRequest.extensions`, and on `response.request.extensions`,
131
+ including redirect history. They are not copied into the URL, headers, or body.
132
+ Their keys and values are omitted from request, response, and policy snapshot
133
+ `repr()` output, but application code must still avoid logging the raw mapping
134
+ when it contains sensitive metadata.
135
+
136
+ When `extensions` is omitted, requests share one empty immutable snapshot and
137
+ the native boundary receives `None`; no per-request metadata mapping or Python
138
+ policy callback is introduced.
139
+
91
140
  ## Sync Example
92
141
 
93
142
  ```python
@@ -24,6 +24,7 @@ __all__ = (
24
24
  "ReadTimeout",
25
25
  "Request",
26
26
  "RequestError",
27
+ "RequestExtensions",
27
28
  "RequestInfo",
28
29
  "Response",
29
30
  "ResponseBodyBudgetExceededError",
@@ -43,6 +44,10 @@ __all__ = (
43
44
  "TimeoutError",
44
45
  "TimeoutPhase",
45
46
  "Timeouts",
47
+ "TransportPolicyBodyState",
48
+ "TransportPolicyHooks",
49
+ "TransportPolicyRequest",
50
+ "TransportPolicyResponse",
46
51
  "TransportState",
47
52
  "TransportStats",
48
53
  "UnclosedClientError",
@@ -81,8 +86,15 @@ from .lifecycle_debug import (
81
86
  AsyncLifecycleDebugSnapshot,
82
87
  )
83
88
  from .limits import Limits
89
+ from .policy import (
90
+ TransportPolicyBodyState,
91
+ TransportPolicyHooks,
92
+ TransportPolicyRequest,
93
+ TransportPolicyResponse,
94
+ )
84
95
  from .pool_diagnostics import OriginPoolDiagnostics, PoolBlockingReason, PoolDiagnostics
85
96
  from .request import Request
97
+ from .request_extensions import RequestExtensions
86
98
  from .request_info import RequestInfo
87
99
  from .response import Response
88
100
  from .stream_response import AsyncStreamResponse, StreamResponse