Pyjoyment 0.1.0__py3-none-any.whl

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 (200) hide show
  1. Pyjo/App/ASGI.py +735 -0
  2. Pyjo/App/CGI.py +773 -0
  3. Pyjo/App/FastCGI.py +631 -0
  4. Pyjo/App/Lambda.py +987 -0
  5. Pyjo/App/WSGI.py +427 -0
  6. Pyjo/App/__init__.py +409 -0
  7. Pyjo/Asset/File.py +377 -0
  8. Pyjo/Asset/Memory.py +235 -0
  9. Pyjo/Asset/__init__.py +200 -0
  10. Pyjo/Base.py +215 -0
  11. Pyjo/Cache.py +119 -0
  12. Pyjo/Collection.py +570 -0
  13. Pyjo/Content/MultiPart.py +325 -0
  14. Pyjo/Content/Single.py +193 -0
  15. Pyjo/Content/__init__.py +806 -0
  16. Pyjo/Cookie/Request.py +90 -0
  17. Pyjo/Cookie/Response.py +294 -0
  18. Pyjo/Cookie/__init__.py +143 -0
  19. Pyjo/DOM/CSS.py +1019 -0
  20. Pyjo/DOM/HTML.py +550 -0
  21. Pyjo/DOM/__init__.py +1329 -0
  22. Pyjo/Date.py +294 -0
  23. Pyjo/EventEmitter.py +522 -0
  24. Pyjo/Exception.py +494 -0
  25. Pyjo/File.py +959 -0
  26. Pyjo/GetOpt.py +605 -0
  27. Pyjo/Headers.py +760 -0
  28. Pyjo/HelloWorld.py +77 -0
  29. Pyjo/Home.py +109 -0
  30. Pyjo/IOLoop/ChildProcess.py +591 -0
  31. Pyjo/IOLoop/Client.py +736 -0
  32. Pyjo/IOLoop/Datagram.py +982 -0
  33. Pyjo/IOLoop/Messages.py +664 -0
  34. Pyjo/IOLoop/Server.py +458 -0
  35. Pyjo/IOLoop/Stdio.py +446 -0
  36. Pyjo/IOLoop/Stream.py +644 -0
  37. Pyjo/IOLoop/Subprocess.py +419 -0
  38. Pyjo/IOLoop/TLS.py +360 -0
  39. Pyjo/IOLoop/__init__.py +1036 -0
  40. Pyjo/IOLoop/certs/README.md +41 -0
  41. Pyjo/IOLoop/certs/ca.crt +20 -0
  42. Pyjo/IOLoop/certs/server.crt +21 -0
  43. Pyjo/IOLoop/certs/server.key +28 -0
  44. Pyjo/JSON/Pointer.py +135 -0
  45. Pyjo/JSON/RPC.py +772 -0
  46. Pyjo/JSON/Schema.py +2506 -0
  47. Pyjo/JSON/__init__.py +573 -0
  48. Pyjo/Loader.py +342 -0
  49. Pyjo/Log.py +723 -0
  50. Pyjo/Message/Request.py +725 -0
  51. Pyjo/Message/Response.py +476 -0
  52. Pyjo/Message/__init__.py +830 -0
  53. Pyjo/Parameters.py +472 -0
  54. Pyjo/Path.py +419 -0
  55. Pyjo/Promise.py +894 -0
  56. Pyjo/Prove.py +1305 -0
  57. Pyjo/Reactor/Asyncio.py +854 -0
  58. Pyjo/Reactor/Poll.py +439 -0
  59. Pyjo/Reactor/__init__.py +525 -0
  60. Pyjo/SSE.py +119 -0
  61. Pyjo/Server/ASGI.py +486 -0
  62. Pyjo/Server/CGI.py +259 -0
  63. Pyjo/Server/Daemon.py +1007 -0
  64. Pyjo/Server/FastCGI.py +517 -0
  65. Pyjo/Server/Hot/__init__.py +687 -0
  66. Pyjo/Server/Hot/__main__.py +5 -0
  67. Pyjo/Server/Lambda.py +641 -0
  68. Pyjo/Server/Prefork.py +917 -0
  69. Pyjo/Server/Prethread.py +394 -0
  70. Pyjo/Server/Reload/Backend/Poll.py +114 -0
  71. Pyjo/Server/Reload/Backend/__init__.py +126 -0
  72. Pyjo/Server/Reload/__init__.py +482 -0
  73. Pyjo/Server/Reload/__main__.py +5 -0
  74. Pyjo/Server/Stdio.py +228 -0
  75. Pyjo/Server/WSGI.py +349 -0
  76. Pyjo/Server/__init__.py +396 -0
  77. Pyjo/String/Bytes.py +532 -0
  78. Pyjo/String/HTML.py +210 -0
  79. Pyjo/String/Mixin.py +333 -0
  80. Pyjo/String/Template.py +470 -0
  81. Pyjo/String/Unicode.py +553 -0
  82. Pyjo/String/__init__.py +0 -0
  83. Pyjo/TOML.py +232 -0
  84. Pyjo/Template.py +1290 -0
  85. Pyjo/Test/Pyjo.py +1454 -0
  86. Pyjo/Test/__init__.py +1233 -0
  87. Pyjo/Test/pytest_plugin.py +305 -0
  88. Pyjo/Transaction/HTTP.py +374 -0
  89. Pyjo/Transaction/WebSocket.py +709 -0
  90. Pyjo/Transaction/__init__.py +429 -0
  91. Pyjo/URL/Template.py +459 -0
  92. Pyjo/URL/__init__.py +651 -0
  93. Pyjo/Upload.py +139 -0
  94. Pyjo/UserAgent/CookieJar.py +391 -0
  95. Pyjo/UserAgent/Proxy.py +138 -0
  96. Pyjo/UserAgent/Server.py +239 -0
  97. Pyjo/UserAgent/Transactor.py +766 -0
  98. Pyjo/UserAgent/__init__.py +1243 -0
  99. Pyjo/Util.py +3567 -0
  100. Pyjo/WebSocket.py +332 -0
  101. Pyjo/YAML.py +1167 -0
  102. Pyjo/__init__.py +441 -0
  103. Pyjo/__main__.py +35 -0
  104. Pyjo/py.typed +0 -0
  105. Pyjoyment/Command/Author/__init__.py +20 -0
  106. Pyjoyment/Command/Author/generate/__init__.py +106 -0
  107. Pyjoyment/Command/Author/generate/app.py +299 -0
  108. Pyjoyment/Command/Author/generate/dockerfile.py +281 -0
  109. Pyjoyment/Command/Author/generate/kubernetes.py +514 -0
  110. Pyjoyment/Command/Author/generate/lambda_zip.py +372 -0
  111. Pyjoyment/Command/Author/generate/lite_app.py +113 -0
  112. Pyjoyment/Command/Author/generate/plugin.py +267 -0
  113. Pyjoyment/Command/Author/generate/pyproject.py +123 -0
  114. Pyjoyment/Command/Author/inflate.py +101 -0
  115. Pyjoyment/Command/__init__.py +332 -0
  116. Pyjoyment/Command/asgi.py +92 -0
  117. Pyjoyment/Command/cgi.py +90 -0
  118. Pyjoyment/Command/daemon.py +160 -0
  119. Pyjoyment/Command/eval.py +128 -0
  120. Pyjoyment/Command/fastcgi.py +99 -0
  121. Pyjoyment/Command/get.py +305 -0
  122. Pyjoyment/Command/lambda.py +117 -0
  123. Pyjoyment/Command/prefork.py +181 -0
  124. Pyjoyment/Command/prethread.py +126 -0
  125. Pyjoyment/Command/routes.py +133 -0
  126. Pyjoyment/Command/stdio.py +92 -0
  127. Pyjoyment/Command/version.py +141 -0
  128. Pyjoyment/Command/wsgi.py +93 -0
  129. Pyjoyment/Commands.py +546 -0
  130. Pyjoyment/Controller.py +1307 -0
  131. Pyjoyment/HelloWorld.py +56 -0
  132. Pyjoyment/Lite.py +494 -0
  133. Pyjoyment/Plugin/AllowedHosts.py +205 -0
  134. Pyjoyment/Plugin/Config.py +248 -0
  135. Pyjoyment/Plugin/DefaultHelpers.py +1202 -0
  136. Pyjoyment/Plugin/EPLRenderer.py +134 -0
  137. Pyjoyment/Plugin/EPRenderer.py +212 -0
  138. Pyjoyment/Plugin/HeaderCondition.py +98 -0
  139. Pyjoyment/Plugin/Health.py +325 -0
  140. Pyjoyment/Plugin/JSONConfig.py +172 -0
  141. Pyjoyment/Plugin/Mount.py +223 -0
  142. Pyjoyment/Plugin/PyRenderer.py +209 -0
  143. Pyjoyment/Plugin/TOMLConfig.py +141 -0
  144. Pyjoyment/Plugin/TagHelpers.py +959 -0
  145. Pyjoyment/Plugin/YAMLConfig.py +178 -0
  146. Pyjoyment/Plugin/__init__.py +80 -0
  147. Pyjoyment/Plugins.py +215 -0
  148. Pyjoyment/Renderer.py +673 -0
  149. Pyjoyment/Routes/Match.py +251 -0
  150. Pyjoyment/Routes/Pattern.py +443 -0
  151. Pyjoyment/Routes/Route.py +827 -0
  152. Pyjoyment/Routes/__init__.py +419 -0
  153. Pyjoyment/Sessions.py +255 -0
  154. Pyjoyment/Static.py +421 -0
  155. Pyjoyment/Types.py +238 -0
  156. Pyjoyment/Validator/Validation.py +395 -0
  157. Pyjoyment/Validator/__init__.py +304 -0
  158. Pyjoyment/__init__.py +1083 -0
  159. Pyjoyment/__main__.py +5 -0
  160. Pyjoyment/py.typed +0 -0
  161. Pyjoyment/resources/public/favicon.ico +0 -0
  162. Pyjoyment/resources/public/favicon.svg +345 -0
  163. Pyjoyment/resources/public/pyjo/bootstrap/LICENSE +21 -0
  164. Pyjoyment/resources/public/pyjo/bootstrap/bootstrap.bundle.min.js.map +1 -0
  165. Pyjoyment/resources/public/pyjo/bootstrap/bootstrap.css +6 -0
  166. Pyjoyment/resources/public/pyjo/bootstrap/bootstrap.js +7 -0
  167. Pyjoyment/resources/public/pyjo/bootstrap/bootstrap.min.css.map +1 -0
  168. Pyjoyment/resources/public/pyjo/failunicat.png +0 -0
  169. Pyjoyment/resources/public/pyjo/failunicat.svg +50 -0
  170. Pyjoyment/resources/public/pyjo/highlight.js/LICENSE +29 -0
  171. Pyjoyment/resources/public/pyjo/highlight.js/highlight-mojo-dark.css +56 -0
  172. Pyjoyment/resources/public/pyjo/highlight.js/highlight.min.js +1262 -0
  173. Pyjoyment/resources/public/pyjo/highlight.js/pyjoyment.min.js +1 -0
  174. Pyjoyment/resources/public/pyjo/logo-black-4x.png +0 -0
  175. Pyjoyment/resources/public/pyjo/logo-black-4x.svg +346 -0
  176. Pyjoyment/resources/public/pyjo/logo-white-2x.png +0 -0
  177. Pyjoyment/resources/public/pyjo/logo-white-2x.svg +346 -0
  178. Pyjoyment/resources/public/pyjo/logo-white-4x.png +0 -0
  179. Pyjoyment/resources/public/pyjo/logo-white-4x.svg +346 -0
  180. Pyjoyment/resources/public/pyjo/logo-white.png +0 -0
  181. Pyjoyment/resources/public/pyjo/logo-white.svg +346 -0
  182. Pyjoyment/resources/public/pyjo/logo.png +0 -0
  183. Pyjoyment/resources/public/pyjo/logo.svg +346 -0
  184. Pyjoyment/resources/public/pyjo/notfound.png +0 -0
  185. Pyjoyment/resources/public/pyjo/notfound.svg +3 -0
  186. Pyjoyment/resources/public/pyjo/nounicat.png +0 -0
  187. Pyjoyment/resources/public/pyjo/nounicat.svg +5 -0
  188. Pyjoyment/resources/public/pyjo/pinstripe-dark.png +0 -0
  189. Pyjoyment/resources/public/pyjo/pinstripe-dark.svg +4 -0
  190. Pyjoyment/resources/public/pyjo/pinstripe-light.png +0 -0
  191. Pyjoyment/resources/public/pyjo/pinstripe-light.svg +4 -0
  192. Pyjoyment/resources/public/pyjo/pyjo.css +204 -0
  193. Pyjoyment/resources/templates/pyjo/debug.html.ep +346 -0
  194. Pyjoyment/resources/templates/pyjo/exception.html.ep +32 -0
  195. Pyjoyment/resources/templates/pyjo/not_found.html.ep +45 -0
  196. pyjoyment-0.1.0.dist-info/METADATA +376 -0
  197. pyjoyment-0.1.0.dist-info/RECORD +200 -0
  198. pyjoyment-0.1.0.dist-info/WHEEL +4 -0
  199. pyjoyment-0.1.0.dist-info/entry_points.txt +8 -0
  200. pyjoyment-0.1.0.dist-info/licenses/LICENSE +201 -0
