gen-worker 0.1.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.
Files changed (67) hide show
  1. gen_worker-0.1.0/.gitignore +22 -0
  2. gen_worker-0.1.0/PKG-INFO +232 -0
  3. gen_worker-0.1.0/README.md +202 -0
  4. gen_worker-0.1.0/examples/demo/README.md +12 -0
  5. gen_worker-0.1.0/examples/demo/pyproject.toml +43 -0
  6. gen_worker-0.1.0/examples/demo/uv.lock +1384 -0
  7. gen_worker-0.1.0/examples/e2e-stub/README.md +5 -0
  8. gen_worker-0.1.0/examples/e2e-stub/pyproject.toml +37 -0
  9. gen_worker-0.1.0/examples/e2e-stub/uv.lock +1286 -0
  10. gen_worker-0.1.0/examples/hello-world/README.md +53 -0
  11. gen_worker-0.1.0/examples/hello-world/pyproject.toml +41 -0
  12. gen_worker-0.1.0/examples/hello-world/uv.lock +1282 -0
  13. gen_worker-0.1.0/examples/image-gen/README.md +13 -0
  14. gen_worker-0.1.0/examples/image-gen/pyproject.toml +48 -0
  15. gen_worker-0.1.0/examples/image-gen/uv.lock +2832 -0
  16. gen_worker-0.1.0/examples/image-gen-legacy/README.md +12 -0
  17. gen_worker-0.1.0/examples/image-gen-legacy/pyproject.toml +37 -0
  18. gen_worker-0.1.0/examples/image-gen-legacy/uv.lock +2526 -0
  19. gen_worker-0.1.0/examples/medasr-transcribe/README.md +13 -0
  20. gen_worker-0.1.0/examples/medasr-transcribe/pyproject.toml +38 -0
  21. gen_worker-0.1.0/examples/medasr-transcribe/uv.lock +3177 -0
  22. gen_worker-0.1.0/examples/smoke-test/README.md +7 -0
  23. gen_worker-0.1.0/examples/smoke-test/pyproject.toml +38 -0
  24. gen_worker-0.1.0/examples/smoke-test/uv.lock +1440 -0
  25. gen_worker-0.1.0/examples/tiny-safetensors/README.md +30 -0
  26. gen_worker-0.1.0/examples/tiny-safetensors/pyproject.toml +36 -0
  27. gen_worker-0.1.0/examples/tiny-safetensors/uv.lock +2368 -0
  28. gen_worker-0.1.0/pyproject.toml +79 -0
  29. gen_worker-0.1.0/src/gen_worker/__init__.py +28 -0
  30. gen_worker-0.1.0/src/gen_worker/backends.py +26 -0
  31. gen_worker-0.1.0/src/gen_worker/decorators.py +74 -0
  32. gen_worker-0.1.0/src/gen_worker/default_model_manager/__init__.py +5 -0
  33. gen_worker-0.1.0/src/gen_worker/discover.py +368 -0
  34. gen_worker-0.1.0/src/gen_worker/downloader.py +84 -0
  35. gen_worker-0.1.0/src/gen_worker/entrypoint.py +163 -0
  36. gen_worker-0.1.0/src/gen_worker/errors.py +22 -0
  37. gen_worker-0.1.0/src/gen_worker/injection.py +135 -0
  38. gen_worker-0.1.0/src/gen_worker/model_interface.py +52 -0
  39. gen_worker-0.1.0/src/gen_worker/pb/__init__.py +27 -0
  40. gen_worker-0.1.0/src/gen_worker/pb/frontend_pb2.py +61 -0
  41. gen_worker-0.1.0/src/gen_worker/pb/frontend_pb2_grpc.py +233 -0
  42. gen_worker-0.1.0/src/gen_worker/pb/worker_scheduler_pb2.py +79 -0
  43. gen_worker-0.1.0/src/gen_worker/pb/worker_scheduler_pb2_grpc.py +100 -0
  44. gen_worker-0.1.0/src/gen_worker/project_validation.py +70 -0
  45. gen_worker-0.1.0/src/gen_worker/testing/__init__.py +1 -0
  46. gen_worker-0.1.0/src/gen_worker/testing/stub_manager.py +74 -0
  47. gen_worker-0.1.0/src/gen_worker/torch_manager/__init__.py +4 -0
  48. gen_worker-0.1.0/src/gen_worker/torch_manager/manager.py +2059 -0
  49. gen_worker-0.1.0/src/gen_worker/torch_manager/utils/base_types/architecture.py +145 -0
  50. gen_worker-0.1.0/src/gen_worker/torch_manager/utils/base_types/common.py +52 -0
  51. gen_worker-0.1.0/src/gen_worker/torch_manager/utils/base_types/config.py +46 -0
  52. gen_worker-0.1.0/src/gen_worker/torch_manager/utils/config.py +321 -0
  53. gen_worker-0.1.0/src/gen_worker/torch_manager/utils/db/database.py +46 -0
  54. gen_worker-0.1.0/src/gen_worker/torch_manager/utils/device.py +26 -0
  55. gen_worker-0.1.0/src/gen_worker/torch_manager/utils/diffusers_fix.py +10 -0
  56. gen_worker-0.1.0/src/gen_worker/torch_manager/utils/flashpack_loader.py +262 -0
  57. gen_worker-0.1.0/src/gen_worker/torch_manager/utils/globals.py +59 -0
  58. gen_worker-0.1.0/src/gen_worker/torch_manager/utils/load_models.py +238 -0
  59. gen_worker-0.1.0/src/gen_worker/torch_manager/utils/local_cache.py +340 -0
  60. gen_worker-0.1.0/src/gen_worker/torch_manager/utils/model_downloader.py +763 -0
  61. gen_worker-0.1.0/src/gen_worker/torch_manager/utils/parse_cli.py +98 -0
  62. gen_worker-0.1.0/src/gen_worker/torch_manager/utils/paths.py +22 -0
  63. gen_worker-0.1.0/src/gen_worker/torch_manager/utils/repository.py +141 -0
  64. gen_worker-0.1.0/src/gen_worker/torch_manager/utils/utils.py +43 -0
  65. gen_worker-0.1.0/src/gen_worker/types.py +47 -0
  66. gen_worker-0.1.0/src/gen_worker/worker.py +2379 -0
  67. gen_worker-0.1.0/uv.lock +2290 -0
