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.
- Pyjo/App/ASGI.py +735 -0
- Pyjo/App/CGI.py +773 -0
- Pyjo/App/FastCGI.py +631 -0
- Pyjo/App/Lambda.py +987 -0
- Pyjo/App/WSGI.py +427 -0
- Pyjo/App/__init__.py +409 -0
- Pyjo/Asset/File.py +377 -0
- Pyjo/Asset/Memory.py +235 -0
- Pyjo/Asset/__init__.py +200 -0
- Pyjo/Base.py +215 -0
- Pyjo/Cache.py +119 -0
- Pyjo/Collection.py +570 -0
- Pyjo/Content/MultiPart.py +325 -0
- Pyjo/Content/Single.py +193 -0
- Pyjo/Content/__init__.py +806 -0
- Pyjo/Cookie/Request.py +90 -0
- Pyjo/Cookie/Response.py +294 -0
- Pyjo/Cookie/__init__.py +143 -0
- Pyjo/DOM/CSS.py +1019 -0
- Pyjo/DOM/HTML.py +550 -0
- Pyjo/DOM/__init__.py +1329 -0
- Pyjo/Date.py +294 -0
- Pyjo/EventEmitter.py +522 -0
- Pyjo/Exception.py +494 -0
- Pyjo/File.py +959 -0
- Pyjo/GetOpt.py +605 -0
- Pyjo/Headers.py +760 -0
- Pyjo/HelloWorld.py +77 -0
- Pyjo/Home.py +109 -0
- Pyjo/IOLoop/ChildProcess.py +591 -0
- Pyjo/IOLoop/Client.py +736 -0
- Pyjo/IOLoop/Datagram.py +982 -0
- Pyjo/IOLoop/Messages.py +664 -0
- Pyjo/IOLoop/Server.py +458 -0
- Pyjo/IOLoop/Stdio.py +446 -0
- Pyjo/IOLoop/Stream.py +644 -0
- Pyjo/IOLoop/Subprocess.py +419 -0
- Pyjo/IOLoop/TLS.py +360 -0
- Pyjo/IOLoop/__init__.py +1036 -0
- Pyjo/IOLoop/certs/README.md +41 -0
- Pyjo/IOLoop/certs/ca.crt +20 -0
- Pyjo/IOLoop/certs/server.crt +21 -0
- Pyjo/IOLoop/certs/server.key +28 -0
- Pyjo/JSON/Pointer.py +135 -0
- Pyjo/JSON/RPC.py +772 -0
- Pyjo/JSON/Schema.py +2506 -0
- Pyjo/JSON/__init__.py +573 -0
- Pyjo/Loader.py +342 -0
- Pyjo/Log.py +723 -0
- Pyjo/Message/Request.py +725 -0
- Pyjo/Message/Response.py +476 -0
- Pyjo/Message/__init__.py +830 -0
- Pyjo/Parameters.py +472 -0
- Pyjo/Path.py +419 -0
- Pyjo/Promise.py +894 -0
- Pyjo/Prove.py +1305 -0
- Pyjo/Reactor/Asyncio.py +854 -0
- Pyjo/Reactor/Poll.py +439 -0
- Pyjo/Reactor/__init__.py +525 -0
- Pyjo/SSE.py +119 -0
- Pyjo/Server/ASGI.py +486 -0
- Pyjo/Server/CGI.py +259 -0
- Pyjo/Server/Daemon.py +1007 -0
- Pyjo/Server/FastCGI.py +517 -0
- Pyjo/Server/Hot/__init__.py +687 -0
- Pyjo/Server/Hot/__main__.py +5 -0
- Pyjo/Server/Lambda.py +641 -0
- Pyjo/Server/Prefork.py +917 -0
- Pyjo/Server/Prethread.py +394 -0
- Pyjo/Server/Reload/Backend/Poll.py +114 -0
- Pyjo/Server/Reload/Backend/__init__.py +126 -0
- Pyjo/Server/Reload/__init__.py +482 -0
- Pyjo/Server/Reload/__main__.py +5 -0
- Pyjo/Server/Stdio.py +228 -0
- Pyjo/Server/WSGI.py +349 -0
- Pyjo/Server/__init__.py +396 -0
- Pyjo/String/Bytes.py +532 -0
- Pyjo/String/HTML.py +210 -0
- Pyjo/String/Mixin.py +333 -0
- Pyjo/String/Template.py +470 -0
- Pyjo/String/Unicode.py +553 -0
- Pyjo/String/__init__.py +0 -0
- Pyjo/TOML.py +232 -0
- Pyjo/Template.py +1290 -0
- Pyjo/Test/Pyjo.py +1454 -0
- Pyjo/Test/__init__.py +1233 -0
- Pyjo/Test/pytest_plugin.py +305 -0
- Pyjo/Transaction/HTTP.py +374 -0
- Pyjo/Transaction/WebSocket.py +709 -0
- Pyjo/Transaction/__init__.py +429 -0
- Pyjo/URL/Template.py +459 -0
- Pyjo/URL/__init__.py +651 -0
- Pyjo/Upload.py +139 -0
- Pyjo/UserAgent/CookieJar.py +391 -0
- Pyjo/UserAgent/Proxy.py +138 -0
- Pyjo/UserAgent/Server.py +239 -0
- Pyjo/UserAgent/Transactor.py +766 -0
- Pyjo/UserAgent/__init__.py +1243 -0
- Pyjo/Util.py +3567 -0
- Pyjo/WebSocket.py +332 -0
- Pyjo/YAML.py +1167 -0
- Pyjo/__init__.py +441 -0
- Pyjo/__main__.py +35 -0
- Pyjo/py.typed +0 -0
- Pyjoyment/Command/Author/__init__.py +20 -0
- Pyjoyment/Command/Author/generate/__init__.py +106 -0
- Pyjoyment/Command/Author/generate/app.py +299 -0
- Pyjoyment/Command/Author/generate/dockerfile.py +281 -0
- Pyjoyment/Command/Author/generate/kubernetes.py +514 -0
- Pyjoyment/Command/Author/generate/lambda_zip.py +372 -0
- Pyjoyment/Command/Author/generate/lite_app.py +113 -0
- Pyjoyment/Command/Author/generate/plugin.py +267 -0
- Pyjoyment/Command/Author/generate/pyproject.py +123 -0
- Pyjoyment/Command/Author/inflate.py +101 -0
- Pyjoyment/Command/__init__.py +332 -0
- Pyjoyment/Command/asgi.py +92 -0
- Pyjoyment/Command/cgi.py +90 -0
- Pyjoyment/Command/daemon.py +160 -0
- Pyjoyment/Command/eval.py +128 -0
- Pyjoyment/Command/fastcgi.py +99 -0
- Pyjoyment/Command/get.py +305 -0
- Pyjoyment/Command/lambda.py +117 -0
- Pyjoyment/Command/prefork.py +181 -0
- Pyjoyment/Command/prethread.py +126 -0
- Pyjoyment/Command/routes.py +133 -0
- Pyjoyment/Command/stdio.py +92 -0
- Pyjoyment/Command/version.py +141 -0
- Pyjoyment/Command/wsgi.py +93 -0
- Pyjoyment/Commands.py +546 -0
- Pyjoyment/Controller.py +1307 -0
- Pyjoyment/HelloWorld.py +56 -0
- Pyjoyment/Lite.py +494 -0
- Pyjoyment/Plugin/AllowedHosts.py +205 -0
- Pyjoyment/Plugin/Config.py +248 -0
- Pyjoyment/Plugin/DefaultHelpers.py +1202 -0
- Pyjoyment/Plugin/EPLRenderer.py +134 -0
- Pyjoyment/Plugin/EPRenderer.py +212 -0
- Pyjoyment/Plugin/HeaderCondition.py +98 -0
- Pyjoyment/Plugin/Health.py +325 -0
- Pyjoyment/Plugin/JSONConfig.py +172 -0
- Pyjoyment/Plugin/Mount.py +223 -0
- Pyjoyment/Plugin/PyRenderer.py +209 -0
- Pyjoyment/Plugin/TOMLConfig.py +141 -0
- Pyjoyment/Plugin/TagHelpers.py +959 -0
- Pyjoyment/Plugin/YAMLConfig.py +178 -0
- Pyjoyment/Plugin/__init__.py +80 -0
- Pyjoyment/Plugins.py +215 -0
- Pyjoyment/Renderer.py +673 -0
- Pyjoyment/Routes/Match.py +251 -0
- Pyjoyment/Routes/Pattern.py +443 -0
- Pyjoyment/Routes/Route.py +827 -0
- Pyjoyment/Routes/__init__.py +419 -0
- Pyjoyment/Sessions.py +255 -0
- Pyjoyment/Static.py +421 -0
- Pyjoyment/Types.py +238 -0
- Pyjoyment/Validator/Validation.py +395 -0
- Pyjoyment/Validator/__init__.py +304 -0
- Pyjoyment/__init__.py +1083 -0
- Pyjoyment/__main__.py +5 -0
- Pyjoyment/py.typed +0 -0
- Pyjoyment/resources/public/favicon.ico +0 -0
- Pyjoyment/resources/public/favicon.svg +345 -0
- Pyjoyment/resources/public/pyjo/bootstrap/LICENSE +21 -0
- Pyjoyment/resources/public/pyjo/bootstrap/bootstrap.bundle.min.js.map +1 -0
- Pyjoyment/resources/public/pyjo/bootstrap/bootstrap.css +6 -0
- Pyjoyment/resources/public/pyjo/bootstrap/bootstrap.js +7 -0
- Pyjoyment/resources/public/pyjo/bootstrap/bootstrap.min.css.map +1 -0
- Pyjoyment/resources/public/pyjo/failunicat.png +0 -0
- Pyjoyment/resources/public/pyjo/failunicat.svg +50 -0
- Pyjoyment/resources/public/pyjo/highlight.js/LICENSE +29 -0
- Pyjoyment/resources/public/pyjo/highlight.js/highlight-mojo-dark.css +56 -0
- Pyjoyment/resources/public/pyjo/highlight.js/highlight.min.js +1262 -0
- Pyjoyment/resources/public/pyjo/highlight.js/pyjoyment.min.js +1 -0
- Pyjoyment/resources/public/pyjo/logo-black-4x.png +0 -0
- Pyjoyment/resources/public/pyjo/logo-black-4x.svg +346 -0
- Pyjoyment/resources/public/pyjo/logo-white-2x.png +0 -0
- Pyjoyment/resources/public/pyjo/logo-white-2x.svg +346 -0
- Pyjoyment/resources/public/pyjo/logo-white-4x.png +0 -0
- Pyjoyment/resources/public/pyjo/logo-white-4x.svg +346 -0
- Pyjoyment/resources/public/pyjo/logo-white.png +0 -0
- Pyjoyment/resources/public/pyjo/logo-white.svg +346 -0
- Pyjoyment/resources/public/pyjo/logo.png +0 -0
- Pyjoyment/resources/public/pyjo/logo.svg +346 -0
- Pyjoyment/resources/public/pyjo/notfound.png +0 -0
- Pyjoyment/resources/public/pyjo/notfound.svg +3 -0
- Pyjoyment/resources/public/pyjo/nounicat.png +0 -0
- Pyjoyment/resources/public/pyjo/nounicat.svg +5 -0
- Pyjoyment/resources/public/pyjo/pinstripe-dark.png +0 -0
- Pyjoyment/resources/public/pyjo/pinstripe-dark.svg +4 -0
- Pyjoyment/resources/public/pyjo/pinstripe-light.png +0 -0
- Pyjoyment/resources/public/pyjo/pinstripe-light.svg +4 -0
- Pyjoyment/resources/public/pyjo/pyjo.css +204 -0
- Pyjoyment/resources/templates/pyjo/debug.html.ep +346 -0
- Pyjoyment/resources/templates/pyjo/exception.html.ep +32 -0
- Pyjoyment/resources/templates/pyjo/not_found.html.ep +45 -0
- pyjoyment-0.1.0.dist-info/METADATA +376 -0
- pyjoyment-0.1.0.dist-info/RECORD +200 -0
- pyjoyment-0.1.0.dist-info/WHEEL +4 -0
- pyjoyment-0.1.0.dist-info/entry_points.txt +8 -0
- pyjoyment-0.1.0.dist-info/licenses/LICENSE +201 -0
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Pyjoyment.Command.prefork - Pre-fork command
|
|
3
|
+
============================================
|
|
4
|
+
::
|
|
5
|
+
|
|
6
|
+
Usage: APPLICATION prefork [OPTIONS]
|
|
7
|
+
|
|
8
|
+
./myapp.py prefork
|
|
9
|
+
./myapp.py prefork -m production -p -l http://*:8080
|
|
10
|
+
./myapp.py prefork -l http://127.0.0.1:8080 -l https://[::]:8081
|
|
11
|
+
./myapp.py prefork -l 'https://*:443?cert=./server.crt&key=./server.key'
|
|
12
|
+
./myapp.py prefork -l http+unix://%2Ftmp%2Fmyapp.sock -w 12
|
|
13
|
+
./myapp.py prefork -l fcgi://127.0.0.1:9000
|
|
14
|
+
./myapp.py prefork -l http://127.0.0.1:8080 -p 127.0.0.0/8 -p fc00::/7
|
|
15
|
+
|
|
16
|
+
Options:
|
|
17
|
+
-a, --accepts <number> Number of connections for workers to
|
|
18
|
+
accept, defaults to 10000
|
|
19
|
+
-b, --backlog <size> Listen backlog size, defaults to
|
|
20
|
+
SOMAXCONN
|
|
21
|
+
-c, --clients <number> Maximum number of concurrent
|
|
22
|
+
connections, defaults to 1000
|
|
23
|
+
-G, --graceful-timeout <seconds> Graceful timeout, defaults to 25.
|
|
24
|
+
-I, --heartbeat-interval <seconds> Heartbeat interval, defaults to 5
|
|
25
|
+
-H, --heartbeat-timeout <seconds> Heartbeat timeout, defaults to 50
|
|
26
|
+
-h, --help Show this summary of available options
|
|
27
|
+
--home <path> Path to home directory of your
|
|
28
|
+
application, defaults to the value of
|
|
29
|
+
PYJO_HOME or auto-detection
|
|
30
|
+
-i, --inactivity-timeout <seconds> Inactivity timeout, defaults to the
|
|
31
|
+
value of PYJO_INACTIVITY_TIMEOUT or 30
|
|
32
|
+
-k, --keep-alive-timeout <seconds> Keep-alive timeout, defaults to the
|
|
33
|
+
value of PYJO_KEEP_ALIVE_TIMEOUT or 5
|
|
34
|
+
-l, --listen <location> One or more locations you want to
|
|
35
|
+
listen on, defaults to the value of
|
|
36
|
+
PYJO_LISTEN, the port of PORT or
|
|
37
|
+
"http://*:3000"
|
|
38
|
+
--log-format <name> Format of log messages, "text" or
|
|
39
|
+
"json", defaults to the value of
|
|
40
|
+
PYJO_LOG_FORMAT or "text"
|
|
41
|
+
-m, --mode <name> Operating mode for your application,
|
|
42
|
+
defaults to the value of PYJO_MODE or
|
|
43
|
+
"development"
|
|
44
|
+
-P, --pid-file <path> Path to process id file, defaults to
|
|
45
|
+
"prefork.pid" in a temporary directory
|
|
46
|
+
-p, --proxy [<network>] Activate reverse proxy support,
|
|
47
|
+
defaults to the value of
|
|
48
|
+
PYJO_REVERSE_PROXY, optionally takes
|
|
49
|
+
one or more trusted proxy addresses or
|
|
50
|
+
networks
|
|
51
|
+
-r, --requests <number> Maximum number of requests per
|
|
52
|
+
keep-alive connection, defaults to 100
|
|
53
|
+
-S, --shutdown-delay <seconds> Time to keep serving after INT or TERM
|
|
54
|
+
before shutting down gracefully,
|
|
55
|
+
defaults to 0
|
|
56
|
+
-s, --spare <number> Temporarily spawn up to this number of
|
|
57
|
+
additional workers, defaults to 2
|
|
58
|
+
-w, --workers <number> Number of workers, defaults to 4
|
|
59
|
+
|
|
60
|
+
:mod:`Pyjoyment.Command.prefork` starts applications with the
|
|
61
|
+
:mod:`Pyjo.Server.Prefork` backend.
|
|
62
|
+
|
|
63
|
+
An option that is not given has the value of the environment variable of
|
|
64
|
+
``PYJO_`` and its name, as ``PYJO_WORKERS`` for ``--workers``, with the
|
|
65
|
+
values of ``--listen`` and ``--proxy`` separated by commas, see
|
|
66
|
+
:mod:`Pyjo.GetOpt`, so that the environment of a container or a platform
|
|
67
|
+
can tune the server. ::
|
|
68
|
+
|
|
69
|
+
PYJO_GRACEFUL_TIMEOUT=8 PYJO_WORKERS=2 ./myapp.py prefork
|
|
70
|
+
|
|
71
|
+
This is a core command, that means it is always enabled and its code a good
|
|
72
|
+
example for learning to build new commands, you're welcome to fork it.
|
|
73
|
+
|
|
74
|
+
See :mod:`Pyjoyment.Commands` for a list of commands that are available by
|
|
75
|
+
default.
|
|
76
|
+
|
|
77
|
+
See also
|
|
78
|
+
--------
|
|
79
|
+
|
|
80
|
+
:mod:`Pyjoyment`, https://mojolicious.org.
|
|
81
|
+
|
|
82
|
+
Ported from `Mojolicious::Command::prefork
|
|
83
|
+
<https://github.com/mojolicious/mojo/blob/v9.49/lib/Mojolicious/Command/prefork.pm>`_ of Mojolicious 9.49.
|
|
84
|
+
|
|
85
|
+
Classes
|
|
86
|
+
-------
|
|
87
|
+
"""
|
|
88
|
+
|
|
89
|
+
import Pyjo.Exception
|
|
90
|
+
import Pyjo.Server.Prefork
|
|
91
|
+
import Pyjoyment.Command
|
|
92
|
+
|
|
93
|
+
from Pyjo.Util import extract_usage, getopt
|
|
94
|
+
|
|
95
|
+
from typing import Any
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
class Pyjoyment_Command_prefork(Pyjoyment.Command.object):
|
|
99
|
+
"""
|
|
100
|
+
:mod:`Pyjoyment.Command.prefork` inherits all attributes and methods from
|
|
101
|
+
:mod:`Pyjoyment.Command` and implements the following new ones.
|
|
102
|
+
"""
|
|
103
|
+
|
|
104
|
+
description = 'Start application with pre-forking HTTP and WebSocket server'
|
|
105
|
+
"""::
|
|
106
|
+
|
|
107
|
+
description = prefork.description
|
|
108
|
+
prefork.description = 'Foo'
|
|
109
|
+
|
|
110
|
+
Short description of this command, used for the command list.
|
|
111
|
+
"""
|
|
112
|
+
|
|
113
|
+
usage = extract_usage()
|
|
114
|
+
"""::
|
|
115
|
+
|
|
116
|
+
usage = prefork.usage
|
|
117
|
+
prefork.usage = 'Foo'
|
|
118
|
+
|
|
119
|
+
Usage information for this command, used for the help screen.
|
|
120
|
+
"""
|
|
121
|
+
|
|
122
|
+
# Not in Mojolicious: the class of the server, which Pyjoyment.Command.prethread replaces
|
|
123
|
+
_server: type[Pyjo.Server.Prefork.object] = Pyjo.Server.Prefork.object
|
|
124
|
+
|
|
125
|
+
def build_server(self, *args: str) -> Pyjo.Server.Prefork.object:
|
|
126
|
+
"""::
|
|
127
|
+
|
|
128
|
+
server = prefork.build_server(*sys.argv[1:])
|
|
129
|
+
|
|
130
|
+
Build :mod:`Pyjo.Server.Prefork` instance from command line arguments.
|
|
131
|
+
"""
|
|
132
|
+
arguments = list(args)
|
|
133
|
+
prefork = self._server.new(app=self.app)
|
|
134
|
+
listen: list[str] = []
|
|
135
|
+
proxy: list[str] = []
|
|
136
|
+
# Not in Mojolicious: the options from the environment variables of their names
|
|
137
|
+
if not getopt(
|
|
138
|
+
arguments,
|
|
139
|
+
{
|
|
140
|
+
'a|accepts=i': lambda name, value: setattr(prefork, 'accepts', value),
|
|
141
|
+
'b|backlog=i': lambda name, value: setattr(prefork, 'backlog', value),
|
|
142
|
+
'c|clients=i': lambda name, value: setattr(prefork, 'max_clients', value),
|
|
143
|
+
# Unlike Mojolicious: the graceful timeout defaults to 25 seconds, as Pyjo.Server.Prefork has it
|
|
144
|
+
'G|graceful-timeout=i': lambda name, value: setattr(prefork, 'graceful_timeout', value),
|
|
145
|
+
'I|heartbeat-interval=i': lambda name, value: setattr(prefork, 'heartbeat_interval', value),
|
|
146
|
+
'H|heartbeat-timeout=i': lambda name, value: setattr(prefork, 'heartbeat_timeout', value),
|
|
147
|
+
'i|inactivity-timeout=i': lambda name, value: setattr(prefork, 'inactivity_timeout', value),
|
|
148
|
+
'k|keep-alive-timeout=i': lambda name, value: setattr(prefork, 'keep_alive_timeout', value),
|
|
149
|
+
'l|listen=s': listen,
|
|
150
|
+
'P|pid-file=s': lambda name, value: setattr(prefork, 'pid_file', value),
|
|
151
|
+
'p|proxy:s': proxy,
|
|
152
|
+
'r|requests=i': lambda name, value: setattr(prefork, 'max_requests', value),
|
|
153
|
+
# Not in Mojolicious: the delay of the graceful shutdown, while the readiness fails
|
|
154
|
+
'S|shutdown-delay=i': lambda name, value: setattr(prefork, 'shutdown_delay', value),
|
|
155
|
+
's|spare=i': lambda name, value: setattr(prefork, 'spare', value),
|
|
156
|
+
'w|workers=i': lambda name, value: setattr(prefork, 'workers', value),
|
|
157
|
+
},
|
|
158
|
+
env_prefix='PYJO_',
|
|
159
|
+
):
|
|
160
|
+
raise Pyjo.Exception.new(self.usage)
|
|
161
|
+
|
|
162
|
+
if listen:
|
|
163
|
+
prefork.listen = listen
|
|
164
|
+
if proxy:
|
|
165
|
+
prefork.reverse_proxy = True
|
|
166
|
+
if trusted := [p for p in proxy if p]:
|
|
167
|
+
prefork.trusted_proxies = trusted
|
|
168
|
+
return prefork
|
|
169
|
+
|
|
170
|
+
def run(self, *args: str) -> Any:
|
|
171
|
+
"""::
|
|
172
|
+
|
|
173
|
+
prefork.run(*sys.argv[1:])
|
|
174
|
+
|
|
175
|
+
Run this command.
|
|
176
|
+
"""
|
|
177
|
+
return self.build_server(*args).run()
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
new = Pyjoyment_Command_prefork.new
|
|
181
|
+
object = Pyjoyment_Command_prefork
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Pyjoyment.Command.prethread - Pre-thread command
|
|
3
|
+
================================================
|
|
4
|
+
::
|
|
5
|
+
|
|
6
|
+
Usage: APPLICATION prethread [OPTIONS]
|
|
7
|
+
|
|
8
|
+
./myapp.py prethread
|
|
9
|
+
./myapp.py prethread -m production -p -l http://*:8080
|
|
10
|
+
./myapp.py prethread -l http://127.0.0.1:8080 -l https://[::]:8081
|
|
11
|
+
./myapp.py prethread -l 'https://*:443?cert=./server.crt&key=./server.key'
|
|
12
|
+
./myapp.py prethread -l http+unix://%2Ftmp%2Fmyapp.sock -w 12
|
|
13
|
+
./myapp.py prethread -l fcgi://127.0.0.1:9000
|
|
14
|
+
./myapp.py prethread -l http://127.0.0.1:8080 -p 127.0.0.0/8 -p fc00::/7
|
|
15
|
+
|
|
16
|
+
Options:
|
|
17
|
+
-a, --accepts <number> Number of connections for workers to
|
|
18
|
+
accept, defaults to 10000
|
|
19
|
+
-b, --backlog <size> Listen backlog size, defaults to
|
|
20
|
+
SOMAXCONN
|
|
21
|
+
-c, --clients <number> Maximum number of concurrent
|
|
22
|
+
connections, defaults to 1000
|
|
23
|
+
-G, --graceful-timeout <seconds> Graceful timeout, defaults to 25.
|
|
24
|
+
-I, --heartbeat-interval <seconds> Heartbeat interval, defaults to 5
|
|
25
|
+
-H, --heartbeat-timeout <seconds> Heartbeat timeout, defaults to 50
|
|
26
|
+
-h, --help Show this summary of available options
|
|
27
|
+
--home <path> Path to home directory of your
|
|
28
|
+
application, defaults to the value of
|
|
29
|
+
PYJO_HOME or auto-detection
|
|
30
|
+
-i, --inactivity-timeout <seconds> Inactivity timeout, defaults to the
|
|
31
|
+
value of PYJO_INACTIVITY_TIMEOUT or 30
|
|
32
|
+
-k, --keep-alive-timeout <seconds> Keep-alive timeout, defaults to the
|
|
33
|
+
value of PYJO_KEEP_ALIVE_TIMEOUT or 5
|
|
34
|
+
-l, --listen <location> One or more locations you want to
|
|
35
|
+
listen on, defaults to the value of
|
|
36
|
+
PYJO_LISTEN, the port of PORT or
|
|
37
|
+
"http://*:3000"
|
|
38
|
+
--log-format <name> Format of log messages, "text" or
|
|
39
|
+
"json", defaults to the value of
|
|
40
|
+
PYJO_LOG_FORMAT or "text"
|
|
41
|
+
-m, --mode <name> Operating mode for your application,
|
|
42
|
+
defaults to the value of PYJO_MODE or
|
|
43
|
+
"development"
|
|
44
|
+
-P, --pid-file <path> Path to process id file, defaults to
|
|
45
|
+
"prethread.pid" in a temporary
|
|
46
|
+
directory
|
|
47
|
+
-p, --proxy [<network>] Activate reverse proxy support,
|
|
48
|
+
defaults to the value of
|
|
49
|
+
PYJO_REVERSE_PROXY, optionally takes
|
|
50
|
+
one or more trusted proxy addresses or
|
|
51
|
+
networks
|
|
52
|
+
-r, --requests <number> Maximum number of requests per
|
|
53
|
+
keep-alive connection, defaults to 100
|
|
54
|
+
-S, --shutdown-delay <seconds> Time to keep serving after INT or TERM
|
|
55
|
+
before shutting down gracefully,
|
|
56
|
+
defaults to 0
|
|
57
|
+
-s, --spare <number> Temporarily spawn up to this number of
|
|
58
|
+
additional workers, defaults to 2
|
|
59
|
+
-w, --workers <number> Number of workers, defaults to 4
|
|
60
|
+
|
|
61
|
+
:mod:`Pyjoyment.Command.prethread` starts applications with the
|
|
62
|
+
:mod:`Pyjo.Server.Prethread` backend, with the options of
|
|
63
|
+
:mod:`Pyjoyment.Command.prefork`.
|
|
64
|
+
|
|
65
|
+
An option that is not given has the value of the environment variable of
|
|
66
|
+
``PYJO_`` and its name, as ``PYJO_WORKERS`` for ``--workers``, with the
|
|
67
|
+
values of ``--listen`` and ``--proxy`` separated by commas, see
|
|
68
|
+
:mod:`Pyjo.GetOpt`, so that the environment of a container or a platform
|
|
69
|
+
can tune the server. ::
|
|
70
|
+
|
|
71
|
+
PYJO_GRACEFUL_TIMEOUT=8 PYJO_WORKERS=2 ./myapp.py prethread
|
|
72
|
+
|
|
73
|
+
This is a core command, that means it is always enabled and its code a good
|
|
74
|
+
example for learning to build new commands, you're welcome to fork it.
|
|
75
|
+
|
|
76
|
+
See :mod:`Pyjoyment.Commands` for a list of commands that are available by
|
|
77
|
+
default.
|
|
78
|
+
|
|
79
|
+
See also
|
|
80
|
+
--------
|
|
81
|
+
|
|
82
|
+
:mod:`Pyjo.Server.Prethread`, :mod:`Pyjoyment`, https://mojolicious.org.
|
|
83
|
+
|
|
84
|
+
It has no counterpart in Mojolicious; it is inspired by
|
|
85
|
+
:mod:`Pyjoyment.Command.prefork`, the counterpart of `Mojolicious::Command::prefork
|
|
86
|
+
<https://github.com/mojolicious/mojo/blob/v9.49/lib/Mojolicious/Command/prefork.pm>`_.
|
|
87
|
+
|
|
88
|
+
Classes
|
|
89
|
+
-------
|
|
90
|
+
"""
|
|
91
|
+
|
|
92
|
+
import Pyjo.Server.Prethread
|
|
93
|
+
import Pyjoyment.Command.prefork
|
|
94
|
+
|
|
95
|
+
from Pyjo.Util import extract_usage
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
class Pyjoyment_Command_prethread(Pyjoyment.Command.prefork.object):
|
|
99
|
+
"""
|
|
100
|
+
:mod:`Pyjoyment.Command.prethread` inherits all attributes and methods from
|
|
101
|
+
:mod:`Pyjoyment.Command.prefork` and implements the following new ones.
|
|
102
|
+
"""
|
|
103
|
+
|
|
104
|
+
description = 'Start application with pre-threading HTTP and WebSocket server'
|
|
105
|
+
"""::
|
|
106
|
+
|
|
107
|
+
description = prethread.description
|
|
108
|
+
prethread.description = 'Foo'
|
|
109
|
+
|
|
110
|
+
Short description of this command, used for the command list.
|
|
111
|
+
"""
|
|
112
|
+
|
|
113
|
+
usage = extract_usage()
|
|
114
|
+
"""::
|
|
115
|
+
|
|
116
|
+
usage = prethread.usage
|
|
117
|
+
prethread.usage = 'Foo'
|
|
118
|
+
|
|
119
|
+
Usage information for this command, used for the help screen.
|
|
120
|
+
"""
|
|
121
|
+
|
|
122
|
+
_server = Pyjo.Server.Prethread.object
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
new = Pyjoyment_Command_prethread.new
|
|
126
|
+
object = Pyjoyment_Command_prethread
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Pyjoyment.Command.routes - Routes command
|
|
3
|
+
=========================================
|
|
4
|
+
::
|
|
5
|
+
|
|
6
|
+
Usage: APPLICATION routes [OPTIONS]
|
|
7
|
+
|
|
8
|
+
./myapp.py routes
|
|
9
|
+
./myapp.py routes -v
|
|
10
|
+
|
|
11
|
+
Options:
|
|
12
|
+
-h, --help Show this summary of available options
|
|
13
|
+
--home <path> Path to home directory of your application,
|
|
14
|
+
defaults to the value of PYJO_HOME or
|
|
15
|
+
auto-detection
|
|
16
|
+
--log-format <name> Format of log messages, "text" or "json",
|
|
17
|
+
defaults to the value of PYJO_LOG_FORMAT or
|
|
18
|
+
"text"
|
|
19
|
+
-m, --mode <name> Operating mode for your application, defaults to
|
|
20
|
+
the value of PYJO_MODE or "development"
|
|
21
|
+
-v, --verbose Print additional details about routes, flags
|
|
22
|
+
indicate C=Conditions, P=Partial, U=Under and
|
|
23
|
+
W=WebSocket
|
|
24
|
+
|
|
25
|
+
:mod:`Pyjoyment.Command.routes` lists all your application routes.
|
|
26
|
+
|
|
27
|
+
This is a core command, that means it is always enabled and its code a good
|
|
28
|
+
example for learning to build new commands, you're welcome to fork it.
|
|
29
|
+
|
|
30
|
+
See :mod:`Pyjoyment.Commands` for a list of commands that are available by
|
|
31
|
+
default.
|
|
32
|
+
|
|
33
|
+
See also
|
|
34
|
+
--------
|
|
35
|
+
|
|
36
|
+
:mod:`Pyjoyment`, https://mojolicious.org.
|
|
37
|
+
|
|
38
|
+
Ported from `Mojolicious::Command::routes
|
|
39
|
+
<https://github.com/mojolicious/mojo/blob/v9.49/lib/Mojolicious/Command/routes.pm>`_ of Mojolicious 9.49.
|
|
40
|
+
|
|
41
|
+
Classes
|
|
42
|
+
-------
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
import Pyjo.Exception
|
|
46
|
+
import Pyjoyment.Command
|
|
47
|
+
import Pyjoyment.Routes.Route
|
|
48
|
+
|
|
49
|
+
from Pyjo.Util import extract_usage, getopt, tablify
|
|
50
|
+
|
|
51
|
+
from typing import Any
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class Pyjoyment_Command_routes(Pyjoyment.Command.object):
|
|
55
|
+
"""
|
|
56
|
+
:mod:`Pyjoyment.Command.routes` inherits all attributes and methods from
|
|
57
|
+
:mod:`Pyjoyment.Command` and implements the following new ones.
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
description = 'Show available routes'
|
|
61
|
+
"""::
|
|
62
|
+
|
|
63
|
+
description = routes.description
|
|
64
|
+
routes.description = 'Foo'
|
|
65
|
+
|
|
66
|
+
Short description of this command, used for the command list.
|
|
67
|
+
"""
|
|
68
|
+
|
|
69
|
+
usage = extract_usage()
|
|
70
|
+
"""::
|
|
71
|
+
|
|
72
|
+
usage = routes.usage
|
|
73
|
+
routes.usage = 'Foo'
|
|
74
|
+
|
|
75
|
+
Usage information for this command, used for the help screen.
|
|
76
|
+
"""
|
|
77
|
+
|
|
78
|
+
def run(self, *args: str) -> None:
|
|
79
|
+
"""::
|
|
80
|
+
|
|
81
|
+
routes.run(*sys.argv[1:])
|
|
82
|
+
|
|
83
|
+
Run this command.
|
|
84
|
+
"""
|
|
85
|
+
arguments = list(args)
|
|
86
|
+
if not (opts := getopt(arguments, {'v|verbose': None})):
|
|
87
|
+
raise Pyjo.Exception.new(self.usage)
|
|
88
|
+
|
|
89
|
+
rows: list[list[str]] = []
|
|
90
|
+
for route in self.app.routes.children:
|
|
91
|
+
_walk(route, 0, rows, bool(opts.verbose))
|
|
92
|
+
print(tablify(rows), end='')
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def _walk(route: Pyjoyment.Routes.Route.object, depth: int, rows: list[list[str]], verbose: bool) -> None:
|
|
96
|
+
# Pattern
|
|
97
|
+
prefix = ''
|
|
98
|
+
if i := depth * 2:
|
|
99
|
+
prefix += ' ' * i + '+'
|
|
100
|
+
row = [prefix + (route.pattern.unparsed or '/')]
|
|
101
|
+
rows.append(row)
|
|
102
|
+
|
|
103
|
+
# Flags
|
|
104
|
+
flags: list[str] = []
|
|
105
|
+
flags.append('C' if route.requires() else '.')
|
|
106
|
+
flags.append('P' if (partial := route.partial) else '.')
|
|
107
|
+
flags.append('U' if route.inline else '.')
|
|
108
|
+
flags.append('W' if route.is_websocket else '.')
|
|
109
|
+
if verbose:
|
|
110
|
+
row.append(''.join(flags))
|
|
111
|
+
|
|
112
|
+
# Methods
|
|
113
|
+
methods: Any = route.methods()
|
|
114
|
+
row.append(','.join(methods).upper() if methods else '*')
|
|
115
|
+
|
|
116
|
+
# Name
|
|
117
|
+
name = route.name or ''
|
|
118
|
+
row.append(f'"{name}"' if route.has_custom_name else name)
|
|
119
|
+
|
|
120
|
+
# Regex (verbose)
|
|
121
|
+
pattern = route.pattern
|
|
122
|
+
pattern.match('/', route.is_endpoint and not partial)
|
|
123
|
+
if verbose:
|
|
124
|
+
row.append(pattern.regex.pattern if pattern.regex is not None else '')
|
|
125
|
+
|
|
126
|
+
depth += 1
|
|
127
|
+
for child in route.children:
|
|
128
|
+
_walk(child, depth, rows, verbose)
|
|
129
|
+
depth -= 1
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
new = Pyjoyment_Command_routes.new
|
|
133
|
+
object = Pyjoyment_Command_routes
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Pyjoyment.Command.stdio - Standard input and output command
|
|
3
|
+
===========================================================
|
|
4
|
+
::
|
|
5
|
+
|
|
6
|
+
Usage: APPLICATION stdio [OPTIONS]
|
|
7
|
+
|
|
8
|
+
./myapp.py stdio
|
|
9
|
+
./myapp.py stdio -m production
|
|
10
|
+
|
|
11
|
+
Options:
|
|
12
|
+
-h, --help Show this summary of available options
|
|
13
|
+
--home <path> Path to home directory of your application,
|
|
14
|
+
defaults to the value of PYJO_HOME or
|
|
15
|
+
auto-detection
|
|
16
|
+
--log-format <name> Format of log messages, "text" or "json",
|
|
17
|
+
defaults to the value of PYJO_LOG_FORMAT or
|
|
18
|
+
"text"
|
|
19
|
+
-m, --mode <name> Operating mode for your application, defaults to
|
|
20
|
+
the value of PYJO_MODE or "development"
|
|
21
|
+
|
|
22
|
+
:mod:`Pyjoyment.Command.stdio` starts applications with the
|
|
23
|
+
:mod:`Pyjo.Server.Stdio` backend, which serves the protocol that the
|
|
24
|
+
application or a plugin gives with a subscriber of its event ``stream`` on
|
|
25
|
+
the standard input and output. It is not detected, as a pipe on the standard
|
|
26
|
+
input is too common to mean it.
|
|
27
|
+
|
|
28
|
+
This is a core command, that means it is always enabled and its code a good
|
|
29
|
+
example for learning to build new commands, you're welcome to fork it.
|
|
30
|
+
|
|
31
|
+
See :mod:`Pyjoyment.Commands` for a list of commands that are available by
|
|
32
|
+
default.
|
|
33
|
+
|
|
34
|
+
See also
|
|
35
|
+
--------
|
|
36
|
+
|
|
37
|
+
:mod:`Pyjoyment`, https://mojolicious.org.
|
|
38
|
+
|
|
39
|
+
It has no counterpart in Mojolicious.
|
|
40
|
+
|
|
41
|
+
Classes
|
|
42
|
+
-------
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
import Pyjo.Exception
|
|
46
|
+
import Pyjo.Server.Stdio
|
|
47
|
+
import Pyjoyment.Command
|
|
48
|
+
|
|
49
|
+
from Pyjo.Util import extract_usage, getopt
|
|
50
|
+
|
|
51
|
+
from typing import Any
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class Pyjoyment_Command_stdio(Pyjoyment.Command.object):
|
|
55
|
+
"""
|
|
56
|
+
:mod:`Pyjoyment.Command.stdio` inherits all attributes and methods from
|
|
57
|
+
:mod:`Pyjoyment.Command` and implements the following new ones.
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
description = 'Start application on standard input and output'
|
|
61
|
+
"""::
|
|
62
|
+
|
|
63
|
+
description = stdio.description
|
|
64
|
+
stdio.description = 'Foo'
|
|
65
|
+
|
|
66
|
+
Short description of this command, used for the command list.
|
|
67
|
+
"""
|
|
68
|
+
|
|
69
|
+
usage = extract_usage()
|
|
70
|
+
"""::
|
|
71
|
+
|
|
72
|
+
usage = stdio.usage
|
|
73
|
+
stdio.usage = 'Foo'
|
|
74
|
+
|
|
75
|
+
Usage information for this command, used for the help screen.
|
|
76
|
+
"""
|
|
77
|
+
|
|
78
|
+
def run(self, *args: str) -> Any:
|
|
79
|
+
"""::
|
|
80
|
+
|
|
81
|
+
stdio.run(*sys.argv[1:])
|
|
82
|
+
|
|
83
|
+
Run this command.
|
|
84
|
+
"""
|
|
85
|
+
arguments = list(args)
|
|
86
|
+
if not getopt(arguments, {}) or len(arguments):
|
|
87
|
+
raise Pyjo.Exception.new(self.usage)
|
|
88
|
+
return Pyjo.Server.Stdio.new(app=self.app).run()
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
new = Pyjoyment_Command_stdio.new
|
|
92
|
+
object = Pyjoyment_Command_stdio
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Pyjoyment.Command.version - Version command
|
|
3
|
+
===========================================
|
|
4
|
+
::
|
|
5
|
+
|
|
6
|
+
Usage: APPLICATION version [OPTIONS]
|
|
7
|
+
|
|
8
|
+
pyjo version
|
|
9
|
+
|
|
10
|
+
Options:
|
|
11
|
+
-h, --help Show this summary of available options
|
|
12
|
+
|
|
13
|
+
:mod:`Pyjoyment.Command.version` shows version information for
|
|
14
|
+
available core and optional modules.
|
|
15
|
+
|
|
16
|
+
This is a core command, that means it is always enabled and its code a good
|
|
17
|
+
example for learning to build new commands, you're welcome to fork it.
|
|
18
|
+
|
|
19
|
+
See :mod:`Pyjoyment.Commands` for a list of commands that are available by
|
|
20
|
+
default.
|
|
21
|
+
|
|
22
|
+
See also
|
|
23
|
+
--------
|
|
24
|
+
|
|
25
|
+
:mod:`Pyjoyment`, https://mojolicious.org.
|
|
26
|
+
|
|
27
|
+
Ported from `Mojolicious::Command::version
|
|
28
|
+
<https://github.com/mojolicious/mojo/blob/v9.49/lib/Mojolicious/Command/version.pm>`_ of Mojolicious 9.49.
|
|
29
|
+
|
|
30
|
+
Classes
|
|
31
|
+
-------
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
import Pyjo.IOLoop.Client
|
|
35
|
+
import Pyjo.IOLoop.TLS
|
|
36
|
+
import Pyjo.Reactor
|
|
37
|
+
import Pyjoyment.Command
|
|
38
|
+
|
|
39
|
+
from Pyjo.Util import extract_usage
|
|
40
|
+
|
|
41
|
+
import importlib.metadata
|
|
42
|
+
import platform
|
|
43
|
+
import re
|
|
44
|
+
import ssl
|
|
45
|
+
import sys
|
|
46
|
+
import tomllib
|
|
47
|
+
|
|
48
|
+
from pathlib import Path
|
|
49
|
+
from typing import Any
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class Pyjoyment_Command_version(Pyjoyment.Command.object):
|
|
53
|
+
"""
|
|
54
|
+
:mod:`Pyjoyment.Command.version` inherits all attributes and methods from
|
|
55
|
+
:mod:`Pyjoyment.Command` and implements the following new ones.
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
description = 'Show versions of available modules'
|
|
59
|
+
"""::
|
|
60
|
+
|
|
61
|
+
description = version.description
|
|
62
|
+
version.description = 'Foo'
|
|
63
|
+
|
|
64
|
+
Short description of this command, used for the command list.
|
|
65
|
+
"""
|
|
66
|
+
|
|
67
|
+
usage = extract_usage()
|
|
68
|
+
"""::
|
|
69
|
+
|
|
70
|
+
usage = version.usage
|
|
71
|
+
version.usage = 'Foo'
|
|
72
|
+
|
|
73
|
+
Usage information for this command, used for the help screen.
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
def run(self, *args: str) -> None:
|
|
77
|
+
"""::
|
|
78
|
+
|
|
79
|
+
version.run(*sys.argv[1:])
|
|
80
|
+
|
|
81
|
+
Run this command.
|
|
82
|
+
"""
|
|
83
|
+
# Unlike Mojolicious: the counterparts of the optional modules of Perl that Mojo shows, which Python has in its
|
|
84
|
+
# standard library, and which Pyjoyment can turn off
|
|
85
|
+
reactor = Pyjo.Reactor.detect()
|
|
86
|
+
nnr = 'getaddrinfo in a thread' if Pyjo.IOLoop.Client.object.can_nnr() else 'n/a'
|
|
87
|
+
socks = 'Pyjo.IOLoop.Client' if Pyjo.IOLoop.Client.object.can_socks() else 'n/a'
|
|
88
|
+
tls = ssl.OPENSSL_VERSION if Pyjo.IOLoop.TLS.object.can_tls() else 'n/a'
|
|
89
|
+
current = _version()
|
|
90
|
+
|
|
91
|
+
print(f"""CORE
|
|
92
|
+
Python ({platform.python_version()}, {sys.platform})
|
|
93
|
+
Pyjoyment ({current})
|
|
94
|
+
|
|
95
|
+
OPTIONAL
|
|
96
|
+
Reactor ({reactor})
|
|
97
|
+
NNR ({nnr})
|
|
98
|
+
SOCKS5 ({socks})
|
|
99
|
+
TLS ({tls})
|
|
100
|
+
""")
|
|
101
|
+
|
|
102
|
+
# Check latest version on PyPI
|
|
103
|
+
# Unlike Mojolicious: the JSON API of PyPI, where Mojo asks MetaCPAN
|
|
104
|
+
try:
|
|
105
|
+
ua = self.app.ua
|
|
106
|
+
ua.max_redirects = 10
|
|
107
|
+
ua.proxy.detect()
|
|
108
|
+
latest = str(ua.get('https://pypi.org/pypi/Pyjoyment/json').result.json()['info']['version'])
|
|
109
|
+
except Exception:
|
|
110
|
+
return
|
|
111
|
+
|
|
112
|
+
msg = 'This version is up to date, have fun!'
|
|
113
|
+
if _numbers(latest) < _numbers(current):
|
|
114
|
+
msg = 'Thanks for testing a development release, you are awesome!'
|
|
115
|
+
if _numbers(latest) > _numbers(current):
|
|
116
|
+
msg = f'You might want to update your Pyjoyment to {latest}!'
|
|
117
|
+
print(msg)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
# The numbers of a version, which compare as the versions do
|
|
121
|
+
def _numbers(version: str) -> tuple[int, ...]:
|
|
122
|
+
return tuple(int(number) for number in re.findall(r'\d+', version))
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
# Not in Mojolicious: the version of the distribution, from its metadata, or from the pyproject.toml of a checkout of
|
|
126
|
+
# its source, as Python has no $VERSION of a module
|
|
127
|
+
def _version() -> str:
|
|
128
|
+
try:
|
|
129
|
+
return importlib.metadata.version('Pyjoyment')
|
|
130
|
+
except importlib.metadata.PackageNotFoundError:
|
|
131
|
+
pass
|
|
132
|
+
pyproject = Path(__file__).resolve().parents[2] / 'pyproject.toml'
|
|
133
|
+
try:
|
|
134
|
+
project: Any = tomllib.loads(pyproject.read_text(encoding='utf-8')).get('project', {})
|
|
135
|
+
except (OSError, tomllib.TOMLDecodeError):
|
|
136
|
+
return 'n/a'
|
|
137
|
+
return str(project['version']) if project.get('name') == 'Pyjoyment' and 'version' in project else 'n/a'
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
new = Pyjoyment_Command_version.new
|
|
141
|
+
object = Pyjoyment_Command_version
|