diff --git a/.env.default b/.env.default index ada21b356..94cbf7921 100644 --- a/.env.default +++ b/.env.default @@ -25,7 +25,11 @@ COMPOSE_PROFILES=gpu #RABBITMQ_DEFAULT_VHOST=default #GIRDER_WORKER_BROKER=amqp://guest:guest@rabbit/default #GIRDER_WORKER_BACKEND=rpc://guest:guest@localhost/ +# Server-side: stamped into jobs at schedule time (worker.api_url setting) #GIRDER_SETTING_WORKER_API_URL=http://girder:8080/api/v1 +# Worker-side: per-worker override when this process cannot reach the stamped URL +# (e.g. remote workers: http://WEB_HOST:8010/api/v1). Leave unset on single-node. +#GIRDER_WORKER_API_URL= #GIRDER_NOTIFICATION_REDIS_URL=redis://redis:6379 # Docker image tag for kitware/viame-web (workers use cpu/gpu tags in compose) @@ -66,7 +70,7 @@ COMPOSE_PROFILES=gpu #ACME_EMAIL=changeme@domain.com #ACME_CA_SERVER=https://acme-v02.api.letsencrypt.org/directory #LOG_LEVEL=ERROR -# Split or standalone worker: remote Girder API (replaces legacy WORKER_API_URL) -#GIRDER_SETTING_WORKER_API_URL=https://viame.kitware.com/api/v1 +# Split / remote worker: override stamped API URL on the worker process +#GIRDER_WORKER_API_URL=https://viame.kitware.com/api/v1 #SOCK_PATH=/var/run/docker.sock WATCHTOWER_API_TOKEN="customtokenstring" diff --git a/docs/Deployment-Docker-Compose.md b/docs/Deployment-Docker-Compose.md index 382dd9e8b..18b330ee2 100644 --- a/docs/Deployment-Docker-Compose.md +++ b/docs/Deployment-Docker-Compose.md @@ -119,32 +119,63 @@ It's possible to split your web server and task runner between multiple nodes. * Make two cloud VM instances, one with NVIDIA drivers and container toolkit, and one without. This is still a special case of scenario 1 from the [Provisioning Guide](Deployment-Provision.md) * Clone the dive repository on both VMs. The `.env` files are **not** identical — the web VM keeps the internal Compose service names, while the worker VM points at the web VM's IP or hostname (referred to below as `WEB_HOST`). +### Worker API URL settings + +Two related variables control how workers call back to Girder. They apply at different layers: + +| Variable | Where to set it | Role | +|----------|-----------------|------| +| `GIRDER_SETTING_WORKER_API_URL` | **Girder web server** process | Sets the Girder system setting `worker.api_url`. That value is **stamped into every job** when it is scheduled (Celery headers / `jobInfoSpec`). | +| `GIRDER_WORKER_API_URL` | **Worker** process only | Optional **per-worker override**. When set, the worker uses this URL for API callbacks instead of the URL stamped at schedule time (including job status/log updates). | + +!!! tip "When to set `GIRDER_WORKER_API_URL`" + + Use it when a worker cannot reach the API URL stamped by the server — typically remote or external workers that cannot resolve Docker-internal names like `girder:8080`. + + Typical mixed setup: + + * Web VM + `localworker` on the Compose network keep the default stamped URL `http://girder:8080/api/v1`. + * Remote worker VMs set `GIRDER_WORKER_API_URL=http://WEB_HOST:8010/api/v1` so they reach Girder through the host-published Traefik port. + + Leave `GIRDER_WORKER_API_URL` **unset** on single-node stacks and on any worker that can already reach the stamped URL. + !!! warning - `GIRDER_SETTING_WORKER_API_URL` is applied by the **web server** as the `worker.api_url` Girder system setting and is then stamped into every job that is dispatched to workers. It must be set on the **web VM**. Setting it only on the worker VM has no effect on the callback URL that workers actually use. + `GIRDER_SETTING_WORKER_API_URL` only affects the **web server** process that schedules jobs. Setting it on a worker container does **not** change the callback URL that worker uses at runtime — use `GIRDER_WORKER_API_URL` for that. + + Port `8080` is Girder's in-container port and is **not** published on the host. Traefik publishes the API on host port `8010` (base `docker-compose.yml`) or on `80`/`443` when you also use `docker-compose.prod.yml`. Remote workers should use the published port — never `8080` unless you publish it yourself. ### Web VM `.env` -The web VM runs RabbitMQ, Redis, and Mongo as Compose services, so it keeps the internal service names — with one exception: `GIRDER_SETTING_WORKER_API_URL` must be an address the **remote worker** can reach, not the internal `girder:8080`. +The web VM runs RabbitMQ, Redis, and Mongo as Compose services and should keep internal service names. For a mixed local + remote worker deployment, leave the server stamping the internal URL (the Compose default): ``` -GIRDER_SETTING_WORKER_API_URL=http://WEB_HOST:8010/api/v1 +# Optional — this is already the Compose default for a single-node / mixed stack +#GIRDER_SETTING_WORKER_API_URL=http://girder:8080/api/v1 ``` -!!! note +`localworker` on the same Compose network can reach `girder:8080` and does not need `GIRDER_WORKER_API_URL`. - Port `8080` is Girder's in-container port and is **not** published on the host. Traefik publishes the API on host port `8010` (base `docker-compose.yml`) or on `80`/`443` when you also use `docker-compose.prod.yml`. Use the published port here — never `8080`. +!!! note - This only applies when workers run on a **separate** host. For a single-node (all-in-one) stack, leave `GIRDER_SETTING_WORKER_API_URL` unset — the default `http://girder:8080/api/v1` is correct because the worker resolves `girder` and reaches port `8080` over the internal Compose network. + If **every** worker (including `localworker`) can reach a single public API URL — for example via host hairpin to `WEB_HOST:8010` — you may instead set `GIRDER_SETTING_WORKER_API_URL=http://WEB_HOST:8010/api/v1` on the web VM and omit `GIRDER_WORKER_API_URL`. Prefer `GIRDER_WORKER_API_URL` on remote workers when local and remote workers need different reachable URLs. ### Worker VM `.env` On the worker VM, uncomment and set these to point at `WEB_HOST`: * `GIRDER_WORKER_BROKER` — RabbitMQ URL on the web VM (e.g. `amqp://guest:guest@WEB_HOST/default`) -* `GIRDER_SETTING_WORKER_API_URL` — Girder API URL on the web VM (e.g. `http://WEB_HOST:8010/api/v1`; match the web VM's value) +* `GIRDER_WORKER_API_URL` — Girder API URL reachable from this worker (e.g. `http://WEB_HOST:8010/api/v1`) * `GIRDER_NOTIFICATION_REDIS_URL` — Redis URL on the web VM (e.g. `redis://WEB_HOST:6379`); required so workers can publish job/UI status notifications +Example: + +``` +GIRDER_WORKER_BROKER=amqp://guest:guest@WEB_HOST/default +GIRDER_WORKER_API_URL=http://WEB_HOST:8010/api/v1 +GIRDER_NOTIFICATION_REDIS_URL=redis://WEB_HOST:6379 +``` + ### Required connectivity The worker VM must be able to reach the web VM on these ports (port `8080` does **not** need to be open between VMs): @@ -169,13 +200,24 @@ In this split setup, `localworker` on the web server handles the `local` queue, ### Verify the configuration -After the stack is up, confirm the web server is handing out the correct callback URL (not the internal `girder:8080` default). From the web VM's Swagger page or via curl: +After the stack is up: + +1. Confirm what the web server stamps into jobs (Swagger or curl on the web VM): ``` GET /api/v1/system/setting?key=worker.api_url ``` -This must return your `http://WEB_HOST:8010/api/v1` value. If it still shows `http://girder:8080/api/v1`, the web VM's `GIRDER_SETTING_WORKER_API_URL` was not applied — jobs will appear to dispatch (and `GET /worker/status` will look healthy, since that only reflects broker connectivity) but will stall because remote workers cannot reach `girder:8080`. +For the recommended mixed setup this is `http://girder:8080/api/v1`. That value is correct for `localworker`; remote workers rely on `GIRDER_WORKER_API_URL` instead. + +2. On each remote worker container, confirm the override is present: + +```bash +docker compose exec girder_worker_default printenv GIRDER_WORKER_API_URL +# -> http://WEB_HOST:8010/api/v1 +``` + +If remote workers stall while `GET /worker/status` looks healthy (broker only), they usually cannot reach the stamped URL and `GIRDER_WORKER_API_URL` is missing or wrong. ## Addon management @@ -233,7 +275,7 @@ This image contains both the backend and client. | GIRDER_ADMIN_PASS | `letmein` | admin password | | GIRDER_WORKER_BROKER | `amqp://guest:guest@rabbit/default` | RabbitMQ connection string (Celery broker) | | GIRDER_WORKER_BACKEND | `rpc://guest:guest@localhost/` | Celery result backend (RPC) | -| GIRDER_SETTING_WORKER_API_URL | `http://girder:8080/api/v1` | Girder REST API URL used by workers. Default is correct for a single-node stack; override with the web host's published URL (e.g. `http://WEB_HOST:8010/api/v1`) only for [split deployments](#splitting-services). | +| GIRDER_SETTING_WORKER_API_URL | `http://girder:8080/api/v1` | Girder system setting `worker.api_url` stamped into jobs at schedule time. Default is correct for single-node and for `localworker` on the Compose network. See [Worker API URL settings](#worker-api-url-settings). | | GIRDER_NOTIFICATION_REDIS_URL | `redis://redis:6379` | Redis URL for notification fan-out | | GIRDER_STATIC_ROOT_DIR | `/opt/dive/clients/girder` | Built web client static files (set in image/Compose) | @@ -260,7 +302,8 @@ This image contains a celery worker to run VIAME pipelines and transcoding jobs. | WORKER_CONCURRENCY | `# of CPU cores` | max concurrnet jobs. **Lower this if you run training** | | WORKER_GPU_UUID | null | leave empty to use all GPUs. Specify UUID to use specific device | | GIRDER_WORKER_BROKER | `amqp://guest:guest@rabbit/default` | RabbitMQ connection string. Ignored in standalone mode. | -| GIRDER_SETTING_WORKER_API_URL | `http://girder:8080/api/v1` | Girder API URL (split/multi-node deployments). Ignored in standalone mode when using `DIVE_API_URL`. | +| GIRDER_WORKER_API_URL | unset | Optional per-worker override of the Girder API base URL used for callbacks. Set on remote/external workers that cannot reach the URL stamped by the server (e.g. `http://WEB_HOST:8010/api/v1`). See [Worker API URL settings](#worker-api-url-settings). Ignored in standalone mode when using `DIVE_API_URL`. | +| GIRDER_SETTING_WORKER_API_URL | `http://girder:8080/api/v1` | Only meaningful on the **web server** (stamped at schedule time). Setting it on a worker process does not override callback URLs at runtime — use `GIRDER_WORKER_API_URL` instead. | | GIRDER_NOTIFICATION_REDIS_URL | `redis://redis:6379` | Redis for notifications when running workers in Compose | | KWIVER_DEFAULT_LOG_LEVEL | `warn` | Log level for VIAME pipeline jobs (env name unchanged; used by the Kwiver logging stack) | | DIVE_USERNAME | null | Username to start private queue processor. Providing this enables standalone mode. | diff --git a/docs/Deployment-Girder-5-Upgrade.md b/docs/Deployment-Girder-5-Upgrade.md index d588a13cd..2e6dcd24f 100644 --- a/docs/Deployment-Girder-5-Upgrade.md +++ b/docs/Deployment-Girder-5-Upgrade.md @@ -21,12 +21,15 @@ Update your `.env` (and any external orchestration) to use Girder 5 names: | Girder 4 / legacy name | Girder 5 name | Purpose | |------------------------|---------------|---------| | `CELERY_BROKER_URL` | `GIRDER_WORKER_BROKER` | RabbitMQ URL for Celery (message broker). | -| `WORKER_API_URL` | `GIRDER_SETTING_WORKER_API_URL` | Girder REST API URL workers call (e.g. `http://girder:8080/api/v1`). | +| `WORKER_API_URL` | `GIRDER_SETTING_WORKER_API_URL` | Server-side Girder setting `worker.api_url` stamped into jobs at schedule time (e.g. `http://girder:8080/api/v1`). | +| *(not used)* | `GIRDER_WORKER_API_URL` | Optional **worker-side** override of the stamped API URL for callbacks. Set on remote workers that cannot reach the server-stamped URL. | | *(not used)* | `GIRDER_WORKER_BACKEND` | Celery result backend (Compose default: `rpc://guest:guest@localhost/`). | | *(not used)* | `GIRDER_NOTIFICATION_REDIS_URL` | Redis URL for Girder notification fan-out (e.g. `redis://redis:6379`). | | *(not used)* | `GIRDER_STATIC_ROOT_DIR` | Path to built web client inside the Girder container (set in Compose). | -`GIRDER_WORKER_BACKEND` is **not** a replacement for `WORKER_API_URL`. Do not point it at `http://…/api/v1`; use `GIRDER_SETTING_WORKER_API_URL` for that. +`GIRDER_WORKER_BACKEND` is **not** a replacement for `WORKER_API_URL`. Do not point it at `http://…/api/v1`. + +Use `GIRDER_SETTING_WORKER_API_URL` on the **web server** (what gets stamped into jobs). Use `GIRDER_WORKER_API_URL` on **worker** processes when they need a different reachable API base than the stamped value. Details: [Worker API URL settings](Deployment-Docker-Compose.md#worker-api-url-settings). ## Recommended upgrade steps @@ -35,7 +38,7 @@ Update your `.env` (and any external orchestration) to use Girder 5 names: 3. **Set image tag** if needed (for example `TAG=latest` in `.env`), then pull images. 4. **Add Redis** — use the `redis` service from `docker-compose.yml` or an external Redis instance and set `GIRDER_NOTIFICATION_REDIS_URL` on `girder` and all worker services. 5. **Rename variables** in `.env` per the table above. -6. **Multi-node deployments:** set `GIRDER_WORKER_BROKER` to your RabbitMQ URL and `GIRDER_SETTING_WORKER_API_URL` to your Girder API URL on every worker host; workers must reach Redis used by the web tier if they rely on notification-related features configured in Compose. +6. **Multi-node deployments:** set `GIRDER_WORKER_BROKER` to your RabbitMQ URL and `GIRDER_WORKER_API_URL` to a Girder API URL reachable from that worker (for example `http://WEB_HOST:8010/api/v1`). Keep `GIRDER_SETTING_WORKER_API_URL` on the web VM at the value appropriate for `localworker` (often the Compose default `http://girder:8080/api/v1`). Workers must reach Redis used by the web tier if they rely on notification-related features configured in Compose. 7. **Rebuild or pull** images, then restart the stack: ```bash diff --git a/server/pyproject.toml b/server/pyproject.toml index b252e5bdd..fed3cb0f7 100644 --- a/server/pyproject.toml +++ b/server/pyproject.toml @@ -40,11 +40,11 @@ classifiers = [ requires-python = ">=3.10,<3.12" dependencies = [ "click>=8.1.3", - "girder==5.0.10", - "girder-client==5.0.10", - "girder_jobs==5.0.10", - "girder_worker==5.0.10", - "girder-plugin-worker==5.0.10", + "girder==5.0.14", + "girder-client==5.0.14", + "girder_jobs==5.0.14", + "girder_worker==5.0.14", + "girder-plugin-worker==5.0.14", "girder_worker_utils>=0.9.0,<1", "pydantic==1.10.13", "pyrabbit2==1.0.7", diff --git a/server/uv.lock b/server/uv.lock index 6f92375ab..57c8e15d9 100644 --- a/server/uv.lock +++ b/server/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 3 +revision = 2 requires-python = ">=3.10, <3.12" resolution-markers = [ "python_full_version >= '3.11' and sys_platform == 'darwin'", @@ -554,12 +554,12 @@ requires-dist = [ { name = "click", specifier = ">=8.1.3" }, { name = "gdal", marker = "extra == 'large-image'", index = "https://girder.github.io/large_image_wheels/" }, { name = "gdown", specifier = ">=6.1.0" }, - { name = "girder", specifier = "==5.0.10" }, - { name = "girder-client", specifier = "==5.0.10" }, - { name = "girder-jobs", specifier = "==5.0.10" }, + { name = "girder", specifier = "==5.0.14" }, + { name = "girder-client", specifier = "==5.0.14" }, + { name = "girder-jobs", specifier = "==5.0.14" }, { name = "girder-large-image", specifier = "==1.34.3a186" }, - { name = "girder-plugin-worker", specifier = "==5.0.10" }, - { name = "girder-worker", specifier = "==5.0.10" }, + { name = "girder-plugin-worker", specifier = "==5.0.14" }, + { name = "girder-worker", specifier = "==5.0.14" }, { name = "girder-worker-utils", specifier = ">=0.9.0,<1" }, { name = "gputil", specifier = ">=1.4.0" }, { name = "large-image", specifier = "==1.34.3a186" }, @@ -691,7 +691,7 @@ wheels = [ [[package]] name = "girder" -version = "5.0.10" +version = "5.0.14" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "bcrypt" }, @@ -717,17 +717,17 @@ dependencies = [ { name = "redis" }, { name = "requests" }, { name = "starlette" }, - { name = "uvicorn" }, + { name = "uvicorn", extra = ["standard"] }, { name = "websockets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/76/ee/018ede53a8f0fed181a53db5068c338b3f9a69161967d26c2716c79bf13b/girder-5.0.10.tar.gz", hash = "sha256:63e2b32e2c53c2e6faa0d88cc72388a626d582d2d480380b18a8cf86c9cee5c3", size = 2805837, upload-time = "2026-06-02T18:16:50.697Z" } +sdist = { url = "https://files.pythonhosted.org/packages/00/e2/504c6acaa68b1eea57b382709c72ee2458b0eb3a04a6139323e95a996fab/girder-5.0.14.tar.gz", hash = "sha256:a8101b4080732ecd9664221298d55823640ebfae4abcf7cc323c30f84d2ff76c", size = 2685089, upload-time = "2026-07-29T20:57:11.899Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/37/3e/b9beab5a61f800dda846bb6711f8a5d01e8508719f82f05e9a477044b17a/girder-5.0.10-py3-none-any.whl", hash = "sha256:4907ef7f0f963d35b88d50d66db20da16794e728b0f8d9de12fcde6dcbc8de84", size = 1986196, upload-time = "2026-06-02T18:16:48.861Z" }, + { url = "https://files.pythonhosted.org/packages/ef/8f/434129461c191f41cc46e8de8b2c579b529d2d557ac5a1d77288b2703179/girder-5.0.14-py3-none-any.whl", hash = "sha256:251a1f85641f941706369a696b355a6b2ac35cf097b5dd5f5f6376c7bb094b48", size = 1767525, upload-time = "2026-07-29T20:57:10.257Z" }, ] [[package]] name = "girder-client" -version = "5.0.10" +version = "5.0.14" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, @@ -735,21 +735,21 @@ dependencies = [ { name = "requests" }, { name = "requests-toolbelt" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c4/4f/24d2569da7a9d0f5b23080585f7085464094be05ffc9a7c757c3febe4031/girder_client-5.0.10.tar.gz", hash = "sha256:ddf49527c7d9611c3c23ffad7f7bf033f58537efeebb61af3577626d4e4a66c1", size = 25814, upload-time = "2026-06-02T18:21:10.708Z" } +sdist = { url = "https://files.pythonhosted.org/packages/3e/e1/283d6d6f80645e8447cbedc4f935f1f47b35e72d6574fbfb0a34c06374ce/girder_client-5.0.14.tar.gz", hash = "sha256:0b907dbf6375c2fdd6b434235361b4c92351acdd5ee8da3afaba3ee020ef72d2", size = 26092, upload-time = "2026-07-29T21:02:15.46Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/62/a7/7f5689570f053656a931e0d55c88f4d8f0ade591c532809da7aa7c1de705/girder_client-5.0.10-py3-none-any.whl", hash = "sha256:d7538a9c824ee07cb9b3043e51473461b46952b9be15e72fbe01684c249218bf", size = 25948, upload-time = "2026-06-02T18:21:09.543Z" }, + { url = "https://files.pythonhosted.org/packages/7b/0a/a140ad55a4e129ee92adb5e2107dd9403f90df03f6a171013b7ad7f9d8c5/girder_client-5.0.14-py3-none-any.whl", hash = "sha256:3f5527c68871a374acfa898cccf1b7d1e721d11e98d9d4ddb0970e3b3a061f5c", size = 25947, upload-time = "2026-07-29T21:02:14.255Z" }, ] [[package]] name = "girder-jobs" -version = "5.0.10" +version = "5.0.14" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "girder" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f9/2b/4e2df0bf9686496eb5291aa98e155201f3c7486a9e99c6347acfc826e4ad/girder_jobs-5.0.10.tar.gz", hash = "sha256:054b2b5f7f55a79abde3ac816527db676e0f5669bca2b2ce41148b038ef04538", size = 205755, upload-time = "2026-06-02T18:18:55.673Z" } +sdist = { url = "https://files.pythonhosted.org/packages/3a/5e/9c80b5fad087a8b4f72e74f419debc9cae3a4eb2e31874632fb9c86c99dd/girder_jobs-5.0.14.tar.gz", hash = "sha256:d094a4c2f79b700ba5644bb11ba76c23425ec3c2066ddd5154f3ba5084593346", size = 205202, upload-time = "2026-07-29T20:59:34.79Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a8/72/9edd9fbf198fa03c54f918d9d3cf42ddb87607ee7fbf3c2fb974afc109ac/girder_jobs-5.0.10-py3-none-any.whl", hash = "sha256:3d1e1c936a7285697d4d4df193d721ac068cd005b19c331eb76c03ea127c770b", size = 202490, upload-time = "2026-06-02T18:18:54.445Z" }, + { url = "https://files.pythonhosted.org/packages/49/2b/52d600ab5e4c81bfb9becbde5405f3039a3237e83a535a52ca822eff2396/girder_jobs-5.0.14-py3-none-any.whl", hash = "sha256:a61a87deb359f9f1bcd980d488a2fafa78817a1c93fb223cf443e3d04837b361", size = 201256, upload-time = "2026-07-29T20:59:33.497Z" }, ] [[package]] @@ -767,20 +767,20 @@ wheels = [ [[package]] name = "girder-plugin-worker" -version = "5.0.10" +version = "5.0.14" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "girder" }, { name = "girder-jobs" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/bf/7b/b09bbc207181ed25bce7422e8e0daeea27de3efff7af50714bceedc1e7c5/girder_plugin_worker-5.0.10.tar.gz", hash = "sha256:e3b7fb7819791ca1196b2002df2d21f63682c2ffa298ec129eaa45536398150f", size = 12282, upload-time = "2026-06-02T18:20:49.814Z" } +sdist = { url = "https://files.pythonhosted.org/packages/62/b8/bd40daf4d386109308200993eafebccb457e88b30188e285e2fee463ce8d/girder_plugin_worker-5.0.14.tar.gz", hash = "sha256:4eb00777a5ea8dc63cb49061237971f8b2dd03d785635f89043f98c06fd5e153", size = 11281, upload-time = "2026-07-29T21:01:49.133Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2f/11/60a9f92ae2f1f7250e77b75a92795f3dbd68947ffec49fc1fd966a150fb6/girder_plugin_worker-5.0.10-py3-none-any.whl", hash = "sha256:ef8c7dc100c9be6c4f391203710d723bf161ee1dbabb44990bf48dbeca33f9b9", size = 13520, upload-time = "2026-06-02T18:20:48.884Z" }, + { url = "https://files.pythonhosted.org/packages/a4/6b/8dad210c045591b541ee760731b11ff8815fa172eb9e25911ad9b3a5d818/girder_plugin_worker-5.0.14-py3-none-any.whl", hash = "sha256:2c319d593c58854d524f0b4fb6d244b515e52dd2ea192e011db017e3d7e2e92a", size = 12272, upload-time = "2026-07-29T21:01:48.248Z" }, ] [[package]] name = "girder-worker" -version = "5.0.10" +version = "5.0.14" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "celery" }, @@ -795,9 +795,9 @@ dependencies = [ { name = "stevedore" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/99/e5/8dc794e3c8944f233363216f1894e330d9b92d9d06bfb335e08f0d33659b/girder_worker-5.0.10.tar.gz", hash = "sha256:ee8f4bc878c986745009743c15a854fe6befebd535cc12bd2f970366f0e597b4", size = 42659, upload-time = "2026-06-02T18:21:21.881Z" } +sdist = { url = "https://files.pythonhosted.org/packages/2e/d2/12bd49a3457a9e33454d9cbbe7195215006460eb052f20ea28118fbd1f0b/girder_worker-5.0.14.tar.gz", hash = "sha256:f591dd5dd0d68f0ccfe20a66076d181cebcab761ba76788b472f780249ff47ad", size = 44916, upload-time = "2026-07-29T21:02:28.011Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c7/22/a47f3769564001cd098e16b70c6667f0b6aea2f3ffe44a8516340ccda64f/girder_worker-5.0.10-py3-none-any.whl", hash = "sha256:fb8185b55f52e30aff2fc2170bb0c868269f2145bdc794617d8ad733a677edf1", size = 59237, upload-time = "2026-06-02T18:21:20.879Z" }, + { url = "https://files.pythonhosted.org/packages/2d/cf/e8d3d5676dbd49472271e0dbc8e2bd899d7fe8c65df66d1b397169680775/girder_worker-5.0.14-py3-none-any.whl", hash = "sha256:deee10926b6418109069bb95283487b03bd3656e5912ccf4de83a1d3375aaa4b", size = 61204, upload-time = "2026-07-29T21:02:27.015Z" }, ] [[package]] @@ -867,6 +867,28 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, ] +[[package]] +name = "httptools" +version = "0.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/e5/d471fcb0e14523fe1c3f4ba58ca52480e7bd70ad7109a3846bc75892f7fb/httptools-0.8.0.tar.gz", hash = "sha256:6b2a32f18d97e16e90827d7a819ffa8dbd8cc245fc4e1fa9d1095b54ef4bd999", size = 271342, upload-time = "2026-05-25T22:17:48.841Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/b9/be66eb0decd730d89b9c94f930e4b8d87787b05724bb84af98bfd825f72c/httptools-0.8.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:bf3b6f807c8541503cecfbb8a8dffb385640d0d96102f3d112aa8740f9b7c826", size = 208805, upload-time = "2026-05-25T22:16:50.434Z" }, + { url = "https://files.pythonhosted.org/packages/9d/f7/b4d41eaae2869d31356bc4bbf546f44fae83ff298af0a043ca0625b06773/httptools-0.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:da684f2e1aa2ee9bdcb083f3f3a68c5956750b375bc5df864d3a5f0c42a40b77", size = 113527, upload-time = "2026-05-25T22:16:51.672Z" }, + { url = "https://files.pythonhosted.org/packages/e6/e4/77487e14fc7be47180fd0eb4267c7486d0cc59b74031839a3daf8650136b/httptools-0.8.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:a6f21e2a3b0067bbe7f67e34cfd16276af556e5e52f4c7503be0cb5f90e905e4", size = 450035, upload-time = "2026-05-25T22:16:53.313Z" }, + { url = "https://files.pythonhosted.org/packages/da/72/5a8f787e323f56fbd86c32a4be92a86776e4cfe8b4317db999f452028362/httptools-0.8.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0ea897f0c729581ebf72131a438a7932d9b14efef72d75ada966700cac3caaeb", size = 451101, upload-time = "2026-05-25T22:16:54.696Z" }, + { url = "https://files.pythonhosted.org/packages/ed/41/b44a25560955197674b6744cb903664300e239235a5eaa69df0890d87054/httptools-0.8.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c0d726cc107fceb7d45f978483b4b70dd8caa836f5914d3434bb18628eb73813", size = 436140, upload-time = "2026-05-25T22:16:56.239Z" }, + { url = "https://files.pythonhosted.org/packages/74/b0/054aac84c03d7e097bf4c605fb7e74eec3d65c0276adf64ee97f3a103ff5/httptools-0.8.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9878eb2785ba5eb70631ad269b37976f73d647955e26c91d490eb8a4edfda4ba", size = 437041, upload-time = "2026-05-25T22:16:57.716Z" }, + { url = "https://files.pythonhosted.org/packages/bb/e8/86b85bbc0ac7892232f1a99ab96a9aa71936984fa06adfc0afc83ca7789e/httptools-0.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:b205e5f5523fa039679da0dfe5a10132b2a4abeae6a86fdd1ddc035f7f836557", size = 90454, upload-time = "2026-05-25T22:16:58.871Z" }, + { url = "https://files.pythonhosted.org/packages/f8/d2/c3eedaef57de65c3cc5f8dc244cf12d09c84ad258a479055aad6db23206c/httptools-0.8.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ed377e64805bdba4943c82717333f8f8603a13b09aff9cead2717c6c817fb168", size = 208428, upload-time = "2026-05-25T22:16:59.717Z" }, + { url = "https://files.pythonhosted.org/packages/f1/94/dfe435d90d0ef61ec0f2cc3d480eef78c59727c6c2ce039f433882f6131a/httptools-0.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9518c406d7b310f05adb1a37f80acabac40504a575d7c0da6d3e365c695ac20d", size = 113366, upload-time = "2026-05-25T22:17:00.795Z" }, + { url = "https://files.pythonhosted.org/packages/cc/d4/13025f1a56e615dcb331e0bbe2d9a1143212b58c263385fc5d2e558f5bac/httptools-0.8.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:57278e6fa0424c42a8a3e454828ab4f0aff27b40cddf9679579b98c6dce6a376", size = 464676, upload-time = "2026-05-25T22:17:02.014Z" }, + { url = "https://files.pythonhosted.org/packages/bf/95/4c1c26c0b985f8a3331682d802598f14e32dc41bf7509266eb2c04ad4801/httptools-0.8.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bbb8caadb2b742d293169d2b458b5c001ef70e3158704aa3d3ef9597624c5d1d", size = 464235, upload-time = "2026-05-25T22:17:03.109Z" }, + { url = "https://files.pythonhosted.org/packages/a2/82/6735be2b0ca527718c431cdb8e5f70c3862c0844a687df0f572c51e11497/httptools-0.8.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:52dd695b865fe96d9d2b16b64a895f3f57bf3cb064e8383cd3b5713a069e8085", size = 449809, upload-time = "2026-05-25T22:17:04.443Z" }, + { url = "https://files.pythonhosted.org/packages/b5/f9/5811c74f37a758c8a4aa3dc430375119d335947e883efc4664d8f3559a41/httptools-0.8.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:20b4aac66ff65f7db06a375808b78f42a94970aa22e826b3cb2b43eb09174124", size = 452174, upload-time = "2026-05-25T22:17:05.476Z" }, + { url = "https://files.pythonhosted.org/packages/cc/94/97b75870dea07b71e3ec535cebe525b08d723152e4c7d13fa887e51f4de2/httptools-0.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:a1b4c8e7a489a0d750d91894e9a8cdc295838f1924c0ca903ae993456fddec07", size = 90991, upload-time = "2026-05-25T22:17:06.75Z" }, +] + [[package]] name = "idna" version = "3.15" @@ -1721,6 +1743,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d8/db/795879cc3ddfe338599bddea6388cc5100b088db0a4caf6e6c1af1c27e04/python_discovery-1.2.2-py3-none-any.whl", hash = "sha256:e1ae95d9af875e78f15e19aed0c6137ab1bb49c200f21f5061786490c9585c7a", size = 31894, upload-time = "2026-04-07T17:28:48.09Z" }, ] +[[package]] +name = "python-dotenv" +version = "1.2.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/82/ed/0301aeeac3e5353ef3d94b6ec08bbcabd04a72018415dcb29e588514bba8/python_dotenv-1.2.2.tar.gz", hash = "sha256:2c371a91fbd7ba082c2c1dc1f8bf89ca22564a087c2c287cd9b662adde799cf3", size = 50135, upload-time = "2026-03-01T16:00:26.196Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0b/d7/1959b9648791274998a9c3526f6d0ec8fd2233e4d4acce81bbae76b44b2a/python_dotenv-1.2.2-py3-none-any.whl", hash = "sha256:1d8214789a24de455a8b8bd8ae6fe3c6b69a5e3d64aa8a8e5d68e694bbcb285a", size = 22101, upload-time = "2026-03-01T16:00:25.09Z" }, +] + [[package]] name = "pytz" version = "2026.1.post1" @@ -2234,6 +2265,37 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/31/a3/5b1562db76a5a488274b2332a97199b32d0442aca0ed193697fd47786316/uvicorn-0.46.0-py3-none-any.whl", hash = "sha256:bbebbcbed972d162afca128605223022bedd345b7bc7855ce66deb31487a9048", size = 70926, upload-time = "2026-04-23T07:15:58.355Z" }, ] +[package.optional-dependencies] +standard = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "httptools" }, + { name = "python-dotenv" }, + { name = "pyyaml" }, + { name = "uvloop", marker = "platform_python_implementation != 'PyPy' and sys_platform != 'cygwin' and sys_platform != 'win32'" }, + { name = "watchfiles" }, + { name = "websockets" }, +] + +[[package]] +name = "uvloop" +version = "0.22.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/06/f0/18d39dbd1971d6d62c4629cc7fa67f74821b0dc1f5a77af43719de7936a7/uvloop-0.22.1.tar.gz", hash = "sha256:6c84bae345b9147082b17371e3dd5d42775bddce91f885499017f4607fdaf39f", size = 2443250, upload-time = "2025-10-16T22:17:19.342Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/eb/14/ecceb239b65adaaf7fde510aa8bd534075695d1e5f8dadfa32b5723d9cfb/uvloop-0.22.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ef6f0d4cc8a9fa1f6a910230cd53545d9a14479311e87e3cb225495952eb672c", size = 1343335, upload-time = "2025-10-16T22:16:11.43Z" }, + { url = "https://files.pythonhosted.org/packages/ba/ae/6f6f9af7f590b319c94532b9567409ba11f4fa71af1148cab1bf48a07048/uvloop-0.22.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7cd375a12b71d33d46af85a3343b35d98e8116134ba404bd657b3b1d15988792", size = 742903, upload-time = "2025-10-16T22:16:12.979Z" }, + { url = "https://files.pythonhosted.org/packages/09/bd/3667151ad0702282a1f4d5d29288fce8a13c8b6858bf0978c219cd52b231/uvloop-0.22.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ac33ed96229b7790eb729702751c0e93ac5bc3bcf52ae9eccbff30da09194b86", size = 3648499, upload-time = "2025-10-16T22:16:14.451Z" }, + { url = "https://files.pythonhosted.org/packages/b3/f6/21657bb3beb5f8c57ce8be3b83f653dd7933c2fd00545ed1b092d464799a/uvloop-0.22.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:481c990a7abe2c6f4fc3d98781cc9426ebd7f03a9aaa7eb03d3bfc68ac2a46bd", size = 3700133, upload-time = "2025-10-16T22:16:16.272Z" }, + { url = "https://files.pythonhosted.org/packages/09/e0/604f61d004ded805f24974c87ddd8374ef675644f476f01f1df90e4cdf72/uvloop-0.22.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a592b043a47ad17911add5fbd087c76716d7c9ccc1d64ec9249ceafd735f03c2", size = 3512681, upload-time = "2025-10-16T22:16:18.07Z" }, + { url = "https://files.pythonhosted.org/packages/bb/ce/8491fd370b0230deb5eac69c7aae35b3be527e25a911c0acdffb922dc1cd/uvloop-0.22.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:1489cf791aa7b6e8c8be1c5a080bae3a672791fcb4e9e12249b05862a2ca9cec", size = 3615261, upload-time = "2025-10-16T22:16:19.596Z" }, + { url = "https://files.pythonhosted.org/packages/c7/d5/69900f7883235562f1f50d8184bb7dd84a2fb61e9ec63f3782546fdbd057/uvloop-0.22.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c60ebcd36f7b240b30788554b6f0782454826a0ed765d8430652621b5de674b9", size = 1352420, upload-time = "2025-10-16T22:16:21.187Z" }, + { url = "https://files.pythonhosted.org/packages/a8/73/c4e271b3bce59724e291465cc936c37758886a4868787da0278b3b56b905/uvloop-0.22.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3b7f102bf3cb1995cfeaee9321105e8f5da76fdb104cdad8986f85461a1b7b77", size = 748677, upload-time = "2025-10-16T22:16:22.558Z" }, + { url = "https://files.pythonhosted.org/packages/86/94/9fb7fad2f824d25f8ecac0d70b94d0d48107ad5ece03769a9c543444f78a/uvloop-0.22.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:53c85520781d84a4b8b230e24a5af5b0778efdb39142b424990ff1ef7c48ba21", size = 3753819, upload-time = "2025-10-16T22:16:23.903Z" }, + { url = "https://files.pythonhosted.org/packages/74/4f/256aca690709e9b008b7108bc85fba619a2bc37c6d80743d18abad16ee09/uvloop-0.22.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:56a2d1fae65fd82197cb8c53c367310b3eabe1bbb9fb5a04d28e3e3520e4f702", size = 3804529, upload-time = "2025-10-16T22:16:25.246Z" }, + { url = "https://files.pythonhosted.org/packages/7f/74/03c05ae4737e871923d21a76fe28b6aad57f5c03b6e6bfcfa5ad616013e4/uvloop-0.22.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:40631b049d5972c6755b06d0bfe8233b1bd9a8a6392d9d1c45c10b6f9e9b2733", size = 3621267, upload-time = "2025-10-16T22:16:26.819Z" }, + { url = "https://files.pythonhosted.org/packages/75/be/f8e590fe61d18b4a92070905497aec4c0e64ae1761498cad09023f3f4b3e/uvloop-0.22.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:535cc37b3a04f6cd2c1ef65fa1d370c9a35b6695df735fcff5427323f2cd5473", size = 3723105, upload-time = "2025-10-16T22:16:28.252Z" }, +] + [[package]] name = "vcs-versioning" version = "1.1.1" @@ -2299,6 +2361,48 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/33/e8/e40370e6d74ddba47f002a32919d91310d6074130fe4e17dabcafc15cbf1/watchdog-6.0.0-py3-none-win_ia64.whl", hash = "sha256:a1914259fa9e1454315171103c6a30961236f508b9b623eae470268bbcc6a22f", size = 79067, upload-time = "2024-11-01T14:07:11.845Z" }, ] +[[package]] +name = "watchfiles" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cd/41/5e1a4bb12aac5f1493fa1bdc11154eca3b258ca4eba65d39c473fe19d8e9/watchfiles-1.2.0.tar.gz", hash = "sha256:c995fba777f1ea992f090f9236e9284cf7a5d1a0130dd5a3d82c598cacd76838", size = 108252, upload-time = "2026-05-18T04:32:04.251Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0d/5a/2bf22ecb24916983bf1cc0095e7dea2741d14d6553b0d6a2ac8bc96eca93/watchfiles-1.2.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:bb68bf4df85abebe5efddc53cf2075520f243a59868d9b3973278b23e76962a9", size = 400471, upload-time = "2026-05-18T04:31:08.908Z" }, + { url = "https://files.pythonhosted.org/packages/55/70/dea1f6a0e76607841a60fb51af150e70124864673f61704abb62b90cdcc7/watchfiles-1.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c16cb06dd17d43b9d185094268459eac92c9538356f050e55b54e82cf700e1d4", size = 394599, upload-time = "2026-05-18T04:30:19.845Z" }, + { url = "https://files.pythonhosted.org/packages/18/52/752dcc7dc817baef5e89518732925795ce52e36a683a9a3c9fb68b21504e/watchfiles-1.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77a0feab9af4c021c581f695258c642b3d10c5fd4c676e33a0d8606425d82631", size = 455458, upload-time = "2026-05-18T04:30:29.126Z" }, + { url = "https://files.pythonhosted.org/packages/12/48/366ebbb22fcc504c2f72b45f0b7e72f40a18795cc01752c16066d597b67a/watchfiles-1.2.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a16ffe19bf5cf9f5edaa1ad1dd830c5a816e8feec430c522302ab55483a4b994", size = 460513, upload-time = "2026-05-18T04:31:40.85Z" }, + { url = "https://files.pythonhosted.org/packages/ad/44/1f9e1b15e7a729062e0d0c3d0d7225ea4ab98b2267ef87287153be2495fc/watchfiles-1.2.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:204f299afcbd65918ab78dbc52626b0ae45e9d8cef403fdbf33ecf9e40eac66e", size = 493616, upload-time = "2026-05-18T04:30:58.47Z" }, + { url = "https://files.pythonhosted.org/packages/7e/55/8b1086dcc8a1d6a697a62767bd7ea368e74c61c6fd171683cfe24a3fe5d2/watchfiles-1.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:11743adfa510bfffebe97659fb280182b5c9b238708f667e866f308c3430dc19", size = 573154, upload-time = "2026-05-18T04:30:37.903Z" }, + { url = "https://files.pythonhosted.org/packages/14/7a/242f400cc77fafa7b18d53d19d9cb64fc6a6f61f28c55913bae7c674d92a/watchfiles-1.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eb72919d93e3a16fc451d3aa3d4b1698423daca1b382d3d959c9ac51297c12a8", size = 467046, upload-time = "2026-05-18T04:30:41.869Z" }, + { url = "https://files.pythonhosted.org/packages/02/c8/79eee650c62d2c186598489814468e389b5def0ebe755399ff645b35b1b2/watchfiles-1.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62f042afde2dde21ec1d2c1a74361e804673df86f51e418a999c9acfe671b07", size = 457100, upload-time = "2026-05-18T04:31:13.064Z" }, + { url = "https://files.pythonhosted.org/packages/81/36/519f6dbb7a95e4fe7c1513ed25b1520295ef9905a27f1f2226a73892bfb7/watchfiles-1.2.0-cp310-cp310-manylinux_2_31_riscv64.whl", hash = "sha256:027ae72bfdfd254862065d8b3e2a815c6ab9b1853ce41e6648ece84afd34a551", size = 467038, upload-time = "2026-05-18T04:30:32.915Z" }, + { url = "https://files.pythonhosted.org/packages/2f/12/951af6b9f89097e02511122258402cb3578443021930b70cf968d6310dc0/watchfiles-1.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e1cfd51e97e13ff3bd047c140764d277fc9b95b7cb5da59e46a47d167adab310", size = 632563, upload-time = "2026-05-18T04:30:11.539Z" }, + { url = "https://files.pythonhosted.org/packages/28/cc/0cba1f0a6117b7ec117271bdc3cb3a5a252005959755a2c09a745e0942cc/watchfiles-1.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:24b2405c0a46738dd9e1cf7135aa5dbdb9d42d024628651b3b13d5117e99f8df", size = 660851, upload-time = "2026-05-18T04:31:53.186Z" }, + { url = "https://files.pythonhosted.org/packages/d0/f2/26347558cc8bf6877845e66b315f644d03c173906aa09e233a3f4fd23928/watchfiles-1.2.0-cp310-cp310-win32.whl", hash = "sha256:8c520725602756229f045b032a1ff33d7ef0f7404189d62f6c2438cb6d8ef6a1", size = 277023, upload-time = "2026-05-18T04:30:18.825Z" }, + { url = "https://files.pythonhosted.org/packages/6d/68/a5e67b6b68e94f4c1511d61c46c55eba0737583620b6febf194c7b9cc23f/watchfiles-1.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:03b14855c6f35539e2d95c442ae9530a75762f1e26567152b9ed05f96534a74d", size = 290107, upload-time = "2026-05-18T04:32:09.677Z" }, + { url = "https://files.pythonhosted.org/packages/fc/3d/8024c801df84d1587740d0359e7fdd80afeae3d159011f3d5376dd82f18e/watchfiles-1.2.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:704fd259e332e01f9b9c178f4bce9e49027e5587cc2600eeeaf8e76e1c846201", size = 400242, upload-time = "2026-05-18T04:31:19.014Z" }, + { url = "https://files.pythonhosted.org/packages/87/5b/f4dfd45323e949984a3a7f9dc31d1cbb049921e7d98253488dda72ccdaa9/watchfiles-1.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6543cf55d170003296d185c0af981f3e1311564907e1f4e08671fc7693a890a5", size = 394562, upload-time = "2026-05-18T04:30:08.46Z" }, + { url = "https://files.pythonhosted.org/packages/98/d8/19483ef075d601c409bce8bcbb5c0f81a10876fff870400568f08ce484a1/watchfiles-1.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89d8c2394a065ca86f5d2910ff263ae67c127e1376ccc4f9fc35c71db879f80a", size = 456611, upload-time = "2026-05-18T04:30:45.723Z" }, + { url = "https://files.pythonhosted.org/packages/b1/6a/cc81fbe7ee42f2f22e661a6e12def7807e01b14b2f39e0ff83fd373fd307/watchfiles-1.2.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:772b80df316480d894a0e3165fdd19cf77f5d17f9a787f94029465ad0e3529d1", size = 461379, upload-time = "2026-05-18T04:31:29.292Z" }, + { url = "https://files.pythonhosted.org/packages/b1/57/7e669002082c0a0f4fb5113bb70125f7110124b846b0a11bc5ae8e90eac1/watchfiles-1.2.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d158cd89df6053823533e06fb1d73c549133bff5f0396170c0e53d9559340717", size = 493556, upload-time = "2026-05-18T04:30:05.44Z" }, + { url = "https://files.pythonhosted.org/packages/45/7d/f60a2b19807b21fe8281f3a8da4f59eef0d5f96825ac4680ba2d4f2ebf91/watchfiles-1.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d516b3283a758e087841aedb8031549fb41ced08f3db10aa6d2bf32dc042525b", size = 575255, upload-time = "2026-05-18T04:30:40.568Z" }, + { url = "https://files.pythonhosted.org/packages/bd/49/77f5b5e6efbcd57482f74948ebb1b97e5c0046d6b61475042d830c84b3ff/watchfiles-1.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:53b2290c92e0506d102cd448fbc610d87079553f86caa39d67440856a8b8bba5", size = 467052, upload-time = "2026-05-18T04:31:17.942Z" }, + { url = "https://files.pythonhosted.org/packages/ee/5a/73e2959af1b97fd5d556f9a8bdba017be23ceeef731869d5eaa0a753d5a3/watchfiles-1.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a711b51aec4370d0dcda5b6c09463206f133a5759341d7744b953a7b62e1100e", size = 456858, upload-time = "2026-05-18T04:30:30.182Z" }, + { url = "https://files.pythonhosted.org/packages/50/57/1bc8c27fad7e6c19bddee15d276dbb6ab72480ec01c127afff1673aee417/watchfiles-1.2.0-cp311-cp311-manylinux_2_31_riscv64.whl", hash = "sha256:e2ca07fa7d89195ec0865d3d285666286740bfa83d83e5cee204043a31ecc165", size = 467579, upload-time = "2026-05-18T04:32:15.897Z" }, + { url = "https://files.pythonhosted.org/packages/09/6c/3c2e44edba3553c5e3c3b8c8a2a6dee6b9e12ae2cf4bd2378bebf9dc3038/watchfiles-1.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e0618518f282c4ebff60f5e5b1247b6d91bb8b9f4476947563a1e74acc66f3c6", size = 633253, upload-time = "2026-05-18T04:31:37.123Z" }, + { url = "https://files.pythonhosted.org/packages/30/c2/d8c84a882ab39bbefcc4915ab3e91830b7a7e990c5570b0b69075aba3faf/watchfiles-1.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0d191c054d0715c3c95c99df9b8dbf6fd096d8c1e021e8f212e1bd8bc444ccb5", size = 660713, upload-time = "2026-05-18T04:31:24.62Z" }, + { url = "https://files.pythonhosted.org/packages/a9/07/f97736a5fc605364fe67b25e9fa4a6965dfd4840d50c406ada507e9d735f/watchfiles-1.2.0-cp311-cp311-win32.whl", hash = "sha256:9342472aff9b093c5acd4f6d8f70ae0937964ab56542502bcf5579782da69ae8", size = 277222, upload-time = "2026-05-18T04:31:21.131Z" }, + { url = "https://files.pythonhosted.org/packages/cf/99/2b04981977fc2608afd60360d928c6aecf6b950292ca221d98f4005f6694/watchfiles-1.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:dbd6c97045dad81227c8d040173da044c1de08de64a5ea8b555da4aee1d5fa22", size = 290274, upload-time = "2026-05-18T04:31:45.966Z" }, + { url = "https://files.pythonhosted.org/packages/3c/74/f7f58a7075ee9cf612b0cfcddb78b8cd8234f0742d6f0075cf0da2dde1c6/watchfiles-1.2.0-cp311-cp311-win_arm64.whl", hash = "sha256:57a2d9fa4fb4c2ecae57b13dfff2c7ab53e21a2ba674fe9f05506680fcdcc0d7", size = 283460, upload-time = "2026-05-18T04:31:39.126Z" }, + { url = "https://files.pythonhosted.org/packages/23/f4/7513ef1e85fc4c6331b59479d6d72661fc391fbe543678052ac72c8b6c19/watchfiles-1.2.0-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:4674d49eb94706dfe666c069fc0a1b646ffcf920473492e209f6d5f60d3f0cc2", size = 403050, upload-time = "2026-05-18T04:30:36.753Z" }, + { url = "https://files.pythonhosted.org/packages/27/0b/a54103cfd732bb703c7a749222011a0483ef3705948dae3b203158601119/watchfiles-1.2.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:094b9b70103d4e963499bdea001ee3c2697b144cd9ae6218a62c0f89ec9e31db", size = 396629, upload-time = "2026-05-18T04:32:03.268Z" }, + { url = "https://files.pythonhosted.org/packages/5e/2c/73f31a3b893886206c3f54d73e8ad8dee58cdb2f69ad2622e0a8a9e07f4e/watchfiles-1.2.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b0ef001f8c25ad0fa9529f914c1600647ecd0f542d11c19b7894768c67b6acb7", size = 457318, upload-time = "2026-05-18T04:31:01.932Z" }, + { url = "https://files.pythonhosted.org/packages/e9/f9/45d021e4a5cc7b9dd567f7cbb06d3b75f751a690063fb6cc7ec60f4e46b7/watchfiles-1.2.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a88fc94e647bc4eec523f1caa540258eb71d14278b9daf72fa1e2658a98df0f0", size = 457771, upload-time = "2026-05-18T04:30:56.331Z" }, +] + [[package]] name = "wcwidth" version = "0.6.0"