@@ -0,0 +1,376 @@
1
+ Metadata-Version: 2.5
2
+ Name: Pyjoyment
3
+ Version: 0.1.0
4
+ Summary: A real-time web framework for the Python programming language, ported from Mojolicious.
5
+ Project-URL: Homepage, https://github.com/dex4er/Pyjoyment
6
+ Project-URL: Documentation, https://pyjoyment.readthedocs.io/
7
+ Project-URL: Source, https://github.com/dex4er/Pyjoyment
8
+ Project-URL: Issues, https://github.com/dex4er/Pyjoyment/issues
9
+ Project-URL: Changelog, https://github.com/dex4er/Pyjoyment/releases
10
+ Author-email: Piotr Roszatycki <piotr.roszatycki@gmail.com>
11
+ License-Expression: Artistic-2.0
12
+ License-File: LICENSE
13
+ Keywords: asgi,async,asyncio,aws-lambda,framework,html,http,json-rpc,json-schema,mojo,mojolicious,pyjo,pyjoyment,tap,test,web,websocket,wsgi
14
+ Classifier: Development Status :: 3 - Alpha
15
+ Classifier: Environment :: Web Environment
16
+ Classifier: Framework :: AsyncIO
17
+ Classifier: Framework :: Pytest
18
+ Classifier: Intended Audience :: Developers
19
+ Classifier: Operating System :: OS Independent
20
+ Classifier: Programming Language :: Python :: 3
21
+ Classifier: Programming Language :: Python :: 3 :: Only
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
24
+ Classifier: Programming Language :: Python :: 3.14
25
+ Classifier: Programming Language :: Python :: 3.15
26
+ Classifier: Programming Language :: Python :: Free Threading :: 2 - Beta
27
+ Classifier: Programming Language :: Python :: Implementation :: CPython
28
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
29
+ Classifier: Topic :: File Formats :: JSON :: JSON Schema
30
+ Classifier: Topic :: Internet :: WWW/HTTP
31
+ Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
32
+ Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
33
+ Classifier: Topic :: Internet :: WWW/HTTP :: WSGI
34
+ Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application
35
+ Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Server
36
+ Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
37
+ Classifier: Topic :: Software Development :: Testing
38
+ Classifier: Topic :: Text Processing :: Markup :: HTML
39
+ Classifier: Typing :: Typed
40
+ Requires-Python: >=3.12
41
+ Description-Content-Type: text/markdown
42
+
43
+ [![Home](https://img.shields.io/badge/%F0%9F%8F%A0-Pyjoyment-02a7a0)](https://github.com/dex4er/Pyjoyment)
44
+ [![GitHub](https://img.shields.io/github/stars/dex4er/Pyjoyment?style=flat&label=GitHub%20%E2%AD%90&logo=github)](https://github.com/dex4er/Pyjoyment)
45
+ [![Documentation](https://img.shields.io/badge/docs-Read_the_Docs-blue?logo=readthedocs&logoColor=white)](https://pyjoyment.readthedocs.io/en/latest/)
46
+ [![DeepWiki](https://img.shields.io/badge/Ask-DeepWiki-blue)](https://deepwiki.com/dex4er/Pyjoyment)
47
+ [![License](https://img.shields.io/github/license/dex4er/Pyjoyment.svg)](https://github.com/dex4er/Pyjoyment/blob/main/LICENSE)
48
+ [![PyPI](https://img.shields.io/pypi/v/Pyjoyment?logo=pypi&logoColor=white)](https://pypi.org/project/Pyjoyment/)
49
+ [![Tests](https://github.com/dex4er/Pyjoyment/actions/workflows/tests.yaml/badge.svg?branch=main)](https://github.com/dex4er/Pyjoyment/actions/workflows/tests.yaml)
50
+ [![Trunk Check](https://github.com/dex4er/Pyjoyment/actions/workflows/trunk-check.yaml/badge.svg?branch=main)](https://github.com/dex4er/Pyjoyment/actions/workflows/trunk-check.yaml)
51
+
52
+ # Pyjoyment
53
+
54
+ <p align="center">
55
+ <picture>
56
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/dex4er/Pyjoyment/main/Pyjoyment/resources/public/pyjo/logo-white-4x.png">
57
+ <img src="https://raw.githubusercontent.com/dex4er/Pyjoyment/main/Pyjoyment/resources/public/pyjo/logo-black-4x.png" alt="Pyjoyment" width="322">
58
+ </picture>
59
+ </p>
60
+
61
+ A real-time web framework for the Python programming language, ported from
62
+ [Mojolicious](https://mojolicious.org), the real-time web framework for Perl.
63
+ Pyjoyment keeps the API of Mojolicious with Python names, so its documentation
64
+ and experience carry over.
65
+
66
+ The `Pyjo` package is the web development toolkit, ported from the `Mojo`
67
+ modules, which can be used for all kinds of applications independently of the
68
+ web framework:
69
+
70
+ - HTTP and WebSocket client and server.
71
+ - Non-blocking I/O web server, which also speaks FastCGI, to a web server in
72
+ front of it and to an application behind it, as PHP on php-fpm, and runs as
73
+ an ASGI, WSGI or CGI application, or as an event function of AWS Lambda.
74
+ - HTML/XML parser with CSS selector support.
75
+ - JSON with JSON Pointers and JSON Schema, from type hints and validated,
76
+ YAML and TOML, all loaded and dumped.
77
+ - JSON-RPC 2.0, its server and its client, over HTTP or any other transport.
78
+ - Command line options with `Pyjo.GetOpt`, in the way of Getopt::Long,
79
+ argparse and Cobra, also from environment variables.
80
+ - Python-ish templates and template strings, with automatic escaping.
81
+ - Containers for URLs, paths, query strings, headers, cookies and HTTP
82
+ messages.
83
+ - Event emitter, event loop with TCP, UDP and UNIX domain sockets and child
84
+ processes, logger and utility functions.
85
+ - Test scripts which print the [Test Anything Protocol](https://testanything.org/)
86
+ (TAP), with `Pyjo.Test`, inspired by Perl's `Test::More`, and a test
87
+ harness, `Pyjo.Prove`, inspired by Perl's `prove`.
88
+
89
+ The `Pyjoyment` package is the web framework itself: routes, controllers,
90
+ renderer, plugins, `Pyjoyment.Lite` and the command line interface. It
91
+ renders JSON, YAML and TOML, and reads its configuration from Python, JSON,
92
+ YAML and TOML files.
93
+
94
+ It mounts the applications of other frameworks under a path or a host, next to
95
+ its own routes: WSGI applications, as those of Flask, and ASGI applications, as
96
+ those of Starlette and the servers of the MCP SDK, in the same process and on
97
+ the same server, whose responses stream at the pace of the client, with their
98
+ WebSockets, FastCGI applications, as PHP on php-fpm, which it connects to, CGI
99
+ programs, which it runs, as a web server does, with one script for every path
100
+ or the scripts of a directory, and event functions of AWS Lambda, which it runs
101
+ in a process of their own, as Lambda does.
102
+
103
+ Both are cloud native: `generate dockerfile` writes the image of an
104
+ application, whose server stops gracefully on the `TERM` of its container
105
+ and listens on the port of `PORT`, as Knative, Cloud Run, Render, Koyeb and
106
+ Heroku set it, and an application runs as an event function of AWS Lambda
107
+ too.
108
+
109
+ Pyjoyment requires Python 3.12 or newer and runs on PyPy on a best-effort
110
+ basis. It needs nothing besides the Python standard library.
111
+
112
+ ## Status
113
+
114
+ Pyjoyment was written against Mojolicious 6 and is being revived as a port of
115
+ Mojolicious 9 to Python 3.12 and newer, with `asyncio` as its event loop.
116
+ The toolkit, the `Pyjo` package, is ported: URLs, DOM and CSS selectors,
117
+ JSON, templates, HTTP messages and cookies, the event loop with promises, the
118
+ user agent, and the servers, on their own, preforking, prethreading, with hot
119
+ deployment or reloading, and through FastCGI, ASGI, WSGI, CGI and AWS Lambda. So is the web framework, the
120
+ `Pyjoyment` package: routes, controllers, the renderer with templates and
121
+ template strings, plugins, `Pyjoyment.Lite` and the commands. The tests of
122
+ Mojolicious are ported with them, and a ported module names the Mojolicious
123
+ version it was ported from in its documentation.
124
+
125
+ Pyjoyment runs on Linux, macOS and Windows. On Windows, Python has no
126
+ `os.fork` and no UNIX domain sockets, so `Pyjo.Server.Prefork`,
127
+ `Pyjo.Server.Hot`, `Pyjo.Server.Reload` and `Pyjo.IOLoop.Subprocess` do not
128
+ run there, and `Pyjo.Server.Prethread` runs the workers in threads instead.
129
+ The event loop watches up to 512 sockets there, with the `select` of Windows,
130
+ and a server stops with Ctrl-C, gracefully, or with Ctrl-Break, immediately.
131
+
132
+ The progress is tracked in [GitHub Issues](https://github.com/dex4er/Pyjoyment/issues).
133
+
134
+ ## Installation
135
+
136
+ Pyjoyment is installed from its Git repository, as the release on PyPI
137
+ predates the revival:
138
+
139
+ ```sh
140
+ pip install git+https://github.com/dex4er/Pyjoyment
141
+ ```
142
+
143
+ or, in a project managed with [uv](https://docs.astral.sh/uv/):
144
+
145
+ ```sh
146
+ uv add git+https://github.com/dex4er/Pyjoyment
147
+ ```
148
+
149
+ The skills for coding agents that write applications with Pyjoyment are a
150
+ plugin of [Claude Code](https://code.claude.com/docs/en/plugins), whose
151
+ `SKILL.md` files other agents read too:
152
+
153
+ ```text
154
+ /plugin install pyjoyment --marketplace dex4er/Pyjoyment
155
+ ```
156
+
157
+ or from the shell, as the extensions of the editors have no `/plugin`:
158
+
159
+ ```sh
160
+ claude plugin install pyjoyment --marketplace dex4er/Pyjoyment
161
+ ```
162
+
163
+ ## Quick start
164
+
165
+ These three lines are a whole web application.
166
+
167
+ ```python
168
+ from Pyjoyment.Lite import *
169
+
170
+
171
+ get('/', {'text': 'I ♥ Pyjoyment!'})
172
+
173
+ app.start()
174
+ ```
175
+
176
+ To run the example with the built-in development web server, just put the
177
+ code into a file and start it with `pyjo-reload`.
178
+
179
+ ```console
180
+ $ pyjo-reload hello.py
181
+ Web application available at http://127.0.0.1:3000
182
+ ```
183
+
184
+ Test it with any HTTP client you prefer.
185
+
186
+ ```console
187
+ $ curl http://127.0.0.1:3000/
188
+ I ♥ Pyjoyment!
189
+ ```
190
+
191
+ ## Duct tape for the HTML5 web
192
+
193
+ Use all the latest Python and HTML features in beautiful single file
194
+ prototypes like this one, and grow them easily into well-structured
195
+ Model-View-Controller web applications with `pyjo generate app`.
196
+
197
+ ```python
198
+ """
199
+ __DATA__
200
+
201
+ @@ index.html.ep
202
+ % url = url_for('title')
203
+ <script>
204
+ const ws = new WebSocket('<%= url.to_abs() %>');
205
+ ws.onmessage = function (event) { document.body.innerHTML += event.data };
206
+ ws.onopen = function (event) { ws.send('https://mojolicious.org') };
207
+ </script>
208
+ """
209
+
210
+ from Pyjoyment.Lite import *
211
+
212
+
213
+ # Render template "index.html.ep" from the DATA section
214
+ @get('/')
215
+ def index(c):
216
+ c.render(template='index')
217
+
218
+
219
+ # WebSocket service used by the template to extract the title from a website
220
+ @websocket('/title')
221
+ def title(c):
222
+ @c.on('message')
223
+ def message(c, msg):
224
+ c.ua().get_p(msg).then(lambda tx: c.send(tx.result.dom().at('title').text))
225
+
226
+
227
+ app.start()
228
+ ```
229
+
230
+ The templates of a script of `Pyjoyment.Lite` are in its docstring, after a
231
+ line `__DATA__`, and the website is requested without blocking, as the
232
+ WebSocket service runs in the event loop.
233
+
234
+ ## Servers
235
+
236
+ `Pyjo.HelloWorld` is the application that a server runs when it is given
237
+ none, and it answers every request with `Your Pyjo is working!`. It runs
238
+ natively on the web server of Pyjoyment:
239
+
240
+ ```python
241
+ import Pyjo.HelloWorld
242
+ import Pyjo.Server.Daemon
243
+
244
+
245
+ Pyjo.Server.Daemon.new(app=Pyjo.HelloWorld.new(), listen=['http://*:3000']).run()
246
+ ```
247
+
248
+ on [uvicorn](https://www.uvicorn.org/), an ASGI server
249
+ (`pip install uvicorn`):
250
+
251
+ ```python
252
+ import Pyjo.HelloWorld
253
+ import Pyjo.Server.ASGI
254
+
255
+ import uvicorn
256
+
257
+
258
+ app = Pyjo.Server.ASGI.new(app=Pyjo.HelloWorld.new()).to_asgi_app()
259
+
260
+ uvicorn.run(app, port=3000)
261
+ ```
262
+
263
+ or on [Werkzeug](https://werkzeug.palletsprojects.com/), a WSGI server
264
+ (`pip install werkzeug`):
265
+
266
+ ```python
267
+ import Pyjo.HelloWorld
268
+ import Pyjo.Server.WSGI
269
+
270
+ from werkzeug.serving import run_simple
271
+
272
+
273
+ app = Pyjo.Server.WSGI.new(app=Pyjo.HelloWorld.new()).to_wsgi_app()
274
+
275
+ run_simple('localhost', 3000, app)
276
+ ```
277
+
278
+ and answers on port 3000:
279
+
280
+ ```sh
281
+ curl http://localhost:3000/
282
+ ```
283
+
284
+ On a platform that tells the server the port to listen on with the `PORT`
285
+ environment variable, as [Knative](https://knative.dev/),
286
+ [Cloud Run](https://cloud.google.com/run), [Render](https://render.com/),
287
+ [Koyeb](https://www.koyeb.com/) or [Heroku](https://www.heroku.com/), the
288
+ web server of Pyjoyment listens on that port, and `generate dockerfile`
289
+ writes the `Dockerfile` of the image of an application, with the port that
290
+ the image exposes:
291
+
292
+ ```sh
293
+ ./myapp.py generate dockerfile --port 8080
294
+ ```
295
+
296
+ On [AWS Lambda](https://aws.amazon.com/lambda/), it is an event function,
297
+ whose handler `hello_world_lambda.handler` answers the events of API
298
+ Gateway, Function URLs and Application Load Balancers:
299
+
300
+ ```python
301
+ import Pyjo.HelloWorld
302
+ import Pyjo.Server.Lambda
303
+
304
+
305
+ # The handler "hello_world_lambda.handler" of an event function of AWS Lambda
306
+ handler = Pyjo.Server.Lambda.new(app=Pyjo.HelloWorld.new()).to_lambda_app()
307
+ ```
308
+
309
+ On a custom runtime, as `provided.al2023`, its `bootstrap` runs it with the
310
+ runtime client of Pyjoyment:
311
+
312
+ ```sh
313
+ #!/bin/sh
314
+ # The bootstrap of a custom runtime of AWS Lambda, as provided.al2023, which runs the handler of the function, as
315
+ # "hello_world_lambda.handler" of _HANDLER, with the runtime client of Pyjoyment
316
+ exec python3 -m Pyjo.Server.Lambda
317
+ ```
318
+
319
+ ## Distributions
320
+
321
+ Pyjoyment needs nothing besides the Python standard library, so what needs
322
+ another library is a distribution of its own, which adds a module to a
323
+ namespace of Pyjoyment, as `Pyjo.Reactor` for a reactor or `Pyjoyment.Plugin`
324
+ for a plugin. They are installed from their Git repositories until they are
325
+ on PyPI.
326
+
327
+ - [Pyjo.Reactor.Twisted - Low-level event reactor with Twisted support](https://pyjoyment.readthedocs.io/projects/pyjo-reactor-twisted/en/latest/)
328
+
329
+ ## Documentation
330
+
331
+ The documentation is on [Read the Docs](https://pyjoyment.readthedocs.io/).
332
+
333
+ ## Examples
334
+
335
+ ### Web scraping
336
+
337
+ ```python
338
+ import Pyjo.UserAgent
339
+
340
+ from Pyjo.String.Unicode import u
341
+
342
+
343
+ # Extract named character references from HTML spec
344
+ tx = Pyjo.UserAgent.new().get('https://html.spec.whatwg.org')
345
+ for n in tx.res.dom('#named-character-references-table tbody > tr').each():
346
+ u(n.at('td > code').text + ' ' + n.children('td')[1].text).trim().say()
347
+ ```
348
+
349
+ ### URL manipulation
350
+
351
+ ```python
352
+ import Pyjo.URL
353
+
354
+
355
+ # 'ssh+git://git@github.com/dex4er/Pyjoyment.git'
356
+ url = Pyjo.URL.new('https://github.com/dex4er/Pyjoyment')
357
+ print(url.set(scheme='ssh+git', userinfo='git', path=f'{url.path}.git').to_unsafe_str())
358
+
359
+ # 'https://pypi.org/search/?q=Pyjoyment&o=&c=Programming+Language+%3A%3A+Python'
360
+ url = Pyjo.URL.new('https://pypi.org/search/')
361
+ print(url.set(query=[('q', 'Pyjoyment'), ('o', ''), ('c', 'Programming Language :: Python')]))
362
+ ```
363
+
364
+ ## Copyright and license
365
+
366
+ Copyright (C) 2014-2026, Piotr Roszatycki.
367
+
368
+ Based on Mojolicious: Copyright (C) 2008-2025, Sebastian Riedel and others.
369
+
370
+ This program is free software, you can redistribute it and/or modify it under
371
+ the terms of the Artistic License version 2.0.
372
+
373
+ The pages of errors bundle [Bootstrap](https://getbootstrap.com), with
374
+ Popper, under the MIT License, and [highlight.js](https://highlightjs.org)
375
+ under the BSD 3-Clause License, whose texts are next to them in
376
+ `Pyjoyment/resources/public/pyjo`.
@@ -0,0 +1,200 @@
1
+ Pyjo/Base.py,sha256=5K0qW02MI-eHNxLGo7VbXPkFRl8_aAhS0dHBjOJjd0A,6747
2
+ Pyjo/Cache.py,sha256=6zQDDM0iytnKXg4vbAatyb3mMrL5C50ymKSB8qTwS_4,2664
3
+ Pyjo/Collection.py,sha256=grCmzjJSiHOb2kOMcpSK2OWNEDrv_UdpXtU8ehe-INg,18359
4
+ Pyjo/Date.py,sha256=T2Zof68CTGY2YX8Ppsr5mrbxiR8FwRKZo17RfkQDJII,9231
5
+ Pyjo/EventEmitter.py,sha256=8lM2XxVGP885ttxtwtnYSOS9PbFadAPrXQFpO-LdU0U,17168
6
+ Pyjo/Exception.py,sha256=Io6HLGUFgJNkJdosSDL8sYRsBbrSJJFamd76VJwnFqQ,15279
7
+ Pyjo/File.py,sha256=H9aXr-kKzSiGzJCm6oSN1tTfi_owmLfXoE1igvbn708,30144
8
+ Pyjo/GetOpt.py,sha256=4NUKkikKw9zNNigY__kOGruXXLVthUWWef6Xky9OPKU,22458
9
+ Pyjo/Headers.py,sha256=JUQKiJdYsZqjjKDnyJjmanaqW_7JGY9BCJ7ZLhAWXeE,24850
10
+ Pyjo/HelloWorld.py,sha256=V4GP1gVMYdMLpVQUPmZjX-DoMDXiwurxZK7auH38N1Q,2059
11
+ Pyjo/Home.py,sha256=gds0gRecwGujECWt-3aAfXOUF0WXqZzdbGAV0vXNl08,3306
12
+ Pyjo/Loader.py,sha256=xygJW6b4bu8D5o6e5iAXdCEtnx8bOYHXNyiYy7U3jdE,11092
13
+ Pyjo/Log.py,sha256=BOkQqoUTli2CdJpQkTXtfQVU9AorExWfDVvdxy4mYPk,22081
14
+ Pyjo/Parameters.py,sha256=dDLa5iJBn7uvntpPZIjNe9LS0OdP4SAthmGy_J4gEGE,15184
15
+ Pyjo/Path.py,sha256=ugy3RH2lQ5TNrYa-gjBrVlLq5PemTjW5dhnwvdLIpvg,11798
16
+ Pyjo/Promise.py,sha256=pV55sS9ReTcGCics-0notzdCuBNGFDQAekHHKfF7sqM,30934
17
+ Pyjo/Prove.py,sha256=QqlISWnV45iwthyvjGMy4r8wAYH4Izhgy0FRXKh5TU4,53934
18
+ Pyjo/SSE.py,sha256=iFSkqWNK75_M1AsAU_zd6V7D93VYLh2MzwfFFkAk1jw,3370
19
+ Pyjo/TOML.py,sha256=v82ptjwZSvUelt2FqVVrlxGSUz-1NMxUMrhhwRuUM_E,8730
20
+ Pyjo/Template.py,sha256=Ql0xNgalm0V6zNwxVAwVyt50bZkEKBlTLyCtXJpKfns,40684
21
+ Pyjo/Upload.py,sha256=n590rSIEgNQeNt47H_c5IJ32u-Ux83vBB95kRcxm7Lc,3037
22
+ Pyjo/Util.py,sha256=sdFM5Vo35O3yNAJeXlh2WEVx9SygwroQ5oB0_hbLpTI,95664
23
+ Pyjo/WebSocket.py,sha256=Yl2nBotfetaJLml4ScbFsYXf_tMYTa6TU3Zgrl2kF6M,8566
24
+ Pyjo/YAML.py,sha256=rB5Z7TlnlXkM24A7yPsiuaDjzxsIVSdnBPA8sLaEd2I,45431
25
+ Pyjo/__init__.py,sha256=LomUbNLmxGPSfFcSTHffNHX2QSIcEYUa5x-_UopH2M8,13646
26
+ Pyjo/__main__.py,sha256=xfFtx4gShmAoRkirSQuc6NT1wlLQ_IzUWi5D6TQKQsw,1018
27
+ Pyjo/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
+ Pyjo/App/ASGI.py,sha256=Bm2At_K1c4ni5Nspvw1cyKmZ39X3abCHNNME0CGBP0I,28431
29
+ Pyjo/App/CGI.py,sha256=M5KYvGiU16cCz_U1LJa4BdpM9x3OAbCz99Bdq2Mov1Q,31443
30
+ Pyjo/App/FastCGI.py,sha256=-S1_XXSUzxJKm0D4kEXkwrRr-1iFy__ObX2DdhE-MT0,25333
31
+ Pyjo/App/Lambda.py,sha256=sBpvcjP227EvCHUvW_wuQ2xogsmknfAegl5HOFvpzBk,38672
32
+ Pyjo/App/WSGI.py,sha256=WNFs1666AvPnfAJhR5q7Y1wubwuHbohEZC6_sbbbAkQ,15282
33
+ Pyjo/App/__init__.py,sha256=k_f-cw2xixflOmdNmp8ozZ0d8hZngZMq96KWIWRj9L0,14231
34
+ Pyjo/Asset/File.py,sha256=CeN9AbfYtETf5r4aGL0n-zhV0i63vO6jg7M0VE_UkAQ,10289
35
+ Pyjo/Asset/Memory.py,sha256=obeNv5oqYeV8hhQ_xSMdSM9NT0cLYP4naKgLAMmjzSk,6083
36
+ Pyjo/Asset/__init__.py,sha256=u4kp4jQ0-ES-XeraBQ1bN1N_Q35kRj1OdAn47-oMygc,5133
37
+ Pyjo/Content/MultiPart.py,sha256=_GNoDuqcaHsic8ZWQWZy86GN7Ioin6xjFtficSdHDdU,10111
38
+ Pyjo/Content/Single.py,sha256=u0-wVn3TlZ_xezfp8_5LpWCG7yYEAf37H_icg4enXV0,5629
39
+ Pyjo/Content/__init__.py,sha256=1UvVAUas6O3s4_rvbM48lGEJ_dkv3bsu6UoS6jLhDb0,24664
40
+ Pyjo/Cookie/Request.py,sha256=MR6yJUOwp5_PyBazH9yNnhQuxWZEhuiE19m9bnbWvLc,2339
41
+ Pyjo/Cookie/Response.py,sha256=PgCGPKfUYpFNMZCrZ8fl76oN63qog3mEgQg3WzBAoZs,8345
42
+ Pyjo/Cookie/__init__.py,sha256=znZNtPpLrKhsEG9RRlcK0j4Zv4aJGKsTe6e6S6h5hkY,3578
43
+ Pyjo/DOM/CSS.py,sha256=A26jC6Uam1a1fETF8OLJ9NEy--koi-brKnWpJwsWw2c,29298
44
+ Pyjo/DOM/HTML.py,sha256=3stiX6U35EE6grvgq_ffnzCkFH7gRQQtdvFYqc4LV9s,17731
45
+ Pyjo/DOM/__init__.py,sha256=gfekyvuytPEJIHQ4Y8IIQndOvAU76B9A3rG5DUcxmhw,41850
46
+ Pyjo/IOLoop/ChildProcess.py,sha256=XvQikJhtbcySThdNEerkn6fxn15NzPqGT5p0jxwKKKI,20707
47
+ Pyjo/IOLoop/Client.py,sha256=ZO2jlf86VbpWrMsAMz-jNdz3erI4BR5_d8buoMOW2cs,23441
48
+ Pyjo/IOLoop/Datagram.py,sha256=xPVD5cuZoAGqzgJRiCIY2UsOVcokCkZ8LghlN4fodSU,33155
49
+ Pyjo/IOLoop/Messages.py,sha256=vhIiCk220fKsgZ-qo-YEGvlltCVVfPLqWxs3c9cctOs,22862
50
+ Pyjo/IOLoop/Server.py,sha256=Pfc4Q3eVwIljUgznnZIGSYjuVTkyvoh9vt8Vf_t8di0,14028
51
+ Pyjo/IOLoop/Stdio.py,sha256=DGSnYzjh6pJ5Fyto-walQwEsK5CVHr_ZOs9uAausKpk,14926
52
+ Pyjo/IOLoop/Stream.py,sha256=BtnGw-Yhic0Mgya_6c6EyqWzwLqON4PsxbGlXDNYSMA,19813
53
+ Pyjo/IOLoop/Subprocess.py,sha256=1tclTeE_Mc1RrCfSvFrZvSFWLwJYKiFCr5WHcVHaZDM,12952
54
+ Pyjo/IOLoop/TLS.py,sha256=9TcGir6cea_SEKpZo6WtWzZImeSeSkiAonFEAUU5gOk,11387
55
+ Pyjo/IOLoop/__init__.py,sha256=_VaGAU-Sf3C-woSbrnVPfCoLcQE3PF3j_apuEaNtPts,34986
56
+ Pyjo/IOLoop/certs/README.md,sha256=zBUcv4f0bc99rCAowWEeGSfIGJz0iUnYFmzrZJ0zJuQ,1880
57
+ Pyjo/IOLoop/certs/ca.crt,sha256=CAYov3ZMWT4CiUqFR0ROJSZBSb_WuwmeHsxQ0_XxFLw,1212
58
+ Pyjo/IOLoop/certs/server.crt,sha256=zRK5GP4jquR4uYQ-tfgmt2ZalD_9tqrcLYXLTPYQW7k,1269
59
+ Pyjo/IOLoop/certs/server.key,sha256=LwGB8OyHjivuQYi2I67cRuAoWJZEF4vxgqTAGlHMFfw,1704
60
+ Pyjo/JSON/Pointer.py,sha256=Du191oGqlsJ-H9l1GXzqhg5dh0G2x3P8ObDf-KNJ7Vo,3834
61
+ Pyjo/JSON/RPC.py,sha256=Yz7NKoGYKGUGs_UIQTskbXecnTNwMcnWUj7FMRTKjyw,30113
62
+ Pyjo/JSON/Schema.py,sha256=X52F6RhorQH2QmDRd7q_6bEQk2zp9b6cfoyETavdr5Q,95862
63
+ Pyjo/JSON/__init__.py,sha256=mAx3dT1UuJGzeQ0JGMllzt8Lf3qR0pEB8Bhb8X_wamI,18241
64
+ Pyjo/Message/Request.py,sha256=D2H7Ho6fChQsUcdJyPNCLuysilRBlb-T1lW4DDL4Fvw,23823
65
+ Pyjo/Message/Response.py,sha256=D-tFIzopMlt9Zy9MelmfdFDYWC4Ng2_shpRIOuecft4,14369
66
+ Pyjo/Message/__init__.py,sha256=G0MgYzzzCo4zezRi9lLD9Vs7IsUSpoWBjp2D8OzMCS4,26754
67
+ Pyjo/Reactor/Asyncio.py,sha256=8_OhuqQMWfoxHpuzcJyKv_cxZz-BPdhujxW2Ma3rG4g,31716
68
+ Pyjo/Reactor/Poll.py,sha256=l-TvVxnV2QQKy7OztnTSy1fcmtXMjG-okIp_o5t4X6s,14345
69
+ Pyjo/Reactor/__init__.py,sha256=bodAs8sCAYgtoZIb-jXDgOFiWpG90MAatDRaDgOpF_E,18918
70
+ Pyjo/Server/ASGI.py,sha256=ZmZdpOuQLDsnvtPvvG12XdSP_uD7GJHF7nVNFJUg2So,17827
71
+ Pyjo/Server/CGI.py,sha256=VJU6fJN3ZEULXvzvPwNVW32RoxZbGLpoJzRJfMi3czA,7528
72
+ Pyjo/Server/Daemon.py,sha256=aka89VsgcLw04j-Ha6oMQX70weHRZDj34eewvJfXFvw,35459
73
+ Pyjo/Server/FastCGI.py,sha256=-mfxYZCsJG0MPrUr6bS9EUs72ro8ebkniNSJ-YRbDUU,17502
74
+ Pyjo/Server/Lambda.py,sha256=5wQ-xk3GNlSl7RtpyGPwTFKwf_JvPNt9Goh0clM4VnE,25248
75
+ Pyjo/Server/Prefork.py,sha256=4oicIgUOLFvoQO2Np8RYxclM8JjAvawDMLGSTPBW-t4,32143
76
+ Pyjo/Server/Prethread.py,sha256=A39MEx3bsim0Y3nMXG3sibg8bNnOB9EsbzPUyaESDdU,13950
77
+ Pyjo/Server/Stdio.py,sha256=ThD69to90oQoB0zsqPhErlNwSfWd6Y982QLjkxRDSqo,7045
78
+ Pyjo/Server/WSGI.py,sha256=xobpCynffQtjl4vFIrARKAx9OPEcdaWRJ6mXhK-CfVo,12300
79
+ Pyjo/Server/__init__.py,sha256=YKB5abwcJBCjlfJ65_Xa2NYvdhxVuGOuzHTwq3I99xU,12764
80
+ Pyjo/Server/Hot/__init__.py,sha256=gzCQIeS9lus1cPhjGwAXotkoDjgqkuyb8SVSTm_pixU,21650
81
+ Pyjo/Server/Hot/__main__.py,sha256=U4OePhSPvGdbGgANsqgQz1ug4fvjkUUGtYOq-tyXLDg,89
82
+ Pyjo/Server/Reload/__init__.py,sha256=7pkb9c4YpuCJTwl7o2mDrsesPGFOpqJ4C26kTTtUH-4,18527
83
+ Pyjo/Server/Reload/__main__.py,sha256=k4M3mMeUCZKO0_sHIV5d4kHcShi7n1htMmcYSscLqM0,101
84
+ Pyjo/Server/Reload/Backend/Poll.py,sha256=y-GMr4Z-3Ko1X6UyhEOqa56VsXQbwqAZV7fT8DmU3Yc,3599
85
+ Pyjo/Server/Reload/Backend/__init__.py,sha256=ZdJgdEJkQRmFkJ-MVx-wBGXqEcGESKKywtf42NC1rCE,3828
86
+ Pyjo/String/Bytes.py,sha256=_PIpWPxe69fPEO2dEbW1eLSd6RhUPv0h4gscw77SgRo,15110
87
+ Pyjo/String/HTML.py,sha256=Aobwy8pjYhBRNUV9zDvzWVTMCvzi-v3tqpn4ciWuf9Q,6013
88
+ Pyjo/String/Mixin.py,sha256=91wvEKkC07B6vX2aLXxpI1A3bPkHWXDAmUFW08jt-sY,9171
89
+ Pyjo/String/Template.py,sha256=4tWu9v_peb0NW0ktNytvcjC57ZyJnjRJ6ATKlIFCPa4,15626
90
+ Pyjo/String/Unicode.py,sha256=E1I0CdTBE2q4NXCNJPIL9VPxSrwH7w3Fvr6E4l1_L44,15889
91
+ Pyjo/String/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
92
+ Pyjo/Test/Pyjo.py,sha256=kYVCBz9BourmU9wjHF4dpy_rqOGhRHsi5oP5EixdCS8,54958
93
+ Pyjo/Test/__init__.py,sha256=o23a3inC8G_icm0Bd-QBljyRrhoCujf0FDwH5441BYo,35957
94
+ Pyjo/Test/pytest_plugin.py,sha256=PNIQvPelS_qPuRPjyPWq-85BoCFMZ2vl-XTY_iiranA,11415
95
+ Pyjo/Transaction/HTTP.py,sha256=CoIqF-hoPMXHtpTvi5BMrI-wMFwSmiX4pwAjXaF7tbA,10859
96
+ Pyjo/Transaction/WebSocket.py,sha256=-5o47XK12vwb507d1u-fXggKFe9B6o2_QSySE_tdNLU,21374
97
+ Pyjo/Transaction/__init__.py,sha256=6sO-N-4aIx9CKFghJvZ8nJGI2Zjt0_35CckNSpfjDTQ,12439
98
+ Pyjo/URL/Template.py,sha256=TV1bpt_WzqBg3qsHZK-Pkr8kd8lwrOR1nZ_w7OnqJLM,19465
99
+ Pyjo/URL/__init__.py,sha256=pS4BzxKBVqSMWzGOo0KGqqR0mJUvp71vfBr1QRNCumc,19156
100
+ Pyjo/UserAgent/CookieJar.py,sha256=Dq9bQDOcxWquf6NNaRa0HnoYBghUIj0TnlWB5Y_QSaU,11880
101
+ Pyjo/UserAgent/Proxy.py,sha256=FBoDUCSZax9aJjnfeOHXbCa7IgnTl_z5Jd6XUkcpyNE,3729
102
+ Pyjo/UserAgent/Server.py,sha256=hiE6Dp-J-tezGx_i82Q8FHrKcDhZ504y-_HNiYP8HjY,7482
103
+ Pyjo/UserAgent/Transactor.py,sha256=7HSTGftpzuyJcU2w9BucxCCPkF3YBT8XT-mG88yZQmk,27182
104
+ Pyjo/UserAgent/__init__.py,sha256=78LqZXJUAM7hKMI7M8SRckVX5jWIhT9pUm7YPsAKd4Q,45623
105
+ Pyjoyment/Commands.py,sha256=uxfD5fOrrGHYpkVVhCDFGKhSiT8I_TzoeUSDr0dlJ3Q,15420
106
+ Pyjoyment/Controller.py,sha256=sUZEL6VsZnr7tXvoYO-jsgwiwaJfDTHRPmZixPltW-M,47995
107
+ Pyjoyment/HelloWorld.py,sha256=MxIyz85zlBbLczzpsffn4jyOWHXHtEYBb_WkORVY508,1488
108
+ Pyjoyment/Lite.py,sha256=YaoCyXQW8bvUBESVcqZkQdnWOhEi406Mtjewb7V9Fb8,15716
109
+ Pyjoyment/Plugins.py,sha256=QLroWdYUz0PZ6ur8LmrflMwOQE_i9Pwfs7ufJun_sXg,6511
110
+ Pyjoyment/Renderer.py,sha256=CXL4OpKxuL_PHtjREqRVp7qN9vEjHH19sJHLTPW1DJI,24640
111
+ Pyjoyment/Sessions.py,sha256=ksgMT7xTK5nStg_dhoiN6Dmr8i3rE6GQ_514Kp3Axo4,7879
112
+ Pyjoyment/Static.py,sha256=4gvLsODJX9gbngRvFrhuuM2AqHPt9tboH3d8JnvEox8,13697
113
+ Pyjoyment/Types.py,sha256=Lzpaae_fQzi1nuX5yJH4jMaHIT3JcfpOeOzXZIaPIuk,7493
114
+ Pyjoyment/__init__.py,sha256=fD3dB64tToy8LvYvE0KH9Mcek71I6I4pC8I8tW7TZF0,38614
115
+ Pyjoyment/__main__.py,sha256=9sg5ARFpwWpiteC3wcXLotm5-gKs4pgVlX2h9UGHx_o,164
116
+ Pyjoyment/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
117
+ Pyjoyment/Command/__init__.py,sha256=LP12sylxEX6Pr-xqtFgSQQ9aSB_dZIvm1lB_EV7MIAI,9907
118
+ Pyjoyment/Command/asgi.py,sha256=5qoTWzX28jyEwP2U3TLmz0hQntfs1F9VRwnHpmBnn1U,2712
119
+ Pyjoyment/Command/cgi.py,sha256=vvPWeQYX3hZeNbnndxug7XvuAr7dQEL2zp0ZQaiHYq4,2505
120
+ Pyjoyment/Command/daemon.py,sha256=U1ckpozZY7NrCSy1LrsEB1xDdML4QeUUWbnX2ssUkOw,6468
121
+ Pyjoyment/Command/eval.py,sha256=Iem5ENsPmLdymfG1Bx_KWfrPJpw_tOzANRRj9Hu9g3M,4212
122
+ Pyjoyment/Command/fastcgi.py,sha256=fN4C82bdZo2eDioiAtzn1Vyz7JBQn6Mtq8YvugJdUG8,3235
123
+ Pyjoyment/Command/get.py,sha256=wTMT9N6LmQHKTK99Pd3TToaFH4QFr99PFj4az_F87SM,10818
124
+ Pyjoyment/Command/lambda.py,sha256=0GmuAWqMWQJ5W_vp0mjQ7JrS9h87FRw1jK7WpZ_SHUY,3988
125
+ Pyjoyment/Command/prefork.py,sha256=8-9zbNTxV8HQv4zhaq0QZYlrCrSMya_VZCpaAFlEKZ4,8272
126
+ Pyjoyment/Command/prethread.py,sha256=tU7N6JqPihNyTQOw9Wm5U19jKFt8z57GbPBYgSNEssw,5788
127
+ Pyjoyment/Command/routes.py,sha256=EH2Eaf_XxI-qRGtLLuzE8bguq_fCVVmEe2FeyDyTGGQ,3910
128
+ Pyjoyment/Command/stdio.py,sha256=Qj5SwSVzPV9Wn2fPAaVY8E8JwtkyTYMFVnjTHfCa7lY,2670
129
+ Pyjoyment/Command/version.py,sha256=VMXYH7zHVzvFNhpDryPt-mEcPXJijWOf-9Ylv4Jh5QM,4173
130
+ Pyjoyment/Command/wsgi.py,sha256=6XY0y7YJRJsGUsCYuy_ClW-Odfjj_U-HpNFZDBCl85A,2737
131
+ Pyjoyment/Command/Author/__init__.py,sha256=Uv_hR-EYB3Pz4MMgeVOeYuGS9X3ahUAdwpV6BU8qA6I,591
132
+ Pyjoyment/Command/Author/inflate.py,sha256=TQDw_nkN1XDT849UxUQQK0x9hEwKC-Hvi2FZnBUDr68,3167
133
+ Pyjoyment/Command/Author/generate/__init__.py,sha256=6_nqlAfvqQ8O3yEf6K6UJ2ieR_WlOx8nuDwVSjWPG-k,2919
134
+ Pyjoyment/Command/Author/generate/app.py,sha256=US5H66C0IGhklbBp9l_RtXoI7C6O9v-1WxJBYicW030,9759
135
+ Pyjoyment/Command/Author/generate/dockerfile.py,sha256=NwSxrsZtd2a5NYF6U3565k21CXC4QXOz_IIZ9W3CeIc,11348
136
+ Pyjoyment/Command/Author/generate/kubernetes.py,sha256=8CEr13XKiBHDXA-_MuhCyeXZeEOh1U1B6oJ8Oy_r-04,18968
137
+ Pyjoyment/Command/Author/generate/lambda_zip.py,sha256=qeUppZ8uiXJMfed6ECHFfu4tKVuRvAeJC4ltu-BzxeU,18614
138
+ Pyjoyment/Command/Author/generate/lite_app.py,sha256=ucVT1_DSLvpEJGzLJeqkOh4B6aZuyfsoDRd27LXOod0,2688
139
+ Pyjoyment/Command/Author/generate/plugin.py,sha256=MLFrrSBrqUcSqatuuJthFYnbe44EXfrUT8yz2Ud--vQ,7343
140
+ Pyjoyment/Command/Author/generate/pyproject.py,sha256=fpbwAWdjUXxFbU8DazhyBmZwgtKEISlMzrevbZcEQKA,3773
141
+ Pyjoyment/Plugin/AllowedHosts.py,sha256=LV6H-7dSFbjnFlhVUFbXgeqcqYvvnHwGYZahNMYzZKE,7698
142
+ Pyjoyment/Plugin/Config.py,sha256=vsNcUP5nZFMwwvzTua5jZAjCuRqeZAlnqm-a0GldwAk,7832
143
+ Pyjoyment/Plugin/DefaultHelpers.py,sha256=Q5KOcFXp5IU7Yu0zmP70rlXXTOM5E3CcqRRUIfqx9zs,35655
144
+ Pyjoyment/Plugin/EPLRenderer.py,sha256=CkkeS8EEqeWbV2U4uhHLP6G_6L-lssxJjpcK2Tdm8Tc,3763
145
+ Pyjoyment/Plugin/EPRenderer.py,sha256=8wc2Uo5hKxm2N4L4ASo1Lok6g0RHfdzeWraSCl6VFto,7565
146
+ Pyjoyment/Plugin/HeaderCondition.py,sha256=zfFbCcgjiRGXylxnHHjP77L4P1bzrMxrjrByK-oHH0c,3136
147
+ Pyjoyment/Plugin/Health.py,sha256=W0B8_R6xjGs9t36oah3-4s7YL129Y0MwSS8RkLuwVmM,11582
148
+ Pyjoyment/Plugin/JSONConfig.py,sha256=Bsvr1W7Ll50kp_tM7mTHRRp0fxjgUl8W7Yo8ElxMsw0,5286
149
+ Pyjoyment/Plugin/Mount.py,sha256=P5_b_Hp2zjr3V0C-4QxWIGeCWZ7L_Nbz0MYmm-QRsoQ,9068
150
+ Pyjoyment/Plugin/PyRenderer.py,sha256=I_99tYeynNJ0lWSAGI-unIF4slakFUGBNLhJvtc20WA,7351
151
+ Pyjoyment/Plugin/TOMLConfig.py,sha256=-9lZRdupX-Fgwl10Ltkc-cZ8YArFIiotfRSmzxGx9MA,4239
152
+ Pyjoyment/Plugin/TagHelpers.py,sha256=taYAaj4iCz3qH9RARcKJSD-Gus7DmGm6wIfG6ORByCc,32264
153
+ Pyjoyment/Plugin/YAMLConfig.py,sha256=O-eVNqyzrhwpbOcd72vni-DlGlJgVBktr4W_UC9TcOo,5762
154
+ Pyjoyment/Plugin/__init__.py,sha256=lpytEdgldYfJdGqS87M6KkEGvYaBNGR22FqURz9JGbg,2100
155
+ Pyjoyment/Routes/Match.py,sha256=d29nCaoYW6ecOwFBxZsRQp5sONgnKtVG2xym3dN4OdY,7522
156
+ Pyjoyment/Routes/Pattern.py,sha256=X5fEoiQjrNxhDfrDk35O2wwKsYmD1sD6_dP-9KgCV9U,13379
157
+ Pyjoyment/Routes/Route.py,sha256=AhzKVRpvg7jwViT8fEXLKYJpViBo7p8Lh6ic62-c5ig,29536
158
+ Pyjoyment/Routes/__init__.py,sha256=tUUzNo5nduGWDDP-bl6rg7yRGWOuouEQOXttvwYsjx0,13377
159
+ Pyjoyment/Validator/Validation.py,sha256=i6Kp0T70L6OUpb6N6qbLX7MJjUHrG9ucYP0AQYc67Dc,11990
160
+ Pyjoyment/Validator/__init__.py,sha256=v6fE8Ras_igH8xgB6Vooc2xC4apU7h5styZvpy5DVUc,8287
161
+ Pyjoyment/resources/public/favicon.ico,sha256=S9KhYole3gKj6_jAmIPkM3GukOMZVmaywLBr44yiLJQ,4620
162
+ Pyjoyment/resources/public/favicon.svg,sha256=DqVmX9fu9SpAwODaniAmxL0nTk5jeMarhX2bznKvvbA,36169
163
+ Pyjoyment/resources/public/pyjo/failunicat.png,sha256=fW_2SmICVvocXXiWtJIm_vSd2OdyZgK2fVWgEykoHoY,63469
164
+ Pyjoyment/resources/public/pyjo/failunicat.svg,sha256=K5HOtmgLnImFdDAa_ndL-US7tvkGWUQoxJrwLazC08k,33658
165
+ Pyjoyment/resources/public/pyjo/logo-black-4x.png,sha256=RpL4qKDc5gxZIda8TCjYQAGpAFX8GvHAc6HuKETHajY,23589
166
+ Pyjoyment/resources/public/pyjo/logo-black-4x.svg,sha256=Qc7XWp6APmFz7BwJ_5IVwR7s2yF0zTBosQubNWM71Bo,43444
167
+ Pyjoyment/resources/public/pyjo/logo-white-2x.png,sha256=SxZCiB2Jdl0nY2UFL-BzjlkhuMtPmfrsSTZW1d5gc6s,9505
168
+ Pyjoyment/resources/public/pyjo/logo-white-2x.svg,sha256=q21tj64eSxEgr22OC_eYeNU2CWjydiC8Lu6ARRP3JRk,43443
169
+ Pyjoyment/resources/public/pyjo/logo-white-4x.png,sha256=IIvQFSLPECwKSv1tJzQYJstx4lTdsbOshl-ylqtHcTo,20943
170
+ Pyjoyment/resources/public/pyjo/logo-white-4x.svg,sha256=jUmeiF7zHciSzYmLMyEWlcgmVtHjwpbrb5MTMnJ9wt8,43444
171
+ Pyjoyment/resources/public/pyjo/logo-white.png,sha256=L4rti0XUAOG07KelLUEhPgL-8CouZaahDozurgzsS2s,3925
172
+ Pyjoyment/resources/public/pyjo/logo-white.svg,sha256=JUnw7LOjAKDTQj8MDrf1uLbMJluFF91F5Q_Ylyq6dV8,43229
173
+ Pyjoyment/resources/public/pyjo/logo.png,sha256=XdWsXDbF1FRgcqUSw6vHU7bKZ27Midr8xu3it-Y_rTY,22891
174
+ Pyjoyment/resources/public/pyjo/logo.svg,sha256=1aMPQYJpiSPPx3YKg8vJzi2GazR4_KndyAbtyBcaRGs,43852
175
+ Pyjoyment/resources/public/pyjo/notfound.png,sha256=B0GMF_aPa9_ERS_ydfALf09yrFQoYgqnmMD99QCdElU,5716
176
+ Pyjoyment/resources/public/pyjo/notfound.svg,sha256=jsrOfjszPwKpAECNFjLJLI-eL8sbRGbT2_kyHTMJ7no,12227
177
+ Pyjoyment/resources/public/pyjo/nounicat.png,sha256=2rk5tqItIXfG2kiCIAaziiqUs1m-a0crhPnLrPKHgyI,7515
178
+ Pyjoyment/resources/public/pyjo/nounicat.svg,sha256=_I4gdF4qzWRI8j9jZUR5kmb4BdT6TmJlryV22jpoefw,872
179
+ Pyjoyment/resources/public/pyjo/pinstripe-dark.png,sha256=Ux0RkptGGGiUoQaVGhvM2MyBmwskmjWkbzAT10VL-Gk,135
180
+ Pyjoyment/resources/public/pyjo/pinstripe-dark.svg,sha256=ylgLJbBaSoIKthhjyUKTfT91EXVpsVO_ynGh0_g78ZI,507
181
+ Pyjoyment/resources/public/pyjo/pinstripe-light.png,sha256=L1Ybd_KGbeVqW0Bjd_PG6Od6xB4Hfsq-hdaVZUzU0tg,211
182
+ Pyjoyment/resources/public/pyjo/pinstripe-light.svg,sha256=nUfAFHn8AJzHvOSKaU2sWOXR40dJFKCPw1mlSS3VIKY,821
183
+ Pyjoyment/resources/public/pyjo/pyjo.css,sha256=uEPCOPnVPa4q8qAKPIy0nX3kOO2_WgFNJ-aRjhaKKJw,3834
184
+ Pyjoyment/resources/public/pyjo/bootstrap/LICENSE,sha256=RiDIStXOhgL_ZWQO1rfIt467ngNlhPDrwczIggaku1E,1093
185
+ Pyjoyment/resources/public/pyjo/bootstrap/bootstrap.bundle.min.js.map,sha256=xhEj5YzApLZdc3ugcMSFkRs9vsbXuAK99mKDlavZwIs,332111
186
+ Pyjoyment/resources/public/pyjo/bootstrap/bootstrap.css,sha256=2FMn2Zx6PuH5tdBQDRNwrOo60ts5wWPC9R8jK67b3t4,232111
187
+ Pyjoyment/resources/public/pyjo/bootstrap/bootstrap.js,sha256=5P1JGBOIxI7FBAvT_mb1fCnI5n_NhQKzNUuW7Hq0fMc,80496
188
+ Pyjoyment/resources/public/pyjo/bootstrap/bootstrap.min.css.map,sha256=SBRPr2qg-zzSznSNlzAjj4iPSrcV8F2r0cmvLFZxmIo,590038
189
+ Pyjoyment/resources/public/pyjo/highlight.js/LICENSE,sha256=bAgUMVkdnfaWyC3FmP4UI3ZbiimbIA7QCyga_Q9kxJA,1514
190
+ Pyjoyment/resources/public/pyjo/highlight.js/highlight-mojo-dark.css,sha256=9nicJ3hxsfHZdikrVYoJht0_KdHQYVHH1uCPYiylLHI,689
191
+ Pyjoyment/resources/public/pyjo/highlight.js/highlight.min.js,sha256=ircesJxR9QHl4lFX2c_xAORswpvL_HRNC3RtRR_Kf1M,129254
192
+ Pyjoyment/resources/public/pyjo/highlight.js/pyjoyment.min.js,sha256=ADgk5O0gbYvR927DAGjYVeW70Yl7dLBU2t76EgNbkJU,327
193
+ Pyjoyment/resources/templates/pyjo/debug.html.ep,sha256=3rX7XnceSIDz-LZ-Eyo0oLdbBfKvZuX2JOHPDLebDNg,17416
194
+ Pyjoyment/resources/templates/pyjo/exception.html.ep,sha256=OQMLIarv_czcqXiDSv1PdrPmUNAINugiK0E_IyxVKBA,1087
195
+ Pyjoyment/resources/templates/pyjo/not_found.html.ep,sha256=5gWNjcP5RGxdn17IT-KGkEKVIYC4aqZm7PtgrSQVLAk,1337
196
+ pyjoyment-0.1.0.dist-info/METADATA,sha256=1RVOnFqO1Qa2Yc8M2MIU6M3GqhOcz-qfadyVPpFZ26Q,14250
197
+ pyjoyment-0.1.0.dist-info/WHEEL,sha256=2iZrJkDIkeDh0k9SikKMqFuRP-ua6mb4Ir1AsER4BEw,87
198
+ pyjoyment-0.1.0.dist-info/entry_points.txt,sha256=xncwiK-yeybuXiMSTX7Ft_j2AT0YIULUAy-DVMYIx70,191
199
+ pyjoyment-0.1.0.dist-info/licenses/LICENSE,sha256=GeLg8geeoc4VdutOzAV1sz_kWyuOcfSqWJ1r7dHaTgo,8971
200
+ pyjoyment-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.33.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,8 @@
1
+ [console_scripts]
2
+ pyjo = Pyjoyment.Commands:main
3
+ pyjo-hot = Pyjo.Server.Hot:main
4
+ pyjo-prove = Pyjo.Prove:main
5
+ pyjo-reload = Pyjo.Server.Reload:main
6
+
7
+ [pytest11]
8
+ pyjo = Pyjo.Test.pytest_plugin