palfrey 0.1.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 (213) hide show
  1. palfrey-0.1.0/.gitignore +32 -0
  2. palfrey-0.1.0/LICENSE +11 -0
  3. palfrey-0.1.0/PKG-INFO +220 -0
  4. palfrey-0.1.0/README.md +155 -0
  5. palfrey-0.1.0/benchmarks/__init__.py +1 -0
  6. palfrey-0.1.0/benchmarks/apps.py +39 -0
  7. palfrey-0.1.0/benchmarks/run.py +546 -0
  8. palfrey-0.1.0/docs/en/docs/concepts/asgi.md +86 -0
  9. palfrey-0.1.0/docs/en/docs/concepts/event-loop.md +43 -0
  10. palfrey-0.1.0/docs/en/docs/concepts/http.md +60 -0
  11. palfrey-0.1.0/docs/en/docs/concepts/lifespan.md +49 -0
  12. palfrey-0.1.0/docs/en/docs/concepts/middleware.md +36 -0
  13. palfrey-0.1.0/docs/en/docs/concepts/server-behavior.md +49 -0
  14. palfrey-0.1.0/docs/en/docs/concepts/terms-and-mental-models.md +140 -0
  15. palfrey-0.1.0/docs/en/docs/concepts/websockets.md +64 -0
  16. palfrey-0.1.0/docs/en/docs/contributing.md +97 -0
  17. palfrey-0.1.0/docs/en/docs/getting-started/installation.md +136 -0
  18. palfrey-0.1.0/docs/en/docs/getting-started/quickstart.md +136 -0
  19. palfrey-0.1.0/docs/en/docs/guides/faq.md +44 -0
  20. palfrey-0.1.0/docs/en/docs/guides/from-zero-to-production.md +94 -0
  21. palfrey-0.1.0/docs/en/docs/guides/https-tls.md +54 -0
  22. palfrey-0.1.0/docs/en/docs/guides/reverse-proxy-nginx.md +66 -0
  23. palfrey-0.1.0/docs/en/docs/guides/security-hardening.md +43 -0
  24. palfrey-0.1.0/docs/en/docs/guides/troubleshooting.md +96 -0
  25. palfrey-0.1.0/docs/en/docs/index.md +139 -0
  26. palfrey-0.1.0/docs/en/docs/operations/benchmarks.md +58 -0
  27. palfrey-0.1.0/docs/en/docs/operations/capacity-planning.md +40 -0
  28. palfrey-0.1.0/docs/en/docs/operations/deployment.md +94 -0
  29. palfrey-0.1.0/docs/en/docs/operations/docker.md +57 -0
  30. palfrey-0.1.0/docs/en/docs/operations/observability.md +44 -0
  31. palfrey-0.1.0/docs/en/docs/operations/platform-notes.md +32 -0
  32. palfrey-0.1.0/docs/en/docs/operations/release-process.md +44 -0
  33. palfrey-0.1.0/docs/en/docs/operations/reload.md +52 -0
  34. palfrey-0.1.0/docs/en/docs/operations/workers.md +76 -0
  35. palfrey-0.1.0/docs/en/docs/reference/cli.md +163 -0
  36. palfrey-0.1.0/docs/en/docs/reference/configuration.md +122 -0
  37. palfrey-0.1.0/docs/en/docs/reference/environment-variables.md +61 -0
  38. palfrey-0.1.0/docs/en/docs/reference/error-catalog.md +104 -0
  39. palfrey-0.1.0/docs/en/docs/reference/logging.md +60 -0
  40. palfrey-0.1.0/docs/en/docs/reference/protocols.md +90 -0
  41. palfrey-0.1.0/docs/en/docs/release-notes.md +69 -0
  42. palfrey-0.1.0/docs/en/docs/sponsorship.md +28 -0
  43. palfrey-0.1.0/docs/en/docs/stylesheets/extra.css +29 -0
  44. palfrey-0.1.0/docs/en/mkdocs.yml +117 -0
  45. palfrey-0.1.0/docs/language_names.yml +183 -0
  46. palfrey-0.1.0/docs/missing-translation.md.yml +4 -0
  47. palfrey-0.1.0/docs_src/cli/basic_commands.py +11 -0
  48. palfrey-0.1.0/docs_src/concepts/asgi_minimal.py +16 -0
  49. palfrey-0.1.0/docs_src/concepts/asgi_scope_inspector.py +32 -0
  50. palfrey-0.1.0/docs_src/concepts/http_read_body.py +32 -0
  51. palfrey-0.1.0/docs_src/concepts/http_streaming.py +23 -0
  52. palfrey-0.1.0/docs_src/concepts/lifespan_state.py +32 -0
  53. palfrey-0.1.0/docs_src/concepts/proxy_headers_middleware.py +26 -0
  54. palfrey-0.1.0/docs_src/concepts/websocket_auth_gate.py +25 -0
  55. palfrey-0.1.0/docs_src/concepts/websocket_chat_room.py +34 -0
  56. palfrey-0.1.0/docs_src/concepts/websocket_echo.py +18 -0
  57. palfrey-0.1.0/docs_src/config/example.py +21 -0
  58. palfrey-0.1.0/docs_src/getting_started/factory_app.py +24 -0
  59. palfrey-0.1.0/docs_src/getting_started/hello_world.py +20 -0
  60. palfrey-0.1.0/docs_src/getting_started/json_api.py +29 -0
  61. palfrey-0.1.0/docs_src/guides/https_run.py +11 -0
  62. palfrey-0.1.0/docs_src/guides/nginx_reverse_proxy_app.py +20 -0
  63. palfrey-0.1.0/docs_src/guides/troubleshooting_healthcheck.py +34 -0
  64. palfrey-0.1.0/docs_src/lifespan/lifespan_app.py +26 -0
  65. palfrey-0.1.0/docs_src/logging/logging_json.py +2 -0
  66. palfrey-0.1.0/docs_src/middleware/proxy_headers.py +19 -0
  67. palfrey-0.1.0/docs_src/operations/benchmark_plan.py +19 -0
  68. palfrey-0.1.0/docs_src/operations/docker_healthcheck.py +34 -0
  69. palfrey-0.1.0/docs_src/operations/graceful_shutdown.py +23 -0
  70. palfrey-0.1.0/docs_src/operations/gunicorn_conf.py +16 -0
  71. palfrey-0.1.0/docs_src/operations/reload_dev.py +13 -0
  72. palfrey-0.1.0/docs_src/operations/systemd_app.py +20 -0
  73. palfrey-0.1.0/docs_src/operations/workers_cpu_bound.py +13 -0
  74. palfrey-0.1.0/docs_src/protocols/websocket_echo.py +16 -0
  75. palfrey-0.1.0/docs_src/reference/custom_headers.py +11 -0
  76. palfrey-0.1.0/docs_src/reference/env_runtime.py +17 -0
  77. palfrey-0.1.0/docs_src/reference/logging_json.py +18 -0
  78. palfrey-0.1.0/docs_src/reference/programmatic_config.py +16 -0
  79. palfrey-0.1.0/docs_src/reference/programmatic_run.py +23 -0
  80. palfrey-0.1.0/docs_src/reload/reload_cli.py +5 -0
  81. palfrey-0.1.0/docs_src/ssl/ssl_cli.py +5 -0
  82. palfrey-0.1.0/docs_src/workers/workers_cli.py +5 -0
  83. palfrey-0.1.0/palfrey/__init__.py +14 -0
  84. palfrey-0.1.0/palfrey/__main__.py +6 -0
  85. palfrey-0.1.0/palfrey/acceleration.py +191 -0
  86. palfrey-0.1.0/palfrey/adapters.py +230 -0
  87. palfrey-0.1.0/palfrey/cli.py +579 -0
  88. palfrey-0.1.0/palfrey/config.py +808 -0
  89. palfrey-0.1.0/palfrey/env.py +55 -0
  90. palfrey-0.1.0/palfrey/http_date.py +50 -0
  91. palfrey-0.1.0/palfrey/importer.py +213 -0
  92. palfrey-0.1.0/palfrey/lifespan.py +187 -0
  93. palfrey-0.1.0/palfrey/logging_config.py +248 -0
  94. palfrey-0.1.0/palfrey/loops/__init__.py +58 -0
  95. palfrey-0.1.0/palfrey/loops/asyncio.py +21 -0
  96. palfrey-0.1.0/palfrey/loops/auto.py +25 -0
  97. palfrey-0.1.0/palfrey/loops/none.py +23 -0
  98. palfrey-0.1.0/palfrey/loops/uvloop.py +29 -0
  99. palfrey-0.1.0/palfrey/main.py +52 -0
  100. palfrey-0.1.0/palfrey/middleware/__init__.py +6 -0
  101. palfrey-0.1.0/palfrey/middleware/message_logger.py +144 -0
  102. palfrey-0.1.0/palfrey/middleware/proxy_headers.py +186 -0
  103. palfrey-0.1.0/palfrey/protocols/__init__.py +0 -0
  104. palfrey-0.1.0/palfrey/protocols/http.py +822 -0
  105. palfrey-0.1.0/palfrey/protocols/http2.py +265 -0
  106. palfrey-0.1.0/palfrey/protocols/http3.py +301 -0
  107. palfrey-0.1.0/palfrey/protocols/utils.py +139 -0
  108. palfrey-0.1.0/palfrey/protocols/websocket.py +1862 -0
  109. palfrey-0.1.0/palfrey/py.typed +0 -0
  110. palfrey-0.1.0/palfrey/runtime.py +352 -0
  111. palfrey-0.1.0/palfrey/server.py +1171 -0
  112. palfrey-0.1.0/palfrey/supervisors/reload.py +231 -0
  113. palfrey-0.1.0/palfrey/supervisors/workers.py +404 -0
  114. palfrey-0.1.0/palfrey/types.py +66 -0
  115. palfrey-0.1.0/palfrey/workers.py +235 -0
  116. palfrey-0.1.0/pyproject.toml +182 -0
  117. palfrey-0.1.0/rust/palfrey_rust/Cargo.toml +13 -0
  118. palfrey-0.1.0/rust/palfrey_rust/src/lib.rs +102 -0
  119. palfrey-0.1.0/scripts/build-rust-extension +5 -0
  120. palfrey-0.1.0/scripts/clean +29 -0
  121. palfrey-0.1.0/scripts/docs.py +334 -0
  122. palfrey-0.1.0/scripts/hooks.py +254 -0
  123. palfrey-0.1.0/scripts/install +20 -0
  124. palfrey-0.1.0/scripts/publish +25 -0
  125. palfrey-0.1.0/tests/__init__.py +0 -0
  126. palfrey-0.1.0/tests/adapters/__init__.py +0 -0
  127. palfrey-0.1.0/tests/adapters/test_adapters.py +230 -0
  128. palfrey-0.1.0/tests/adapters/test_adapters_compat_extra.py +63 -0
  129. palfrey-0.1.0/tests/benchmarks/__init__.py +0 -0
  130. palfrey-0.1.0/tests/benchmarks/test_run_script.py +148 -0
  131. palfrey-0.1.0/tests/cli/__init__.py +0 -0
  132. palfrey-0.1.0/tests/cli/test_cli_compat.py +281 -0
  133. palfrey-0.1.0/tests/cli/test_cli_runtime_mode_compat.py +84 -0
  134. palfrey-0.1.0/tests/cli/test_cli_surface.py +101 -0
  135. palfrey-0.1.0/tests/config/__init__.py +0 -0
  136. palfrey-0.1.0/tests/config/custom_protocol_classes.py +11 -0
  137. palfrey-0.1.0/tests/config/test_config.py +99 -0
  138. palfrey-0.1.0/tests/config/test_config_bind_socket_compat.py +168 -0
  139. palfrey-0.1.0/tests/config/test_config_compat.py +122 -0
  140. palfrey-0.1.0/tests/config/test_config_load_compat.py +198 -0
  141. palfrey-0.1.0/tests/config/test_config_loop_factory_compat.py +54 -0
  142. palfrey-0.1.0/tests/config/test_config_runtime_modes_compat.py +118 -0
  143. palfrey-0.1.0/tests/config/test_config_uvicorn_compat_extra.py +45 -0
  144. palfrey-0.1.0/tests/fixtures/__init__.py +0 -0
  145. palfrey-0.1.0/tests/fixtures/apps.py +194 -0
  146. palfrey-0.1.0/tests/helpers.py +15 -0
  147. palfrey-0.1.0/tests/importer/__init__.py +0 -0
  148. palfrey-0.1.0/tests/importer/circular_import_a.py +1 -0
  149. palfrey-0.1.0/tests/importer/circular_import_b.py +1 -0
  150. palfrey-0.1.0/tests/importer/raise_import_error.py +3 -0
  151. palfrey-0.1.0/tests/importer/test_importer.py +172 -0
  152. palfrey-0.1.0/tests/importer/test_importer_compat.py +81 -0
  153. palfrey-0.1.0/tests/integration/__init__.py +0 -0
  154. palfrey-0.1.0/tests/integration/test_http_headers_integration.py +109 -0
  155. palfrey-0.1.0/tests/integration/test_http_integration.py +58 -0
  156. palfrey-0.1.0/tests/integration/test_uvicorn_differential_compat.py +706 -0
  157. palfrey-0.1.0/tests/integration/test_websocket_integration.py +114 -0
  158. palfrey-0.1.0/tests/loops/__init__.py +0 -0
  159. palfrey-0.1.0/tests/loops/custom_loop_class.py +7 -0
  160. palfrey-0.1.0/tests/loops/custom_loop_factory.py +8 -0
  161. palfrey-0.1.0/tests/loops/test_custom_loop_compat.py +37 -0
  162. palfrey-0.1.0/tests/loops/test_loops.py +60 -0
  163. palfrey-0.1.0/tests/middleware/__init__.py +0 -0
  164. palfrey-0.1.0/tests/middleware/test_message_logger.py +34 -0
  165. palfrey-0.1.0/tests/middleware/test_message_logger_compat_extra.py +79 -0
  166. palfrey-0.1.0/tests/middleware/test_message_logger_lifecycle_compat.py +51 -0
  167. palfrey-0.1.0/tests/middleware/test_proxy_headers.py +97 -0
  168. palfrey-0.1.0/tests/middleware/test_proxy_headers_compat_extra.py +149 -0
  169. palfrey-0.1.0/tests/middleware/test_proxy_headers_host_matrix_compat.py +79 -0
  170. palfrey-0.1.0/tests/protocols/__init__.py +0 -0
  171. palfrey-0.1.0/tests/protocols/test_http2_protocol.py +328 -0
  172. palfrey-0.1.0/tests/protocols/test_http3_protocol.py +285 -0
  173. palfrey-0.1.0/tests/protocols/test_http_asgi.py +252 -0
  174. palfrey-0.1.0/tests/protocols/test_http_behavior_compat.py +186 -0
  175. palfrey-0.1.0/tests/protocols/test_http_headers_compat_extra.py +114 -0
  176. palfrey-0.1.0/tests/protocols/test_http_parser.py +125 -0
  177. palfrey-0.1.0/tests/protocols/test_http_response.py +125 -0
  178. palfrey-0.1.0/tests/protocols/test_utils.py +116 -0
  179. palfrey-0.1.0/tests/protocols/test_websocket_behavior_compat.py +776 -0
  180. palfrey-0.1.0/tests/protocols/test_websocket_coverage_extra.py +996 -0
  181. palfrey-0.1.0/tests/protocols/test_websocket_protocol.py +2663 -0
  182. palfrey-0.1.0/tests/runtime/__init__.py +0 -0
  183. palfrey-0.1.0/tests/runtime/test_coverage_edges.py +112 -0
  184. palfrey-0.1.0/tests/runtime/test_env.py +42 -0
  185. palfrey-0.1.0/tests/runtime/test_env_dotenv_compat.py +28 -0
  186. palfrey-0.1.0/tests/runtime/test_gunicorn_workers_compat.py +214 -0
  187. palfrey-0.1.0/tests/runtime/test_lifespan.py +71 -0
  188. palfrey-0.1.0/tests/runtime/test_logging_config.py +135 -0
  189. palfrey-0.1.0/tests/runtime/test_logging_config_compat.py +218 -0
  190. palfrey-0.1.0/tests/runtime/test_main_module_compat.py +20 -0
  191. palfrey-0.1.0/tests/runtime/test_public_api_compat.py +14 -0
  192. palfrey-0.1.0/tests/runtime/test_runtime.py +224 -0
  193. palfrey-0.1.0/tests/runtime/test_runtime_api_compat.py +205 -0
  194. palfrey-0.1.0/tests/runtime/test_runtime_behavior_compat.py +157 -0
  195. palfrey-0.1.0/tests/runtime/test_runtime_main_compat.py +44 -0
  196. palfrey-0.1.0/tests/server/__init__.py +0 -0
  197. palfrey-0.1.0/tests/server/test_server_behavior_compat.py +561 -0
  198. palfrey-0.1.0/tests/server/test_server_http_next.py +248 -0
  199. palfrey-0.1.0/tests/server/test_server_internal.py +528 -0
  200. palfrey-0.1.0/tests/server/test_server_serve_compat_extra.py +453 -0
  201. palfrey-0.1.0/tests/supervisors/__init__.py +0 -0
  202. palfrey-0.1.0/tests/supervisors/test_reload.py +294 -0
  203. palfrey-0.1.0/tests/supervisors/test_reload_behavior_compat.py +122 -0
  204. palfrey-0.1.0/tests/supervisors/test_workers.py +238 -0
  205. palfrey-0.1.0/tests/supervisors/test_workers_behavior_compat.py +144 -0
  206. palfrey-0.1.0/tests/unit/__init__.py +0 -0
  207. palfrey-0.1.0/tests/unit/test_acceleration.py +51 -0
  208. palfrey-0.1.0/tests/unit/test_acceleration_compat_extra.py +50 -0
  209. palfrey-0.1.0/tests/unit/test_cli.py +16 -0
  210. palfrey-0.1.0/tests/unit/test_config.py +13 -0
  211. palfrey-0.1.0/tests/unit/test_http_protocol.py +29 -0
  212. palfrey-0.1.0/tests/unit/test_importer.py +27 -0
  213. palfrey-0.1.0/tests/unit/test_websocket_protocol.py +17 -0