@@ -0,0 +1,22 @@
1
+ # Python
2
+ **/.venv
3
+ *.pyc
4
+ __pycache__
5
+ **/dist
6
+ .mypy_cache
7
+
8
+ .env
9
+ generated_images/
10
+
11
+ !src/gen_worker/pb/**
12
+ !src/gen_worker/pb/__init__.py
13
+
14
+ # Keep generated protobuf stubs, but never commit bytecode caches.
15
+ src/gen_worker/pb/__pycache__/
16
+ src/gen_worker/pb/**/*.pyc
17
+ src/gen_worker/pb/**/*.pyo
18
+
19
+ **/*.png
20
+ **/*.jpg
21
+
22
+ .task/
@@ -0,0 +1,232 @@
1
+ Metadata-Version: 2.4
2
+ Name: gen-worker
3
+ Version: 0.1.0
4
+ Summary: A library used to build custom endpoints in Cozy Creator's serverless function platform.
5
+ Author-email: Paul Fidika <paul@fidika.com>
6
+ Requires-Python: >=3.12
7
+ Requires-Dist: aiohttp>=3.11.14
8
+ Requires-Dist: backoff>=2.2.1
9
+ Requires-Dist: grpcio>=1.71.0
10
+ Requires-Dist: msgspec>=0.18.6
11
+ Requires-Dist: protobuf>=5.26.1
12
+ Requires-Dist: psutil>=7.0.0
13
+ Requires-Dist: pyjwt[crypto]>=2.8.0
14
+ Requires-Dist: tqdm>=4.66.0
15
+ Provides-Extra: dev
16
+ Requires-Dist: devpi-client>=7.2.0; extra == 'dev'
17
+ Requires-Dist: grpcio-tools>=1.71.0; extra == 'dev'
18
+ Provides-Extra: onnxruntime
19
+ Requires-Dist: onnxruntime>=1.18.0; extra == 'onnxruntime'
20
+ Provides-Extra: tensorrt
21
+ Requires-Dist: tensorrt; extra == 'tensorrt'
22
+ Provides-Extra: torch
23
+ Requires-Dist: flashpack>=0.1.2; extra == 'torch'
24
+ Requires-Dist: numpy>=1.26.0; extra == 'torch'
25
+ Requires-Dist: safetensors>=0.4.3; extra == 'torch'
26
+ Requires-Dist: torch>=2.6.0; extra == 'torch'
27
+ Requires-Dist: torchaudio>=2.6.0; extra == 'torch'
28
+ Requires-Dist: torchvision>=0.21.0; extra == 'torch'
29
+ Description-Content-Type: text/markdown
30
+
31
+ This is a python package, called gen_worker, which provides the worker runtime SDK:
32
+
33
+ - Orchestrator gRPC client + job loop
34
+ - Function discovery via @worker_function
35
+ - ActionContext + errors + progress events
36
+ - Model downloading from the Cozy hub (async + retries + progress)
37
+ - Output saving via the Cozy hub file API (ctx.save_bytes/ctx.save_file -> Asset refs)
38
+
39
+ Torch-based model memory management is optional and installed via extras.
40
+
41
+ ---
42
+
43
+ Files in `python-worker/src/gen_worker/pb` are generated from the `.proto` definitions in `gen-orchestrator/proto`.
44
+
45
+ Assuming `gen-orchestrator` is checked out as a sibling repo, regenerate stubs with:
46
+
47
+ `task -d python-worker proto`
48
+
49
+ This runs `uv sync --extra dev` and then `grpc_tools.protoc` against `../gen-orchestrator/proto`.
50
+
51
+ Install modes:
52
+
53
+ - Core only: `gen-worker`
54
+ - Torch runtime add-on: `gen-worker[torch]` (torch + torchvision + torchaudio + safetensors + flashpack + numpy)
55
+
56
+ Example tenant projects live in `./examples`. They use:
57
+
58
+ - `pyproject.toml` + `uv.lock` for dependencies (no requirements.txt)
59
+ - `[tool.cozy]` in `pyproject.toml` for deployment config (functions.modules, runtime.base_image, etc.)
60
+
61
+ Dependency policy:
62
+
63
+ - Require `pyproject.toml` and/or `uv.lock`
64
+ - Do not use `requirements.txt`
65
+ - Put Cozy deployment config in `pyproject.toml` under `[tool.cozy]`
66
+
67
+ Example:
68
+
69
+ ```toml
70
+ [tool.cozy]
71
+ functions.modules = ["functions"]
72
+
73
+ [tool.cozy.runtime]
74
+ base_image = "ghcr.io/cozy/python-worker:cuda12.1-torch2.6"
75
+ ```
76
+
77
+ Function signature:
78
+
79
+ ```python
80
+ from typing import Annotated, Iterator
81
+
82
+ import msgspec
83
+
84
+ from gen_worker import ActionContext, ResourceRequirements, worker_function
85
+ from gen_worker.injection import ModelArtifacts, ModelRef, ModelRefSource as Src
86
+
87
+ class Input(msgspec.Struct):
88
+ prompt: str
89
+ model_key: str = "default"
90
+
91
+ class Output(msgspec.Struct):
92
+ text: str
93
+
94
+ @worker_function(ResourceRequirements())
95
+ def run(
96
+ ctx: ActionContext,
97
+ # The worker injects cached handles based on the ModelRef.
98
+ # ModelRef(Src.DEPLOYMENT, ...) is fixed by deployment configuration (or a literal model id).
99
+ artifacts: Annotated[ModelArtifacts, ModelRef(Src.DEPLOYMENT, "google/functiongemma-270m-it")],
100
+ payload: Input,
101
+ ) -> Output:
102
+ return Output(text=f"prompt={payload.prompt} model_root={artifacts.root_dir}")
103
+
104
+ class Delta(msgspec.Struct):
105
+ delta: str
106
+
107
+ @worker_function(ResourceRequirements())
108
+ def run_incremental(ctx: ActionContext, payload: Input) -> Iterator[Delta]:
109
+ for ch in payload.prompt:
110
+ if ctx.is_canceled():
111
+ raise InterruptedError("canceled")
112
+ yield Delta(delta=ch)
113
+ ```
114
+
115
+ Dynamic checkpoints:
116
+
117
+ - Prefer deployment-defined allowlists. Requests pick a **key/label** from the payload
118
+ (e.g. `payload.model_key`), and the worker resolves it via a deployment-provided mapping.
119
+ - Use `ModelRef(Src.PAYLOAD, "model_key")` for this pattern (the payload value is a key, not a raw HF id).
120
+
121
+ Build contract (gen-builder):
122
+
123
+ - Tenant code + `pyproject.toml`/`uv.lock` are packaged together
124
+ - gen-builder layers tenant code + deps on top of a python-worker base image
125
+ - gen-orchestrator deploys the resulting worker image
126
+
127
+ ---
128
+
129
+ ## Manual builds (without gen-builder)
130
+
131
+ You can build worker images directly using Docker, without gen-builder.
132
+
133
+ ### 1. Project structure
134
+
135
+ ```
136
+ my-worker/
137
+ ├── pyproject.toml # dependencies + [tool.cozy] config
138
+ ├── uv.lock # lockfile (recommended)
139
+ └── src/
140
+ └── my_module/
141
+ └── __init__.py # contains @worker_function decorated functions
142
+ ```
143
+
144
+ ### 2. Copy the Dockerfile template
145
+
146
+ Copy `Dockerfile.template` from this repo to your project as `Dockerfile`:
147
+
148
+ ```bash
149
+ cp /path/to/python-worker/Dockerfile.template ./Dockerfile
150
+ ```
151
+
152
+ Or write your own:
153
+
154
+ ```dockerfile
155
+ ARG BASE_IMAGE=cozycreator/python-worker:cuda12.8-torch2.9
156
+ FROM ${BASE_IMAGE}
157
+
158
+ WORKDIR /app
159
+ COPY . /app
160
+
161
+ RUN pip install --no-cache-dir uv
162
+ RUN if [ -f /app/uv.lock ]; then uv sync --frozen --no-dev; else uv sync --no-dev; fi
163
+
164
+ # Generate function manifest at build time
165
+ RUN mkdir -p /app/.cozy && python -m gen_worker.discover > /app/.cozy/manifest.json
166
+
167
+ ENTRYPOINT ["python", "-m", "gen_worker.entrypoint"]
168
+ ```
169
+
170
+ ### 3. Build
171
+
172
+ ```bash
173
+ # CPU only
174
+ docker build -t my-worker --build-arg BASE_IMAGE=cozycreator/python-worker:cpu-torch2.9 .
175
+
176
+ # CUDA 12.8 (default)
177
+ docker build -t my-worker .
178
+
179
+ # CUDA 13.0
180
+ docker build -t my-worker --build-arg BASE_IMAGE=cozycreator/python-worker:cuda13-torch2.9 .
181
+ ```
182
+
183
+ ### 4. Run
184
+
185
+ ```bash
186
+ docker run -e ORCHESTRATOR_URL=http://orchestrator:8080 my-worker
187
+ ```
188
+
189
+ The worker will:
190
+ 1. Read the manifest from `/app/.cozy/manifest.json`
191
+ 2. Self-register with the orchestrator
192
+ 3. Start listening for tasks
193
+
194
+ ### Available base images
195
+
196
+ | Image | GPU | CUDA | PyTorch |
197
+ |-------|-----|------|---------|
198
+ | `cozycreator/python-worker:cpu-torch2.9` | No | - | 2.9.1 |
199
+ | `cozycreator/python-worker:cuda12.6-torch2.9` | Yes | 12.6 | 2.9.1 |
200
+ | `cozycreator/python-worker:cuda12.8-torch2.9` | Yes | 12.8 | 2.9.1 |
201
+ | `cozycreator/python-worker:cuda13-torch2.9` | Yes | 13.0 | 2.9.1 |
202
+
203
+ ### What happens automatically
204
+
205
+ - **Function discovery**: `gen_worker.discover` scans for `@worker_function` decorators
206
+ - **Manifest generation**: Input/output schemas extracted from msgspec types
207
+ - **Self-registration**: Worker registers its functions with orchestrator on startup
208
+
209
+ No gen-builder required for local development or custom CI pipelines.
210
+
211
+ ---
212
+
213
+ Env hints:
214
+
215
+ - `SCHEDULER_ADDR` sets the primary scheduler address.
216
+ - `SCHEDULER_ADDRS` (comma-separated) provides seed addresses for leader discovery.
217
+ - `WORKER_JWT` is accepted as the auth token if `AUTH_TOKEN` is not set.
218
+ - `SCHEDULER_JWKS_URL` enables verification of `WORKER_JWT` before connecting.
219
+ - JWT verification uses RSA and requires PyJWT crypto support (installed by default via `PyJWT[crypto]`).
220
+ - `WORKER_MAX_INPUT_BYTES`, `WORKER_MAX_OUTPUT_BYTES`, `WORKER_MAX_UPLOAD_BYTES` cap payload sizes.
221
+ - `WORKER_MAX_CONCURRENCY` limits concurrent runs; `ResourceRequirements(max_concurrency=...)` limits per-function.
222
+ - `COZY_HUB_URL` base URL for Cozy hub downloads (used by core downloader).
223
+ - `COZY_HUB_TOKEN` optional bearer token for Cozy hub downloads.
224
+ - `MODEL_MANAGER_CLASS` optional ModelManager plugin (module:Class) loaded at startup.
225
+
226
+ Error hints:
227
+
228
+ - Use `gen_worker.errors.RetryableError` in worker functions to flag retryable failures.
229
+
230
+ API note:
231
+
232
+ - `output_format` is an orchestrator HTTP response preference (queue vs long-poll bytes/url) and does not change worker behavior; workers persist outputs as `Asset` refs via the Cozy hub file API.
@@ -0,0 +1,202 @@
1
+ This is a python package, called gen_worker, which provides the worker runtime SDK:
2
+
3
+ - Orchestrator gRPC client + job loop
4
+ - Function discovery via @worker_function
5
+ - ActionContext + errors + progress events
6
+ - Model downloading from the Cozy hub (async + retries + progress)
7
+ - Output saving via the Cozy hub file API (ctx.save_bytes/ctx.save_file -> Asset refs)
8
+
9
+ Torch-based model memory management is optional and installed via extras.
10
+
11
+ ---
12
+
13
+ Files in `python-worker/src/gen_worker/pb` are generated from the `.proto` definitions in `gen-orchestrator/proto`.
14
+
15
+ Assuming `gen-orchestrator` is checked out as a sibling repo, regenerate stubs with:
16
+
17
+ `task -d python-worker proto`
18
+
19
+ This runs `uv sync --extra dev` and then `grpc_tools.protoc` against `../gen-orchestrator/proto`.
20
+
21
+ Install modes:
22
+
23
+ - Core only: `gen-worker`
24
+ - Torch runtime add-on: `gen-worker[torch]` (torch + torchvision + torchaudio + safetensors + flashpack + numpy)
25
+
26
+ Example tenant projects live in `./examples`. They use:
27
+
28
+ - `pyproject.toml` + `uv.lock` for dependencies (no requirements.txt)
29
+ - `[tool.cozy]` in `pyproject.toml` for deployment config (functions.modules, runtime.base_image, etc.)
30
+
31
+ Dependency policy:
32
+
33
+ - Require `pyproject.toml` and/or `uv.lock`
34
+ - Do not use `requirements.txt`
35
+ - Put Cozy deployment config in `pyproject.toml` under `[tool.cozy]`
36
+
37
+ Example:
38
+
39
+ ```toml
40
+ [tool.cozy]
41
+ functions.modules = ["functions"]
42
+
43
+ [tool.cozy.runtime]
44
+ base_image = "ghcr.io/cozy/python-worker:cuda12.1-torch2.6"
45
+ ```
46
+
47
+ Function signature:
48
+
49
+ ```python
50
+ from typing import Annotated, Iterator
51
+
52
+ import msgspec
53
+
54
+ from gen_worker import ActionContext, ResourceRequirements, worker_function
55
+ from gen_worker.injection import ModelArtifacts, ModelRef, ModelRefSource as Src
56
+
57
+ class Input(msgspec.Struct):
58
+ prompt: str
59
+ model_key: str = "default"
60
+
61
+ class Output(msgspec.Struct):
62
+ text: str
63
+
64
+ @worker_function(ResourceRequirements())
65
+ def run(
66
+ ctx: ActionContext,
67
+ # The worker injects cached handles based on the ModelRef.
68
+ # ModelRef(Src.DEPLOYMENT, ...) is fixed by deployment configuration (or a literal model id).
69
+ artifacts: Annotated[ModelArtifacts, ModelRef(Src.DEPLOYMENT, "google/functiongemma-270m-it")],
70
+ payload: Input,
71
+ ) -> Output:
72
+ return Output(text=f"prompt={payload.prompt} model_root={artifacts.root_dir}")
73
+
74
+ class Delta(msgspec.Struct):
75
+ delta: str
76
+
77
+ @worker_function(ResourceRequirements())
78
+ def run_incremental(ctx: ActionContext, payload: Input) -> Iterator[Delta]:
79
+ for ch in payload.prompt:
80
+ if ctx.is_canceled():
81
+ raise InterruptedError("canceled")
82
+ yield Delta(delta=ch)
83
+ ```
84
+
85
+ Dynamic checkpoints:
86
+
87
+ - Prefer deployment-defined allowlists. Requests pick a **key/label** from the payload
88
+ (e.g. `payload.model_key`), and the worker resolves it via a deployment-provided mapping.
89
+ - Use `ModelRef(Src.PAYLOAD, "model_key")` for this pattern (the payload value is a key, not a raw HF id).
90
+
91
+ Build contract (gen-builder):
92
+
93
+ - Tenant code + `pyproject.toml`/`uv.lock` are packaged together
94
+ - gen-builder layers tenant code + deps on top of a python-worker base image
95
+ - gen-orchestrator deploys the resulting worker image
96
+
97
+ ---
98
+
99
+ ## Manual builds (without gen-builder)
100
+
101
+ You can build worker images directly using Docker, without gen-builder.
102
+
103
+ ### 1. Project structure
104
+
105
+ ```
106
+ my-worker/
107
+ ├── pyproject.toml # dependencies + [tool.cozy] config
108
+ ├── uv.lock # lockfile (recommended)
109
+ └── src/
110
+ └── my_module/
111
+ └── __init__.py # contains @worker_function decorated functions
112
+ ```
113
+
114
+ ### 2. Copy the Dockerfile template
115
+
116
+ Copy `Dockerfile.template` from this repo to your project as `Dockerfile`:
117
+
118
+ ```bash
119
+ cp /path/to/python-worker/Dockerfile.template ./Dockerfile
120
+ ```
121
+
122
+ Or write your own:
123
+
124
+ ```dockerfile
125
+ ARG BASE_IMAGE=cozycreator/python-worker:cuda12.8-torch2.9
126
+ FROM ${BASE_IMAGE}
127
+
128
+ WORKDIR /app
129
+ COPY . /app
130
+
131
+ RUN pip install --no-cache-dir uv
132
+ RUN if [ -f /app/uv.lock ]; then uv sync --frozen --no-dev; else uv sync --no-dev; fi
133
+
134
+ # Generate function manifest at build time
135
+ RUN mkdir -p /app/.cozy && python -m gen_worker.discover > /app/.cozy/manifest.json
136
+
137
+ ENTRYPOINT ["python", "-m", "gen_worker.entrypoint"]
138
+ ```
139
+
140
+ ### 3. Build
141
+
142
+ ```bash
143
+ # CPU only
144
+ docker build -t my-worker --build-arg BASE_IMAGE=cozycreator/python-worker:cpu-torch2.9 .
145
+
146
+ # CUDA 12.8 (default)
147
+ docker build -t my-worker .
148
+
149
+ # CUDA 13.0
150
+ docker build -t my-worker --build-arg BASE_IMAGE=cozycreator/python-worker:cuda13-torch2.9 .
151
+ ```
152
+
153
+ ### 4. Run
154
+
155
+ ```bash
156
+ docker run -e ORCHESTRATOR_URL=http://orchestrator:8080 my-worker
157
+ ```
158
+
159
+ The worker will:
160
+ 1. Read the manifest from `/app/.cozy/manifest.json`
161
+ 2. Self-register with the orchestrator
162
+ 3. Start listening for tasks
163
+
164
+ ### Available base images
165
+
166
+ | Image | GPU | CUDA | PyTorch |
167
+ |-------|-----|------|---------|
168
+ | `cozycreator/python-worker:cpu-torch2.9` | No | - | 2.9.1 |
169
+ | `cozycreator/python-worker:cuda12.6-torch2.9` | Yes | 12.6 | 2.9.1 |
170
+ | `cozycreator/python-worker:cuda12.8-torch2.9` | Yes | 12.8 | 2.9.1 |
171
+ | `cozycreator/python-worker:cuda13-torch2.9` | Yes | 13.0 | 2.9.1 |
172
+
173
+ ### What happens automatically
174
+
175
+ - **Function discovery**: `gen_worker.discover` scans for `@worker_function` decorators
176
+ - **Manifest generation**: Input/output schemas extracted from msgspec types
177
+ - **Self-registration**: Worker registers its functions with orchestrator on startup
178
+
179
+ No gen-builder required for local development or custom CI pipelines.
180
+
181
+ ---
182
+
183
+ Env hints:
184
+
185
+ - `SCHEDULER_ADDR` sets the primary scheduler address.
186
+ - `SCHEDULER_ADDRS` (comma-separated) provides seed addresses for leader discovery.
187
+ - `WORKER_JWT` is accepted as the auth token if `AUTH_TOKEN` is not set.
188
+ - `SCHEDULER_JWKS_URL` enables verification of `WORKER_JWT` before connecting.
189
+ - JWT verification uses RSA and requires PyJWT crypto support (installed by default via `PyJWT[crypto]`).
190
+ - `WORKER_MAX_INPUT_BYTES`, `WORKER_MAX_OUTPUT_BYTES`, `WORKER_MAX_UPLOAD_BYTES` cap payload sizes.
191
+ - `WORKER_MAX_CONCURRENCY` limits concurrent runs; `ResourceRequirements(max_concurrency=...)` limits per-function.
192
+ - `COZY_HUB_URL` base URL for Cozy hub downloads (used by core downloader).
193
+ - `COZY_HUB_TOKEN` optional bearer token for Cozy hub downloads.
194
+ - `MODEL_MANAGER_CLASS` optional ModelManager plugin (module:Class) loaded at startup.
195
+
196
+ Error hints:
197
+
198
+ - Use `gen_worker.errors.RetryableError` in worker functions to flag retryable failures.
199
+
200
+ API note:
201
+
202
+ - `output_format` is an orchestrator HTTP response preference (queue vs long-poll bytes/url) and does not change worker behavior; workers persist outputs as `Asset` refs via the Cozy hub file API.
@@ -0,0 +1,12 @@
1
+ Demo worker functions (minimal).
2
+
3
+ What this contains:
4
+
5
+ - Python module `demo` with several @worker_function examples.
6
+ - `pyproject.toml` with deps and `[tool.cozy]` deployment config.
7
+
8
+ Notes:
9
+
10
+ - Install deps with `uv sync` and generate `uv.lock` for reproducible builds.
11
+ - gen-builder reads `[tool.cozy].functions.modules` from `pyproject.toml`.
12
+ - Deploy with gen-builder by pointing the build source at this folder.
@@ -0,0 +1,43 @@
1
+ [project]
2
+ name = "demo"
3
+ version = "0.1.0"
4
+ description = "Add your description here"
5
+ readme = "README.md"
6
+ authors = [
7
+ { name = "Paul Fidika", email = "paul@fidika.com" }
8
+ ]
9
+ requires-python = ">=3.12"
10
+ dependencies = [
11
+ "gen-worker>=0.1.4",
12
+ "Pillow>=10.0",
13
+ ]
14
+
15
+ [dependency-groups]
16
+ dev = [
17
+ "mypy>=1.10.0",
18
+ ]
19
+
20
+ [project.scripts]
21
+ demo = "demo:main"
22
+
23
+ [build-system]
24
+ requires = ["hatchling"]
25
+ build-backend = "hatchling.build"
26
+
27
+ [tool.hatch.metadata]
28
+ allow-direct-references = true
29
+
30
+ [tool.hatch.build.targets.wheel]
31
+ packages = ["src/demo"]
32
+
33
+ [tool.uv.sources]
34
+ gen-worker = { path = "../.." }
35
+
36
+ [tool.mypy]
37
+ python_version = "3.12"
38
+ ignore_missing_imports = true
39
+ disallow_untyped_defs = true
40
+ python_executable = ".venv/bin/python3"
41
+
42
+ [tool.cozy.runtime]
43
+ base_image = "ghcr.io/cozy/python-worker:cuda12.1-torch2.6"