queueflow 0.2.2__tar.gz → 0.3.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.
- {queueflow-0.2.2/queueflow.egg-info → queueflow-0.3.0}/PKG-INFO +46 -4
- {queueflow-0.2.2 → queueflow-0.3.0}/README.md +45 -3
- {queueflow-0.2.2 → queueflow-0.3.0}/pyproject.toml +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/__init__.py +4 -2
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/api/cron_api.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/api/dlq_api.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/api/health_api.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/api/jobs_api.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/api/system_api.py +245 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/api/worker_api.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/api/workflows_api.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/api_client.py +2 -2
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/configuration.py +3 -3
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/exceptions.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/facade.py +214 -41
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/models/__init__.py +3 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/models/backoff_strategy.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/models/complete_job_request.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/models/create_batch_jobs_request.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/models/create_batch_jobs_response.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/models/create_cron_request.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/models/create_cron_response.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/models/create_job_request.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/models/create_job_response.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/models/create_workflow_request.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/models/create_workflow_response.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/models/cron_schedule.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/models/dead_letter.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/models/error_body.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/models/fail_job_request.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/models/health_status.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/models/heartbeat_request.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/models/heartbeat_response.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/models/job.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/models/job_config.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/models/job_config_request.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/models/job_status.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/models/lease_jobs_request.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/models/lease_jobs_response.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/models/leased_job.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/models/list_crons_response.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/models/list_dead_letters_response.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/models/list_jobs_response.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/models/list_workflows_response.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/models/on_failure.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/models/on_success.py +1 -1
- queueflow-0.3.0/queueflow/models/queue_stats.py +101 -0
- queueflow-0.3.0/queueflow/models/queues_response.py +95 -0
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/models/ready_status.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/models/replay_dead_letter_response.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/models/stats_snapshot.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/models/step_status.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/models/tasks_response.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/models/workflow.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/models/workflow_diagram_response.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/models/workflow_status.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/models/workflow_step.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/models/workflow_step_state.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/models/workflow_step_states_response.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/rest.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0/queueflow.egg-info}/PKG-INFO +46 -4
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow.egg-info/SOURCES.txt +4 -0
- {queueflow-0.2.2 → queueflow-0.3.0}/setup.py +3 -3
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_backoff_strategy.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_complete_job_request.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_create_batch_jobs_request.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_create_batch_jobs_response.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_create_cron_request.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_create_cron_response.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_create_job_request.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_create_job_response.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_create_workflow_request.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_create_workflow_response.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_cron_api.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_cron_schedule.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_dead_letter.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_dlq_api.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_error_body.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_facade.py +245 -3
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_fail_job_request.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_health_api.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_health_status.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_heartbeat_request.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_heartbeat_response.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_job.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_job_config.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_job_config_request.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_job_status.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_jobs_api.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_lease_jobs_request.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_lease_jobs_response.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_leased_job.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_list_crons_response.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_list_dead_letters_response.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_list_jobs_response.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_list_workflows_response.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_live.py +62 -0
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_on_failure.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_on_success.py +1 -1
- queueflow-0.3.0/test/test_queue_stats.py +59 -0
- queueflow-0.3.0/test/test_queues_response.py +66 -0
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_ready_status.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_replay_dead_letter_response.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_stats_snapshot.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_step_status.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_system_api.py +7 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_tasks_response.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_worker_api.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_workflow.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_workflow_diagram_response.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_workflow_status.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_workflow_step.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_workflow_step_state.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_workflow_step_states_response.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/test/test_workflows_api.py +1 -1
- {queueflow-0.2.2 → queueflow-0.3.0}/LICENSE +0 -0
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/api/__init__.py +0 -0
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/api_response.py +0 -0
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow/py.typed +0 -0
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow.egg-info/dependency_links.txt +0 -0
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow.egg-info/requires.txt +0 -0
- {queueflow-0.2.2 → queueflow-0.3.0}/queueflow.egg-info/top_level.txt +0 -0
- {queueflow-0.2.2 → queueflow-0.3.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: queueflow
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Python client for QueueFlow, a PostgreSQL-native distributed job queue and workflow engine.
|
|
5
5
|
Home-page: https://github.com/elision-labs/queueflow-sdk-python
|
|
6
6
|
Author: QueueFlow
|
|
@@ -93,9 +93,12 @@ qf = QueueFlow(
|
|
|
93
93
|
base_url, # required, e.g. "http://localhost:8000"
|
|
94
94
|
token, # required: tenant bearer token (any non-empty token on the dev server)
|
|
95
95
|
worker_token=None, # credential for qf.worker and run_worker (defaults to token; dev mode only)
|
|
96
|
+
timeout=30.0, # default per-request timeout in seconds; a (connect, read) pair or None also work
|
|
96
97
|
)
|
|
97
98
|
```
|
|
98
99
|
|
|
100
|
+
Any generated api method accepts `_request_timeout=` to override the default for one call.
|
|
101
|
+
|
|
99
102
|
The generated per-tag clients hang off the facade for anything the helpers do not cover:
|
|
100
103
|
`qf.jobs`, `qf.workflows`, `qf.worker`, `qf.cron`, `qf.dlq`, `qf.system`, `qf.health_api`.
|
|
101
104
|
|
|
@@ -168,16 +171,50 @@ def transcode(job, ctx):
|
|
|
168
171
|
return {"ok": True}
|
|
169
172
|
|
|
170
173
|
stop = threading.Event() # set it (e.g. from a signal handler) to drain
|
|
171
|
-
qf.run_worker(
|
|
174
|
+
result = qf.run_worker(
|
|
175
|
+
"orders",
|
|
176
|
+
{"send_email": send_email, "transcode": transcode},
|
|
177
|
+
stop=stop,
|
|
178
|
+
concurrency=4,
|
|
179
|
+
)
|
|
180
|
+
for job in result.unfinished: # handlers still running when the drain gave up
|
|
181
|
+
print("abandoned", job.id)
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
```python
|
|
185
|
+
run_worker(
|
|
186
|
+
queue, handlers,
|
|
187
|
+
lease_secs=30, # lease per job; each in-flight job is heartbeated at half this
|
|
188
|
+
wait_secs=20, # long-poll wait when the queue is empty
|
|
189
|
+
stop=None, # threading.Event: set it to stop
|
|
190
|
+
on_error=None, # called on transient lease errors (default: throttled log)
|
|
191
|
+
concurrency=1, # handlers running at once, on a ThreadPoolExecutor
|
|
192
|
+
poll_wait_secs=5, # cap on wait_secs while `stop` is provided (bounds stop latency)
|
|
193
|
+
drain_timeout=30.0, # seconds to wait for in-flight handlers after stop
|
|
194
|
+
) -> WorkerRunResult # .unfinished: jobs still running when the drain gave up
|
|
172
195
|
```
|
|
173
196
|
|
|
174
|
-
`run_worker
|
|
175
|
-
job at a time, heartbeats each in-flight job at half the lease interval, stops reporting when the
|
|
197
|
+
`run_worker` heartbeats each in-flight job at half the lease interval, stops reporting when the
|
|
176
198
|
lease is lost, and applies the server's retry policy on errors. Handlers take `(job)` or
|
|
177
199
|
`(job, ctx)` and return the result dict (or `None` for `{}`). Delivery is at-least-once, so make
|
|
178
200
|
handlers idempotent. The low-level calls (`qf.worker.lease_jobs`, `heartbeat_job`, `complete_job`,
|
|
179
201
|
`fail_job`) are also exposed.
|
|
180
202
|
|
|
203
|
+
Concurrency: up to `concurrency` handlers run at once. Each lease asks for as many jobs as there
|
|
204
|
+
are free slots, and no lease is issued while every slot is busy.
|
|
205
|
+
|
|
206
|
+
Stop and drain: set `stop`. The generated urllib3 client cannot cancel an in-flight long poll, so
|
|
207
|
+
while `stop` is provided each lease waits at most `poll_wait_secs` (never more than `wait_secs`),
|
|
208
|
+
which bounds stop latency to about that long; without `stop`, the full `wait_secs` is used. After
|
|
209
|
+
the loop exits, handlers already running get up to `drain_timeout` seconds to finish and report.
|
|
210
|
+
Any handler still running after that is abandoned: its `ctx.cancelled` flips, nothing is reported
|
|
211
|
+
(the lease expires and the server redelivers), and the job is listed in the returned
|
|
212
|
+
`WorkerRunResult.unfinished`. Python cannot kill a thread, so an abandoned handler keeps its pool
|
|
213
|
+
thread until it returns; long handlers should check `ctx.cancelled`.
|
|
214
|
+
|
|
215
|
+
Timeouts: every request uses the client-wide `timeout` (30s by default, see Client), except the
|
|
216
|
+
lease long poll, which gets its own timeout of the effective wait plus 35 seconds.
|
|
217
|
+
|
|
181
218
|
Rules the runtime enforces, and that any hand-rolled loop over `qf.worker` must honour too:
|
|
182
219
|
|
|
183
220
|
1. Worker routes authenticate with the **worker token**, not a tenant token. Pass it as
|
|
@@ -209,10 +246,15 @@ Rules the runtime enforces, and that any hand-rolled loop over `qf.worker` must
|
|
|
209
246
|
```python
|
|
210
247
|
qf.system.get_stats() # engine counters
|
|
211
248
|
qf.system.list_tasks() # registered task handler names
|
|
249
|
+
qf.queues() # live per-queue backlog: pending, scheduled, running, oldest pending age
|
|
212
250
|
qf.health_api.get_health()
|
|
213
251
|
qf.health_api.get_ready()
|
|
214
252
|
```
|
|
215
253
|
|
|
254
|
+
`qf.queues()` (`GET /api/v1/queues`) returns a `QueueStats` per queue that currently has
|
|
255
|
+
non-terminal jobs, so you can decide whether to add workers; idle queues are omitted.
|
|
256
|
+
`qf.system.list_queues()` is the raw call.
|
|
257
|
+
|
|
216
258
|
## Authentication
|
|
217
259
|
|
|
218
260
|
Every request carries `Authorization: Bearer <token>`. Two credentials exist:
|
|
@@ -52,9 +52,12 @@ qf = QueueFlow(
|
|
|
52
52
|
base_url, # required, e.g. "http://localhost:8000"
|
|
53
53
|
token, # required: tenant bearer token (any non-empty token on the dev server)
|
|
54
54
|
worker_token=None, # credential for qf.worker and run_worker (defaults to token; dev mode only)
|
|
55
|
+
timeout=30.0, # default per-request timeout in seconds; a (connect, read) pair or None also work
|
|
55
56
|
)
|
|
56
57
|
```
|
|
57
58
|
|
|
59
|
+
Any generated api method accepts `_request_timeout=` to override the default for one call.
|
|
60
|
+
|
|
58
61
|
The generated per-tag clients hang off the facade for anything the helpers do not cover:
|
|
59
62
|
`qf.jobs`, `qf.workflows`, `qf.worker`, `qf.cron`, `qf.dlq`, `qf.system`, `qf.health_api`.
|
|
60
63
|
|
|
@@ -127,16 +130,50 @@ def transcode(job, ctx):
|
|
|
127
130
|
return {"ok": True}
|
|
128
131
|
|
|
129
132
|
stop = threading.Event() # set it (e.g. from a signal handler) to drain
|
|
130
|
-
qf.run_worker(
|
|
133
|
+
result = qf.run_worker(
|
|
134
|
+
"orders",
|
|
135
|
+
{"send_email": send_email, "transcode": transcode},
|
|
136
|
+
stop=stop,
|
|
137
|
+
concurrency=4,
|
|
138
|
+
)
|
|
139
|
+
for job in result.unfinished: # handlers still running when the drain gave up
|
|
140
|
+
print("abandoned", job.id)
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
```python
|
|
144
|
+
run_worker(
|
|
145
|
+
queue, handlers,
|
|
146
|
+
lease_secs=30, # lease per job; each in-flight job is heartbeated at half this
|
|
147
|
+
wait_secs=20, # long-poll wait when the queue is empty
|
|
148
|
+
stop=None, # threading.Event: set it to stop
|
|
149
|
+
on_error=None, # called on transient lease errors (default: throttled log)
|
|
150
|
+
concurrency=1, # handlers running at once, on a ThreadPoolExecutor
|
|
151
|
+
poll_wait_secs=5, # cap on wait_secs while `stop` is provided (bounds stop latency)
|
|
152
|
+
drain_timeout=30.0, # seconds to wait for in-flight handlers after stop
|
|
153
|
+
) -> WorkerRunResult # .unfinished: jobs still running when the drain gave up
|
|
131
154
|
```
|
|
132
155
|
|
|
133
|
-
`run_worker
|
|
134
|
-
job at a time, heartbeats each in-flight job at half the lease interval, stops reporting when the
|
|
156
|
+
`run_worker` heartbeats each in-flight job at half the lease interval, stops reporting when the
|
|
135
157
|
lease is lost, and applies the server's retry policy on errors. Handlers take `(job)` or
|
|
136
158
|
`(job, ctx)` and return the result dict (or `None` for `{}`). Delivery is at-least-once, so make
|
|
137
159
|
handlers idempotent. The low-level calls (`qf.worker.lease_jobs`, `heartbeat_job`, `complete_job`,
|
|
138
160
|
`fail_job`) are also exposed.
|
|
139
161
|
|
|
162
|
+
Concurrency: up to `concurrency` handlers run at once. Each lease asks for as many jobs as there
|
|
163
|
+
are free slots, and no lease is issued while every slot is busy.
|
|
164
|
+
|
|
165
|
+
Stop and drain: set `stop`. The generated urllib3 client cannot cancel an in-flight long poll, so
|
|
166
|
+
while `stop` is provided each lease waits at most `poll_wait_secs` (never more than `wait_secs`),
|
|
167
|
+
which bounds stop latency to about that long; without `stop`, the full `wait_secs` is used. After
|
|
168
|
+
the loop exits, handlers already running get up to `drain_timeout` seconds to finish and report.
|
|
169
|
+
Any handler still running after that is abandoned: its `ctx.cancelled` flips, nothing is reported
|
|
170
|
+
(the lease expires and the server redelivers), and the job is listed in the returned
|
|
171
|
+
`WorkerRunResult.unfinished`. Python cannot kill a thread, so an abandoned handler keeps its pool
|
|
172
|
+
thread until it returns; long handlers should check `ctx.cancelled`.
|
|
173
|
+
|
|
174
|
+
Timeouts: every request uses the client-wide `timeout` (30s by default, see Client), except the
|
|
175
|
+
lease long poll, which gets its own timeout of the effective wait plus 35 seconds.
|
|
176
|
+
|
|
140
177
|
Rules the runtime enforces, and that any hand-rolled loop over `qf.worker` must honour too:
|
|
141
178
|
|
|
142
179
|
1. Worker routes authenticate with the **worker token**, not a tenant token. Pass it as
|
|
@@ -168,10 +205,15 @@ Rules the runtime enforces, and that any hand-rolled loop over `qf.worker` must
|
|
|
168
205
|
```python
|
|
169
206
|
qf.system.get_stats() # engine counters
|
|
170
207
|
qf.system.list_tasks() # registered task handler names
|
|
208
|
+
qf.queues() # live per-queue backlog: pending, scheduled, running, oldest pending age
|
|
171
209
|
qf.health_api.get_health()
|
|
172
210
|
qf.health_api.get_ready()
|
|
173
211
|
```
|
|
174
212
|
|
|
213
|
+
`qf.queues()` (`GET /api/v1/queues`) returns a `QueueStats` per queue that currently has
|
|
214
|
+
non-terminal jobs, so you can decide whether to add workers; idle queues are omitted.
|
|
215
|
+
`qf.system.list_queues()` is the raw call.
|
|
216
|
+
|
|
175
217
|
## Authentication
|
|
176
218
|
|
|
177
219
|
Every request carries `Authorization: Bearer <token>`. Two credentials exist:
|
|
@@ -7,14 +7,14 @@
|
|
|
7
7
|
|
|
8
8
|
REST API for QueueFlow, a PostgreSQL-native distributed job queue and workflow engine.
|
|
9
9
|
|
|
10
|
-
The version of the OpenAPI document:
|
|
10
|
+
The version of the OpenAPI document: 0.2.0
|
|
11
11
|
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
|
12
12
|
|
|
13
13
|
Do not edit the class manually.
|
|
14
14
|
""" # noqa: E501
|
|
15
15
|
|
|
16
16
|
|
|
17
|
-
__version__ = "0.
|
|
17
|
+
__version__ = "0.3.0"
|
|
18
18
|
|
|
19
19
|
# import apis into sdk package
|
|
20
20
|
from queueflow.api.cron_api import CronApi
|
|
@@ -67,6 +67,8 @@ from queueflow.models.list_jobs_response import ListJobsResponse
|
|
|
67
67
|
from queueflow.models.list_workflows_response import ListWorkflowsResponse
|
|
68
68
|
from queueflow.models.on_failure import OnFailure
|
|
69
69
|
from queueflow.models.on_success import OnSuccess
|
|
70
|
+
from queueflow.models.queue_stats import QueueStats
|
|
71
|
+
from queueflow.models.queues_response import QueuesResponse
|
|
70
72
|
from queueflow.models.ready_status import ReadyStatus
|
|
71
73
|
from queueflow.models.replay_dead_letter_response import ReplayDeadLetterResponse
|
|
72
74
|
from queueflow.models.stats_snapshot import StatsSnapshot
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
REST API for QueueFlow, a PostgreSQL-native distributed job queue and workflow engine.
|
|
7
7
|
|
|
8
|
-
The version of the OpenAPI document:
|
|
8
|
+
The version of the OpenAPI document: 0.2.0
|
|
9
9
|
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
|
10
10
|
|
|
11
11
|
Do not edit the class manually.
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
REST API for QueueFlow, a PostgreSQL-native distributed job queue and workflow engine.
|
|
7
7
|
|
|
8
|
-
The version of the OpenAPI document:
|
|
8
|
+
The version of the OpenAPI document: 0.2.0
|
|
9
9
|
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
|
10
10
|
|
|
11
11
|
Do not edit the class manually.
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
REST API for QueueFlow, a PostgreSQL-native distributed job queue and workflow engine.
|
|
7
7
|
|
|
8
|
-
The version of the OpenAPI document:
|
|
8
|
+
The version of the OpenAPI document: 0.2.0
|
|
9
9
|
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
|
10
10
|
|
|
11
11
|
Do not edit the class manually.
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
REST API for QueueFlow, a PostgreSQL-native distributed job queue and workflow engine.
|
|
7
7
|
|
|
8
|
-
The version of the OpenAPI document:
|
|
8
|
+
The version of the OpenAPI document: 0.2.0
|
|
9
9
|
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
|
10
10
|
|
|
11
11
|
Do not edit the class manually.
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
REST API for QueueFlow, a PostgreSQL-native distributed job queue and workflow engine.
|
|
7
7
|
|
|
8
|
-
The version of the OpenAPI document:
|
|
8
|
+
The version of the OpenAPI document: 0.2.0
|
|
9
9
|
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
|
10
10
|
|
|
11
11
|
Do not edit the class manually.
|
|
@@ -16,6 +16,7 @@ from pydantic import validate_call, Field, StrictFloat, StrictStr, StrictInt
|
|
|
16
16
|
from typing import Any, Dict, List, Optional, Tuple, Union
|
|
17
17
|
from typing_extensions import Annotated
|
|
18
18
|
|
|
19
|
+
from queueflow.models.queues_response import QueuesResponse
|
|
19
20
|
from queueflow.models.stats_snapshot import StatsSnapshot
|
|
20
21
|
from queueflow.models.tasks_response import TasksResponse
|
|
21
22
|
|
|
@@ -280,6 +281,249 @@ class SystemApi:
|
|
|
280
281
|
|
|
281
282
|
|
|
282
283
|
|
|
284
|
+
@validate_call
|
|
285
|
+
def list_queues(
|
|
286
|
+
self,
|
|
287
|
+
_request_timeout: Union[
|
|
288
|
+
None,
|
|
289
|
+
Annotated[StrictFloat, Field(gt=0)],
|
|
290
|
+
Tuple[
|
|
291
|
+
Annotated[StrictFloat, Field(gt=0)],
|
|
292
|
+
Annotated[StrictFloat, Field(gt=0)]
|
|
293
|
+
]
|
|
294
|
+
] = None,
|
|
295
|
+
_request_auth: Optional[Dict[StrictStr, Any]] = None,
|
|
296
|
+
_content_type: Optional[StrictStr] = None,
|
|
297
|
+
_headers: Optional[Dict[StrictStr, Any]] = None,
|
|
298
|
+
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
|
|
299
|
+
) -> QueuesResponse:
|
|
300
|
+
"""list_queues
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
:param _request_timeout: timeout setting for this request. If one
|
|
304
|
+
number provided, it will be total request
|
|
305
|
+
timeout. It can also be a pair (tuple) of
|
|
306
|
+
(connection, read) timeouts.
|
|
307
|
+
:type _request_timeout: int, tuple(int, int), optional
|
|
308
|
+
:param _request_auth: set to override the auth_settings for an a single
|
|
309
|
+
request; this effectively ignores the
|
|
310
|
+
authentication in the spec for a single request.
|
|
311
|
+
:type _request_auth: dict, optional
|
|
312
|
+
:param _content_type: force content-type for the request.
|
|
313
|
+
:type _content_type: str, Optional
|
|
314
|
+
:param _headers: set to override the headers for a single
|
|
315
|
+
request; this effectively ignores the headers
|
|
316
|
+
in the spec for a single request.
|
|
317
|
+
:type _headers: dict, optional
|
|
318
|
+
:param _host_index: set to override the host_index for a single
|
|
319
|
+
request; this effectively ignores the host_index
|
|
320
|
+
in the spec for a single request.
|
|
321
|
+
:type _host_index: int, optional
|
|
322
|
+
:return: Returns the result object.
|
|
323
|
+
""" # noqa: E501
|
|
324
|
+
|
|
325
|
+
_param = self._list_queues_serialize(
|
|
326
|
+
_request_auth=_request_auth,
|
|
327
|
+
_content_type=_content_type,
|
|
328
|
+
_headers=_headers,
|
|
329
|
+
_host_index=_host_index
|
|
330
|
+
)
|
|
331
|
+
|
|
332
|
+
_response_types_map: Dict[str, Optional[str]] = {
|
|
333
|
+
'200': "QueuesResponse",
|
|
334
|
+
}
|
|
335
|
+
response_data = self.api_client.call_api(
|
|
336
|
+
*_param,
|
|
337
|
+
_request_timeout=_request_timeout
|
|
338
|
+
)
|
|
339
|
+
response_data.read()
|
|
340
|
+
return self.api_client.response_deserialize(
|
|
341
|
+
response_data=response_data,
|
|
342
|
+
response_types_map=_response_types_map,
|
|
343
|
+
).data
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
@validate_call
|
|
347
|
+
def list_queues_with_http_info(
|
|
348
|
+
self,
|
|
349
|
+
_request_timeout: Union[
|
|
350
|
+
None,
|
|
351
|
+
Annotated[StrictFloat, Field(gt=0)],
|
|
352
|
+
Tuple[
|
|
353
|
+
Annotated[StrictFloat, Field(gt=0)],
|
|
354
|
+
Annotated[StrictFloat, Field(gt=0)]
|
|
355
|
+
]
|
|
356
|
+
] = None,
|
|
357
|
+
_request_auth: Optional[Dict[StrictStr, Any]] = None,
|
|
358
|
+
_content_type: Optional[StrictStr] = None,
|
|
359
|
+
_headers: Optional[Dict[StrictStr, Any]] = None,
|
|
360
|
+
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
|
|
361
|
+
) -> ApiResponse[QueuesResponse]:
|
|
362
|
+
"""list_queues
|
|
363
|
+
|
|
364
|
+
|
|
365
|
+
:param _request_timeout: timeout setting for this request. If one
|
|
366
|
+
number provided, it will be total request
|
|
367
|
+
timeout. It can also be a pair (tuple) of
|
|
368
|
+
(connection, read) timeouts.
|
|
369
|
+
:type _request_timeout: int, tuple(int, int), optional
|
|
370
|
+
:param _request_auth: set to override the auth_settings for an a single
|
|
371
|
+
request; this effectively ignores the
|
|
372
|
+
authentication in the spec for a single request.
|
|
373
|
+
:type _request_auth: dict, optional
|
|
374
|
+
:param _content_type: force content-type for the request.
|
|
375
|
+
:type _content_type: str, Optional
|
|
376
|
+
:param _headers: set to override the headers for a single
|
|
377
|
+
request; this effectively ignores the headers
|
|
378
|
+
in the spec for a single request.
|
|
379
|
+
:type _headers: dict, optional
|
|
380
|
+
:param _host_index: set to override the host_index for a single
|
|
381
|
+
request; this effectively ignores the host_index
|
|
382
|
+
in the spec for a single request.
|
|
383
|
+
:type _host_index: int, optional
|
|
384
|
+
:return: Returns the result object.
|
|
385
|
+
""" # noqa: E501
|
|
386
|
+
|
|
387
|
+
_param = self._list_queues_serialize(
|
|
388
|
+
_request_auth=_request_auth,
|
|
389
|
+
_content_type=_content_type,
|
|
390
|
+
_headers=_headers,
|
|
391
|
+
_host_index=_host_index
|
|
392
|
+
)
|
|
393
|
+
|
|
394
|
+
_response_types_map: Dict[str, Optional[str]] = {
|
|
395
|
+
'200': "QueuesResponse",
|
|
396
|
+
}
|
|
397
|
+
response_data = self.api_client.call_api(
|
|
398
|
+
*_param,
|
|
399
|
+
_request_timeout=_request_timeout
|
|
400
|
+
)
|
|
401
|
+
response_data.read()
|
|
402
|
+
return self.api_client.response_deserialize(
|
|
403
|
+
response_data=response_data,
|
|
404
|
+
response_types_map=_response_types_map,
|
|
405
|
+
)
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
@validate_call
|
|
409
|
+
def list_queues_without_preload_content(
|
|
410
|
+
self,
|
|
411
|
+
_request_timeout: Union[
|
|
412
|
+
None,
|
|
413
|
+
Annotated[StrictFloat, Field(gt=0)],
|
|
414
|
+
Tuple[
|
|
415
|
+
Annotated[StrictFloat, Field(gt=0)],
|
|
416
|
+
Annotated[StrictFloat, Field(gt=0)]
|
|
417
|
+
]
|
|
418
|
+
] = None,
|
|
419
|
+
_request_auth: Optional[Dict[StrictStr, Any]] = None,
|
|
420
|
+
_content_type: Optional[StrictStr] = None,
|
|
421
|
+
_headers: Optional[Dict[StrictStr, Any]] = None,
|
|
422
|
+
_host_index: Annotated[StrictInt, Field(ge=0, le=0)] = 0,
|
|
423
|
+
) -> RESTResponseType:
|
|
424
|
+
"""list_queues
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
:param _request_timeout: timeout setting for this request. If one
|
|
428
|
+
number provided, it will be total request
|
|
429
|
+
timeout. It can also be a pair (tuple) of
|
|
430
|
+
(connection, read) timeouts.
|
|
431
|
+
:type _request_timeout: int, tuple(int, int), optional
|
|
432
|
+
:param _request_auth: set to override the auth_settings for an a single
|
|
433
|
+
request; this effectively ignores the
|
|
434
|
+
authentication in the spec for a single request.
|
|
435
|
+
:type _request_auth: dict, optional
|
|
436
|
+
:param _content_type: force content-type for the request.
|
|
437
|
+
:type _content_type: str, Optional
|
|
438
|
+
:param _headers: set to override the headers for a single
|
|
439
|
+
request; this effectively ignores the headers
|
|
440
|
+
in the spec for a single request.
|
|
441
|
+
:type _headers: dict, optional
|
|
442
|
+
:param _host_index: set to override the host_index for a single
|
|
443
|
+
request; this effectively ignores the host_index
|
|
444
|
+
in the spec for a single request.
|
|
445
|
+
:type _host_index: int, optional
|
|
446
|
+
:return: Returns the result object.
|
|
447
|
+
""" # noqa: E501
|
|
448
|
+
|
|
449
|
+
_param = self._list_queues_serialize(
|
|
450
|
+
_request_auth=_request_auth,
|
|
451
|
+
_content_type=_content_type,
|
|
452
|
+
_headers=_headers,
|
|
453
|
+
_host_index=_host_index
|
|
454
|
+
)
|
|
455
|
+
|
|
456
|
+
_response_types_map: Dict[str, Optional[str]] = {
|
|
457
|
+
'200': "QueuesResponse",
|
|
458
|
+
}
|
|
459
|
+
response_data = self.api_client.call_api(
|
|
460
|
+
*_param,
|
|
461
|
+
_request_timeout=_request_timeout
|
|
462
|
+
)
|
|
463
|
+
return response_data.response
|
|
464
|
+
|
|
465
|
+
|
|
466
|
+
def _list_queues_serialize(
|
|
467
|
+
self,
|
|
468
|
+
_request_auth,
|
|
469
|
+
_content_type,
|
|
470
|
+
_headers,
|
|
471
|
+
_host_index,
|
|
472
|
+
) -> RequestSerialized:
|
|
473
|
+
|
|
474
|
+
_host = None
|
|
475
|
+
|
|
476
|
+
_collection_formats: Dict[str, str] = {
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
_path_params: Dict[str, str] = {}
|
|
480
|
+
_query_params: List[Tuple[str, str]] = []
|
|
481
|
+
_header_params: Dict[str, Optional[str]] = _headers or {}
|
|
482
|
+
_form_params: List[Tuple[str, str]] = []
|
|
483
|
+
_files: Dict[
|
|
484
|
+
str, Union[str, bytes, List[str], List[bytes], List[Tuple[str, bytes]]]
|
|
485
|
+
] = {}
|
|
486
|
+
_body_params: Optional[bytes] = None
|
|
487
|
+
|
|
488
|
+
# process the path parameters
|
|
489
|
+
# process the query parameters
|
|
490
|
+
# process the header parameters
|
|
491
|
+
# process the form parameters
|
|
492
|
+
# process the body parameter
|
|
493
|
+
|
|
494
|
+
|
|
495
|
+
# set the HTTP header `Accept`
|
|
496
|
+
if 'Accept' not in _header_params:
|
|
497
|
+
_header_params['Accept'] = self.api_client.select_header_accept(
|
|
498
|
+
[
|
|
499
|
+
'application/json'
|
|
500
|
+
]
|
|
501
|
+
)
|
|
502
|
+
|
|
503
|
+
|
|
504
|
+
# authentication setting
|
|
505
|
+
_auth_settings: List[str] = [
|
|
506
|
+
'bearerAuth'
|
|
507
|
+
]
|
|
508
|
+
|
|
509
|
+
return self.api_client.param_serialize(
|
|
510
|
+
method='GET',
|
|
511
|
+
resource_path='/api/v1/queues',
|
|
512
|
+
path_params=_path_params,
|
|
513
|
+
query_params=_query_params,
|
|
514
|
+
header_params=_header_params,
|
|
515
|
+
body=_body_params,
|
|
516
|
+
post_params=_form_params,
|
|
517
|
+
files=_files,
|
|
518
|
+
auth_settings=_auth_settings,
|
|
519
|
+
collection_formats=_collection_formats,
|
|
520
|
+
_host=_host,
|
|
521
|
+
_request_auth=_request_auth
|
|
522
|
+
)
|
|
523
|
+
|
|
524
|
+
|
|
525
|
+
|
|
526
|
+
|
|
283
527
|
@validate_call
|
|
284
528
|
def list_tasks(
|
|
285
529
|
self,
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
REST API for QueueFlow, a PostgreSQL-native distributed job queue and workflow engine.
|
|
7
7
|
|
|
8
|
-
The version of the OpenAPI document:
|
|
8
|
+
The version of the OpenAPI document: 0.2.0
|
|
9
9
|
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
|
10
10
|
|
|
11
11
|
Do not edit the class manually.
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
REST API for QueueFlow, a PostgreSQL-native distributed job queue and workflow engine.
|
|
7
7
|
|
|
8
|
-
The version of the OpenAPI document:
|
|
8
|
+
The version of the OpenAPI document: 0.2.0
|
|
9
9
|
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
|
10
10
|
|
|
11
11
|
Do not edit the class manually.
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
REST API for QueueFlow, a PostgreSQL-native distributed job queue and workflow engine.
|
|
7
7
|
|
|
8
|
-
The version of the OpenAPI document:
|
|
8
|
+
The version of the OpenAPI document: 0.2.0
|
|
9
9
|
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
|
10
10
|
|
|
11
11
|
Do not edit the class manually.
|
|
@@ -90,7 +90,7 @@ class ApiClient:
|
|
|
90
90
|
self.default_headers[header_name] = header_value
|
|
91
91
|
self.cookie = cookie
|
|
92
92
|
# Set default User-Agent.
|
|
93
|
-
self.user_agent = 'OpenAPI-Generator/0.
|
|
93
|
+
self.user_agent = 'OpenAPI-Generator/0.3.0/python'
|
|
94
94
|
self.client_side_validation = configuration.client_side_validation
|
|
95
95
|
|
|
96
96
|
def __enter__(self):
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
REST API for QueueFlow, a PostgreSQL-native distributed job queue and workflow engine.
|
|
7
7
|
|
|
8
|
-
The version of the OpenAPI document:
|
|
8
|
+
The version of the OpenAPI document: 0.2.0
|
|
9
9
|
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
|
10
10
|
|
|
11
11
|
Do not edit the class manually.
|
|
@@ -503,8 +503,8 @@ class Configuration:
|
|
|
503
503
|
return "Python SDK Debug Report:\n"\
|
|
504
504
|
"OS: {env}\n"\
|
|
505
505
|
"Python Version: {pyversion}\n"\
|
|
506
|
-
"Version of the API:
|
|
507
|
-
"SDK Package Version: 0.
|
|
506
|
+
"Version of the API: 0.2.0\n"\
|
|
507
|
+
"SDK Package Version: 0.3.0".\
|
|
508
508
|
format(env=sys.platform, pyversion=sys.version)
|
|
509
509
|
|
|
510
510
|
def get_host_settings(self) -> List[HostSetting]:
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
REST API for QueueFlow, a PostgreSQL-native distributed job queue and workflow engine.
|
|
7
7
|
|
|
8
|
-
The version of the OpenAPI document:
|
|
8
|
+
The version of the OpenAPI document: 0.2.0
|
|
9
9
|
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
|
10
10
|
|
|
11
11
|
Do not edit the class manually.
|