@@ -0,0 +1,32 @@
1
+ # folders
2
+ *.egg-info/
3
+ .hypothesis/
4
+ .idea/
5
+ .mypy_cache/
6
+ .pytest_cache/
7
+ .scannerwork/
8
+ .tox/
9
+ .venv/
10
+ .vscode/
11
+ __pycache__/
12
+ virtualenv/
13
+ build/
14
+ dist/
15
+ node_modules/
16
+ results/
17
+ site/
18
+ site_lang/
19
+ target/
20
+
21
+ # files
22
+ par.md
23
+ **/*.so
24
+ **/*.sqlite
25
+ *.iml
26
+ **/*_test*
27
+ .DS_Store
28
+ .coverage
29
+ .coverage.*
30
+ .python-version
31
+ coverage.*
32
+ example.sqlite
palfrey-0.1.0/LICENSE ADDED
@@ -0,0 +1,11 @@
1
+ Copyright © 2025, Dymmond Ltd. All rights reserved.
2
+
3
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
4
+
5
+ 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
6
+
7
+ 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8
+
9
+ 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
10
+
11
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
palfrey-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,220 @@
1
+ Metadata-Version: 2.4
2
+ Name: palfrey
3
+ Version: 0.1.0
4
+ Summary: A clean-room ASGI server with Uvicorn-compatible CLI and behavior mapping.
5
+ Project-URL: Homepage, https://github.com/dymmond/palfrey
6
+ Project-URL: Documentation, https://palfrey.dymmond.com
7
+ Project-URL: Source, https://github.com/dymmond/palfrey
8
+ Project-URL: Changelog, https://github.com/dymmond/palfrey/blob/main/CHANGELOG.md
9
+ Author-email: Tiago Silva <tarsil@tarsild.io>
10
+ License: MIT
11
+ License-File: LICENSE
12
+ Keywords: asgi,click,server,websocket
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Environment :: Web Environment
15
+ Classifier: Framework :: AsyncIO
16
+ Classifier: Intended Audience :: Developers
17
+ Classifier: License :: OSI Approved :: MIT License
18
+ Classifier: Operating System :: OS Independent
19
+ Classifier: Programming Language :: Python
20
+ Classifier: Programming Language :: Python :: 3
21
+ Classifier: Programming Language :: Python :: 3 :: Only
22
+ Classifier: Programming Language :: Python :: 3.10
23
+ Classifier: Programming Language :: Python :: 3.11
24
+ Classifier: Programming Language :: Python :: 3.12
25
+ Classifier: Programming Language :: Python :: 3.13
26
+ Classifier: Programming Language :: Python :: 3.14
27
+ Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
28
+ Classifier: Typing :: Typed
29
+ Requires-Python: >=3.10
30
+ Requires-Dist: click<9.0.0,>=8.1.7
31
+ Requires-Dist: h11>=0.8
32
+ Provides-Extra: benchmark
33
+ Requires-Dist: uvicorn[standard]<1.0.0,>=0.34.0; extra == 'benchmark'
34
+ Provides-Extra: dev
35
+ Requires-Dist: maturin<2.0.0,>=1.9.0; extra == 'dev'
36
+ Requires-Dist: ruff<1.0.0,>=0.11.0; extra == 'dev'
37
+ Requires-Dist: ty>=0.0.1a16; extra == 'dev'
38
+ Provides-Extra: docs
39
+ Requires-Dist: griffe-typingdoc<1.0,>=0.2.2; extra == 'docs'
40
+ Requires-Dist: mdx-include>=1.4.2; extra == 'docs'
41
+ Requires-Dist: mkdocs-macros-plugin>=0.4.0; extra == 'docs'
42
+ Requires-Dist: mkdocs-material>=9.4.4; extra == 'docs'
43
+ Requires-Dist: mkdocs-meta-descriptions-plugin>=2.3.0; extra == 'docs'
44
+ Requires-Dist: mkdocs<2.0.0,>=1.1.2; extra == 'docs'
45
+ Requires-Dist: mkdocstrings[python]>=0.23.0; extra == 'docs'
46
+ Requires-Dist: pyyaml<7.0.0,>=6.0; extra == 'docs'
47
+ Requires-Dist: sayer>=0.7.4; extra == 'docs'
48
+ Requires-Dist: typing-extensions>=3.10.0; extra == 'docs'
49
+ Provides-Extra: http2
50
+ Requires-Dist: h2>=4.1.0; extra == 'http2'
51
+ Provides-Extra: http3
52
+ Requires-Dist: aioquic>=1.2.0; extra == 'http3'
53
+ Provides-Extra: standard
54
+ Requires-Dist: colorama>=0.4; (sys_platform == 'win32') and extra == 'standard'
55
+ Requires-Dist: httptools>=0.6.3; extra == 'standard'
56
+ Requires-Dist: python-dotenv>=0.13; extra == 'standard'
57
+ Requires-Dist: pyyaml>=5.1; extra == 'standard'
58
+ Requires-Dist: uvloop>=0.15.1; (sys_platform != 'win32' and (sys_platform != 'cygwin' and platform_python_implementation != 'PyPy')) and extra == 'standard'
59
+ Requires-Dist: watchfiles>=0.20; extra == 'standard'
60
+ Requires-Dist: websockets>=10.4; extra == 'standard'
61
+ Provides-Extra: testing
62
+ Requires-Dist: pytest-cov<7.0.0,>=5.0.0; extra == 'testing'
63
+ Requires-Dist: pytest<9.0.0,>=8.3.0; extra == 'testing'
64
+ Description-Content-Type: text/markdown
65
+
66
+ # Palfrey
67
+
68
+ <p align="center">
69
+ <a href="https://palfrey.dymmond.com"><img src="https://res.cloudinary.com/dymmond/image/upload/v1771522360/Palfrey/Logo/logo_ocxyty.png" alt='Palfrey'></a>
70
+ </p>
71
+
72
+ <p align="center">
73
+ <em>Palfrey is a clean-room, high-performance Python ASGI server with source-traceable parity mapping.</em>
74
+ </p>
75
+
76
+ <p align="center">
77
+ <a href="https://github.com/dymmond/palfrey/actions/workflows/ci.yml/badge.svg?event=push&branch=main" target="_blank">
78
+ <img src="https://github.com/dymmond/palfrey/actions/workflows/ci.yml/badge.svg?event=push&branch=main" alt="Test Suite">
79
+ </a>
80
+
81
+ <a href="https://pypi.org/project/palfrey" target="_blank">
82
+ <img src="https://img.shields.io/pypi/v/palfrey?color=%2334D058&label=pypi%20package" alt="Package version">
83
+ </a>
84
+
85
+ <a href="https://pypi.org/project/palfrey" target="_blank">
86
+ <img src="https://img.shields.io/pypi/pyversions/palfrey.svg?color=%2334D058" alt="Supported Python versions">
87
+ </a>
88
+ </p>
89
+
90
+ ---
91
+
92
+ **Documentation**: [https://palfrey.dev](https://palfrey.dev) 📚
93
+
94
+ **Source Code**: [https://github.com/dymmond/palfrey](https://github.com/dymmond/palfrey)
95
+
96
+ **The official supported version is always the latest released**.
97
+
98
+ ---
99
+
100
+ Palfrey is a clean-room ASGI server focused on three things:
101
+
102
+ - behavior you can reason about
103
+ - deployment controls you can operate safely
104
+ - performance you can reproduce and verify
105
+
106
+ Protocol runtime modes include HTTP/1.1 backends plus opt-in HTTP/2 (`--http h2`) and HTTP/3 (`--http h3`) paths.
107
+
108
+ This documentation is written for both technical and non-technical readers.
109
+
110
+ - Engineers can use the protocol details, option tables, and runbooks.
111
+ - Product, support, and operations teams can use the plain-language summaries and checklists.
112
+
113
+ ## What Palfrey Does
114
+
115
+ At runtime, Palfrey sits between clients and your ASGI application.
116
+
117
+ 1. accepts TCP or UNIX socket connections
118
+ 2. parses protocol bytes into ASGI events
119
+ 3. calls your app with `scope`, `receive`, `send`
120
+ 4. writes responses back to clients
121
+ 5. manages process behavior (reload, workers, graceful shutdown)
122
+
123
+ ## Who Should Start Where
124
+
125
+ ## If you are new to ASGI
126
+
127
+ 1. [Installation](getting-started/installation.md)
128
+ 2. [Quickstart](getting-started/quickstart.md)
129
+ 3. [Terms and Mental Models](concepts/terms-and-mental-models.md)
130
+ 4. [Server Behavior](concepts/server-behavior.md)
131
+
132
+ ## If you operate production services
133
+
134
+ 1. [Deployment](operations/deployment.md)
135
+ 2. [Workers](operations/workers.md)
136
+ 3. [Observability](operations/observability.md)
137
+ 4. [Troubleshooting](guides/troubleshooting.md)
138
+ 5. [Release Process](operations/release-process.md)
139
+
140
+ ## First 60 Seconds
141
+
142
+ Create `main.py`:
143
+
144
+ ```python
145
+ async def app(scope, receive, send):
146
+ """Return a plain-text greeting for HTTP requests."""
147
+ if scope["type"] != "http":
148
+ return
149
+
150
+ body = b"Hello from Palfrey"
151
+ await send(
152
+ {
153
+ "type": "http.response.start",
154
+ "status": 200,
155
+ "headers": [
156
+ (b"content-type", b"text/plain; charset=utf-8"),
157
+ (b"content-length", str(len(body)).encode("ascii")),
158
+ ],
159
+ }
160
+ )
161
+ await send({"type": "http.response.body", "body": body})
162
+ ```
163
+
164
+ Run Palfrey:
165
+
166
+ ```bash
167
+ palfrey main:app --host 127.0.0.1 --port 8000
168
+ ```
169
+
170
+ Check it:
171
+
172
+ ```bash
173
+ curl http://127.0.0.1:8000
174
+ ```
175
+
176
+ Gunicorn + Palfrey worker:
177
+
178
+ ```bash
179
+ gunicorn main:app -k palfrey.workers.PalfreyWorker -w 4 -b 0.0.0.0:8000
180
+ ```
181
+
182
+ ## Documentation Structure
183
+
184
+ ## Getting Started
185
+
186
+ - install, verify, and run your first app
187
+ - move from a minimal app to real startup patterns
188
+
189
+ ## Concepts
190
+
191
+ - what ASGI is, and how Palfrey applies it
192
+ - how HTTP, WebSocket, and lifespan flows behave
193
+ - how server internals affect user-visible outcomes
194
+
195
+ ## Reference
196
+
197
+ - full CLI and config surface
198
+ - protocol and logging behavior
199
+ - env var model and common errors
200
+
201
+ ## Guides
202
+
203
+ - migration, security hardening, production rollout
204
+ - practical troubleshooting and FAQ
205
+
206
+ ## Operations
207
+
208
+ - deployment shapes, workers, reload model
209
+ - capacity planning, observability, benchmark method
210
+ - platform-specific notes and release process
211
+
212
+ ## Plain-Language Summary
213
+
214
+ If your application is the business logic, Palfrey is the runtime control layer around it.
215
+ A good runtime control layer gives teams:
216
+
217
+ - predictable startup and shutdown
218
+ - fewer surprises under traffic spikes
219
+ - clearer incident response paths
220
+ - safer, repeatable deployments
@@ -0,0 +1,155 @@
1
+ # Palfrey
2
+
3
+ <p align="center">
4
+ <a href="https://palfrey.dymmond.com"><img src="https://res.cloudinary.com/dymmond/image/upload/v1771522360/Palfrey/Logo/logo_ocxyty.png" alt='Palfrey'></a>
5
+ </p>
6
+
7
+ <p align="center">
8
+ <em>Palfrey is a clean-room, high-performance Python ASGI server with source-traceable parity mapping.</em>
9
+ </p>
10
+
11
+ <p align="center">
12
+ <a href="https://github.com/dymmond/palfrey/actions/workflows/ci.yml/badge.svg?event=push&branch=main" target="_blank">
13
+ <img src="https://github.com/dymmond/palfrey/actions/workflows/ci.yml/badge.svg?event=push&branch=main" alt="Test Suite">
14
+ </a>
15
+
16
+ <a href="https://pypi.org/project/palfrey" target="_blank">
17
+ <img src="https://img.shields.io/pypi/v/palfrey?color=%2334D058&label=pypi%20package" alt="Package version">
18
+ </a>
19
+
20
+ <a href="https://pypi.org/project/palfrey" target="_blank">
21
+ <img src="https://img.shields.io/pypi/pyversions/palfrey.svg?color=%2334D058" alt="Supported Python versions">
22
+ </a>
23
+ </p>
24
+
25
+ ---
26
+
27
+ **Documentation**: [https://palfrey.dev](https://palfrey.dev) 📚
28
+
29
+ **Source Code**: [https://github.com/dymmond/palfrey](https://github.com/dymmond/palfrey)
30
+
31
+ **The official supported version is always the latest released**.
32
+
33
+ ---
34
+
35
+ Palfrey is a clean-room ASGI server focused on three things:
36
+
37
+ - behavior you can reason about
38
+ - deployment controls you can operate safely
39
+ - performance you can reproduce and verify
40
+
41
+ Protocol runtime modes include HTTP/1.1 backends plus opt-in HTTP/2 (`--http h2`) and HTTP/3 (`--http h3`) paths.
42
+
43
+ This documentation is written for both technical and non-technical readers.
44
+
45
+ - Engineers can use the protocol details, option tables, and runbooks.
46
+ - Product, support, and operations teams can use the plain-language summaries and checklists.
47
+
48
+ ## What Palfrey Does
49
+
50
+ At runtime, Palfrey sits between clients and your ASGI application.
51
+
52
+ 1. accepts TCP or UNIX socket connections
53
+ 2. parses protocol bytes into ASGI events
54
+ 3. calls your app with `scope`, `receive`, `send`
55
+ 4. writes responses back to clients
56
+ 5. manages process behavior (reload, workers, graceful shutdown)
57
+
58
+ ## Who Should Start Where
59
+
60
+ ## If you are new to ASGI
61
+
62
+ 1. [Installation](getting-started/installation.md)
63
+ 2. [Quickstart](getting-started/quickstart.md)
64
+ 3. [Terms and Mental Models](concepts/terms-and-mental-models.md)
65
+ 4. [Server Behavior](concepts/server-behavior.md)
66
+
67
+ ## If you operate production services
68
+
69
+ 1. [Deployment](operations/deployment.md)
70
+ 2. [Workers](operations/workers.md)
71
+ 3. [Observability](operations/observability.md)
72
+ 4. [Troubleshooting](guides/troubleshooting.md)
73
+ 5. [Release Process](operations/release-process.md)
74
+
75
+ ## First 60 Seconds
76
+
77
+ Create `main.py`:
78
+
79
+ ```python
80
+ async def app(scope, receive, send):
81
+ """Return a plain-text greeting for HTTP requests."""
82
+ if scope["type"] != "http":
83
+ return
84
+
85
+ body = b"Hello from Palfrey"
86
+ await send(
87
+ {
88
+ "type": "http.response.start",
89
+ "status": 200,
90
+ "headers": [
91
+ (b"content-type", b"text/plain; charset=utf-8"),
92
+ (b"content-length", str(len(body)).encode("ascii")),
93
+ ],
94
+ }
95
+ )
96
+ await send({"type": "http.response.body", "body": body})
97
+ ```
98
+
99
+ Run Palfrey:
100
+
101
+ ```bash
102
+ palfrey main:app --host 127.0.0.1 --port 8000
103
+ ```
104
+
105
+ Check it:
106
+
107
+ ```bash
108
+ curl http://127.0.0.1:8000
109
+ ```
110
+
111
+ Gunicorn + Palfrey worker:
112
+
113
+ ```bash
114
+ gunicorn main:app -k palfrey.workers.PalfreyWorker -w 4 -b 0.0.0.0:8000
115
+ ```
116
+
117
+ ## Documentation Structure
118
+
119
+ ## Getting Started
120
+
121
+ - install, verify, and run your first app
122
+ - move from a minimal app to real startup patterns
123
+
124
+ ## Concepts
125
+
126
+ - what ASGI is, and how Palfrey applies it
127
+ - how HTTP, WebSocket, and lifespan flows behave
128
+ - how server internals affect user-visible outcomes
129
+
130
+ ## Reference
131
+
132
+ - full CLI and config surface
133
+ - protocol and logging behavior
134
+ - env var model and common errors
135
+
136
+ ## Guides
137
+
138
+ - migration, security hardening, production rollout
139
+ - practical troubleshooting and FAQ
140
+
141
+ ## Operations
142
+
143
+ - deployment shapes, workers, reload model
144
+ - capacity planning, observability, benchmark method
145
+ - platform-specific notes and release process
146
+
147
+ ## Plain-Language Summary
148
+
149
+ If your application is the business logic, Palfrey is the runtime control layer around it.
150
+ A good runtime control layer gives teams:
151
+
152
+ - predictable startup and shutdown
153
+ - fewer surprises under traffic spikes
154
+ - clearer incident response paths
155
+ - safer, repeatable deployments
@@ -0,0 +1 @@
1
+ """Benchmark package for Palfrey performance comparisons."""
@@ -0,0 +1,39 @@
1
+ """Benchmark ASGI application targets."""
2
+
3
+ from __future__ import annotations
4
+
5
+
6
+ async def app(scope, receive, send):
7
+ """Serve HTTP and WebSocket echo paths for benchmark workloads."""
8
+
9
+ if scope["type"] == "lifespan":
10
+ while True:
11
+ message = await receive()
12
+ if message["type"] == "lifespan.startup":
13
+ await send({"type": "lifespan.startup.complete"})
14
+ elif message["type"] == "lifespan.shutdown":
15
+ await send({"type": "lifespan.shutdown.complete"})
16
+ return
17
+
18
+ if scope["type"] == "http":
19
+ await send(
20
+ {
21
+ "type": "http.response.start",
22
+ "status": 200,
23
+ "headers": [(b"content-type", b"text/plain")],
24
+ }
25
+ )
26
+ await send({"type": "http.response.body", "body": b"pong"})
27
+ return
28
+
29
+ if scope["type"] == "websocket":
30
+ await send({"type": "websocket.accept"})
31
+ while True:
32
+ message = await receive()
33
+ if message["type"] == "websocket.disconnect":
34
+ return
35
+ if message["type"] == "websocket.receive":
36
+ if "text" in message:
37
+ await send({"type": "websocket.send", "text": message["text"]})
38
+ else:
39
+ await send({"type": "websocket.send", "bytes": message.get("bytes", b"")})