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,239 @@
1
+ """
2
+ Pyjo.UserAgent.Server - Application server
3
+ ==========================================
4
+ ::
5
+
6
+ from Pyjo.UserAgent.Server import Server
7
+
8
+ server = Server()
9
+ print(server.url())
10
+
11
+ # Or import the module, as in Google Python Style Guide
12
+
13
+ import Pyjo.UserAgent.Server
14
+
15
+ server = Pyjo.UserAgent.Server.new()
16
+ print(server.url())
17
+
18
+ :mod:`Pyjo.UserAgent.Server` is an embedded web server based on
19
+ :mod:`Pyjo.Server.Daemon` that processes requests for :mod:`Pyjo.UserAgent`.
20
+
21
+ The end of a ``with`` block closes its servers.
22
+
23
+ See also
24
+ --------
25
+
26
+ :mod:`Pyjoyment`, https://mojolicious.org.
27
+
28
+ Ported from `Mojo::UserAgent::Server <https://github.com/mojolicious/mojo/blob/v9.49/lib/Mojo/UserAgent/Server.pm>`_
29
+ of Mojolicious 9.49.
30
+
31
+ Classes
32
+ -------
33
+ """
34
+
35
+ import Pyjo.Base
36
+ import Pyjo.IOLoop
37
+ import Pyjo.Reactor
38
+ import Pyjo.Server
39
+ import Pyjo.Server.Daemon
40
+ import Pyjo.URL
41
+
42
+ import sys
43
+ import weakref
44
+
45
+ from types import TracebackType
46
+ from typing import Any, Self, cast
47
+
48
+
49
+ # The application of all servers that have none of their own
50
+ _singleton: Pyjo.Server.Application | None = None
51
+
52
+
53
+ class Pyjo_UserAgent_Server(Pyjo.Base.object):
54
+ """
55
+ :mod:`Pyjo.UserAgent.Server` inherits all methods from :mod:`Pyjo.Base`
56
+ and implements the following new ones.
57
+ """
58
+
59
+ def __init__(self, *, app: Pyjo.Server.Application | None = None, ioloop: Pyjo.IOLoop.object | None = None) -> None:
60
+ """::
61
+
62
+ server = Pyjo.UserAgent.Server.new()
63
+ server = Pyjo.UserAgent.Server.new(ioloop=Pyjo.IOLoop.new())
64
+
65
+ Construct a new :mod:`Pyjo.UserAgent.Server` object.
66
+ """
67
+ self._app = app
68
+
69
+ self.ioloop: Pyjo.IOLoop.object = ioloop if ioloop is not None else Pyjo.IOLoop.object.singleton()
70
+ """::
71
+
72
+ loop = server.ioloop
73
+ server.ioloop = Pyjo.IOLoop.new()
74
+
75
+ Event loop object to use for I/O operations, defaults to the global
76
+ :mod:`Pyjo.IOLoop` singleton.
77
+ """
78
+
79
+ self._proto = 'http'
80
+ self._port: int | None = None
81
+ self._nb_port: int | None = None
82
+ self._server: Pyjo.Server.Daemon.object | None = None
83
+ self._nb_server: Pyjo.Server.Daemon.object | None = None
84
+ self._previous: set[int] = set()
85
+
86
+ def __del__(self) -> None:
87
+ try:
88
+ if sys.is_finalizing():
89
+ return
90
+ Pyjo.Reactor._finalize(self.restart) # pyright: ignore[reportPrivateUsage]
91
+ except Exception:
92
+ pass
93
+
94
+ # Not in Mojolicious: a context manager, which closes its servers where the block ends, as PyPy frees the object
95
+ # only when its garbage collector runs
96
+ def __enter__(self) -> Self:
97
+ return self
98
+
99
+ def __exit__(
100
+ self, type: type[BaseException] | None, value: BaseException | None, traceback: TracebackType | None
101
+ ) -> None:
102
+ self.close()
103
+
104
+ @property
105
+ def app(self) -> Pyjo.Server.Application | None:
106
+ """::
107
+
108
+ app = server.app
109
+ server.app = Pyjoyment.new()
110
+
111
+ Application this server handles, instance specific applications
112
+ override the global default, which :func:`app` of the module gives.
113
+ """
114
+ return self._app or _singleton
115
+
116
+ @app.setter
117
+ def app(self, value: Pyjo.Server.Application) -> None:
118
+ self._app = value
119
+
120
+ # Not in Mojolicious: the release of the servers, which Perl does in DESTROY, also at the end of a with block
121
+ def close(self) -> None:
122
+ """::
123
+
124
+ server.close()
125
+
126
+ Close the servers, as the end of a ``with`` block does, which start
127
+ again on new ports when they are used again.
128
+ """
129
+ self.restart()
130
+
131
+ def nb_url(self, proto: str | None = None) -> Pyjo.URL.object:
132
+ """::
133
+
134
+ url = server.nb_url()
135
+ url = server.nb_url('http')
136
+ url = server.nb_url('https')
137
+
138
+ Get absolute :mod:`Pyjo.URL` object for server processing non-blocking
139
+ requests with :attr:`app` and switch protocol if necessary.
140
+ """
141
+ return self._url(True, proto)
142
+
143
+ def restart(self) -> None:
144
+ """::
145
+
146
+ server.restart()
147
+
148
+ Restart server with new port.
149
+ """
150
+ self._previous = {port for port in (self._port, self._nb_port) if port is not None}
151
+ self._nb_port = self._port = None
152
+ self._close()
153
+
154
+ def _close(self) -> None:
155
+ _close_servers(self._server, self._nb_server)
156
+ self._nb_server = self._server = None
157
+
158
+ # Unlike Mojolicious: a server on a new port gets another one than before the restart, as the system may give the
159
+ # port that the restart freed again, and Mojo takes what it gives
160
+ def _listen(self, proto: str, port: int | None, ioloop: Pyjo.IOLoop.object | None) -> Pyjo.Server.Daemon.object:
161
+ while True:
162
+ server = (
163
+ Pyjo.Server.Daemon.new(silent=True)
164
+ if ioloop is None
165
+ else Pyjo.Server.Daemon.new(ioloop=ioloop, silent=True)
166
+ )
167
+ if (app := self.app) is not None:
168
+ server.app = _weak(app)
169
+ server.listen = [f'{proto}://127.0.0.1' + (f':{port}' if port else '')]
170
+ server.start()
171
+ if port or server.ports()[0] not in self._previous:
172
+ return server
173
+ _close_servers(server)
174
+
175
+ def url(self, proto: str | None = None) -> Pyjo.URL.object:
176
+ """::
177
+
178
+ url = server.url()
179
+ url = server.url('http')
180
+ url = server.url('https')
181
+
182
+ Get absolute :mod:`Pyjo.URL` object for server processing blocking
183
+ requests with :attr:`app` and switch protocol if necessary.
184
+ """
185
+ return self._url(False, proto)
186
+
187
+ def _url(self, nb: bool, proto: str | None) -> Pyjo.URL.object:
188
+ if self._server is None or proto:
189
+ proto = self._proto = proto or 'http'
190
+ self._close()
191
+
192
+ # Blocking
193
+ server = self._server = self._listen(proto, self._port, self.ioloop)
194
+ self._port = server.ports()[0]
195
+
196
+ # Non-blocking
197
+ server = self._nb_server = self._listen(proto, self._nb_port, None)
198
+ self._nb_port = server.ports()[0]
199
+
200
+ port = self._nb_port if nb else self._port
201
+ return Pyjo.URL.new(f'{self._proto}://127.0.0.1:{port}/')
202
+
203
+
204
+ # Not in Mojolicious: the servers are closed where they are dropped, as Perl closes them when it frees them, and PyPy frees
205
+ # them only when its garbage collector runs, after a new server has taken over the port
206
+ def _close_servers(*servers: Pyjo.Server.Daemon.object | None) -> None:
207
+ for server in servers:
208
+ if server is not None:
209
+ server.__exit__(None, None, None)
210
+
211
+
212
+ def app(value: Pyjo.Server.Application | None = None) -> Pyjo.Server.Application | None:
213
+ """::
214
+
215
+ app = Pyjo.UserAgent.Server.app()
216
+ Pyjo.UserAgent.Server.app(Pyjoyment.new())
217
+
218
+ The global default application of the servers, as Mojo calls ``app`` on
219
+ the class. ::
220
+
221
+ # Change application behavior
222
+ Pyjo.UserAgent.Server.app().log.level = 'fatal'
223
+ """
224
+ global _singleton
225
+ if value is not None:
226
+ _singleton = value
227
+ return _singleton
228
+
229
+
230
+ # A server refers to the application weakly, as Mojo weakens it
231
+ def _weak(app: Any) -> Any:
232
+ if isinstance(app, weakref.ProxyType):
233
+ return cast(Any, app)
234
+ return cast(Any, weakref.proxy(app))
235
+
236
+
237
+ new = Pyjo_UserAgent_Server.new
238
+ object = Pyjo_UserAgent_Server
239
+ Server = Pyjo_UserAgent_Server