muscles-asgi 1.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- muscles_asgi-1.0.0/PKG-INFO +170 -0
- muscles_asgi-1.0.0/README.md +141 -0
- muscles_asgi-1.0.0/pyproject.toml +35 -0
- muscles_asgi-1.0.0/src/muscles/asgi/Makefile +26 -0
- muscles_asgi-1.0.0/src/muscles/asgi/__about__.py +6 -0
- muscles_asgi-1.0.0/src/muscles/asgi/__init__.py +62 -0
- muscles_asgi-1.0.0/src/muscles/asgi/action_bridge.py +260 -0
- muscles_asgi-1.0.0/src/muscles/asgi/app.py +72 -0
- muscles_asgi-1.0.0/src/muscles/asgi/asgi/__init__.py +43 -0
- muscles_asgi-1.0.0/src/muscles/asgi/asgi/actor.py +52 -0
- muscles_asgi-1.0.0/src/muscles/asgi/asgi/error_handler.py +68 -0
- muscles_asgi-1.0.0/src/muscles/asgi/asgi/http_code.py +397 -0
- muscles_asgi-1.0.0/src/muscles/asgi/asgi/request.py +1091 -0
- muscles_asgi-1.0.0/src/muscles/asgi/asgi/response.py +576 -0
- muscles_asgi-1.0.0/src/muscles/asgi/asgi/routers.py +159 -0
- muscles_asgi-1.0.0/src/muscles/asgi/asgi/server.py +739 -0
- muscles_asgi-1.0.0/src/muscles/asgi/asgi/strategy.py +130 -0
- muscles_asgi-1.0.0/src/muscles/asgi/assets/__init__.py +6 -0
- muscles_asgi-1.0.0/src/muscles/asgi/assets/asset.py +81 -0
- muscles_asgi-1.0.0/src/muscles/asgi/assets/axios.min.js +3 -0
- muscles_asgi-1.0.0/src/muscles/asgi/assets/vue.global.js +15934 -0
- muscles_asgi-1.0.0/src/muscles/asgi/providers.py +38 -0
- muscles_asgi-1.0.0/src/muscles/asgi/restful/__init__.py +31 -0
- muscles_asgi-1.0.0/src/muscles/asgi/restful/mount.py +83 -0
- muscles_asgi-1.0.0/src/muscles/asgi/restful/parameters.py +46 -0
- muscles_asgi-1.0.0/src/muscles/asgi/restful/request_body.py +58 -0
- muscles_asgi-1.0.0/src/muscles/asgi/restful/response_body.py +39 -0
- muscles_asgi-1.0.0/src/muscles/asgi/restful/restful.py +275 -0
- muscles_asgi-1.0.0/src/muscles/asgi/restful/swagger.py +290 -0
- muscles_asgi-1.0.0/src/muscles/asgi/restful/templates/swagger.jinja2 +38 -0
- muscles_asgi-1.0.0/src/muscles/asgi/template/__init__.py +10 -0
- muscles_asgi-1.0.0/src/muscles/asgi/template/template.py +464 -0
- muscles_asgi-1.0.0/src/muscles/asgi/testing.py +140 -0
- muscles_asgi-1.0.0/src/muscles/asgi/uwsgi/__init__.py +5 -0
- muscles_asgi-1.0.0/src/muscles/asgi/uwsgi/uwsgi.py +18 -0
- muscles_asgi-1.0.0/src/muscles/asgi/watchdog/__init__.py +6 -0
- muscles_asgi-1.0.0/src/muscles/asgi/watchdog/watchdog.py +137 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: muscles-asgi
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Muscles ASGI runtime adapter for Web/API applications
|
|
5
|
+
License: MIT
|
|
6
|
+
Author: Denis B.
|
|
7
|
+
Author-email: denis@butko.info
|
|
8
|
+
Requires-Python: >=3.10,<4.0
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
16
|
+
Provides-Extra: mime
|
|
17
|
+
Provides-Extra: server
|
|
18
|
+
Requires-Dist: dnspython (==2.6.1)
|
|
19
|
+
Requires-Dist: jinja2 (==3.1.2)
|
|
20
|
+
Requires-Dist: jsonschema (==4.16.0)
|
|
21
|
+
Requires-Dist: muscles (>=1.0.0rc1,<2.0.0)
|
|
22
|
+
Requires-Dist: python-magic (==0.4.27) ; extra == "mime"
|
|
23
|
+
Requires-Dist: requests (>=2.31.0,<3.0.0)
|
|
24
|
+
Requires-Dist: requests-toolbelt (>=1.0.0,<2.0.0)
|
|
25
|
+
Requires-Dist: uwsgi (==2.0.20) ; extra == "server"
|
|
26
|
+
Requires-Dist: watchdog (>=4.0.0,<5.0.0)
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
|
|
29
|
+
# Muscles ASGI
|
|
30
|
+
|
|
31
|
+
`muscles-asgi` is the ASGI runtime for Muscles. It mirrors the WSGI API model
|
|
32
|
+
while using ASGI scopes/events for async-capable servers.
|
|
33
|
+
|
|
34
|
+
## Installation
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pip install muscles-asgi
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Canonical ecosystem install matrix is documented in core:
|
|
41
|
+
[Muscles installation matrix](https://github.com/butkoden/muscles/blob/master/docs/installation.md).
|
|
42
|
+
|
|
43
|
+
## Related Repositories
|
|
44
|
+
|
|
45
|
+
- [`muscles`](https://github.com/butkoden/muscles) - core contracts, routing, actions and canonical documentation.
|
|
46
|
+
- [`muscles-wsgi`](https://github.com/butkoden/muscles-wsgi) - WSGI runtime with the same application model.
|
|
47
|
+
- [`muscles-cli`](https://github.com/butkoden/muscles-cli) - CLI projection and developer commands.
|
|
48
|
+
- [`muscles-sse`](https://github.com/butkoden/muscles-sse) - streaming projection for action results.
|
|
49
|
+
- [`muscles-mcp`](https://github.com/butkoden/muscles-mcp) - MCP projection that can bind to ASGI entrypoints.
|
|
50
|
+
- [`muscles-benchmarks`](https://github.com/butkoden/muscles-benchmarks) - ASGI regression and architecture checks.
|
|
51
|
+
|
|
52
|
+
## Runtime
|
|
53
|
+
|
|
54
|
+
An app binds `Context` to `AsgiStrategy`:
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
from muscles import ApplicationMeta, Configurator, Context
|
|
58
|
+
from muscles.asgi import AsgiStrategy
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class App(metaclass=ApplicationMeta):
|
|
62
|
+
config = Configurator(obj={"main": {"HOST": "0.0.0.0", "PORT": "8080"}})
|
|
63
|
+
context = Context(AsgiStrategy, params={})
|
|
64
|
+
|
|
65
|
+
def run(self, *args):
|
|
66
|
+
return self.context.execute(*args, shutup=True)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
The ASGI package shares core schemas, route matching and OpenAPI generation with
|
|
70
|
+
the other runtimes. It should not duplicate core itinerary code.
|
|
71
|
+
|
|
72
|
+
## Schema Ownership
|
|
73
|
+
|
|
74
|
+
ASGI does not ship its own `muscles.asgi.schema_` package. Framework schemas,
|
|
75
|
+
columns, fields, request/response bodies, security objects and value objects
|
|
76
|
+
belong to `muscles.core.schema` and should be imported from `muscles`:
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
from muscles import Column, JsonRequestBody, Model, String
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## REST API And Swagger
|
|
83
|
+
|
|
84
|
+
`RestApi` controllers/actions are projected into OpenAPI automatically. Generated
|
|
85
|
+
paths include the external API prefix, so a mounted route such as
|
|
86
|
+
`/api/v1/bookings` appears in Swagger exactly as clients must call it.
|
|
87
|
+
|
|
88
|
+
More detail: [docs/openapi-and-routing.md](docs/openapi-and-routing.md).
|
|
89
|
+
Backend pipeline features are documented in
|
|
90
|
+
[docs/backend-pipeline.md](docs/backend-pipeline.md).
|
|
91
|
+
|
|
92
|
+
## Application Inspection
|
|
93
|
+
|
|
94
|
+
Use `mount_api(app, api)` after declaring a `RestApi` to project ASGI routes into
|
|
95
|
+
the core `ApplicationRegistry`. This makes routes visible to
|
|
96
|
+
`inspect_application(app)` and CLI/doctor tooling without making the registry
|
|
97
|
+
the HTTP dispatch source.
|
|
98
|
+
|
|
99
|
+
Call it after all controllers/actions are registered and before running
|
|
100
|
+
inspection, doctor checks or generators. It is safe to call more than once:
|
|
101
|
+
already projected routes are skipped. `finalize_api(app, api)` is an alias for
|
|
102
|
+
projects that prefer a "declare, then finalize" bootstrap style.
|
|
103
|
+
`asgi_app(app)` also calls `mount_application_apis(app)` once when the ASGI
|
|
104
|
+
entrypoint is created, so APIs stored as attributes on the application are
|
|
105
|
+
visible to runtime inspection without additional app-side adapters.
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
from muscles import inspect_application
|
|
109
|
+
from muscles.asgi import RestApi, finalize_api
|
|
110
|
+
|
|
111
|
+
app = App()
|
|
112
|
+
api = RestApi(name="Api", prefix="/api")
|
|
113
|
+
|
|
114
|
+
@api.init("/ping", method="get")
|
|
115
|
+
def ping(request):
|
|
116
|
+
return {"ok": True}
|
|
117
|
+
|
|
118
|
+
finalize_api(app, api)
|
|
119
|
+
assert any(route["path"] == "/api/ping" for route in inspect_application(app)["routes"])
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Request dispatch still uses the ASGI `RestApi` route tree. The projected routes
|
|
123
|
+
are lightweight descriptors for tools that need to understand the application
|
|
124
|
+
without knowing ASGI internals.
|
|
125
|
+
|
|
126
|
+
When the application has a neutral `TelemetryProvider`, ASGI records a
|
|
127
|
+
`muscles.server.dispatch` span for matched routes with app, route, method and
|
|
128
|
+
HTTP status attributes.
|
|
129
|
+
|
|
130
|
+
## Action Bridge
|
|
131
|
+
|
|
132
|
+
`ActionAsgiAdapter` is an optional HTTP projection for Muscles actions. It keeps
|
|
133
|
+
package-specific features out of ASGI routes: packages register normal core
|
|
134
|
+
actions, and ASGI exposes only the actions explicitly allowed by the project.
|
|
135
|
+
|
|
136
|
+
```python
|
|
137
|
+
from muscles.asgi import ActionAsgiAdapter
|
|
138
|
+
|
|
139
|
+
application = ActionAsgiAdapter.from_application(
|
|
140
|
+
app,
|
|
141
|
+
allowed_actions={"bookings.echo"},
|
|
142
|
+
)
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
The bridge accepts JSON `POST /actions/<action-name>` requests, executes through
|
|
146
|
+
core `ActionDispatcher(..., transport="http")`, returns JSON for non-stream
|
|
147
|
+
results, and returns `application/problem+json` for core action errors. Stream
|
|
148
|
+
actions should be projected through `muscles-sse`.
|
|
149
|
+
|
|
150
|
+
## Request Handling
|
|
151
|
+
|
|
152
|
+
Request parsing does not require `cgi`, `multipart` or `python-magic` at import
|
|
153
|
+
time. Multipart form data uses the standard library path, and missing MIME
|
|
154
|
+
detection falls back safely.
|
|
155
|
+
|
|
156
|
+
ASGI request execution is stateless on `Context`: request-specific data
|
|
157
|
+
(`scope`, `receive`, `send`) is passed directly into `context.execute(...)`
|
|
158
|
+
per request. The strategy keeps a persistent server lifecycle while request
|
|
159
|
+
state stays isolated.
|
|
160
|
+
|
|
161
|
+
## Development
|
|
162
|
+
|
|
163
|
+
Run tests with sibling packages on `PYTHONPATH`:
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
PYTHONPATH=../muscles/src:src python -m pytest -q
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
Production notes: [docs/production.md](docs/production.md).
|
|
170
|
+
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# Muscles ASGI
|
|
2
|
+
|
|
3
|
+
`muscles-asgi` is the ASGI runtime for Muscles. It mirrors the WSGI API model
|
|
4
|
+
while using ASGI scopes/events for async-capable servers.
|
|
5
|
+
|
|
6
|
+
## Installation
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
pip install muscles-asgi
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Canonical ecosystem install matrix is documented in core:
|
|
13
|
+
[Muscles installation matrix](https://github.com/butkoden/muscles/blob/master/docs/installation.md).
|
|
14
|
+
|
|
15
|
+
## Related Repositories
|
|
16
|
+
|
|
17
|
+
- [`muscles`](https://github.com/butkoden/muscles) - core contracts, routing, actions and canonical documentation.
|
|
18
|
+
- [`muscles-wsgi`](https://github.com/butkoden/muscles-wsgi) - WSGI runtime with the same application model.
|
|
19
|
+
- [`muscles-cli`](https://github.com/butkoden/muscles-cli) - CLI projection and developer commands.
|
|
20
|
+
- [`muscles-sse`](https://github.com/butkoden/muscles-sse) - streaming projection for action results.
|
|
21
|
+
- [`muscles-mcp`](https://github.com/butkoden/muscles-mcp) - MCP projection that can bind to ASGI entrypoints.
|
|
22
|
+
- [`muscles-benchmarks`](https://github.com/butkoden/muscles-benchmarks) - ASGI regression and architecture checks.
|
|
23
|
+
|
|
24
|
+
## Runtime
|
|
25
|
+
|
|
26
|
+
An app binds `Context` to `AsgiStrategy`:
|
|
27
|
+
|
|
28
|
+
```python
|
|
29
|
+
from muscles import ApplicationMeta, Configurator, Context
|
|
30
|
+
from muscles.asgi import AsgiStrategy
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class App(metaclass=ApplicationMeta):
|
|
34
|
+
config = Configurator(obj={"main": {"HOST": "0.0.0.0", "PORT": "8080"}})
|
|
35
|
+
context = Context(AsgiStrategy, params={})
|
|
36
|
+
|
|
37
|
+
def run(self, *args):
|
|
38
|
+
return self.context.execute(*args, shutup=True)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
The ASGI package shares core schemas, route matching and OpenAPI generation with
|
|
42
|
+
the other runtimes. It should not duplicate core itinerary code.
|
|
43
|
+
|
|
44
|
+
## Schema Ownership
|
|
45
|
+
|
|
46
|
+
ASGI does not ship its own `muscles.asgi.schema_` package. Framework schemas,
|
|
47
|
+
columns, fields, request/response bodies, security objects and value objects
|
|
48
|
+
belong to `muscles.core.schema` and should be imported from `muscles`:
|
|
49
|
+
|
|
50
|
+
```python
|
|
51
|
+
from muscles import Column, JsonRequestBody, Model, String
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## REST API And Swagger
|
|
55
|
+
|
|
56
|
+
`RestApi` controllers/actions are projected into OpenAPI automatically. Generated
|
|
57
|
+
paths include the external API prefix, so a mounted route such as
|
|
58
|
+
`/api/v1/bookings` appears in Swagger exactly as clients must call it.
|
|
59
|
+
|
|
60
|
+
More detail: [docs/openapi-and-routing.md](docs/openapi-and-routing.md).
|
|
61
|
+
Backend pipeline features are documented in
|
|
62
|
+
[docs/backend-pipeline.md](docs/backend-pipeline.md).
|
|
63
|
+
|
|
64
|
+
## Application Inspection
|
|
65
|
+
|
|
66
|
+
Use `mount_api(app, api)` after declaring a `RestApi` to project ASGI routes into
|
|
67
|
+
the core `ApplicationRegistry`. This makes routes visible to
|
|
68
|
+
`inspect_application(app)` and CLI/doctor tooling without making the registry
|
|
69
|
+
the HTTP dispatch source.
|
|
70
|
+
|
|
71
|
+
Call it after all controllers/actions are registered and before running
|
|
72
|
+
inspection, doctor checks or generators. It is safe to call more than once:
|
|
73
|
+
already projected routes are skipped. `finalize_api(app, api)` is an alias for
|
|
74
|
+
projects that prefer a "declare, then finalize" bootstrap style.
|
|
75
|
+
`asgi_app(app)` also calls `mount_application_apis(app)` once when the ASGI
|
|
76
|
+
entrypoint is created, so APIs stored as attributes on the application are
|
|
77
|
+
visible to runtime inspection without additional app-side adapters.
|
|
78
|
+
|
|
79
|
+
```python
|
|
80
|
+
from muscles import inspect_application
|
|
81
|
+
from muscles.asgi import RestApi, finalize_api
|
|
82
|
+
|
|
83
|
+
app = App()
|
|
84
|
+
api = RestApi(name="Api", prefix="/api")
|
|
85
|
+
|
|
86
|
+
@api.init("/ping", method="get")
|
|
87
|
+
def ping(request):
|
|
88
|
+
return {"ok": True}
|
|
89
|
+
|
|
90
|
+
finalize_api(app, api)
|
|
91
|
+
assert any(route["path"] == "/api/ping" for route in inspect_application(app)["routes"])
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Request dispatch still uses the ASGI `RestApi` route tree. The projected routes
|
|
95
|
+
are lightweight descriptors for tools that need to understand the application
|
|
96
|
+
without knowing ASGI internals.
|
|
97
|
+
|
|
98
|
+
When the application has a neutral `TelemetryProvider`, ASGI records a
|
|
99
|
+
`muscles.server.dispatch` span for matched routes with app, route, method and
|
|
100
|
+
HTTP status attributes.
|
|
101
|
+
|
|
102
|
+
## Action Bridge
|
|
103
|
+
|
|
104
|
+
`ActionAsgiAdapter` is an optional HTTP projection for Muscles actions. It keeps
|
|
105
|
+
package-specific features out of ASGI routes: packages register normal core
|
|
106
|
+
actions, and ASGI exposes only the actions explicitly allowed by the project.
|
|
107
|
+
|
|
108
|
+
```python
|
|
109
|
+
from muscles.asgi import ActionAsgiAdapter
|
|
110
|
+
|
|
111
|
+
application = ActionAsgiAdapter.from_application(
|
|
112
|
+
app,
|
|
113
|
+
allowed_actions={"bookings.echo"},
|
|
114
|
+
)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
The bridge accepts JSON `POST /actions/<action-name>` requests, executes through
|
|
118
|
+
core `ActionDispatcher(..., transport="http")`, returns JSON for non-stream
|
|
119
|
+
results, and returns `application/problem+json` for core action errors. Stream
|
|
120
|
+
actions should be projected through `muscles-sse`.
|
|
121
|
+
|
|
122
|
+
## Request Handling
|
|
123
|
+
|
|
124
|
+
Request parsing does not require `cgi`, `multipart` or `python-magic` at import
|
|
125
|
+
time. Multipart form data uses the standard library path, and missing MIME
|
|
126
|
+
detection falls back safely.
|
|
127
|
+
|
|
128
|
+
ASGI request execution is stateless on `Context`: request-specific data
|
|
129
|
+
(`scope`, `receive`, `send`) is passed directly into `context.execute(...)`
|
|
130
|
+
per request. The strategy keeps a persistent server lifecycle while request
|
|
131
|
+
state stays isolated.
|
|
132
|
+
|
|
133
|
+
## Development
|
|
134
|
+
|
|
135
|
+
Run tests with sibling packages on `PYTHONPATH`:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
PYTHONPATH=../muscles/src:src python -m pytest -q
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Production notes: [docs/production.md](docs/production.md).
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["poetry-core>=1.0.0"]
|
|
3
|
+
build-backend = "poetry.core.masonry.api"
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
[tool.poetry]
|
|
7
|
+
name = "muscles-asgi"
|
|
8
|
+
version = "1.0.0"
|
|
9
|
+
description = "Muscles ASGI runtime adapter for Web/API applications"
|
|
10
|
+
readme = "README.md"
|
|
11
|
+
authors = ["Denis B. <denis@butko.info>"]
|
|
12
|
+
license = "MIT"
|
|
13
|
+
packages = [{include = "muscles", from = "src"}]
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
[tool.poetry.dependencies]
|
|
17
|
+
python = ">=3.10,<4.0"
|
|
18
|
+
muscles = ">=1.0.0rc1,<2.0.0"
|
|
19
|
+
watchdog = "^4.0.0"
|
|
20
|
+
uwsgi = {version = "==2.0.20", optional = true}
|
|
21
|
+
jinja2 = "==3.1.2"
|
|
22
|
+
jsonschema = "==4.16.0"
|
|
23
|
+
python-magic = {version = "==0.4.27", optional = true}
|
|
24
|
+
requests = "^2.31.0"
|
|
25
|
+
requests-toolbelt = "^1.0.0"
|
|
26
|
+
dnspython = "==2.6.1"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
[tool.poetry.dev-dependencies]
|
|
30
|
+
pytest = "==7.1.3"
|
|
31
|
+
setuptools = "==69.0.2"
|
|
32
|
+
|
|
33
|
+
[tool.poetry.extras]
|
|
34
|
+
server = ["uwsgi"]
|
|
35
|
+
mime = ["python-magic"]
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Makefile
|
|
2
|
+
|
|
3
|
+
start:
|
|
4
|
+
docker-compose up -d
|
|
5
|
+
docker exec -it butkoinfo_core_1 bash
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
stop:
|
|
9
|
+
docker-compose up -d
|
|
10
|
+
docker exec -it butkoinfo-core-1 bash
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
console:
|
|
14
|
+
docker exec -it butkoinfo_core_1 bash
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
logs:
|
|
18
|
+
docker-compose logs
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
develop:
|
|
22
|
+
#docker exec -it butkoinfo_core_1 pipenv install
|
|
23
|
+
pipenv run python setup.py develop
|
|
24
|
+
pipenv install
|
|
25
|
+
|
|
26
|
+
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
from .asgi import *
|
|
2
|
+
from .watchdog import *
|
|
3
|
+
from .uwsgi import *
|
|
4
|
+
from .template import Template
|
|
5
|
+
from .template import *
|
|
6
|
+
from .restful import *
|
|
7
|
+
from .assets import *
|
|
8
|
+
from .app import MuscularAsgiApp, asgi_app
|
|
9
|
+
from .action_bridge import ActionAsgiAdapter
|
|
10
|
+
from .providers import AsgiGeneratorProvider
|
|
11
|
+
from .testing import TestClient, TestResponse
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
__all__ = (
|
|
15
|
+
"Asset",
|
|
16
|
+
"RestApi",
|
|
17
|
+
"finalize_api",
|
|
18
|
+
"mount_api",
|
|
19
|
+
"mount_application_apis",
|
|
20
|
+
"TemplateLoader",
|
|
21
|
+
"Filters",
|
|
22
|
+
"Template",
|
|
23
|
+
"UwsgiReload",
|
|
24
|
+
"Watchdog",
|
|
25
|
+
"PatternMatchingHandler",
|
|
26
|
+
"ResponseErrorHandler",
|
|
27
|
+
"AsgiStrategy",
|
|
28
|
+
"ImproperBodyPartContentException",
|
|
29
|
+
"NonMultipartContentTypeException",
|
|
30
|
+
"BodyPart",
|
|
31
|
+
"FileStorage",
|
|
32
|
+
"FieldStorage",
|
|
33
|
+
"Request",
|
|
34
|
+
"Response",
|
|
35
|
+
"BadResponse",
|
|
36
|
+
"BaseResponse",
|
|
37
|
+
"MakeResponse",
|
|
38
|
+
"JsonResponse",
|
|
39
|
+
"HtmlResponse",
|
|
40
|
+
"code_status",
|
|
41
|
+
"Transport",
|
|
42
|
+
"AsgiTransport",
|
|
43
|
+
"AsgiServer",
|
|
44
|
+
"RouteRule",
|
|
45
|
+
"RouteRuleDefault",
|
|
46
|
+
"RouteRuleVar",
|
|
47
|
+
"RouteRuleInt",
|
|
48
|
+
"RouteRuleFloat",
|
|
49
|
+
"Itinerary",
|
|
50
|
+
"Node",
|
|
51
|
+
"Routes",
|
|
52
|
+
"Api",
|
|
53
|
+
"api",
|
|
54
|
+
"routes",
|
|
55
|
+
"itinerary",
|
|
56
|
+
"MuscularAsgiApp",
|
|
57
|
+
"asgi_app",
|
|
58
|
+
"ActionAsgiAdapter",
|
|
59
|
+
"AsgiGeneratorProvider",
|
|
60
|
+
"TestClient",
|
|
61
|
+
"TestResponse",
|
|
62
|
+
)
|