From 4a110b94de2592494f9966ecc99cc28356d2ed63 Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Mon, 14 Jul 2025 15:17:19 -0600 Subject: [PATCH 01/38] feat: create docker-compose file --- docker/docker-compose.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 docker/docker-compose.yml diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml new file mode 100644 index 000000000..e69de29bb From 17d4ced3ef554a3a499ab36f063af8d709eb3caa Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Mon, 14 Jul 2025 15:21:35 -0600 Subject: [PATCH 02/38] feat: set up pre-commit hooks --- .pre-commit-hook.yml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 .pre-commit-hook.yml diff --git a/.pre-commit-hook.yml b/.pre-commit-hook.yml new file mode 100644 index 000000000..a805a377e --- /dev/null +++ b/.pre-commit-hook.yml @@ -0,0 +1,21 @@ +repos: + - repo: https://github.com/psf/black + rev: 24.4.2 + hooks: + - id: black + + - repo: https://github.com/pycqa/flake8 + rev: 7.0.0 + hooks: + - id: flake8 + args: [ + '--count', + '--select=E9,F63,F7,F82,F401,F541,F631,F634,F701,F702', + '--show-source', + '--statistics' + ] + + - repo: https://github.com/pre-commit/mirrors-mypy + rev: v1.10.0 # Use the latest stable version or pin to your preference + hooks: + - id: mypy \ No newline at end of file From 44a3924b676a7ee08a107ae56833ae7e945bdd33 Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Mon, 14 Jul 2025 15:27:17 -0600 Subject: [PATCH 03/38] feat" add pre-commit to requirements files --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index 35e72d84b..f12eec89f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -48,6 +48,7 @@ pg8000==1.31.2 phonenumbers==9.0.7 pillow==11.3.0 pluggy==1.6.0 +pre-commit propcache==0.3.2 proto-plus==1.26.1 protobuf==6.31.1 From 11f45983b90fb0c02eaff17a74f5562d7b15f98f Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Mon, 14 Jul 2025 15:35:21 -0600 Subject: [PATCH 04/38] Fix pre-commit configureation file name --- .pre-commit-hook.yml => .pre-commit-config.yaml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .pre-commit-hook.yml => .pre-commit-config.yaml (100%) diff --git a/.pre-commit-hook.yml b/.pre-commit-config.yaml similarity index 100% rename from .pre-commit-hook.yml rename to .pre-commit-config.yaml From 05210b9d6042e168734b039f3729ac1b2be18722 Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Mon, 14 Jul 2025 15:36:58 -0600 Subject: [PATCH 05/38] feat: update README to include pre-commit info --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 218adfaaa..9303b01d1 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,9 @@ uv venv source .venv/bin/activate uv pip install -r requirements.txt +# Set up pre-commit hooks +pre-commit install + # Set up environment variables cp .env.example .env # Edit `.env` to configure database connection and app settings From a796dfcb8cc50abb8688ef645867807f914ce9a7 Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Mon, 14 Jul 2025 16:52:16 -0600 Subject: [PATCH 06/38] fix: refactor docker directory structure --- docker/app/Dockerfile | 23 +++++++++++++++++++ docker/{ => db}/Dockerfile | 0 docker/{ => db}/postgis.d/initdb-postgis.sh | 0 docker/{ => db}/postgis.d/update-postgis.sh | 0 .../timescaledb.d/000_install_timescaledb.sh | 0 .../timescaledb.d/001_timescaledb_tune.sh | 0 docker/docker-compose.yml | 16 +++++++++++++ 7 files changed, 39 insertions(+) create mode 100644 docker/app/Dockerfile rename docker/{ => db}/Dockerfile (100%) rename docker/{ => db}/postgis.d/initdb-postgis.sh (100%) rename docker/{ => db}/postgis.d/update-postgis.sh (100%) rename docker/{ => db}/timescaledb.d/000_install_timescaledb.sh (100%) rename docker/{ => db}/timescaledb.d/001_timescaledb_tune.sh (100%) diff --git a/docker/app/Dockerfile b/docker/app/Dockerfile new file mode 100644 index 000000000..73d3204e3 --- /dev/null +++ b/docker/app/Dockerfile @@ -0,0 +1,23 @@ +FROM python:3.13-slim AS base + +# install uv (fast dependency manager) +RUN curl -Ls https://astral.sh/uv/install.sh | sh -s -- v0.7.17 && \ + cp /root/.local/bin/uv /usr/local/bin/uv + +# set workdir +WORKDIR /app + +# copy dependencies first to leverage Docker cache +COPY pyproject.toml uv.lock* requirements*.txt* ./ + +ENV UV_PROJECT_ENVIRONMENT="/usr/local/" +RUN uv sync --locked --no-dev + +# copy the full project source +COPY ./.. . + +# expose FastAPI's default dev port +EXPOSE 8000 + +# default command (run the development server) +CMD [] diff --git a/docker/Dockerfile b/docker/db/Dockerfile similarity index 100% rename from docker/Dockerfile rename to docker/db/Dockerfile diff --git a/docker/postgis.d/initdb-postgis.sh b/docker/db/postgis.d/initdb-postgis.sh similarity index 100% rename from docker/postgis.d/initdb-postgis.sh rename to docker/db/postgis.d/initdb-postgis.sh diff --git a/docker/postgis.d/update-postgis.sh b/docker/db/postgis.d/update-postgis.sh similarity index 100% rename from docker/postgis.d/update-postgis.sh rename to docker/db/postgis.d/update-postgis.sh diff --git a/docker/timescaledb.d/000_install_timescaledb.sh b/docker/db/timescaledb.d/000_install_timescaledb.sh similarity index 100% rename from docker/timescaledb.d/000_install_timescaledb.sh rename to docker/db/timescaledb.d/000_install_timescaledb.sh diff --git a/docker/timescaledb.d/001_timescaledb_tune.sh b/docker/db/timescaledb.d/001_timescaledb_tune.sh similarity index 100% rename from docker/timescaledb.d/001_timescaledb_tune.sh rename to docker/db/timescaledb.d/001_timescaledb_tune.sh diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index e69de29bb..236d08a38 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -0,0 +1,16 @@ +services: + db: + build: + context: ./db + dockerfile: Dockerfile + environment: + - POSTGRES_USER=${POSTGRES_USER} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + - POSTGRES_DB=${POSTGRES_DB} + ports: + - 5432:5432 + volumes: + - postgres_data:/var/lib/postgresql/data + +volumes: + postgres_data: \ No newline at end of file From 2793ea608c0e93789b544917d812bf2109c3c4fc Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Mon, 14 Jul 2025 17:54:27 -0600 Subject: [PATCH 07/38] feat: docker compose and Dockerfile updates This commit includes the following changes: - Added a new `docker-compose.yml` file to manage multi-container Docker applications. - Updated the `Dockerfile` in the `docker/app` directory to: - Install system dependencies for `psycopg2` and `uv`. - Copy the full project source into the Docker image. Future work will include putting docker-compose.yml into the docker directory --- docker-compose.yml | 27 +++++++++++++++++++++++++++ docker/app/Dockerfile | 21 +++++++++++++++------ docker/docker-compose.yml | 16 ---------------- 3 files changed, 42 insertions(+), 22 deletions(-) create mode 100644 docker-compose.yml delete mode 100644 docker/docker-compose.yml diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..c169fdf04 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,27 @@ +# keep docker-compose.yml in root directory to configure with root .env + +services: + db: + image: postgis/postgis:17-3.5 + environment: + - POSTGRES_USER=${POSTGRES_USER} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + - POSTGRES_DB=${POSTGRES_DB} + ports: + - 5432:5432 + volumes: + - postgres_data:/var/lib/postgresql/data + + app: + build: + context: . + dockerfile: ./docker/app/Dockerfile + environment: + - DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB} + ports: + - 8000:8000 + depends_on: + - db + +volumes: + postgres_data: \ No newline at end of file diff --git a/docker/app/Dockerfile b/docker/app/Dockerfile index 73d3204e3..bab568211 100644 --- a/docker/app/Dockerfile +++ b/docker/app/Dockerfile @@ -1,5 +1,11 @@ FROM python:3.13-slim AS base +# install system dependencies for psycopg2 and uv +RUN apt-get update && apt-get install -y curl gcc libpq-dev + +# install curl +RUN apt-get update && apt-get install -y curl + # install uv (fast dependency manager) RUN curl -Ls https://astral.sh/uv/install.sh | sh -s -- v0.7.17 && \ cp /root/.local/bin/uv /usr/local/bin/uv @@ -7,17 +13,20 @@ RUN curl -Ls https://astral.sh/uv/install.sh | sh -s -- v0.7.17 && \ # set workdir WORKDIR /app -# copy dependencies first to leverage Docker cache -COPY pyproject.toml uv.lock* requirements*.txt* ./ +# copy the full project source +COPY . . +run ls -la + +# install dependencies using uv ENV UV_PROJECT_ENVIRONMENT="/usr/local/" RUN uv sync --locked --no-dev -# copy the full project source -COPY ./.. . +# migrate with Alembic +RUN python db/base.py create_all # expose FastAPI's default dev port EXPOSE 8000 -# default command (run the development server) -CMD [] +# default command (run database migrations and the FastAPI development server) +CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"] diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml deleted file mode 100644 index 236d08a38..000000000 --- a/docker/docker-compose.yml +++ /dev/null @@ -1,16 +0,0 @@ -services: - db: - build: - context: ./db - dockerfile: Dockerfile - environment: - - POSTGRES_USER=${POSTGRES_USER} - - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} - - POSTGRES_DB=${POSTGRES_DB} - ports: - - 5432:5432 - volumes: - - postgres_data:/var/lib/postgresql/data - -volumes: - postgres_data: \ No newline at end of file From 8cc19e9beb32f74e9dbb764894934d16d3c3b549 Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Tue, 15 Jul 2025 11:44:44 -0600 Subject: [PATCH 08/38] fix: update Dockerfile and docker-compose.yml --- .pre-commit-config.yaml | 8 ++++---- alembic/env.py | 17 ++++++++++++++--- requirements.txt | 1 + 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a805a377e..de1f0749c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -15,7 +15,7 @@ repos: '--statistics' ] - - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.10.0 # Use the latest stable version or pin to your preference - hooks: - - id: mypy \ No newline at end of file + # - repo: https://github.com/pre-commit/mirrors-mypy + # rev: v1.10.0 # Use the latest stable version or pin to your preference + # hooks: + # - id: mypy \ No newline at end of file diff --git a/alembic/env.py b/alembic/env.py index 9f73c07a4..491cec89f 100644 --- a/alembic/env.py +++ b/alembic/env.py @@ -1,9 +1,10 @@ +from alembic import context +from dotenv import load_dotenv from logging.config import fileConfig - +from os import environ from sqlalchemy import engine_from_config from sqlalchemy import pool -from alembic import context # this is the Alembic Config object, which provides # access to the values within the .ini file in use. @@ -19,7 +20,7 @@ # from myapp import mymodel # from db import Base # Import your Base from models/__init__.py -from db import * +from db import Base # target_metadata = mymodel.Base.metadata target_metadata = Base.metadata @@ -28,6 +29,16 @@ # can be acquired: # my_important_option = config.get_main_option("my_important_option") # ... etc. +load_dotenv() +user = environ.get("POSTGRES_USER", None) +password = environ.get("POSTGRES_PASSWORD", None) +db = environ.get("POSTGRES_DB", None) +host = environ.get("POSTGRES_HOST", "db") +port = environ.get("POSTGRES_PORT", "5432") + +SQLALCHEMY_DATABASE_URL = f"postgresql+psycopg2://{user}:{password}@{host}:{port}/{db}" +print(SQLALCHEMY_DATABASE_URL) +config.set_main_option("sqlalchemy.url", SQLALCHEMY_DATABASE_URL) def run_migrations_offline() -> None: diff --git a/requirements.txt b/requirements.txt index f12eec89f..aad3d45f3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -63,6 +63,7 @@ pyjwt==2.10.1 pyshp==2.3.1 pytest==8.4.0 python-dateutil==2.9.0.post0 +python-dotenv python-multipart==0.0.20 requests==2.32.4 rsa==4.9.1 From 039d157f70a20535762949ac9683f0a470e9b6b6 Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Tue, 15 Jul 2025 11:53:16 -0600 Subject: [PATCH 09/38] fix: archive timescale db dockerfile --- docker/{db => timescale_db_extension}/Dockerfile | 0 docker/{db => timescale_db_extension}/postgis.d/initdb-postgis.sh | 0 docker/{db => timescale_db_extension}/postgis.d/update-postgis.sh | 0 .../timescaledb.d/000_install_timescaledb.sh | 0 .../timescaledb.d/001_timescaledb_tune.sh | 0 5 files changed, 0 insertions(+), 0 deletions(-) rename docker/{db => timescale_db_extension}/Dockerfile (100%) rename docker/{db => timescale_db_extension}/postgis.d/initdb-postgis.sh (100%) rename docker/{db => timescale_db_extension}/postgis.d/update-postgis.sh (100%) rename docker/{db => timescale_db_extension}/timescaledb.d/000_install_timescaledb.sh (100%) rename docker/{db => timescale_db_extension}/timescaledb.d/001_timescaledb_tune.sh (100%) diff --git a/docker/db/Dockerfile b/docker/timescale_db_extension/Dockerfile similarity index 100% rename from docker/db/Dockerfile rename to docker/timescale_db_extension/Dockerfile diff --git a/docker/db/postgis.d/initdb-postgis.sh b/docker/timescale_db_extension/postgis.d/initdb-postgis.sh similarity index 100% rename from docker/db/postgis.d/initdb-postgis.sh rename to docker/timescale_db_extension/postgis.d/initdb-postgis.sh diff --git a/docker/db/postgis.d/update-postgis.sh b/docker/timescale_db_extension/postgis.d/update-postgis.sh similarity index 100% rename from docker/db/postgis.d/update-postgis.sh rename to docker/timescale_db_extension/postgis.d/update-postgis.sh diff --git a/docker/db/timescaledb.d/000_install_timescaledb.sh b/docker/timescale_db_extension/timescaledb.d/000_install_timescaledb.sh similarity index 100% rename from docker/db/timescaledb.d/000_install_timescaledb.sh rename to docker/timescale_db_extension/timescaledb.d/000_install_timescaledb.sh diff --git a/docker/db/timescaledb.d/001_timescaledb_tune.sh b/docker/timescale_db_extension/timescaledb.d/001_timescaledb_tune.sh similarity index 100% rename from docker/db/timescaledb.d/001_timescaledb_tune.sh rename to docker/timescale_db_extension/timescaledb.d/001_timescaledb_tune.sh From 431d097a1a8caf59c4cb258504b30fe0563d4f2b Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Tue, 15 Jul 2025 11:58:52 -0600 Subject: [PATCH 10/38] feat: create dockerignore --- .dockerignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .dockerignore diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000..b694934fb --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +.venv \ No newline at end of file From 48057fdfd24b2574e3b7a0b9864766082773f260 Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Tue, 15 Jul 2025 12:07:39 -0600 Subject: [PATCH 11/38] feat: update dependencies --- pyproject.toml | 105 ++++++++--- requirements.txt | 4 +- uv.lock | 473 +++++++++++++++++++++++++++++++++++------------ 3 files changed, 435 insertions(+), 147 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 2a778ac27..87bcedc88 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,32 +5,91 @@ description = "Add your description here" readme = "README.md" requires-python = ">=3.13" dependencies = [ - "aiosqlite>=0.21.0", - "alembic>=1.16.1", - "asyncpg>=0.30.0", - "bcrypt>=4.3.0", - "cloud-sql-python-connector>=1.18.2", - "email-validator>=2.2.0", - "fastadmin>=0.2.22", - "fastapi>=0.115.12", - "fastapi-pagination>=0.13.2", - "geoalchemy2>=0.17.1", - "google-cloud-storage>=3.1.1", - "greenlet>=3.2.2", - "gunicorn>=23.0.0", - "httpx>=0.28.1", + "aiofiles==24.1.0", + "aiohappyeyeballs==2.6.1", + "aiohttp==3.12.13", + "aiosignal==1.3.2", + "aiosqlite==0.21.0", + "alembic==1.16.1", + "annotated-types==0.7.0", + "anyio==4.9.0", + "asgiref==3.8.1", + "asn1crypto==1.5.1", + "asyncpg==0.30.0", + "attrs==25.3.0", + "bcrypt==4.3.0", + "cachetools==5.5.2", + "certifi==2025.4.26", + "cffi==1.17.1", + "charset-normalizer==3.4.2", + "click==8.2.1", + "cloud-sql-python-connector==1.18.2", + "cryptography==45.0.4", + "dnspython==2.7.0", + "email-validator==2.2.0", + "fastadmin==0.2.22", + "fastapi==0.115.12", + "fastapi-pagination==0.13.2", + "frozenlist==1.7.0", + "geoalchemy2==0.17.1", + "google-api-core==2.25.1", + "google-auth==2.40.3", + "google-cloud-core==2.4.3", + "google-cloud-storage==3.1.1", + "google-crc32c==1.7.1", + "google-resumable-media==2.7.2", + "googleapis-common-protos==1.70.0", + "greenlet==3.2.2", + "gunicorn==23.0.0", + "h11==0.16.0", + "httpcore==1.0.9", + "httpx==0.28.1", + "idna==3.10", + "iniconfig==2.1.0", + "mako==1.3.10", + "markupsafe==3.0.2", + "multidict==6.6.3", + "numpy==2.3.0", + "packaging==25.0", "pandas>=2.3.0", - "pg8000>=1.31.2", - "phonenumbers>=9.0.7", - "pillow>=11.2.1", - "psycopg2>=2.9.10", + "pg8000==1.31.2", + "phonenumbers==9.0.7", + "pillow==11.3.0", + "pluggy==1.6.0", + "pre-commit>=4.2.0", + "propcache==0.3.2", + "proto-plus==1.26.1", + "protobuf==6.31.1", + "psycopg2==2.9.10", + "pyasn1==0.6.1", + "pyasn1-modules==0.4.2", + "pycparser==2.22", + "pydantic==2.11.5", + "pydantic-core==2.33.2", + "pygments==2.19.1", + "pyjwt==2.10.1", "pyproj>=3.7.1", - "pyshp>=2.3.1", - "python-multipart>=0.0.20", - "shapely>=2.1.1", + "pyshp==2.3.1", + "pytest==8.4.0", + "python-dateutil==2.9.0.post0", + "python-dotenv>=1.0.0", + "python-multipart==0.0.20", + "requests==2.32.4", + "rsa==4.9.1", + "scramp==1.4.5", + "shapely==2.1.1", + "six==1.17.0", + "sniffio==1.3.1", + "sqlalchemy==2.0.41", "sqlalchemy-continuum>=1.4.2", - "sqlalchemy-searchable>=2.1.0", - "uvicorn>=0.34.3", + "sqlalchemy-searchable==2.1.0", + "sqlalchemy-utils==0.41.2", + "starlette==0.46.2", + "typing-extensions==4.14.0", + "typing-inspection==0.4.1", + "urllib3==2.5.0", + "uvicorn==0.34.3", + "yarl==1.20.1", ] [tool.alembic] diff --git a/requirements.txt b/requirements.txt index aad3d45f3..94fe1eb39 100644 --- a/requirements.txt +++ b/requirements.txt @@ -48,7 +48,7 @@ pg8000==1.31.2 phonenumbers==9.0.7 pillow==11.3.0 pluggy==1.6.0 -pre-commit +pre-commit>=4.2.0 propcache==0.3.2 proto-plus==1.26.1 protobuf==6.31.1 @@ -63,7 +63,7 @@ pyjwt==2.10.1 pyshp==2.3.1 pytest==8.4.0 python-dateutil==2.9.0.post0 -python-dotenv +python-dotenv>=1.0.0 python-multipart==0.0.20 requests==2.32.4 rsa==4.9.1 diff --git a/uv.lock b/uv.lock index 0f914e5f8..b3246d93d 100644 --- a/uv.lock +++ b/uv.lock @@ -80,16 +80,16 @@ wheels = [ [[package]] name = "alembic" -version = "1.16.2" +version = "1.16.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mako" }, { name = "sqlalchemy" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9c/35/116797ff14635e496bbda0c168987f5326a6555b09312e9b817e360d1f56/alembic-1.16.2.tar.gz", hash = "sha256:e53c38ff88dadb92eb22f8b150708367db731d58ad7e9d417c9168ab516cbed8", size = 1963563, upload-time = "2025-06-16T18:05:08.566Z" } +sdist = { url = "https://files.pythonhosted.org/packages/20/89/bfb4fe86e3fc3972d35431af7bedbc60fa606e8b17196704a1747f7aa4c3/alembic-1.16.1.tar.gz", hash = "sha256:43d37ba24b3d17bc1eb1024fe0f51cd1dc95aeb5464594a02c6bb9ca9864bfa4", size = 1955006, upload-time = "2025-05-21T23:11:05.991Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/dd/e2/88e425adac5ad887a087c38d04fe2030010572a3e0e627f8a6e8c33eeda8/alembic-1.16.2-py3-none-any.whl", hash = "sha256:5f42e9bd0afdbd1d5e3ad856c01754530367debdebf21ed6894e34af52b3bb03", size = 242717, upload-time = "2025-06-16T18:05:10.27Z" }, + { url = "https://files.pythonhosted.org/packages/31/59/565286efff3692c5716c212202af61466480f6357c4ae3089d4453bff1f3/alembic-1.16.1-py3-none-any.whl", hash = "sha256:0cdd48acada30d93aa1035767d67dff25702f8de74d7c3919f2e8492c8db2e67", size = 242488, upload-time = "2025-05-21T23:11:07.783Z" }, ] [[package]] @@ -218,11 +218,11 @@ wheels = [ [[package]] name = "certifi" -version = "2025.6.15" +version = "2025.4.26" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/73/f7/f14b46d4bcd21092d7d3ccef689615220d8a08fb25e564b65d20738e672e/certifi-2025.6.15.tar.gz", hash = "sha256:d747aa5a8b9bbbb1bb8c22bb13e22bd1f18e9796defa16bab421f7f7a317323b", size = 158753, upload-time = "2025-06-15T02:45:51.329Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e8/9e/c05b3920a3b7d20d3d3310465f50348e5b3694f4f88c6daf736eef3024c4/certifi-2025.4.26.tar.gz", hash = "sha256:0a816057ea3cdefcef70270d2c515e4506bbc954f417fa5ade2021213bb8f0c6", size = 160705, upload-time = "2025-04-26T02:12:29.51Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/84/ae/320161bd181fc06471eed047ecce67b693fd7515b16d495d8932db763426/certifi-2025.6.15-py3-none-any.whl", hash = "sha256:2e0c7ce7cb5d8f8634ca55d2ba7e6ec2689a2fd6537d8dec1296a477a4910057", size = 157650, upload-time = "2025-06-15T02:45:49.977Z" }, + { url = "https://files.pythonhosted.org/packages/4a/7e/3db2bd1b1f9e95f7cddca6d6e75e2f2bd9f51b1246e546d88addca0106bd/certifi-2025.4.26-py3-none-any.whl", hash = "sha256:30350364dfe371162649852c63336a15c70c6510c2ad5015b21c2345311805f3", size = 159618, upload-time = "2025-04-26T02:12:27.662Z" }, ] [[package]] @@ -247,6 +247,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7c/fc/6a8cb64e5f0324877d503c854da15d76c1e50eb722e320b15345c4d0c6de/cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a", size = 182009, upload-time = "2024-09-04T20:44:45.309Z" }, ] +[[package]] +name = "cfgv" +version = "3.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/11/74/539e56497d9bd1d484fd863dd69cbbfa653cd2aa27abfe35653494d85e94/cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560", size = 7114, upload-time = "2023-08-12T20:38:17.776Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c5/55/51844dd50c4fc7a33b653bfaba4c2456f06955289ca770a5dbd5fd267374/cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9", size = 7249, upload-time = "2023-08-12T20:38:16.269Z" }, +] + [[package]] name = "charset-normalizer" version = "3.4.2" @@ -309,37 +318,46 @@ wheels = [ [[package]] name = "cryptography" -version = "45.0.5" +version = "45.0.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/95/1e/49527ac611af559665f71cbb8f92b332b5ec9c6fbc4e88b0f8e92f5e85df/cryptography-45.0.5.tar.gz", hash = "sha256:72e76caa004ab63accdf26023fccd1d087f6d90ec6048ff33ad0445abf7f605a", size = 744903, upload-time = "2025-07-02T13:06:25.941Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f0/fb/09e28bc0c46d2c547085e60897fea96310574c70fb21cd58a730a45f3403/cryptography-45.0.5-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:101ee65078f6dd3e5a028d4f19c07ffa4dd22cce6a20eaa160f8b5219911e7d8", size = 7043092, upload-time = "2025-07-02T13:05:01.514Z" }, - { url = "https://files.pythonhosted.org/packages/b1/05/2194432935e29b91fb649f6149c1a4f9e6d3d9fc880919f4ad1bcc22641e/cryptography-45.0.5-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3a264aae5f7fbb089dbc01e0242d3b67dffe3e6292e1f5182122bdf58e65215d", size = 4205926, upload-time = "2025-07-02T13:05:04.741Z" }, - { url = "https://files.pythonhosted.org/packages/07/8b/9ef5da82350175e32de245646b1884fc01124f53eb31164c77f95a08d682/cryptography-45.0.5-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e74d30ec9c7cb2f404af331d5b4099a9b322a8a6b25c4632755c8757345baac5", size = 4429235, upload-time = "2025-07-02T13:05:07.084Z" }, - { url = "https://files.pythonhosted.org/packages/7c/e1/c809f398adde1994ee53438912192d92a1d0fc0f2d7582659d9ef4c28b0c/cryptography-45.0.5-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:3af26738f2db354aafe492fb3869e955b12b2ef2e16908c8b9cb928128d42c57", size = 4209785, upload-time = "2025-07-02T13:05:09.321Z" }, - { url = "https://files.pythonhosted.org/packages/d0/8b/07eb6bd5acff58406c5e806eff34a124936f41a4fb52909ffa4d00815f8c/cryptography-45.0.5-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e6c00130ed423201c5bc5544c23359141660b07999ad82e34e7bb8f882bb78e0", size = 3893050, upload-time = "2025-07-02T13:05:11.069Z" }, - { url = "https://files.pythonhosted.org/packages/ec/ef/3333295ed58d900a13c92806b67e62f27876845a9a908c939f040887cca9/cryptography-45.0.5-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:dd420e577921c8c2d31289536c386aaa30140b473835e97f83bc71ea9d2baf2d", size = 4457379, upload-time = "2025-07-02T13:05:13.32Z" }, - { url = "https://files.pythonhosted.org/packages/d9/9d/44080674dee514dbb82b21d6fa5d1055368f208304e2ab1828d85c9de8f4/cryptography-45.0.5-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:d05a38884db2ba215218745f0781775806bde4f32e07b135348355fe8e4991d9", size = 4209355, upload-time = "2025-07-02T13:05:15.017Z" }, - { url = "https://files.pythonhosted.org/packages/c9/d8/0749f7d39f53f8258e5c18a93131919ac465ee1f9dccaf1b3f420235e0b5/cryptography-45.0.5-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:ad0caded895a00261a5b4aa9af828baede54638754b51955a0ac75576b831b27", size = 4456087, upload-time = "2025-07-02T13:05:16.945Z" }, - { url = "https://files.pythonhosted.org/packages/09/d7/92acac187387bf08902b0bf0699816f08553927bdd6ba3654da0010289b4/cryptography-45.0.5-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9024beb59aca9d31d36fcdc1604dd9bbeed0a55bface9f1908df19178e2f116e", size = 4332873, upload-time = "2025-07-02T13:05:18.743Z" }, - { url = "https://files.pythonhosted.org/packages/03/c2/840e0710da5106a7c3d4153c7215b2736151bba60bf4491bdb421df5056d/cryptography-45.0.5-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:91098f02ca81579c85f66df8a588c78f331ca19089763d733e34ad359f474174", size = 4564651, upload-time = "2025-07-02T13:05:21.382Z" }, - { url = "https://files.pythonhosted.org/packages/2e/92/cc723dd6d71e9747a887b94eb3827825c6c24b9e6ce2bb33b847d31d5eaa/cryptography-45.0.5-cp311-abi3-win32.whl", hash = "sha256:926c3ea71a6043921050eaa639137e13dbe7b4ab25800932a8498364fc1abec9", size = 2929050, upload-time = "2025-07-02T13:05:23.39Z" }, - { url = "https://files.pythonhosted.org/packages/1f/10/197da38a5911a48dd5389c043de4aec4b3c94cb836299b01253940788d78/cryptography-45.0.5-cp311-abi3-win_amd64.whl", hash = "sha256:b85980d1e345fe769cfc57c57db2b59cff5464ee0c045d52c0df087e926fbe63", size = 3403224, upload-time = "2025-07-02T13:05:25.202Z" }, - { url = "https://files.pythonhosted.org/packages/fe/2b/160ce8c2765e7a481ce57d55eba1546148583e7b6f85514472b1d151711d/cryptography-45.0.5-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:f3562c2f23c612f2e4a6964a61d942f891d29ee320edb62ff48ffb99f3de9ae8", size = 7017143, upload-time = "2025-07-02T13:05:27.229Z" }, - { url = "https://files.pythonhosted.org/packages/c2/e7/2187be2f871c0221a81f55ee3105d3cf3e273c0a0853651d7011eada0d7e/cryptography-45.0.5-cp37-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3fcfbefc4a7f332dece7272a88e410f611e79458fab97b5efe14e54fe476f4fd", size = 4197780, upload-time = "2025-07-02T13:05:29.299Z" }, - { url = "https://files.pythonhosted.org/packages/b9/cf/84210c447c06104e6be9122661159ad4ce7a8190011669afceeaea150524/cryptography-45.0.5-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:460f8c39ba66af7db0545a8c6f2eabcbc5a5528fc1cf6c3fa9a1e44cec33385e", size = 4420091, upload-time = "2025-07-02T13:05:31.221Z" }, - { url = "https://files.pythonhosted.org/packages/3e/6a/cb8b5c8bb82fafffa23aeff8d3a39822593cee6e2f16c5ca5c2ecca344f7/cryptography-45.0.5-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:9b4cf6318915dccfe218e69bbec417fdd7c7185aa7aab139a2c0beb7468c89f0", size = 4198711, upload-time = "2025-07-02T13:05:33.062Z" }, - { url = "https://files.pythonhosted.org/packages/04/f7/36d2d69df69c94cbb2473871926daf0f01ad8e00fe3986ac3c1e8c4ca4b3/cryptography-45.0.5-cp37-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2089cc8f70a6e454601525e5bf2779e665d7865af002a5dec8d14e561002e135", size = 3883299, upload-time = "2025-07-02T13:05:34.94Z" }, - { url = "https://files.pythonhosted.org/packages/82/c7/f0ea40f016de72f81288e9fe8d1f6748036cb5ba6118774317a3ffc6022d/cryptography-45.0.5-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:0027d566d65a38497bc37e0dd7c2f8ceda73597d2ac9ba93810204f56f52ebc7", size = 4450558, upload-time = "2025-07-02T13:05:37.288Z" }, - { url = "https://files.pythonhosted.org/packages/06/ae/94b504dc1a3cdf642d710407c62e86296f7da9e66f27ab12a1ee6fdf005b/cryptography-45.0.5-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:be97d3a19c16a9be00edf79dca949c8fa7eff621763666a145f9f9535a5d7f42", size = 4198020, upload-time = "2025-07-02T13:05:39.102Z" }, - { url = "https://files.pythonhosted.org/packages/05/2b/aaf0adb845d5dabb43480f18f7ca72e94f92c280aa983ddbd0bcd6ecd037/cryptography-45.0.5-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:7760c1c2e1a7084153a0f68fab76e754083b126a47d0117c9ed15e69e2103492", size = 4449759, upload-time = "2025-07-02T13:05:41.398Z" }, - { url = "https://files.pythonhosted.org/packages/91/e4/f17e02066de63e0100a3a01b56f8f1016973a1d67551beaf585157a86b3f/cryptography-45.0.5-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:6ff8728d8d890b3dda5765276d1bc6fb099252915a2cd3aff960c4c195745dd0", size = 4319991, upload-time = "2025-07-02T13:05:43.64Z" }, - { url = "https://files.pythonhosted.org/packages/f2/2e/e2dbd629481b499b14516eed933f3276eb3239f7cee2dcfa4ee6b44d4711/cryptography-45.0.5-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:7259038202a47fdecee7e62e0fd0b0738b6daa335354396c6ddebdbe1206af2a", size = 4554189, upload-time = "2025-07-02T13:05:46.045Z" }, - { url = "https://files.pythonhosted.org/packages/f8/ea/a78a0c38f4c8736287b71c2ea3799d173d5ce778c7d6e3c163a95a05ad2a/cryptography-45.0.5-cp37-abi3-win32.whl", hash = "sha256:1e1da5accc0c750056c556a93c3e9cb828970206c68867712ca5805e46dc806f", size = 2911769, upload-time = "2025-07-02T13:05:48.329Z" }, - { url = "https://files.pythonhosted.org/packages/79/b3/28ac139109d9005ad3f6b6f8976ffede6706a6478e21c889ce36c840918e/cryptography-45.0.5-cp37-abi3-win_amd64.whl", hash = "sha256:90cb0a7bb35959f37e23303b7eed0a32280510030daba3f7fdfbb65defde6a97", size = 3390016, upload-time = "2025-07-02T13:05:50.811Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/fe/c8/a2a376a8711c1e11708b9c9972e0c3223f5fc682552c82d8db844393d6ce/cryptography-45.0.4.tar.gz", hash = "sha256:7405ade85c83c37682c8fe65554759800a4a8c54b2d96e0f8ad114d31b808d57", size = 744890, upload-time = "2025-06-10T00:03:51.297Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cc/1c/92637793de053832523b410dbe016d3f5c11b41d0cf6eef8787aabb51d41/cryptography-45.0.4-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:425a9a6ac2823ee6e46a76a21a4e8342d8fa5c01e08b823c1f19a8b74f096069", size = 7055712, upload-time = "2025-06-10T00:02:38.826Z" }, + { url = "https://files.pythonhosted.org/packages/ba/14/93b69f2af9ba832ad6618a03f8a034a5851dc9a3314336a3d71c252467e1/cryptography-45.0.4-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:680806cf63baa0039b920f4976f5f31b10e772de42f16310a6839d9f21a26b0d", size = 4205335, upload-time = "2025-06-10T00:02:41.64Z" }, + { url = "https://files.pythonhosted.org/packages/67/30/fae1000228634bf0b647fca80403db5ca9e3933b91dd060570689f0bd0f7/cryptography-45.0.4-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4ca0f52170e821bc8da6fc0cc565b7bb8ff8d90d36b5e9fdd68e8a86bdf72036", size = 4431487, upload-time = "2025-06-10T00:02:43.696Z" }, + { url = "https://files.pythonhosted.org/packages/6d/5a/7dffcf8cdf0cb3c2430de7404b327e3db64735747d641fc492539978caeb/cryptography-45.0.4-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:f3fe7a5ae34d5a414957cc7f457e2b92076e72938423ac64d215722f6cf49a9e", size = 4208922, upload-time = "2025-06-10T00:02:45.334Z" }, + { url = "https://files.pythonhosted.org/packages/c6/f3/528729726eb6c3060fa3637253430547fbaaea95ab0535ea41baa4a6fbd8/cryptography-45.0.4-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:25eb4d4d3e54595dc8adebc6bbd5623588991d86591a78c2548ffb64797341e2", size = 3900433, upload-time = "2025-06-10T00:02:47.359Z" }, + { url = "https://files.pythonhosted.org/packages/d9/4a/67ba2e40f619e04d83c32f7e1d484c1538c0800a17c56a22ff07d092ccc1/cryptography-45.0.4-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:ce1678a2ccbe696cf3af15a75bb72ee008d7ff183c9228592ede9db467e64f1b", size = 4464163, upload-time = "2025-06-10T00:02:49.412Z" }, + { url = "https://files.pythonhosted.org/packages/7e/9a/b4d5aa83661483ac372464809c4b49b5022dbfe36b12fe9e323ca8512420/cryptography-45.0.4-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:49fe9155ab32721b9122975e168a6760d8ce4cffe423bcd7ca269ba41b5dfac1", size = 4208687, upload-time = "2025-06-10T00:02:50.976Z" }, + { url = "https://files.pythonhosted.org/packages/db/b7/a84bdcd19d9c02ec5807f2ec2d1456fd8451592c5ee353816c09250e3561/cryptography-45.0.4-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:2882338b2a6e0bd337052e8b9007ced85c637da19ef9ecaf437744495c8c2999", size = 4463623, upload-time = "2025-06-10T00:02:52.542Z" }, + { url = "https://files.pythonhosted.org/packages/d8/84/69707d502d4d905021cac3fb59a316344e9f078b1da7fb43ecde5e10840a/cryptography-45.0.4-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:23b9c3ea30c3ed4db59e7b9619272e94891f8a3a5591d0b656a7582631ccf750", size = 4332447, upload-time = "2025-06-10T00:02:54.63Z" }, + { url = "https://files.pythonhosted.org/packages/f3/ee/d4f2ab688e057e90ded24384e34838086a9b09963389a5ba6854b5876598/cryptography-45.0.4-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b0a97c927497e3bc36b33987abb99bf17a9a175a19af38a892dc4bbb844d7ee2", size = 4572830, upload-time = "2025-06-10T00:02:56.689Z" }, + { url = "https://files.pythonhosted.org/packages/70/d4/994773a261d7ff98034f72c0e8251fe2755eac45e2265db4c866c1c6829c/cryptography-45.0.4-cp311-abi3-win32.whl", hash = "sha256:e00a6c10a5c53979d6242f123c0a97cff9f3abed7f064fc412c36dc521b5f257", size = 2932769, upload-time = "2025-06-10T00:02:58.467Z" }, + { url = "https://files.pythonhosted.org/packages/5a/42/c80bd0b67e9b769b364963b5252b17778a397cefdd36fa9aa4a5f34c599a/cryptography-45.0.4-cp311-abi3-win_amd64.whl", hash = "sha256:817ee05c6c9f7a69a16200f0c90ab26d23a87701e2a284bd15156783e46dbcc8", size = 3410441, upload-time = "2025-06-10T00:03:00.14Z" }, + { url = "https://files.pythonhosted.org/packages/ce/0b/2488c89f3a30bc821c9d96eeacfcab6ff3accc08a9601ba03339c0fd05e5/cryptography-45.0.4-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:964bcc28d867e0f5491a564b7debb3ffdd8717928d315d12e0d7defa9e43b723", size = 7031836, upload-time = "2025-06-10T00:03:01.726Z" }, + { url = "https://files.pythonhosted.org/packages/fe/51/8c584ed426093aac257462ae62d26ad61ef1cbf5b58d8b67e6e13c39960e/cryptography-45.0.4-cp37-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:6a5bf57554e80f75a7db3d4b1dacaa2764611ae166ab42ea9a72bcdb5d577637", size = 4195746, upload-time = "2025-06-10T00:03:03.94Z" }, + { url = "https://files.pythonhosted.org/packages/5c/7d/4b0ca4d7af95a704eef2f8f80a8199ed236aaf185d55385ae1d1610c03c2/cryptography-45.0.4-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:46cf7088bf91bdc9b26f9c55636492c1cce3e7aaf8041bbf0243f5e5325cfb2d", size = 4424456, upload-time = "2025-06-10T00:03:05.589Z" }, + { url = "https://files.pythonhosted.org/packages/1d/45/5fabacbc6e76ff056f84d9f60eeac18819badf0cefc1b6612ee03d4ab678/cryptography-45.0.4-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:7bedbe4cc930fa4b100fc845ea1ea5788fcd7ae9562e669989c11618ae8d76ee", size = 4198495, upload-time = "2025-06-10T00:03:09.172Z" }, + { url = "https://files.pythonhosted.org/packages/55/b7/ffc9945b290eb0a5d4dab9b7636706e3b5b92f14ee5d9d4449409d010d54/cryptography-45.0.4-cp37-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:eaa3e28ea2235b33220b949c5a0d6cf79baa80eab2eb5607ca8ab7525331b9ff", size = 3885540, upload-time = "2025-06-10T00:03:10.835Z" }, + { url = "https://files.pythonhosted.org/packages/7f/e3/57b010282346980475e77d414080acdcb3dab9a0be63071efc2041a2c6bd/cryptography-45.0.4-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:7ef2dde4fa9408475038fc9aadfc1fb2676b174e68356359632e980c661ec8f6", size = 4452052, upload-time = "2025-06-10T00:03:12.448Z" }, + { url = "https://files.pythonhosted.org/packages/37/e6/ddc4ac2558bf2ef517a358df26f45bc774a99bf4653e7ee34b5e749c03e3/cryptography-45.0.4-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:6a3511ae33f09094185d111160fd192c67aa0a2a8d19b54d36e4c78f651dc5ad", size = 4198024, upload-time = "2025-06-10T00:03:13.976Z" }, + { url = "https://files.pythonhosted.org/packages/3a/c0/85fa358ddb063ec588aed4a6ea1df57dc3e3bc1712d87c8fa162d02a65fc/cryptography-45.0.4-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:06509dc70dd71fa56eaa138336244e2fbaf2ac164fc9b5e66828fccfd2b680d6", size = 4451442, upload-time = "2025-06-10T00:03:16.248Z" }, + { url = "https://files.pythonhosted.org/packages/33/67/362d6ec1492596e73da24e669a7fbbaeb1c428d6bf49a29f7a12acffd5dc/cryptography-45.0.4-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:5f31e6b0a5a253f6aa49be67279be4a7e5a4ef259a9f33c69f7d1b1191939872", size = 4325038, upload-time = "2025-06-10T00:03:18.4Z" }, + { url = "https://files.pythonhosted.org/packages/53/75/82a14bf047a96a1b13ebb47fb9811c4f73096cfa2e2b17c86879687f9027/cryptography-45.0.4-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:944e9ccf67a9594137f942d5b52c8d238b1b4e46c7a0c2891b7ae6e01e7c80a4", size = 4560964, upload-time = "2025-06-10T00:03:20.06Z" }, + { url = "https://files.pythonhosted.org/packages/cd/37/1a3cba4c5a468ebf9b95523a5ef5651244693dc712001e276682c278fc00/cryptography-45.0.4-cp37-abi3-win32.whl", hash = "sha256:c22fe01e53dc65edd1945a2e6f0015e887f84ced233acecb64b4daadb32f5c97", size = 2924557, upload-time = "2025-06-10T00:03:22.563Z" }, + { url = "https://files.pythonhosted.org/packages/2a/4b/3256759723b7e66380397d958ca07c59cfc3fb5c794fb5516758afd05d41/cryptography-45.0.4-cp37-abi3-win_amd64.whl", hash = "sha256:627ba1bc94f6adf0b0a2e35d87020285ead22d9f648c7e75bb64f367375f3b22", size = 3395508, upload-time = "2025-06-10T00:03:24.586Z" }, +] + +[[package]] +name = "distlib" +version = "0.3.9" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0d/dd/1bec4c5ddb504ca60fc29472f3d27e8d4da1257a854e1d96742f15c1d02d/distlib-0.3.9.tar.gz", hash = "sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403", size = 613923, upload-time = "2024-10-09T18:35:47.551Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/91/a1/cf2472db20f7ce4a6be1253a81cfdf85ad9c7885ffbed7047fb72c24cf87/distlib-0.3.9-py2.py3-none-any.whl", hash = "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87", size = 468973, upload-time = "2024-10-09T18:35:44.272Z" }, ] [[package]] @@ -379,30 +397,39 @@ wheels = [ [[package]] name = "fastapi" -version = "0.115.14" +version = "0.115.12" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pydantic" }, { name = "starlette" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ca/53/8c38a874844a8b0fa10dd8adf3836ac154082cf88d3f22b544e9ceea0a15/fastapi-0.115.14.tar.gz", hash = "sha256:b1de15cdc1c499a4da47914db35d0e4ef8f1ce62b624e94e0e5824421df99739", size = 296263, upload-time = "2025-06-26T15:29:08.21Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f4/55/ae499352d82338331ca1e28c7f4a63bfd09479b16395dce38cf50a39e2c2/fastapi-0.115.12.tar.gz", hash = "sha256:1e2c2a2646905f9e83d32f04a3f86aff4a286669c6c950ca95b5fd68c2602681", size = 295236, upload-time = "2025-03-23T22:55:43.822Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/53/50/b1222562c6d270fea83e9c9075b8e8600b8479150a18e4516a6138b980d1/fastapi-0.115.14-py3-none-any.whl", hash = "sha256:6c0c8bf9420bd58f565e585036d971872472b4f7d3f6c73b698e10cffdefb3ca", size = 95514, upload-time = "2025-06-26T15:29:06.49Z" }, + { url = "https://files.pythonhosted.org/packages/50/b3/b51f09c2ba432a576fe63758bddc81f78f0c6309d9e5c10d194313bf021e/fastapi-0.115.12-py3-none-any.whl", hash = "sha256:e94613d6c05e27be7ffebdd6ea5f388112e5e430c8f7d6494a9d1d88d43e814d", size = 95164, upload-time = "2025-03-23T22:55:42.101Z" }, ] [[package]] name = "fastapi-pagination" -version = "0.13.3" +version = "0.13.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "fastapi" }, { name = "pydantic" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/10/4c/e98a1665b6ac2e9e4ed98450e4e0ea48108f3bc52de517d9a70cc22761c2/fastapi_pagination-0.13.3.tar.gz", hash = "sha256:40c2383aff13a3a0e4a2742dfbf004572e88458cd8f338d85f90a27e07abab4a", size = 550898, upload-time = "2025-06-25T21:22:15.287Z" } +sdist = { url = "https://files.pythonhosted.org/packages/19/25/fc3c9ed9d99df279acdbf57da1a3a91ffceae9c087882cbe8a9cb1229b1e/fastapi_pagination-0.13.2.tar.gz", hash = "sha256:5e76f129aef706601b86114428ca3ff68715bfa3929bf4df8c7ed27561d7f661", size = 550389, upload-time = "2025-06-07T09:30:44.319Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/bf/73/ef1ab892c2d189d8b6bd72325e9e710df6737c3b7976e12aa5749a56ea01/fastapi_pagination-0.13.3-py3-none-any.whl", hash = "sha256:e1b1cc7fa5c773c61087845ef8a73ed6b516071c057418698b9242461573f44e", size = 50986, upload-time = "2025-06-25T21:22:13.591Z" }, + { url = "https://files.pythonhosted.org/packages/d9/cb/cf2f10d4620b31a77705226c7292f39b4a191cef3485ea42561fc2e157d9/fastapi_pagination-0.13.2-py3-none-any.whl", hash = "sha256:d2ec66ffda5cd9c1d665521f3916b16ebbb15d5010a945449292540ef70c4d9a", size = 50404, upload-time = "2025-06-07T09:30:42.218Z" }, +] + +[[package]] +name = "filelock" +version = "3.18.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0a/10/c23352565a6544bdc5353e0b15fc1c563352101f30e24bf500207a54df9a/filelock-3.18.0.tar.gz", hash = "sha256:adbc88eabb99d2fec8c9c1b229b171f18afa655400173ddc653d5d01501fb9f2", size = 18075, upload-time = "2025-03-14T07:11:40.47Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4d/36/2a115987e2d8c300a974597416d9de88f2444426de9571f4b59b2cca3acc/filelock-3.18.0-py3-none-any.whl", hash = "sha256:c401f4f8377c4464e6db25fff06205fd89bdd83b65eb0488ed1b160f780e21de", size = 16215, upload-time = "2025-03-14T07:11:39.145Z" }, ] [[package]] @@ -562,26 +589,27 @@ wheels = [ [[package]] name = "greenlet" -version = "3.2.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c9/92/bb85bd6e80148a4d2e0c59f7c0c2891029f8fd510183afc7d8d2feeed9b6/greenlet-3.2.3.tar.gz", hash = "sha256:8b0dd8ae4c0d6f5e54ee55ba935eeb3d735a9b58a8a1e5b5cbab64e01a39f365", size = 185752, upload-time = "2025-06-05T16:16:09.955Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b1/cf/f5c0b23309070ae93de75c90d29300751a5aacefc0a3ed1b1d8edb28f08b/greenlet-3.2.3-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:500b8689aa9dd1ab26872a34084503aeddefcb438e2e7317b89b11eaea1901ad", size = 270732, upload-time = "2025-06-05T16:10:08.26Z" }, - { url = "https://files.pythonhosted.org/packages/48/ae/91a957ba60482d3fecf9be49bc3948f341d706b52ddb9d83a70d42abd498/greenlet-3.2.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:a07d3472c2a93117af3b0136f246b2833fdc0b542d4a9799ae5f41c28323faef", size = 639033, upload-time = "2025-06-05T16:38:53.983Z" }, - { url = "https://files.pythonhosted.org/packages/6f/df/20ffa66dd5a7a7beffa6451bdb7400d66251374ab40b99981478c69a67a8/greenlet-3.2.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:8704b3768d2f51150626962f4b9a9e4a17d2e37c8a8d9867bbd9fa4eb938d3b3", size = 652999, upload-time = "2025-06-05T16:41:37.89Z" }, - { url = "https://files.pythonhosted.org/packages/51/b4/ebb2c8cb41e521f1d72bf0465f2f9a2fd803f674a88db228887e6847077e/greenlet-3.2.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:5035d77a27b7c62db6cf41cf786cfe2242644a7a337a0e155c80960598baab95", size = 647368, upload-time = "2025-06-05T16:48:21.467Z" }, - { url = "https://files.pythonhosted.org/packages/8e/6a/1e1b5aa10dced4ae876a322155705257748108b7fd2e4fae3f2a091fe81a/greenlet-3.2.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2d8aa5423cd4a396792f6d4580f88bdc6efcb9205891c9d40d20f6e670992efb", size = 650037, upload-time = "2025-06-05T16:13:06.402Z" }, - { url = "https://files.pythonhosted.org/packages/26/f2/ad51331a157c7015c675702e2d5230c243695c788f8f75feba1af32b3617/greenlet-3.2.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2c724620a101f8170065d7dded3f962a2aea7a7dae133a009cada42847e04a7b", size = 608402, upload-time = "2025-06-05T16:12:51.91Z" }, - { url = "https://files.pythonhosted.org/packages/26/bc/862bd2083e6b3aff23300900a956f4ea9a4059de337f5c8734346b9b34fc/greenlet-3.2.3-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:873abe55f134c48e1f2a6f53f7d1419192a3d1a4e873bace00499a4e45ea6af0", size = 1119577, upload-time = "2025-06-05T16:36:49.787Z" }, - { url = "https://files.pythonhosted.org/packages/86/94/1fc0cc068cfde885170e01de40a619b00eaa8f2916bf3541744730ffb4c3/greenlet-3.2.3-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:024571bbce5f2c1cfff08bf3fbaa43bbc7444f580ae13b0099e95d0e6e67ed36", size = 1147121, upload-time = "2025-06-05T16:12:42.527Z" }, - { url = "https://files.pythonhosted.org/packages/27/1a/199f9587e8cb08a0658f9c30f3799244307614148ffe8b1e3aa22f324dea/greenlet-3.2.3-cp313-cp313-win_amd64.whl", hash = "sha256:5195fb1e75e592dd04ce79881c8a22becdfa3e6f500e7feb059b1e6fdd54d3e3", size = 297603, upload-time = "2025-06-05T16:20:12.651Z" }, - { url = "https://files.pythonhosted.org/packages/d8/ca/accd7aa5280eb92b70ed9e8f7fd79dc50a2c21d8c73b9a0856f5b564e222/greenlet-3.2.3-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:3d04332dddb10b4a211b68111dabaee2e1a073663d117dc10247b5b1642bac86", size = 271479, upload-time = "2025-06-05T16:10:47.525Z" }, - { url = "https://files.pythonhosted.org/packages/55/71/01ed9895d9eb49223280ecc98a557585edfa56b3d0e965b9fa9f7f06b6d9/greenlet-3.2.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8186162dffde068a465deab08fc72c767196895c39db26ab1c17c0b77a6d8b97", size = 683952, upload-time = "2025-06-05T16:38:55.125Z" }, - { url = "https://files.pythonhosted.org/packages/ea/61/638c4bdf460c3c678a0a1ef4c200f347dff80719597e53b5edb2fb27ab54/greenlet-3.2.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f4bfbaa6096b1b7a200024784217defedf46a07c2eee1a498e94a1b5f8ec5728", size = 696917, upload-time = "2025-06-05T16:41:38.959Z" }, - { url = "https://files.pythonhosted.org/packages/22/cc/0bd1a7eb759d1f3e3cc2d1bc0f0b487ad3cc9f34d74da4b80f226fde4ec3/greenlet-3.2.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:ed6cfa9200484d234d8394c70f5492f144b20d4533f69262d530a1a082f6ee9a", size = 692443, upload-time = "2025-06-05T16:48:23.113Z" }, - { url = "https://files.pythonhosted.org/packages/67/10/b2a4b63d3f08362662e89c103f7fe28894a51ae0bc890fabf37d1d780e52/greenlet-3.2.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:02b0df6f63cd15012bed5401b47829cfd2e97052dc89da3cfaf2c779124eb892", size = 692995, upload-time = "2025-06-05T16:13:07.972Z" }, - { url = "https://files.pythonhosted.org/packages/5a/c6/ad82f148a4e3ce9564056453a71529732baf5448ad53fc323e37efe34f66/greenlet-3.2.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:86c2d68e87107c1792e2e8d5399acec2487a4e993ab76c792408e59394d52141", size = 655320, upload-time = "2025-06-05T16:12:53.453Z" }, - { url = "https://files.pythonhosted.org/packages/5c/4f/aab73ecaa6b3086a4c89863d94cf26fa84cbff63f52ce9bc4342b3087a06/greenlet-3.2.3-cp314-cp314-win_amd64.whl", hash = "sha256:8c47aae8fbbfcf82cc13327ae802ba13c9c36753b67e760023fd116bc124a62a", size = 301236, upload-time = "2025-06-05T16:15:20.111Z" }, +version = "3.2.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/34/c1/a82edae11d46c0d83481aacaa1e578fea21d94a1ef400afd734d47ad95ad/greenlet-3.2.2.tar.gz", hash = "sha256:ad053d34421a2debba45aa3cc39acf454acbcd025b3fc1a9f8a0dee237abd485", size = 185797, upload-time = "2025-05-09T19:47:35.066Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/89/30/97b49779fff8601af20972a62cc4af0c497c1504dfbb3e93be218e093f21/greenlet-3.2.2-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:3ab7194ee290302ca15449f601036007873028712e92ca15fc76597a0aeb4c59", size = 269150, upload-time = "2025-05-09T14:50:30.784Z" }, + { url = "https://files.pythonhosted.org/packages/21/30/877245def4220f684bc2e01df1c2e782c164e84b32e07373992f14a2d107/greenlet-3.2.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2dc5c43bb65ec3669452af0ab10729e8fdc17f87a1f2ad7ec65d4aaaefabf6bf", size = 637381, upload-time = "2025-05-09T15:24:12.893Z" }, + { url = "https://files.pythonhosted.org/packages/8e/16/adf937908e1f913856b5371c1d8bdaef5f58f251d714085abeea73ecc471/greenlet-3.2.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:decb0658ec19e5c1f519faa9a160c0fc85a41a7e6654b3ce1b44b939f8bf1325", size = 651427, upload-time = "2025-05-09T15:24:51.074Z" }, + { url = "https://files.pythonhosted.org/packages/ad/49/6d79f58fa695b618654adac64e56aff2eeb13344dc28259af8f505662bb1/greenlet-3.2.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6fadd183186db360b61cb34e81117a096bff91c072929cd1b529eb20dd46e6c5", size = 645795, upload-time = "2025-05-09T15:29:26.673Z" }, + { url = "https://files.pythonhosted.org/packages/5a/e6/28ed5cb929c6b2f001e96b1d0698c622976cd8f1e41fe7ebc047fa7c6dd4/greenlet-3.2.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1919cbdc1c53ef739c94cf2985056bcc0838c1f217b57647cbf4578576c63825", size = 648398, upload-time = "2025-05-09T14:53:36.61Z" }, + { url = "https://files.pythonhosted.org/packages/9d/70/b200194e25ae86bc57077f695b6cc47ee3118becf54130c5514456cf8dac/greenlet-3.2.2-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3885f85b61798f4192d544aac7b25a04ece5fe2704670b4ab73c2d2c14ab740d", size = 606795, upload-time = "2025-05-09T14:53:47.039Z" }, + { url = "https://files.pythonhosted.org/packages/f8/c8/ba1def67513a941154ed8f9477ae6e5a03f645be6b507d3930f72ed508d3/greenlet-3.2.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:85f3e248507125bf4af607a26fd6cb8578776197bd4b66e35229cdf5acf1dfbf", size = 1117976, upload-time = "2025-05-09T15:27:06.542Z" }, + { url = "https://files.pythonhosted.org/packages/c3/30/d0e88c1cfcc1b3331d63c2b54a0a3a4a950ef202fb8b92e772ca714a9221/greenlet-3.2.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:1e76106b6fc55fa3d6fe1c527f95ee65e324a13b62e243f77b48317346559708", size = 1145509, upload-time = "2025-05-09T14:54:02.223Z" }, + { url = "https://files.pythonhosted.org/packages/90/2e/59d6491834b6e289051b252cf4776d16da51c7c6ca6a87ff97e3a50aa0cd/greenlet-3.2.2-cp313-cp313-win_amd64.whl", hash = "sha256:fe46d4f8e94e637634d54477b0cfabcf93c53f29eedcbdeecaf2af32029b4421", size = 296023, upload-time = "2025-05-09T14:53:24.157Z" }, + { url = "https://files.pythonhosted.org/packages/65/66/8a73aace5a5335a1cba56d0da71b7bd93e450f17d372c5b7c5fa547557e9/greenlet-3.2.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba30e88607fb6990544d84caf3c706c4b48f629e18853fc6a646f82db9629418", size = 629911, upload-time = "2025-05-09T15:24:22.376Z" }, + { url = "https://files.pythonhosted.org/packages/48/08/c8b8ebac4e0c95dcc68ec99198842e7db53eda4ab3fb0a4e785690883991/greenlet-3.2.2-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:055916fafad3e3388d27dd68517478933a97edc2fc54ae79d3bec827de2c64c4", size = 635251, upload-time = "2025-05-09T15:24:52.205Z" }, + { url = "https://files.pythonhosted.org/packages/37/26/7db30868f73e86b9125264d2959acabea132b444b88185ba5c462cb8e571/greenlet-3.2.2-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2593283bf81ca37d27d110956b79e8723f9aa50c4bcdc29d3c0543d4743d2763", size = 632620, upload-time = "2025-05-09T15:29:28.051Z" }, + { url = "https://files.pythonhosted.org/packages/10/ec/718a3bd56249e729016b0b69bee4adea0dfccf6ca43d147ef3b21edbca16/greenlet-3.2.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89c69e9a10670eb7a66b8cef6354c24671ba241f46152dd3eed447f79c29fb5b", size = 628851, upload-time = "2025-05-09T14:53:38.472Z" }, + { url = "https://files.pythonhosted.org/packages/9b/9d/d1c79286a76bc62ccdc1387291464af16a4204ea717f24e77b0acd623b99/greenlet-3.2.2-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:02a98600899ca1ca5d3a2590974c9e3ec259503b2d6ba6527605fcd74e08e207", size = 593718, upload-time = "2025-05-09T14:53:48.313Z" }, + { url = "https://files.pythonhosted.org/packages/cd/41/96ba2bf948f67b245784cd294b84e3d17933597dffd3acdb367a210d1949/greenlet-3.2.2-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:b50a8c5c162469c3209e5ec92ee4f95c8231b11db6a04db09bbe338176723bb8", size = 1105752, upload-time = "2025-05-09T15:27:08.217Z" }, + { url = "https://files.pythonhosted.org/packages/68/3b/3b97f9d33c1f2eb081759da62bd6162159db260f602f048bc2f36b4c453e/greenlet-3.2.2-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:45f9f4853fb4cc46783085261c9ec4706628f3b57de3e68bae03e8f8b3c0de51", size = 1125170, upload-time = "2025-05-09T14:54:04.082Z" }, + { url = "https://files.pythonhosted.org/packages/31/df/b7d17d66c8d0f578d2885a3d8f565e9e4725eacc9d3fdc946d0031c055c4/greenlet-3.2.2-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:9ea5231428af34226c05f927e16fc7f6fa5e39e3ad3cd24ffa48ba53a47f4240", size = 269899, upload-time = "2025-05-09T14:54:01.581Z" }, ] [[package]] @@ -633,6 +661,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" }, ] +[[package]] +name = "identify" +version = "2.6.12" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/88/d193a27416618628a5eea64e3223acd800b40749a96ffb322a9b55a49ed1/identify-2.6.12.tar.gz", hash = "sha256:d8de45749f1efb108badef65ee8386f0f7bb19a7f26185f74de6367bffbaf0e6", size = 99254, upload-time = "2025-05-23T20:37:53.3Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7a/cd/18f8da995b658420625f7ef13f037be53ae04ec5ad33f9b718240dcfd48c/identify-2.6.12-py2.py3-none-any.whl", hash = "sha256:ad9672d5a72e0d2ff7c5c8809b62dfa60458626352fb0eb7b55e69bdc45334a2", size = 99145, upload-time = "2025-05-23T20:37:51.495Z" }, +] + [[package]] name = "idna" version = "3.10" @@ -741,32 +778,91 @@ name = "nmsamplelocations" version = "0.1.0" source = { virtual = "." } dependencies = [ + { name = "aiofiles" }, + { name = "aiohappyeyeballs" }, + { name = "aiohttp" }, + { name = "aiosignal" }, { name = "aiosqlite" }, { name = "alembic" }, + { name = "annotated-types" }, + { name = "anyio" }, + { name = "asgiref" }, + { name = "asn1crypto" }, { name = "asyncpg" }, + { name = "attrs" }, { name = "bcrypt" }, + { name = "cachetools" }, + { name = "certifi" }, + { name = "cffi" }, + { name = "charset-normalizer" }, + { name = "click" }, { name = "cloud-sql-python-connector" }, + { name = "cryptography" }, + { name = "dnspython" }, { name = "email-validator" }, { name = "fastadmin" }, { name = "fastapi" }, { name = "fastapi-pagination" }, + { name = "frozenlist" }, { name = "geoalchemy2" }, + { name = "google-api-core" }, + { name = "google-auth" }, + { name = "google-cloud-core" }, { name = "google-cloud-storage" }, + { name = "google-crc32c" }, + { name = "google-resumable-media" }, + { name = "googleapis-common-protos" }, { name = "greenlet" }, { name = "gunicorn" }, + { name = "h11" }, + { name = "httpcore" }, { name = "httpx" }, + { name = "idna" }, + { name = "iniconfig" }, + { name = "mako" }, + { name = "markupsafe" }, + { name = "multidict" }, + { name = "numpy" }, + { name = "packaging" }, { name = "pandas" }, { name = "pg8000" }, { name = "phonenumbers" }, { name = "pillow" }, + { name = "pluggy" }, + { name = "pre-commit" }, + { name = "propcache" }, + { name = "proto-plus" }, + { name = "protobuf" }, { name = "psycopg2" }, + { name = "pyasn1" }, + { name = "pyasn1-modules" }, + { name = "pycparser" }, + { name = "pydantic" }, + { name = "pydantic-core" }, + { name = "pygments" }, + { name = "pyjwt" }, { name = "pyproj" }, { name = "pyshp" }, + { name = "pytest" }, + { name = "python-dateutil" }, + { name = "python-dotenv" }, { name = "python-multipart" }, + { name = "requests" }, + { name = "rsa" }, + { name = "scramp" }, { name = "shapely" }, + { name = "six" }, + { name = "sniffio" }, + { name = "sqlalchemy" }, { name = "sqlalchemy-continuum" }, { name = "sqlalchemy-searchable" }, + { name = "sqlalchemy-utils" }, + { name = "starlette" }, + { name = "typing-extensions" }, + { name = "typing-inspection" }, + { name = "urllib3" }, { name = "uvicorn" }, + { name = "yarl" }, ] [package.dev-dependencies] @@ -776,65 +872,133 @@ dev = [ [package.metadata] requires-dist = [ - { name = "aiosqlite", specifier = ">=0.21.0" }, - { name = "alembic", specifier = ">=1.16.1" }, - { name = "asyncpg", specifier = ">=0.30.0" }, - { name = "bcrypt", specifier = ">=4.3.0" }, - { name = "cloud-sql-python-connector", specifier = ">=1.18.2" }, - { name = "email-validator", specifier = ">=2.2.0" }, - { name = "fastadmin", specifier = ">=0.2.22" }, - { name = "fastapi", specifier = ">=0.115.12" }, - { name = "fastapi-pagination", specifier = ">=0.13.2" }, - { name = "geoalchemy2", specifier = ">=0.17.1" }, - { name = "google-cloud-storage", specifier = ">=3.1.1" }, - { name = "greenlet", specifier = ">=3.2.2" }, - { name = "gunicorn", specifier = ">=23.0.0" }, - { name = "httpx", specifier = ">=0.28.1" }, + { name = "aiofiles", specifier = "==24.1.0" }, + { name = "aiohappyeyeballs", specifier = "==2.6.1" }, + { name = "aiohttp", specifier = "==3.12.13" }, + { name = "aiosignal", specifier = "==1.3.2" }, + { name = "aiosqlite", specifier = "==0.21.0" }, + { name = "alembic", specifier = "==1.16.1" }, + { name = "annotated-types", specifier = "==0.7.0" }, + { name = "anyio", specifier = "==4.9.0" }, + { name = "asgiref", specifier = "==3.8.1" }, + { name = "asn1crypto", specifier = "==1.5.1" }, + { name = "asyncpg", specifier = "==0.30.0" }, + { name = "attrs", specifier = "==25.3.0" }, + { name = "bcrypt", specifier = "==4.3.0" }, + { name = "cachetools", specifier = "==5.5.2" }, + { name = "certifi", specifier = "==2025.4.26" }, + { name = "cffi", specifier = "==1.17.1" }, + { name = "charset-normalizer", specifier = "==3.4.2" }, + { name = "click", specifier = "==8.2.1" }, + { name = "cloud-sql-python-connector", specifier = "==1.18.2" }, + { name = "cryptography", specifier = "==45.0.4" }, + { name = "dnspython", specifier = "==2.7.0" }, + { name = "email-validator", specifier = "==2.2.0" }, + { name = "fastadmin", specifier = "==0.2.22" }, + { name = "fastapi", specifier = "==0.115.12" }, + { name = "fastapi-pagination", specifier = "==0.13.2" }, + { name = "frozenlist", specifier = "==1.7.0" }, + { name = "geoalchemy2", specifier = "==0.17.1" }, + { name = "google-api-core", specifier = "==2.25.1" }, + { name = "google-auth", specifier = "==2.40.3" }, + { name = "google-cloud-core", specifier = "==2.4.3" }, + { name = "google-cloud-storage", specifier = "==3.1.1" }, + { name = "google-crc32c", specifier = "==1.7.1" }, + { name = "google-resumable-media", specifier = "==2.7.2" }, + { name = "googleapis-common-protos", specifier = "==1.70.0" }, + { name = "greenlet", specifier = "==3.2.2" }, + { name = "gunicorn", specifier = "==23.0.0" }, + { name = "h11", specifier = "==0.16.0" }, + { name = "httpcore", specifier = "==1.0.9" }, + { name = "httpx", specifier = "==0.28.1" }, + { name = "idna", specifier = "==3.10" }, + { name = "iniconfig", specifier = "==2.1.0" }, + { name = "mako", specifier = "==1.3.10" }, + { name = "markupsafe", specifier = "==3.0.2" }, + { name = "multidict", specifier = "==6.6.3" }, + { name = "numpy", specifier = "==2.3.0" }, + { name = "packaging", specifier = "==25.0" }, { name = "pandas", specifier = ">=2.3.0" }, - { name = "pg8000", specifier = ">=1.31.2" }, - { name = "phonenumbers", specifier = ">=9.0.7" }, - { name = "pillow", specifier = ">=11.2.1" }, - { name = "psycopg2", specifier = ">=2.9.10" }, + { name = "pg8000", specifier = "==1.31.2" }, + { name = "phonenumbers", specifier = "==9.0.7" }, + { name = "pillow", specifier = "==11.3.0" }, + { name = "pluggy", specifier = "==1.6.0" }, + { name = "pre-commit", specifier = ">=4.2.0" }, + { name = "propcache", specifier = "==0.3.2" }, + { name = "proto-plus", specifier = "==1.26.1" }, + { name = "protobuf", specifier = "==6.31.1" }, + { name = "psycopg2", specifier = "==2.9.10" }, + { name = "pyasn1", specifier = "==0.6.1" }, + { name = "pyasn1-modules", specifier = "==0.4.2" }, + { name = "pycparser", specifier = "==2.22" }, + { name = "pydantic", specifier = "==2.11.5" }, + { name = "pydantic-core", specifier = "==2.33.2" }, + { name = "pygments", specifier = "==2.19.1" }, + { name = "pyjwt", specifier = "==2.10.1" }, { name = "pyproj", specifier = ">=3.7.1" }, - { name = "pyshp", specifier = ">=2.3.1" }, - { name = "python-multipart", specifier = ">=0.0.20" }, - { name = "shapely", specifier = ">=2.1.1" }, + { name = "pyshp", specifier = "==2.3.1" }, + { name = "pytest", specifier = "==8.4.0" }, + { name = "python-dateutil", specifier = "==2.9.0.post0" }, + { name = "python-dotenv", specifier = ">=1.0.0" }, + { name = "python-multipart", specifier = "==0.0.20" }, + { name = "requests", specifier = "==2.32.4" }, + { name = "rsa", specifier = "==4.9.1" }, + { name = "scramp", specifier = "==1.4.5" }, + { name = "shapely", specifier = "==2.1.1" }, + { name = "six", specifier = "==1.17.0" }, + { name = "sniffio", specifier = "==1.3.1" }, + { name = "sqlalchemy", specifier = "==2.0.41" }, { name = "sqlalchemy-continuum", specifier = ">=1.4.2" }, - { name = "sqlalchemy-searchable", specifier = ">=2.1.0" }, - { name = "uvicorn", specifier = ">=0.34.3" }, + { name = "sqlalchemy-searchable", specifier = "==2.1.0" }, + { name = "sqlalchemy-utils", specifier = "==0.41.2" }, + { name = "starlette", specifier = "==0.46.2" }, + { name = "typing-extensions", specifier = "==4.14.0" }, + { name = "typing-inspection", specifier = "==0.4.1" }, + { name = "urllib3", specifier = "==2.5.0" }, + { name = "uvicorn", specifier = "==0.34.3" }, + { name = "yarl", specifier = "==1.20.1" }, ] [package.metadata.requires-dev] dev = [{ name = "pytest", specifier = ">=8.4.0" }] +[[package]] +name = "nodeenv" +version = "1.9.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437, upload-time = "2024-06-04T18:44:11.171Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314, upload-time = "2024-06-04T18:44:08.352Z" }, +] + [[package]] name = "numpy" -version = "2.3.1" +version = "2.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/2e/19/d7c972dfe90a353dbd3efbbe1d14a5951de80c99c9dc1b93cd998d51dc0f/numpy-2.3.1.tar.gz", hash = "sha256:1ec9ae20a4226da374362cca3c62cd753faf2f951440b0e3b98e93c235441d2b", size = 20390372, upload-time = "2025-06-21T12:28:33.469Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d4/bd/35ad97006d8abff8631293f8ea6adf07b0108ce6fec68da3c3fcca1197f2/numpy-2.3.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:25a1992b0a3fdcdaec9f552ef10d8103186f5397ab45e2d25f8ac51b1a6b97e8", size = 20889381, upload-time = "2025-06-21T12:19:04.103Z" }, - { url = "https://files.pythonhosted.org/packages/f1/4f/df5923874d8095b6062495b39729178eef4a922119cee32a12ee1bd4664c/numpy-2.3.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7dea630156d39b02a63c18f508f85010230409db5b2927ba59c8ba4ab3e8272e", size = 14152726, upload-time = "2025-06-21T12:19:25.599Z" }, - { url = "https://files.pythonhosted.org/packages/8c/0f/a1f269b125806212a876f7efb049b06c6f8772cf0121139f97774cd95626/numpy-2.3.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:bada6058dd886061f10ea15f230ccf7dfff40572e99fef440a4a857c8728c9c0", size = 5105145, upload-time = "2025-06-21T12:19:34.782Z" }, - { url = "https://files.pythonhosted.org/packages/6d/63/a7f7fd5f375b0361682f6ffbf686787e82b7bbd561268e4f30afad2bb3c0/numpy-2.3.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:a894f3816eb17b29e4783e5873f92faf55b710c2519e5c351767c51f79d8526d", size = 6639409, upload-time = "2025-06-21T12:19:45.228Z" }, - { url = "https://files.pythonhosted.org/packages/bf/0d/1854a4121af895aab383f4aa233748f1df4671ef331d898e32426756a8a6/numpy-2.3.1-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:18703df6c4a4fee55fd3d6e5a253d01c5d33a295409b03fda0c86b3ca2ff41a1", size = 14257630, upload-time = "2025-06-21T12:20:06.544Z" }, - { url = "https://files.pythonhosted.org/packages/50/30/af1b277b443f2fb08acf1c55ce9d68ee540043f158630d62cef012750f9f/numpy-2.3.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:5902660491bd7a48b2ec16c23ccb9124b8abfd9583c5fdfa123fe6b421e03de1", size = 16627546, upload-time = "2025-06-21T12:20:31.002Z" }, - { url = "https://files.pythonhosted.org/packages/6e/ec/3b68220c277e463095342d254c61be8144c31208db18d3fd8ef02712bcd6/numpy-2.3.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:36890eb9e9d2081137bd78d29050ba63b8dab95dff7912eadf1185e80074b2a0", size = 15562538, upload-time = "2025-06-21T12:20:54.322Z" }, - { url = "https://files.pythonhosted.org/packages/77/2b/4014f2bcc4404484021c74d4c5ee8eb3de7e3f7ac75f06672f8dcf85140a/numpy-2.3.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a780033466159c2270531e2b8ac063704592a0bc62ec4a1b991c7c40705eb0e8", size = 18360327, upload-time = "2025-06-21T12:21:21.053Z" }, - { url = "https://files.pythonhosted.org/packages/40/8d/2ddd6c9b30fcf920837b8672f6c65590c7d92e43084c25fc65edc22e93ca/numpy-2.3.1-cp313-cp313-win32.whl", hash = "sha256:39bff12c076812595c3a306f22bfe49919c5513aa1e0e70fac756a0be7c2a2b8", size = 6312330, upload-time = "2025-06-21T12:25:07.447Z" }, - { url = "https://files.pythonhosted.org/packages/dd/c8/beaba449925988d415efccb45bf977ff8327a02f655090627318f6398c7b/numpy-2.3.1-cp313-cp313-win_amd64.whl", hash = "sha256:8d5ee6eec45f08ce507a6570e06f2f879b374a552087a4179ea7838edbcbfa42", size = 12731565, upload-time = "2025-06-21T12:25:26.444Z" }, - { url = "https://files.pythonhosted.org/packages/0b/c3/5c0c575d7ec78c1126998071f58facfc124006635da75b090805e642c62e/numpy-2.3.1-cp313-cp313-win_arm64.whl", hash = "sha256:0c4d9e0a8368db90f93bd192bfa771ace63137c3488d198ee21dfb8e7771916e", size = 10190262, upload-time = "2025-06-21T12:25:42.196Z" }, - { url = "https://files.pythonhosted.org/packages/ea/19/a029cd335cf72f79d2644dcfc22d90f09caa86265cbbde3b5702ccef6890/numpy-2.3.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:b0b5397374f32ec0649dd98c652a1798192042e715df918c20672c62fb52d4b8", size = 20987593, upload-time = "2025-06-21T12:21:51.664Z" }, - { url = "https://files.pythonhosted.org/packages/25/91/8ea8894406209107d9ce19b66314194675d31761fe2cb3c84fe2eeae2f37/numpy-2.3.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:c5bdf2015ccfcee8253fb8be695516ac4457c743473a43290fd36eba6a1777eb", size = 14300523, upload-time = "2025-06-21T12:22:13.583Z" }, - { url = "https://files.pythonhosted.org/packages/a6/7f/06187b0066eefc9e7ce77d5f2ddb4e314a55220ad62dd0bfc9f2c44bac14/numpy-2.3.1-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:d70f20df7f08b90a2062c1f07737dd340adccf2068d0f1b9b3d56e2038979fee", size = 5227993, upload-time = "2025-06-21T12:22:22.53Z" }, - { url = "https://files.pythonhosted.org/packages/e8/ec/a926c293c605fa75e9cfb09f1e4840098ed46d2edaa6e2152ee35dc01ed3/numpy-2.3.1-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:2fb86b7e58f9ac50e1e9dd1290154107e47d1eef23a0ae9145ded06ea606f992", size = 6736652, upload-time = "2025-06-21T12:22:33.629Z" }, - { url = "https://files.pythonhosted.org/packages/e3/62/d68e52fb6fde5586650d4c0ce0b05ff3a48ad4df4ffd1b8866479d1d671d/numpy-2.3.1-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:23ab05b2d241f76cb883ce8b9a93a680752fbfcbd51c50eff0b88b979e471d8c", size = 14331561, upload-time = "2025-06-21T12:22:55.056Z" }, - { url = "https://files.pythonhosted.org/packages/fc/ec/b74d3f2430960044bdad6900d9f5edc2dc0fb8bf5a0be0f65287bf2cbe27/numpy-2.3.1-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:ce2ce9e5de4703a673e705183f64fd5da5bf36e7beddcb63a25ee2286e71ca48", size = 16693349, upload-time = "2025-06-21T12:23:20.53Z" }, - { url = "https://files.pythonhosted.org/packages/0d/15/def96774b9d7eb198ddadfcbd20281b20ebb510580419197e225f5c55c3e/numpy-2.3.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c4913079974eeb5c16ccfd2b1f09354b8fed7e0d6f2cab933104a09a6419b1ee", size = 15642053, upload-time = "2025-06-21T12:23:43.697Z" }, - { url = "https://files.pythonhosted.org/packages/2b/57/c3203974762a759540c6ae71d0ea2341c1fa41d84e4971a8e76d7141678a/numpy-2.3.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:010ce9b4f00d5c036053ca684c77441f2f2c934fd23bee058b4d6f196efd8280", size = 18434184, upload-time = "2025-06-21T12:24:10.708Z" }, - { url = "https://files.pythonhosted.org/packages/22/8a/ccdf201457ed8ac6245187850aff4ca56a79edbea4829f4e9f14d46fa9a5/numpy-2.3.1-cp313-cp313t-win32.whl", hash = "sha256:6269b9edfe32912584ec496d91b00b6d34282ca1d07eb10e82dfc780907d6c2e", size = 6440678, upload-time = "2025-06-21T12:24:21.596Z" }, - { url = "https://files.pythonhosted.org/packages/f1/7e/7f431d8bd8eb7e03d79294aed238b1b0b174b3148570d03a8a8a8f6a0da9/numpy-2.3.1-cp313-cp313t-win_amd64.whl", hash = "sha256:2a809637460e88a113e186e87f228d74ae2852a2e0c44de275263376f17b5bdc", size = 12870697, upload-time = "2025-06-21T12:24:40.644Z" }, - { url = "https://files.pythonhosted.org/packages/d4/ca/af82bf0fad4c3e573c6930ed743b5308492ff19917c7caaf2f9b6f9e2e98/numpy-2.3.1-cp313-cp313t-win_arm64.whl", hash = "sha256:eccb9a159db9aed60800187bc47a6d3451553f0e1b08b068d8b277ddfbb9b244", size = 10260376, upload-time = "2025-06-21T12:24:56.884Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/f3/db/8e12381333aea300890829a0a36bfa738cac95475d88982d538725143fd9/numpy-2.3.0.tar.gz", hash = "sha256:581f87f9e9e9db2cba2141400e160e9dd644ee248788d6f90636eeb8fd9260a6", size = 20382813, upload-time = "2025-06-07T14:54:32.608Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/73/fc/1d67f751fd4dbafc5780244fe699bc4084268bad44b7c5deb0492473127b/numpy-2.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5754ab5595bfa2c2387d241296e0381c21f44a4b90a776c3c1d39eede13a746a", size = 20889633, upload-time = "2025-06-07T14:44:06.839Z" }, + { url = "https://files.pythonhosted.org/packages/e8/95/73ffdb69e5c3f19ec4530f8924c4386e7ba097efc94b9c0aff607178ad94/numpy-2.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d11fa02f77752d8099573d64e5fe33de3229b6632036ec08f7080f46b6649959", size = 14151683, upload-time = "2025-06-07T14:44:28.847Z" }, + { url = "https://files.pythonhosted.org/packages/64/d5/06d4bb31bb65a1d9c419eb5676173a2f90fd8da3c59f816cc54c640ce265/numpy-2.3.0-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:aba48d17e87688a765ab1cd557882052f238e2f36545dfa8e29e6a91aef77afe", size = 5102683, upload-time = "2025-06-07T14:44:38.417Z" }, + { url = "https://files.pythonhosted.org/packages/12/8b/6c2cef44f8ccdc231f6b56013dff1d71138c48124334aded36b1a1b30c5a/numpy-2.3.0-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:4dc58865623023b63b10d52f18abaac3729346a7a46a778381e0e3af4b7f3beb", size = 6640253, upload-time = "2025-06-07T14:44:49.359Z" }, + { url = "https://files.pythonhosted.org/packages/62/aa/fca4bf8de3396ddb59544df9b75ffe5b73096174de97a9492d426f5cd4aa/numpy-2.3.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:df470d376f54e052c76517393fa443758fefcdd634645bc9c1f84eafc67087f0", size = 14258658, upload-time = "2025-06-07T14:45:10.156Z" }, + { url = "https://files.pythonhosted.org/packages/1c/12/734dce1087eed1875f2297f687e671cfe53a091b6f2f55f0c7241aad041b/numpy-2.3.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:87717eb24d4a8a64683b7a4e91ace04e2f5c7c77872f823f02a94feee186168f", size = 16628765, upload-time = "2025-06-07T14:45:35.076Z" }, + { url = "https://files.pythonhosted.org/packages/48/03/ffa41ade0e825cbcd5606a5669962419528212a16082763fc051a7247d76/numpy-2.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d8fa264d56882b59dcb5ea4d6ab6f31d0c58a57b41aec605848b6eb2ef4a43e8", size = 15564335, upload-time = "2025-06-07T14:45:58.797Z" }, + { url = "https://files.pythonhosted.org/packages/07/58/869398a11863310aee0ff85a3e13b4c12f20d032b90c4b3ee93c3b728393/numpy-2.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e651756066a0eaf900916497e20e02fe1ae544187cb0fe88de981671ee7f6270", size = 18360608, upload-time = "2025-06-07T14:46:25.687Z" }, + { url = "https://files.pythonhosted.org/packages/2f/8a/5756935752ad278c17e8a061eb2127c9a3edf4ba2c31779548b336f23c8d/numpy-2.3.0-cp313-cp313-win32.whl", hash = "sha256:e43c3cce3b6ae5f94696669ff2a6eafd9a6b9332008bafa4117af70f4b88be6f", size = 6310005, upload-time = "2025-06-07T14:50:13.138Z" }, + { url = "https://files.pythonhosted.org/packages/08/60/61d60cf0dfc0bf15381eaef46366ebc0c1a787856d1db0c80b006092af84/numpy-2.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:81ae0bf2564cf475f94be4a27ef7bcf8af0c3e28da46770fc904da9abd5279b5", size = 12729093, upload-time = "2025-06-07T14:50:31.82Z" }, + { url = "https://files.pythonhosted.org/packages/66/31/2f2f2d2b3e3c32d5753d01437240feaa32220b73258c9eef2e42a0832866/numpy-2.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:c8738baa52505fa6e82778580b23f945e3578412554d937093eac9205e845e6e", size = 9885689, upload-time = "2025-06-07T14:50:47.888Z" }, + { url = "https://files.pythonhosted.org/packages/f1/89/c7828f23cc50f607ceb912774bb4cff225ccae7131c431398ad8400e2c98/numpy-2.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:39b27d8b38942a647f048b675f134dd5a567f95bfff481f9109ec308515c51d8", size = 20986612, upload-time = "2025-06-07T14:46:56.077Z" }, + { url = "https://files.pythonhosted.org/packages/dd/46/79ecf47da34c4c50eedec7511e53d57ffdfd31c742c00be7dc1d5ffdb917/numpy-2.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0eba4a1ea88f9a6f30f56fdafdeb8da3774349eacddab9581a21234b8535d3d3", size = 14298953, upload-time = "2025-06-07T14:47:18.053Z" }, + { url = "https://files.pythonhosted.org/packages/59/44/f6caf50713d6ff4480640bccb2a534ce1d8e6e0960c8f864947439f0ee95/numpy-2.3.0-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:b0f1f11d0a1da54927436505a5a7670b154eac27f5672afc389661013dfe3d4f", size = 5225806, upload-time = "2025-06-07T14:47:27.524Z" }, + { url = "https://files.pythonhosted.org/packages/a6/43/e1fd1aca7c97e234dd05e66de4ab7a5be54548257efcdd1bc33637e72102/numpy-2.3.0-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:690d0a5b60a47e1f9dcec7b77750a4854c0d690e9058b7bef3106e3ae9117808", size = 6735169, upload-time = "2025-06-07T14:47:38.057Z" }, + { url = "https://files.pythonhosted.org/packages/84/89/f76f93b06a03177c0faa7ca94d0856c4e5c4bcaf3c5f77640c9ed0303e1c/numpy-2.3.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:8b51ead2b258284458e570942137155978583e407babc22e3d0ed7af33ce06f8", size = 14330701, upload-time = "2025-06-07T14:47:59.113Z" }, + { url = "https://files.pythonhosted.org/packages/aa/f5/4858c3e9ff7a7d64561b20580cf7cc5d085794bd465a19604945d6501f6c/numpy-2.3.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:aaf81c7b82c73bd9b45e79cfb9476cb9c29e937494bfe9092c26aece812818ad", size = 16692983, upload-time = "2025-06-07T14:48:24.196Z" }, + { url = "https://files.pythonhosted.org/packages/08/17/0e3b4182e691a10e9483bcc62b4bb8693dbf9ea5dc9ba0b77a60435074bb/numpy-2.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:f420033a20b4f6a2a11f585f93c843ac40686a7c3fa514060a97d9de93e5e72b", size = 15641435, upload-time = "2025-06-07T14:48:47.712Z" }, + { url = "https://files.pythonhosted.org/packages/4e/d5/463279fda028d3c1efa74e7e8d507605ae87f33dbd0543cf4c4527c8b882/numpy-2.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:d344ca32ab482bcf8735d8f95091ad081f97120546f3d250240868430ce52555", size = 18433798, upload-time = "2025-06-07T14:49:14.866Z" }, + { url = "https://files.pythonhosted.org/packages/0e/1e/7a9d98c886d4c39a2b4d3a7c026bffcf8fbcaf518782132d12a301cfc47a/numpy-2.3.0-cp313-cp313t-win32.whl", hash = "sha256:48a2e8eaf76364c32a1feaa60d6925eaf32ed7a040183b807e02674305beef61", size = 6438632, upload-time = "2025-06-07T14:49:25.67Z" }, + { url = "https://files.pythonhosted.org/packages/fe/ab/66fc909931d5eb230107d016861824f335ae2c0533f422e654e5ff556784/numpy-2.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ba17f93a94e503551f154de210e4d50c5e3ee20f7e7a1b5f6ce3f22d419b93bb", size = 12868491, upload-time = "2025-06-07T14:49:44.898Z" }, + { url = "https://files.pythonhosted.org/packages/ee/e8/2c8a1c9e34d6f6d600c83d5ce5b71646c32a13f34ca5c518cc060639841c/numpy-2.3.0-cp313-cp313t-win_arm64.whl", hash = "sha256:f14e016d9409680959691c109be98c436c6249eaf7f118b424679793607b5944", size = 9935345, upload-time = "2025-06-07T14:50:02.311Z" }, ] [[package]] @@ -888,11 +1052,11 @@ wheels = [ [[package]] name = "phonenumbers" -version = "9.0.8" +version = "9.0.7" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/86/3a/8dd1d5e15ac347db59a43fc623638d8088f9d511e7f8d8eec7d90b3abb4f/phonenumbers-9.0.8.tar.gz", hash = "sha256:16f03f2cf65b5eee99ed25827d810febcab92b5d76f977e425fcd2e4ca6d4865", size = 2297504, upload-time = "2025-06-25T05:41:38.414Z" } +sdist = { url = "https://files.pythonhosted.org/packages/49/8c/2c09b844e819e70c261ad79cc302a5e307d97cb0ab70c227031d8ad72871/phonenumbers-9.0.7.tar.gz", hash = "sha256:d4cc2aa36cbf9b0004c370f406d1510ddef56bba9e5f759471ef47e998d8a2f9", size = 2297250, upload-time = "2025-06-09T06:01:09.224Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/48/2e/23c1eca9f73e332b947c66c431690672783cf49b8418aa650ce06bdf6115/phonenumbers-9.0.8-py2.py3-none-any.whl", hash = "sha256:53d357111c0ead0d6408ae443613b18d3a053431ca1ddf7e881457c0969afcf9", size = 2583252, upload-time = "2025-06-25T05:41:34.815Z" }, + { url = "https://files.pythonhosted.org/packages/03/d6/71ed688698834669f61dbba51601a27b62c1a7f5f868444f973a3fd33dc8/phonenumbers-9.0.7-py2.py3-none-any.whl", hash = "sha256:306eb14d1eaeb82230a08aa1614d04c93322b65b1ded2fff585161ed7eca39fc", size = 2583027, upload-time = "2025-06-09T06:01:04.772Z" }, ] [[package]] @@ -950,6 +1114,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/89/c7/5572fa4a3f45740eaab6ae86fcdf7195b55beac1371ac8c619d880cfe948/pillow-11.3.0-cp314-cp314t-win_arm64.whl", hash = "sha256:79ea0d14d3ebad43ec77ad5272e6ff9bba5b679ef73375ea760261207fa8e0aa", size = 2512835, upload-time = "2025-07-01T09:15:50.399Z" }, ] +[[package]] +name = "platformdirs" +version = "4.3.8" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/fe/8b/3c73abc9c759ecd3f1f7ceff6685840859e8070c4d947c93fae71f6a0bf2/platformdirs-4.3.8.tar.gz", hash = "sha256:3d512d96e16bcb959a814c9f348431070822a6496326a4be0911c40b5a74c2bc", size = 21362, upload-time = "2025-05-07T22:47:42.121Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fe/39/979e8e21520d4e47a0bbe349e2713c0aac6f3d853d0e5b34d76206c439aa/platformdirs-4.3.8-py3-none-any.whl", hash = "sha256:ff7059bb7eb1179e2685604f4aaf157cfd9535242bd23742eadc3c13542139b4", size = 18567, upload-time = "2025-05-07T22:47:40.376Z" }, +] + [[package]] name = "pluggy" version = "1.6.0" @@ -959,6 +1132,22 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, ] +[[package]] +name = "pre-commit" +version = "4.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cfgv" }, + { name = "identify" }, + { name = "nodeenv" }, + { name = "pyyaml" }, + { name = "virtualenv" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/08/39/679ca9b26c7bb2999ff122d50faa301e49af82ca9c066ec061cfbc0c6784/pre_commit-4.2.0.tar.gz", hash = "sha256:601283b9757afd87d40c4c4a9b2b5de9637a8ea02eaff7adc2d0fb4e04841146", size = 193424, upload-time = "2025-03-18T21:35:20.987Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/74/a88bf1b1efeae488a0c0b7bdf71429c313722d1fc0f377537fbe554e6180/pre_commit-4.2.0-py2.py3-none-any.whl", hash = "sha256:a009ca7205f1eb497d10b845e52c838a98b6cdd2102a6c8e4540e94ee75c58bd", size = 220707, upload-time = "2025-03-18T21:35:19.343Z" }, +] + [[package]] name = "propcache" version = "0.3.2" @@ -1067,7 +1256,7 @@ wheels = [ [[package]] name = "pydantic" -version = "2.11.7" +version = "2.11.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-types" }, @@ -1075,9 +1264,9 @@ dependencies = [ { name = "typing-extensions" }, { name = "typing-inspection" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/00/dd/4325abf92c39ba8623b5af936ddb36ffcfe0beae70405d456ab1fb2f5b8c/pydantic-2.11.7.tar.gz", hash = "sha256:d989c3c6cb79469287b1569f7447a17848c998458d49ebe294e975b9baf0f0db", size = 788350, upload-time = "2025-06-14T08:33:17.137Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f0/86/8ce9040065e8f924d642c58e4a344e33163a07f6b57f836d0d734e0ad3fb/pydantic-2.11.5.tar.gz", hash = "sha256:7f853db3d0ce78ce8bbb148c401c2cdd6431b3473c0cdff2755c7690952a7b7a", size = 787102, upload-time = "2025-05-22T21:18:08.761Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6a/c0/ec2b1c8712ca690e5d61979dee872603e92b8a32f94cc1b72d53beab008a/pydantic-2.11.7-py3-none-any.whl", hash = "sha256:dde5df002701f6de26248661f6835bbe296a47bf73990135c7d07ce741b9623b", size = 444782, upload-time = "2025-06-14T08:33:14.905Z" }, + { url = "https://files.pythonhosted.org/packages/b5/69/831ed22b38ff9b4b64b66569f0e5b7b97cf3638346eb95a2147fdb49ad5f/pydantic-2.11.5-py3-none-any.whl", hash = "sha256:f9c26ba06f9747749ca1e5c94d6a85cb84254577553c8785576fd38fa64dc0f7", size = 444229, upload-time = "2025-05-22T21:18:06.329Z" }, ] [[package]] @@ -1110,11 +1299,11 @@ wheels = [ [[package]] name = "pygments" -version = "2.19.2" +version = "2.19.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } +sdist = { url = "https://files.pythonhosted.org/packages/7c/2d/c3338d48ea6cc0feb8446d8e6937e1408088a72a39937982cc6111d17f84/pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f", size = 4968581, upload-time = "2025-01-06T17:26:30.443Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, + { url = "https://files.pythonhosted.org/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c", size = 1225293, upload-time = "2025-01-06T17:26:25.553Z" }, ] [[package]] @@ -1156,7 +1345,7 @@ wheels = [ [[package]] name = "pytest" -version = "8.4.1" +version = "8.4.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, @@ -1165,9 +1354,9 @@ dependencies = [ { name = "pluggy" }, { name = "pygments" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/08/ba/45911d754e8eba3d5a841a5ce61a65a685ff1798421ac054f85aa8747dfb/pytest-8.4.1.tar.gz", hash = "sha256:7c67fd69174877359ed9371ec3af8a3d2b04741818c51e5e99cc1742251fa93c", size = 1517714, upload-time = "2025-06-18T05:48:06.109Z" } +sdist = { url = "https://files.pythonhosted.org/packages/fb/aa/405082ce2749be5398045152251ac69c0f3578c7077efc53431303af97ce/pytest-8.4.0.tar.gz", hash = "sha256:14d920b48472ea0dbf68e45b96cd1ffda4705f33307dcc86c676c1b5104838a6", size = 1515232, upload-time = "2025-06-02T17:36:30.03Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/29/16/c8a903f4c4dffe7a12843191437d7cd8e32751d5de349d45d3fe69544e87/pytest-8.4.1-py3-none-any.whl", hash = "sha256:539c70ba6fcead8e78eebbf1115e8b589e7565830d7d006a8723f19ac8a0afb7", size = 365474, upload-time = "2025-06-18T05:48:03.955Z" }, + { url = "https://files.pythonhosted.org/packages/2f/de/afa024cbe022b1b318a3d224125aa24939e99b4ff6f22e0ba639a2eaee47/pytest-8.4.0-py3-none-any.whl", hash = "sha256:f40f825768ad76c0977cbacdf1fd37c6f7a468e460ea6a0636078f8972d4517e", size = 363797, upload-time = "2025-06-02T17:36:27.859Z" }, ] [[package]] @@ -1182,6 +1371,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, ] +[[package]] +name = "python-dotenv" +version = "1.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/b0/4bc07ccd3572a2f9df7e6782f52b0c6c90dcbb803ac4a167702d7d0dfe1e/python_dotenv-1.1.1.tar.gz", hash = "sha256:a8a6399716257f45be6a007360200409fce5cda2661e3dec71d23dc15f6189ab", size = 41978, upload-time = "2025-06-24T04:21:07.341Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5f/ed/539768cf28c661b5b068d66d96a2f155c4971a5d55684a514c1a0e0dec2f/python_dotenv-1.1.1-py3-none-any.whl", hash = "sha256:31f23644fe2602f88ff55e1f5c79ba497e01224ee7737937930c448e4d0e24dc", size = 20556, upload-time = "2025-06-24T04:21:06.073Z" }, +] + [[package]] name = "python-multipart" version = "0.0.20" @@ -1200,6 +1398,23 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00", size = 509225, upload-time = "2025-03-25T02:24:58.468Z" }, ] +[[package]] +name = "pyyaml" +version = "6.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631, upload-time = "2024-08-06T20:33:50.674Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309, upload-time = "2024-08-06T20:32:43.4Z" }, + { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679, upload-time = "2024-08-06T20:32:44.801Z" }, + { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428, upload-time = "2024-08-06T20:32:46.432Z" }, + { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361, upload-time = "2024-08-06T20:32:51.188Z" }, + { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523, upload-time = "2024-08-06T20:32:53.019Z" }, + { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660, upload-time = "2024-08-06T20:32:54.708Z" }, + { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597, upload-time = "2024-08-06T20:32:56.985Z" }, + { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527, upload-time = "2024-08-06T20:33:03.001Z" }, + { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446, upload-time = "2024-08-06T20:33:04.33Z" }, +] + [[package]] name = "requests" version = "2.32.4" @@ -1396,15 +1611,29 @@ wheels = [ [[package]] name = "uvicorn" -version = "0.35.0" +version = "0.34.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, { name = "h11" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5e/42/e0e305207bb88c6b8d3061399c6a961ffe5fbb7e2aa63c9234df7259e9cd/uvicorn-0.35.0.tar.gz", hash = "sha256:bc662f087f7cf2ce11a1d7fd70b90c9f98ef2e2831556dd078d131b96cc94a01", size = 78473, upload-time = "2025-06-28T16:15:46.058Z" } +sdist = { url = "https://files.pythonhosted.org/packages/de/ad/713be230bcda622eaa35c28f0d328c3675c371238470abdea52417f17a8e/uvicorn-0.34.3.tar.gz", hash = "sha256:35919a9a979d7a59334b6b10e05d77c1d0d574c50e0fc98b8b1a0f165708b55a", size = 76631, upload-time = "2025-06-01T07:48:17.531Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6d/0d/8adfeaa62945f90d19ddc461c55f4a50c258af7662d34b6a3d5d1f8646f6/uvicorn-0.34.3-py3-none-any.whl", hash = "sha256:16246631db62bdfbf069b0645177d6e8a77ba950cfedbfd093acef9444e4d885", size = 62431, upload-time = "2025-06-01T07:48:15.664Z" }, +] + +[[package]] +name = "virtualenv" +version = "20.31.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "distlib" }, + { name = "filelock" }, + { name = "platformdirs" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/56/2c/444f465fb2c65f40c3a104fd0c495184c4f2336d65baf398e3c75d72ea94/virtualenv-20.31.2.tar.gz", hash = "sha256:e10c0a9d02835e592521be48b332b6caee6887f332c111aa79a09b9e79efc2af", size = 6076316, upload-time = "2025-05-08T17:58:23.811Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d2/e2/dc81b1bd1dcfe91735810265e9d26bc8ec5da45b4c0f6237e286819194c3/uvicorn-0.35.0-py3-none-any.whl", hash = "sha256:197535216b25ff9b785e29a0b79199f55222193d47f820816e7da751e9bc8d4a", size = 66406, upload-time = "2025-06-28T16:15:44.816Z" }, + { url = "https://files.pythonhosted.org/packages/f3/40/b1c265d4b2b62b58576588510fc4d1fe60a86319c8de99fd8e9fec617d2c/virtualenv-20.31.2-py3-none-any.whl", hash = "sha256:36efd0d9650ee985f0cad72065001e66d49a6f24eb44d98980f630686243cf11", size = 6057982, upload-time = "2025-05-08T17:58:21.15Z" }, ] [[package]] From 94d4fe326a84a7dcfcbeca4609cdc48bb07fb97f Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Tue, 15 Jul 2025 16:26:39 -0600 Subject: [PATCH 12/38] feat: alembic init --- alembic/README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/alembic/README b/alembic/README index fdacc05f6..98e4f9c44 100644 --- a/alembic/README +++ b/alembic/README @@ -1 +1 @@ -pyproject configuration, based on the generic configuration. \ No newline at end of file +Generic single-database configuration. \ No newline at end of file From e7c143c11c140db4cba994d05a2d41129682fd59 Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Tue, 15 Jul 2025 16:26:57 -0600 Subject: [PATCH 13/38] use environment variables for migrations --- alembic/env.py | 1 - 1 file changed, 1 deletion(-) diff --git a/alembic/env.py b/alembic/env.py index 491cec89f..7a43cf1f9 100644 --- a/alembic/env.py +++ b/alembic/env.py @@ -37,7 +37,6 @@ port = environ.get("POSTGRES_PORT", "5432") SQLALCHEMY_DATABASE_URL = f"postgresql+psycopg2://{user}:{password}@{host}:{port}/{db}" -print(SQLALCHEMY_DATABASE_URL) config.set_main_option("sqlalchemy.url", SQLALCHEMY_DATABASE_URL) From daa7beb6abb043134bd45e30fbc4c3181bc251b2 Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Tue, 15 Jul 2025 16:27:16 -0600 Subject: [PATCH 14/38] fix: import libraries for all migration files --- alembic/script.py.mako | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/alembic/script.py.mako b/alembic/script.py.mako index 480b130d6..40b87b8a7 100644 --- a/alembic/script.py.mako +++ b/alembic/script.py.mako @@ -8,12 +8,14 @@ Create Date: ${create_date} from typing import Sequence, Union from alembic import op +import geoalchemy2 import sqlalchemy as sa +import sqlalchemy_utils ${imports if imports else ""} # revision identifiers, used by Alembic. revision: str = ${repr(up_revision)} -down_revision: Union[str, None] = ${repr(down_revision)} +down_revision: Union[str, Sequence[str], None] = ${repr(down_revision)} branch_labels: Union[str, Sequence[str], None] = ${repr(branch_labels)} depends_on: Union[str, Sequence[str], None] = ${repr(depends_on)} From b0d40b9ac8d6e5deeb1aa9daace24662bf0fa04e Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Tue, 15 Jul 2025 16:27:58 -0600 Subject: [PATCH 15/38] set up docker --- docker-compose.yml | 2 + docker/app/Dockerfile | 13 +- docker/timescale_db_extension/Dockerfile | 222 ------------------ .../postgis.d/initdb-postgis.sh | 25 -- .../postgis.d/update-postgis.sh | 28 --- .../timescaledb.d/000_install_timescaledb.sh | 37 --- .../timescaledb.d/001_timescaledb_tune.sh | 123 ---------- 7 files changed, 9 insertions(+), 441 deletions(-) delete mode 100644 docker/timescale_db_extension/Dockerfile delete mode 100644 docker/timescale_db_extension/postgis.d/initdb-postgis.sh delete mode 100644 docker/timescale_db_extension/postgis.d/update-postgis.sh delete mode 100644 docker/timescale_db_extension/timescaledb.d/000_install_timescaledb.sh delete mode 100644 docker/timescale_db_extension/timescaledb.d/001_timescaledb_tune.sh diff --git a/docker-compose.yml b/docker-compose.yml index c169fdf04..b9780b83a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -22,6 +22,8 @@ services: - 8000:8000 depends_on: - db + links: + - db volumes: postgres_data: \ No newline at end of file diff --git a/docker/app/Dockerfile b/docker/app/Dockerfile index bab568211..cfb7d8bea 100644 --- a/docker/app/Dockerfile +++ b/docker/app/Dockerfile @@ -10,23 +10,24 @@ RUN apt-get update && apt-get install -y curl RUN curl -Ls https://astral.sh/uv/install.sh | sh -s -- v0.7.17 && \ cp /root/.local/bin/uv /usr/local/bin/uv +# install postgresql client +RUN apt-get update && apt-get install -y postgresql-client + # set workdir WORKDIR /app # copy the full project source COPY . . -run ls -la - # install dependencies using uv ENV UV_PROJECT_ENVIRONMENT="/usr/local/" RUN uv sync --locked --no-dev -# migrate with Alembic -RUN python db/base.py create_all - # expose FastAPI's default dev port EXPOSE 8000 +# set environment variables for database connection +RUN chmod +x entrypoint.sh + # default command (run database migrations and the FastAPI development server) -CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"] +CMD ["sh", "entrypoint.sh"] diff --git a/docker/timescale_db_extension/Dockerfile b/docker/timescale_db_extension/Dockerfile deleted file mode 100644 index 51b1f8c5c..000000000 --- a/docker/timescale_db_extension/Dockerfile +++ /dev/null @@ -1,222 +0,0 @@ -# =========================================================================== -# Tools -ARG GO_VERSION=1.22.4 -FROM golang:${GO_VERSION}-alpine AS tools - -ENV TOOLS_VERSION 0.8.1 - -RUN apk update && apk add --no-cache git gcc musl-dev \ - && go install github.com/timescale/timescaledb-tune/cmd/timescaledb-tune@latest \ - && go install github.com/timescale/timescaledb-parallel-copy/cmd/timescaledb-parallel-copy@latest -# =========================================================================== - -#ARG BASE_IMAGE=postgres:17-alpine3.22 -FROM postgres:17-alpine3.22 - -#LABEL maintainer="PostGIS Project - https://postgis.net" \ -# org.opencontainers.image.description="PostGIS 3.5.2+dfsg-1.pgdg110+1 spatial database extension with PostgreSQL 17 bullseye" \ -# org.opencontainers.image.source="https://github.com/postgis/docker-postgis" - -ENV POSTGIS_MAJOR 3 -ENV POSTGIS_VERSION 3.5.2+dfsg-1.pgdg110+1 - -ARG ALPINE_VERSION=3.21 -ARG CLANG_VERSION=19 -ARG PG_MAJOR=17 -ARG PG_VERSION=17 -ARG PG_MAJOR_VERSION=17 -ARG PGVECTOR_VERSION='v0.7.2' - - -#LABEL maintainer="PostGIS Project - https://postgis.net" \ -# org.opencontainers.image.description="PostGIS 3.5.3 spatial database extension with PostgreSQL 17 Alpine" \ -# org.opencontainers.image.source="https://github.com/postgis/docker-postgis" - -ENV POSTGIS_VERSION 3.5.3 -ENV POSTGIS_SHA256 44222ed2b8f742ffc1ceb429b09ebb484c7880f9ba27bf7b6b197346cdd25437 - -RUN set -eux \ - && apk add --no-cache --virtual .fetch-deps \ - ca-certificates \ - openssl \ - tar \ - \ - && wget -O postgis.tar.gz "https://github.com/postgis/postgis/archive/${POSTGIS_VERSION}.tar.gz" \ - && echo "${POSTGIS_SHA256} *postgis.tar.gz" | sha256sum -c - \ - && mkdir -p /usr/src/postgis \ - && tar \ - --extract \ - --file postgis.tar.gz \ - --directory /usr/src/postgis \ - --strip-components 1 \ - && rm postgis.tar.gz \ - \ - && apk add --no-cache --virtual .build-deps \ - \ - gdal-dev \ - geos-dev \ - proj-dev \ - proj-util \ - sfcgal-dev \ - \ - # The upstream variable, '$DOCKER_PG_LLVM_DEPS' contains - # the correct versions of 'llvm-dev' and 'clang' for the current version of PostgreSQL. - # This improvement has been discussed in https://github.com/docker-library/postgres/pull/1077 - $DOCKER_PG_LLVM_DEPS \ - \ - autoconf \ - automake \ - cunit-dev \ - file \ - g++ \ - gcc \ - gettext-dev \ - git \ - json-c-dev \ - libtool \ - libxml2-dev \ - make \ - pcre2-dev \ - perl \ - protobuf-c-dev \ - \ -# build PostGIS - with Link Time Optimization (LTO) enabled - && cd /usr/src/postgis \ - && gettextize \ - && ./autogen.sh \ - && ./configure \ - --enable-lto \ - && make -j$(nproc) \ - && make install \ - \ -# This section is for refreshing the proj data for the regression tests. -# It serves as a workaround for an issue documented at https://trac.osgeo.org/postgis/ticket/5316 -# This increases the Docker image size by about 1 MB. - && projsync --system-directory --file ch_swisstopo_CHENyx06_ETRS \ - && projsync --system-directory --file us_noaa_eshpgn \ - && projsync --system-directory --file us_noaa_prvi \ - && projsync --system-directory --file us_noaa_wmhpgn \ -# This section performs a regression check. - && mkdir /tempdb \ - && chown -R postgres:postgres /tempdb \ - && su postgres -c 'pg_ctl -D /tempdb init' \ - && su postgres -c 'pg_ctl -D /tempdb -c -l /tmp/logfile -o '-F' start ' \ - && cd regress \ - && make -j$(nproc) check RUNTESTFLAGS="--extension --verbose" PGUSER=postgres \ - \ - && su postgres -c 'psql -c "CREATE EXTENSION IF NOT EXISTS postgis;"' \ - && su postgres -c 'psql -c "CREATE EXTENSION IF NOT EXISTS postgis_raster;"' \ - && su postgres -c 'psql -c "CREATE EXTENSION IF NOT EXISTS postgis_sfcgal;"' \ - && su postgres -c 'psql -c "CREATE EXTENSION IF NOT EXISTS fuzzystrmatch; --needed for postgis_tiger_geocoder "' \ - && su postgres -c 'psql -c "CREATE EXTENSION IF NOT EXISTS address_standardizer;"' \ - && su postgres -c 'psql -c "CREATE EXTENSION IF NOT EXISTS address_standardizer_data_us;"' \ - && su postgres -c 'psql -c "CREATE EXTENSION IF NOT EXISTS postgis_tiger_geocoder;"' \ - && su postgres -c 'psql -c "CREATE EXTENSION IF NOT EXISTS postgis_topology;"' \ - && su postgres -c 'psql -t -c "SELECT version();"' >> /_pgis_full_version.txt \ - && su postgres -c 'psql -t -c "SELECT PostGIS_Full_Version();"' >> /_pgis_full_version.txt \ - && su postgres -c 'psql -t -c "\dx"' >> /_pgis_full_version.txt \ - \ - && su postgres -c 'pg_ctl -D /tempdb --mode=immediate stop' \ - && rm -rf /tempdb \ - && rm -rf /tmp/logfile \ - && rm -rf /tmp/pgis_reg \ -# add .postgis-rundeps - && apk add --no-cache --virtual .postgis-rundeps \ - \ - gdal \ - geos \ - proj \ - sfcgal \ - \ - json-c \ - libstdc++ \ - pcre2 \ - protobuf-c \ - \ - # ca-certificates: for accessing remote raster files - # fix https://github.com/postgis/docker-postgis/issues/307 - ca-certificates \ -# clean - && cd / \ - && rm -rf /usr/src/postgis \ - && apk del .fetch-deps .build-deps \ -# At the end of the build, we print the collected information -# from the '/_pgis_full_version.txt' file. This is for experimental and internal purposes. - && cat /_pgis_full_version.txt - - -RUN mkdir -p /docker-entrypoint-initdb.d -COPY ./postgis.d/initdb-postgis.sh /docker-entrypoint-initdb.d/10_postgis.sh -COPY ./postgis.d/update-postgis.sh /usr/local/bin - -#=========================================================================== -# TimescaleDB -ARG OSS_ONLY - -#LABEL maintainer="Timescale https://www.timescale.com" - - -RUN set -ex; \ - echo "https://dl-cdn.alpinelinux.org/alpine/v${ALPINE_VERSION}/community/" >> /etc/apk/repositories; \ - apk update; \ - if [ "$PG_MAJOR_VERSION" -ge 16 ] ; then \ - apk add --no-cache postgresql${PG_VERSION}-plpython3; \ - fi - - - -RUN set -ex; \ - apk update; \ - apk add --no-cache --virtual .vector-deps \ - postgresql${PG_VERSION}-dev \ - git \ - build-base \ - clang${CLANG_VERSION} \ - llvm${CLANG_VERSION}-dev \ - llvm${CLANG_VERSION}; \ - git clone --branch ${PGVECTOR_VERSION} https://github.com/pgvector/pgvector.git /build/pgvector; \ - cd /build/pgvector; \ - make; \ - make install; \ - apk del .vector-deps; - -COPY timescaledb.d/* /docker-entrypoint-initdb.d/ -COPY --from=tools /go/bin/* /usr/local/bin/ -#COPY --from=oldversions /usr/local/lib/postgresql/timescaledb-*.so /usr/local/lib/postgresql/ -#COPY --from=oldversions /usr/local/share/postgresql/extension/timescaledb--*.sql /usr/local/share/postgresql/extension/ - -ARG TS_VERSION -RUN set -ex \ - && apk add --no-cache --virtual .fetch-deps \ - ca-certificates \ - git \ - openssl \ - openssl-dev \ - tar \ - && mkdir -p /build/ \ - && git clone https://github.com/timescale/timescaledb /build/timescaledb \ - \ - && apk add --no-cache --virtual .build-deps \ - coreutils \ - dpkg-dev dpkg \ - gcc \ - krb5-dev \ - libc-dev \ - make \ - cmake \ - util-linux-dev \ - \ - # Build current version \ - && cd /build/timescaledb && rm -fr build \ - && git checkout ${TS_VERSION} \ - && ./bootstrap -DCMAKE_BUILD_TYPE=RelWithDebInfo -DREGRESS_CHECKS=OFF -DTAP_CHECKS=OFF -DGENERATE_DOWNGRADE_SCRIPT=ON -DWARNINGS_AS_ERRORS=OFF -DPROJECT_INSTALL_METHOD="docker"${OSS_ONLY} \ - && cd build && make install \ - && cd ~ \ - \ - && if [ "${OSS_ONLY}" != "" ]; then rm -f $(pg_config --pkglibdir)/timescaledb-tsl-*.so; fi \ - && apk del .fetch-deps .build-deps \ - && rm -rf /build \ - && sed -r -i "s/[#]*\s*(shared_preload_libraries)\s*=\s*'(.*)'/\1 = 'timescaledb,\2'/;s/,'/'/" /usr/local/share/postgresql/postgresql.conf.sample - - -LABEL org.opencontainers.image.source="https://github.com/DataIntegrationGroup/NMSampleLocations" diff --git a/docker/timescale_db_extension/postgis.d/initdb-postgis.sh b/docker/timescale_db_extension/postgis.d/initdb-postgis.sh deleted file mode 100644 index eb5626334..000000000 --- a/docker/timescale_db_extension/postgis.d/initdb-postgis.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/bash - -set -e - -# Perform all actions as $POSTGRES_USER -export PGUSER="$POSTGRES_USER" - -# Create the 'template_postgis' template db -"${psql[@]}" <<- 'EOSQL' -CREATE DATABASE template_postgis IS_TEMPLATE true; -EOSQL - -# Load PostGIS into both template_database and $POSTGRES_DB -for DB in template_postgis "$POSTGRES_DB"; do - echo "Loading PostGIS extensions into $DB" - "${psql[@]}" --dbname="$DB" <<-'EOSQL' - CREATE EXTENSION IF NOT EXISTS postgis; - CREATE EXTENSION IF NOT EXISTS postgis_topology; - -- Reconnect to update pg_setting.resetval - -- See https://github.com/postgis/docker-postgis/issues/288 - \c - CREATE EXTENSION IF NOT EXISTS fuzzystrmatch; - CREATE EXTENSION IF NOT EXISTS postgis_tiger_geocoder; -EOSQL -done \ No newline at end of file diff --git a/docker/timescale_db_extension/postgis.d/update-postgis.sh b/docker/timescale_db_extension/postgis.d/update-postgis.sh deleted file mode 100644 index ff4b2e7cd..000000000 --- a/docker/timescale_db_extension/postgis.d/update-postgis.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/sh - -set -e - -# Perform all actions as $POSTGRES_USER -export PGUSER="$POSTGRES_USER" - -POSTGIS_VERSION="${POSTGIS_VERSION%%+*}" - -# Load PostGIS into both template_database and $POSTGRES_DB -for DB in template_postgis "$POSTGRES_DB" "${@}"; do - echo "Updating PostGIS extensions '$DB' to $POSTGIS_VERSION" - psql --dbname="$DB" -c " - -- Upgrade PostGIS (includes raster) - CREATE EXTENSION IF NOT EXISTS postgis VERSION '$POSTGIS_VERSION'; - ALTER EXTENSION postgis UPDATE TO '$POSTGIS_VERSION'; - - -- Upgrade Topology - CREATE EXTENSION IF NOT EXISTS postgis_topology VERSION '$POSTGIS_VERSION'; - ALTER EXTENSION postgis_topology UPDATE TO '$POSTGIS_VERSION'; - - -- Install Tiger dependencies in case not already installed - CREATE EXTENSION IF NOT EXISTS fuzzystrmatch; - -- Upgrade US Tiger Geocoder - CREATE EXTENSION IF NOT EXISTS postgis_tiger_geocoder VERSION '$POSTGIS_VERSION'; - ALTER EXTENSION postgis_tiger_geocoder UPDATE TO '$POSTGIS_VERSION'; - " -done \ No newline at end of file diff --git a/docker/timescale_db_extension/timescaledb.d/000_install_timescaledb.sh b/docker/timescale_db_extension/timescaledb.d/000_install_timescaledb.sh deleted file mode 100644 index 38823021f..000000000 --- a/docker/timescale_db_extension/timescaledb.d/000_install_timescaledb.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/bash - -create_sql=`mktemp` - -if [ -z "${POSTGRESQL_CONF_DIR:-}" ]; then - POSTGRESQL_CONF_DIR=${PGDATA} -fi - -cat <${create_sql} -CREATE EXTENSION IF NOT EXISTS timescaledb CASCADE; -EOF - -TS_TELEMETRY='basic' -if [ "${TIMESCALEDB_TELEMETRY:-}" == "off" ]; then - TS_TELEMETRY='off' - - # We delete the job as well to ensure that we do not spam the - # log with other messages related to the Telemetry job. - cat <>${create_sql} -SELECT alter_job(1,scheduled:=false); -EOF -fi - -echo "timescaledb.telemetry_level=${TS_TELEMETRY}" >> ${POSTGRESQL_CONF_DIR}/postgresql.conf - -if [ -z "${POSTGRESQL_PASSWORD:-}" ]; then - POSTGRESQL_PASSWORD=${POSTGRES_PASSWORD:-} -fi -export PGPASSWORD="$POSTGRESQL_PASSWORD" - -# create extension timescaledb in initial databases -psql -U "${POSTGRES_USER}" postgres -f ${create_sql} -psql -U "${POSTGRES_USER}" template1 -f ${create_sql} - -if [ "${POSTGRES_DB:-postgres}" != 'postgres' ]; then - psql -U "${POSTGRES_USER}" "${POSTGRES_DB}" -f ${create_sql} -fi \ No newline at end of file diff --git a/docker/timescale_db_extension/timescaledb.d/001_timescaledb_tune.sh b/docker/timescale_db_extension/timescaledb.d/001_timescaledb_tune.sh deleted file mode 100644 index 95cc6db94..000000000 --- a/docker/timescale_db_extension/timescaledb.d/001_timescaledb_tune.sh +++ /dev/null @@ -1,123 +0,0 @@ -#!/bin/bash - -NO_TS_TUNE=${NO_TS_TUNE:-""} -TS_TUNE_MEMORY=${TS_TUNE_MEMORY:-""} -TS_TUNE_NUM_CPUS=${TS_TUNE_NUM_CPUS:-""} -TS_TUNE_MAX_CONNS=${TS_TUNE_MAX_CONNS:-""} -TS_TUNE_MAX_BG_WORKERS=${TS_TUNE_MAX_BG_WORKERS:-""} -TS_TUNE_WAL_DISK_SIZE=${TS_TUNE_WAL_DISK_SIZE:-""} - -if [ ! -z "${NO_TS_TUNE:-}" ]; then - # The user has explicitly requested not to run timescaledb-tune; exit this script - exit 0 -fi - - -if [ -z "${POSTGRESQL_CONF_DIR:-}" ]; then - POSTGRESQL_CONF_DIR=${PGDATA} -fi - -if [ -z "${TS_TUNE_MEMORY:-}" ]; then - # See if we can get the container's total allocated memory from the cgroups metadata - # Try with cgroups v2 first. - if [ -f /sys/fs/cgroup/cgroup.controllers ]; then - TS_TUNE_MEMORY=$(cat /sys/fs/cgroup/memory.max) - case ${TS_TUNE_MEMORY} in - max) - TS_TUNE_MEMORY="" - ;; - *) - TS_CGROUPS_MAX_MEM=true - ;; - esac - # cgroups v2 is not available, try with cgroups v1 - elif [ -f /sys/fs/cgroup/memory/memory.limit_in_bytes ]; then - TS_TUNE_MEMORY=$(cat /sys/fs/cgroup/memory/memory.limit_in_bytes) - TS_CGROUPS_MAX_MEM=true - fi - if [ "${TS_CGROUPS_MAX_MEM:-false}" != "false" ]; then - if [ "${TS_TUNE_MEMORY}" = "18446744073709551615" ]; then - # Bash seems to error out for numbers greater than signed 64-bit, - # so if the value of limit_in_bytes is the 64-bit UNSIGNED max value - # we should just bail out and hope timescaledb-tune can figure this - # out. If we don't, the next comparison is likely going to fail - # or it might store a negative value which will crash later. - TS_TUNE_MEMORY="" - fi - - FREE_KB=$(grep MemTotal: /proc/meminfo | awk '{print $2}') - FREE_BYTES=$(( ${FREE_KB} * 1024 )) - if [ ${TS_TUNE_MEMORY} -gt ${FREE_BYTES} ]; then - # Something weird is going on if the cgroups memory limit exceeds the total available - # amount of system memory reported by "free", which is the total amount of memory available on the host. - # Most likely, it is this issue: https://github.com/moby/moby/issues/18087 (if no limit is - # set, the max limit is set to the max 64 bit integer). In this case, we just leave - # TS_TUNE_MEMORY blank and let timescaledb-tune derive the memory itself using syscalls. - TS_TUNE_MEMORY="" - else - # Convert the bytes to MB so it plays nicely with timescaledb-tune - TS_TUNE_MEMORY="$(echo ${TS_TUNE_MEMORY} | awk '{print int($1 / 1024 / 1024)}')MB" - fi - fi -fi - -if [ -z "${TS_TUNE_NUM_CPUS:-}" ]; then - # See if we can get the container's available CPUs from the cgroups metadata - # Try with cgroups v2 first. - if [ -f /sys/fs/cgroup/cgroup.controllers ]; then - TS_TUNE_NUM_CPUS=$(cat /sys/fs/cgroup/cpu.max | awk '{print $1}') - if [ "${TS_TUNE_NUM_CPUS}" = "max" ]; then - TS_TUNE_NUM_CPUS="" - else - TS_TUNE_NUM_CPUS_PERIOD=$(cat /sys/fs/cgroup/cpu.max | awk '{print $2}') - fi - # cgroups v2 is not available, try with cgroups v1 - elif [ -f /sys/fs/cgroup/cpu/cpu.cfs_quota_us ]; then - TS_TUNE_NUM_CPUS=$(cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us) - if [ "${TS_TUNE_NUM_CPUS}" = "-1" ]; then - TS_TUNE_NUM_CPUS="" - else - TS_TUNE_NUM_CPUS_PERIOD=$(cat /sys/fs/cgroup/cpu/cpu.cfs_period_us) - fi - fi - - if [ -n "${TS_TUNE_NUM_CPUS}" ]; then - if [ "${TS_TUNE_NUM_CPUS_PERIOD}" != "100000" ]; then - # Detecting cpu via cgroups with modified duration is not supported - TS_TUNE_NUM_CPUS="" - else - # Determine (integer) number of CPUs, rounding up - if [ $(( ${TS_TUNE_NUM_CPUS} % 100000 )) -eq 0 ]; then - TS_TUNE_NUM_CPUS=$(( ${TS_TUNE_NUM_CPUS} / 100000 )) - else - TS_TUNE_NUM_CPUS=$(( ( ${TS_TUNE_NUM_CPUS} / 100000 ) + 1 )) - fi - fi - fi -fi - -if [ ! -z "${TS_TUNE_MEMORY:-}" ]; then - TS_TUNE_MEMORY_FLAGS=--memory="${TS_TUNE_MEMORY}" -fi - -if [ ! -z "${TS_TUNE_NUM_CPUS:-}" ]; then - TS_TUNE_NUM_CPUS_FLAGS=--cpus=${TS_TUNE_NUM_CPUS} -fi - -if [ ! -z "${TS_TUNE_MAX_CONNS:-}" ]; then - TS_TUNE_MAX_CONNS_FLAGS=--max-conns=${TS_TUNE_MAX_CONNS} -fi - -if [ ! -z "${TS_TUNE_MAX_BG_WORKERS:-}" ]; then - TS_TUNE_MAX_BG_WORKERS_FLAGS=--max-bg-workers=${TS_TUNE_MAX_BG_WORKERS} -fi - -if [ ! -z "${TS_TUNE_WAL_DISK_SIZE:-}" ]; then - TS_TUNE_WAL_DISK_SIZE_FLAGS=--wal-disk-size="${TS_TUNE_WAL_DISK_SIZE}" -fi - -if [ ! -z "${PG_MAJOR}" ]; then - TS_TUNE_PG_VERSION=--pg-version=${PG_MAJOR} -fi - -/usr/local/bin/timescaledb-tune --quiet --yes --conf-path="${POSTGRESQL_CONF_DIR}/postgresql.conf" ${TS_TUNE_MEMORY_FLAGS} ${TS_TUNE_NUM_CPUS_FLAGS} ${TS_TUNE_MAX_CONNS_FLAGS} ${TS_TUNE_MAX_BG_WORKERS_FLAGS} ${TS_TUNE_WAL_DISK_SIZE_FLAGS} ${TS_TUNE_PG_VERSION} \ No newline at end of file From c014142a4cba2b8e994b998a19087679e8ebed23 Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Tue, 15 Jul 2025 16:28:16 -0600 Subject: [PATCH 16/38] fix: use shell script to wait for db connection ready --- entrypoint.sh | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 entrypoint.sh diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100644 index 000000000..fe00065e7 --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,13 @@ +#!/bin/sh +# Wait for PostgreSQL to be ready +until PGPASSWORD="$POSTGRES_PASSWORD" pg_isready -h db -p 5432 -U "$POSTGRES_USER"; do + echo "Waiting for postgres..." + sleep 2 +done + +echo "Running migrations..." +alembic revision --autogenerate -m "Initial migration" +echo "Applying migrations..." +alembic upgrade head +echo "Starting the application..." +uvicorn main:app --host 0.0.0.0 --port 8000 \ No newline at end of file From 27550ca60d1f56fab3d255f082dc501f99a6c0dc Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Tue, 22 Jul 2025 10:04:38 -0600 Subject: [PATCH 17/38] style: clarify echo statement --- entrypoint.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/entrypoint.sh b/entrypoint.sh index fe00065e7..74677e414 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -5,7 +5,7 @@ until PGPASSWORD="$POSTGRES_PASSWORD" pg_isready -h db -p 5432 -U "$POSTGRES_USE sleep 2 done -echo "Running migrations..." +echo "Creating initial migration script..." alembic revision --autogenerate -m "Initial migration" echo "Applying migrations..." alembic upgrade head From 93d8bb4e3ba0206ee866232e876740410e422c1b Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Tue, 22 Jul 2025 10:41:49 -0600 Subject: [PATCH 18/38] feat: initial migration script --- alembic/env.py | 26 +- .../d3cadc559792_initial_migration.py | 2077 +++++++++++++++++ 2 files changed, 2088 insertions(+), 15 deletions(-) create mode 100644 alembic/versions/d3cadc559792_initial_migration.py diff --git a/alembic/env.py b/alembic/env.py index 7a43cf1f9..95ec16f5e 100644 --- a/alembic/env.py +++ b/alembic/env.py @@ -29,35 +29,28 @@ # can be acquired: # my_important_option = config.get_main_option("my_important_option") # ... etc. + load_dotenv() + user = environ.get("POSTGRES_USER", None) password = environ.get("POSTGRES_PASSWORD", None) db = environ.get("POSTGRES_DB", None) -host = environ.get("POSTGRES_HOST", "db") -port = environ.get("POSTGRES_PORT", "5432") +host = environ.get("POSTGRES_HOST", None) +port = environ.get("POSTGRES_PORT", None) SQLALCHEMY_DATABASE_URL = f"postgresql+psycopg2://{user}:{password}@{host}:{port}/{db}" config.set_main_option("sqlalchemy.url", SQLALCHEMY_DATABASE_URL) def run_migrations_offline() -> None: - """Run migrations in 'offline' mode. - - This configures the context with just a URL - and not an Engine, though an Engine is acceptable - here as well. By skipping the Engine creation - we don't even need a DBAPI to be available. - - Calls to context.execute() here emit the given string to the - script output. - - """ + """Run migrations in 'offline' mode.""" url = config.get_main_option("sqlalchemy.url") context.configure( url=url, target_metadata=target_metadata, literal_binds=True, dialect_opts={"paramstyle": "named"}, + # include_object=include_object, ) with context.begin_transaction(): @@ -78,8 +71,11 @@ def run_migrations_online() -> None: ) with connectable.connect() as connection: - context.configure(connection=connection, target_metadata=target_metadata) - + context.configure( + connection=connection, + target_metadata=target_metadata, + # include_object=include_object, + ) with context.begin_transaction(): context.run_migrations() diff --git a/alembic/versions/d3cadc559792_initial_migration.py b/alembic/versions/d3cadc559792_initial_migration.py new file mode 100644 index 000000000..33dcab70c --- /dev/null +++ b/alembic/versions/d3cadc559792_initial_migration.py @@ -0,0 +1,2077 @@ +"""Initial migration + +Revision ID: d3cadc559792 +Revises: +Create Date: 2025-07-22 10:41:01.015074 + +""" + +from typing import Sequence, Union + +from alembic import op +import geoalchemy2 +import sqlalchemy as sa +import sqlalchemy_utils +from sqlalchemy.dialects import postgresql + +# revision identifiers, used by Alembic. +revision: str = "d3cadc559792" +down_revision: Union[str, Sequence[str], None] = None +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + """Upgrade schema.""" + # ### commands auto generated by Alembic - please adjust! ### + op.create_table( + "asset", + sa.Column("filename", sa.String(), nullable=True), + sa.Column("storage_service", sa.String(), nullable=True), + sa.Column("storage_path", sa.String(), nullable=True), + sa.Column("mime_type", sa.String(), nullable=True), + sa.Column("size", sa.Integer(), nullable=True), + sa.Column( + "search_vector", + sqlalchemy_utils.types.ts_vector.TSVectorType(), + nullable=True, + ), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.PrimaryKeyConstraint("id"), + ) + op.create_index( + "ix_asset_search_vector", + "asset", + ["search_vector"], + unique=False, + postgresql_using="gin", + ) + op.create_table( + "lexicon_category", + sa.Column("name", sa.String(length=100), nullable=False), + sa.Column("description", sa.String(length=255), nullable=True), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.PrimaryKeyConstraint("id"), + sa.UniqueConstraint("name"), + ) + op.create_table( + "lexicon_term", + sa.Column("term", sa.String(length=100), nullable=False), + sa.Column("definition", sa.String(length=255), nullable=False), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.PrimaryKeyConstraint("id"), + sa.UniqueConstraint("term"), + ) + op.create_table( + "pub_author", + sa.Column("name", sa.String(), nullable=False), + sa.Column("affiliation", sa.String(), nullable=True), + sa.Column( + "search_vector", + sqlalchemy_utils.types.ts_vector.TSVectorType(), + nullable=True, + ), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.PrimaryKeyConstraint("id"), + ) + op.create_index( + "ix_pub_author_search_vector", + "pub_author", + ["search_vector"], + unique=False, + postgresql_using="gin", + ) + op.create_table( + "sensor", + sa.Column("name", sa.String(length=255), nullable=False), + sa.Column("model", sa.String(length=50), nullable=True), + sa.Column("serial_no", sa.String(length=50), nullable=True), + sa.Column("date_installed", sa.DateTime(), nullable=True), + sa.Column("date_removed", sa.DateTime(), nullable=True), + sa.Column("recording_interval", sa.Integer(), nullable=True), + sa.Column("notes", sa.String(length=50), nullable=True), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.PrimaryKeyConstraint("id"), + ) + op.create_table( + "user", + sa.Column("id", sa.Integer(), nullable=False), + sa.Column("username", sa.String(length=255), nullable=False), + sa.Column("password", sa.String(length=255), nullable=False), + sa.Column("is_superuser", sa.Boolean(), nullable=False), + sa.Column("is_active", sa.Boolean(), nullable=False), + sa.Column("avatar_url", sa.Text(), nullable=True), + sa.PrimaryKeyConstraint("id"), + ) + op.create_table( + "contact", + sa.Column("name", sa.String(length=100), nullable=False), + sa.Column("role", sa.String(length=100), nullable=False), + sa.Column( + "search_vector", + sqlalchemy_utils.types.ts_vector.TSVectorType(), + nullable=True, + ), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.ForeignKeyConstraint( + ["role"], + ["lexicon_term.term"], + ), + sa.PrimaryKeyConstraint("id"), + ) + op.create_index( + "ix_contact_search_vector", + "contact", + ["search_vector"], + unique=False, + postgresql_using="gin", + ) + op.create_table( + "geochronology_age", + sa.Column("location_id", sa.Integer(), nullable=False), + sa.Column("age", sa.Float(), nullable=False), + sa.Column("age_error", sa.Float(), nullable=True), + sa.Column("method", sa.String(length=100), nullable=True), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.ForeignKeyConstraint( + ["method"], + ["lexicon_term.term"], + ), + sa.PrimaryKeyConstraint("id"), + ) + op.create_table( + "groundwater_level_sensor", + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.Column("sensor_id", sa.Integer(), nullable=False), + sa.ForeignKeyConstraint(["sensor_id"], ["sensor.id"], ondelete="CASCADE"), + sa.PrimaryKeyConstraint("id"), + sa.UniqueConstraint("sensor_id"), + ) + op.create_table( + "lexicon_term_category_association", + sa.Column("lexicon_term", sa.String(length=100), nullable=False), + sa.Column("category_name", sa.String(length=255), nullable=False), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.ForeignKeyConstraint( + ["category_name"], ["lexicon_category.name"], ondelete="CASCADE" + ), + sa.ForeignKeyConstraint( + ["lexicon_term"], ["lexicon_term.term"], ondelete="CASCADE" + ), + sa.PrimaryKeyConstraint("id"), + ) + op.create_table( + "lexicon_triple", + sa.Column("subject", sa.String(length=100), nullable=False), + sa.Column("predicate", sa.String(length=100), nullable=False), + sa.Column("object_", sa.String(length=100), nullable=False), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.ForeignKeyConstraint(["object_"], ["lexicon_term.term"], ondelete="CASCADE"), + sa.ForeignKeyConstraint(["subject"], ["lexicon_term.term"], ondelete="CASCADE"), + sa.PrimaryKeyConstraint("id"), + ) + op.create_table( + "location", + sa.Column("notes", sa.Text(), nullable=True), + sa.Column( + "point", + geoalchemy2.types.Geometry( + geometry_type="POINT", + srid=4326, + from_text="ST_GeomFromEWKT", + name="geometry", + nullable=False, + ), + nullable=False, + ), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.Column("release_status", sa.String(length=100), nullable=True), + sa.ForeignKeyConstraint( + ["release_status"], + ["lexicon_term.term"], + ), + sa.PrimaryKeyConstraint("id"), + ) + op.create_index( + "idx_location_point", + "location", + ["point"], + unique=False, + postgresql_using="gist", + ) + op.create_table( + "publication", + sa.Column("title", sa.Text(), nullable=False), + sa.Column("abstract", sa.Text(), nullable=True), + sa.Column("doi", sa.String(), nullable=True), + sa.Column("year", sa.Integer(), nullable=True), + sa.Column("publisher", sa.String(), nullable=True), + sa.Column("url", sa.String(), nullable=True), + sa.Column("publication_type", sa.String(length=100), nullable=False), + sa.Column( + "search_vector", + sqlalchemy_utils.types.ts_vector.TSVectorType(), + nullable=True, + ), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.ForeignKeyConstraint( + ["publication_type"], + ["lexicon_term.term"], + ), + sa.PrimaryKeyConstraint("id"), + sa.UniqueConstraint("doi"), + ) + op.create_index( + "ix_publication_search_vector", + "publication", + ["search_vector"], + unique=False, + postgresql_using="gin", + ) + op.create_table( + "thing", + sa.Column("name", sa.String(length=255), nullable=False), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.Column("release_status", sa.String(length=100), nullable=True), + sa.ForeignKeyConstraint( + ["release_status"], + ["lexicon_term.term"], + ), + sa.PrimaryKeyConstraint("id"), + ) + op.create_table( + "address", + sa.Column("contact_id", sa.Integer(), nullable=False), + sa.Column("address_line_1", sa.String(length=255), nullable=False), + sa.Column("address_line_2", sa.String(length=255), nullable=True), + sa.Column("city", sa.String(length=100), nullable=False), + sa.Column("state", sa.String(length=50), nullable=False), + sa.Column("postal_code", sa.String(length=20), nullable=False), + sa.Column("country", sa.String(length=100), nullable=True), + sa.Column("address_type", sa.String(length=100), nullable=True), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.ForeignKeyConstraint( + ["address_type"], + ["lexicon_term.term"], + ), + sa.ForeignKeyConstraint(["contact_id"], ["contact.id"], ondelete="CASCADE"), + sa.PrimaryKeyConstraint("id"), + ) + op.create_table( + "asset_thing_association", + sa.Column("asset_id", sa.Integer(), nullable=False), + sa.Column("thing_id", sa.Integer(), nullable=False), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.ForeignKeyConstraint(["asset_id"], ["asset.id"], ondelete="CASCADE"), + sa.ForeignKeyConstraint(["thing_id"], ["thing.id"], ondelete="CASCADE"), + sa.PrimaryKeyConstraint("id"), + ) + op.create_table( + "email", + sa.Column("contact_id", sa.Integer(), nullable=False), + sa.Column("email", sa.String(length=100), nullable=False), + sa.Column("email_type", sa.String(length=100), nullable=True), + sa.Column( + "search_vector", + sqlalchemy_utils.types.ts_vector.TSVectorType(), + nullable=True, + ), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.ForeignKeyConstraint(["contact_id"], ["contact.id"], ondelete="CASCADE"), + sa.ForeignKeyConstraint( + ["email_type"], + ["lexicon_term.term"], + ), + sa.PrimaryKeyConstraint("id"), + ) + op.create_index( + "ix_email_search_vector", + "email", + ["search_vector"], + unique=False, + postgresql_using="gin", + ) + op.create_table( + "location_thing_association", + sa.Column("location_id", sa.Integer(), nullable=False), + sa.Column("thing_id", sa.Integer(), nullable=False), + sa.Column( + "effective_start", + sa.DateTime(), + server_default=sa.text("now()"), + nullable=False, + ), + sa.Column("effective_end", sa.DateTime(), nullable=True), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.ForeignKeyConstraint(["location_id"], ["location.id"], ondelete="CASCADE"), + sa.ForeignKeyConstraint(["thing_id"], ["thing.id"], ondelete="CASCADE"), + sa.PrimaryKeyConstraint("location_id", "thing_id", "id"), + ) + op.create_table( + "phone", + sa.Column("contact_id", sa.Integer(), nullable=False), + sa.Column("phone_number", sa.String(length=20), nullable=False), + sa.Column("phone_type", sa.String(length=100), nullable=True), + sa.Column( + "search_vector", + sqlalchemy_utils.types.ts_vector.TSVectorType(), + nullable=True, + ), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.ForeignKeyConstraint(["contact_id"], ["contact.id"], ondelete="CASCADE"), + sa.ForeignKeyConstraint( + ["phone_type"], + ["lexicon_term.term"], + ), + sa.PrimaryKeyConstraint("id"), + ) + op.create_index( + "ix_phone_search_vector", + "phone", + ["search_vector"], + unique=False, + postgresql_using="gin", + ) + op.create_table( + "pub_author_contact_association", + sa.Column("author_id", sa.Integer(), nullable=False), + sa.Column("contact_id", sa.Integer(), nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.ForeignKeyConstraint(["author_id"], ["pub_author.id"], ondelete="CASCADE"), + sa.ForeignKeyConstraint(["contact_id"], ["contact.id"], ondelete="CASCADE"), + sa.PrimaryKeyConstraint("author_id", "contact_id"), + ) + op.create_table( + "pub_author_publication_association", + sa.Column("publication_id", sa.Integer(), nullable=False), + sa.Column("author_id", sa.Integer(), nullable=False), + sa.Column("author_order", sa.Integer(), nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.ForeignKeyConstraint(["author_id"], ["pub_author.id"], ondelete="CASCADE"), + sa.ForeignKeyConstraint( + ["publication_id"], ["publication.id"], ondelete="CASCADE" + ), + sa.PrimaryKeyConstraint("publication_id", "author_id"), + ) + op.create_table( + "series", + sa.Column("observed_property", sa.String(length=100), nullable=False), + sa.Column("unit", sa.String(length=100), nullable=False), + sa.Column("name", sa.String(length=255), nullable=False), + sa.Column("description", sa.Text(), nullable=True), + sa.Column("sensor_id", sa.Integer(), nullable=True), + sa.Column("thing_id", sa.Integer(), nullable=False), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.Column("release_status", sa.String(length=100), nullable=True), + sa.ForeignKeyConstraint( + ["observed_property"], + ["lexicon_term.term"], + ), + sa.ForeignKeyConstraint( + ["release_status"], + ["lexicon_term.term"], + ), + sa.ForeignKeyConstraint(["sensor_id"], ["sensor.id"], ondelete="CASCADE"), + sa.ForeignKeyConstraint(["thing_id"], ["thing.id"], ondelete="CASCADE"), + sa.ForeignKeyConstraint( + ["unit"], + ["lexicon_term.term"], + ), + sa.PrimaryKeyConstraint("id"), + ) + op.create_table( + "spring_thing", + sa.Column("description", sa.String(length=255), nullable=True), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.Column("thing_id", sa.Integer(), nullable=False), + sa.ForeignKeyConstraint(["thing_id"], ["thing.id"], ondelete="CASCADE"), + sa.PrimaryKeyConstraint("id"), + sa.UniqueConstraint("thing_id"), + ) + op.create_table( + "thing_contact_association", + sa.Column("thing_id", sa.Integer(), nullable=False), + sa.Column("contact_id", sa.Integer(), nullable=False), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.ForeignKeyConstraint( + ["contact_id"], + ["contact.id"], + ), + sa.ForeignKeyConstraint( + ["thing_id"], + ["thing.id"], + ), + sa.PrimaryKeyConstraint("id"), + ) + op.create_table( + "thing_id_link", + sa.Column("thing_id", sa.Integer(), nullable=True), + sa.Column("relation", sa.String(length=100), nullable=False), + sa.Column("alternate_id", sa.String(length=100), nullable=False), + sa.Column("alternate_organization", sa.String(length=100), nullable=False), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.ForeignKeyConstraint( + ["alternate_organization"], + ["lexicon_term.term"], + ), + sa.ForeignKeyConstraint( + ["relation"], + ["lexicon_term.term"], + ), + sa.ForeignKeyConstraint(["thing_id"], ["thing.id"], ondelete="CASCADE"), + sa.PrimaryKeyConstraint("id"), + ) + op.create_table( + "well_thing", + sa.Column("well_depth", sa.Float(), nullable=True), + sa.Column("hole_depth", sa.Float(), nullable=True), + sa.Column("well_type", sa.String(length=100), nullable=True), + sa.Column("casing_diameter", sa.Float(), nullable=True), + sa.Column("casing_depth", sa.Float(), nullable=True), + sa.Column("casing_description", sa.String(length=50), nullable=True), + sa.Column("construction_notes", sa.String(length=250), nullable=True), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.Column("thing_id", sa.Integer(), nullable=False), + sa.ForeignKeyConstraint(["thing_id"], ["thing.id"], ondelete="CASCADE"), + sa.ForeignKeyConstraint( + ["well_type"], + ["lexicon_term.term"], + ), + sa.PrimaryKeyConstraint("id"), + sa.UniqueConstraint("thing_id"), + ) + op.create_table( + "collaborative_network_well", + sa.Column("actively_monitored", sa.Boolean(), nullable=False), + sa.Column("well_id", sa.Integer(), nullable=False), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.ForeignKeyConstraint(["well_id"], ["well_thing.id"], ondelete="CASCADE"), + sa.PrimaryKeyConstraint("id"), + ) + op.create_table( + "geochemical_series", + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.Column("series_id", sa.Integer(), nullable=False), + sa.ForeignKeyConstraint(["series_id"], ["series.id"], ondelete="CASCADE"), + sa.PrimaryKeyConstraint("id"), + sa.UniqueConstraint("series_id"), + ) + op.create_table( + "geothermal_series", + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.Column("series_id", sa.Integer(), nullable=False), + sa.ForeignKeyConstraint(["series_id"], ["series.id"], ondelete="CASCADE"), + sa.PrimaryKeyConstraint("id"), + sa.UniqueConstraint("series_id"), + ) + op.create_table( + "groundwater_level_series", + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.Column("series_id", sa.Integer(), nullable=False), + sa.ForeignKeyConstraint(["series_id"], ["series.id"], ondelete="CASCADE"), + sa.PrimaryKeyConstraint("id"), + sa.UniqueConstraint("series_id"), + ) + op.create_table( + "well_screen", + sa.Column("well_id", sa.Integer(), nullable=False), + sa.Column("screen_depth_top", sa.Float(), nullable=False), + sa.Column("screen_depth_bottom", sa.Float(), nullable=False), + sa.Column("screen_type", sa.String(length=100), nullable=True), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.ForeignKeyConstraint( + ["screen_type"], + ["lexicon_term.term"], + ), + sa.ForeignKeyConstraint(["well_id"], ["well_thing.id"], ondelete="CASCADE"), + sa.PrimaryKeyConstraint("id"), + ) + op.drop_table("loader_lookuptables") + op.drop_index(op.f("idx_tiger_addr_tlid_statefp"), table_name="addr") + op.drop_index(op.f("idx_tiger_addr_zip"), table_name="addr") + op.drop_table("addr") + op.drop_index(op.f("idx_tiger_county"), table_name="county") + op.drop_table("county") + op.drop_index(op.f("idx_tiger_featnames_lname"), table_name="featnames") + op.drop_index(op.f("idx_tiger_featnames_snd_name"), table_name="featnames") + op.drop_index(op.f("idx_tiger_featnames_tlid_statefp"), table_name="featnames") + op.drop_table("featnames") + op.drop_table("state_lookup") + op.drop_index(op.f("place_lookup_name_idx"), table_name="place_lookup") + op.drop_index(op.f("place_lookup_state_idx"), table_name="place_lookup") + op.drop_table("place_lookup") + op.drop_table("zip_state") + op.drop_index( + op.f("secondary_unit_lookup_abbrev_idx"), table_name="secondary_unit_lookup" + ) + op.drop_table("secondary_unit_lookup") + op.drop_index( + op.f("idx_tiger_state_the_geom_gist"), + table_name="state", + postgresql_using="gist", + ) + op.drop_table("state") + op.drop_index( + op.f("idx_addrfeat_geom_gist"), table_name="addrfeat", postgresql_using="gist" + ) + op.drop_index(op.f("idx_addrfeat_tlid"), table_name="addrfeat") + op.drop_index(op.f("idx_addrfeat_zipl"), table_name="addrfeat") + op.drop_index(op.f("idx_addrfeat_zipr"), table_name="addrfeat") + op.drop_table("addrfeat") + op.drop_index(op.f("direction_lookup_abbrev_idx"), table_name="direction_lookup") + op.drop_table("direction_lookup") + op.drop_index(op.f("idx_tiger_faces_countyfp"), table_name="faces") + op.drop_index(op.f("idx_tiger_faces_tfid"), table_name="faces") + op.drop_index( + op.f("tiger_faces_the_geom_gist"), table_name="faces", postgresql_using="gist" + ) + op.drop_table("faces") + op.drop_table("bg") + op.drop_table("zip_lookup_all") + op.drop_index( + op.f("tige_cousub_the_geom_gist"), table_name="cousub", postgresql_using="gist" + ) + op.drop_table("cousub") + op.drop_table("pagc_rules") + op.drop_table("zcta5") + op.drop_table("zip_lookup") + op.drop_index(op.f("county_lookup_name_idx"), table_name="county_lookup") + op.drop_index(op.f("county_lookup_state_idx"), table_name="county_lookup") + op.drop_table("county_lookup") + op.drop_index(op.f("idx_edges_tlid"), table_name="edges") + op.drop_index(op.f("idx_tiger_edges_countyfp"), table_name="edges") + op.drop_index( + op.f("idx_tiger_edges_the_geom_gist"), + table_name="edges", + postgresql_using="gist", + ) + op.drop_table("edges") + op.drop_table("tabblock20") + op.drop_table("loader_variables") + op.drop_table("pagc_gaz") + op.drop_index( + op.f("street_type_lookup_abbrev_idx"), table_name="street_type_lookup" + ) + op.drop_table("street_type_lookup") + op.drop_table("geocode_settings_default") + op.drop_table("geocode_settings") + op.drop_table("zip_state_loc") + op.drop_table("tract") + op.drop_table("tabblock") + op.drop_table("spatial_ref_sys") + op.drop_table("topology") + op.drop_table("pagc_lex") + op.drop_table("loader_platform") + op.drop_table("zip_lookup_base") + op.drop_index( + op.f("tiger_place_the_geom_gist"), table_name="place", postgresql_using="gist" + ) + op.drop_table("place") + op.drop_index(op.f("countysub_lookup_name_idx"), table_name="countysub_lookup") + op.drop_index(op.f("countysub_lookup_state_idx"), table_name="countysub_lookup") + op.drop_table("countysub_lookup") + op.drop_table("layer") + # ### end Alembic commands ### + + +def downgrade() -> None: + """Downgrade schema.""" + # ### commands auto generated by Alembic - please adjust! ### + op.create_table( + "layer", + sa.Column("topology_id", sa.INTEGER(), autoincrement=False, nullable=False), + sa.Column("layer_id", sa.INTEGER(), autoincrement=False, nullable=False), + sa.Column("schema_name", sa.VARCHAR(), autoincrement=False, nullable=False), + sa.Column("table_name", sa.VARCHAR(), autoincrement=False, nullable=False), + sa.Column("feature_column", sa.VARCHAR(), autoincrement=False, nullable=False), + sa.Column("feature_type", sa.INTEGER(), autoincrement=False, nullable=False), + sa.Column( + "level", + sa.INTEGER(), + server_default=sa.text("0"), + autoincrement=False, + nullable=False, + ), + sa.Column("child_id", sa.INTEGER(), autoincrement=False, nullable=True), + sa.ForeignKeyConstraint( + ["topology_id"], ["topology.id"], name=op.f("layer_topology_id_fkey") + ), + sa.PrimaryKeyConstraint("topology_id", "layer_id", name=op.f("layer_pkey")), + sa.UniqueConstraint( + "schema_name", + "table_name", + "feature_column", + name=op.f("layer_schema_name_table_name_feature_column_key"), + postgresql_include=[], + postgresql_nulls_not_distinct=False, + ), + ) + op.create_table( + "countysub_lookup", + sa.Column("st_code", sa.INTEGER(), autoincrement=False, nullable=False), + sa.Column("state", sa.VARCHAR(length=2), autoincrement=False, nullable=True), + sa.Column("co_code", sa.INTEGER(), autoincrement=False, nullable=False), + sa.Column("county", sa.VARCHAR(length=90), autoincrement=False, nullable=True), + sa.Column("cs_code", sa.INTEGER(), autoincrement=False, nullable=False), + sa.Column("name", sa.VARCHAR(length=90), autoincrement=False, nullable=True), + sa.PrimaryKeyConstraint( + "st_code", "co_code", "cs_code", name=op.f("countysub_lookup_pkey") + ), + ) + op.create_index( + op.f("countysub_lookup_state_idx"), "countysub_lookup", ["state"], unique=False + ) + op.create_index( + op.f("countysub_lookup_name_idx"), + "countysub_lookup", + [sa.literal_column("soundex(name::text)")], + unique=False, + ) + op.create_table( + "place", + sa.Column("gid", sa.INTEGER(), autoincrement=True, nullable=False), + sa.Column("statefp", sa.VARCHAR(length=2), autoincrement=False, nullable=True), + sa.Column("placefp", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column("placens", sa.VARCHAR(length=8), autoincrement=False, nullable=True), + sa.Column("plcidfp", sa.VARCHAR(length=7), autoincrement=False, nullable=False), + sa.Column("name", sa.VARCHAR(length=100), autoincrement=False, nullable=True), + sa.Column( + "namelsad", sa.VARCHAR(length=100), autoincrement=False, nullable=True + ), + sa.Column("lsad", sa.VARCHAR(length=2), autoincrement=False, nullable=True), + sa.Column("classfp", sa.VARCHAR(length=2), autoincrement=False, nullable=True), + sa.Column("cpi", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column("pcicbsa", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column("pcinecta", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column("mtfcc", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column("funcstat", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column("aland", sa.BIGINT(), autoincrement=False, nullable=True), + sa.Column("awater", sa.BIGINT(), autoincrement=False, nullable=True), + sa.Column( + "intptlat", sa.VARCHAR(length=11), autoincrement=False, nullable=True + ), + sa.Column( + "intptlon", sa.VARCHAR(length=12), autoincrement=False, nullable=True + ), + sa.Column( + "the_geom", + geoalchemy2.types.Geometry( + from_text="ST_GeomFromEWKT", + name="geometry", + _spatial_index_reflected=True, + ), + autoincrement=False, + nullable=True, + ), + sa.CheckConstraint( + "geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL", + name=op.f("enforce_geotype_the_geom"), + ), + sa.CheckConstraint( + "st_ndims(the_geom) = 2", name=op.f("enforce_dims_the_geom") + ), + sa.CheckConstraint( + "st_srid(the_geom) = 4269", name=op.f("enforce_srid_the_geom") + ), + sa.PrimaryKeyConstraint("plcidfp", name=op.f("place_pkey")), + sa.UniqueConstraint( + "gid", + name=op.f("uidx_tiger_place_gid"), + postgresql_include=[], + postgresql_nulls_not_distinct=False, + ), + ) + op.create_index( + op.f("tiger_place_the_geom_gist"), + "place", + ["the_geom"], + unique=False, + postgresql_using="gist", + ) + op.create_table( + "zip_lookup_base", + sa.Column("zip", sa.VARCHAR(length=5), autoincrement=False, nullable=False), + sa.Column("state", sa.VARCHAR(length=40), autoincrement=False, nullable=True), + sa.Column("county", sa.VARCHAR(length=90), autoincrement=False, nullable=True), + sa.Column("city", sa.VARCHAR(length=90), autoincrement=False, nullable=True), + sa.Column("statefp", sa.VARCHAR(length=2), autoincrement=False, nullable=True), + sa.PrimaryKeyConstraint("zip", name=op.f("zip_lookup_base_pkey")), + ) + op.create_table( + "loader_platform", + sa.Column("os", sa.VARCHAR(length=50), autoincrement=False, nullable=False), + sa.Column("declare_sect", sa.TEXT(), autoincrement=False, nullable=True), + sa.Column("pgbin", sa.TEXT(), autoincrement=False, nullable=True), + sa.Column("wget", sa.TEXT(), autoincrement=False, nullable=True), + sa.Column("unzip_command", sa.TEXT(), autoincrement=False, nullable=True), + sa.Column("psql", sa.TEXT(), autoincrement=False, nullable=True), + sa.Column("path_sep", sa.TEXT(), autoincrement=False, nullable=True), + sa.Column("loader", sa.TEXT(), autoincrement=False, nullable=True), + sa.Column("environ_set_command", sa.TEXT(), autoincrement=False, nullable=True), + sa.Column( + "county_process_command", sa.TEXT(), autoincrement=False, nullable=True + ), + sa.PrimaryKeyConstraint("os", name=op.f("loader_platform_pkey")), + ) + op.create_table( + "pagc_lex", + sa.Column("id", sa.INTEGER(), autoincrement=True, nullable=False), + sa.Column("seq", sa.INTEGER(), autoincrement=False, nullable=True), + sa.Column("word", sa.TEXT(), autoincrement=False, nullable=True), + sa.Column("stdword", sa.TEXT(), autoincrement=False, nullable=True), + sa.Column("token", sa.INTEGER(), autoincrement=False, nullable=True), + sa.Column( + "is_custom", + sa.BOOLEAN(), + server_default=sa.text("true"), + autoincrement=False, + nullable=False, + ), + sa.PrimaryKeyConstraint("id", name=op.f("pagc_lex_pkey")), + ) + op.create_table( + "topology", + sa.Column("id", sa.INTEGER(), autoincrement=True, nullable=False), + sa.Column("name", sa.VARCHAR(), autoincrement=False, nullable=False), + sa.Column("srid", sa.INTEGER(), autoincrement=False, nullable=False), + sa.Column( + "precision", + sa.DOUBLE_PRECISION(precision=53), + autoincrement=False, + nullable=False, + ), + sa.Column( + "hasz", + sa.BOOLEAN(), + server_default=sa.text("false"), + autoincrement=False, + nullable=False, + ), + sa.PrimaryKeyConstraint("id", name=op.f("topology_pkey")), + sa.UniqueConstraint( + "name", + name=op.f("topology_name_key"), + postgresql_include=[], + postgresql_nulls_not_distinct=False, + ), + ) + op.create_table( + "spatial_ref_sys", + sa.Column("srid", sa.INTEGER(), autoincrement=False, nullable=False), + sa.Column( + "auth_name", sa.VARCHAR(length=256), autoincrement=False, nullable=True + ), + sa.Column("auth_srid", sa.INTEGER(), autoincrement=False, nullable=True), + sa.Column( + "srtext", sa.VARCHAR(length=2048), autoincrement=False, nullable=True + ), + sa.Column( + "proj4text", sa.VARCHAR(length=2048), autoincrement=False, nullable=True + ), + sa.CheckConstraint( + "srid > 0 AND srid <= 998999", name=op.f("spatial_ref_sys_srid_check") + ), + sa.PrimaryKeyConstraint("srid", name=op.f("spatial_ref_sys_pkey")), + ) + op.create_table( + "tabblock", + sa.Column("gid", sa.INTEGER(), autoincrement=True, nullable=False), + sa.Column("statefp", sa.VARCHAR(length=2), autoincrement=False, nullable=True), + sa.Column("countyfp", sa.VARCHAR(length=3), autoincrement=False, nullable=True), + sa.Column("tractce", sa.VARCHAR(length=6), autoincrement=False, nullable=True), + sa.Column("blockce", sa.VARCHAR(length=4), autoincrement=False, nullable=True), + sa.Column( + "tabblock_id", sa.VARCHAR(length=16), autoincrement=False, nullable=False + ), + sa.Column("name", sa.VARCHAR(length=20), autoincrement=False, nullable=True), + sa.Column("mtfcc", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column("ur", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column("uace", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column("funcstat", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column( + "aland", + sa.DOUBLE_PRECISION(precision=53), + autoincrement=False, + nullable=True, + ), + sa.Column( + "awater", + sa.DOUBLE_PRECISION(precision=53), + autoincrement=False, + nullable=True, + ), + sa.Column( + "intptlat", sa.VARCHAR(length=11), autoincrement=False, nullable=True + ), + sa.Column( + "intptlon", sa.VARCHAR(length=12), autoincrement=False, nullable=True + ), + sa.Column( + "the_geom", + geoalchemy2.types.Geometry( + spatial_index=False, + from_text="ST_GeomFromEWKT", + name="geometry", + _spatial_index_reflected=True, + ), + autoincrement=False, + nullable=True, + ), + sa.CheckConstraint( + "geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL", + name=op.f("enforce_geotype_geom"), + ), + sa.CheckConstraint("st_ndims(the_geom) = 2", name=op.f("enforce_dims_geom")), + sa.CheckConstraint("st_srid(the_geom) = 4269", name=op.f("enforce_srid_geom")), + sa.PrimaryKeyConstraint("tabblock_id", name=op.f("tabblock_pkey")), + ) + op.create_table( + "tract", + sa.Column("gid", sa.INTEGER(), autoincrement=True, nullable=False), + sa.Column("statefp", sa.VARCHAR(length=2), autoincrement=False, nullable=True), + sa.Column("countyfp", sa.VARCHAR(length=3), autoincrement=False, nullable=True), + sa.Column("tractce", sa.VARCHAR(length=6), autoincrement=False, nullable=True), + sa.Column( + "tract_id", sa.VARCHAR(length=11), autoincrement=False, nullable=False + ), + sa.Column("name", sa.VARCHAR(length=7), autoincrement=False, nullable=True), + sa.Column( + "namelsad", sa.VARCHAR(length=20), autoincrement=False, nullable=True + ), + sa.Column("mtfcc", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column("funcstat", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column( + "aland", + sa.DOUBLE_PRECISION(precision=53), + autoincrement=False, + nullable=True, + ), + sa.Column( + "awater", + sa.DOUBLE_PRECISION(precision=53), + autoincrement=False, + nullable=True, + ), + sa.Column( + "intptlat", sa.VARCHAR(length=11), autoincrement=False, nullable=True + ), + sa.Column( + "intptlon", sa.VARCHAR(length=12), autoincrement=False, nullable=True + ), + sa.Column( + "the_geom", + geoalchemy2.types.Geometry( + spatial_index=False, + from_text="ST_GeomFromEWKT", + name="geometry", + _spatial_index_reflected=True, + ), + autoincrement=False, + nullable=True, + ), + sa.CheckConstraint( + "geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL", + name=op.f("enforce_geotype_geom"), + ), + sa.CheckConstraint("st_ndims(the_geom) = 2", name=op.f("enforce_dims_geom")), + sa.CheckConstraint("st_srid(the_geom) = 4269", name=op.f("enforce_srid_geom")), + sa.PrimaryKeyConstraint("tract_id", name=op.f("tract_pkey")), + ) + op.create_table( + "zip_state_loc", + sa.Column("zip", sa.VARCHAR(length=5), autoincrement=False, nullable=False), + sa.Column("stusps", sa.VARCHAR(length=2), autoincrement=False, nullable=False), + sa.Column("statefp", sa.VARCHAR(length=2), autoincrement=False, nullable=True), + sa.Column("place", sa.VARCHAR(length=100), autoincrement=False, nullable=False), + sa.PrimaryKeyConstraint( + "zip", "stusps", "place", name=op.f("zip_state_loc_pkey") + ), + ) + op.create_table( + "geocode_settings", + sa.Column("name", sa.TEXT(), autoincrement=False, nullable=False), + sa.Column("setting", sa.TEXT(), autoincrement=False, nullable=True), + sa.Column("unit", sa.TEXT(), autoincrement=False, nullable=True), + sa.Column("category", sa.TEXT(), autoincrement=False, nullable=True), + sa.Column("short_desc", sa.TEXT(), autoincrement=False, nullable=True), + sa.PrimaryKeyConstraint("name", name=op.f("geocode_settings_pkey")), + ) + op.create_table( + "geocode_settings_default", + sa.Column("name", sa.TEXT(), autoincrement=False, nullable=False), + sa.Column("setting", sa.TEXT(), autoincrement=False, nullable=True), + sa.Column("unit", sa.TEXT(), autoincrement=False, nullable=True), + sa.Column("category", sa.TEXT(), autoincrement=False, nullable=True), + sa.Column("short_desc", sa.TEXT(), autoincrement=False, nullable=True), + sa.PrimaryKeyConstraint("name", name=op.f("geocode_settings_default_pkey")), + ) + op.create_table( + "street_type_lookup", + sa.Column("name", sa.VARCHAR(length=50), autoincrement=False, nullable=False), + sa.Column("abbrev", sa.VARCHAR(length=50), autoincrement=False, nullable=True), + sa.Column( + "is_hw", + sa.BOOLEAN(), + server_default=sa.text("false"), + autoincrement=False, + nullable=False, + ), + sa.PrimaryKeyConstraint("name", name=op.f("street_type_lookup_pkey")), + ) + op.create_index( + op.f("street_type_lookup_abbrev_idx"), + "street_type_lookup", + ["abbrev"], + unique=False, + ) + op.create_table( + "pagc_gaz", + sa.Column("id", sa.INTEGER(), autoincrement=True, nullable=False), + sa.Column("seq", sa.INTEGER(), autoincrement=False, nullable=True), + sa.Column("word", sa.TEXT(), autoincrement=False, nullable=True), + sa.Column("stdword", sa.TEXT(), autoincrement=False, nullable=True), + sa.Column("token", sa.INTEGER(), autoincrement=False, nullable=True), + sa.Column( + "is_custom", + sa.BOOLEAN(), + server_default=sa.text("true"), + autoincrement=False, + nullable=False, + ), + sa.PrimaryKeyConstraint("id", name=op.f("pagc_gaz_pkey")), + ) + op.create_table( + "loader_variables", + sa.Column( + "tiger_year", sa.VARCHAR(length=4), autoincrement=False, nullable=False + ), + sa.Column("website_root", sa.TEXT(), autoincrement=False, nullable=True), + sa.Column("staging_fold", sa.TEXT(), autoincrement=False, nullable=True), + sa.Column("data_schema", sa.TEXT(), autoincrement=False, nullable=True), + sa.Column("staging_schema", sa.TEXT(), autoincrement=False, nullable=True), + sa.PrimaryKeyConstraint("tiger_year", name=op.f("loader_variables_pkey")), + ) + op.create_table( + "tabblock20", + sa.Column("statefp", sa.VARCHAR(length=2), autoincrement=False, nullable=True), + sa.Column("countyfp", sa.VARCHAR(length=3), autoincrement=False, nullable=True), + sa.Column("tractce", sa.VARCHAR(length=6), autoincrement=False, nullable=True), + sa.Column("blockce", sa.VARCHAR(length=4), autoincrement=False, nullable=True), + sa.Column("geoid", sa.VARCHAR(length=15), autoincrement=False, nullable=False), + sa.Column("name", sa.VARCHAR(length=10), autoincrement=False, nullable=True), + sa.Column("mtfcc", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column("ur", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column("uace", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column("uatype", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column("funcstat", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column( + "aland", + sa.DOUBLE_PRECISION(precision=53), + autoincrement=False, + nullable=True, + ), + sa.Column( + "awater", + sa.DOUBLE_PRECISION(precision=53), + autoincrement=False, + nullable=True, + ), + sa.Column( + "intptlat", sa.VARCHAR(length=11), autoincrement=False, nullable=True + ), + sa.Column( + "intptlon", sa.VARCHAR(length=12), autoincrement=False, nullable=True + ), + sa.Column( + "the_geom", + geoalchemy2.types.Geometry( + geometry_type="MULTIPOLYGON", + srid=4269, + spatial_index=False, + from_text="ST_GeomFromEWKT", + name="geometry", + _spatial_index_reflected=True, + ), + autoincrement=False, + nullable=True, + ), + sa.Column( + "housing", + sa.DOUBLE_PRECISION(precision=53), + autoincrement=False, + nullable=True, + ), + sa.Column( + "pop", sa.DOUBLE_PRECISION(precision=53), autoincrement=False, nullable=True + ), + sa.PrimaryKeyConstraint("geoid", name=op.f("pk_tabblock20")), + ) + op.create_table( + "edges", + sa.Column("gid", sa.INTEGER(), autoincrement=True, nullable=False), + sa.Column("statefp", sa.VARCHAR(length=2), autoincrement=False, nullable=True), + sa.Column("countyfp", sa.VARCHAR(length=3), autoincrement=False, nullable=True), + sa.Column("tlid", sa.BIGINT(), autoincrement=False, nullable=True), + sa.Column( + "tfidl", + sa.NUMERIC(precision=10, scale=0), + autoincrement=False, + nullable=True, + ), + sa.Column( + "tfidr", + sa.NUMERIC(precision=10, scale=0), + autoincrement=False, + nullable=True, + ), + sa.Column("mtfcc", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column( + "fullname", sa.VARCHAR(length=100), autoincrement=False, nullable=True + ), + sa.Column("smid", sa.VARCHAR(length=22), autoincrement=False, nullable=True), + sa.Column( + "lfromadd", sa.VARCHAR(length=12), autoincrement=False, nullable=True + ), + sa.Column("ltoadd", sa.VARCHAR(length=12), autoincrement=False, nullable=True), + sa.Column( + "rfromadd", sa.VARCHAR(length=12), autoincrement=False, nullable=True + ), + sa.Column("rtoadd", sa.VARCHAR(length=12), autoincrement=False, nullable=True), + sa.Column("zipl", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column("zipr", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column("featcat", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column("hydroflg", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column("railflg", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column("roadflg", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column("olfflg", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column("passflg", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column("divroad", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column("exttyp", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column("ttyp", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column( + "deckedroad", sa.VARCHAR(length=1), autoincrement=False, nullable=True + ), + sa.Column("artpath", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column("persist", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column("gcseflg", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column("offsetl", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column("offsetr", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column( + "tnidf", + sa.NUMERIC(precision=10, scale=0), + autoincrement=False, + nullable=True, + ), + sa.Column( + "tnidt", + sa.NUMERIC(precision=10, scale=0), + autoincrement=False, + nullable=True, + ), + sa.Column( + "the_geom", + geoalchemy2.types.Geometry( + from_text="ST_GeomFromEWKT", + name="geometry", + _spatial_index_reflected=True, + ), + autoincrement=False, + nullable=True, + ), + sa.CheckConstraint( + "geometrytype(the_geom) = 'MULTILINESTRING'::text OR the_geom IS NULL", + name=op.f("enforce_geotype_the_geom"), + ), + sa.CheckConstraint( + "st_ndims(the_geom) = 2", name=op.f("enforce_dims_the_geom") + ), + sa.CheckConstraint( + "st_srid(the_geom) = 4269", name=op.f("enforce_srid_the_geom") + ), + sa.PrimaryKeyConstraint("gid", name=op.f("edges_pkey")), + ) + op.create_index( + op.f("idx_tiger_edges_the_geom_gist"), + "edges", + ["the_geom"], + unique=False, + postgresql_using="gist", + ) + op.create_index( + op.f("idx_tiger_edges_countyfp"), "edges", ["countyfp"], unique=False + ) + op.create_index(op.f("idx_edges_tlid"), "edges", ["tlid"], unique=False) + op.create_table( + "county_lookup", + sa.Column("st_code", sa.INTEGER(), autoincrement=False, nullable=False), + sa.Column("state", sa.VARCHAR(length=2), autoincrement=False, nullable=True), + sa.Column("co_code", sa.INTEGER(), autoincrement=False, nullable=False), + sa.Column("name", sa.VARCHAR(length=90), autoincrement=False, nullable=True), + sa.PrimaryKeyConstraint("st_code", "co_code", name=op.f("county_lookup_pkey")), + ) + op.create_index( + op.f("county_lookup_state_idx"), "county_lookup", ["state"], unique=False + ) + op.create_index( + op.f("county_lookup_name_idx"), + "county_lookup", + [sa.literal_column("soundex(name::text)")], + unique=False, + ) + op.create_table( + "zip_lookup", + sa.Column("zip", sa.INTEGER(), autoincrement=False, nullable=False), + sa.Column("st_code", sa.INTEGER(), autoincrement=False, nullable=True), + sa.Column("state", sa.VARCHAR(length=2), autoincrement=False, nullable=True), + sa.Column("co_code", sa.INTEGER(), autoincrement=False, nullable=True), + sa.Column("county", sa.VARCHAR(length=90), autoincrement=False, nullable=True), + sa.Column("cs_code", sa.INTEGER(), autoincrement=False, nullable=True), + sa.Column("cousub", sa.VARCHAR(length=90), autoincrement=False, nullable=True), + sa.Column("pl_code", sa.INTEGER(), autoincrement=False, nullable=True), + sa.Column("place", sa.VARCHAR(length=90), autoincrement=False, nullable=True), + sa.Column("cnt", sa.INTEGER(), autoincrement=False, nullable=True), + sa.PrimaryKeyConstraint("zip", name=op.f("zip_lookup_pkey")), + ) + op.create_table( + "zcta5", + sa.Column("gid", sa.INTEGER(), autoincrement=True, nullable=False), + sa.Column("statefp", sa.VARCHAR(length=2), autoincrement=False, nullable=False), + sa.Column("zcta5ce", sa.VARCHAR(length=5), autoincrement=False, nullable=False), + sa.Column("classfp", sa.VARCHAR(length=2), autoincrement=False, nullable=True), + sa.Column("mtfcc", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column("funcstat", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column( + "aland", + sa.DOUBLE_PRECISION(precision=53), + autoincrement=False, + nullable=True, + ), + sa.Column( + "awater", + sa.DOUBLE_PRECISION(precision=53), + autoincrement=False, + nullable=True, + ), + sa.Column( + "intptlat", sa.VARCHAR(length=11), autoincrement=False, nullable=True + ), + sa.Column( + "intptlon", sa.VARCHAR(length=12), autoincrement=False, nullable=True + ), + sa.Column("partflg", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column( + "the_geom", + geoalchemy2.types.Geometry( + spatial_index=False, + from_text="ST_GeomFromEWKT", + name="geometry", + _spatial_index_reflected=True, + ), + autoincrement=False, + nullable=True, + ), + sa.CheckConstraint( + "geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL", + name=op.f("enforce_geotype_the_geom"), + ), + sa.CheckConstraint( + "st_ndims(the_geom) = 2", name=op.f("enforce_dims_the_geom") + ), + sa.CheckConstraint( + "st_srid(the_geom) = 4269", name=op.f("enforce_srid_the_geom") + ), + sa.PrimaryKeyConstraint( + "zcta5ce", "statefp", name=op.f("pk_tiger_zcta5_zcta5ce") + ), + sa.UniqueConstraint( + "gid", + name=op.f("uidx_tiger_zcta5_gid"), + postgresql_include=[], + postgresql_nulls_not_distinct=False, + ), + ) + op.create_table( + "pagc_rules", + sa.Column("id", sa.INTEGER(), autoincrement=True, nullable=False), + sa.Column("rule", sa.TEXT(), autoincrement=False, nullable=True), + sa.Column( + "is_custom", + sa.BOOLEAN(), + server_default=sa.text("true"), + autoincrement=False, + nullable=True, + ), + sa.PrimaryKeyConstraint("id", name=op.f("pagc_rules_pkey")), + ) + op.create_table( + "cousub", + sa.Column("gid", sa.INTEGER(), autoincrement=True, nullable=False), + sa.Column("statefp", sa.VARCHAR(length=2), autoincrement=False, nullable=True), + sa.Column("countyfp", sa.VARCHAR(length=3), autoincrement=False, nullable=True), + sa.Column("cousubfp", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column("cousubns", sa.VARCHAR(length=8), autoincrement=False, nullable=True), + sa.Column( + "cosbidfp", sa.VARCHAR(length=10), autoincrement=False, nullable=False + ), + sa.Column("name", sa.VARCHAR(length=100), autoincrement=False, nullable=True), + sa.Column( + "namelsad", sa.VARCHAR(length=100), autoincrement=False, nullable=True + ), + sa.Column("lsad", sa.VARCHAR(length=2), autoincrement=False, nullable=True), + sa.Column("classfp", sa.VARCHAR(length=2), autoincrement=False, nullable=True), + sa.Column("mtfcc", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column("cnectafp", sa.VARCHAR(length=3), autoincrement=False, nullable=True), + sa.Column("nectafp", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column("nctadvfp", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column("funcstat", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column( + "aland", + sa.NUMERIC(precision=14, scale=0), + autoincrement=False, + nullable=True, + ), + sa.Column( + "awater", + sa.NUMERIC(precision=14, scale=0), + autoincrement=False, + nullable=True, + ), + sa.Column( + "intptlat", sa.VARCHAR(length=11), autoincrement=False, nullable=True + ), + sa.Column( + "intptlon", sa.VARCHAR(length=12), autoincrement=False, nullable=True + ), + sa.Column( + "the_geom", + geoalchemy2.types.Geometry( + from_text="ST_GeomFromEWKT", + name="geometry", + _spatial_index_reflected=True, + ), + autoincrement=False, + nullable=True, + ), + sa.CheckConstraint( + "geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL", + name=op.f("enforce_geotype_the_geom"), + ), + sa.CheckConstraint( + "st_ndims(the_geom) = 2", name=op.f("enforce_dims_the_geom") + ), + sa.CheckConstraint( + "st_srid(the_geom) = 4269", name=op.f("enforce_srid_the_geom") + ), + sa.PrimaryKeyConstraint("cosbidfp", name=op.f("cousub_pkey")), + sa.UniqueConstraint( + "gid", + name=op.f("uidx_cousub_gid"), + postgresql_include=[], + postgresql_nulls_not_distinct=False, + ), + ) + op.create_index( + op.f("tige_cousub_the_geom_gist"), + "cousub", + ["the_geom"], + unique=False, + postgresql_using="gist", + ) + op.create_table( + "zip_lookup_all", + sa.Column("zip", sa.INTEGER(), autoincrement=False, nullable=True), + sa.Column("st_code", sa.INTEGER(), autoincrement=False, nullable=True), + sa.Column("state", sa.VARCHAR(length=2), autoincrement=False, nullable=True), + sa.Column("co_code", sa.INTEGER(), autoincrement=False, nullable=True), + sa.Column("county", sa.VARCHAR(length=90), autoincrement=False, nullable=True), + sa.Column("cs_code", sa.INTEGER(), autoincrement=False, nullable=True), + sa.Column("cousub", sa.VARCHAR(length=90), autoincrement=False, nullable=True), + sa.Column("pl_code", sa.INTEGER(), autoincrement=False, nullable=True), + sa.Column("place", sa.VARCHAR(length=90), autoincrement=False, nullable=True), + sa.Column("cnt", sa.INTEGER(), autoincrement=False, nullable=True), + ) + op.create_table( + "bg", + sa.Column("gid", sa.INTEGER(), autoincrement=True, nullable=False), + sa.Column("statefp", sa.VARCHAR(length=2), autoincrement=False, nullable=True), + sa.Column("countyfp", sa.VARCHAR(length=3), autoincrement=False, nullable=True), + sa.Column("tractce", sa.VARCHAR(length=6), autoincrement=False, nullable=True), + sa.Column("blkgrpce", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column("bg_id", sa.VARCHAR(length=12), autoincrement=False, nullable=False), + sa.Column( + "namelsad", sa.VARCHAR(length=13), autoincrement=False, nullable=True + ), + sa.Column("mtfcc", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column("funcstat", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column( + "aland", + sa.DOUBLE_PRECISION(precision=53), + autoincrement=False, + nullable=True, + ), + sa.Column( + "awater", + sa.DOUBLE_PRECISION(precision=53), + autoincrement=False, + nullable=True, + ), + sa.Column( + "intptlat", sa.VARCHAR(length=11), autoincrement=False, nullable=True + ), + sa.Column( + "intptlon", sa.VARCHAR(length=12), autoincrement=False, nullable=True + ), + sa.Column( + "the_geom", + geoalchemy2.types.Geometry( + spatial_index=False, + from_text="ST_GeomFromEWKT", + name="geometry", + _spatial_index_reflected=True, + ), + autoincrement=False, + nullable=True, + ), + sa.CheckConstraint( + "geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL", + name=op.f("enforce_geotype_geom"), + ), + sa.CheckConstraint("st_ndims(the_geom) = 2", name=op.f("enforce_dims_geom")), + sa.CheckConstraint("st_srid(the_geom) = 4269", name=op.f("enforce_srid_geom")), + sa.PrimaryKeyConstraint("bg_id", name=op.f("bg_pkey")), + comment="block groups", + ) + op.create_table( + "faces", + sa.Column("gid", sa.INTEGER(), autoincrement=True, nullable=False), + sa.Column( + "tfid", + sa.NUMERIC(precision=10, scale=0), + autoincrement=False, + nullable=True, + ), + sa.Column( + "statefp00", sa.VARCHAR(length=2), autoincrement=False, nullable=True + ), + sa.Column( + "countyfp00", sa.VARCHAR(length=3), autoincrement=False, nullable=True + ), + sa.Column( + "tractce00", sa.VARCHAR(length=6), autoincrement=False, nullable=True + ), + sa.Column( + "blkgrpce00", sa.VARCHAR(length=1), autoincrement=False, nullable=True + ), + sa.Column( + "blockce00", sa.VARCHAR(length=4), autoincrement=False, nullable=True + ), + sa.Column( + "cousubfp00", sa.VARCHAR(length=5), autoincrement=False, nullable=True + ), + sa.Column( + "submcdfp00", sa.VARCHAR(length=5), autoincrement=False, nullable=True + ), + sa.Column( + "conctyfp00", sa.VARCHAR(length=5), autoincrement=False, nullable=True + ), + sa.Column( + "placefp00", sa.VARCHAR(length=5), autoincrement=False, nullable=True + ), + sa.Column( + "aiannhfp00", sa.VARCHAR(length=5), autoincrement=False, nullable=True + ), + sa.Column( + "aiannhce00", sa.VARCHAR(length=4), autoincrement=False, nullable=True + ), + sa.Column( + "comptyp00", sa.VARCHAR(length=1), autoincrement=False, nullable=True + ), + sa.Column( + "trsubfp00", sa.VARCHAR(length=5), autoincrement=False, nullable=True + ), + sa.Column( + "trsubce00", sa.VARCHAR(length=3), autoincrement=False, nullable=True + ), + sa.Column("anrcfp00", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column( + "elsdlea00", sa.VARCHAR(length=5), autoincrement=False, nullable=True + ), + sa.Column( + "scsdlea00", sa.VARCHAR(length=5), autoincrement=False, nullable=True + ), + sa.Column( + "unsdlea00", sa.VARCHAR(length=5), autoincrement=False, nullable=True + ), + sa.Column("uace00", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column("cd108fp", sa.VARCHAR(length=2), autoincrement=False, nullable=True), + sa.Column("sldust00", sa.VARCHAR(length=3), autoincrement=False, nullable=True), + sa.Column("sldlst00", sa.VARCHAR(length=3), autoincrement=False, nullable=True), + sa.Column("vtdst00", sa.VARCHAR(length=6), autoincrement=False, nullable=True), + sa.Column( + "zcta5ce00", sa.VARCHAR(length=5), autoincrement=False, nullable=True + ), + sa.Column("tazce00", sa.VARCHAR(length=6), autoincrement=False, nullable=True), + sa.Column("ugace00", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column( + "puma5ce00", sa.VARCHAR(length=5), autoincrement=False, nullable=True + ), + sa.Column("statefp", sa.VARCHAR(length=2), autoincrement=False, nullable=True), + sa.Column("countyfp", sa.VARCHAR(length=3), autoincrement=False, nullable=True), + sa.Column("tractce", sa.VARCHAR(length=6), autoincrement=False, nullable=True), + sa.Column("blkgrpce", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column("blockce", sa.VARCHAR(length=4), autoincrement=False, nullable=True), + sa.Column("cousubfp", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column("submcdfp", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column("conctyfp", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column("placefp", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column("aiannhfp", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column("aiannhce", sa.VARCHAR(length=4), autoincrement=False, nullable=True), + sa.Column("comptyp", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column("trsubfp", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column("trsubce", sa.VARCHAR(length=3), autoincrement=False, nullable=True), + sa.Column("anrcfp", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column("ttractce", sa.VARCHAR(length=6), autoincrement=False, nullable=True), + sa.Column("tblkgpce", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column("elsdlea", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column("scsdlea", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column("unsdlea", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column("uace", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column("cd111fp", sa.VARCHAR(length=2), autoincrement=False, nullable=True), + sa.Column("sldust", sa.VARCHAR(length=3), autoincrement=False, nullable=True), + sa.Column("sldlst", sa.VARCHAR(length=3), autoincrement=False, nullable=True), + sa.Column("vtdst", sa.VARCHAR(length=6), autoincrement=False, nullable=True), + sa.Column("zcta5ce", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column("tazce", sa.VARCHAR(length=6), autoincrement=False, nullable=True), + sa.Column("ugace", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column("puma5ce", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column("csafp", sa.VARCHAR(length=3), autoincrement=False, nullable=True), + sa.Column("cbsafp", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column("metdivfp", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column("cnectafp", sa.VARCHAR(length=3), autoincrement=False, nullable=True), + sa.Column("nectafp", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column("nctadvfp", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column("lwflag", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column("offset", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column( + "atotal", + sa.DOUBLE_PRECISION(precision=53), + autoincrement=False, + nullable=True, + ), + sa.Column( + "intptlat", sa.VARCHAR(length=11), autoincrement=False, nullable=True + ), + sa.Column( + "intptlon", sa.VARCHAR(length=12), autoincrement=False, nullable=True + ), + sa.Column( + "the_geom", + geoalchemy2.types.Geometry( + from_text="ST_GeomFromEWKT", + name="geometry", + _spatial_index_reflected=True, + ), + autoincrement=False, + nullable=True, + ), + sa.Column( + "tractce20", sa.VARCHAR(length=6), autoincrement=False, nullable=True + ), + sa.Column( + "blkgrpce20", sa.VARCHAR(length=1), autoincrement=False, nullable=True + ), + sa.Column( + "blockce20", sa.VARCHAR(length=4), autoincrement=False, nullable=True + ), + sa.Column( + "countyfp20", sa.VARCHAR(length=3), autoincrement=False, nullable=True + ), + sa.Column( + "statefp20", sa.VARCHAR(length=2), autoincrement=False, nullable=True + ), + sa.CheckConstraint( + "geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL", + name=op.f("enforce_geotype_the_geom"), + ), + sa.CheckConstraint( + "st_ndims(the_geom) = 2", name=op.f("enforce_dims_the_geom") + ), + sa.CheckConstraint( + "st_srid(the_geom) = 4269", name=op.f("enforce_srid_the_geom") + ), + sa.PrimaryKeyConstraint("gid", name=op.f("faces_pkey")), + ) + op.create_index( + op.f("tiger_faces_the_geom_gist"), + "faces", + ["the_geom"], + unique=False, + postgresql_using="gist", + ) + op.create_index(op.f("idx_tiger_faces_tfid"), "faces", ["tfid"], unique=False) + op.create_index( + op.f("idx_tiger_faces_countyfp"), "faces", ["countyfp"], unique=False + ) + op.create_table( + "direction_lookup", + sa.Column("name", sa.VARCHAR(length=20), autoincrement=False, nullable=False), + sa.Column("abbrev", sa.VARCHAR(length=3), autoincrement=False, nullable=True), + sa.PrimaryKeyConstraint("name", name=op.f("direction_lookup_pkey")), + ) + op.create_index( + op.f("direction_lookup_abbrev_idx"), + "direction_lookup", + ["abbrev"], + unique=False, + ) + op.create_table( + "addrfeat", + sa.Column("gid", sa.INTEGER(), autoincrement=True, nullable=False), + sa.Column("tlid", sa.BIGINT(), autoincrement=False, nullable=True), + sa.Column("statefp", sa.VARCHAR(length=2), autoincrement=False, nullable=False), + sa.Column("aridl", sa.VARCHAR(length=22), autoincrement=False, nullable=True), + sa.Column("aridr", sa.VARCHAR(length=22), autoincrement=False, nullable=True), + sa.Column( + "linearid", sa.VARCHAR(length=22), autoincrement=False, nullable=True + ), + sa.Column( + "fullname", sa.VARCHAR(length=100), autoincrement=False, nullable=True + ), + sa.Column("lfromhn", sa.VARCHAR(length=12), autoincrement=False, nullable=True), + sa.Column("ltohn", sa.VARCHAR(length=12), autoincrement=False, nullable=True), + sa.Column("rfromhn", sa.VARCHAR(length=12), autoincrement=False, nullable=True), + sa.Column("rtohn", sa.VARCHAR(length=12), autoincrement=False, nullable=True), + sa.Column("zipl", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column("zipr", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column( + "edge_mtfcc", sa.VARCHAR(length=5), autoincrement=False, nullable=True + ), + sa.Column("parityl", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column("parityr", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column("plus4l", sa.VARCHAR(length=4), autoincrement=False, nullable=True), + sa.Column("plus4r", sa.VARCHAR(length=4), autoincrement=False, nullable=True), + sa.Column("lfromtyp", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column("ltotyp", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column("rfromtyp", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column("rtotyp", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column("offsetl", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column("offsetr", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column( + "the_geom", + geoalchemy2.types.Geometry( + from_text="ST_GeomFromEWKT", + name="geometry", + _spatial_index_reflected=True, + ), + autoincrement=False, + nullable=True, + ), + sa.CheckConstraint( + "geometrytype(the_geom) = 'LINESTRING'::text OR the_geom IS NULL", + name=op.f("enforce_geotype_the_geom"), + ), + sa.CheckConstraint( + "st_ndims(the_geom) = 2", name=op.f("enforce_dims_the_geom") + ), + sa.CheckConstraint( + "st_srid(the_geom) = 4269", name=op.f("enforce_srid_the_geom") + ), + sa.PrimaryKeyConstraint("gid", name=op.f("addrfeat_pkey")), + ) + op.create_index(op.f("idx_addrfeat_zipr"), "addrfeat", ["zipr"], unique=False) + op.create_index(op.f("idx_addrfeat_zipl"), "addrfeat", ["zipl"], unique=False) + op.create_index(op.f("idx_addrfeat_tlid"), "addrfeat", ["tlid"], unique=False) + op.create_index( + op.f("idx_addrfeat_geom_gist"), + "addrfeat", + ["the_geom"], + unique=False, + postgresql_using="gist", + ) + op.create_table( + "state", + sa.Column("gid", sa.INTEGER(), autoincrement=True, nullable=False), + sa.Column("region", sa.VARCHAR(length=2), autoincrement=False, nullable=True), + sa.Column("division", sa.VARCHAR(length=2), autoincrement=False, nullable=True), + sa.Column("statefp", sa.VARCHAR(length=2), autoincrement=False, nullable=False), + sa.Column("statens", sa.VARCHAR(length=8), autoincrement=False, nullable=True), + sa.Column("stusps", sa.VARCHAR(length=2), autoincrement=False, nullable=False), + sa.Column("name", sa.VARCHAR(length=100), autoincrement=False, nullable=True), + sa.Column("lsad", sa.VARCHAR(length=2), autoincrement=False, nullable=True), + sa.Column("mtfcc", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column("funcstat", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column("aland", sa.BIGINT(), autoincrement=False, nullable=True), + sa.Column("awater", sa.BIGINT(), autoincrement=False, nullable=True), + sa.Column( + "intptlat", sa.VARCHAR(length=11), autoincrement=False, nullable=True + ), + sa.Column( + "intptlon", sa.VARCHAR(length=12), autoincrement=False, nullable=True + ), + sa.Column( + "the_geom", + geoalchemy2.types.Geometry( + from_text="ST_GeomFromEWKT", + name="geometry", + _spatial_index_reflected=True, + ), + autoincrement=False, + nullable=True, + ), + sa.CheckConstraint( + "geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL", + name=op.f("enforce_geotype_the_geom"), + ), + sa.CheckConstraint( + "st_ndims(the_geom) = 2", name=op.f("enforce_dims_the_geom") + ), + sa.CheckConstraint( + "st_srid(the_geom) = 4269", name=op.f("enforce_srid_the_geom") + ), + sa.PrimaryKeyConstraint("statefp", name=op.f("pk_tiger_state")), + sa.UniqueConstraint( + "gid", + name=op.f("uidx_tiger_state_gid"), + postgresql_include=[], + postgresql_nulls_not_distinct=False, + ), + sa.UniqueConstraint( + "stusps", + name=op.f("uidx_tiger_state_stusps"), + postgresql_include=[], + postgresql_nulls_not_distinct=False, + ), + ) + op.create_index( + op.f("idx_tiger_state_the_geom_gist"), + "state", + ["the_geom"], + unique=False, + postgresql_using="gist", + ) + op.create_table( + "secondary_unit_lookup", + sa.Column("name", sa.VARCHAR(length=20), autoincrement=False, nullable=False), + sa.Column("abbrev", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.PrimaryKeyConstraint("name", name=op.f("secondary_unit_lookup_pkey")), + ) + op.create_index( + op.f("secondary_unit_lookup_abbrev_idx"), + "secondary_unit_lookup", + ["abbrev"], + unique=False, + ) + op.create_table( + "zip_state", + sa.Column("zip", sa.VARCHAR(length=5), autoincrement=False, nullable=False), + sa.Column("stusps", sa.VARCHAR(length=2), autoincrement=False, nullable=False), + sa.Column("statefp", sa.VARCHAR(length=2), autoincrement=False, nullable=True), + sa.PrimaryKeyConstraint("zip", "stusps", name=op.f("zip_state_pkey")), + ) + op.create_table( + "place_lookup", + sa.Column("st_code", sa.INTEGER(), autoincrement=False, nullable=False), + sa.Column("state", sa.VARCHAR(length=2), autoincrement=False, nullable=True), + sa.Column("pl_code", sa.INTEGER(), autoincrement=False, nullable=False), + sa.Column("name", sa.VARCHAR(length=90), autoincrement=False, nullable=True), + sa.PrimaryKeyConstraint("st_code", "pl_code", name=op.f("place_lookup_pkey")), + ) + op.create_index( + op.f("place_lookup_state_idx"), "place_lookup", ["state"], unique=False + ) + op.create_index( + op.f("place_lookup_name_idx"), + "place_lookup", + [sa.literal_column("soundex(name::text)")], + unique=False, + ) + op.create_table( + "state_lookup", + sa.Column("st_code", sa.INTEGER(), autoincrement=False, nullable=False), + sa.Column("name", sa.VARCHAR(length=40), autoincrement=False, nullable=True), + sa.Column("abbrev", sa.VARCHAR(length=3), autoincrement=False, nullable=True), + sa.Column("statefp", sa.CHAR(length=2), autoincrement=False, nullable=True), + sa.PrimaryKeyConstraint("st_code", name=op.f("state_lookup_pkey")), + sa.UniqueConstraint( + "abbrev", + name=op.f("state_lookup_abbrev_key"), + postgresql_include=[], + postgresql_nulls_not_distinct=False, + ), + sa.UniqueConstraint( + "name", + name=op.f("state_lookup_name_key"), + postgresql_include=[], + postgresql_nulls_not_distinct=False, + ), + sa.UniqueConstraint( + "statefp", + name=op.f("state_lookup_statefp_key"), + postgresql_include=[], + postgresql_nulls_not_distinct=False, + ), + ) + op.create_table( + "featnames", + sa.Column("gid", sa.INTEGER(), autoincrement=True, nullable=False), + sa.Column("tlid", sa.BIGINT(), autoincrement=False, nullable=True), + sa.Column( + "fullname", sa.VARCHAR(length=100), autoincrement=False, nullable=True + ), + sa.Column("name", sa.VARCHAR(length=100), autoincrement=False, nullable=True), + sa.Column( + "predirabrv", sa.VARCHAR(length=15), autoincrement=False, nullable=True + ), + sa.Column( + "pretypabrv", sa.VARCHAR(length=50), autoincrement=False, nullable=True + ), + sa.Column( + "prequalabr", sa.VARCHAR(length=15), autoincrement=False, nullable=True + ), + sa.Column( + "sufdirabrv", sa.VARCHAR(length=15), autoincrement=False, nullable=True + ), + sa.Column( + "suftypabrv", sa.VARCHAR(length=50), autoincrement=False, nullable=True + ), + sa.Column( + "sufqualabr", sa.VARCHAR(length=15), autoincrement=False, nullable=True + ), + sa.Column("predir", sa.VARCHAR(length=2), autoincrement=False, nullable=True), + sa.Column("pretyp", sa.VARCHAR(length=3), autoincrement=False, nullable=True), + sa.Column("prequal", sa.VARCHAR(length=2), autoincrement=False, nullable=True), + sa.Column("sufdir", sa.VARCHAR(length=2), autoincrement=False, nullable=True), + sa.Column("suftyp", sa.VARCHAR(length=3), autoincrement=False, nullable=True), + sa.Column("sufqual", sa.VARCHAR(length=2), autoincrement=False, nullable=True), + sa.Column( + "linearid", sa.VARCHAR(length=22), autoincrement=False, nullable=True + ), + sa.Column("mtfcc", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column("paflag", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column("statefp", sa.VARCHAR(length=2), autoincrement=False, nullable=True), + sa.PrimaryKeyConstraint("gid", name=op.f("featnames_pkey")), + ) + op.create_index( + op.f("idx_tiger_featnames_tlid_statefp"), + "featnames", + ["tlid", "statefp"], + unique=False, + ) + op.create_index( + op.f("idx_tiger_featnames_snd_name"), + "featnames", + [sa.literal_column("soundex(name::text)")], + unique=False, + ) + op.create_index( + op.f("idx_tiger_featnames_lname"), + "featnames", + [sa.literal_column("lower(name::text)")], + unique=False, + ) + op.create_table( + "county", + sa.Column("gid", sa.INTEGER(), autoincrement=True, nullable=False), + sa.Column("statefp", sa.VARCHAR(length=2), autoincrement=False, nullable=True), + sa.Column("countyfp", sa.VARCHAR(length=3), autoincrement=False, nullable=True), + sa.Column("countyns", sa.VARCHAR(length=8), autoincrement=False, nullable=True), + sa.Column( + "cntyidfp", sa.VARCHAR(length=5), autoincrement=False, nullable=False + ), + sa.Column("name", sa.VARCHAR(length=100), autoincrement=False, nullable=True), + sa.Column( + "namelsad", sa.VARCHAR(length=100), autoincrement=False, nullable=True + ), + sa.Column("lsad", sa.VARCHAR(length=2), autoincrement=False, nullable=True), + sa.Column("classfp", sa.VARCHAR(length=2), autoincrement=False, nullable=True), + sa.Column("mtfcc", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column("csafp", sa.VARCHAR(length=3), autoincrement=False, nullable=True), + sa.Column("cbsafp", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column("metdivfp", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column("funcstat", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column("aland", sa.BIGINT(), autoincrement=False, nullable=True), + sa.Column( + "awater", + sa.DOUBLE_PRECISION(precision=53), + autoincrement=False, + nullable=True, + ), + sa.Column( + "intptlat", sa.VARCHAR(length=11), autoincrement=False, nullable=True + ), + sa.Column( + "intptlon", sa.VARCHAR(length=12), autoincrement=False, nullable=True + ), + sa.Column( + "the_geom", + geoalchemy2.types.Geometry( + spatial_index=False, + from_text="ST_GeomFromEWKT", + name="geometry", + _spatial_index_reflected=True, + ), + autoincrement=False, + nullable=True, + ), + sa.CheckConstraint( + "geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL", + name=op.f("enforce_geotype_geom"), + ), + sa.CheckConstraint("st_ndims(the_geom) = 2", name=op.f("enforce_dims_geom")), + sa.CheckConstraint("st_srid(the_geom) = 4269", name=op.f("enforce_srid_geom")), + sa.PrimaryKeyConstraint("cntyidfp", name=op.f("pk_tiger_county")), + sa.UniqueConstraint( + "gid", + name=op.f("uidx_county_gid"), + postgresql_include=[], + postgresql_nulls_not_distinct=False, + ), + ) + op.create_index(op.f("idx_tiger_county"), "county", ["countyfp"], unique=False) + op.create_table( + "addr", + sa.Column("gid", sa.INTEGER(), autoincrement=True, nullable=False), + sa.Column("tlid", sa.BIGINT(), autoincrement=False, nullable=True), + sa.Column("fromhn", sa.VARCHAR(length=12), autoincrement=False, nullable=True), + sa.Column("tohn", sa.VARCHAR(length=12), autoincrement=False, nullable=True), + sa.Column("side", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column("zip", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column("plus4", sa.VARCHAR(length=4), autoincrement=False, nullable=True), + sa.Column("fromtyp", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column("totyp", sa.VARCHAR(length=1), autoincrement=False, nullable=True), + sa.Column("fromarmid", sa.INTEGER(), autoincrement=False, nullable=True), + sa.Column("toarmid", sa.INTEGER(), autoincrement=False, nullable=True), + sa.Column("arid", sa.VARCHAR(length=22), autoincrement=False, nullable=True), + sa.Column("mtfcc", sa.VARCHAR(length=5), autoincrement=False, nullable=True), + sa.Column("statefp", sa.VARCHAR(length=2), autoincrement=False, nullable=True), + sa.PrimaryKeyConstraint("gid", name=op.f("addr_pkey")), + ) + op.create_index(op.f("idx_tiger_addr_zip"), "addr", ["zip"], unique=False) + op.create_index( + op.f("idx_tiger_addr_tlid_statefp"), "addr", ["tlid", "statefp"], unique=False + ) + op.create_table( + "loader_lookuptables", + sa.Column( + "process_order", + sa.INTEGER(), + server_default=sa.text("1000"), + autoincrement=False, + nullable=False, + ), + sa.Column( + "lookup_name", + sa.TEXT(), + autoincrement=False, + nullable=False, + comment="This is the table name to inherit from and suffix of resulting output table -- how the table will be named -- edges here would mean -- ma_edges , pa_edges etc. except in the case of national tables. national level tables have no prefix", + ), + sa.Column( + "table_name", + sa.TEXT(), + autoincrement=False, + nullable=True, + comment="suffix of the tables to load e.g. edges would load all tables like *edges.dbf(shp) -- so tl_2010_42129_edges.dbf . ", + ), + sa.Column( + "single_mode", + sa.BOOLEAN(), + server_default=sa.text("true"), + autoincrement=False, + nullable=False, + ), + sa.Column( + "load", + sa.BOOLEAN(), + server_default=sa.text("true"), + autoincrement=False, + nullable=False, + comment="Whether or not to load the table. For states and zcta5 (you may just want to download states10, zcta510 nationwide file manually) load your own into a single table that inherits from tiger.states, tiger.zcta5. You'll get improved performance for some geocoding cases.", + ), + sa.Column( + "level_county", + sa.BOOLEAN(), + server_default=sa.text("false"), + autoincrement=False, + nullable=False, + ), + sa.Column( + "level_state", + sa.BOOLEAN(), + server_default=sa.text("false"), + autoincrement=False, + nullable=False, + ), + sa.Column( + "level_nation", + sa.BOOLEAN(), + server_default=sa.text("false"), + autoincrement=False, + nullable=False, + comment="These are tables that contain all data for the whole US so there is just a single file", + ), + sa.Column("post_load_process", sa.TEXT(), autoincrement=False, nullable=True), + sa.Column( + "single_geom_mode", + sa.BOOLEAN(), + server_default=sa.text("false"), + autoincrement=False, + nullable=True, + ), + sa.Column( + "insert_mode", + sa.CHAR(length=1), + server_default=sa.text("'c'::bpchar"), + autoincrement=False, + nullable=False, + ), + sa.Column("pre_load_process", sa.TEXT(), autoincrement=False, nullable=True), + sa.Column( + "columns_exclude", + postgresql.ARRAY(sa.TEXT()), + autoincrement=False, + nullable=True, + comment="List of columns to exclude as an array. This is excluded from both input table and output table and rest of columns remaining are assumed to be in same order in both tables. gid, geoid,cpi,suffix1ce are excluded if no columns are specified.", + ), + sa.Column( + "website_root_override", + sa.TEXT(), + autoincrement=False, + nullable=True, + comment="Path to use for wget instead of that specified in year table. Needed currently for zcta where they release that only for 2000 and 2010", + ), + sa.PrimaryKeyConstraint("lookup_name", name=op.f("loader_lookuptables_pkey")), + ) + op.drop_table("well_screen") + op.drop_table("groundwater_level_series") + op.drop_table("geothermal_series") + op.drop_table("geochemical_series") + op.drop_table("collaborative_network_well") + op.drop_table("well_thing") + op.drop_table("thing_id_link") + op.drop_table("thing_contact_association") + op.drop_table("spring_thing") + op.drop_table("series") + op.drop_table("pub_author_publication_association") + op.drop_table("pub_author_contact_association") + op.drop_index("ix_phone_search_vector", table_name="phone", postgresql_using="gin") + op.drop_table("phone") + op.drop_table("location_thing_association") + op.drop_index("ix_email_search_vector", table_name="email", postgresql_using="gin") + op.drop_table("email") + op.drop_table("asset_thing_association") + op.drop_table("address") + op.drop_table("thing") + op.drop_index( + "ix_publication_search_vector", table_name="publication", postgresql_using="gin" + ) + op.drop_table("publication") + op.drop_index("idx_location_point", table_name="location", postgresql_using="gist") + op.drop_table("location") + op.drop_table("lexicon_triple") + op.drop_table("lexicon_term_category_association") + op.drop_table("groundwater_level_sensor") + op.drop_table("geochronology_age") + op.drop_index( + "ix_contact_search_vector", table_name="contact", postgresql_using="gin" + ) + op.drop_table("contact") + op.drop_table("user") + op.drop_table("sensor") + op.drop_index( + "ix_pub_author_search_vector", table_name="pub_author", postgresql_using="gin" + ) + op.drop_table("pub_author") + op.drop_table("lexicon_term") + op.drop_table("lexicon_category") + op.drop_index("ix_asset_search_vector", table_name="asset", postgresql_using="gin") + op.drop_table("asset") + # ### end Alembic commands ### From fb57626c91841329daf319adfc4bdadefe752d3d Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Tue, 22 Jul 2025 10:45:02 -0600 Subject: [PATCH 19/38] fix: drop idx_location_point index if exists before migration This spatial index is automatically created by PostGIS when the `point` column is created, and it can cause issues with the migration if it already exists. This change ensures that the index is dropped before the migration runs, preventing potential conflicts. --- alembic/versions/d3cadc559792_initial_migration.py | 1 + 1 file changed, 1 insertion(+) diff --git a/alembic/versions/d3cadc559792_initial_migration.py b/alembic/versions/d3cadc559792_initial_migration.py index 33dcab70c..8a29070e2 100644 --- a/alembic/versions/d3cadc559792_initial_migration.py +++ b/alembic/versions/d3cadc559792_initial_migration.py @@ -225,6 +225,7 @@ def upgrade() -> None: ), sa.PrimaryKeyConstraint("id"), ) + op.execute("DROP INDEX IF EXISTS idx_location_point;") op.create_index( "idx_location_point", "location", From 11d42cbd1bf3aef7de8abd200ff69156922143c8 Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Tue, 22 Jul 2025 11:13:05 -0600 Subject: [PATCH 20/38] fix: make initial migration script compatible with PostGIS --- alembic/env.py | 52 +- .../d3cadc559792_initial_migration.py | 2078 ----------------- .../fb089dbbfc43_initial_migration.py | 627 +++++ 3 files changed, 677 insertions(+), 2080 deletions(-) delete mode 100644 alembic/versions/d3cadc559792_initial_migration.py create mode 100644 alembic/versions/fb089dbbfc43_initial_migration.py diff --git a/alembic/env.py b/alembic/env.py index 95ec16f5e..d108967dd 100644 --- a/alembic/env.py +++ b/alembic/env.py @@ -42,6 +42,54 @@ config.set_main_option("sqlalchemy.url", SQLALCHEMY_DATABASE_URL) +def include_object(object, name, type_, reflected, compare_to): + # List of tables to exclude from Alembic autogenerate + # these tables are created by PostGIS and TIGER geocoder + # and should not be included in migration upgrades or downgrades + excluded_tables = { + "loader_lookuptables", + "addr", + "county", + "featnames", + "state_lookup", + "place_lookup", + "zip_state", + "secondary_unit_lookup", + "state", + "addrfeat", + "direction_lookup", + "faces", + "bg", + "zip_lookup_all", + "cousub", + "pagc_rules", + "zcta5", + "zip_lookup", + "county_lookup", + "edges", + "tabblock20", + "loader_variables", + "pagc_gaz", + "street_type_lookup", + "geocode_settings_default", + "geocode_settings", + "zip_state_loc", + "tract", + "tabblock", + "spatial_ref_sys", + "topology", + "pagc_lex", + "loader_platform", + "zip_lookup_base", + "place", + "countysub_lookup", + "layer", + } + if type_ == "table" and name in excluded_tables: + return False + return True + + def run_migrations_offline() -> None: """Run migrations in 'offline' mode.""" url = config.get_main_option("sqlalchemy.url") @@ -50,7 +98,7 @@ def run_migrations_offline() -> None: target_metadata=target_metadata, literal_binds=True, dialect_opts={"paramstyle": "named"}, - # include_object=include_object, + include_object=include_object, ) with context.begin_transaction(): @@ -74,7 +122,7 @@ def run_migrations_online() -> None: context.configure( connection=connection, target_metadata=target_metadata, - # include_object=include_object, + include_object=include_object, ) with context.begin_transaction(): context.run_migrations() diff --git a/alembic/versions/d3cadc559792_initial_migration.py b/alembic/versions/d3cadc559792_initial_migration.py deleted file mode 100644 index 8a29070e2..000000000 --- a/alembic/versions/d3cadc559792_initial_migration.py +++ /dev/null @@ -1,2078 +0,0 @@ -"""Initial migration - -Revision ID: d3cadc559792 -Revises: -Create Date: 2025-07-22 10:41:01.015074 - -""" - -from typing import Sequence, Union - -from alembic import op -import geoalchemy2 -import sqlalchemy as sa -import sqlalchemy_utils -from sqlalchemy.dialects import postgresql - -# revision identifiers, used by Alembic. -revision: str = "d3cadc559792" -down_revision: Union[str, Sequence[str], None] = None -branch_labels: Union[str, Sequence[str], None] = None -depends_on: Union[str, Sequence[str], None] = None - - -def upgrade() -> None: - """Upgrade schema.""" - # ### commands auto generated by Alembic - please adjust! ### - op.create_table( - "asset", - sa.Column("filename", sa.String(), nullable=True), - sa.Column("storage_service", sa.String(), nullable=True), - sa.Column("storage_path", sa.String(), nullable=True), - sa.Column("mime_type", sa.String(), nullable=True), - sa.Column("size", sa.Integer(), nullable=True), - sa.Column( - "search_vector", - sqlalchemy_utils.types.ts_vector.TSVectorType(), - nullable=True, - ), - sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), - sa.Column( - "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False - ), - sa.PrimaryKeyConstraint("id"), - ) - op.create_index( - "ix_asset_search_vector", - "asset", - ["search_vector"], - unique=False, - postgresql_using="gin", - ) - op.create_table( - "lexicon_category", - sa.Column("name", sa.String(length=100), nullable=False), - sa.Column("description", sa.String(length=255), nullable=True), - sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), - sa.Column( - "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False - ), - sa.PrimaryKeyConstraint("id"), - sa.UniqueConstraint("name"), - ) - op.create_table( - "lexicon_term", - sa.Column("term", sa.String(length=100), nullable=False), - sa.Column("definition", sa.String(length=255), nullable=False), - sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), - sa.Column( - "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False - ), - sa.PrimaryKeyConstraint("id"), - sa.UniqueConstraint("term"), - ) - op.create_table( - "pub_author", - sa.Column("name", sa.String(), nullable=False), - sa.Column("affiliation", sa.String(), nullable=True), - sa.Column( - "search_vector", - sqlalchemy_utils.types.ts_vector.TSVectorType(), - nullable=True, - ), - sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), - sa.Column( - "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False - ), - sa.PrimaryKeyConstraint("id"), - ) - op.create_index( - "ix_pub_author_search_vector", - "pub_author", - ["search_vector"], - unique=False, - postgresql_using="gin", - ) - op.create_table( - "sensor", - sa.Column("name", sa.String(length=255), nullable=False), - sa.Column("model", sa.String(length=50), nullable=True), - sa.Column("serial_no", sa.String(length=50), nullable=True), - sa.Column("date_installed", sa.DateTime(), nullable=True), - sa.Column("date_removed", sa.DateTime(), nullable=True), - sa.Column("recording_interval", sa.Integer(), nullable=True), - sa.Column("notes", sa.String(length=50), nullable=True), - sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), - sa.Column( - "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False - ), - sa.PrimaryKeyConstraint("id"), - ) - op.create_table( - "user", - sa.Column("id", sa.Integer(), nullable=False), - sa.Column("username", sa.String(length=255), nullable=False), - sa.Column("password", sa.String(length=255), nullable=False), - sa.Column("is_superuser", sa.Boolean(), nullable=False), - sa.Column("is_active", sa.Boolean(), nullable=False), - sa.Column("avatar_url", sa.Text(), nullable=True), - sa.PrimaryKeyConstraint("id"), - ) - op.create_table( - "contact", - sa.Column("name", sa.String(length=100), nullable=False), - sa.Column("role", sa.String(length=100), nullable=False), - sa.Column( - "search_vector", - sqlalchemy_utils.types.ts_vector.TSVectorType(), - nullable=True, - ), - sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), - sa.Column( - "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False - ), - sa.ForeignKeyConstraint( - ["role"], - ["lexicon_term.term"], - ), - sa.PrimaryKeyConstraint("id"), - ) - op.create_index( - "ix_contact_search_vector", - "contact", - ["search_vector"], - unique=False, - postgresql_using="gin", - ) - op.create_table( - "geochronology_age", - sa.Column("location_id", sa.Integer(), nullable=False), - sa.Column("age", sa.Float(), nullable=False), - sa.Column("age_error", sa.Float(), nullable=True), - sa.Column("method", sa.String(length=100), nullable=True), - sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), - sa.Column( - "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False - ), - sa.ForeignKeyConstraint( - ["method"], - ["lexicon_term.term"], - ), - sa.PrimaryKeyConstraint("id"), - ) - op.create_table( - "groundwater_level_sensor", - sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), - sa.Column( - "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False - ), - sa.Column("sensor_id", sa.Integer(), nullable=False), - sa.ForeignKeyConstraint(["sensor_id"], ["sensor.id"], ondelete="CASCADE"), - sa.PrimaryKeyConstraint("id"), - sa.UniqueConstraint("sensor_id"), - ) - op.create_table( - "lexicon_term_category_association", - sa.Column("lexicon_term", sa.String(length=100), nullable=False), - sa.Column("category_name", sa.String(length=255), nullable=False), - sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), - sa.Column( - "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False - ), - sa.ForeignKeyConstraint( - ["category_name"], ["lexicon_category.name"], ondelete="CASCADE" - ), - sa.ForeignKeyConstraint( - ["lexicon_term"], ["lexicon_term.term"], ondelete="CASCADE" - ), - sa.PrimaryKeyConstraint("id"), - ) - op.create_table( - "lexicon_triple", - sa.Column("subject", sa.String(length=100), nullable=False), - sa.Column("predicate", sa.String(length=100), nullable=False), - sa.Column("object_", sa.String(length=100), nullable=False), - sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), - sa.Column( - "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False - ), - sa.ForeignKeyConstraint(["object_"], ["lexicon_term.term"], ondelete="CASCADE"), - sa.ForeignKeyConstraint(["subject"], ["lexicon_term.term"], ondelete="CASCADE"), - sa.PrimaryKeyConstraint("id"), - ) - op.create_table( - "location", - sa.Column("notes", sa.Text(), nullable=True), - sa.Column( - "point", - geoalchemy2.types.Geometry( - geometry_type="POINT", - srid=4326, - from_text="ST_GeomFromEWKT", - name="geometry", - nullable=False, - ), - nullable=False, - ), - sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), - sa.Column( - "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False - ), - sa.Column("release_status", sa.String(length=100), nullable=True), - sa.ForeignKeyConstraint( - ["release_status"], - ["lexicon_term.term"], - ), - sa.PrimaryKeyConstraint("id"), - ) - op.execute("DROP INDEX IF EXISTS idx_location_point;") - op.create_index( - "idx_location_point", - "location", - ["point"], - unique=False, - postgresql_using="gist", - ) - op.create_table( - "publication", - sa.Column("title", sa.Text(), nullable=False), - sa.Column("abstract", sa.Text(), nullable=True), - sa.Column("doi", sa.String(), nullable=True), - sa.Column("year", sa.Integer(), nullable=True), - sa.Column("publisher", sa.String(), nullable=True), - sa.Column("url", sa.String(), nullable=True), - sa.Column("publication_type", sa.String(length=100), nullable=False), - sa.Column( - "search_vector", - sqlalchemy_utils.types.ts_vector.TSVectorType(), - nullable=True, - ), - sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), - sa.Column( - "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False - ), - sa.ForeignKeyConstraint( - ["publication_type"], - ["lexicon_term.term"], - ), - sa.PrimaryKeyConstraint("id"), - sa.UniqueConstraint("doi"), - ) - op.create_index( - "ix_publication_search_vector", - "publication", - ["search_vector"], - unique=False, - postgresql_using="gin", - ) - op.create_table( - "thing", - sa.Column("name", sa.String(length=255), nullable=False), - sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), - sa.Column( - "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False - ), - sa.Column("release_status", sa.String(length=100), nullable=True), - sa.ForeignKeyConstraint( - ["release_status"], - ["lexicon_term.term"], - ), - sa.PrimaryKeyConstraint("id"), - ) - op.create_table( - "address", - sa.Column("contact_id", sa.Integer(), nullable=False), - sa.Column("address_line_1", sa.String(length=255), nullable=False), - sa.Column("address_line_2", sa.String(length=255), nullable=True), - sa.Column("city", sa.String(length=100), nullable=False), - sa.Column("state", sa.String(length=50), nullable=False), - sa.Column("postal_code", sa.String(length=20), nullable=False), - sa.Column("country", sa.String(length=100), nullable=True), - sa.Column("address_type", sa.String(length=100), nullable=True), - sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), - sa.Column( - "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False - ), - sa.ForeignKeyConstraint( - ["address_type"], - ["lexicon_term.term"], - ), - sa.ForeignKeyConstraint(["contact_id"], ["contact.id"], ondelete="CASCADE"), - sa.PrimaryKeyConstraint("id"), - ) - op.create_table( - "asset_thing_association", - sa.Column("asset_id", sa.Integer(), nullable=False), - sa.Column("thing_id", sa.Integer(), nullable=False), - sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), - sa.Column( - "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False - ), - sa.ForeignKeyConstraint(["asset_id"], ["asset.id"], ondelete="CASCADE"), - sa.ForeignKeyConstraint(["thing_id"], ["thing.id"], ondelete="CASCADE"), - sa.PrimaryKeyConstraint("id"), - ) - op.create_table( - "email", - sa.Column("contact_id", sa.Integer(), nullable=False), - sa.Column("email", sa.String(length=100), nullable=False), - sa.Column("email_type", sa.String(length=100), nullable=True), - sa.Column( - "search_vector", - sqlalchemy_utils.types.ts_vector.TSVectorType(), - nullable=True, - ), - sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), - sa.Column( - "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False - ), - sa.ForeignKeyConstraint(["contact_id"], ["contact.id"], ondelete="CASCADE"), - sa.ForeignKeyConstraint( - ["email_type"], - ["lexicon_term.term"], - ), - sa.PrimaryKeyConstraint("id"), - ) - op.create_index( - "ix_email_search_vector", - "email", - ["search_vector"], - unique=False, - postgresql_using="gin", - ) - op.create_table( - "location_thing_association", - sa.Column("location_id", sa.Integer(), nullable=False), - sa.Column("thing_id", sa.Integer(), nullable=False), - sa.Column( - "effective_start", - sa.DateTime(), - server_default=sa.text("now()"), - nullable=False, - ), - sa.Column("effective_end", sa.DateTime(), nullable=True), - sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), - sa.Column( - "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False - ), - sa.ForeignKeyConstraint(["location_id"], ["location.id"], ondelete="CASCADE"), - sa.ForeignKeyConstraint(["thing_id"], ["thing.id"], ondelete="CASCADE"), - sa.PrimaryKeyConstraint("location_id", "thing_id", "id"), - ) - op.create_table( - "phone", - sa.Column("contact_id", sa.Integer(), nullable=False), - sa.Column("phone_number", sa.String(length=20), nullable=False), - sa.Column("phone_type", sa.String(length=100), nullable=True), - sa.Column( - "search_vector", - sqlalchemy_utils.types.ts_vector.TSVectorType(), - nullable=True, - ), - sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), - sa.Column( - "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False - ), - sa.ForeignKeyConstraint(["contact_id"], ["contact.id"], ondelete="CASCADE"), - sa.ForeignKeyConstraint( - ["phone_type"], - ["lexicon_term.term"], - ), - sa.PrimaryKeyConstraint("id"), - ) - op.create_index( - "ix_phone_search_vector", - "phone", - ["search_vector"], - unique=False, - postgresql_using="gin", - ) - op.create_table( - "pub_author_contact_association", - sa.Column("author_id", sa.Integer(), nullable=False), - sa.Column("contact_id", sa.Integer(), nullable=False), - sa.Column( - "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False - ), - sa.ForeignKeyConstraint(["author_id"], ["pub_author.id"], ondelete="CASCADE"), - sa.ForeignKeyConstraint(["contact_id"], ["contact.id"], ondelete="CASCADE"), - sa.PrimaryKeyConstraint("author_id", "contact_id"), - ) - op.create_table( - "pub_author_publication_association", - sa.Column("publication_id", sa.Integer(), nullable=False), - sa.Column("author_id", sa.Integer(), nullable=False), - sa.Column("author_order", sa.Integer(), nullable=False), - sa.Column( - "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False - ), - sa.ForeignKeyConstraint(["author_id"], ["pub_author.id"], ondelete="CASCADE"), - sa.ForeignKeyConstraint( - ["publication_id"], ["publication.id"], ondelete="CASCADE" - ), - sa.PrimaryKeyConstraint("publication_id", "author_id"), - ) - op.create_table( - "series", - sa.Column("observed_property", sa.String(length=100), nullable=False), - sa.Column("unit", sa.String(length=100), nullable=False), - sa.Column("name", sa.String(length=255), nullable=False), - sa.Column("description", sa.Text(), nullable=True), - sa.Column("sensor_id", sa.Integer(), nullable=True), - sa.Column("thing_id", sa.Integer(), nullable=False), - sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), - sa.Column( - "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False - ), - sa.Column("release_status", sa.String(length=100), nullable=True), - sa.ForeignKeyConstraint( - ["observed_property"], - ["lexicon_term.term"], - ), - sa.ForeignKeyConstraint( - ["release_status"], - ["lexicon_term.term"], - ), - sa.ForeignKeyConstraint(["sensor_id"], ["sensor.id"], ondelete="CASCADE"), - sa.ForeignKeyConstraint(["thing_id"], ["thing.id"], ondelete="CASCADE"), - sa.ForeignKeyConstraint( - ["unit"], - ["lexicon_term.term"], - ), - sa.PrimaryKeyConstraint("id"), - ) - op.create_table( - "spring_thing", - sa.Column("description", sa.String(length=255), nullable=True), - sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), - sa.Column( - "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False - ), - sa.Column("thing_id", sa.Integer(), nullable=False), - sa.ForeignKeyConstraint(["thing_id"], ["thing.id"], ondelete="CASCADE"), - sa.PrimaryKeyConstraint("id"), - sa.UniqueConstraint("thing_id"), - ) - op.create_table( - "thing_contact_association", - sa.Column("thing_id", sa.Integer(), nullable=False), - sa.Column("contact_id", sa.Integer(), nullable=False), - sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), - sa.Column( - "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False - ), - sa.ForeignKeyConstraint( - ["contact_id"], - ["contact.id"], - ), - sa.ForeignKeyConstraint( - ["thing_id"], - ["thing.id"], - ), - sa.PrimaryKeyConstraint("id"), - ) - op.create_table( - "thing_id_link", - sa.Column("thing_id", sa.Integer(), nullable=True), - sa.Column("relation", sa.String(length=100), nullable=False), - sa.Column("alternate_id", sa.String(length=100), nullable=False), - sa.Column("alternate_organization", sa.String(length=100), nullable=False), - sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), - sa.Column( - "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False - ), - sa.ForeignKeyConstraint( - ["alternate_organization"], - ["lexicon_term.term"], - ), - sa.ForeignKeyConstraint( - ["relation"], - ["lexicon_term.term"], - ), - sa.ForeignKeyConstraint(["thing_id"], ["thing.id"], ondelete="CASCADE"), - sa.PrimaryKeyConstraint("id"), - ) - op.create_table( - "well_thing", - sa.Column("well_depth", sa.Float(), nullable=True), - sa.Column("hole_depth", sa.Float(), nullable=True), - sa.Column("well_type", sa.String(length=100), nullable=True), - sa.Column("casing_diameter", sa.Float(), nullable=True), - sa.Column("casing_depth", sa.Float(), nullable=True), - sa.Column("casing_description", sa.String(length=50), nullable=True), - sa.Column("construction_notes", sa.String(length=250), nullable=True), - sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), - sa.Column( - "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False - ), - sa.Column("thing_id", sa.Integer(), nullable=False), - sa.ForeignKeyConstraint(["thing_id"], ["thing.id"], ondelete="CASCADE"), - sa.ForeignKeyConstraint( - ["well_type"], - ["lexicon_term.term"], - ), - sa.PrimaryKeyConstraint("id"), - sa.UniqueConstraint("thing_id"), - ) - op.create_table( - "collaborative_network_well", - sa.Column("actively_monitored", sa.Boolean(), nullable=False), - sa.Column("well_id", sa.Integer(), nullable=False), - sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), - sa.Column( - "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False - ), - sa.ForeignKeyConstraint(["well_id"], ["well_thing.id"], ondelete="CASCADE"), - sa.PrimaryKeyConstraint("id"), - ) - op.create_table( - "geochemical_series", - sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), - sa.Column( - "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False - ), - sa.Column("series_id", sa.Integer(), nullable=False), - sa.ForeignKeyConstraint(["series_id"], ["series.id"], ondelete="CASCADE"), - sa.PrimaryKeyConstraint("id"), - sa.UniqueConstraint("series_id"), - ) - op.create_table( - "geothermal_series", - sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), - sa.Column( - "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False - ), - sa.Column("series_id", sa.Integer(), nullable=False), - sa.ForeignKeyConstraint(["series_id"], ["series.id"], ondelete="CASCADE"), - sa.PrimaryKeyConstraint("id"), - sa.UniqueConstraint("series_id"), - ) - op.create_table( - "groundwater_level_series", - sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), - sa.Column( - "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False - ), - sa.Column("series_id", sa.Integer(), nullable=False), - sa.ForeignKeyConstraint(["series_id"], ["series.id"], ondelete="CASCADE"), - sa.PrimaryKeyConstraint("id"), - sa.UniqueConstraint("series_id"), - ) - op.create_table( - "well_screen", - sa.Column("well_id", sa.Integer(), nullable=False), - sa.Column("screen_depth_top", sa.Float(), nullable=False), - sa.Column("screen_depth_bottom", sa.Float(), nullable=False), - sa.Column("screen_type", sa.String(length=100), nullable=True), - sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), - sa.Column( - "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False - ), - sa.ForeignKeyConstraint( - ["screen_type"], - ["lexicon_term.term"], - ), - sa.ForeignKeyConstraint(["well_id"], ["well_thing.id"], ondelete="CASCADE"), - sa.PrimaryKeyConstraint("id"), - ) - op.drop_table("loader_lookuptables") - op.drop_index(op.f("idx_tiger_addr_tlid_statefp"), table_name="addr") - op.drop_index(op.f("idx_tiger_addr_zip"), table_name="addr") - op.drop_table("addr") - op.drop_index(op.f("idx_tiger_county"), table_name="county") - op.drop_table("county") - op.drop_index(op.f("idx_tiger_featnames_lname"), table_name="featnames") - op.drop_index(op.f("idx_tiger_featnames_snd_name"), table_name="featnames") - op.drop_index(op.f("idx_tiger_featnames_tlid_statefp"), table_name="featnames") - op.drop_table("featnames") - op.drop_table("state_lookup") - op.drop_index(op.f("place_lookup_name_idx"), table_name="place_lookup") - op.drop_index(op.f("place_lookup_state_idx"), table_name="place_lookup") - op.drop_table("place_lookup") - op.drop_table("zip_state") - op.drop_index( - op.f("secondary_unit_lookup_abbrev_idx"), table_name="secondary_unit_lookup" - ) - op.drop_table("secondary_unit_lookup") - op.drop_index( - op.f("idx_tiger_state_the_geom_gist"), - table_name="state", - postgresql_using="gist", - ) - op.drop_table("state") - op.drop_index( - op.f("idx_addrfeat_geom_gist"), table_name="addrfeat", postgresql_using="gist" - ) - op.drop_index(op.f("idx_addrfeat_tlid"), table_name="addrfeat") - op.drop_index(op.f("idx_addrfeat_zipl"), table_name="addrfeat") - op.drop_index(op.f("idx_addrfeat_zipr"), table_name="addrfeat") - op.drop_table("addrfeat") - op.drop_index(op.f("direction_lookup_abbrev_idx"), table_name="direction_lookup") - op.drop_table("direction_lookup") - op.drop_index(op.f("idx_tiger_faces_countyfp"), table_name="faces") - op.drop_index(op.f("idx_tiger_faces_tfid"), table_name="faces") - op.drop_index( - op.f("tiger_faces_the_geom_gist"), table_name="faces", postgresql_using="gist" - ) - op.drop_table("faces") - op.drop_table("bg") - op.drop_table("zip_lookup_all") - op.drop_index( - op.f("tige_cousub_the_geom_gist"), table_name="cousub", postgresql_using="gist" - ) - op.drop_table("cousub") - op.drop_table("pagc_rules") - op.drop_table("zcta5") - op.drop_table("zip_lookup") - op.drop_index(op.f("county_lookup_name_idx"), table_name="county_lookup") - op.drop_index(op.f("county_lookup_state_idx"), table_name="county_lookup") - op.drop_table("county_lookup") - op.drop_index(op.f("idx_edges_tlid"), table_name="edges") - op.drop_index(op.f("idx_tiger_edges_countyfp"), table_name="edges") - op.drop_index( - op.f("idx_tiger_edges_the_geom_gist"), - table_name="edges", - postgresql_using="gist", - ) - op.drop_table("edges") - op.drop_table("tabblock20") - op.drop_table("loader_variables") - op.drop_table("pagc_gaz") - op.drop_index( - op.f("street_type_lookup_abbrev_idx"), table_name="street_type_lookup" - ) - op.drop_table("street_type_lookup") - op.drop_table("geocode_settings_default") - op.drop_table("geocode_settings") - op.drop_table("zip_state_loc") - op.drop_table("tract") - op.drop_table("tabblock") - op.drop_table("spatial_ref_sys") - op.drop_table("topology") - op.drop_table("pagc_lex") - op.drop_table("loader_platform") - op.drop_table("zip_lookup_base") - op.drop_index( - op.f("tiger_place_the_geom_gist"), table_name="place", postgresql_using="gist" - ) - op.drop_table("place") - op.drop_index(op.f("countysub_lookup_name_idx"), table_name="countysub_lookup") - op.drop_index(op.f("countysub_lookup_state_idx"), table_name="countysub_lookup") - op.drop_table("countysub_lookup") - op.drop_table("layer") - # ### end Alembic commands ### - - -def downgrade() -> None: - """Downgrade schema.""" - # ### commands auto generated by Alembic - please adjust! ### - op.create_table( - "layer", - sa.Column("topology_id", sa.INTEGER(), autoincrement=False, nullable=False), - sa.Column("layer_id", sa.INTEGER(), autoincrement=False, nullable=False), - sa.Column("schema_name", sa.VARCHAR(), autoincrement=False, nullable=False), - sa.Column("table_name", sa.VARCHAR(), autoincrement=False, nullable=False), - sa.Column("feature_column", sa.VARCHAR(), autoincrement=False, nullable=False), - sa.Column("feature_type", sa.INTEGER(), autoincrement=False, nullable=False), - sa.Column( - "level", - sa.INTEGER(), - server_default=sa.text("0"), - autoincrement=False, - nullable=False, - ), - sa.Column("child_id", sa.INTEGER(), autoincrement=False, nullable=True), - sa.ForeignKeyConstraint( - ["topology_id"], ["topology.id"], name=op.f("layer_topology_id_fkey") - ), - sa.PrimaryKeyConstraint("topology_id", "layer_id", name=op.f("layer_pkey")), - sa.UniqueConstraint( - "schema_name", - "table_name", - "feature_column", - name=op.f("layer_schema_name_table_name_feature_column_key"), - postgresql_include=[], - postgresql_nulls_not_distinct=False, - ), - ) - op.create_table( - "countysub_lookup", - sa.Column("st_code", sa.INTEGER(), autoincrement=False, nullable=False), - sa.Column("state", sa.VARCHAR(length=2), autoincrement=False, nullable=True), - sa.Column("co_code", sa.INTEGER(), autoincrement=False, nullable=False), - sa.Column("county", sa.VARCHAR(length=90), autoincrement=False, nullable=True), - sa.Column("cs_code", sa.INTEGER(), autoincrement=False, nullable=False), - sa.Column("name", sa.VARCHAR(length=90), autoincrement=False, nullable=True), - sa.PrimaryKeyConstraint( - "st_code", "co_code", "cs_code", name=op.f("countysub_lookup_pkey") - ), - ) - op.create_index( - op.f("countysub_lookup_state_idx"), "countysub_lookup", ["state"], unique=False - ) - op.create_index( - op.f("countysub_lookup_name_idx"), - "countysub_lookup", - [sa.literal_column("soundex(name::text)")], - unique=False, - ) - op.create_table( - "place", - sa.Column("gid", sa.INTEGER(), autoincrement=True, nullable=False), - sa.Column("statefp", sa.VARCHAR(length=2), autoincrement=False, nullable=True), - sa.Column("placefp", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column("placens", sa.VARCHAR(length=8), autoincrement=False, nullable=True), - sa.Column("plcidfp", sa.VARCHAR(length=7), autoincrement=False, nullable=False), - sa.Column("name", sa.VARCHAR(length=100), autoincrement=False, nullable=True), - sa.Column( - "namelsad", sa.VARCHAR(length=100), autoincrement=False, nullable=True - ), - sa.Column("lsad", sa.VARCHAR(length=2), autoincrement=False, nullable=True), - sa.Column("classfp", sa.VARCHAR(length=2), autoincrement=False, nullable=True), - sa.Column("cpi", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column("pcicbsa", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column("pcinecta", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column("mtfcc", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column("funcstat", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column("aland", sa.BIGINT(), autoincrement=False, nullable=True), - sa.Column("awater", sa.BIGINT(), autoincrement=False, nullable=True), - sa.Column( - "intptlat", sa.VARCHAR(length=11), autoincrement=False, nullable=True - ), - sa.Column( - "intptlon", sa.VARCHAR(length=12), autoincrement=False, nullable=True - ), - sa.Column( - "the_geom", - geoalchemy2.types.Geometry( - from_text="ST_GeomFromEWKT", - name="geometry", - _spatial_index_reflected=True, - ), - autoincrement=False, - nullable=True, - ), - sa.CheckConstraint( - "geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL", - name=op.f("enforce_geotype_the_geom"), - ), - sa.CheckConstraint( - "st_ndims(the_geom) = 2", name=op.f("enforce_dims_the_geom") - ), - sa.CheckConstraint( - "st_srid(the_geom) = 4269", name=op.f("enforce_srid_the_geom") - ), - sa.PrimaryKeyConstraint("plcidfp", name=op.f("place_pkey")), - sa.UniqueConstraint( - "gid", - name=op.f("uidx_tiger_place_gid"), - postgresql_include=[], - postgresql_nulls_not_distinct=False, - ), - ) - op.create_index( - op.f("tiger_place_the_geom_gist"), - "place", - ["the_geom"], - unique=False, - postgresql_using="gist", - ) - op.create_table( - "zip_lookup_base", - sa.Column("zip", sa.VARCHAR(length=5), autoincrement=False, nullable=False), - sa.Column("state", sa.VARCHAR(length=40), autoincrement=False, nullable=True), - sa.Column("county", sa.VARCHAR(length=90), autoincrement=False, nullable=True), - sa.Column("city", sa.VARCHAR(length=90), autoincrement=False, nullable=True), - sa.Column("statefp", sa.VARCHAR(length=2), autoincrement=False, nullable=True), - sa.PrimaryKeyConstraint("zip", name=op.f("zip_lookup_base_pkey")), - ) - op.create_table( - "loader_platform", - sa.Column("os", sa.VARCHAR(length=50), autoincrement=False, nullable=False), - sa.Column("declare_sect", sa.TEXT(), autoincrement=False, nullable=True), - sa.Column("pgbin", sa.TEXT(), autoincrement=False, nullable=True), - sa.Column("wget", sa.TEXT(), autoincrement=False, nullable=True), - sa.Column("unzip_command", sa.TEXT(), autoincrement=False, nullable=True), - sa.Column("psql", sa.TEXT(), autoincrement=False, nullable=True), - sa.Column("path_sep", sa.TEXT(), autoincrement=False, nullable=True), - sa.Column("loader", sa.TEXT(), autoincrement=False, nullable=True), - sa.Column("environ_set_command", sa.TEXT(), autoincrement=False, nullable=True), - sa.Column( - "county_process_command", sa.TEXT(), autoincrement=False, nullable=True - ), - sa.PrimaryKeyConstraint("os", name=op.f("loader_platform_pkey")), - ) - op.create_table( - "pagc_lex", - sa.Column("id", sa.INTEGER(), autoincrement=True, nullable=False), - sa.Column("seq", sa.INTEGER(), autoincrement=False, nullable=True), - sa.Column("word", sa.TEXT(), autoincrement=False, nullable=True), - sa.Column("stdword", sa.TEXT(), autoincrement=False, nullable=True), - sa.Column("token", sa.INTEGER(), autoincrement=False, nullable=True), - sa.Column( - "is_custom", - sa.BOOLEAN(), - server_default=sa.text("true"), - autoincrement=False, - nullable=False, - ), - sa.PrimaryKeyConstraint("id", name=op.f("pagc_lex_pkey")), - ) - op.create_table( - "topology", - sa.Column("id", sa.INTEGER(), autoincrement=True, nullable=False), - sa.Column("name", sa.VARCHAR(), autoincrement=False, nullable=False), - sa.Column("srid", sa.INTEGER(), autoincrement=False, nullable=False), - sa.Column( - "precision", - sa.DOUBLE_PRECISION(precision=53), - autoincrement=False, - nullable=False, - ), - sa.Column( - "hasz", - sa.BOOLEAN(), - server_default=sa.text("false"), - autoincrement=False, - nullable=False, - ), - sa.PrimaryKeyConstraint("id", name=op.f("topology_pkey")), - sa.UniqueConstraint( - "name", - name=op.f("topology_name_key"), - postgresql_include=[], - postgresql_nulls_not_distinct=False, - ), - ) - op.create_table( - "spatial_ref_sys", - sa.Column("srid", sa.INTEGER(), autoincrement=False, nullable=False), - sa.Column( - "auth_name", sa.VARCHAR(length=256), autoincrement=False, nullable=True - ), - sa.Column("auth_srid", sa.INTEGER(), autoincrement=False, nullable=True), - sa.Column( - "srtext", sa.VARCHAR(length=2048), autoincrement=False, nullable=True - ), - sa.Column( - "proj4text", sa.VARCHAR(length=2048), autoincrement=False, nullable=True - ), - sa.CheckConstraint( - "srid > 0 AND srid <= 998999", name=op.f("spatial_ref_sys_srid_check") - ), - sa.PrimaryKeyConstraint("srid", name=op.f("spatial_ref_sys_pkey")), - ) - op.create_table( - "tabblock", - sa.Column("gid", sa.INTEGER(), autoincrement=True, nullable=False), - sa.Column("statefp", sa.VARCHAR(length=2), autoincrement=False, nullable=True), - sa.Column("countyfp", sa.VARCHAR(length=3), autoincrement=False, nullable=True), - sa.Column("tractce", sa.VARCHAR(length=6), autoincrement=False, nullable=True), - sa.Column("blockce", sa.VARCHAR(length=4), autoincrement=False, nullable=True), - sa.Column( - "tabblock_id", sa.VARCHAR(length=16), autoincrement=False, nullable=False - ), - sa.Column("name", sa.VARCHAR(length=20), autoincrement=False, nullable=True), - sa.Column("mtfcc", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column("ur", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column("uace", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column("funcstat", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column( - "aland", - sa.DOUBLE_PRECISION(precision=53), - autoincrement=False, - nullable=True, - ), - sa.Column( - "awater", - sa.DOUBLE_PRECISION(precision=53), - autoincrement=False, - nullable=True, - ), - sa.Column( - "intptlat", sa.VARCHAR(length=11), autoincrement=False, nullable=True - ), - sa.Column( - "intptlon", sa.VARCHAR(length=12), autoincrement=False, nullable=True - ), - sa.Column( - "the_geom", - geoalchemy2.types.Geometry( - spatial_index=False, - from_text="ST_GeomFromEWKT", - name="geometry", - _spatial_index_reflected=True, - ), - autoincrement=False, - nullable=True, - ), - sa.CheckConstraint( - "geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL", - name=op.f("enforce_geotype_geom"), - ), - sa.CheckConstraint("st_ndims(the_geom) = 2", name=op.f("enforce_dims_geom")), - sa.CheckConstraint("st_srid(the_geom) = 4269", name=op.f("enforce_srid_geom")), - sa.PrimaryKeyConstraint("tabblock_id", name=op.f("tabblock_pkey")), - ) - op.create_table( - "tract", - sa.Column("gid", sa.INTEGER(), autoincrement=True, nullable=False), - sa.Column("statefp", sa.VARCHAR(length=2), autoincrement=False, nullable=True), - sa.Column("countyfp", sa.VARCHAR(length=3), autoincrement=False, nullable=True), - sa.Column("tractce", sa.VARCHAR(length=6), autoincrement=False, nullable=True), - sa.Column( - "tract_id", sa.VARCHAR(length=11), autoincrement=False, nullable=False - ), - sa.Column("name", sa.VARCHAR(length=7), autoincrement=False, nullable=True), - sa.Column( - "namelsad", sa.VARCHAR(length=20), autoincrement=False, nullable=True - ), - sa.Column("mtfcc", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column("funcstat", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column( - "aland", - sa.DOUBLE_PRECISION(precision=53), - autoincrement=False, - nullable=True, - ), - sa.Column( - "awater", - sa.DOUBLE_PRECISION(precision=53), - autoincrement=False, - nullable=True, - ), - sa.Column( - "intptlat", sa.VARCHAR(length=11), autoincrement=False, nullable=True - ), - sa.Column( - "intptlon", sa.VARCHAR(length=12), autoincrement=False, nullable=True - ), - sa.Column( - "the_geom", - geoalchemy2.types.Geometry( - spatial_index=False, - from_text="ST_GeomFromEWKT", - name="geometry", - _spatial_index_reflected=True, - ), - autoincrement=False, - nullable=True, - ), - sa.CheckConstraint( - "geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL", - name=op.f("enforce_geotype_geom"), - ), - sa.CheckConstraint("st_ndims(the_geom) = 2", name=op.f("enforce_dims_geom")), - sa.CheckConstraint("st_srid(the_geom) = 4269", name=op.f("enforce_srid_geom")), - sa.PrimaryKeyConstraint("tract_id", name=op.f("tract_pkey")), - ) - op.create_table( - "zip_state_loc", - sa.Column("zip", sa.VARCHAR(length=5), autoincrement=False, nullable=False), - sa.Column("stusps", sa.VARCHAR(length=2), autoincrement=False, nullable=False), - sa.Column("statefp", sa.VARCHAR(length=2), autoincrement=False, nullable=True), - sa.Column("place", sa.VARCHAR(length=100), autoincrement=False, nullable=False), - sa.PrimaryKeyConstraint( - "zip", "stusps", "place", name=op.f("zip_state_loc_pkey") - ), - ) - op.create_table( - "geocode_settings", - sa.Column("name", sa.TEXT(), autoincrement=False, nullable=False), - sa.Column("setting", sa.TEXT(), autoincrement=False, nullable=True), - sa.Column("unit", sa.TEXT(), autoincrement=False, nullable=True), - sa.Column("category", sa.TEXT(), autoincrement=False, nullable=True), - sa.Column("short_desc", sa.TEXT(), autoincrement=False, nullable=True), - sa.PrimaryKeyConstraint("name", name=op.f("geocode_settings_pkey")), - ) - op.create_table( - "geocode_settings_default", - sa.Column("name", sa.TEXT(), autoincrement=False, nullable=False), - sa.Column("setting", sa.TEXT(), autoincrement=False, nullable=True), - sa.Column("unit", sa.TEXT(), autoincrement=False, nullable=True), - sa.Column("category", sa.TEXT(), autoincrement=False, nullable=True), - sa.Column("short_desc", sa.TEXT(), autoincrement=False, nullable=True), - sa.PrimaryKeyConstraint("name", name=op.f("geocode_settings_default_pkey")), - ) - op.create_table( - "street_type_lookup", - sa.Column("name", sa.VARCHAR(length=50), autoincrement=False, nullable=False), - sa.Column("abbrev", sa.VARCHAR(length=50), autoincrement=False, nullable=True), - sa.Column( - "is_hw", - sa.BOOLEAN(), - server_default=sa.text("false"), - autoincrement=False, - nullable=False, - ), - sa.PrimaryKeyConstraint("name", name=op.f("street_type_lookup_pkey")), - ) - op.create_index( - op.f("street_type_lookup_abbrev_idx"), - "street_type_lookup", - ["abbrev"], - unique=False, - ) - op.create_table( - "pagc_gaz", - sa.Column("id", sa.INTEGER(), autoincrement=True, nullable=False), - sa.Column("seq", sa.INTEGER(), autoincrement=False, nullable=True), - sa.Column("word", sa.TEXT(), autoincrement=False, nullable=True), - sa.Column("stdword", sa.TEXT(), autoincrement=False, nullable=True), - sa.Column("token", sa.INTEGER(), autoincrement=False, nullable=True), - sa.Column( - "is_custom", - sa.BOOLEAN(), - server_default=sa.text("true"), - autoincrement=False, - nullable=False, - ), - sa.PrimaryKeyConstraint("id", name=op.f("pagc_gaz_pkey")), - ) - op.create_table( - "loader_variables", - sa.Column( - "tiger_year", sa.VARCHAR(length=4), autoincrement=False, nullable=False - ), - sa.Column("website_root", sa.TEXT(), autoincrement=False, nullable=True), - sa.Column("staging_fold", sa.TEXT(), autoincrement=False, nullable=True), - sa.Column("data_schema", sa.TEXT(), autoincrement=False, nullable=True), - sa.Column("staging_schema", sa.TEXT(), autoincrement=False, nullable=True), - sa.PrimaryKeyConstraint("tiger_year", name=op.f("loader_variables_pkey")), - ) - op.create_table( - "tabblock20", - sa.Column("statefp", sa.VARCHAR(length=2), autoincrement=False, nullable=True), - sa.Column("countyfp", sa.VARCHAR(length=3), autoincrement=False, nullable=True), - sa.Column("tractce", sa.VARCHAR(length=6), autoincrement=False, nullable=True), - sa.Column("blockce", sa.VARCHAR(length=4), autoincrement=False, nullable=True), - sa.Column("geoid", sa.VARCHAR(length=15), autoincrement=False, nullable=False), - sa.Column("name", sa.VARCHAR(length=10), autoincrement=False, nullable=True), - sa.Column("mtfcc", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column("ur", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column("uace", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column("uatype", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column("funcstat", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column( - "aland", - sa.DOUBLE_PRECISION(precision=53), - autoincrement=False, - nullable=True, - ), - sa.Column( - "awater", - sa.DOUBLE_PRECISION(precision=53), - autoincrement=False, - nullable=True, - ), - sa.Column( - "intptlat", sa.VARCHAR(length=11), autoincrement=False, nullable=True - ), - sa.Column( - "intptlon", sa.VARCHAR(length=12), autoincrement=False, nullable=True - ), - sa.Column( - "the_geom", - geoalchemy2.types.Geometry( - geometry_type="MULTIPOLYGON", - srid=4269, - spatial_index=False, - from_text="ST_GeomFromEWKT", - name="geometry", - _spatial_index_reflected=True, - ), - autoincrement=False, - nullable=True, - ), - sa.Column( - "housing", - sa.DOUBLE_PRECISION(precision=53), - autoincrement=False, - nullable=True, - ), - sa.Column( - "pop", sa.DOUBLE_PRECISION(precision=53), autoincrement=False, nullable=True - ), - sa.PrimaryKeyConstraint("geoid", name=op.f("pk_tabblock20")), - ) - op.create_table( - "edges", - sa.Column("gid", sa.INTEGER(), autoincrement=True, nullable=False), - sa.Column("statefp", sa.VARCHAR(length=2), autoincrement=False, nullable=True), - sa.Column("countyfp", sa.VARCHAR(length=3), autoincrement=False, nullable=True), - sa.Column("tlid", sa.BIGINT(), autoincrement=False, nullable=True), - sa.Column( - "tfidl", - sa.NUMERIC(precision=10, scale=0), - autoincrement=False, - nullable=True, - ), - sa.Column( - "tfidr", - sa.NUMERIC(precision=10, scale=0), - autoincrement=False, - nullable=True, - ), - sa.Column("mtfcc", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column( - "fullname", sa.VARCHAR(length=100), autoincrement=False, nullable=True - ), - sa.Column("smid", sa.VARCHAR(length=22), autoincrement=False, nullable=True), - sa.Column( - "lfromadd", sa.VARCHAR(length=12), autoincrement=False, nullable=True - ), - sa.Column("ltoadd", sa.VARCHAR(length=12), autoincrement=False, nullable=True), - sa.Column( - "rfromadd", sa.VARCHAR(length=12), autoincrement=False, nullable=True - ), - sa.Column("rtoadd", sa.VARCHAR(length=12), autoincrement=False, nullable=True), - sa.Column("zipl", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column("zipr", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column("featcat", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column("hydroflg", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column("railflg", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column("roadflg", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column("olfflg", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column("passflg", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column("divroad", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column("exttyp", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column("ttyp", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column( - "deckedroad", sa.VARCHAR(length=1), autoincrement=False, nullable=True - ), - sa.Column("artpath", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column("persist", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column("gcseflg", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column("offsetl", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column("offsetr", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column( - "tnidf", - sa.NUMERIC(precision=10, scale=0), - autoincrement=False, - nullable=True, - ), - sa.Column( - "tnidt", - sa.NUMERIC(precision=10, scale=0), - autoincrement=False, - nullable=True, - ), - sa.Column( - "the_geom", - geoalchemy2.types.Geometry( - from_text="ST_GeomFromEWKT", - name="geometry", - _spatial_index_reflected=True, - ), - autoincrement=False, - nullable=True, - ), - sa.CheckConstraint( - "geometrytype(the_geom) = 'MULTILINESTRING'::text OR the_geom IS NULL", - name=op.f("enforce_geotype_the_geom"), - ), - sa.CheckConstraint( - "st_ndims(the_geom) = 2", name=op.f("enforce_dims_the_geom") - ), - sa.CheckConstraint( - "st_srid(the_geom) = 4269", name=op.f("enforce_srid_the_geom") - ), - sa.PrimaryKeyConstraint("gid", name=op.f("edges_pkey")), - ) - op.create_index( - op.f("idx_tiger_edges_the_geom_gist"), - "edges", - ["the_geom"], - unique=False, - postgresql_using="gist", - ) - op.create_index( - op.f("idx_tiger_edges_countyfp"), "edges", ["countyfp"], unique=False - ) - op.create_index(op.f("idx_edges_tlid"), "edges", ["tlid"], unique=False) - op.create_table( - "county_lookup", - sa.Column("st_code", sa.INTEGER(), autoincrement=False, nullable=False), - sa.Column("state", sa.VARCHAR(length=2), autoincrement=False, nullable=True), - sa.Column("co_code", sa.INTEGER(), autoincrement=False, nullable=False), - sa.Column("name", sa.VARCHAR(length=90), autoincrement=False, nullable=True), - sa.PrimaryKeyConstraint("st_code", "co_code", name=op.f("county_lookup_pkey")), - ) - op.create_index( - op.f("county_lookup_state_idx"), "county_lookup", ["state"], unique=False - ) - op.create_index( - op.f("county_lookup_name_idx"), - "county_lookup", - [sa.literal_column("soundex(name::text)")], - unique=False, - ) - op.create_table( - "zip_lookup", - sa.Column("zip", sa.INTEGER(), autoincrement=False, nullable=False), - sa.Column("st_code", sa.INTEGER(), autoincrement=False, nullable=True), - sa.Column("state", sa.VARCHAR(length=2), autoincrement=False, nullable=True), - sa.Column("co_code", sa.INTEGER(), autoincrement=False, nullable=True), - sa.Column("county", sa.VARCHAR(length=90), autoincrement=False, nullable=True), - sa.Column("cs_code", sa.INTEGER(), autoincrement=False, nullable=True), - sa.Column("cousub", sa.VARCHAR(length=90), autoincrement=False, nullable=True), - sa.Column("pl_code", sa.INTEGER(), autoincrement=False, nullable=True), - sa.Column("place", sa.VARCHAR(length=90), autoincrement=False, nullable=True), - sa.Column("cnt", sa.INTEGER(), autoincrement=False, nullable=True), - sa.PrimaryKeyConstraint("zip", name=op.f("zip_lookup_pkey")), - ) - op.create_table( - "zcta5", - sa.Column("gid", sa.INTEGER(), autoincrement=True, nullable=False), - sa.Column("statefp", sa.VARCHAR(length=2), autoincrement=False, nullable=False), - sa.Column("zcta5ce", sa.VARCHAR(length=5), autoincrement=False, nullable=False), - sa.Column("classfp", sa.VARCHAR(length=2), autoincrement=False, nullable=True), - sa.Column("mtfcc", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column("funcstat", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column( - "aland", - sa.DOUBLE_PRECISION(precision=53), - autoincrement=False, - nullable=True, - ), - sa.Column( - "awater", - sa.DOUBLE_PRECISION(precision=53), - autoincrement=False, - nullable=True, - ), - sa.Column( - "intptlat", sa.VARCHAR(length=11), autoincrement=False, nullable=True - ), - sa.Column( - "intptlon", sa.VARCHAR(length=12), autoincrement=False, nullable=True - ), - sa.Column("partflg", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column( - "the_geom", - geoalchemy2.types.Geometry( - spatial_index=False, - from_text="ST_GeomFromEWKT", - name="geometry", - _spatial_index_reflected=True, - ), - autoincrement=False, - nullable=True, - ), - sa.CheckConstraint( - "geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL", - name=op.f("enforce_geotype_the_geom"), - ), - sa.CheckConstraint( - "st_ndims(the_geom) = 2", name=op.f("enforce_dims_the_geom") - ), - sa.CheckConstraint( - "st_srid(the_geom) = 4269", name=op.f("enforce_srid_the_geom") - ), - sa.PrimaryKeyConstraint( - "zcta5ce", "statefp", name=op.f("pk_tiger_zcta5_zcta5ce") - ), - sa.UniqueConstraint( - "gid", - name=op.f("uidx_tiger_zcta5_gid"), - postgresql_include=[], - postgresql_nulls_not_distinct=False, - ), - ) - op.create_table( - "pagc_rules", - sa.Column("id", sa.INTEGER(), autoincrement=True, nullable=False), - sa.Column("rule", sa.TEXT(), autoincrement=False, nullable=True), - sa.Column( - "is_custom", - sa.BOOLEAN(), - server_default=sa.text("true"), - autoincrement=False, - nullable=True, - ), - sa.PrimaryKeyConstraint("id", name=op.f("pagc_rules_pkey")), - ) - op.create_table( - "cousub", - sa.Column("gid", sa.INTEGER(), autoincrement=True, nullable=False), - sa.Column("statefp", sa.VARCHAR(length=2), autoincrement=False, nullable=True), - sa.Column("countyfp", sa.VARCHAR(length=3), autoincrement=False, nullable=True), - sa.Column("cousubfp", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column("cousubns", sa.VARCHAR(length=8), autoincrement=False, nullable=True), - sa.Column( - "cosbidfp", sa.VARCHAR(length=10), autoincrement=False, nullable=False - ), - sa.Column("name", sa.VARCHAR(length=100), autoincrement=False, nullable=True), - sa.Column( - "namelsad", sa.VARCHAR(length=100), autoincrement=False, nullable=True - ), - sa.Column("lsad", sa.VARCHAR(length=2), autoincrement=False, nullable=True), - sa.Column("classfp", sa.VARCHAR(length=2), autoincrement=False, nullable=True), - sa.Column("mtfcc", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column("cnectafp", sa.VARCHAR(length=3), autoincrement=False, nullable=True), - sa.Column("nectafp", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column("nctadvfp", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column("funcstat", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column( - "aland", - sa.NUMERIC(precision=14, scale=0), - autoincrement=False, - nullable=True, - ), - sa.Column( - "awater", - sa.NUMERIC(precision=14, scale=0), - autoincrement=False, - nullable=True, - ), - sa.Column( - "intptlat", sa.VARCHAR(length=11), autoincrement=False, nullable=True - ), - sa.Column( - "intptlon", sa.VARCHAR(length=12), autoincrement=False, nullable=True - ), - sa.Column( - "the_geom", - geoalchemy2.types.Geometry( - from_text="ST_GeomFromEWKT", - name="geometry", - _spatial_index_reflected=True, - ), - autoincrement=False, - nullable=True, - ), - sa.CheckConstraint( - "geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL", - name=op.f("enforce_geotype_the_geom"), - ), - sa.CheckConstraint( - "st_ndims(the_geom) = 2", name=op.f("enforce_dims_the_geom") - ), - sa.CheckConstraint( - "st_srid(the_geom) = 4269", name=op.f("enforce_srid_the_geom") - ), - sa.PrimaryKeyConstraint("cosbidfp", name=op.f("cousub_pkey")), - sa.UniqueConstraint( - "gid", - name=op.f("uidx_cousub_gid"), - postgresql_include=[], - postgresql_nulls_not_distinct=False, - ), - ) - op.create_index( - op.f("tige_cousub_the_geom_gist"), - "cousub", - ["the_geom"], - unique=False, - postgresql_using="gist", - ) - op.create_table( - "zip_lookup_all", - sa.Column("zip", sa.INTEGER(), autoincrement=False, nullable=True), - sa.Column("st_code", sa.INTEGER(), autoincrement=False, nullable=True), - sa.Column("state", sa.VARCHAR(length=2), autoincrement=False, nullable=True), - sa.Column("co_code", sa.INTEGER(), autoincrement=False, nullable=True), - sa.Column("county", sa.VARCHAR(length=90), autoincrement=False, nullable=True), - sa.Column("cs_code", sa.INTEGER(), autoincrement=False, nullable=True), - sa.Column("cousub", sa.VARCHAR(length=90), autoincrement=False, nullable=True), - sa.Column("pl_code", sa.INTEGER(), autoincrement=False, nullable=True), - sa.Column("place", sa.VARCHAR(length=90), autoincrement=False, nullable=True), - sa.Column("cnt", sa.INTEGER(), autoincrement=False, nullable=True), - ) - op.create_table( - "bg", - sa.Column("gid", sa.INTEGER(), autoincrement=True, nullable=False), - sa.Column("statefp", sa.VARCHAR(length=2), autoincrement=False, nullable=True), - sa.Column("countyfp", sa.VARCHAR(length=3), autoincrement=False, nullable=True), - sa.Column("tractce", sa.VARCHAR(length=6), autoincrement=False, nullable=True), - sa.Column("blkgrpce", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column("bg_id", sa.VARCHAR(length=12), autoincrement=False, nullable=False), - sa.Column( - "namelsad", sa.VARCHAR(length=13), autoincrement=False, nullable=True - ), - sa.Column("mtfcc", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column("funcstat", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column( - "aland", - sa.DOUBLE_PRECISION(precision=53), - autoincrement=False, - nullable=True, - ), - sa.Column( - "awater", - sa.DOUBLE_PRECISION(precision=53), - autoincrement=False, - nullable=True, - ), - sa.Column( - "intptlat", sa.VARCHAR(length=11), autoincrement=False, nullable=True - ), - sa.Column( - "intptlon", sa.VARCHAR(length=12), autoincrement=False, nullable=True - ), - sa.Column( - "the_geom", - geoalchemy2.types.Geometry( - spatial_index=False, - from_text="ST_GeomFromEWKT", - name="geometry", - _spatial_index_reflected=True, - ), - autoincrement=False, - nullable=True, - ), - sa.CheckConstraint( - "geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL", - name=op.f("enforce_geotype_geom"), - ), - sa.CheckConstraint("st_ndims(the_geom) = 2", name=op.f("enforce_dims_geom")), - sa.CheckConstraint("st_srid(the_geom) = 4269", name=op.f("enforce_srid_geom")), - sa.PrimaryKeyConstraint("bg_id", name=op.f("bg_pkey")), - comment="block groups", - ) - op.create_table( - "faces", - sa.Column("gid", sa.INTEGER(), autoincrement=True, nullable=False), - sa.Column( - "tfid", - sa.NUMERIC(precision=10, scale=0), - autoincrement=False, - nullable=True, - ), - sa.Column( - "statefp00", sa.VARCHAR(length=2), autoincrement=False, nullable=True - ), - sa.Column( - "countyfp00", sa.VARCHAR(length=3), autoincrement=False, nullable=True - ), - sa.Column( - "tractce00", sa.VARCHAR(length=6), autoincrement=False, nullable=True - ), - sa.Column( - "blkgrpce00", sa.VARCHAR(length=1), autoincrement=False, nullable=True - ), - sa.Column( - "blockce00", sa.VARCHAR(length=4), autoincrement=False, nullable=True - ), - sa.Column( - "cousubfp00", sa.VARCHAR(length=5), autoincrement=False, nullable=True - ), - sa.Column( - "submcdfp00", sa.VARCHAR(length=5), autoincrement=False, nullable=True - ), - sa.Column( - "conctyfp00", sa.VARCHAR(length=5), autoincrement=False, nullable=True - ), - sa.Column( - "placefp00", sa.VARCHAR(length=5), autoincrement=False, nullable=True - ), - sa.Column( - "aiannhfp00", sa.VARCHAR(length=5), autoincrement=False, nullable=True - ), - sa.Column( - "aiannhce00", sa.VARCHAR(length=4), autoincrement=False, nullable=True - ), - sa.Column( - "comptyp00", sa.VARCHAR(length=1), autoincrement=False, nullable=True - ), - sa.Column( - "trsubfp00", sa.VARCHAR(length=5), autoincrement=False, nullable=True - ), - sa.Column( - "trsubce00", sa.VARCHAR(length=3), autoincrement=False, nullable=True - ), - sa.Column("anrcfp00", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column( - "elsdlea00", sa.VARCHAR(length=5), autoincrement=False, nullable=True - ), - sa.Column( - "scsdlea00", sa.VARCHAR(length=5), autoincrement=False, nullable=True - ), - sa.Column( - "unsdlea00", sa.VARCHAR(length=5), autoincrement=False, nullable=True - ), - sa.Column("uace00", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column("cd108fp", sa.VARCHAR(length=2), autoincrement=False, nullable=True), - sa.Column("sldust00", sa.VARCHAR(length=3), autoincrement=False, nullable=True), - sa.Column("sldlst00", sa.VARCHAR(length=3), autoincrement=False, nullable=True), - sa.Column("vtdst00", sa.VARCHAR(length=6), autoincrement=False, nullable=True), - sa.Column( - "zcta5ce00", sa.VARCHAR(length=5), autoincrement=False, nullable=True - ), - sa.Column("tazce00", sa.VARCHAR(length=6), autoincrement=False, nullable=True), - sa.Column("ugace00", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column( - "puma5ce00", sa.VARCHAR(length=5), autoincrement=False, nullable=True - ), - sa.Column("statefp", sa.VARCHAR(length=2), autoincrement=False, nullable=True), - sa.Column("countyfp", sa.VARCHAR(length=3), autoincrement=False, nullable=True), - sa.Column("tractce", sa.VARCHAR(length=6), autoincrement=False, nullable=True), - sa.Column("blkgrpce", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column("blockce", sa.VARCHAR(length=4), autoincrement=False, nullable=True), - sa.Column("cousubfp", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column("submcdfp", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column("conctyfp", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column("placefp", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column("aiannhfp", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column("aiannhce", sa.VARCHAR(length=4), autoincrement=False, nullable=True), - sa.Column("comptyp", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column("trsubfp", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column("trsubce", sa.VARCHAR(length=3), autoincrement=False, nullable=True), - sa.Column("anrcfp", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column("ttractce", sa.VARCHAR(length=6), autoincrement=False, nullable=True), - sa.Column("tblkgpce", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column("elsdlea", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column("scsdlea", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column("unsdlea", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column("uace", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column("cd111fp", sa.VARCHAR(length=2), autoincrement=False, nullable=True), - sa.Column("sldust", sa.VARCHAR(length=3), autoincrement=False, nullable=True), - sa.Column("sldlst", sa.VARCHAR(length=3), autoincrement=False, nullable=True), - sa.Column("vtdst", sa.VARCHAR(length=6), autoincrement=False, nullable=True), - sa.Column("zcta5ce", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column("tazce", sa.VARCHAR(length=6), autoincrement=False, nullable=True), - sa.Column("ugace", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column("puma5ce", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column("csafp", sa.VARCHAR(length=3), autoincrement=False, nullable=True), - sa.Column("cbsafp", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column("metdivfp", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column("cnectafp", sa.VARCHAR(length=3), autoincrement=False, nullable=True), - sa.Column("nectafp", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column("nctadvfp", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column("lwflag", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column("offset", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column( - "atotal", - sa.DOUBLE_PRECISION(precision=53), - autoincrement=False, - nullable=True, - ), - sa.Column( - "intptlat", sa.VARCHAR(length=11), autoincrement=False, nullable=True - ), - sa.Column( - "intptlon", sa.VARCHAR(length=12), autoincrement=False, nullable=True - ), - sa.Column( - "the_geom", - geoalchemy2.types.Geometry( - from_text="ST_GeomFromEWKT", - name="geometry", - _spatial_index_reflected=True, - ), - autoincrement=False, - nullable=True, - ), - sa.Column( - "tractce20", sa.VARCHAR(length=6), autoincrement=False, nullable=True - ), - sa.Column( - "blkgrpce20", sa.VARCHAR(length=1), autoincrement=False, nullable=True - ), - sa.Column( - "blockce20", sa.VARCHAR(length=4), autoincrement=False, nullable=True - ), - sa.Column( - "countyfp20", sa.VARCHAR(length=3), autoincrement=False, nullable=True - ), - sa.Column( - "statefp20", sa.VARCHAR(length=2), autoincrement=False, nullable=True - ), - sa.CheckConstraint( - "geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL", - name=op.f("enforce_geotype_the_geom"), - ), - sa.CheckConstraint( - "st_ndims(the_geom) = 2", name=op.f("enforce_dims_the_geom") - ), - sa.CheckConstraint( - "st_srid(the_geom) = 4269", name=op.f("enforce_srid_the_geom") - ), - sa.PrimaryKeyConstraint("gid", name=op.f("faces_pkey")), - ) - op.create_index( - op.f("tiger_faces_the_geom_gist"), - "faces", - ["the_geom"], - unique=False, - postgresql_using="gist", - ) - op.create_index(op.f("idx_tiger_faces_tfid"), "faces", ["tfid"], unique=False) - op.create_index( - op.f("idx_tiger_faces_countyfp"), "faces", ["countyfp"], unique=False - ) - op.create_table( - "direction_lookup", - sa.Column("name", sa.VARCHAR(length=20), autoincrement=False, nullable=False), - sa.Column("abbrev", sa.VARCHAR(length=3), autoincrement=False, nullable=True), - sa.PrimaryKeyConstraint("name", name=op.f("direction_lookup_pkey")), - ) - op.create_index( - op.f("direction_lookup_abbrev_idx"), - "direction_lookup", - ["abbrev"], - unique=False, - ) - op.create_table( - "addrfeat", - sa.Column("gid", sa.INTEGER(), autoincrement=True, nullable=False), - sa.Column("tlid", sa.BIGINT(), autoincrement=False, nullable=True), - sa.Column("statefp", sa.VARCHAR(length=2), autoincrement=False, nullable=False), - sa.Column("aridl", sa.VARCHAR(length=22), autoincrement=False, nullable=True), - sa.Column("aridr", sa.VARCHAR(length=22), autoincrement=False, nullable=True), - sa.Column( - "linearid", sa.VARCHAR(length=22), autoincrement=False, nullable=True - ), - sa.Column( - "fullname", sa.VARCHAR(length=100), autoincrement=False, nullable=True - ), - sa.Column("lfromhn", sa.VARCHAR(length=12), autoincrement=False, nullable=True), - sa.Column("ltohn", sa.VARCHAR(length=12), autoincrement=False, nullable=True), - sa.Column("rfromhn", sa.VARCHAR(length=12), autoincrement=False, nullable=True), - sa.Column("rtohn", sa.VARCHAR(length=12), autoincrement=False, nullable=True), - sa.Column("zipl", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column("zipr", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column( - "edge_mtfcc", sa.VARCHAR(length=5), autoincrement=False, nullable=True - ), - sa.Column("parityl", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column("parityr", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column("plus4l", sa.VARCHAR(length=4), autoincrement=False, nullable=True), - sa.Column("plus4r", sa.VARCHAR(length=4), autoincrement=False, nullable=True), - sa.Column("lfromtyp", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column("ltotyp", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column("rfromtyp", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column("rtotyp", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column("offsetl", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column("offsetr", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column( - "the_geom", - geoalchemy2.types.Geometry( - from_text="ST_GeomFromEWKT", - name="geometry", - _spatial_index_reflected=True, - ), - autoincrement=False, - nullable=True, - ), - sa.CheckConstraint( - "geometrytype(the_geom) = 'LINESTRING'::text OR the_geom IS NULL", - name=op.f("enforce_geotype_the_geom"), - ), - sa.CheckConstraint( - "st_ndims(the_geom) = 2", name=op.f("enforce_dims_the_geom") - ), - sa.CheckConstraint( - "st_srid(the_geom) = 4269", name=op.f("enforce_srid_the_geom") - ), - sa.PrimaryKeyConstraint("gid", name=op.f("addrfeat_pkey")), - ) - op.create_index(op.f("idx_addrfeat_zipr"), "addrfeat", ["zipr"], unique=False) - op.create_index(op.f("idx_addrfeat_zipl"), "addrfeat", ["zipl"], unique=False) - op.create_index(op.f("idx_addrfeat_tlid"), "addrfeat", ["tlid"], unique=False) - op.create_index( - op.f("idx_addrfeat_geom_gist"), - "addrfeat", - ["the_geom"], - unique=False, - postgresql_using="gist", - ) - op.create_table( - "state", - sa.Column("gid", sa.INTEGER(), autoincrement=True, nullable=False), - sa.Column("region", sa.VARCHAR(length=2), autoincrement=False, nullable=True), - sa.Column("division", sa.VARCHAR(length=2), autoincrement=False, nullable=True), - sa.Column("statefp", sa.VARCHAR(length=2), autoincrement=False, nullable=False), - sa.Column("statens", sa.VARCHAR(length=8), autoincrement=False, nullable=True), - sa.Column("stusps", sa.VARCHAR(length=2), autoincrement=False, nullable=False), - sa.Column("name", sa.VARCHAR(length=100), autoincrement=False, nullable=True), - sa.Column("lsad", sa.VARCHAR(length=2), autoincrement=False, nullable=True), - sa.Column("mtfcc", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column("funcstat", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column("aland", sa.BIGINT(), autoincrement=False, nullable=True), - sa.Column("awater", sa.BIGINT(), autoincrement=False, nullable=True), - sa.Column( - "intptlat", sa.VARCHAR(length=11), autoincrement=False, nullable=True - ), - sa.Column( - "intptlon", sa.VARCHAR(length=12), autoincrement=False, nullable=True - ), - sa.Column( - "the_geom", - geoalchemy2.types.Geometry( - from_text="ST_GeomFromEWKT", - name="geometry", - _spatial_index_reflected=True, - ), - autoincrement=False, - nullable=True, - ), - sa.CheckConstraint( - "geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL", - name=op.f("enforce_geotype_the_geom"), - ), - sa.CheckConstraint( - "st_ndims(the_geom) = 2", name=op.f("enforce_dims_the_geom") - ), - sa.CheckConstraint( - "st_srid(the_geom) = 4269", name=op.f("enforce_srid_the_geom") - ), - sa.PrimaryKeyConstraint("statefp", name=op.f("pk_tiger_state")), - sa.UniqueConstraint( - "gid", - name=op.f("uidx_tiger_state_gid"), - postgresql_include=[], - postgresql_nulls_not_distinct=False, - ), - sa.UniqueConstraint( - "stusps", - name=op.f("uidx_tiger_state_stusps"), - postgresql_include=[], - postgresql_nulls_not_distinct=False, - ), - ) - op.create_index( - op.f("idx_tiger_state_the_geom_gist"), - "state", - ["the_geom"], - unique=False, - postgresql_using="gist", - ) - op.create_table( - "secondary_unit_lookup", - sa.Column("name", sa.VARCHAR(length=20), autoincrement=False, nullable=False), - sa.Column("abbrev", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.PrimaryKeyConstraint("name", name=op.f("secondary_unit_lookup_pkey")), - ) - op.create_index( - op.f("secondary_unit_lookup_abbrev_idx"), - "secondary_unit_lookup", - ["abbrev"], - unique=False, - ) - op.create_table( - "zip_state", - sa.Column("zip", sa.VARCHAR(length=5), autoincrement=False, nullable=False), - sa.Column("stusps", sa.VARCHAR(length=2), autoincrement=False, nullable=False), - sa.Column("statefp", sa.VARCHAR(length=2), autoincrement=False, nullable=True), - sa.PrimaryKeyConstraint("zip", "stusps", name=op.f("zip_state_pkey")), - ) - op.create_table( - "place_lookup", - sa.Column("st_code", sa.INTEGER(), autoincrement=False, nullable=False), - sa.Column("state", sa.VARCHAR(length=2), autoincrement=False, nullable=True), - sa.Column("pl_code", sa.INTEGER(), autoincrement=False, nullable=False), - sa.Column("name", sa.VARCHAR(length=90), autoincrement=False, nullable=True), - sa.PrimaryKeyConstraint("st_code", "pl_code", name=op.f("place_lookup_pkey")), - ) - op.create_index( - op.f("place_lookup_state_idx"), "place_lookup", ["state"], unique=False - ) - op.create_index( - op.f("place_lookup_name_idx"), - "place_lookup", - [sa.literal_column("soundex(name::text)")], - unique=False, - ) - op.create_table( - "state_lookup", - sa.Column("st_code", sa.INTEGER(), autoincrement=False, nullable=False), - sa.Column("name", sa.VARCHAR(length=40), autoincrement=False, nullable=True), - sa.Column("abbrev", sa.VARCHAR(length=3), autoincrement=False, nullable=True), - sa.Column("statefp", sa.CHAR(length=2), autoincrement=False, nullable=True), - sa.PrimaryKeyConstraint("st_code", name=op.f("state_lookup_pkey")), - sa.UniqueConstraint( - "abbrev", - name=op.f("state_lookup_abbrev_key"), - postgresql_include=[], - postgresql_nulls_not_distinct=False, - ), - sa.UniqueConstraint( - "name", - name=op.f("state_lookup_name_key"), - postgresql_include=[], - postgresql_nulls_not_distinct=False, - ), - sa.UniqueConstraint( - "statefp", - name=op.f("state_lookup_statefp_key"), - postgresql_include=[], - postgresql_nulls_not_distinct=False, - ), - ) - op.create_table( - "featnames", - sa.Column("gid", sa.INTEGER(), autoincrement=True, nullable=False), - sa.Column("tlid", sa.BIGINT(), autoincrement=False, nullable=True), - sa.Column( - "fullname", sa.VARCHAR(length=100), autoincrement=False, nullable=True - ), - sa.Column("name", sa.VARCHAR(length=100), autoincrement=False, nullable=True), - sa.Column( - "predirabrv", sa.VARCHAR(length=15), autoincrement=False, nullable=True - ), - sa.Column( - "pretypabrv", sa.VARCHAR(length=50), autoincrement=False, nullable=True - ), - sa.Column( - "prequalabr", sa.VARCHAR(length=15), autoincrement=False, nullable=True - ), - sa.Column( - "sufdirabrv", sa.VARCHAR(length=15), autoincrement=False, nullable=True - ), - sa.Column( - "suftypabrv", sa.VARCHAR(length=50), autoincrement=False, nullable=True - ), - sa.Column( - "sufqualabr", sa.VARCHAR(length=15), autoincrement=False, nullable=True - ), - sa.Column("predir", sa.VARCHAR(length=2), autoincrement=False, nullable=True), - sa.Column("pretyp", sa.VARCHAR(length=3), autoincrement=False, nullable=True), - sa.Column("prequal", sa.VARCHAR(length=2), autoincrement=False, nullable=True), - sa.Column("sufdir", sa.VARCHAR(length=2), autoincrement=False, nullable=True), - sa.Column("suftyp", sa.VARCHAR(length=3), autoincrement=False, nullable=True), - sa.Column("sufqual", sa.VARCHAR(length=2), autoincrement=False, nullable=True), - sa.Column( - "linearid", sa.VARCHAR(length=22), autoincrement=False, nullable=True - ), - sa.Column("mtfcc", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column("paflag", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column("statefp", sa.VARCHAR(length=2), autoincrement=False, nullable=True), - sa.PrimaryKeyConstraint("gid", name=op.f("featnames_pkey")), - ) - op.create_index( - op.f("idx_tiger_featnames_tlid_statefp"), - "featnames", - ["tlid", "statefp"], - unique=False, - ) - op.create_index( - op.f("idx_tiger_featnames_snd_name"), - "featnames", - [sa.literal_column("soundex(name::text)")], - unique=False, - ) - op.create_index( - op.f("idx_tiger_featnames_lname"), - "featnames", - [sa.literal_column("lower(name::text)")], - unique=False, - ) - op.create_table( - "county", - sa.Column("gid", sa.INTEGER(), autoincrement=True, nullable=False), - sa.Column("statefp", sa.VARCHAR(length=2), autoincrement=False, nullable=True), - sa.Column("countyfp", sa.VARCHAR(length=3), autoincrement=False, nullable=True), - sa.Column("countyns", sa.VARCHAR(length=8), autoincrement=False, nullable=True), - sa.Column( - "cntyidfp", sa.VARCHAR(length=5), autoincrement=False, nullable=False - ), - sa.Column("name", sa.VARCHAR(length=100), autoincrement=False, nullable=True), - sa.Column( - "namelsad", sa.VARCHAR(length=100), autoincrement=False, nullable=True - ), - sa.Column("lsad", sa.VARCHAR(length=2), autoincrement=False, nullable=True), - sa.Column("classfp", sa.VARCHAR(length=2), autoincrement=False, nullable=True), - sa.Column("mtfcc", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column("csafp", sa.VARCHAR(length=3), autoincrement=False, nullable=True), - sa.Column("cbsafp", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column("metdivfp", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column("funcstat", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column("aland", sa.BIGINT(), autoincrement=False, nullable=True), - sa.Column( - "awater", - sa.DOUBLE_PRECISION(precision=53), - autoincrement=False, - nullable=True, - ), - sa.Column( - "intptlat", sa.VARCHAR(length=11), autoincrement=False, nullable=True - ), - sa.Column( - "intptlon", sa.VARCHAR(length=12), autoincrement=False, nullable=True - ), - sa.Column( - "the_geom", - geoalchemy2.types.Geometry( - spatial_index=False, - from_text="ST_GeomFromEWKT", - name="geometry", - _spatial_index_reflected=True, - ), - autoincrement=False, - nullable=True, - ), - sa.CheckConstraint( - "geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL", - name=op.f("enforce_geotype_geom"), - ), - sa.CheckConstraint("st_ndims(the_geom) = 2", name=op.f("enforce_dims_geom")), - sa.CheckConstraint("st_srid(the_geom) = 4269", name=op.f("enforce_srid_geom")), - sa.PrimaryKeyConstraint("cntyidfp", name=op.f("pk_tiger_county")), - sa.UniqueConstraint( - "gid", - name=op.f("uidx_county_gid"), - postgresql_include=[], - postgresql_nulls_not_distinct=False, - ), - ) - op.create_index(op.f("idx_tiger_county"), "county", ["countyfp"], unique=False) - op.create_table( - "addr", - sa.Column("gid", sa.INTEGER(), autoincrement=True, nullable=False), - sa.Column("tlid", sa.BIGINT(), autoincrement=False, nullable=True), - sa.Column("fromhn", sa.VARCHAR(length=12), autoincrement=False, nullable=True), - sa.Column("tohn", sa.VARCHAR(length=12), autoincrement=False, nullable=True), - sa.Column("side", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column("zip", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column("plus4", sa.VARCHAR(length=4), autoincrement=False, nullable=True), - sa.Column("fromtyp", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column("totyp", sa.VARCHAR(length=1), autoincrement=False, nullable=True), - sa.Column("fromarmid", sa.INTEGER(), autoincrement=False, nullable=True), - sa.Column("toarmid", sa.INTEGER(), autoincrement=False, nullable=True), - sa.Column("arid", sa.VARCHAR(length=22), autoincrement=False, nullable=True), - sa.Column("mtfcc", sa.VARCHAR(length=5), autoincrement=False, nullable=True), - sa.Column("statefp", sa.VARCHAR(length=2), autoincrement=False, nullable=True), - sa.PrimaryKeyConstraint("gid", name=op.f("addr_pkey")), - ) - op.create_index(op.f("idx_tiger_addr_zip"), "addr", ["zip"], unique=False) - op.create_index( - op.f("idx_tiger_addr_tlid_statefp"), "addr", ["tlid", "statefp"], unique=False - ) - op.create_table( - "loader_lookuptables", - sa.Column( - "process_order", - sa.INTEGER(), - server_default=sa.text("1000"), - autoincrement=False, - nullable=False, - ), - sa.Column( - "lookup_name", - sa.TEXT(), - autoincrement=False, - nullable=False, - comment="This is the table name to inherit from and suffix of resulting output table -- how the table will be named -- edges here would mean -- ma_edges , pa_edges etc. except in the case of national tables. national level tables have no prefix", - ), - sa.Column( - "table_name", - sa.TEXT(), - autoincrement=False, - nullable=True, - comment="suffix of the tables to load e.g. edges would load all tables like *edges.dbf(shp) -- so tl_2010_42129_edges.dbf . ", - ), - sa.Column( - "single_mode", - sa.BOOLEAN(), - server_default=sa.text("true"), - autoincrement=False, - nullable=False, - ), - sa.Column( - "load", - sa.BOOLEAN(), - server_default=sa.text("true"), - autoincrement=False, - nullable=False, - comment="Whether or not to load the table. For states and zcta5 (you may just want to download states10, zcta510 nationwide file manually) load your own into a single table that inherits from tiger.states, tiger.zcta5. You'll get improved performance for some geocoding cases.", - ), - sa.Column( - "level_county", - sa.BOOLEAN(), - server_default=sa.text("false"), - autoincrement=False, - nullable=False, - ), - sa.Column( - "level_state", - sa.BOOLEAN(), - server_default=sa.text("false"), - autoincrement=False, - nullable=False, - ), - sa.Column( - "level_nation", - sa.BOOLEAN(), - server_default=sa.text("false"), - autoincrement=False, - nullable=False, - comment="These are tables that contain all data for the whole US so there is just a single file", - ), - sa.Column("post_load_process", sa.TEXT(), autoincrement=False, nullable=True), - sa.Column( - "single_geom_mode", - sa.BOOLEAN(), - server_default=sa.text("false"), - autoincrement=False, - nullable=True, - ), - sa.Column( - "insert_mode", - sa.CHAR(length=1), - server_default=sa.text("'c'::bpchar"), - autoincrement=False, - nullable=False, - ), - sa.Column("pre_load_process", sa.TEXT(), autoincrement=False, nullable=True), - sa.Column( - "columns_exclude", - postgresql.ARRAY(sa.TEXT()), - autoincrement=False, - nullable=True, - comment="List of columns to exclude as an array. This is excluded from both input table and output table and rest of columns remaining are assumed to be in same order in both tables. gid, geoid,cpi,suffix1ce are excluded if no columns are specified.", - ), - sa.Column( - "website_root_override", - sa.TEXT(), - autoincrement=False, - nullable=True, - comment="Path to use for wget instead of that specified in year table. Needed currently for zcta where they release that only for 2000 and 2010", - ), - sa.PrimaryKeyConstraint("lookup_name", name=op.f("loader_lookuptables_pkey")), - ) - op.drop_table("well_screen") - op.drop_table("groundwater_level_series") - op.drop_table("geothermal_series") - op.drop_table("geochemical_series") - op.drop_table("collaborative_network_well") - op.drop_table("well_thing") - op.drop_table("thing_id_link") - op.drop_table("thing_contact_association") - op.drop_table("spring_thing") - op.drop_table("series") - op.drop_table("pub_author_publication_association") - op.drop_table("pub_author_contact_association") - op.drop_index("ix_phone_search_vector", table_name="phone", postgresql_using="gin") - op.drop_table("phone") - op.drop_table("location_thing_association") - op.drop_index("ix_email_search_vector", table_name="email", postgresql_using="gin") - op.drop_table("email") - op.drop_table("asset_thing_association") - op.drop_table("address") - op.drop_table("thing") - op.drop_index( - "ix_publication_search_vector", table_name="publication", postgresql_using="gin" - ) - op.drop_table("publication") - op.drop_index("idx_location_point", table_name="location", postgresql_using="gist") - op.drop_table("location") - op.drop_table("lexicon_triple") - op.drop_table("lexicon_term_category_association") - op.drop_table("groundwater_level_sensor") - op.drop_table("geochronology_age") - op.drop_index( - "ix_contact_search_vector", table_name="contact", postgresql_using="gin" - ) - op.drop_table("contact") - op.drop_table("user") - op.drop_table("sensor") - op.drop_index( - "ix_pub_author_search_vector", table_name="pub_author", postgresql_using="gin" - ) - op.drop_table("pub_author") - op.drop_table("lexicon_term") - op.drop_table("lexicon_category") - op.drop_index("ix_asset_search_vector", table_name="asset", postgresql_using="gin") - op.drop_table("asset") - # ### end Alembic commands ### diff --git a/alembic/versions/fb089dbbfc43_initial_migration.py b/alembic/versions/fb089dbbfc43_initial_migration.py new file mode 100644 index 000000000..91d060b2b --- /dev/null +++ b/alembic/versions/fb089dbbfc43_initial_migration.py @@ -0,0 +1,627 @@ +"""Initial migration + +Revision ID: fb089dbbfc43 +Revises: +Create Date: 2025-07-22 11:12:10.398798 + +""" + +from typing import Sequence, Union + +from alembic import op +import geoalchemy2 +import sqlalchemy as sa +import sqlalchemy_utils + + +# revision identifiers, used by Alembic. +revision: str = "fb089dbbfc43" +down_revision: Union[str, Sequence[str], None] = None +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + """Upgrade schema.""" + # ### commands auto generated by Alembic - please adjust! ### + op.create_table( + "asset", + sa.Column("filename", sa.String(), nullable=True), + sa.Column("storage_service", sa.String(), nullable=True), + sa.Column("storage_path", sa.String(), nullable=True), + sa.Column("mime_type", sa.String(), nullable=True), + sa.Column("size", sa.Integer(), nullable=True), + sa.Column( + "search_vector", + sqlalchemy_utils.types.ts_vector.TSVectorType(), + nullable=True, + ), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.PrimaryKeyConstraint("id"), + ) + op.create_index( + "ix_asset_search_vector", + "asset", + ["search_vector"], + unique=False, + postgresql_using="gin", + ) + op.create_table( + "lexicon_category", + sa.Column("name", sa.String(length=100), nullable=False), + sa.Column("description", sa.String(length=255), nullable=True), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.PrimaryKeyConstraint("id"), + sa.UniqueConstraint("name"), + ) + op.create_table( + "lexicon_term", + sa.Column("term", sa.String(length=100), nullable=False), + sa.Column("definition", sa.String(length=255), nullable=False), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.PrimaryKeyConstraint("id"), + sa.UniqueConstraint("term"), + ) + op.create_table( + "pub_author", + sa.Column("name", sa.String(), nullable=False), + sa.Column("affiliation", sa.String(), nullable=True), + sa.Column( + "search_vector", + sqlalchemy_utils.types.ts_vector.TSVectorType(), + nullable=True, + ), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.PrimaryKeyConstraint("id"), + ) + op.create_index( + "ix_pub_author_search_vector", + "pub_author", + ["search_vector"], + unique=False, + postgresql_using="gin", + ) + op.create_table( + "sensor", + sa.Column("name", sa.String(length=255), nullable=False), + sa.Column("model", sa.String(length=50), nullable=True), + sa.Column("serial_no", sa.String(length=50), nullable=True), + sa.Column("date_installed", sa.DateTime(), nullable=True), + sa.Column("date_removed", sa.DateTime(), nullable=True), + sa.Column("recording_interval", sa.Integer(), nullable=True), + sa.Column("notes", sa.String(length=50), nullable=True), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.PrimaryKeyConstraint("id"), + ) + op.create_table( + "user", + sa.Column("id", sa.Integer(), nullable=False), + sa.Column("username", sa.String(length=255), nullable=False), + sa.Column("password", sa.String(length=255), nullable=False), + sa.Column("is_superuser", sa.Boolean(), nullable=False), + sa.Column("is_active", sa.Boolean(), nullable=False), + sa.Column("avatar_url", sa.Text(), nullable=True), + sa.PrimaryKeyConstraint("id"), + ) + op.create_table( + "contact", + sa.Column("name", sa.String(length=100), nullable=False), + sa.Column("role", sa.String(length=100), nullable=False), + sa.Column( + "search_vector", + sqlalchemy_utils.types.ts_vector.TSVectorType(), + nullable=True, + ), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.ForeignKeyConstraint( + ["role"], + ["lexicon_term.term"], + ), + sa.PrimaryKeyConstraint("id"), + ) + op.create_index( + "ix_contact_search_vector", + "contact", + ["search_vector"], + unique=False, + postgresql_using="gin", + ) + op.create_table( + "geochronology_age", + sa.Column("location_id", sa.Integer(), nullable=False), + sa.Column("age", sa.Float(), nullable=False), + sa.Column("age_error", sa.Float(), nullable=True), + sa.Column("method", sa.String(length=100), nullable=True), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.ForeignKeyConstraint( + ["method"], + ["lexicon_term.term"], + ), + sa.PrimaryKeyConstraint("id"), + ) + op.create_table( + "groundwater_level_sensor", + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.Column("sensor_id", sa.Integer(), nullable=False), + sa.ForeignKeyConstraint(["sensor_id"], ["sensor.id"], ondelete="CASCADE"), + sa.PrimaryKeyConstraint("id"), + sa.UniqueConstraint("sensor_id"), + ) + op.create_table( + "lexicon_term_category_association", + sa.Column("lexicon_term", sa.String(length=100), nullable=False), + sa.Column("category_name", sa.String(length=255), nullable=False), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.ForeignKeyConstraint( + ["category_name"], ["lexicon_category.name"], ondelete="CASCADE" + ), + sa.ForeignKeyConstraint( + ["lexicon_term"], ["lexicon_term.term"], ondelete="CASCADE" + ), + sa.PrimaryKeyConstraint("id"), + ) + op.create_table( + "lexicon_triple", + sa.Column("subject", sa.String(length=100), nullable=False), + sa.Column("predicate", sa.String(length=100), nullable=False), + sa.Column("object_", sa.String(length=100), nullable=False), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.ForeignKeyConstraint(["object_"], ["lexicon_term.term"], ondelete="CASCADE"), + sa.ForeignKeyConstraint(["subject"], ["lexicon_term.term"], ondelete="CASCADE"), + sa.PrimaryKeyConstraint("id"), + ) + op.create_table( + "location", + sa.Column("notes", sa.Text(), nullable=True), + sa.Column( + "point", + geoalchemy2.types.Geometry( + geometry_type="POINT", + srid=4326, + from_text="ST_GeomFromEWKT", + name="geometry", + nullable=False, + ), + nullable=False, + ), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.Column("release_status", sa.String(length=100), nullable=True), + sa.ForeignKeyConstraint( + ["release_status"], + ["lexicon_term.term"], + ), + sa.PrimaryKeyConstraint("id"), + ) + op.create_index( + "idx_location_point", + "location", + ["point"], + unique=False, + postgresql_using="gist", + ) + op.create_table( + "publication", + sa.Column("title", sa.Text(), nullable=False), + sa.Column("abstract", sa.Text(), nullable=True), + sa.Column("doi", sa.String(), nullable=True), + sa.Column("year", sa.Integer(), nullable=True), + sa.Column("publisher", sa.String(), nullable=True), + sa.Column("url", sa.String(), nullable=True), + sa.Column("publication_type", sa.String(length=100), nullable=False), + sa.Column( + "search_vector", + sqlalchemy_utils.types.ts_vector.TSVectorType(), + nullable=True, + ), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.ForeignKeyConstraint( + ["publication_type"], + ["lexicon_term.term"], + ), + sa.PrimaryKeyConstraint("id"), + sa.UniqueConstraint("doi"), + ) + op.create_index( + "ix_publication_search_vector", + "publication", + ["search_vector"], + unique=False, + postgresql_using="gin", + ) + op.create_table( + "thing", + sa.Column("name", sa.String(length=255), nullable=False), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.Column("release_status", sa.String(length=100), nullable=True), + sa.ForeignKeyConstraint( + ["release_status"], + ["lexicon_term.term"], + ), + sa.PrimaryKeyConstraint("id"), + ) + op.create_table( + "address", + sa.Column("contact_id", sa.Integer(), nullable=False), + sa.Column("address_line_1", sa.String(length=255), nullable=False), + sa.Column("address_line_2", sa.String(length=255), nullable=True), + sa.Column("city", sa.String(length=100), nullable=False), + sa.Column("state", sa.String(length=50), nullable=False), + sa.Column("postal_code", sa.String(length=20), nullable=False), + sa.Column("country", sa.String(length=100), nullable=True), + sa.Column("address_type", sa.String(length=100), nullable=True), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.ForeignKeyConstraint( + ["address_type"], + ["lexicon_term.term"], + ), + sa.ForeignKeyConstraint(["contact_id"], ["contact.id"], ondelete="CASCADE"), + sa.PrimaryKeyConstraint("id"), + ) + op.create_table( + "asset_thing_association", + sa.Column("asset_id", sa.Integer(), nullable=False), + sa.Column("thing_id", sa.Integer(), nullable=False), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.ForeignKeyConstraint(["asset_id"], ["asset.id"], ondelete="CASCADE"), + sa.ForeignKeyConstraint(["thing_id"], ["thing.id"], ondelete="CASCADE"), + sa.PrimaryKeyConstraint("id"), + ) + op.create_table( + "email", + sa.Column("contact_id", sa.Integer(), nullable=False), + sa.Column("email", sa.String(length=100), nullable=False), + sa.Column("email_type", sa.String(length=100), nullable=True), + sa.Column( + "search_vector", + sqlalchemy_utils.types.ts_vector.TSVectorType(), + nullable=True, + ), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.ForeignKeyConstraint(["contact_id"], ["contact.id"], ondelete="CASCADE"), + sa.ForeignKeyConstraint( + ["email_type"], + ["lexicon_term.term"], + ), + sa.PrimaryKeyConstraint("id"), + ) + op.create_index( + "ix_email_search_vector", + "email", + ["search_vector"], + unique=False, + postgresql_using="gin", + ) + op.create_table( + "location_thing_association", + sa.Column("location_id", sa.Integer(), nullable=False), + sa.Column("thing_id", sa.Integer(), nullable=False), + sa.Column( + "effective_start", + sa.DateTime(), + server_default=sa.text("now()"), + nullable=False, + ), + sa.Column("effective_end", sa.DateTime(), nullable=True), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.ForeignKeyConstraint(["location_id"], ["location.id"], ondelete="CASCADE"), + sa.ForeignKeyConstraint(["thing_id"], ["thing.id"], ondelete="CASCADE"), + sa.PrimaryKeyConstraint("location_id", "thing_id", "id"), + ) + op.create_table( + "phone", + sa.Column("contact_id", sa.Integer(), nullable=False), + sa.Column("phone_number", sa.String(length=20), nullable=False), + sa.Column("phone_type", sa.String(length=100), nullable=True), + sa.Column( + "search_vector", + sqlalchemy_utils.types.ts_vector.TSVectorType(), + nullable=True, + ), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.ForeignKeyConstraint(["contact_id"], ["contact.id"], ondelete="CASCADE"), + sa.ForeignKeyConstraint( + ["phone_type"], + ["lexicon_term.term"], + ), + sa.PrimaryKeyConstraint("id"), + ) + op.create_index( + "ix_phone_search_vector", + "phone", + ["search_vector"], + unique=False, + postgresql_using="gin", + ) + op.create_table( + "pub_author_contact_association", + sa.Column("author_id", sa.Integer(), nullable=False), + sa.Column("contact_id", sa.Integer(), nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.ForeignKeyConstraint(["author_id"], ["pub_author.id"], ondelete="CASCADE"), + sa.ForeignKeyConstraint(["contact_id"], ["contact.id"], ondelete="CASCADE"), + sa.PrimaryKeyConstraint("author_id", "contact_id"), + ) + op.create_table( + "pub_author_publication_association", + sa.Column("publication_id", sa.Integer(), nullable=False), + sa.Column("author_id", sa.Integer(), nullable=False), + sa.Column("author_order", sa.Integer(), nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.ForeignKeyConstraint(["author_id"], ["pub_author.id"], ondelete="CASCADE"), + sa.ForeignKeyConstraint( + ["publication_id"], ["publication.id"], ondelete="CASCADE" + ), + sa.PrimaryKeyConstraint("publication_id", "author_id"), + ) + op.create_table( + "series", + sa.Column("observed_property", sa.String(length=100), nullable=False), + sa.Column("unit", sa.String(length=100), nullable=False), + sa.Column("name", sa.String(length=255), nullable=False), + sa.Column("description", sa.Text(), nullable=True), + sa.Column("sensor_id", sa.Integer(), nullable=True), + sa.Column("thing_id", sa.Integer(), nullable=False), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.Column("release_status", sa.String(length=100), nullable=True), + sa.ForeignKeyConstraint( + ["observed_property"], + ["lexicon_term.term"], + ), + sa.ForeignKeyConstraint( + ["release_status"], + ["lexicon_term.term"], + ), + sa.ForeignKeyConstraint(["sensor_id"], ["sensor.id"], ondelete="CASCADE"), + sa.ForeignKeyConstraint(["thing_id"], ["thing.id"], ondelete="CASCADE"), + sa.ForeignKeyConstraint( + ["unit"], + ["lexicon_term.term"], + ), + sa.PrimaryKeyConstraint("id"), + ) + op.create_table( + "spring_thing", + sa.Column("description", sa.String(length=255), nullable=True), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.Column("thing_id", sa.Integer(), nullable=False), + sa.ForeignKeyConstraint(["thing_id"], ["thing.id"], ondelete="CASCADE"), + sa.PrimaryKeyConstraint("id"), + sa.UniqueConstraint("thing_id"), + ) + op.create_table( + "thing_contact_association", + sa.Column("thing_id", sa.Integer(), nullable=False), + sa.Column("contact_id", sa.Integer(), nullable=False), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.ForeignKeyConstraint( + ["contact_id"], + ["contact.id"], + ), + sa.ForeignKeyConstraint( + ["thing_id"], + ["thing.id"], + ), + sa.PrimaryKeyConstraint("id"), + ) + op.create_table( + "thing_id_link", + sa.Column("thing_id", sa.Integer(), nullable=True), + sa.Column("relation", sa.String(length=100), nullable=False), + sa.Column("alternate_id", sa.String(length=100), nullable=False), + sa.Column("alternate_organization", sa.String(length=100), nullable=False), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.ForeignKeyConstraint( + ["alternate_organization"], + ["lexicon_term.term"], + ), + sa.ForeignKeyConstraint( + ["relation"], + ["lexicon_term.term"], + ), + sa.ForeignKeyConstraint(["thing_id"], ["thing.id"], ondelete="CASCADE"), + sa.PrimaryKeyConstraint("id"), + ) + op.create_table( + "well_thing", + sa.Column("well_depth", sa.Float(), nullable=True), + sa.Column("hole_depth", sa.Float(), nullable=True), + sa.Column("well_type", sa.String(length=100), nullable=True), + sa.Column("casing_diameter", sa.Float(), nullable=True), + sa.Column("casing_depth", sa.Float(), nullable=True), + sa.Column("casing_description", sa.String(length=50), nullable=True), + sa.Column("construction_notes", sa.String(length=250), nullable=True), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.Column("thing_id", sa.Integer(), nullable=False), + sa.ForeignKeyConstraint(["thing_id"], ["thing.id"], ondelete="CASCADE"), + sa.ForeignKeyConstraint( + ["well_type"], + ["lexicon_term.term"], + ), + sa.PrimaryKeyConstraint("id"), + sa.UniqueConstraint("thing_id"), + ) + op.create_table( + "collaborative_network_well", + sa.Column("actively_monitored", sa.Boolean(), nullable=False), + sa.Column("well_id", sa.Integer(), nullable=False), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.ForeignKeyConstraint(["well_id"], ["well_thing.id"], ondelete="CASCADE"), + sa.PrimaryKeyConstraint("id"), + ) + op.create_table( + "geochemical_series", + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.Column("series_id", sa.Integer(), nullable=False), + sa.ForeignKeyConstraint(["series_id"], ["series.id"], ondelete="CASCADE"), + sa.PrimaryKeyConstraint("id"), + sa.UniqueConstraint("series_id"), + ) + op.create_table( + "geothermal_series", + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.Column("series_id", sa.Integer(), nullable=False), + sa.ForeignKeyConstraint(["series_id"], ["series.id"], ondelete="CASCADE"), + sa.PrimaryKeyConstraint("id"), + sa.UniqueConstraint("series_id"), + ) + op.create_table( + "groundwater_level_series", + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.Column("series_id", sa.Integer(), nullable=False), + sa.ForeignKeyConstraint(["series_id"], ["series.id"], ondelete="CASCADE"), + sa.PrimaryKeyConstraint("id"), + sa.UniqueConstraint("series_id"), + ) + op.create_table( + "well_screen", + sa.Column("well_id", sa.Integer(), nullable=False), + sa.Column("screen_depth_top", sa.Float(), nullable=False), + sa.Column("screen_depth_bottom", sa.Float(), nullable=False), + sa.Column("screen_type", sa.String(length=100), nullable=True), + sa.Column("id", sa.Integer(), autoincrement=True, nullable=False), + sa.Column( + "created_at", sa.DateTime(), server_default=sa.text("now()"), nullable=False + ), + sa.ForeignKeyConstraint( + ["screen_type"], + ["lexicon_term.term"], + ), + sa.ForeignKeyConstraint(["well_id"], ["well_thing.id"], ondelete="CASCADE"), + sa.PrimaryKeyConstraint("id"), + ) + # ### end Alembic commands ### + + +def downgrade() -> None: + """Downgrade schema.""" + # ### commands auto generated by Alembic - please adjust! ### + op.drop_table("well_screen") + op.drop_table("groundwater_level_series") + op.drop_table("geothermal_series") + op.drop_table("geochemical_series") + op.drop_table("collaborative_network_well") + op.drop_table("well_thing") + op.drop_table("thing_id_link") + op.drop_table("thing_contact_association") + op.drop_table("spring_thing") + op.drop_table("series") + op.drop_table("pub_author_publication_association") + op.drop_table("pub_author_contact_association") + op.drop_index("ix_phone_search_vector", table_name="phone", postgresql_using="gin") + op.drop_table("phone") + op.drop_table("location_thing_association") + op.drop_index("ix_email_search_vector", table_name="email", postgresql_using="gin") + op.drop_table("email") + op.drop_table("asset_thing_association") + op.drop_table("address") + op.drop_table("thing") + op.drop_index( + "ix_publication_search_vector", table_name="publication", postgresql_using="gin" + ) + op.drop_table("publication") + op.drop_index("idx_location_point", table_name="location", postgresql_using="gist") + op.drop_table("location") + op.drop_table("lexicon_triple") + op.drop_table("lexicon_term_category_association") + op.drop_table("groundwater_level_sensor") + op.drop_table("geochronology_age") + op.drop_index( + "ix_contact_search_vector", table_name="contact", postgresql_using="gin" + ) + op.drop_table("contact") + op.drop_table("user") + op.drop_table("sensor") + op.drop_index( + "ix_pub_author_search_vector", table_name="pub_author", postgresql_using="gin" + ) + op.drop_table("pub_author") + op.drop_table("lexicon_term") + op.drop_table("lexicon_category") + op.drop_index("ix_asset_search_vector", table_name="asset", postgresql_using="gin") + op.drop_table("asset") + # ### end Alembic commands ### From 3f07e523c5b2f6ccd1632168397bed843b90697a Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Tue, 22 Jul 2025 11:14:10 -0600 Subject: [PATCH 21/38] fix: drop idx_location_point index if exists This commit ensures that the index `idx_location_point` is dropped if it exists before creating a new one. This prevents errors during migrations when the index already exists. This is particularly useful in environments where the database schema may have been modified manually or by previous migrations. This change is part of the initial migration setup to ensure a clean state for the `location` --- alembic/versions/fb089dbbfc43_initial_migration.py | 1 + 1 file changed, 1 insertion(+) diff --git a/alembic/versions/fb089dbbfc43_initial_migration.py b/alembic/versions/fb089dbbfc43_initial_migration.py index 91d060b2b..cf2c63289 100644 --- a/alembic/versions/fb089dbbfc43_initial_migration.py +++ b/alembic/versions/fb089dbbfc43_initial_migration.py @@ -225,6 +225,7 @@ def upgrade() -> None: ), sa.PrimaryKeyConstraint("id"), ) + op.execute("DROP INDEX IF EXISTS idx_location_point;") op.create_index( "idx_location_point", "location", From bdac0f30a032cd344d197f42ce5dff18af87f4fb Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Tue, 22 Jul 2025 11:18:00 -0600 Subject: [PATCH 22/38] fix: avoid creating migration scripts in docker --- entrypoint.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/entrypoint.sh b/entrypoint.sh index 74677e414..1a59b1afc 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -5,8 +5,6 @@ until PGPASSWORD="$POSTGRES_PASSWORD" pg_isready -h db -p 5432 -U "$POSTGRES_USE sleep 2 done -echo "Creating initial migration script..." -alembic revision --autogenerate -m "Initial migration" echo "Applying migrations..." alembic upgrade head echo "Starting the application..." From 42fcbda145f0a8495f281e037d73110e486835e8 Mon Sep 17 00:00:00 2001 From: jacob-a-brown Date: Tue, 22 Jul 2025 17:18:53 +0000 Subject: [PATCH 23/38] Formatting changes --- alembic/versions/fb089dbbfc43_initial_migration.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/alembic/versions/fb089dbbfc43_initial_migration.py b/alembic/versions/fb089dbbfc43_initial_migration.py index cf2c63289..15c1e9789 100644 --- a/alembic/versions/fb089dbbfc43_initial_migration.py +++ b/alembic/versions/fb089dbbfc43_initial_migration.py @@ -1,7 +1,7 @@ """Initial migration Revision ID: fb089dbbfc43 -Revises: +Revises: Create Date: 2025-07-22 11:12:10.398798 """ From 6dc752894335d1a77ccec867a36f846361d62125 Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Tue, 22 Jul 2025 11:33:28 -0600 Subject: [PATCH 24/38] fix: make alembic migrations compatible with PostGIS and TIGER tables Use flexible include_object function to exclude specific tables from migrations. Ensure entrypoint script is executable and correctly handles database migrations. --- alembic/env.py | 48 ++----------------- ...n.py => 5901f059248a_initial_migration.py} | 7 ++- 2 files changed, 7 insertions(+), 48 deletions(-) rename alembic/versions/{fb089dbbfc43_initial_migration.py => 5901f059248a_initial_migration.py} (99%) diff --git a/alembic/env.py b/alembic/env.py index d108967dd..cd838231d 100644 --- a/alembic/env.py +++ b/alembic/env.py @@ -24,6 +24,7 @@ # target_metadata = mymodel.Base.metadata target_metadata = Base.metadata +model_tables = set(target_metadata.tables.keys()) # other values from the config, defined by the needs of env.py, # can be acquired: @@ -43,50 +44,9 @@ def include_object(object, name, type_, reflected, compare_to): - # List of tables to exclude from Alembic autogenerate - # these tables are created by PostGIS and TIGER geocoder - # and should not be included in migration upgrades or downgrades - excluded_tables = { - "loader_lookuptables", - "addr", - "county", - "featnames", - "state_lookup", - "place_lookup", - "zip_state", - "secondary_unit_lookup", - "state", - "addrfeat", - "direction_lookup", - "faces", - "bg", - "zip_lookup_all", - "cousub", - "pagc_rules", - "zcta5", - "zip_lookup", - "county_lookup", - "edges", - "tabblock20", - "loader_variables", - "pagc_gaz", - "street_type_lookup", - "geocode_settings_default", - "geocode_settings", - "zip_state_loc", - "tract", - "tabblock", - "spatial_ref_sys", - "topology", - "pagc_lex", - "loader_platform", - "zip_lookup_base", - "place", - "countysub_lookup", - "layer", - } - if type_ == "table" and name in excluded_tables: - return False + # only include tables in sql alchemy model, not auto-generated tables from PostGIS or TIGER + if type_ == "table": + return name in model_tables return True diff --git a/alembic/versions/fb089dbbfc43_initial_migration.py b/alembic/versions/5901f059248a_initial_migration.py similarity index 99% rename from alembic/versions/fb089dbbfc43_initial_migration.py rename to alembic/versions/5901f059248a_initial_migration.py index cf2c63289..9d764f543 100644 --- a/alembic/versions/fb089dbbfc43_initial_migration.py +++ b/alembic/versions/5901f059248a_initial_migration.py @@ -1,8 +1,8 @@ """Initial migration -Revision ID: fb089dbbfc43 +Revision ID: 5901f059248a Revises: -Create Date: 2025-07-22 11:12:10.398798 +Create Date: 2025-07-22 11:32:48.826352 """ @@ -15,7 +15,7 @@ # revision identifiers, used by Alembic. -revision: str = "fb089dbbfc43" +revision: str = "5901f059248a" down_revision: Union[str, Sequence[str], None] = None branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None @@ -225,7 +225,6 @@ def upgrade() -> None: ), sa.PrimaryKeyConstraint("id"), ) - op.execute("DROP INDEX IF EXISTS idx_location_point;") op.create_index( "idx_location_point", "location", From 458c110607f1dbf6620e69c550fbf56dc14915f7 Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Tue, 22 Jul 2025 11:34:22 -0600 Subject: [PATCH 25/38] fix: drop index if exists before creating it This commit ensures that the index `idx_location_point` is dropped if it exists before attempting to create it again. This prevents errors during migrations when the index already exists. This change is made in the Alembic migration script `5901f059248a_initial_migration.py` and the Dockerfile for the application. --- alembic/versions/5901f059248a_initial_migration.py | 1 + 1 file changed, 1 insertion(+) diff --git a/alembic/versions/5901f059248a_initial_migration.py b/alembic/versions/5901f059248a_initial_migration.py index 9d764f543..8332c75f1 100644 --- a/alembic/versions/5901f059248a_initial_migration.py +++ b/alembic/versions/5901f059248a_initial_migration.py @@ -225,6 +225,7 @@ def upgrade() -> None: ), sa.PrimaryKeyConstraint("id"), ) + op.execute("DROP INDEX IF EXISTS idx_location_point;") op.create_index( "idx_location_point", "location", From d6d622c4d01c20b6703a0f26ab6a2056002ba7a1 Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Tue, 22 Jul 2025 11:56:38 -0600 Subject: [PATCH 26/38] fix: keep sh script endings LF --- .gitattributes | 1 + entrypoint.sh | 1 + 2 files changed, 2 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..526c8a38d --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.sh text eol=lf \ No newline at end of file diff --git a/entrypoint.sh b/entrypoint.sh index 1a59b1afc..995a2adb1 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -4,6 +4,7 @@ until PGPASSWORD="$POSTGRES_PASSWORD" pg_isready -h db -p 5432 -U "$POSTGRES_USE echo "Waiting for postgres..." sleep 2 done +echo "PostgreSQL is ready!" echo "Applying migrations..." alembic upgrade head From a2ceeb04d0662df309e891ebf7c2d16c9cbc5b27 Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Tue, 22 Jul 2025 11:56:54 -0600 Subject: [PATCH 27/38] fix: use .env POSTGRES_HOST for local env, db for docker This allows the migration scripts to be created with the correct database host depending on the environment. --- alembic/env.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/alembic/env.py b/alembic/env.py index cd838231d..88380f40a 100644 --- a/alembic/env.py +++ b/alembic/env.py @@ -33,13 +33,20 @@ load_dotenv() -user = environ.get("POSTGRES_USER", None) -password = environ.get("POSTGRES_PASSWORD", None) -db = environ.get("POSTGRES_DB", None) -host = environ.get("POSTGRES_HOST", None) -port = environ.get("POSTGRES_PORT", None) +db_url = environ.get("DATABASE_URL", None) +if db_url: + SQLALCHEMY_DATABASE_URL = db_url +else: + # Fallback to environment variables for PostgreSQL connection + user = environ.get("POSTGRES_USER", None) + password = environ.get("POSTGRES_PASSWORD", None) + db = environ.get("POSTGRES_DB", None) + host = environ.get("POSTGRES_HOST", None) + port = environ.get("POSTGRES_PORT", None) + SQLALCHEMY_DATABASE_URL = ( + f"postgresql+psycopg2://{user}:{password}@{host}:{port}/{db}" + ) -SQLALCHEMY_DATABASE_URL = f"postgresql+psycopg2://{user}:{password}@{host}:{port}/{db}" config.set_main_option("sqlalchemy.url", SQLALCHEMY_DATABASE_URL) From 417290eb854f732b98e88d2680854f60b1af8b37 Mon Sep 17 00:00:00 2001 From: jacob-a-brown Date: Tue, 22 Jul 2025 17:57:57 +0000 Subject: [PATCH 28/38] Formatting changes --- alembic/versions/5901f059248a_initial_migration.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/alembic/versions/5901f059248a_initial_migration.py b/alembic/versions/5901f059248a_initial_migration.py index 8332c75f1..7a8ee7cb9 100644 --- a/alembic/versions/5901f059248a_initial_migration.py +++ b/alembic/versions/5901f059248a_initial_migration.py @@ -1,7 +1,7 @@ """Initial migration Revision ID: 5901f059248a -Revises: +Revises: Create Date: 2025-07-22 11:32:48.826352 """ From 3b4dcb5fdf2d6cff69f3a51ca71ad89f5d8cb06a Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Tue, 22 Jul 2025 12:05:54 -0600 Subject: [PATCH 29/38] feat: add pre-commit to pyproject --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 9bcafb8d4..722ff443e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -59,6 +59,7 @@ dependencies = [ "phonenumbers==9.0.8", "pillow==11.3.0", "pluggy==1.6.0", + "pre-commit==4.2.0", "propcache==0.3.2", "proto-plus==1.26.1", "protobuf==6.31.1", From fa4205e2e64a306843e87e556dbe5d013055588c Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Tue, 22 Jul 2025 12:10:41 -0600 Subject: [PATCH 30/38] fix: update uv.lock --- uv.lock | 224 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 117 insertions(+), 107 deletions(-) diff --git a/uv.lock b/uv.lock index 2a7d10e85..692106725 100644 --- a/uv.lock +++ b/uv.lock @@ -80,16 +80,16 @@ wheels = [ [[package]] name = "alembic" -version = "1.16.1" +version = "1.16.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mako" }, { name = "sqlalchemy" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/20/89/bfb4fe86e3fc3972d35431af7bedbc60fa606e8b17196704a1747f7aa4c3/alembic-1.16.1.tar.gz", hash = "sha256:43d37ba24b3d17bc1eb1024fe0f51cd1dc95aeb5464594a02c6bb9ca9864bfa4", size = 1955006, upload-time = "2025-05-21T23:11:05.991Z" } +sdist = { url = "https://files.pythonhosted.org/packages/9c/35/116797ff14635e496bbda0c168987f5326a6555b09312e9b817e360d1f56/alembic-1.16.2.tar.gz", hash = "sha256:e53c38ff88dadb92eb22f8b150708367db731d58ad7e9d417c9168ab516cbed8", size = 1963563, upload-time = "2025-06-16T18:05:08.566Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/31/59/565286efff3692c5716c212202af61466480f6357c4ae3089d4453bff1f3/alembic-1.16.1-py3-none-any.whl", hash = "sha256:0cdd48acada30d93aa1035767d67dff25702f8de74d7c3919f2e8492c8db2e67", size = 242488, upload-time = "2025-05-21T23:11:07.783Z" }, + { url = "https://files.pythonhosted.org/packages/dd/e2/88e425adac5ad887a087c38d04fe2030010572a3e0e627f8a6e8c33eeda8/alembic-1.16.2-py3-none-any.whl", hash = "sha256:5f42e9bd0afdbd1d5e3ad856c01754530367debdebf21ed6894e34af52b3bb03", size = 242717, upload-time = "2025-06-16T18:05:10.27Z" }, ] [[package]] @@ -159,14 +159,14 @@ wheels = [ [[package]] name = "authlib" -version = "1.6.0" +version = "1.6.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cryptography" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a2/9d/b1e08d36899c12c8b894a44a5583ee157789f26fc4b176f8e4b6217b56e1/authlib-1.6.0.tar.gz", hash = "sha256:4367d32031b7af175ad3a323d571dc7257b7099d55978087ceae4a0d88cd3210", size = 158371, upload-time = "2025-05-23T00:21:45.011Z" } +sdist = { url = "https://files.pythonhosted.org/packages/8e/a1/d8d1c6f8bc922c0b87ae0d933a8ed57be1bef6970894ed79c2852a153cd3/authlib-1.6.1.tar.gz", hash = "sha256:4dffdbb1460ba6ec8c17981a4c67af7d8af131231b5a36a88a1e8c80c111cdfd", size = 159988, upload-time = "2025-07-20T07:38:42.834Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/84/29/587c189bbab1ccc8c86a03a5d0e13873df916380ef1be461ebe6acebf48d/authlib-1.6.0-py2.py3-none-any.whl", hash = "sha256:91685589498f79e8655e8a8947431ad6288831d643f11c55c2143ffcc738048d", size = 239981, upload-time = "2025-05-23T00:21:43.075Z" }, + { url = "https://files.pythonhosted.org/packages/f9/58/cc6a08053f822f98f334d38a27687b69c6655fb05cd74a7a5e70a2aeed95/authlib-1.6.1-py2.py3-none-any.whl", hash = "sha256:e9d2031c34c6309373ab845afc24168fe9e93dc52d252631f52642f21f5ed06e", size = 239299, upload-time = "2025-07-20T07:38:39.259Z" }, ] [[package]] @@ -230,11 +230,11 @@ wheels = [ [[package]] name = "certifi" -version = "2025.4.26" +version = "2025.6.15" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e8/9e/c05b3920a3b7d20d3d3310465f50348e5b3694f4f88c6daf736eef3024c4/certifi-2025.4.26.tar.gz", hash = "sha256:0a816057ea3cdefcef70270d2c515e4506bbc954f417fa5ade2021213bb8f0c6", size = 160705, upload-time = "2025-04-26T02:12:29.51Z" } +sdist = { url = "https://files.pythonhosted.org/packages/73/f7/f14b46d4bcd21092d7d3ccef689615220d8a08fb25e564b65d20738e672e/certifi-2025.6.15.tar.gz", hash = "sha256:d747aa5a8b9bbbb1bb8c22bb13e22bd1f18e9796defa16bab421f7f7a317323b", size = 158753, upload-time = "2025-06-15T02:45:51.329Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4a/7e/3db2bd1b1f9e95f7cddca6d6e75e2f2bd9f51b1246e546d88addca0106bd/certifi-2025.4.26-py3-none-any.whl", hash = "sha256:30350364dfe371162649852c63336a15c70c6510c2ad5015b21c2345311805f3", size = 159618, upload-time = "2025-04-26T02:12:27.662Z" }, + { url = "https://files.pythonhosted.org/packages/84/ae/320161bd181fc06471eed047ecce67b693fd7515b16d495d8932db763426/certifi-2025.6.15-py3-none-any.whl", hash = "sha256:2e0c7ce7cb5d8f8634ca55d2ba7e6ec2689a2fd6537d8dec1296a477a4910057", size = 157650, upload-time = "2025-06-15T02:45:49.977Z" }, ] [[package]] @@ -330,46 +330,46 @@ wheels = [ [[package]] name = "cryptography" -version = "45.0.4" +version = "45.0.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fe/c8/a2a376a8711c1e11708b9c9972e0c3223f5fc682552c82d8db844393d6ce/cryptography-45.0.4.tar.gz", hash = "sha256:7405ade85c83c37682c8fe65554759800a4a8c54b2d96e0f8ad114d31b808d57", size = 744890, upload-time = "2025-06-10T00:03:51.297Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/cc/1c/92637793de053832523b410dbe016d3f5c11b41d0cf6eef8787aabb51d41/cryptography-45.0.4-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:425a9a6ac2823ee6e46a76a21a4e8342d8fa5c01e08b823c1f19a8b74f096069", size = 7055712, upload-time = "2025-06-10T00:02:38.826Z" }, - { url = "https://files.pythonhosted.org/packages/ba/14/93b69f2af9ba832ad6618a03f8a034a5851dc9a3314336a3d71c252467e1/cryptography-45.0.4-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:680806cf63baa0039b920f4976f5f31b10e772de42f16310a6839d9f21a26b0d", size = 4205335, upload-time = "2025-06-10T00:02:41.64Z" }, - { url = "https://files.pythonhosted.org/packages/67/30/fae1000228634bf0b647fca80403db5ca9e3933b91dd060570689f0bd0f7/cryptography-45.0.4-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4ca0f52170e821bc8da6fc0cc565b7bb8ff8d90d36b5e9fdd68e8a86bdf72036", size = 4431487, upload-time = "2025-06-10T00:02:43.696Z" }, - { url = "https://files.pythonhosted.org/packages/6d/5a/7dffcf8cdf0cb3c2430de7404b327e3db64735747d641fc492539978caeb/cryptography-45.0.4-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:f3fe7a5ae34d5a414957cc7f457e2b92076e72938423ac64d215722f6cf49a9e", size = 4208922, upload-time = "2025-06-10T00:02:45.334Z" }, - { url = "https://files.pythonhosted.org/packages/c6/f3/528729726eb6c3060fa3637253430547fbaaea95ab0535ea41baa4a6fbd8/cryptography-45.0.4-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:25eb4d4d3e54595dc8adebc6bbd5623588991d86591a78c2548ffb64797341e2", size = 3900433, upload-time = "2025-06-10T00:02:47.359Z" }, - { url = "https://files.pythonhosted.org/packages/d9/4a/67ba2e40f619e04d83c32f7e1d484c1538c0800a17c56a22ff07d092ccc1/cryptography-45.0.4-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:ce1678a2ccbe696cf3af15a75bb72ee008d7ff183c9228592ede9db467e64f1b", size = 4464163, upload-time = "2025-06-10T00:02:49.412Z" }, - { url = "https://files.pythonhosted.org/packages/7e/9a/b4d5aa83661483ac372464809c4b49b5022dbfe36b12fe9e323ca8512420/cryptography-45.0.4-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:49fe9155ab32721b9122975e168a6760d8ce4cffe423bcd7ca269ba41b5dfac1", size = 4208687, upload-time = "2025-06-10T00:02:50.976Z" }, - { url = "https://files.pythonhosted.org/packages/db/b7/a84bdcd19d9c02ec5807f2ec2d1456fd8451592c5ee353816c09250e3561/cryptography-45.0.4-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:2882338b2a6e0bd337052e8b9007ced85c637da19ef9ecaf437744495c8c2999", size = 4463623, upload-time = "2025-06-10T00:02:52.542Z" }, - { url = "https://files.pythonhosted.org/packages/d8/84/69707d502d4d905021cac3fb59a316344e9f078b1da7fb43ecde5e10840a/cryptography-45.0.4-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:23b9c3ea30c3ed4db59e7b9619272e94891f8a3a5591d0b656a7582631ccf750", size = 4332447, upload-time = "2025-06-10T00:02:54.63Z" }, - { url = "https://files.pythonhosted.org/packages/f3/ee/d4f2ab688e057e90ded24384e34838086a9b09963389a5ba6854b5876598/cryptography-45.0.4-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b0a97c927497e3bc36b33987abb99bf17a9a175a19af38a892dc4bbb844d7ee2", size = 4572830, upload-time = "2025-06-10T00:02:56.689Z" }, - { url = "https://files.pythonhosted.org/packages/70/d4/994773a261d7ff98034f72c0e8251fe2755eac45e2265db4c866c1c6829c/cryptography-45.0.4-cp311-abi3-win32.whl", hash = "sha256:e00a6c10a5c53979d6242f123c0a97cff9f3abed7f064fc412c36dc521b5f257", size = 2932769, upload-time = "2025-06-10T00:02:58.467Z" }, - { url = "https://files.pythonhosted.org/packages/5a/42/c80bd0b67e9b769b364963b5252b17778a397cefdd36fa9aa4a5f34c599a/cryptography-45.0.4-cp311-abi3-win_amd64.whl", hash = "sha256:817ee05c6c9f7a69a16200f0c90ab26d23a87701e2a284bd15156783e46dbcc8", size = 3410441, upload-time = "2025-06-10T00:03:00.14Z" }, - { url = "https://files.pythonhosted.org/packages/ce/0b/2488c89f3a30bc821c9d96eeacfcab6ff3accc08a9601ba03339c0fd05e5/cryptography-45.0.4-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:964bcc28d867e0f5491a564b7debb3ffdd8717928d315d12e0d7defa9e43b723", size = 7031836, upload-time = "2025-06-10T00:03:01.726Z" }, - { url = "https://files.pythonhosted.org/packages/fe/51/8c584ed426093aac257462ae62d26ad61ef1cbf5b58d8b67e6e13c39960e/cryptography-45.0.4-cp37-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:6a5bf57554e80f75a7db3d4b1dacaa2764611ae166ab42ea9a72bcdb5d577637", size = 4195746, upload-time = "2025-06-10T00:03:03.94Z" }, - { url = "https://files.pythonhosted.org/packages/5c/7d/4b0ca4d7af95a704eef2f8f80a8199ed236aaf185d55385ae1d1610c03c2/cryptography-45.0.4-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:46cf7088bf91bdc9b26f9c55636492c1cce3e7aaf8041bbf0243f5e5325cfb2d", size = 4424456, upload-time = "2025-06-10T00:03:05.589Z" }, - { url = "https://files.pythonhosted.org/packages/1d/45/5fabacbc6e76ff056f84d9f60eeac18819badf0cefc1b6612ee03d4ab678/cryptography-45.0.4-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:7bedbe4cc930fa4b100fc845ea1ea5788fcd7ae9562e669989c11618ae8d76ee", size = 4198495, upload-time = "2025-06-10T00:03:09.172Z" }, - { url = "https://files.pythonhosted.org/packages/55/b7/ffc9945b290eb0a5d4dab9b7636706e3b5b92f14ee5d9d4449409d010d54/cryptography-45.0.4-cp37-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:eaa3e28ea2235b33220b949c5a0d6cf79baa80eab2eb5607ca8ab7525331b9ff", size = 3885540, upload-time = "2025-06-10T00:03:10.835Z" }, - { url = "https://files.pythonhosted.org/packages/7f/e3/57b010282346980475e77d414080acdcb3dab9a0be63071efc2041a2c6bd/cryptography-45.0.4-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:7ef2dde4fa9408475038fc9aadfc1fb2676b174e68356359632e980c661ec8f6", size = 4452052, upload-time = "2025-06-10T00:03:12.448Z" }, - { url = "https://files.pythonhosted.org/packages/37/e6/ddc4ac2558bf2ef517a358df26f45bc774a99bf4653e7ee34b5e749c03e3/cryptography-45.0.4-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:6a3511ae33f09094185d111160fd192c67aa0a2a8d19b54d36e4c78f651dc5ad", size = 4198024, upload-time = "2025-06-10T00:03:13.976Z" }, - { url = "https://files.pythonhosted.org/packages/3a/c0/85fa358ddb063ec588aed4a6ea1df57dc3e3bc1712d87c8fa162d02a65fc/cryptography-45.0.4-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:06509dc70dd71fa56eaa138336244e2fbaf2ac164fc9b5e66828fccfd2b680d6", size = 4451442, upload-time = "2025-06-10T00:03:16.248Z" }, - { url = "https://files.pythonhosted.org/packages/33/67/362d6ec1492596e73da24e669a7fbbaeb1c428d6bf49a29f7a12acffd5dc/cryptography-45.0.4-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:5f31e6b0a5a253f6aa49be67279be4a7e5a4ef259a9f33c69f7d1b1191939872", size = 4325038, upload-time = "2025-06-10T00:03:18.4Z" }, - { url = "https://files.pythonhosted.org/packages/53/75/82a14bf047a96a1b13ebb47fb9811c4f73096cfa2e2b17c86879687f9027/cryptography-45.0.4-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:944e9ccf67a9594137f942d5b52c8d238b1b4e46c7a0c2891b7ae6e01e7c80a4", size = 4560964, upload-time = "2025-06-10T00:03:20.06Z" }, - { url = "https://files.pythonhosted.org/packages/cd/37/1a3cba4c5a468ebf9b95523a5ef5651244693dc712001e276682c278fc00/cryptography-45.0.4-cp37-abi3-win32.whl", hash = "sha256:c22fe01e53dc65edd1945a2e6f0015e887f84ced233acecb64b4daadb32f5c97", size = 2924557, upload-time = "2025-06-10T00:03:22.563Z" }, - { url = "https://files.pythonhosted.org/packages/2a/4b/3256759723b7e66380397d958ca07c59cfc3fb5c794fb5516758afd05d41/cryptography-45.0.4-cp37-abi3-win_amd64.whl", hash = "sha256:627ba1bc94f6adf0b0a2e35d87020285ead22d9f648c7e75bb64f367375f3b22", size = 3395508, upload-time = "2025-06-10T00:03:24.586Z" }, +sdist = { url = "https://files.pythonhosted.org/packages/95/1e/49527ac611af559665f71cbb8f92b332b5ec9c6fbc4e88b0f8e92f5e85df/cryptography-45.0.5.tar.gz", hash = "sha256:72e76caa004ab63accdf26023fccd1d087f6d90ec6048ff33ad0445abf7f605a", size = 744903, upload-time = "2025-07-02T13:06:25.941Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f0/fb/09e28bc0c46d2c547085e60897fea96310574c70fb21cd58a730a45f3403/cryptography-45.0.5-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:101ee65078f6dd3e5a028d4f19c07ffa4dd22cce6a20eaa160f8b5219911e7d8", size = 7043092, upload-time = "2025-07-02T13:05:01.514Z" }, + { url = "https://files.pythonhosted.org/packages/b1/05/2194432935e29b91fb649f6149c1a4f9e6d3d9fc880919f4ad1bcc22641e/cryptography-45.0.5-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3a264aae5f7fbb089dbc01e0242d3b67dffe3e6292e1f5182122bdf58e65215d", size = 4205926, upload-time = "2025-07-02T13:05:04.741Z" }, + { url = "https://files.pythonhosted.org/packages/07/8b/9ef5da82350175e32de245646b1884fc01124f53eb31164c77f95a08d682/cryptography-45.0.5-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e74d30ec9c7cb2f404af331d5b4099a9b322a8a6b25c4632755c8757345baac5", size = 4429235, upload-time = "2025-07-02T13:05:07.084Z" }, + { url = "https://files.pythonhosted.org/packages/7c/e1/c809f398adde1994ee53438912192d92a1d0fc0f2d7582659d9ef4c28b0c/cryptography-45.0.5-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:3af26738f2db354aafe492fb3869e955b12b2ef2e16908c8b9cb928128d42c57", size = 4209785, upload-time = "2025-07-02T13:05:09.321Z" }, + { url = "https://files.pythonhosted.org/packages/d0/8b/07eb6bd5acff58406c5e806eff34a124936f41a4fb52909ffa4d00815f8c/cryptography-45.0.5-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e6c00130ed423201c5bc5544c23359141660b07999ad82e34e7bb8f882bb78e0", size = 3893050, upload-time = "2025-07-02T13:05:11.069Z" }, + { url = "https://files.pythonhosted.org/packages/ec/ef/3333295ed58d900a13c92806b67e62f27876845a9a908c939f040887cca9/cryptography-45.0.5-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:dd420e577921c8c2d31289536c386aaa30140b473835e97f83bc71ea9d2baf2d", size = 4457379, upload-time = "2025-07-02T13:05:13.32Z" }, + { url = "https://files.pythonhosted.org/packages/d9/9d/44080674dee514dbb82b21d6fa5d1055368f208304e2ab1828d85c9de8f4/cryptography-45.0.5-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:d05a38884db2ba215218745f0781775806bde4f32e07b135348355fe8e4991d9", size = 4209355, upload-time = "2025-07-02T13:05:15.017Z" }, + { url = "https://files.pythonhosted.org/packages/c9/d8/0749f7d39f53f8258e5c18a93131919ac465ee1f9dccaf1b3f420235e0b5/cryptography-45.0.5-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:ad0caded895a00261a5b4aa9af828baede54638754b51955a0ac75576b831b27", size = 4456087, upload-time = "2025-07-02T13:05:16.945Z" }, + { url = "https://files.pythonhosted.org/packages/09/d7/92acac187387bf08902b0bf0699816f08553927bdd6ba3654da0010289b4/cryptography-45.0.5-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9024beb59aca9d31d36fcdc1604dd9bbeed0a55bface9f1908df19178e2f116e", size = 4332873, upload-time = "2025-07-02T13:05:18.743Z" }, + { url = "https://files.pythonhosted.org/packages/03/c2/840e0710da5106a7c3d4153c7215b2736151bba60bf4491bdb421df5056d/cryptography-45.0.5-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:91098f02ca81579c85f66df8a588c78f331ca19089763d733e34ad359f474174", size = 4564651, upload-time = "2025-07-02T13:05:21.382Z" }, + { url = "https://files.pythonhosted.org/packages/2e/92/cc723dd6d71e9747a887b94eb3827825c6c24b9e6ce2bb33b847d31d5eaa/cryptography-45.0.5-cp311-abi3-win32.whl", hash = "sha256:926c3ea71a6043921050eaa639137e13dbe7b4ab25800932a8498364fc1abec9", size = 2929050, upload-time = "2025-07-02T13:05:23.39Z" }, + { url = "https://files.pythonhosted.org/packages/1f/10/197da38a5911a48dd5389c043de4aec4b3c94cb836299b01253940788d78/cryptography-45.0.5-cp311-abi3-win_amd64.whl", hash = "sha256:b85980d1e345fe769cfc57c57db2b59cff5464ee0c045d52c0df087e926fbe63", size = 3403224, upload-time = "2025-07-02T13:05:25.202Z" }, + { url = "https://files.pythonhosted.org/packages/fe/2b/160ce8c2765e7a481ce57d55eba1546148583e7b6f85514472b1d151711d/cryptography-45.0.5-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:f3562c2f23c612f2e4a6964a61d942f891d29ee320edb62ff48ffb99f3de9ae8", size = 7017143, upload-time = "2025-07-02T13:05:27.229Z" }, + { url = "https://files.pythonhosted.org/packages/c2/e7/2187be2f871c0221a81f55ee3105d3cf3e273c0a0853651d7011eada0d7e/cryptography-45.0.5-cp37-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3fcfbefc4a7f332dece7272a88e410f611e79458fab97b5efe14e54fe476f4fd", size = 4197780, upload-time = "2025-07-02T13:05:29.299Z" }, + { url = "https://files.pythonhosted.org/packages/b9/cf/84210c447c06104e6be9122661159ad4ce7a8190011669afceeaea150524/cryptography-45.0.5-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:460f8c39ba66af7db0545a8c6f2eabcbc5a5528fc1cf6c3fa9a1e44cec33385e", size = 4420091, upload-time = "2025-07-02T13:05:31.221Z" }, + { url = "https://files.pythonhosted.org/packages/3e/6a/cb8b5c8bb82fafffa23aeff8d3a39822593cee6e2f16c5ca5c2ecca344f7/cryptography-45.0.5-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:9b4cf6318915dccfe218e69bbec417fdd7c7185aa7aab139a2c0beb7468c89f0", size = 4198711, upload-time = "2025-07-02T13:05:33.062Z" }, + { url = "https://files.pythonhosted.org/packages/04/f7/36d2d69df69c94cbb2473871926daf0f01ad8e00fe3986ac3c1e8c4ca4b3/cryptography-45.0.5-cp37-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2089cc8f70a6e454601525e5bf2779e665d7865af002a5dec8d14e561002e135", size = 3883299, upload-time = "2025-07-02T13:05:34.94Z" }, + { url = "https://files.pythonhosted.org/packages/82/c7/f0ea40f016de72f81288e9fe8d1f6748036cb5ba6118774317a3ffc6022d/cryptography-45.0.5-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:0027d566d65a38497bc37e0dd7c2f8ceda73597d2ac9ba93810204f56f52ebc7", size = 4450558, upload-time = "2025-07-02T13:05:37.288Z" }, + { url = "https://files.pythonhosted.org/packages/06/ae/94b504dc1a3cdf642d710407c62e86296f7da9e66f27ab12a1ee6fdf005b/cryptography-45.0.5-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:be97d3a19c16a9be00edf79dca949c8fa7eff621763666a145f9f9535a5d7f42", size = 4198020, upload-time = "2025-07-02T13:05:39.102Z" }, + { url = "https://files.pythonhosted.org/packages/05/2b/aaf0adb845d5dabb43480f18f7ca72e94f92c280aa983ddbd0bcd6ecd037/cryptography-45.0.5-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:7760c1c2e1a7084153a0f68fab76e754083b126a47d0117c9ed15e69e2103492", size = 4449759, upload-time = "2025-07-02T13:05:41.398Z" }, + { url = "https://files.pythonhosted.org/packages/91/e4/f17e02066de63e0100a3a01b56f8f1016973a1d67551beaf585157a86b3f/cryptography-45.0.5-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:6ff8728d8d890b3dda5765276d1bc6fb099252915a2cd3aff960c4c195745dd0", size = 4319991, upload-time = "2025-07-02T13:05:43.64Z" }, + { url = "https://files.pythonhosted.org/packages/f2/2e/e2dbd629481b499b14516eed933f3276eb3239f7cee2dcfa4ee6b44d4711/cryptography-45.0.5-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:7259038202a47fdecee7e62e0fd0b0738b6daa335354396c6ddebdbe1206af2a", size = 4554189, upload-time = "2025-07-02T13:05:46.045Z" }, + { url = "https://files.pythonhosted.org/packages/f8/ea/a78a0c38f4c8736287b71c2ea3799d173d5ce778c7d6e3c163a95a05ad2a/cryptography-45.0.5-cp37-abi3-win32.whl", hash = "sha256:1e1da5accc0c750056c556a93c3e9cb828970206c68867712ca5805e46dc806f", size = 2911769, upload-time = "2025-07-02T13:05:48.329Z" }, + { url = "https://files.pythonhosted.org/packages/79/b3/28ac139109d9005ad3f6b6f8976ffede6706a6478e21c889ce36c840918e/cryptography-45.0.5-cp37-abi3-win_amd64.whl", hash = "sha256:90cb0a7bb35959f37e23303b7eed0a32280510030daba3f7fdfbb65defde6a97", size = 3390016, upload-time = "2025-07-02T13:05:50.811Z" }, ] [[package]] name = "distlib" -version = "0.3.9" +version = "0.4.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/0d/dd/1bec4c5ddb504ca60fc29472f3d27e8d4da1257a854e1d96742f15c1d02d/distlib-0.3.9.tar.gz", hash = "sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403", size = 613923, upload-time = "2024-10-09T18:35:47.551Z" } +sdist = { url = "https://files.pythonhosted.org/packages/96/8e/709914eb2b5749865801041647dc7f4e6d00b549cfe88b65ca192995f07c/distlib-0.4.0.tar.gz", hash = "sha256:feec40075be03a04501a973d81f633735b4b69f98b05450592310c0f401a4e0d", size = 614605, upload-time = "2025-07-17T16:52:00.465Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/91/a1/cf2472db20f7ce4a6be1253a81cfdf85ad9c7885ffbed7047fb72c24cf87/distlib-0.3.9-py2.py3-none-any.whl", hash = "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87", size = 468973, upload-time = "2024-10-09T18:35:44.272Z" }, + { url = "https://files.pythonhosted.org/packages/33/6b/e0547afaf41bf2c42e52430072fa5658766e3d65bd4b03a563d1b6336f57/distlib-0.4.0-py2.py3-none-any.whl", hash = "sha256:9659f7d87e46584a30b5780e43ac7a2143098441670ff0a49d5f9034c54a6c16", size = 469047, upload-time = "2025-07-17T16:51:58.613Z" }, ] [[package]] @@ -435,16 +435,16 @@ wheels = [ [[package]] name = "fastapi-pagination" -version = "0.13.2" +version = "0.13.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "fastapi" }, { name = "pydantic" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/19/25/fc3c9ed9d99df279acdbf57da1a3a91ffceae9c087882cbe8a9cb1229b1e/fastapi_pagination-0.13.2.tar.gz", hash = "sha256:5e76f129aef706601b86114428ca3ff68715bfa3929bf4df8c7ed27561d7f661", size = 550389, upload-time = "2025-06-07T09:30:44.319Z" } +sdist = { url = "https://files.pythonhosted.org/packages/10/4c/e98a1665b6ac2e9e4ed98450e4e0ea48108f3bc52de517d9a70cc22761c2/fastapi_pagination-0.13.3.tar.gz", hash = "sha256:40c2383aff13a3a0e4a2742dfbf004572e88458cd8f338d85f90a27e07abab4a", size = 550898, upload-time = "2025-06-25T21:22:15.287Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d9/cb/cf2f10d4620b31a77705226c7292f39b4a191cef3485ea42561fc2e157d9/fastapi_pagination-0.13.2-py3-none-any.whl", hash = "sha256:d2ec66ffda5cd9c1d665521f3916b16ebbb15d5010a945449292540ef70c4d9a", size = 50404, upload-time = "2025-06-07T09:30:42.218Z" }, + { url = "https://files.pythonhosted.org/packages/bf/73/ef1ab892c2d189d8b6bd72325e9e710df6737c3b7976e12aa5749a56ea01/fastapi_pagination-0.13.3-py3-none-any.whl", hash = "sha256:e1b1cc7fa5c773c61087845ef8a73ed6b516071c057418698b9242461573f44e", size = 50986, upload-time = "2025-06-25T21:22:13.591Z" }, ] [[package]] @@ -613,27 +613,26 @@ wheels = [ [[package]] name = "greenlet" -version = "3.2.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/34/c1/a82edae11d46c0d83481aacaa1e578fea21d94a1ef400afd734d47ad95ad/greenlet-3.2.2.tar.gz", hash = "sha256:ad053d34421a2debba45aa3cc39acf454acbcd025b3fc1a9f8a0dee237abd485", size = 185797, upload-time = "2025-05-09T19:47:35.066Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/89/30/97b49779fff8601af20972a62cc4af0c497c1504dfbb3e93be218e093f21/greenlet-3.2.2-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:3ab7194ee290302ca15449f601036007873028712e92ca15fc76597a0aeb4c59", size = 269150, upload-time = "2025-05-09T14:50:30.784Z" }, - { url = "https://files.pythonhosted.org/packages/21/30/877245def4220f684bc2e01df1c2e782c164e84b32e07373992f14a2d107/greenlet-3.2.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2dc5c43bb65ec3669452af0ab10729e8fdc17f87a1f2ad7ec65d4aaaefabf6bf", size = 637381, upload-time = "2025-05-09T15:24:12.893Z" }, - { url = "https://files.pythonhosted.org/packages/8e/16/adf937908e1f913856b5371c1d8bdaef5f58f251d714085abeea73ecc471/greenlet-3.2.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:decb0658ec19e5c1f519faa9a160c0fc85a41a7e6654b3ce1b44b939f8bf1325", size = 651427, upload-time = "2025-05-09T15:24:51.074Z" }, - { url = "https://files.pythonhosted.org/packages/ad/49/6d79f58fa695b618654adac64e56aff2eeb13344dc28259af8f505662bb1/greenlet-3.2.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6fadd183186db360b61cb34e81117a096bff91c072929cd1b529eb20dd46e6c5", size = 645795, upload-time = "2025-05-09T15:29:26.673Z" }, - { url = "https://files.pythonhosted.org/packages/5a/e6/28ed5cb929c6b2f001e96b1d0698c622976cd8f1e41fe7ebc047fa7c6dd4/greenlet-3.2.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1919cbdc1c53ef739c94cf2985056bcc0838c1f217b57647cbf4578576c63825", size = 648398, upload-time = "2025-05-09T14:53:36.61Z" }, - { url = "https://files.pythonhosted.org/packages/9d/70/b200194e25ae86bc57077f695b6cc47ee3118becf54130c5514456cf8dac/greenlet-3.2.2-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3885f85b61798f4192d544aac7b25a04ece5fe2704670b4ab73c2d2c14ab740d", size = 606795, upload-time = "2025-05-09T14:53:47.039Z" }, - { url = "https://files.pythonhosted.org/packages/f8/c8/ba1def67513a941154ed8f9477ae6e5a03f645be6b507d3930f72ed508d3/greenlet-3.2.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:85f3e248507125bf4af607a26fd6cb8578776197bd4b66e35229cdf5acf1dfbf", size = 1117976, upload-time = "2025-05-09T15:27:06.542Z" }, - { url = "https://files.pythonhosted.org/packages/c3/30/d0e88c1cfcc1b3331d63c2b54a0a3a4a950ef202fb8b92e772ca714a9221/greenlet-3.2.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:1e76106b6fc55fa3d6fe1c527f95ee65e324a13b62e243f77b48317346559708", size = 1145509, upload-time = "2025-05-09T14:54:02.223Z" }, - { url = "https://files.pythonhosted.org/packages/90/2e/59d6491834b6e289051b252cf4776d16da51c7c6ca6a87ff97e3a50aa0cd/greenlet-3.2.2-cp313-cp313-win_amd64.whl", hash = "sha256:fe46d4f8e94e637634d54477b0cfabcf93c53f29eedcbdeecaf2af32029b4421", size = 296023, upload-time = "2025-05-09T14:53:24.157Z" }, - { url = "https://files.pythonhosted.org/packages/65/66/8a73aace5a5335a1cba56d0da71b7bd93e450f17d372c5b7c5fa547557e9/greenlet-3.2.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba30e88607fb6990544d84caf3c706c4b48f629e18853fc6a646f82db9629418", size = 629911, upload-time = "2025-05-09T15:24:22.376Z" }, - { url = "https://files.pythonhosted.org/packages/48/08/c8b8ebac4e0c95dcc68ec99198842e7db53eda4ab3fb0a4e785690883991/greenlet-3.2.2-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:055916fafad3e3388d27dd68517478933a97edc2fc54ae79d3bec827de2c64c4", size = 635251, upload-time = "2025-05-09T15:24:52.205Z" }, - { url = "https://files.pythonhosted.org/packages/37/26/7db30868f73e86b9125264d2959acabea132b444b88185ba5c462cb8e571/greenlet-3.2.2-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2593283bf81ca37d27d110956b79e8723f9aa50c4bcdc29d3c0543d4743d2763", size = 632620, upload-time = "2025-05-09T15:29:28.051Z" }, - { url = "https://files.pythonhosted.org/packages/10/ec/718a3bd56249e729016b0b69bee4adea0dfccf6ca43d147ef3b21edbca16/greenlet-3.2.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89c69e9a10670eb7a66b8cef6354c24671ba241f46152dd3eed447f79c29fb5b", size = 628851, upload-time = "2025-05-09T14:53:38.472Z" }, - { url = "https://files.pythonhosted.org/packages/9b/9d/d1c79286a76bc62ccdc1387291464af16a4204ea717f24e77b0acd623b99/greenlet-3.2.2-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:02a98600899ca1ca5d3a2590974c9e3ec259503b2d6ba6527605fcd74e08e207", size = 593718, upload-time = "2025-05-09T14:53:48.313Z" }, - { url = "https://files.pythonhosted.org/packages/cd/41/96ba2bf948f67b245784cd294b84e3d17933597dffd3acdb367a210d1949/greenlet-3.2.2-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:b50a8c5c162469c3209e5ec92ee4f95c8231b11db6a04db09bbe338176723bb8", size = 1105752, upload-time = "2025-05-09T15:27:08.217Z" }, - { url = "https://files.pythonhosted.org/packages/68/3b/3b97f9d33c1f2eb081759da62bd6162159db260f602f048bc2f36b4c453e/greenlet-3.2.2-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:45f9f4853fb4cc46783085261c9ec4706628f3b57de3e68bae03e8f8b3c0de51", size = 1125170, upload-time = "2025-05-09T14:54:04.082Z" }, - { url = "https://files.pythonhosted.org/packages/31/df/b7d17d66c8d0f578d2885a3d8f565e9e4725eacc9d3fdc946d0031c055c4/greenlet-3.2.2-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:9ea5231428af34226c05f927e16fc7f6fa5e39e3ad3cd24ffa48ba53a47f4240", size = 269899, upload-time = "2025-05-09T14:54:01.581Z" }, +version = "3.2.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c9/92/bb85bd6e80148a4d2e0c59f7c0c2891029f8fd510183afc7d8d2feeed9b6/greenlet-3.2.3.tar.gz", hash = "sha256:8b0dd8ae4c0d6f5e54ee55ba935eeb3d735a9b58a8a1e5b5cbab64e01a39f365", size = 185752, upload-time = "2025-06-05T16:16:09.955Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b1/cf/f5c0b23309070ae93de75c90d29300751a5aacefc0a3ed1b1d8edb28f08b/greenlet-3.2.3-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:500b8689aa9dd1ab26872a34084503aeddefcb438e2e7317b89b11eaea1901ad", size = 270732, upload-time = "2025-06-05T16:10:08.26Z" }, + { url = "https://files.pythonhosted.org/packages/48/ae/91a957ba60482d3fecf9be49bc3948f341d706b52ddb9d83a70d42abd498/greenlet-3.2.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:a07d3472c2a93117af3b0136f246b2833fdc0b542d4a9799ae5f41c28323faef", size = 639033, upload-time = "2025-06-05T16:38:53.983Z" }, + { url = "https://files.pythonhosted.org/packages/6f/df/20ffa66dd5a7a7beffa6451bdb7400d66251374ab40b99981478c69a67a8/greenlet-3.2.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:8704b3768d2f51150626962f4b9a9e4a17d2e37c8a8d9867bbd9fa4eb938d3b3", size = 652999, upload-time = "2025-06-05T16:41:37.89Z" }, + { url = "https://files.pythonhosted.org/packages/51/b4/ebb2c8cb41e521f1d72bf0465f2f9a2fd803f674a88db228887e6847077e/greenlet-3.2.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:5035d77a27b7c62db6cf41cf786cfe2242644a7a337a0e155c80960598baab95", size = 647368, upload-time = "2025-06-05T16:48:21.467Z" }, + { url = "https://files.pythonhosted.org/packages/8e/6a/1e1b5aa10dced4ae876a322155705257748108b7fd2e4fae3f2a091fe81a/greenlet-3.2.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2d8aa5423cd4a396792f6d4580f88bdc6efcb9205891c9d40d20f6e670992efb", size = 650037, upload-time = "2025-06-05T16:13:06.402Z" }, + { url = "https://files.pythonhosted.org/packages/26/f2/ad51331a157c7015c675702e2d5230c243695c788f8f75feba1af32b3617/greenlet-3.2.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2c724620a101f8170065d7dded3f962a2aea7a7dae133a009cada42847e04a7b", size = 608402, upload-time = "2025-06-05T16:12:51.91Z" }, + { url = "https://files.pythonhosted.org/packages/26/bc/862bd2083e6b3aff23300900a956f4ea9a4059de337f5c8734346b9b34fc/greenlet-3.2.3-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:873abe55f134c48e1f2a6f53f7d1419192a3d1a4e873bace00499a4e45ea6af0", size = 1119577, upload-time = "2025-06-05T16:36:49.787Z" }, + { url = "https://files.pythonhosted.org/packages/86/94/1fc0cc068cfde885170e01de40a619b00eaa8f2916bf3541744730ffb4c3/greenlet-3.2.3-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:024571bbce5f2c1cfff08bf3fbaa43bbc7444f580ae13b0099e95d0e6e67ed36", size = 1147121, upload-time = "2025-06-05T16:12:42.527Z" }, + { url = "https://files.pythonhosted.org/packages/27/1a/199f9587e8cb08a0658f9c30f3799244307614148ffe8b1e3aa22f324dea/greenlet-3.2.3-cp313-cp313-win_amd64.whl", hash = "sha256:5195fb1e75e592dd04ce79881c8a22becdfa3e6f500e7feb059b1e6fdd54d3e3", size = 297603, upload-time = "2025-06-05T16:20:12.651Z" }, + { url = "https://files.pythonhosted.org/packages/d8/ca/accd7aa5280eb92b70ed9e8f7fd79dc50a2c21d8c73b9a0856f5b564e222/greenlet-3.2.3-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:3d04332dddb10b4a211b68111dabaee2e1a073663d117dc10247b5b1642bac86", size = 271479, upload-time = "2025-06-05T16:10:47.525Z" }, + { url = "https://files.pythonhosted.org/packages/55/71/01ed9895d9eb49223280ecc98a557585edfa56b3d0e965b9fa9f7f06b6d9/greenlet-3.2.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8186162dffde068a465deab08fc72c767196895c39db26ab1c17c0b77a6d8b97", size = 683952, upload-time = "2025-06-05T16:38:55.125Z" }, + { url = "https://files.pythonhosted.org/packages/ea/61/638c4bdf460c3c678a0a1ef4c200f347dff80719597e53b5edb2fb27ab54/greenlet-3.2.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f4bfbaa6096b1b7a200024784217defedf46a07c2eee1a498e94a1b5f8ec5728", size = 696917, upload-time = "2025-06-05T16:41:38.959Z" }, + { url = "https://files.pythonhosted.org/packages/22/cc/0bd1a7eb759d1f3e3cc2d1bc0f0b487ad3cc9f34d74da4b80f226fde4ec3/greenlet-3.2.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:ed6cfa9200484d234d8394c70f5492f144b20d4533f69262d530a1a082f6ee9a", size = 692443, upload-time = "2025-06-05T16:48:23.113Z" }, + { url = "https://files.pythonhosted.org/packages/67/10/b2a4b63d3f08362662e89c103f7fe28894a51ae0bc890fabf37d1d780e52/greenlet-3.2.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:02b0df6f63cd15012bed5401b47829cfd2e97052dc89da3cfaf2c779124eb892", size = 692995, upload-time = "2025-06-05T16:13:07.972Z" }, + { url = "https://files.pythonhosted.org/packages/5a/c6/ad82f148a4e3ce9564056453a71529732baf5448ad53fc323e37efe34f66/greenlet-3.2.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:86c2d68e87107c1792e2e8d5399acec2487a4e993ab76c792408e59394d52141", size = 655320, upload-time = "2025-06-05T16:12:53.453Z" }, + { url = "https://files.pythonhosted.org/packages/5c/4f/aab73ecaa6b3086a4c89863d94cf26fa84cbff63f52ce9bc4342b3087a06/greenlet-3.2.3-cp314-cp314-win_amd64.whl", hash = "sha256:8c47aae8fbbfcf82cc13327ae802ba13c9c36753b67e760023fd116bc124a62a", size = 301236, upload-time = "2025-06-05T16:15:20.111Z" }, ] [[package]] @@ -877,6 +876,7 @@ dependencies = [ { name = "phonenumbers" }, { name = "pillow" }, { name = "pluggy" }, + { name = "pre-commit" }, { name = "propcache" }, { name = "proto-plus" }, { name = "protobuf" }, @@ -976,6 +976,7 @@ requires-dist = [ { name = "phonenumbers", specifier = "==9.0.8" }, { name = "pillow", specifier = "==11.3.0" }, { name = "pluggy", specifier = "==1.6.0" }, + { name = "pre-commit", specifier = "==4.2.0" }, { name = "propcache", specifier = "==0.3.2" }, { name = "proto-plus", specifier = "==1.26.1" }, { name = "protobuf", specifier = "==6.31.1" }, @@ -1019,34 +1020,43 @@ dev = [ { name = "python-dotenv", specifier = ">=1.1.1" }, ] +[[package]] +name = "nodeenv" +version = "1.9.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437, upload-time = "2024-06-04T18:44:11.171Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314, upload-time = "2024-06-04T18:44:08.352Z" }, +] + [[package]] name = "numpy" -version = "2.3.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f3/db/8e12381333aea300890829a0a36bfa738cac95475d88982d538725143fd9/numpy-2.3.0.tar.gz", hash = "sha256:581f87f9e9e9db2cba2141400e160e9dd644ee248788d6f90636eeb8fd9260a6", size = 20382813, upload-time = "2025-06-07T14:54:32.608Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/73/fc/1d67f751fd4dbafc5780244fe699bc4084268bad44b7c5deb0492473127b/numpy-2.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5754ab5595bfa2c2387d241296e0381c21f44a4b90a776c3c1d39eede13a746a", size = 20889633, upload-time = "2025-06-07T14:44:06.839Z" }, - { url = "https://files.pythonhosted.org/packages/e8/95/73ffdb69e5c3f19ec4530f8924c4386e7ba097efc94b9c0aff607178ad94/numpy-2.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d11fa02f77752d8099573d64e5fe33de3229b6632036ec08f7080f46b6649959", size = 14151683, upload-time = "2025-06-07T14:44:28.847Z" }, - { url = "https://files.pythonhosted.org/packages/64/d5/06d4bb31bb65a1d9c419eb5676173a2f90fd8da3c59f816cc54c640ce265/numpy-2.3.0-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:aba48d17e87688a765ab1cd557882052f238e2f36545dfa8e29e6a91aef77afe", size = 5102683, upload-time = "2025-06-07T14:44:38.417Z" }, - { url = "https://files.pythonhosted.org/packages/12/8b/6c2cef44f8ccdc231f6b56013dff1d71138c48124334aded36b1a1b30c5a/numpy-2.3.0-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:4dc58865623023b63b10d52f18abaac3729346a7a46a778381e0e3af4b7f3beb", size = 6640253, upload-time = "2025-06-07T14:44:49.359Z" }, - { url = "https://files.pythonhosted.org/packages/62/aa/fca4bf8de3396ddb59544df9b75ffe5b73096174de97a9492d426f5cd4aa/numpy-2.3.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:df470d376f54e052c76517393fa443758fefcdd634645bc9c1f84eafc67087f0", size = 14258658, upload-time = "2025-06-07T14:45:10.156Z" }, - { url = "https://files.pythonhosted.org/packages/1c/12/734dce1087eed1875f2297f687e671cfe53a091b6f2f55f0c7241aad041b/numpy-2.3.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:87717eb24d4a8a64683b7a4e91ace04e2f5c7c77872f823f02a94feee186168f", size = 16628765, upload-time = "2025-06-07T14:45:35.076Z" }, - { url = "https://files.pythonhosted.org/packages/48/03/ffa41ade0e825cbcd5606a5669962419528212a16082763fc051a7247d76/numpy-2.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d8fa264d56882b59dcb5ea4d6ab6f31d0c58a57b41aec605848b6eb2ef4a43e8", size = 15564335, upload-time = "2025-06-07T14:45:58.797Z" }, - { url = "https://files.pythonhosted.org/packages/07/58/869398a11863310aee0ff85a3e13b4c12f20d032b90c4b3ee93c3b728393/numpy-2.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e651756066a0eaf900916497e20e02fe1ae544187cb0fe88de981671ee7f6270", size = 18360608, upload-time = "2025-06-07T14:46:25.687Z" }, - { url = "https://files.pythonhosted.org/packages/2f/8a/5756935752ad278c17e8a061eb2127c9a3edf4ba2c31779548b336f23c8d/numpy-2.3.0-cp313-cp313-win32.whl", hash = "sha256:e43c3cce3b6ae5f94696669ff2a6eafd9a6b9332008bafa4117af70f4b88be6f", size = 6310005, upload-time = "2025-06-07T14:50:13.138Z" }, - { url = "https://files.pythonhosted.org/packages/08/60/61d60cf0dfc0bf15381eaef46366ebc0c1a787856d1db0c80b006092af84/numpy-2.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:81ae0bf2564cf475f94be4a27ef7bcf8af0c3e28da46770fc904da9abd5279b5", size = 12729093, upload-time = "2025-06-07T14:50:31.82Z" }, - { url = "https://files.pythonhosted.org/packages/66/31/2f2f2d2b3e3c32d5753d01437240feaa32220b73258c9eef2e42a0832866/numpy-2.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:c8738baa52505fa6e82778580b23f945e3578412554d937093eac9205e845e6e", size = 9885689, upload-time = "2025-06-07T14:50:47.888Z" }, - { url = "https://files.pythonhosted.org/packages/f1/89/c7828f23cc50f607ceb912774bb4cff225ccae7131c431398ad8400e2c98/numpy-2.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:39b27d8b38942a647f048b675f134dd5a567f95bfff481f9109ec308515c51d8", size = 20986612, upload-time = "2025-06-07T14:46:56.077Z" }, - { url = "https://files.pythonhosted.org/packages/dd/46/79ecf47da34c4c50eedec7511e53d57ffdfd31c742c00be7dc1d5ffdb917/numpy-2.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0eba4a1ea88f9a6f30f56fdafdeb8da3774349eacddab9581a21234b8535d3d3", size = 14298953, upload-time = "2025-06-07T14:47:18.053Z" }, - { url = "https://files.pythonhosted.org/packages/59/44/f6caf50713d6ff4480640bccb2a534ce1d8e6e0960c8f864947439f0ee95/numpy-2.3.0-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:b0f1f11d0a1da54927436505a5a7670b154eac27f5672afc389661013dfe3d4f", size = 5225806, upload-time = "2025-06-07T14:47:27.524Z" }, - { url = "https://files.pythonhosted.org/packages/a6/43/e1fd1aca7c97e234dd05e66de4ab7a5be54548257efcdd1bc33637e72102/numpy-2.3.0-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:690d0a5b60a47e1f9dcec7b77750a4854c0d690e9058b7bef3106e3ae9117808", size = 6735169, upload-time = "2025-06-07T14:47:38.057Z" }, - { url = "https://files.pythonhosted.org/packages/84/89/f76f93b06a03177c0faa7ca94d0856c4e5c4bcaf3c5f77640c9ed0303e1c/numpy-2.3.0-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:8b51ead2b258284458e570942137155978583e407babc22e3d0ed7af33ce06f8", size = 14330701, upload-time = "2025-06-07T14:47:59.113Z" }, - { url = "https://files.pythonhosted.org/packages/aa/f5/4858c3e9ff7a7d64561b20580cf7cc5d085794bd465a19604945d6501f6c/numpy-2.3.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:aaf81c7b82c73bd9b45e79cfb9476cb9c29e937494bfe9092c26aece812818ad", size = 16692983, upload-time = "2025-06-07T14:48:24.196Z" }, - { url = "https://files.pythonhosted.org/packages/08/17/0e3b4182e691a10e9483bcc62b4bb8693dbf9ea5dc9ba0b77a60435074bb/numpy-2.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:f420033a20b4f6a2a11f585f93c843ac40686a7c3fa514060a97d9de93e5e72b", size = 15641435, upload-time = "2025-06-07T14:48:47.712Z" }, - { url = "https://files.pythonhosted.org/packages/4e/d5/463279fda028d3c1efa74e7e8d507605ae87f33dbd0543cf4c4527c8b882/numpy-2.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:d344ca32ab482bcf8735d8f95091ad081f97120546f3d250240868430ce52555", size = 18433798, upload-time = "2025-06-07T14:49:14.866Z" }, - { url = "https://files.pythonhosted.org/packages/0e/1e/7a9d98c886d4c39a2b4d3a7c026bffcf8fbcaf518782132d12a301cfc47a/numpy-2.3.0-cp313-cp313t-win32.whl", hash = "sha256:48a2e8eaf76364c32a1feaa60d6925eaf32ed7a040183b807e02674305beef61", size = 6438632, upload-time = "2025-06-07T14:49:25.67Z" }, - { url = "https://files.pythonhosted.org/packages/fe/ab/66fc909931d5eb230107d016861824f335ae2c0533f422e654e5ff556784/numpy-2.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ba17f93a94e503551f154de210e4d50c5e3ee20f7e7a1b5f6ce3f22d419b93bb", size = 12868491, upload-time = "2025-06-07T14:49:44.898Z" }, - { url = "https://files.pythonhosted.org/packages/ee/e8/2c8a1c9e34d6f6d600c83d5ce5b71646c32a13f34ca5c518cc060639841c/numpy-2.3.0-cp313-cp313t-win_arm64.whl", hash = "sha256:f14e016d9409680959691c109be98c436c6249eaf7f118b424679793607b5944", size = 9935345, upload-time = "2025-06-07T14:50:02.311Z" }, +version = "2.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2e/19/d7c972dfe90a353dbd3efbbe1d14a5951de80c99c9dc1b93cd998d51dc0f/numpy-2.3.1.tar.gz", hash = "sha256:1ec9ae20a4226da374362cca3c62cd753faf2f951440b0e3b98e93c235441d2b", size = 20390372, upload-time = "2025-06-21T12:28:33.469Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d4/bd/35ad97006d8abff8631293f8ea6adf07b0108ce6fec68da3c3fcca1197f2/numpy-2.3.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:25a1992b0a3fdcdaec9f552ef10d8103186f5397ab45e2d25f8ac51b1a6b97e8", size = 20889381, upload-time = "2025-06-21T12:19:04.103Z" }, + { url = "https://files.pythonhosted.org/packages/f1/4f/df5923874d8095b6062495b39729178eef4a922119cee32a12ee1bd4664c/numpy-2.3.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7dea630156d39b02a63c18f508f85010230409db5b2927ba59c8ba4ab3e8272e", size = 14152726, upload-time = "2025-06-21T12:19:25.599Z" }, + { url = "https://files.pythonhosted.org/packages/8c/0f/a1f269b125806212a876f7efb049b06c6f8772cf0121139f97774cd95626/numpy-2.3.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:bada6058dd886061f10ea15f230ccf7dfff40572e99fef440a4a857c8728c9c0", size = 5105145, upload-time = "2025-06-21T12:19:34.782Z" }, + { url = "https://files.pythonhosted.org/packages/6d/63/a7f7fd5f375b0361682f6ffbf686787e82b7bbd561268e4f30afad2bb3c0/numpy-2.3.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:a894f3816eb17b29e4783e5873f92faf55b710c2519e5c351767c51f79d8526d", size = 6639409, upload-time = "2025-06-21T12:19:45.228Z" }, + { url = "https://files.pythonhosted.org/packages/bf/0d/1854a4121af895aab383f4aa233748f1df4671ef331d898e32426756a8a6/numpy-2.3.1-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:18703df6c4a4fee55fd3d6e5a253d01c5d33a295409b03fda0c86b3ca2ff41a1", size = 14257630, upload-time = "2025-06-21T12:20:06.544Z" }, + { url = "https://files.pythonhosted.org/packages/50/30/af1b277b443f2fb08acf1c55ce9d68ee540043f158630d62cef012750f9f/numpy-2.3.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:5902660491bd7a48b2ec16c23ccb9124b8abfd9583c5fdfa123fe6b421e03de1", size = 16627546, upload-time = "2025-06-21T12:20:31.002Z" }, + { url = "https://files.pythonhosted.org/packages/6e/ec/3b68220c277e463095342d254c61be8144c31208db18d3fd8ef02712bcd6/numpy-2.3.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:36890eb9e9d2081137bd78d29050ba63b8dab95dff7912eadf1185e80074b2a0", size = 15562538, upload-time = "2025-06-21T12:20:54.322Z" }, + { url = "https://files.pythonhosted.org/packages/77/2b/4014f2bcc4404484021c74d4c5ee8eb3de7e3f7ac75f06672f8dcf85140a/numpy-2.3.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a780033466159c2270531e2b8ac063704592a0bc62ec4a1b991c7c40705eb0e8", size = 18360327, upload-time = "2025-06-21T12:21:21.053Z" }, + { url = "https://files.pythonhosted.org/packages/40/8d/2ddd6c9b30fcf920837b8672f6c65590c7d92e43084c25fc65edc22e93ca/numpy-2.3.1-cp313-cp313-win32.whl", hash = "sha256:39bff12c076812595c3a306f22bfe49919c5513aa1e0e70fac756a0be7c2a2b8", size = 6312330, upload-time = "2025-06-21T12:25:07.447Z" }, + { url = "https://files.pythonhosted.org/packages/dd/c8/beaba449925988d415efccb45bf977ff8327a02f655090627318f6398c7b/numpy-2.3.1-cp313-cp313-win_amd64.whl", hash = "sha256:8d5ee6eec45f08ce507a6570e06f2f879b374a552087a4179ea7838edbcbfa42", size = 12731565, upload-time = "2025-06-21T12:25:26.444Z" }, + { url = "https://files.pythonhosted.org/packages/0b/c3/5c0c575d7ec78c1126998071f58facfc124006635da75b090805e642c62e/numpy-2.3.1-cp313-cp313-win_arm64.whl", hash = "sha256:0c4d9e0a8368db90f93bd192bfa771ace63137c3488d198ee21dfb8e7771916e", size = 10190262, upload-time = "2025-06-21T12:25:42.196Z" }, + { url = "https://files.pythonhosted.org/packages/ea/19/a029cd335cf72f79d2644dcfc22d90f09caa86265cbbde3b5702ccef6890/numpy-2.3.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:b0b5397374f32ec0649dd98c652a1798192042e715df918c20672c62fb52d4b8", size = 20987593, upload-time = "2025-06-21T12:21:51.664Z" }, + { url = "https://files.pythonhosted.org/packages/25/91/8ea8894406209107d9ce19b66314194675d31761fe2cb3c84fe2eeae2f37/numpy-2.3.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:c5bdf2015ccfcee8253fb8be695516ac4457c743473a43290fd36eba6a1777eb", size = 14300523, upload-time = "2025-06-21T12:22:13.583Z" }, + { url = "https://files.pythonhosted.org/packages/a6/7f/06187b0066eefc9e7ce77d5f2ddb4e314a55220ad62dd0bfc9f2c44bac14/numpy-2.3.1-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:d70f20df7f08b90a2062c1f07737dd340adccf2068d0f1b9b3d56e2038979fee", size = 5227993, upload-time = "2025-06-21T12:22:22.53Z" }, + { url = "https://files.pythonhosted.org/packages/e8/ec/a926c293c605fa75e9cfb09f1e4840098ed46d2edaa6e2152ee35dc01ed3/numpy-2.3.1-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:2fb86b7e58f9ac50e1e9dd1290154107e47d1eef23a0ae9145ded06ea606f992", size = 6736652, upload-time = "2025-06-21T12:22:33.629Z" }, + { url = "https://files.pythonhosted.org/packages/e3/62/d68e52fb6fde5586650d4c0ce0b05ff3a48ad4df4ffd1b8866479d1d671d/numpy-2.3.1-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:23ab05b2d241f76cb883ce8b9a93a680752fbfcbd51c50eff0b88b979e471d8c", size = 14331561, upload-time = "2025-06-21T12:22:55.056Z" }, + { url = "https://files.pythonhosted.org/packages/fc/ec/b74d3f2430960044bdad6900d9f5edc2dc0fb8bf5a0be0f65287bf2cbe27/numpy-2.3.1-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:ce2ce9e5de4703a673e705183f64fd5da5bf36e7beddcb63a25ee2286e71ca48", size = 16693349, upload-time = "2025-06-21T12:23:20.53Z" }, + { url = "https://files.pythonhosted.org/packages/0d/15/def96774b9d7eb198ddadfcbd20281b20ebb510580419197e225f5c55c3e/numpy-2.3.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c4913079974eeb5c16ccfd2b1f09354b8fed7e0d6f2cab933104a09a6419b1ee", size = 15642053, upload-time = "2025-06-21T12:23:43.697Z" }, + { url = "https://files.pythonhosted.org/packages/2b/57/c3203974762a759540c6ae71d0ea2341c1fa41d84e4971a8e76d7141678a/numpy-2.3.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:010ce9b4f00d5c036053ca684c77441f2f2c934fd23bee058b4d6f196efd8280", size = 18434184, upload-time = "2025-06-21T12:24:10.708Z" }, + { url = "https://files.pythonhosted.org/packages/22/8a/ccdf201457ed8ac6245187850aff4ca56a79edbea4829f4e9f14d46fa9a5/numpy-2.3.1-cp313-cp313t-win32.whl", hash = "sha256:6269b9edfe32912584ec496d91b00b6d34282ca1d07eb10e82dfc780907d6c2e", size = 6440678, upload-time = "2025-06-21T12:24:21.596Z" }, + { url = "https://files.pythonhosted.org/packages/f1/7e/7f431d8bd8eb7e03d79294aed238b1b0b174b3148570d03a8a8a8f6a0da9/numpy-2.3.1-cp313-cp313t-win_amd64.whl", hash = "sha256:2a809637460e88a113e186e87f228d74ae2852a2e0c44de275263376f17b5bdc", size = 12870697, upload-time = "2025-06-21T12:24:40.644Z" }, + { url = "https://files.pythonhosted.org/packages/d4/ca/af82bf0fad4c3e573c6930ed743b5308492ff19917c7caaf2f9b6f9e2e98/numpy-2.3.1-cp313-cp313t-win_arm64.whl", hash = "sha256:eccb9a159db9aed60800187bc47a6d3451553f0e1b08b068d8b277ddfbb9b244", size = 10260376, upload-time = "2025-06-21T12:24:56.884Z" }, ] [[package]] @@ -1100,11 +1110,11 @@ wheels = [ [[package]] name = "phonenumbers" -version = "9.0.7" +version = "9.0.8" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/49/8c/2c09b844e819e70c261ad79cc302a5e307d97cb0ab70c227031d8ad72871/phonenumbers-9.0.7.tar.gz", hash = "sha256:d4cc2aa36cbf9b0004c370f406d1510ddef56bba9e5f759471ef47e998d8a2f9", size = 2297250, upload-time = "2025-06-09T06:01:09.224Z" } +sdist = { url = "https://files.pythonhosted.org/packages/86/3a/8dd1d5e15ac347db59a43fc623638d8088f9d511e7f8d8eec7d90b3abb4f/phonenumbers-9.0.8.tar.gz", hash = "sha256:16f03f2cf65b5eee99ed25827d810febcab92b5d76f977e425fcd2e4ca6d4865", size = 2297504, upload-time = "2025-06-25T05:41:38.414Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/03/d6/71ed688698834669f61dbba51601a27b62c1a7f5f868444f973a3fd33dc8/phonenumbers-9.0.7-py2.py3-none-any.whl", hash = "sha256:306eb14d1eaeb82230a08aa1614d04c93322b65b1ded2fff585161ed7eca39fc", size = 2583027, upload-time = "2025-06-09T06:01:04.772Z" }, + { url = "https://files.pythonhosted.org/packages/48/2e/23c1eca9f73e332b947c66c431690672783cf49b8418aa650ce06bdf6115/phonenumbers-9.0.8-py2.py3-none-any.whl", hash = "sha256:53d357111c0ead0d6408ae443613b18d3a053431ca1ddf7e881457c0969afcf9", size = 2583252, upload-time = "2025-06-25T05:41:34.815Z" }, ] [[package]] @@ -1304,7 +1314,7 @@ wheels = [ [[package]] name = "pydantic" -version = "2.11.5" +version = "2.11.7" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-types" }, @@ -1312,9 +1322,9 @@ dependencies = [ { name = "typing-extensions" }, { name = "typing-inspection" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f0/86/8ce9040065e8f924d642c58e4a344e33163a07f6b57f836d0d734e0ad3fb/pydantic-2.11.5.tar.gz", hash = "sha256:7f853db3d0ce78ce8bbb148c401c2cdd6431b3473c0cdff2755c7690952a7b7a", size = 787102, upload-time = "2025-05-22T21:18:08.761Z" } +sdist = { url = "https://files.pythonhosted.org/packages/00/dd/4325abf92c39ba8623b5af936ddb36ffcfe0beae70405d456ab1fb2f5b8c/pydantic-2.11.7.tar.gz", hash = "sha256:d989c3c6cb79469287b1569f7447a17848c998458d49ebe294e975b9baf0f0db", size = 788350, upload-time = "2025-06-14T08:33:17.137Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b5/69/831ed22b38ff9b4b64b66569f0e5b7b97cf3638346eb95a2147fdb49ad5f/pydantic-2.11.5-py3-none-any.whl", hash = "sha256:f9c26ba06f9747749ca1e5c94d6a85cb84254577553c8785576fd38fa64dc0f7", size = 444229, upload-time = "2025-05-22T21:18:06.329Z" }, + { url = "https://files.pythonhosted.org/packages/6a/c0/ec2b1c8712ca690e5d61979dee872603e92b8a32f94cc1b72d53beab008a/pydantic-2.11.7-py3-none-any.whl", hash = "sha256:dde5df002701f6de26248661f6835bbe296a47bf73990135c7d07ce741b9623b", size = 444782, upload-time = "2025-06-14T08:33:14.905Z" }, ] [[package]] @@ -1347,11 +1357,11 @@ wheels = [ [[package]] name = "pygments" -version = "2.19.1" +version = "2.19.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7c/2d/c3338d48ea6cc0feb8446d8e6937e1408088a72a39937982cc6111d17f84/pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f", size = 4968581, upload-time = "2025-01-06T17:26:30.443Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c", size = 1225293, upload-time = "2025-01-06T17:26:25.553Z" }, + { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, ] [[package]] @@ -1393,7 +1403,7 @@ wheels = [ [[package]] name = "pytest" -version = "8.4.0" +version = "8.4.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, @@ -1402,9 +1412,9 @@ dependencies = [ { name = "pluggy" }, { name = "pygments" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fb/aa/405082ce2749be5398045152251ac69c0f3578c7077efc53431303af97ce/pytest-8.4.0.tar.gz", hash = "sha256:14d920b48472ea0dbf68e45b96cd1ffda4705f33307dcc86c676c1b5104838a6", size = 1515232, upload-time = "2025-06-02T17:36:30.03Z" } +sdist = { url = "https://files.pythonhosted.org/packages/08/ba/45911d754e8eba3d5a841a5ce61a65a685ff1798421ac054f85aa8747dfb/pytest-8.4.1.tar.gz", hash = "sha256:7c67fd69174877359ed9371ec3af8a3d2b04741818c51e5e99cc1742251fa93c", size = 1517714, upload-time = "2025-06-18T05:48:06.109Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2f/de/afa024cbe022b1b318a3d224125aa24939e99b4ff6f22e0ba639a2eaee47/pytest-8.4.0-py3-none-any.whl", hash = "sha256:f40f825768ad76c0977cbacdf1fd37c6f7a468e460ea6a0636078f8972d4517e", size = 363797, upload-time = "2025-06-02T17:36:27.859Z" }, + { url = "https://files.pythonhosted.org/packages/29/16/c8a903f4c4dffe7a12843191437d7cd8e32751d5de349d45d3fe69544e87/pytest-8.4.1-py3-none-any.whl", hash = "sha256:539c70ba6fcead8e78eebbf1115e8b589e7565830d7d006a8723f19ac8a0afb7", size = 365474, upload-time = "2025-06-18T05:48:03.955Z" }, ] [[package]] @@ -1673,29 +1683,29 @@ wheels = [ [[package]] name = "uvicorn" -version = "0.34.3" +version = "0.35.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, { name = "h11" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/de/ad/713be230bcda622eaa35c28f0d328c3675c371238470abdea52417f17a8e/uvicorn-0.34.3.tar.gz", hash = "sha256:35919a9a979d7a59334b6b10e05d77c1d0d574c50e0fc98b8b1a0f165708b55a", size = 76631, upload-time = "2025-06-01T07:48:17.531Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5e/42/e0e305207bb88c6b8d3061399c6a961ffe5fbb7e2aa63c9234df7259e9cd/uvicorn-0.35.0.tar.gz", hash = "sha256:bc662f087f7cf2ce11a1d7fd70b90c9f98ef2e2831556dd078d131b96cc94a01", size = 78473, upload-time = "2025-06-28T16:15:46.058Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6d/0d/8adfeaa62945f90d19ddc461c55f4a50c258af7662d34b6a3d5d1f8646f6/uvicorn-0.34.3-py3-none-any.whl", hash = "sha256:16246631db62bdfbf069b0645177d6e8a77ba950cfedbfd093acef9444e4d885", size = 62431, upload-time = "2025-06-01T07:48:15.664Z" }, + { url = "https://files.pythonhosted.org/packages/d2/e2/dc81b1bd1dcfe91735810265e9d26bc8ec5da45b4c0f6237e286819194c3/uvicorn-0.35.0-py3-none-any.whl", hash = "sha256:197535216b25ff9b785e29a0b79199f55222193d47f820816e7da751e9bc8d4a", size = 66406, upload-time = "2025-06-28T16:15:44.816Z" }, ] [[package]] name = "virtualenv" -version = "20.31.2" +version = "20.32.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "distlib" }, { name = "filelock" }, { name = "platformdirs" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/56/2c/444f465fb2c65f40c3a104fd0c495184c4f2336d65baf398e3c75d72ea94/virtualenv-20.31.2.tar.gz", hash = "sha256:e10c0a9d02835e592521be48b332b6caee6887f332c111aa79a09b9e79efc2af", size = 6076316, upload-time = "2025-05-08T17:58:23.811Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a9/96/0834f30fa08dca3738614e6a9d42752b6420ee94e58971d702118f7cfd30/virtualenv-20.32.0.tar.gz", hash = "sha256:886bf75cadfdc964674e6e33eb74d787dff31ca314ceace03ca5810620f4ecf0", size = 6076970, upload-time = "2025-07-21T04:09:50.985Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f3/40/b1c265d4b2b62b58576588510fc4d1fe60a86319c8de99fd8e9fec617d2c/virtualenv-20.31.2-py3-none-any.whl", hash = "sha256:36efd0d9650ee985f0cad72065001e66d49a6f24eb44d98980f630686243cf11", size = 6057982, upload-time = "2025-05-08T17:58:21.15Z" }, + { url = "https://files.pythonhosted.org/packages/5c/c6/f8f28009920a736d0df434b52e9feebfb4d702ba942f15338cb4a83eafc1/virtualenv-20.32.0-py3-none-any.whl", hash = "sha256:2c310aecb62e5aa1b06103ed7c2977b81e042695de2697d01017ff0f1034af56", size = 6057761, upload-time = "2025-07-21T04:09:48.059Z" }, ] [[package]] From 3367d545846efd634df9808bc1ed71acb2528e7e Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Tue, 22 Jul 2025 12:18:39 -0600 Subject: [PATCH 31/38] fix: install dev dependencies with uv --- docker/app/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/app/Dockerfile b/docker/app/Dockerfile index cfb7d8bea..414203128 100644 --- a/docker/app/Dockerfile +++ b/docker/app/Dockerfile @@ -21,7 +21,7 @@ COPY . . # install dependencies using uv ENV UV_PROJECT_ENVIRONMENT="/usr/local/" -RUN uv sync --locked --no-dev +RUN uv sync --locked # expose FastAPI's default dev port EXPOSE 8000 From 4f4343294b6c17bd5670549c5dbb55d9ea7a084d Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Tue, 22 Jul 2025 12:19:10 -0600 Subject: [PATCH 32/38] feat: update migration from pre-production changes --- .../8447b9ebaf29_changes_to_pre_production.py | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 alembic/versions/8447b9ebaf29_changes_to_pre_production.py diff --git a/alembic/versions/8447b9ebaf29_changes_to_pre_production.py b/alembic/versions/8447b9ebaf29_changes_to_pre_production.py new file mode 100644 index 000000000..956add039 --- /dev/null +++ b/alembic/versions/8447b9ebaf29_changes_to_pre_production.py @@ -0,0 +1,87 @@ +"""changes to pre-production + +Revision ID: 8447b9ebaf29 +Revises: 5901f059248a +Create Date: 2025-07-22 12:17:19.076090 + +""" + +from typing import Sequence, Union + +from alembic import op +import sqlalchemy as sa +import sqlalchemy_utils + + +# revision identifiers, used by Alembic. +revision: str = "8447b9ebaf29" +down_revision: Union[str, Sequence[str], None] = "5901f059248a" +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + """Upgrade schema.""" + # ### commands auto generated by Alembic - please adjust! ### + op.add_column( + "address", + sa.Column( + "search_vector", + sqlalchemy_utils.types.ts_vector.TSVectorType(), + nullable=True, + ), + ) + op.create_index( + "ix_address_search_vector", + "address", + ["search_vector"], + unique=False, + postgresql_using="gin", + ) + op.add_column( + "thing", + sa.Column( + "search_vector", + sqlalchemy_utils.types.ts_vector.TSVectorType(), + nullable=True, + ), + ) + op.create_index( + "ix_thing_search_vector", + "thing", + ["search_vector"], + unique=False, + postgresql_using="gin", + ) + op.add_column( + "well_thing", + sa.Column( + "search_vector", + sqlalchemy_utils.types.ts_vector.TSVectorType(), + nullable=True, + ), + ) + op.create_index( + "ix_well_thing_search_vector", + "well_thing", + ["search_vector"], + unique=False, + postgresql_using="gin", + ) + # ### end Alembic commands ### + + +def downgrade() -> None: + """Downgrade schema.""" + # ### commands auto generated by Alembic - please adjust! ### + op.drop_index( + "ix_well_thing_search_vector", table_name="well_thing", postgresql_using="gin" + ) + op.drop_column("well_thing", "search_vector") + op.drop_index("ix_thing_search_vector", table_name="thing", postgresql_using="gin") + op.drop_column("thing", "search_vector") + op.drop_index( + "ix_address_search_vector", table_name="address", postgresql_using="gin" + ) + op.drop_column("address", "search_vector") + # ### end Alembic commands ### From 72144ea634a3059f8192d6f09d538c625c04ed7b Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Tue, 22 Jul 2025 13:49:49 -0600 Subject: [PATCH 33/38] feat: autoreload changes --- docker-compose.yml | 2 ++ entrypoint.sh | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index b9780b83a..199612827 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -24,6 +24,8 @@ services: - db links: - db + volumes: + - .:/app volumes: postgres_data: \ No newline at end of file diff --git a/entrypoint.sh b/entrypoint.sh index 995a2adb1..662487618 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -9,4 +9,4 @@ echo "PostgreSQL is ready!" echo "Applying migrations..." alembic upgrade head echo "Starting the application..." -uvicorn main:app --host 0.0.0.0 --port 8000 \ No newline at end of file +uvicorn main:app --host 0.0.0.0 --port 8000 --reload \ No newline at end of file From fc231eef49f0e513d639ee5faf6cbf5a92bc8349 Mon Sep 17 00:00:00 2001 From: chasetmartin <36861079+chasetmartin@users.noreply.github.com> Date: Tue, 22 Jul 2025 13:11:09 -0700 Subject: [PATCH 34/38] Adds platform to docker-compose --- docker-compose.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 199612827..b8d2abed5 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,7 +2,8 @@ services: db: - image: postgis/postgis:17-3.5 + image: postgis/postgis:16-master + platform: linux/amd64 environment: - POSTGRES_USER=${POSTGRES_USER} - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} From 720979e606d90f57d54e39abd514fe010bdf78be Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Tue, 22 Jul 2025 14:16:41 -0600 Subject: [PATCH 35/38] fix: use latest version of postgis --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index b8d2abed5..b646b6f26 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,7 +2,7 @@ services: db: - image: postgis/postgis:16-master + image: postgis/postgis:17-3.5 platform: linux/amd64 environment: - POSTGRES_USER=${POSTGRES_USER} From a81f022f492ddeaab964e8d57c933c8463446e15 Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Tue, 22 Jul 2025 14:24:52 -0600 Subject: [PATCH 36/38] fix: load env vars for engine connect --- db/engine.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/db/engine.py b/db/engine.py index a51c3f7c1..e084fac6a 100644 --- a/db/engine.py +++ b/db/engine.py @@ -15,6 +15,7 @@ # =============================================================================== import asyncio +from dotenv import load_dotenv import os from contextlib import contextmanager from sqlalchemy import ( @@ -26,6 +27,7 @@ ) from sqlalchemy.util import await_only +load_dotenv() driver = os.environ.get("DB_DRIVER", "") From 9b78e5d6a295b1297cd171c46e537b5c0725b35d Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Tue, 22 Jul 2025 14:33:59 -0600 Subject: [PATCH 37/38] fix: set env vars in docker compose This allows the env variables to be set for the docker containers to talk with each other - that is, host must be "db" for the app to connect to the database because in Docker, the host should be the name of the database service, not localhost. --- alembic/env.py | 20 +++++++------------- docker-compose.yml | 5 ++++- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/alembic/env.py b/alembic/env.py index 88380f40a..89ba72be3 100644 --- a/alembic/env.py +++ b/alembic/env.py @@ -33,19 +33,13 @@ load_dotenv() -db_url = environ.get("DATABASE_URL", None) -if db_url: - SQLALCHEMY_DATABASE_URL = db_url -else: - # Fallback to environment variables for PostgreSQL connection - user = environ.get("POSTGRES_USER", None) - password = environ.get("POSTGRES_PASSWORD", None) - db = environ.get("POSTGRES_DB", None) - host = environ.get("POSTGRES_HOST", None) - port = environ.get("POSTGRES_PORT", None) - SQLALCHEMY_DATABASE_URL = ( - f"postgresql+psycopg2://{user}:{password}@{host}:{port}/{db}" - ) +# Fallback to environment variables for PostgreSQL connection +user = environ.get("POSTGRES_USER", None) +password = environ.get("POSTGRES_PASSWORD", None) +db = environ.get("POSTGRES_DB", None) +host = environ.get("POSTGRES_HOST", None) +port = environ.get("POSTGRES_PORT", None) +SQLALCHEMY_DATABASE_URL = f"postgresql+psycopg2://{user}:{password}@{host}:{port}/{db}" config.set_main_option("sqlalchemy.url", SQLALCHEMY_DATABASE_URL) diff --git a/docker-compose.yml b/docker-compose.yml index b646b6f26..ebce2102d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -18,7 +18,10 @@ services: context: . dockerfile: ./docker/app/Dockerfile environment: - - DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB} + - POSTGRES_USER=${POSTGRES_USER} + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD} + - POSTGRES_DB=${POSTGRES_DB} + - POSTGRES_HOST=db ports: - 8000:8000 depends_on: From f5461e9e11dc2869ddb46be19fdc3d1ccb800fac Mon Sep 17 00:00:00 2001 From: Jacob Brown Date: Tue, 22 Jul 2025 14:38:25 -0600 Subject: [PATCH 38/38] fix: add alembic.ini to GitHub repo This should be there for all to use. The database connection strings are now made through environment variables, which are set in the appropriate yaml/.env/secrets files. --- .gitignore | 3 +- alembic.ini | 141 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 142 insertions(+), 2 deletions(-) create mode 100644 alembic.ini diff --git a/.gitignore b/.gitignore index 41e72f6ae..818dc6e32 100644 --- a/.gitignore +++ b/.gitignore @@ -24,5 +24,4 @@ migrate.sh # deployment files -app.yaml -alembic.ini \ No newline at end of file +app.yaml \ No newline at end of file diff --git a/alembic.ini b/alembic.ini new file mode 100644 index 000000000..8507f6273 --- /dev/null +++ b/alembic.ini @@ -0,0 +1,141 @@ +# A generic, single database configuration. + +[alembic] +# path to migration scripts. +# this is typically a path given in POSIX (e.g. forward slashes) +# format, relative to the token %(here)s which refers to the location of this +# ini file +script_location = %(here)s/alembic + +# template used to generate migration file names; The default value is %%(rev)s_%%(slug)s +# Uncomment the line below if you want the files to be prepended with date and time +# see https://alembic.sqlalchemy.org/en/latest/tutorial.html#editing-the-ini-file +# for all available tokens +# file_template = %%(year)d_%%(month).2d_%%(day).2d_%%(hour).2d%%(minute).2d-%%(rev)s_%%(slug)s + +# sys.path path, will be prepended to sys.path if present. +# defaults to the current working directory. for multiple paths, the path separator +# is defined by "path_separator" below. +prepend_sys_path = . + + +# timezone to use when rendering the date within the migration file +# as well as the filename. +# If specified, requires the python>=3.9 or backports.zoneinfo library and tzdata library. +# Any required deps can installed by adding `alembic[tz]` to the pip requirements +# string value is passed to ZoneInfo() +# leave blank for localtime +# timezone = + +# max length of characters to apply to the "slug" field +# truncate_slug_length = 40 + +# set to 'true' to run the environment during +# the 'revision' command, regardless of autogenerate +# revision_environment = false + +# set to 'true' to allow .pyc and .pyo files without +# a source .py file to be detected as revisions in the +# versions/ directory +# sourceless = false + +# version location specification; This defaults +# to /versions. When using multiple version +# directories, initial revisions must be specified with --version-path. +# The path separator used here should be the separator specified by "path_separator" +# below. +# version_locations = %(here)s/bar:%(here)s/bat:%(here)s/alembic/versions + +# path_separator; This indicates what character is used to split lists of file +# paths, including version_locations and prepend_sys_path within configparser +# files such as alembic.ini. +# The default rendered in new alembic.ini files is "os", which uses os.pathsep +# to provide os-dependent path splitting. +# +# Note that in order to support legacy alembic.ini files, this default does NOT +# take place if path_separator is not present in alembic.ini. If this +# option is omitted entirely, fallback logic is as follows: +# +# 1. Parsing of the version_locations option falls back to using the legacy +# "version_path_separator" key, which if absent then falls back to the legacy +# behavior of splitting on spaces and/or commas. +# 2. Parsing of the prepend_sys_path option falls back to the legacy +# behavior of splitting on spaces, commas, or colons. +# +# Valid values for path_separator are: +# +# path_separator = : +# path_separator = ; +# path_separator = space +# path_separator = newline +# +# Use os.pathsep. Default configuration used for new projects. +path_separator = os + +# set to 'true' to search source files recursively +# in each "version_locations" directory +# new in Alembic version 1.10 +# recursive_version_locations = false + +# the output encoding used when revision files +# are written from script.py.mako +# output_encoding = utf-8 + +# database URL. This is consumed by the user-maintained env.py script only. +# other means of configuring database URLs may be customized within the env.py +# file. +sqlalchemy.url = + + +[post_write_hooks] +# post_write_hooks defines scripts or Python functions that are run +# on newly generated revision scripts. See the documentation for further +# detail and examples + +# format using "black" - use the console_scripts runner, against the "black" entrypoint +# hooks = black +# black.type = console_scripts +# black.entrypoint = black +# black.options = -l 79 REVISION_SCRIPT_FILENAME + +# lint with attempts to fix using "ruff" - use the exec runner, execute a binary +# hooks = ruff +# ruff.type = exec +# ruff.executable = %(here)s/.venv/bin/ruff +# ruff.options = check --fix REVISION_SCRIPT_FILENAME + +# Logging configuration. This is also consumed by the user-maintained +# env.py script only. +[loggers] +keys = root,sqlalchemy,alembic + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = WARNING +handlers = console +qualname = + +[logger_sqlalchemy] +level = WARNING +handlers = +qualname = sqlalchemy.engine + +[logger_alembic] +level = INFO +handlers = +qualname = alembic + +[handler_console] +class = StreamHandler +args = (sys.stderr,) +level = NOTSET +formatter = generic + +[formatter_generic] +format = %(levelname)-5.5s [%(name)s] %(message)s +datefmt = %H:%M:%S