From 97fd51f349e6360b6dad89a3ec839e1499d9169a Mon Sep 17 00:00:00 2001 From: Russ Allbery Date: Thu, 12 Dec 2024 12:02:49 -0800 Subject: [PATCH] Prepare 4.0.0 release Update pre-commit, Python, and Docker dependencies. Update the shared Ruff configuration file. Move Pydantic model configuration to the top of the class to make it more obvious. Collect the change log for 4.0.0. Update the worker base container to w_2024_42. --- .pre-commit-config.yaml | 2 +- CHANGELOG.md | 16 ++++++++++++++++ Dockerfile | 4 ++-- Dockerfile.worker | 2 +- changelog.d/20241210_140315_rra_DM_47986.md | 11 ----------- changelog.d/20241211_181509_rra_DM_47986.md | 3 --- pyproject.toml | 4 ++-- requirements/main.txt | 17 +++++++++-------- ruff-shared.toml | 12 +++++++++--- src/vocutouts/config.py | 20 ++++++++++---------- src/vocutouts/models/domain/cutout.py | 8 ++++---- 11 files changed, 54 insertions(+), 45 deletions(-) delete mode 100644 changelog.d/20241210_140315_rra_DM_47986.md delete mode 100644 changelog.d/20241211_181509_rra_DM_47986.md diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 25aa520..03c0347 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -8,7 +8,7 @@ repos: - id: trailing-whitespace - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.8.2 + rev: v0.8.3 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] diff --git a/CHANGELOG.md b/CHANGELOG.md index a017859..ae71d3e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,22 @@ Find changes for the upcoming release in the project's [changelog.d directory](h + +## 4.0.0 (2024-12-12) + +### Backwards-incompatible changes + +- Switch to Wobbly for job storage. All previous job history will be lost unless the vo-cutouts database is converted into Wobbly's storage format and inserted into Wobbly's database. + +### Bug fixes + +- Catch errors from parsing the dataset ID or creating a Butler in the backend worker and report them as proper worker exceptions so that they don't produce uncaught exception errors. +- Append a colon after the error code when reporting UWS errors. + +### Other changes + +- Render all UWS XML output except for error VOTables using vo-models rather than hand-written XML templates. + ## 3.2.0 (2024-09-16) diff --git a/Dockerfile b/Dockerfile index 34f10d1..25c440d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,7 +12,7 @@ # - Runs a non-root user. # - Sets up the entrypoint and port. -FROM python:3.12.7-slim-bookworm AS base-image +FROM python:3.12.8-slim-bookworm AS base-image # Update system packages COPY scripts/install-base-packages.sh . @@ -21,7 +21,7 @@ RUN ./install-base-packages.sh && rm ./install-base-packages.sh FROM base-image AS install-image # Install uv. -COPY --from=ghcr.io/astral-sh/uv:0.4.9 /uv /bin/uv +COPY --from=ghcr.io/astral-sh/uv:0.5.8 /uv /bin/uv # Install system packages only needed for building dependencies. COPY scripts/install-dependency-packages.sh . diff --git a/Dockerfile.worker b/Dockerfile.worker index 88fe71d..8040455 100644 --- a/Dockerfile.worker +++ b/Dockerfile.worker @@ -2,7 +2,7 @@ # are based on stack containers and install any required supporting code # for the image cutout backend, arq, and the backend worker definition. -FROM lsstsqre/centos:7-stack-lsst_distrib-w_2024_27 +FROM lsstsqre/centos:7-stack-lsst_distrib-w_2024_42 # Reset the user to root since we need to do system install tasks. USER root diff --git a/changelog.d/20241210_140315_rra_DM_47986.md b/changelog.d/20241210_140315_rra_DM_47986.md deleted file mode 100644 index 4a53a80..0000000 --- a/changelog.d/20241210_140315_rra_DM_47986.md +++ /dev/null @@ -1,11 +0,0 @@ -### Backwards-incompatible changes - -- Switch to Wobbly for job storage. All previous job history will be lost unless the vo-cutouts database is converted into Wobbly's storage format and inserted into Wobbly's database. - -### Bug fixes - -- Append a colon after the error code when reporting UWS errors. - -### Other changes - -- Render all UWS XML output except for error VOTables using vo-models rather than hand-written XML templates. diff --git a/changelog.d/20241211_181509_rra_DM_47986.md b/changelog.d/20241211_181509_rra_DM_47986.md deleted file mode 100644 index 3f34ccd..0000000 --- a/changelog.d/20241211_181509_rra_DM_47986.md +++ /dev/null @@ -1,3 +0,0 @@ -### Bug fixes - -- Catch errors from parsing the dataset ID or creating a Butler in the backend worker and report them as proper worker exceptions so that they don't produce uncaught exception errors. diff --git a/pyproject.toml b/pyproject.toml index bac6a35..86ab317 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,13 +22,13 @@ classifiers = [ requires-python = ">=3.11" dependencies = [ "astropy", - "click", - "fastapi", + "fastapi>=0.100", "pydantic>2", "pydantic-settings", "safir[uws]>=9.0.1", "structlog", "uvicorn[standard]", + "vo-models>=0.4.1", ] dynamic = ["version"] diff --git a/requirements/main.txt b/requirements/main.txt index fb92d78..91e08c5 100644 --- a/requirements/main.txt +++ b/requirements/main.txt @@ -96,9 +96,9 @@ cachetools==5.5.0 \ --hash=sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292 \ --hash=sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a # via google-auth -casefy==0.1.7 \ - --hash=sha256:6accce985a64b9edb2a610a29ac489d78fac80e52ff8f2d137e294f2f92b8027 \ - --hash=sha256:ab05ff1c67f2a8e62d9f8986fa9a849416d61ac5413ec57d1f827b4f36589cf6 +casefy==1.0.0 \ + --hash=sha256:bc99428475c2089c5f6a21297b4cfe4e83dff132cf3bb06655ddcb90632af1ed \ + --hash=sha256:c89f96fb0fbd13691073b7a65c1e668e81453247d647479a3db105e86d7b0df9 # via dataclasses-avroschema certifi==2024.8.30 \ --hash=sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8 \ @@ -287,7 +287,6 @@ click==8.1.7 \ --hash=sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28 \ --hash=sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de # via - # vo-cutouts (pyproject.toml) # arq # safir # uvicorn @@ -331,9 +330,9 @@ cryptography==44.0.0 \ dacite==1.8.1 \ --hash=sha256:cc31ad6fdea1f49962ea42db9421772afe01ac5442380d9a99fcf3d188c61afe # via dataclasses-avroschema -dataclasses-avroschema==0.65.6 \ - --hash=sha256:96d09278e9d770229c2f6e6eb58656d0b59f460d6098f2761d1c04faf96f6a40 \ - --hash=sha256:a4527afb3d1fe83fa4b811a77e5ed200cad776c11635868edd68626e46814515 +dataclasses-avroschema==0.65.7 \ + --hash=sha256:62b874f020b57294f65e7aced4a634757502e1b410bdb1d6f8e0515eb3fc5c3e \ + --hash=sha256:e59a8a962e1956533a9083468a08dd3958553738e3f87f6bc516fe525901302f # via safir fast-depends==2.4.12 \ --hash=sha256:9393e6de827f7afa0141e54fa9553b737396aaf06bd0040e159d1f790487b16d \ @@ -1394,7 +1393,9 @@ uvloop==0.21.0 ; platform_python_implementation != 'PyPy' and sys_platform != 'c vo-models==0.4.2 \ --hash=sha256:cbca9c22d2ddd4a283c07d1d3e56726e7892b5acf110926417915284caf2583b \ --hash=sha256:fc781f8f4746cf9d610687a2ce8a6ceb64717ba56e72ba487cafc4fe6df24907 - # via safir + # via + # vo-cutouts (pyproject.toml) + # safir watchfiles==1.0.3 \ --hash=sha256:0179252846be03fa97d4d5f8233d1c620ef004855f0717712ae1c558f1974a16 \ --hash=sha256:06ce08549e49ba69ccc36fc5659a3d0ff4e3a07d542b895b8a9013fcab46c2dc \ diff --git a/ruff-shared.toml b/ruff-shared.toml index aff2c6e..8b0e8d0 100644 --- a/ruff-shared.toml +++ b/ruff-shared.toml @@ -58,9 +58,9 @@ ignore = [ "S607", # using PATH is not a security vulnerability "SIM102", # sometimes the formatting of nested if statements is clearer "SIM117", # sometimes nested with contexts are clearer - "TCH001", # we decided to not maintain separate TYPE_CHECKING blocks - "TCH002", # we decided to not maintain separate TYPE_CHECKING blocks - "TCH003", # we decided to not maintain separate TYPE_CHECKING blocks + "TC001", # we decided to not maintain separate TYPE_CHECKING blocks + "TC002", # we decided to not maintain separate TYPE_CHECKING blocks + "TC003", # we decided to not maintain separate TYPE_CHECKING blocks "TD003", # we don't require issues be created for TODOs "TID252", # if we're going to use relative imports, use them always "TRY003", # good general advice but lint is way too aggressive @@ -123,6 +123,12 @@ select = ["ALL"] "S301", # allow tests for whether code can be pickled "SLF001", # tests are allowed to access private members ] +"tests/schema_test.py" = [ + "ASYNC221", # useful to run subprocess in async tests for Alembic +] +"*/tests/schema_test.py" = [ + "ASYNC221", # useful to run subprocess in async tests for Alembic +] # These are too useful as attributes or methods to allow the conflict with the # built-in to rule out their use. diff --git a/src/vocutouts/config.py b/src/vocutouts/config.py index 5367392..49a4cef 100644 --- a/src/vocutouts/config.py +++ b/src/vocutouts/config.py @@ -23,13 +23,13 @@ class Config(UWSAppSettings): """Configuration for vo-cutouts.""" - slack_webhook: SecretStr | None = Field( - None, - title="Slack webhook for alerts", - description="If set, alerts will be posted to this Slack webhook", + model_config = SettingsConfigDict( + env_prefix="CUTOUT_", case_sensitive=False ) - tmpdir: Path = Field(Path("/tmp"), title="Temporary directory for workers") + log_level: LogLevel = Field( + LogLevel.INFO, title="Log level of the application's logger" + ) name: str = Field("vo-cutouts", title="Name of application") @@ -39,13 +39,13 @@ class Config(UWSAppSettings): Profile.development, title="Application logging profile" ) - log_level: LogLevel = Field( - LogLevel.INFO, title="Log level of the application's logger" + slack_webhook: SecretStr | None = Field( + None, + title="Slack webhook for alerts", + description="If set, alerts will be posted to this Slack webhook", ) - model_config = SettingsConfigDict( - env_prefix="CUTOUT_", case_sensitive=False - ) + tmpdir: Path = Field(Path("/tmp"), title="Temporary directory for workers") @property def uws_config(self) -> UWSConfig: diff --git a/src/vocutouts/models/domain/cutout.py b/src/vocutouts/models/domain/cutout.py index 77e46a9..cc554f1 100644 --- a/src/vocutouts/models/domain/cutout.py +++ b/src/vocutouts/models/domain/cutout.py @@ -80,6 +80,8 @@ def _deserialize_sky_coord(c: Any) -> SkyCoord: class WorkerCircleStencil(BaseModel): """Represents a ``CIRCLE`` or ``POS=CIRCLE`` stencil.""" + model_config = ConfigDict(arbitrary_types_allowed=True) + type: Literal["circle"] = "circle" center: SkyCoordSerializable @@ -88,19 +90,17 @@ class WorkerCircleStencil(BaseModel): radius: AngleSerializable """Radius of the circle.""" - model_config = ConfigDict(arbitrary_types_allowed=True) - class WorkerPolygonStencil(BaseModel): """Represents a ``POLYGON`` or ``POS=POLYGON`` stencil.""" + model_config = ConfigDict(arbitrary_types_allowed=True) + type: Literal["polygon"] = "polygon" vertices: SkyCoordSerializable """Vertices of the polygon in counter-clockwise winding.""" - model_config = ConfigDict(arbitrary_types_allowed=True) - class WorkerRangeStencil(BaseModel): """Represents a ``POS=RANGE`` stencil."""