dynamicforms-fastapi-viewsets 0.11.0__tar.gz → 0.11.1__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.
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/PKG-INFO +1 -1
- dynamicforms_fastapi_viewsets-0.11.1/fastapi_viewsets/__init__.py +1 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/decorators/celery_viewset/server.py +23 -4
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/middleware/__init__.py +3 -1
- dynamicforms_fastapi_viewsets-0.11.0/fastapi_viewsets/__init__.py +0 -1
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/.gitignore +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/LICENSE +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/README.md +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/action_configuration.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/backends/__init__.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/backends/django_orm.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/collection_viewset.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/conf.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/context/__init__.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/context/auth/__init__.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/context/auth/django.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/context/auth/jwt.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/context/auth/static.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/cursor.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/decorators/__init__.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/decorators/build_schema.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/decorators/celery_viewset/__init__.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/decorators/celery_viewset/client.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/decorators/celery_viewset/payload.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/decorators/celery_viewset/result_reader.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/decorators/conftest.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/decorators/lifecycle_runner.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/decorators/primary_key_model_helper.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/decorators/route_viewset.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/endpoint_docs.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/events/__init__.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/events/authorizers.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/events/changes.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/events/conftest.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/events/delivery.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/events/event.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/events/lifecycle.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/events/redis.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/events/sources.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/events/store.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/events/topics.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/events/viewset.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/exceptions.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/filters/__init__.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/filters/base.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/filters/declaration.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/filters/operators.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/filters/registry.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/list_query.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/list_shapes.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/middleware/auth/__init__.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/middleware/auth/authorization.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/middleware/idempotency.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/middleware/rate_limiter.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/mixins.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/mux_ws/__init__.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/mux_ws/asgi.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/mux_ws/protocol.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/mux_ws/registry.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/mux_ws/server.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/mux_ws/transports.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/py.typed +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/response_classes.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/routing.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/save_state/__init__.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/save_state/save_state.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/fastapi_viewsets/save_state/serialize_state.py +0 -0
- {dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/pyproject.toml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: dynamicforms-fastapi-viewsets
|
|
3
|
-
Version: 0.11.
|
|
3
|
+
Version: 0.11.1
|
|
4
4
|
Summary: Django REST Framework-style viewsets for FastAPI, with optional Celery-backed async execution and a Vue/TypeScript client counterpart.
|
|
5
5
|
Project-URL: Homepage, https://github.com/dynamicforms/fastapi-viewsets
|
|
6
6
|
Project-URL: Repository, https://github.com/dynamicforms/fastapi-viewsets
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.11.1"
|
|
@@ -200,16 +200,21 @@ class _Run:
|
|
|
200
200
|
One execution in this process. Maps the exceptions the executor raises into it to this
|
|
201
201
|
package's: a soft time limit and the gevent pool's hard time limit (`gevent.Timeout`) to
|
|
202
202
|
`ActionInterruptedError`, any other celery, billiard or kombu exception to `ActionFailedError`, and
|
|
203
|
-
the `asyncio.CancelledError` of an execution an interruption cancelled to that interruption
|
|
203
|
+
the `asyncio.CancelledError` of an execution an interruption cancelled to that interruption, or
|
|
204
|
+
to the `SystemExit` / `KeyboardInterrupt` of a process exit.
|
|
204
205
|
"""
|
|
205
206
|
|
|
206
207
|
def __init__(self, task: str):
|
|
207
208
|
self.task = task
|
|
208
|
-
self.interruption:
|
|
209
|
+
self.interruption: BaseException | None = None
|
|
209
210
|
self._interrupting: BaseException | None = None
|
|
210
211
|
|
|
211
212
|
def interrupted(self, error: BaseException) -> None:
|
|
212
213
|
"""Records `error`, which interrupted the loop while the execution was suspended."""
|
|
214
|
+
if isinstance(error, (KeyboardInterrupt, SystemExit)):
|
|
215
|
+
self.interruption = error
|
|
216
|
+
self._interrupting = error
|
|
217
|
+
return
|
|
213
218
|
translated = self.translate(error)
|
|
214
219
|
if isinstance(translated, ActionInterruptedError):
|
|
215
220
|
self.interruption = translated
|
|
@@ -286,6 +291,13 @@ def _event_loop() -> asyncio.AbstractEventLoop:
|
|
|
286
291
|
return loop
|
|
287
292
|
|
|
288
293
|
|
|
294
|
+
def _supervised() -> bool:
|
|
295
|
+
"""Whether this process is a pool child that billiard started, whose supervisor outlives it."""
|
|
296
|
+
from billiard.process import current_process
|
|
297
|
+
|
|
298
|
+
return getattr(current_process(), "_parent_pid", None) is not None
|
|
299
|
+
|
|
300
|
+
|
|
289
301
|
_started_pid: int | None = None
|
|
290
302
|
_started_loops: "weakref.WeakSet[asyncio.AbstractEventLoop]" = weakref.WeakSet()
|
|
291
303
|
_started_lock = threading.Lock()
|
|
@@ -564,7 +576,8 @@ def celery_viewset_server(
|
|
|
564
576
|
one as `ActionFailedError`. The
|
|
565
577
|
worker's supervisor reports what ends an execution from outside it (a hard time limit, a
|
|
566
578
|
termination, a lost process) and a call that never runs (revoked, expired, unknown, rejected)
|
|
567
|
-
to the caller and to `Middleware.on_transition()
|
|
579
|
+
to the caller and to `Middleware.on_transition()`; a process no supervisor outlives (any pool but
|
|
580
|
+
`prefork`) reports its own exit as `interrupted` with reason `terminated`.
|
|
568
581
|
"""
|
|
569
582
|
if redis_client is None:
|
|
570
583
|
raise ValueError("redis_client is required for celery_viewset_server")
|
|
@@ -641,6 +654,10 @@ def celery_viewset_server(
|
|
|
641
654
|
translated error, or a process exit as it is. An `HTTPException` the action raised is its
|
|
642
655
|
answer and is not re-raised.
|
|
643
656
|
|
|
657
|
+
A process exit is reported as `interrupted` with reason `terminated` where no supervisor
|
|
658
|
+
outlives the process (any process but a prefork pool child); a prefork pool child's
|
|
659
|
+
supervisor reports it.
|
|
660
|
+
|
|
644
661
|
The gevent pool's hard time limit is reported here as the supervisor reports another
|
|
645
662
|
pool's, as `interrupted` with reason `time_limit`, and its `gevent.Timeout` is re-raised
|
|
646
663
|
as it is: the pool handles the time limit only when that exception reaches it."""
|
|
@@ -678,7 +695,9 @@ def celery_viewset_server(
|
|
|
678
695
|
pushed.status_code,
|
|
679
696
|
pushed.detail,
|
|
680
697
|
)
|
|
681
|
-
if
|
|
698
|
+
if process_exit and not _supervised():
|
|
699
|
+
_report("interrupted", task_name, call, lambda _t: pushed)
|
|
700
|
+
elif correlation_id and result_queue_key:
|
|
682
701
|
push_payload(redis_client, result_queue_key, error_payload(correlation_id, task_name, pushed))
|
|
683
702
|
if process_exit:
|
|
684
703
|
raise caught
|
|
@@ -253,7 +253,9 @@ class Middleware(ABC):
|
|
|
253
253
|
action itself sees `asyncio.CancelledError` in the latter case. An execution the executor
|
|
254
254
|
ends from outside (a hard time limit, a termination, a lost process) ends its process:
|
|
255
255
|
`call_next()` raises `SystemExit` where the process is stopped with SIGTERM and has time to
|
|
256
|
-
unwind,
|
|
256
|
+
unwind, whether the action was running or suspended at an `await`, and nothing at all where it
|
|
257
|
+
is killed. `on_transition()` reports it either way: the supervisor of a prefork pool child, or
|
|
258
|
+
the exiting process itself where no supervisor outlives it. In a
|
|
257
259
|
gevent pool a hard time limit ends the execution only and reaches `call_next()` as
|
|
258
260
|
`ActionInterruptedError`.
|
|
259
261
|
"""
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.11.0"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{dynamicforms_fastapi_viewsets-0.11.0 → dynamicforms_fastapi_viewsets-0.11.1}/pyproject.toml
RENAMED
|
File without changes
|