From 09912aaec8b62cd8f2d2d175e18b4720af11e0c3 Mon Sep 17 00:00:00 2001 From: cl0ete Date: Thu, 26 Sep 2024 14:39:24 +0200 Subject: [PATCH 01/56] add alembic to TR --- trustregistry/poetry.lock | 107 +++++++++++++++++++++++++++++++++++ trustregistry/pyproject.toml | 1 + 2 files changed, 108 insertions(+) diff --git a/trustregistry/poetry.lock b/trustregistry/poetry.lock index 37fcd1fcf..d003e2248 100644 --- a/trustregistry/poetry.lock +++ b/trustregistry/poetry.lock @@ -1,5 +1,24 @@ # This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +[[package]] +name = "alembic" +version = "1.13.3" +description = "A database migration tool for SQLAlchemy." +optional = false +python-versions = ">=3.8" +files = [ + {file = "alembic-1.13.3-py3-none-any.whl", hash = "sha256:908e905976d15235fae59c9ac42c4c5b75cfcefe3d27c0fbf7ae15a37715d80e"}, + {file = "alembic-1.13.3.tar.gz", hash = "sha256:203503117415561e203aa14541740643a611f641517f0209fcae63e9fa09f1a2"}, +] + +[package.dependencies] +Mako = "*" +SQLAlchemy = ">=1.3.0" +typing-extensions = ">=4" + +[package.extras] +tz = ["backports.zoneinfo"] + [[package]] name = "annotated-types" version = "0.7.0" @@ -626,6 +645,94 @@ win32-setctime = {version = ">=1.0.0", markers = "sys_platform == \"win32\""} [package.extras] dev = ["Sphinx (==7.2.5)", "colorama (==0.4.5)", "colorama (==0.4.6)", "exceptiongroup (==1.1.3)", "freezegun (==1.1.0)", "freezegun (==1.2.2)", "mypy (==v0.910)", "mypy (==v0.971)", "mypy (==v1.4.1)", "mypy (==v1.5.1)", "pre-commit (==3.4.0)", "pytest (==6.1.2)", "pytest (==7.4.0)", "pytest-cov (==2.12.1)", "pytest-cov (==4.1.0)", "pytest-mypy-plugins (==1.9.3)", "pytest-mypy-plugins (==3.0.0)", "sphinx-autobuild (==2021.3.14)", "sphinx-rtd-theme (==1.3.0)", "tox (==3.27.1)", "tox (==4.11.0)"] +[[package]] +name = "mako" +version = "1.3.5" +description = "A super-fast templating language that borrows the best ideas from the existing templating languages." +optional = false +python-versions = ">=3.8" +files = [ + {file = "Mako-1.3.5-py3-none-any.whl", hash = "sha256:260f1dbc3a519453a9c856dedfe4beb4e50bd5a26d96386cb6c80856556bb91a"}, + {file = "Mako-1.3.5.tar.gz", hash = "sha256:48dbc20568c1d276a2698b36d968fa76161bf127194907ea6fc594fa81f943bc"}, +] + +[package.dependencies] +MarkupSafe = ">=0.9.2" + +[package.extras] +babel = ["Babel"] +lingua = ["lingua"] +testing = ["pytest"] + +[[package]] +name = "markupsafe" +version = "2.1.5" +description = "Safely add untrusted strings to HTML/XML markup." +optional = false +python-versions = ">=3.7" +files = [ + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, + {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, +] + [[package]] name = "mccabe" version = "0.7.0" diff --git a/trustregistry/pyproject.toml b/trustregistry/pyproject.toml index 851e593a4..8233f686e 100644 --- a/trustregistry/pyproject.toml +++ b/trustregistry/pyproject.toml @@ -18,6 +18,7 @@ sqlalchemy = "~=2.0.19" uvicorn = { version = "~0.31.0" } ddtrace = "^2.14.0" scalar-fastapi = "^1.0.3" +alembic = "~1.13.2" [tool.poetry.dev-dependencies] anyio = "~4.6.0" From dfc0bf4601192a05cdd51508b4808eb3ca82a27b Mon Sep 17 00:00:00 2001 From: cl0ete Date: Thu, 26 Sep 2024 14:40:02 +0200 Subject: [PATCH 02/56] run alembic init --- trustregistry/alembic.ini | 117 ++++++++++++++++++++++++ trustregistry/migrations/README | 1 + trustregistry/migrations/env.py | 103 +++++++++++++++++++++ trustregistry/migrations/script.py.mako | 26 ++++++ 4 files changed, 247 insertions(+) create mode 100644 trustregistry/alembic.ini create mode 100644 trustregistry/migrations/README create mode 100644 trustregistry/migrations/env.py create mode 100644 trustregistry/migrations/script.py.mako diff --git a/trustregistry/alembic.ini b/trustregistry/alembic.ini new file mode 100644 index 000000000..053a02703 --- /dev/null +++ b/trustregistry/alembic.ini @@ -0,0 +1,117 @@ +# A generic, single database configuration. + +[alembic] +# path to migration scripts +# Use forward slashes (/) also on windows to provide an os agnostic path +script_location = migrations + +# 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. +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. +# 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 migrations/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 "version_path_separator" below. +# version_locations = %(here)s/bar:%(here)s/bat:migrations/versions + +# version path separator; As mentioned above, this is the character used to split +# version_locations. The default within new alembic.ini files is "os", which uses os.pathsep. +# If this key is omitted entirely, it falls back to the legacy behavior of splitting on spaces and/or commas. +# Valid values for version_path_separator are: +# +# version_path_separator = : +# version_path_separator = ; +# version_path_separator = space +# version_path_separator = newline +version_path_separator = os # Use os.pathsep. Default configuration used for new projects. + +# 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 + +sqlalchemy.url = postgresql://trustregistry:trustregistry@0.0.0.0:5432/trustregistry + + +[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 = --fix REVISION_SCRIPT_FILENAME + +# Logging configuration +[loggers] +keys = root,sqlalchemy,alembic + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = WARN +handlers = console +qualname = + +[logger_sqlalchemy] +level = WARN +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 diff --git a/trustregistry/migrations/README b/trustregistry/migrations/README new file mode 100644 index 000000000..98e4f9c44 --- /dev/null +++ b/trustregistry/migrations/README @@ -0,0 +1 @@ +Generic single-database configuration. \ No newline at end of file diff --git a/trustregistry/migrations/env.py b/trustregistry/migrations/env.py new file mode 100644 index 000000000..157f53729 --- /dev/null +++ b/trustregistry/migrations/env.py @@ -0,0 +1,103 @@ +import os +from logging.config import fileConfig +from shared.log_config import get_logger + +from sqlalchemy import engine_from_config +from sqlalchemy import pool + +from alembic import context +from trustregistry.db import Base +# this is the Alembic Config object, which provides +# access to the values within the .ini file in use. +config = context.config + +#Get db url from environment variable +db_url = os.environ.get('POSTGRES_DATABASE_URL', "test123") +print(f"db_url: {db_url}") +if db_url: + config.set_main_option('sqlalchemy.url', db_url) + +# Interpret the config file for Python logging. +# This line sets up loggers basically. +if config.config_file_name is not None: + fileConfig(config.config_file_name) + +logger = get_logger(__name__) + + +# Get the database URL from environment variable +db_url = os.environ.get('POSTGRES_DATABASE_URL') + +if db_url: + logger.info(f"Using database URL from environment: {db_url}") + config.set_main_option('sqlalchemy.url', db_url) +else: + logger.warning("POSTGRES_DATABASE_URL not set in environment. Using default URL from alembic.ini") + db_url = config.get_main_option('sqlalchemy.url') + +# Verify that we have a valid database URL +if not db_url: + raise ValueError("Database URL is not set. Please set POSTGRES_DATABASE_URL environment variable or provide a valid sqlalchemy.url in alembic.ini") + +# add your model's MetaData object here +# for 'autogenerate' support +# from myapp import mymodel +# target_metadata = mymodel.Base.metadata +target_metadata = Base.metadata + +# other values from the config, defined by the needs of env.py, +# can be acquired: +# my_important_option = config.get_main_option("my_important_option") +# ... etc. + + +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. + + """ + url = config.get_main_option("sqlalchemy.url") + context.configure( + url=url, + target_metadata=target_metadata, + literal_binds=True, + dialect_opts={"paramstyle": "named"}, + ) + + with context.begin_transaction(): + context.run_migrations() + + +def run_migrations_online() -> None: + """Run migrations in 'online' mode. + + In this scenario we need to create an Engine + and associate a connection with the context. + + """ + connectable = engine_from_config( + config.get_section(config.config_ini_section, {}), + prefix="sqlalchemy.", + poolclass=pool.NullPool, + ) + + with connectable.connect() as connection: + context.configure( + connection=connection, target_metadata=target_metadata + ) + + with context.begin_transaction(): + context.run_migrations() + + +if context.is_offline_mode(): + run_migrations_offline() +else: + run_migrations_online() diff --git a/trustregistry/migrations/script.py.mako b/trustregistry/migrations/script.py.mako new file mode 100644 index 000000000..fbc4b07dc --- /dev/null +++ b/trustregistry/migrations/script.py.mako @@ -0,0 +1,26 @@ +"""${message} + +Revision ID: ${up_revision} +Revises: ${down_revision | comma,n} +Create Date: ${create_date} + +""" +from typing import Sequence, Union + +from alembic import op +import sqlalchemy as sa +${imports if imports else ""} + +# revision identifiers, used by Alembic. +revision: str = ${repr(up_revision)} +down_revision: Union[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)} + + +def upgrade() -> None: + ${upgrades if upgrades else "pass"} + + +def downgrade() -> None: + ${downgrades if downgrades else "pass"} From 275581422d9a179a76236402ff6e0fadd7def256 Mon Sep 17 00:00:00 2001 From: cl0ete Date: Thu, 26 Sep 2024 14:40:35 +0200 Subject: [PATCH 03/56] create initial migration --- .../versions/fd3e6dc8a75a_initial_schema.py | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 trustregistry/migrations/versions/fd3e6dc8a75a_initial_schema.py diff --git a/trustregistry/migrations/versions/fd3e6dc8a75a_initial_schema.py b/trustregistry/migrations/versions/fd3e6dc8a75a_initial_schema.py new file mode 100644 index 000000000..8ad7dbafe --- /dev/null +++ b/trustregistry/migrations/versions/fd3e6dc8a75a_initial_schema.py @@ -0,0 +1,63 @@ +"""Initial schema + +Revision ID: fd3e6dc8a75a +Revises: +Create Date: 2024-09-26 13:38:19.138285 + +""" +from typing import Sequence, Union +import trustregistry.list_type +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision: str = 'fd3e6dc8a75a' +down_revision: Union[str, None] = None +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.create_table('actors', + sa.Column('id', sa.String(), nullable=False), + sa.Column('name', sa.String(), nullable=False), + sa.Column('roles', trustregistry.list_type.StringList(), nullable=False), + sa.Column('didcomm_invitation', sa.String(), nullable=True), + sa.Column('did', sa.String(), nullable=False), + sa.PrimaryKeyConstraint('id') + ) + op.create_index(op.f('ix_actors_did'), 'actors', ['did'], unique=True) + op.create_index(op.f('ix_actors_didcomm_invitation'), 'actors', ['didcomm_invitation'], unique=True) + op.create_index(op.f('ix_actors_id'), 'actors', ['id'], unique=True) + op.create_index(op.f('ix_actors_name'), 'actors', ['name'], unique=True) + op.create_index(op.f('ix_actors_roles'), 'actors', ['roles'], unique=False) + op.create_table('schemas', + sa.Column('id', sa.String(), nullable=False), + sa.Column('did', sa.String(), nullable=False), + sa.Column('name', sa.String(), nullable=False), + sa.Column('version', sa.String(), nullable=False), + sa.PrimaryKeyConstraint('id') + ) + op.create_index(op.f('ix_schemas_did'), 'schemas', ['did'], unique=False) + op.create_index(op.f('ix_schemas_id'), 'schemas', ['id'], unique=True) + op.create_index(op.f('ix_schemas_name'), 'schemas', ['name'], unique=False) + op.create_index(op.f('ix_schemas_version'), 'schemas', ['version'], unique=False) + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.drop_index(op.f('ix_schemas_version'), table_name='schemas') + op.drop_index(op.f('ix_schemas_name'), table_name='schemas') + op.drop_index(op.f('ix_schemas_id'), table_name='schemas') + op.drop_index(op.f('ix_schemas_did'), table_name='schemas') + op.drop_table('schemas') + op.drop_index(op.f('ix_actors_roles'), table_name='actors') + op.drop_index(op.f('ix_actors_name'), table_name='actors') + op.drop_index(op.f('ix_actors_id'), table_name='actors') + op.drop_index(op.f('ix_actors_didcomm_invitation'), table_name='actors') + op.drop_index(op.f('ix_actors_did'), table_name='actors') + op.drop_table('actors') + # ### end Alembic commands ### From 10b42cca731f45ab5abd8a0593c21f4559d16ee1 Mon Sep 17 00:00:00 2001 From: cl0ete Date: Thu, 26 Sep 2024 14:41:35 +0200 Subject: [PATCH 04/56] :art: --- trustregistry/migrations/env.py | 32 ++++---- .../versions/fd3e6dc8a75a_initial_schema.py | 81 ++++++++++--------- 2 files changed, 62 insertions(+), 51 deletions(-) diff --git a/trustregistry/migrations/env.py b/trustregistry/migrations/env.py index 157f53729..6fdb11dbf 100644 --- a/trustregistry/migrations/env.py +++ b/trustregistry/migrations/env.py @@ -1,21 +1,21 @@ import os from logging.config import fileConfig -from shared.log_config import get_logger - -from sqlalchemy import engine_from_config -from sqlalchemy import pool from alembic import context +from sqlalchemy import engine_from_config, pool + +from shared.log_config import get_logger from trustregistry.db import Base + # this is the Alembic Config object, which provides # access to the values within the .ini file in use. config = context.config -#Get db url from environment variable -db_url = os.environ.get('POSTGRES_DATABASE_URL', "test123") +# Get db url from environment variable +db_url = os.environ.get("POSTGRES_DATABASE_URL", "test123") print(f"db_url: {db_url}") if db_url: - config.set_main_option('sqlalchemy.url', db_url) + config.set_main_option("sqlalchemy.url", db_url) # Interpret the config file for Python logging. # This line sets up loggers basically. @@ -26,18 +26,22 @@ # Get the database URL from environment variable -db_url = os.environ.get('POSTGRES_DATABASE_URL') +db_url = os.environ.get("POSTGRES_DATABASE_URL") if db_url: logger.info(f"Using database URL from environment: {db_url}") - config.set_main_option('sqlalchemy.url', db_url) + config.set_main_option("sqlalchemy.url", db_url) else: - logger.warning("POSTGRES_DATABASE_URL not set in environment. Using default URL from alembic.ini") - db_url = config.get_main_option('sqlalchemy.url') + logger.warning( + "POSTGRES_DATABASE_URL not set in environment. Using default URL from alembic.ini" + ) + db_url = config.get_main_option("sqlalchemy.url") # Verify that we have a valid database URL if not db_url: - raise ValueError("Database URL is not set. Please set POSTGRES_DATABASE_URL environment variable or provide a valid sqlalchemy.url in alembic.ini") + raise ValueError( + "Database URL is not set. Please set POSTGRES_DATABASE_URL environment variable or provide a valid sqlalchemy.url in alembic.ini" + ) # add your model's MetaData object here # for 'autogenerate' support @@ -89,9 +93,7 @@ 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) with context.begin_transaction(): context.run_migrations() diff --git a/trustregistry/migrations/versions/fd3e6dc8a75a_initial_schema.py b/trustregistry/migrations/versions/fd3e6dc8a75a_initial_schema.py index 8ad7dbafe..8b4727ed6 100644 --- a/trustregistry/migrations/versions/fd3e6dc8a75a_initial_schema.py +++ b/trustregistry/migrations/versions/fd3e6dc8a75a_initial_schema.py @@ -5,14 +5,16 @@ Create Date: 2024-09-26 13:38:19.138285 """ + from typing import Sequence, Union -import trustregistry.list_type -from alembic import op + import sqlalchemy as sa +from alembic import op +import trustregistry.list_type # revision identifiers, used by Alembic. -revision: str = 'fd3e6dc8a75a' +revision: str = "fd3e6dc8a75a" down_revision: Union[str, None] = None branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None @@ -20,44 +22,51 @@ def upgrade() -> None: # ### commands auto generated by Alembic - please adjust! ### - op.create_table('actors', - sa.Column('id', sa.String(), nullable=False), - sa.Column('name', sa.String(), nullable=False), - sa.Column('roles', trustregistry.list_type.StringList(), nullable=False), - sa.Column('didcomm_invitation', sa.String(), nullable=True), - sa.Column('did', sa.String(), nullable=False), - sa.PrimaryKeyConstraint('id') + op.create_table( + "actors", + sa.Column("id", sa.String(), nullable=False), + sa.Column("name", sa.String(), nullable=False), + sa.Column("roles", trustregistry.list_type.StringList(), nullable=False), + sa.Column("didcomm_invitation", sa.String(), nullable=True), + sa.Column("did", sa.String(), nullable=False), + sa.PrimaryKeyConstraint("id"), + ) + op.create_index(op.f("ix_actors_did"), "actors", ["did"], unique=True) + op.create_index( + op.f("ix_actors_didcomm_invitation"), + "actors", + ["didcomm_invitation"], + unique=True, ) - op.create_index(op.f('ix_actors_did'), 'actors', ['did'], unique=True) - op.create_index(op.f('ix_actors_didcomm_invitation'), 'actors', ['didcomm_invitation'], unique=True) - op.create_index(op.f('ix_actors_id'), 'actors', ['id'], unique=True) - op.create_index(op.f('ix_actors_name'), 'actors', ['name'], unique=True) - op.create_index(op.f('ix_actors_roles'), 'actors', ['roles'], unique=False) - op.create_table('schemas', - sa.Column('id', sa.String(), nullable=False), - sa.Column('did', sa.String(), nullable=False), - sa.Column('name', sa.String(), nullable=False), - sa.Column('version', sa.String(), nullable=False), - sa.PrimaryKeyConstraint('id') + op.create_index(op.f("ix_actors_id"), "actors", ["id"], unique=True) + op.create_index(op.f("ix_actors_name"), "actors", ["name"], unique=True) + op.create_index(op.f("ix_actors_roles"), "actors", ["roles"], unique=False) + op.create_table( + "schemas", + sa.Column("id", sa.String(), nullable=False), + sa.Column("did", sa.String(), nullable=False), + sa.Column("name", sa.String(), nullable=False), + sa.Column("version", sa.String(), nullable=False), + sa.PrimaryKeyConstraint("id"), ) - op.create_index(op.f('ix_schemas_did'), 'schemas', ['did'], unique=False) - op.create_index(op.f('ix_schemas_id'), 'schemas', ['id'], unique=True) - op.create_index(op.f('ix_schemas_name'), 'schemas', ['name'], unique=False) - op.create_index(op.f('ix_schemas_version'), 'schemas', ['version'], unique=False) + op.create_index(op.f("ix_schemas_did"), "schemas", ["did"], unique=False) + op.create_index(op.f("ix_schemas_id"), "schemas", ["id"], unique=True) + op.create_index(op.f("ix_schemas_name"), "schemas", ["name"], unique=False) + op.create_index(op.f("ix_schemas_version"), "schemas", ["version"], unique=False) # ### end Alembic commands ### def downgrade() -> None: # ### commands auto generated by Alembic - please adjust! ### - op.drop_index(op.f('ix_schemas_version'), table_name='schemas') - op.drop_index(op.f('ix_schemas_name'), table_name='schemas') - op.drop_index(op.f('ix_schemas_id'), table_name='schemas') - op.drop_index(op.f('ix_schemas_did'), table_name='schemas') - op.drop_table('schemas') - op.drop_index(op.f('ix_actors_roles'), table_name='actors') - op.drop_index(op.f('ix_actors_name'), table_name='actors') - op.drop_index(op.f('ix_actors_id'), table_name='actors') - op.drop_index(op.f('ix_actors_didcomm_invitation'), table_name='actors') - op.drop_index(op.f('ix_actors_did'), table_name='actors') - op.drop_table('actors') + op.drop_index(op.f("ix_schemas_version"), table_name="schemas") + op.drop_index(op.f("ix_schemas_name"), table_name="schemas") + op.drop_index(op.f("ix_schemas_id"), table_name="schemas") + op.drop_index(op.f("ix_schemas_did"), table_name="schemas") + op.drop_table("schemas") + op.drop_index(op.f("ix_actors_roles"), table_name="actors") + op.drop_index(op.f("ix_actors_name"), table_name="actors") + op.drop_index(op.f("ix_actors_id"), table_name="actors") + op.drop_index(op.f("ix_actors_didcomm_invitation"), table_name="actors") + op.drop_index(op.f("ix_actors_did"), table_name="actors") + op.drop_table("actors") # ### end Alembic commands ### From b6670b2c919dc0acb4f5cc80d9f5a9eb3c40cb57 Mon Sep 17 00:00:00 2001 From: cl0ete Date: Thu, 26 Sep 2024 14:42:29 +0200 Subject: [PATCH 05/56] alembic creates the tables now --- trustregistry/main.py | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/trustregistry/main.py b/trustregistry/main.py index 03b9320ef..b0862459f 100644 --- a/trustregistry/main.py +++ b/trustregistry/main.py @@ -1,14 +1,19 @@ import os from contextlib import asynccontextmanager +from alembic import command +from alembic.config import Config +from alembic.migration import MigrationContext +from alembic.script import ScriptDirectory from fastapi import Depends, FastAPI from scalar_fastapi import get_scalar_api_reference from sqlalchemy import inspect +from sqlalchemy.engine import Engine from sqlalchemy.orm import Session from shared.constants import PROJECT_VERSION from shared.log_config import get_logger -from trustregistry import crud, db +from trustregistry import crud from trustregistry.database import engine from trustregistry.db import get_db from trustregistry.registry import registry_actors, registry_schemas @@ -19,10 +24,42 @@ ROOT_PATH = os.getenv("ROOT_PATH", "") +def check_migrations(engine: Engine) -> bool: + # Check if alembic_version table exists + with engine.connect() as connection: + inspector = inspect(connection) + has_alembic_version = "alembic_version" in inspector.get_table_names() + + if not has_alembic_version: + return False + + # Get current revision + with engine.connect() as connection: + context = MigrationContext.configure(connection) + current_rev = context.get_current_revision() + + # Get head revision + alembic_cfg = Config("alembic.ini") + script = ScriptDirectory.from_config(alembic_cfg) + head_rev = script.get_current_head() + + return current_rev == head_rev + + @asynccontextmanager async def lifespan(_: FastAPI): - db.Base.metadata.create_all(bind=engine) - engine.dispose() + alembic_cfg = Config("alembic.ini") + + if not check_migrations(engine): + logger.info("Applying database migrations...") + try: + command.upgrade(alembic_cfg, "head") + except Exception as e: + logger.error("Error applying database migrations: {}", e) + raise e + logger.info("Database migrations applied successfully.") + else: + logger.info("Database is up to date. No migrations needed.") logger.debug("TrustRegistry startup: Validate tables are created") with engine.connect() as connection: From ae29e38afc068525bb354115aaf40c13e4719f99 Mon Sep 17 00:00:00 2001 From: cl0ete Date: Thu, 26 Sep 2024 15:45:02 +0200 Subject: [PATCH 06/56] # pylint: disable=redefined-outer-name --- trustregistry/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trustregistry/main.py b/trustregistry/main.py index b0862459f..b8484f301 100644 --- a/trustregistry/main.py +++ b/trustregistry/main.py @@ -24,7 +24,7 @@ ROOT_PATH = os.getenv("ROOT_PATH", "") -def check_migrations(engine: Engine) -> bool: +def check_migrations(engine: Engine) -> bool: # pylint: disable=redefined-outer-name # Check if alembic_version table exists with engine.connect() as connection: inspector = inspect(connection) From 6396e693aea32d557bdc39f45caad83c026bdbff Mon Sep 17 00:00:00 2001 From: cl0ete Date: Thu, 26 Sep 2024 15:45:13 +0200 Subject: [PATCH 07/56] :art: --- trustregistry/migrations/env.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/trustregistry/migrations/env.py b/trustregistry/migrations/env.py index 6fdb11dbf..d82934d9f 100644 --- a/trustregistry/migrations/env.py +++ b/trustregistry/migrations/env.py @@ -40,7 +40,8 @@ # Verify that we have a valid database URL if not db_url: raise ValueError( - "Database URL is not set. Please set POSTGRES_DATABASE_URL environment variable or provide a valid sqlalchemy.url in alembic.ini" + "Database URL is not set. Please set POSTGRES_DATABASE_URL environment \ + variable or provide a valid sqlalchemy.url in alembic.ini" ) # add your model's MetaData object here From cb307a5202a4773372345cb7e1b34955afe7766a Mon Sep 17 00:00:00 2001 From: cl0ete Date: Fri, 27 Sep 2024 07:30:48 +0200 Subject: [PATCH 08/56] stamp the db --- trustregistry/main.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/trustregistry/main.py b/trustregistry/main.py index b8484f301..7165008c9 100644 --- a/trustregistry/main.py +++ b/trustregistry/main.py @@ -8,6 +8,7 @@ from fastapi import Depends, FastAPI from scalar_fastapi import get_scalar_api_reference from sqlalchemy import inspect +from sqlalchemy.exc import ProgrammingError from sqlalchemy.engine import Engine from sqlalchemy.orm import Session @@ -53,11 +54,17 @@ async def lifespan(_: FastAPI): if not check_migrations(engine): logger.info("Applying database migrations...") try: + logger.info("Checking and applying database migrations...") command.upgrade(alembic_cfg, "head") - except Exception as e: - logger.error("Error applying database migrations: {}", e) - raise e - logger.info("Database migrations applied successfully.") + logger.info("Database schema is up to date.") + except ProgrammingError as e: + if 'already exists' in str(e): + logger.warning("Database schema already exists. Stamping with current version.") + command.stamp(alembic_cfg, "head") + logger.info("Database stamped with current migration version.") + else: + logger.error(f"Unexpected error during migration: {e}") + raise else: logger.info("Database is up to date. No migrations needed.") From 904b43c11b2f640766239470b62843c11ef800d0 Mon Sep 17 00:00:00 2001 From: cl0ete Date: Fri, 27 Sep 2024 07:31:10 +0200 Subject: [PATCH 09/56] :art: --- trustregistry/main.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/trustregistry/main.py b/trustregistry/main.py index 7165008c9..b56bdb0a4 100644 --- a/trustregistry/main.py +++ b/trustregistry/main.py @@ -8,8 +8,8 @@ from fastapi import Depends, FastAPI from scalar_fastapi import get_scalar_api_reference from sqlalchemy import inspect -from sqlalchemy.exc import ProgrammingError from sqlalchemy.engine import Engine +from sqlalchemy.exc import ProgrammingError from sqlalchemy.orm import Session from shared.constants import PROJECT_VERSION @@ -58,8 +58,10 @@ async def lifespan(_: FastAPI): command.upgrade(alembic_cfg, "head") logger.info("Database schema is up to date.") except ProgrammingError as e: - if 'already exists' in str(e): - logger.warning("Database schema already exists. Stamping with current version.") + if "already exists" in str(e): + logger.warning( + "Database schema already exists. Stamping with current version." + ) command.stamp(alembic_cfg, "head") logger.info("Database stamped with current migration version.") else: From e0e4aa6a5f606c3616251bd7848f94e1a7ce1ae0 Mon Sep 17 00:00:00 2001 From: cl0ete Date: Wed, 9 Oct 2024 12:59:53 +0200 Subject: [PATCH 10/56] poetry lock --- trustregistry/poetry.lock | 125 +++++++++++++++++++------------------- 1 file changed, 63 insertions(+), 62 deletions(-) diff --git a/trustregistry/poetry.lock b/trustregistry/poetry.lock index d003e2248..8e33fac85 100644 --- a/trustregistry/poetry.lock +++ b/trustregistry/poetry.lock @@ -666,71 +666,72 @@ testing = ["pytest"] [[package]] name = "markupsafe" -version = "2.1.5" +version = "3.0.1" description = "Safely add untrusted strings to HTML/XML markup." optional = false -python-versions = ">=3.7" +python-versions = ">=3.9" files = [ - {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, - {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, - {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, - {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, - {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, - {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, - {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, - {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, + {file = "MarkupSafe-3.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:db842712984e91707437461930e6011e60b39136c7331e971952bb30465bc1a1"}, + {file = "MarkupSafe-3.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3ffb4a8e7d46ed96ae48805746755fadd0909fea2306f93d5d8233ba23dda12a"}, + {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:67c519635a4f64e495c50e3107d9b4075aec33634272b5db1cde839e07367589"}, + {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:48488d999ed50ba8d38c581d67e496f955821dc183883550a6fbc7f1aefdc170"}, + {file = "MarkupSafe-3.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f31ae06f1328595d762c9a2bf29dafd8621c7d3adc130cbb46278079758779ca"}, + {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:80fcbf3add8790caddfab6764bde258b5d09aefbe9169c183f88a7410f0f6dea"}, + {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3341c043c37d78cc5ae6e3e305e988532b072329639007fd408a476642a89fd6"}, + {file = "MarkupSafe-3.0.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cb53e2a99df28eee3b5f4fea166020d3ef9116fdc5764bc5117486e6d1211b25"}, + {file = "MarkupSafe-3.0.1-cp310-cp310-win32.whl", hash = "sha256:db15ce28e1e127a0013dfb8ac243a8e392db8c61eae113337536edb28bdc1f97"}, + {file = "MarkupSafe-3.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:4ffaaac913c3f7345579db4f33b0020db693f302ca5137f106060316761beea9"}, + {file = "MarkupSafe-3.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:26627785a54a947f6d7336ce5963569b5d75614619e75193bdb4e06e21d447ad"}, + {file = "MarkupSafe-3.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b954093679d5750495725ea6f88409946d69cfb25ea7b4c846eef5044194f583"}, + {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:973a371a55ce9ed333a3a0f8e0bcfae9e0d637711534bcb11e130af2ab9334e7"}, + {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:244dbe463d5fb6d7ce161301a03a6fe744dac9072328ba9fc82289238582697b"}, + {file = "MarkupSafe-3.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d98e66a24497637dd31ccab090b34392dddb1f2f811c4b4cd80c230205c074a3"}, + {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ad91738f14eb8da0ff82f2acd0098b6257621410dcbd4df20aaa5b4233d75a50"}, + {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7044312a928a66a4c2a22644147bc61a199c1709712069a344a3fb5cfcf16915"}, + {file = "MarkupSafe-3.0.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a4792d3b3a6dfafefdf8e937f14906a51bd27025a36f4b188728a73382231d91"}, + {file = "MarkupSafe-3.0.1-cp311-cp311-win32.whl", hash = "sha256:fa7d686ed9883f3d664d39d5a8e74d3c5f63e603c2e3ff0abcba23eac6542635"}, + {file = "MarkupSafe-3.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:9ba25a71ebf05b9bb0e2ae99f8bc08a07ee8e98c612175087112656ca0f5c8bf"}, + {file = "MarkupSafe-3.0.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:8ae369e84466aa70f3154ee23c1451fda10a8ee1b63923ce76667e3077f2b0c4"}, + {file = "MarkupSafe-3.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40f1e10d51c92859765522cbd79c5c8989f40f0419614bcdc5015e7b6bf97fc5"}, + {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a4cb365cb49b750bdb60b846b0c0bc49ed62e59a76635095a179d440540c346"}, + {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee3941769bd2522fe39222206f6dd97ae83c442a94c90f2b7a25d847d40f4729"}, + {file = "MarkupSafe-3.0.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62fada2c942702ef8952754abfc1a9f7658a4d5460fabe95ac7ec2cbe0d02abc"}, + {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4c2d64fdba74ad16138300815cfdc6ab2f4647e23ced81f59e940d7d4a1469d9"}, + {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:fb532dd9900381d2e8f48172ddc5a59db4c445a11b9fab40b3b786da40d3b56b"}, + {file = "MarkupSafe-3.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0f84af7e813784feb4d5e4ff7db633aba6c8ca64a833f61d8e4eade234ef0c38"}, + {file = "MarkupSafe-3.0.1-cp312-cp312-win32.whl", hash = "sha256:cbf445eb5628981a80f54087f9acdbf84f9b7d862756110d172993b9a5ae81aa"}, + {file = "MarkupSafe-3.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:a10860e00ded1dd0a65b83e717af28845bb7bd16d8ace40fe5531491de76b79f"}, + {file = "MarkupSafe-3.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e81c52638315ff4ac1b533d427f50bc0afc746deb949210bc85f05d4f15fd772"}, + {file = "MarkupSafe-3.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:312387403cd40699ab91d50735ea7a507b788091c416dd007eac54434aee51da"}, + {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ae99f31f47d849758a687102afdd05bd3d3ff7dbab0a8f1587981b58a76152a"}, + {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c97ff7fedf56d86bae92fa0a646ce1a0ec7509a7578e1ed238731ba13aabcd1c"}, + {file = "MarkupSafe-3.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7420ceda262dbb4b8d839a4ec63d61c261e4e77677ed7c66c99f4e7cb5030dd"}, + {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:45d42d132cff577c92bfba536aefcfea7e26efb975bd455db4e6602f5c9f45e7"}, + {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4c8817557d0de9349109acb38b9dd570b03cc5014e8aabf1cbddc6e81005becd"}, + {file = "MarkupSafe-3.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a54c43d3ec4cf2a39f4387ad044221c66a376e58c0d0e971d47c475ba79c6b5"}, + {file = "MarkupSafe-3.0.1-cp313-cp313-win32.whl", hash = "sha256:c91b394f7601438ff79a4b93d16be92f216adb57d813a78be4446fe0f6bc2d8c"}, + {file = "MarkupSafe-3.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:fe32482b37b4b00c7a52a07211b479653b7fe4f22b2e481b9a9b099d8a430f2f"}, + {file = "MarkupSafe-3.0.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:17b2aea42a7280db02ac644db1d634ad47dcc96faf38ab304fe26ba2680d359a"}, + {file = "MarkupSafe-3.0.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:852dc840f6d7c985603e60b5deaae1d89c56cb038b577f6b5b8c808c97580f1d"}, + {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0778de17cff1acaeccc3ff30cd99a3fd5c50fc58ad3d6c0e0c4c58092b859396"}, + {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:800100d45176652ded796134277ecb13640c1a537cad3b8b53da45aa96330453"}, + {file = "MarkupSafe-3.0.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d06b24c686a34c86c8c1fba923181eae6b10565e4d80bdd7bc1c8e2f11247aa4"}, + {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:33d1c36b90e570ba7785dacd1faaf091203d9942bc036118fab8110a401eb1a8"}, + {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:beeebf760a9c1f4c07ef6a53465e8cfa776ea6a2021eda0d0417ec41043fe984"}, + {file = "MarkupSafe-3.0.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:bbde71a705f8e9e4c3e9e33db69341d040c827c7afa6789b14c6e16776074f5a"}, + {file = "MarkupSafe-3.0.1-cp313-cp313t-win32.whl", hash = "sha256:82b5dba6eb1bcc29cc305a18a3c5365d2af06ee71b123216416f7e20d2a84e5b"}, + {file = "MarkupSafe-3.0.1-cp313-cp313t-win_amd64.whl", hash = "sha256:730d86af59e0e43ce277bb83970530dd223bf7f2a838e086b50affa6ec5f9295"}, + {file = "MarkupSafe-3.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:4935dd7883f1d50e2ffecca0aa33dc1946a94c8f3fdafb8df5c330e48f71b132"}, + {file = "MarkupSafe-3.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e9393357f19954248b00bed7c56f29a25c930593a77630c719653d51e7669c2a"}, + {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40621d60d0e58aa573b68ac5e2d6b20d44392878e0bfc159012a5787c4e35bc8"}, + {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f94190df587738280d544971500b9cafc9b950d32efcb1fba9ac10d84e6aa4e6"}, + {file = "MarkupSafe-3.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b6a387d61fe41cdf7ea95b38e9af11cfb1a63499af2759444b99185c4ab33f5b"}, + {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:8ad4ad1429cd4f315f32ef263c1342166695fad76c100c5d979c45d5570ed58b"}, + {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e24bfe89c6ac4c31792793ad9f861b8f6dc4546ac6dc8f1c9083c7c4f2b335cd"}, + {file = "MarkupSafe-3.0.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2a4b34a8d14649315c4bc26bbfa352663eb51d146e35eef231dd739d54a5430a"}, + {file = "MarkupSafe-3.0.1-cp39-cp39-win32.whl", hash = "sha256:242d6860f1fd9191aef5fae22b51c5c19767f93fb9ead4d21924e0bcb17619d8"}, + {file = "MarkupSafe-3.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:93e8248d650e7e9d49e8251f883eed60ecbc0e8ffd6349e18550925e31bd029b"}, + {file = "markupsafe-3.0.1.tar.gz", hash = "sha256:3e683ee4f5d0fa2dde4db77ed8dd8a876686e3fc417655c2ece9a90576905344"}, ] [[package]] From 842bb1e1625a0277770e54941f3c29f6cf15e71a Mon Sep 17 00:00:00 2001 From: cl0ete Date: Wed, 9 Oct 2024 14:57:38 +0200 Subject: [PATCH 11/56] update test for new alembic code --- trustregistry/tests/test_main.py | 147 ++++++++++++++++++++++++++++--- 1 file changed, 137 insertions(+), 10 deletions(-) diff --git a/trustregistry/tests/test_main.py b/trustregistry/tests/test_main.py index 7c10e36b8..652af3304 100644 --- a/trustregistry/tests/test_main.py +++ b/trustregistry/tests/test_main.py @@ -2,10 +2,11 @@ import pytest from fastapi import FastAPI +from sqlalchemy.exc import ProgrammingError from sqlalchemy.orm import Session from trustregistry import db -from trustregistry.main import app, lifespan, registry, root +from trustregistry.main import app, check_migrations, lifespan, registry, root @pytest.fixture @@ -19,28 +20,154 @@ def test_create_app(): routes = [route.path for route in app.routes] - expected_routes = ["/", "/registry"] + expected_routes = ["/", "/registry", "/docs"] for route in expected_routes: assert route in routes -@patch("trustregistry.main.inspect") +@pytest.mark.anyio +@patch("trustregistry.main.engine") +@patch("trustregistry.main.check_migrations") +@patch("trustregistry.main.Config") +@patch("trustregistry.main.command") +@patch("trustregistry.main.logger") +async def test_lifespan_migrations_needed( + mock_logger, mock_command, mock_config, mock_check_migrations, mock_engine +): + mock_check_migrations.return_value = False + mock_config.return_value = MagicMock() + + async with lifespan(FastAPI()): + pass + + mock_command.upgrade.assert_called_once_with(mock_config.return_value, "head") + mock_logger.info.assert_any_call("Applying database migrations...") + mock_logger.info.assert_any_call("Database schema is up to date.") + + +@pytest.mark.anyio +@patch("trustregistry.main.engine") +@patch("trustregistry.main.check_migrations") +@patch("trustregistry.main.Config") +@patch("trustregistry.main.command") +@patch("trustregistry.main.logger") +async def test_lifespan_already_exists_error( + mock_logger, mock_command, mock_config, mock_check_migrations, mock_engine +): + mock_check_migrations.return_value = False + mock_config.return_value = MagicMock() + mock_command.upgrade.side_effect = ProgrammingError( + "Table already exists", None, None + ) + + async with lifespan(FastAPI()): + pass + + mock_command.stamp.assert_called_once_with(mock_config.return_value, "head") + mock_logger.warning.assert_called_once_with( + "Database schema already exists. Stamping with current version." + ) + mock_logger.info.assert_called_with( + "Database stamped with current migration version." + ) + + +@pytest.mark.anyio @patch("trustregistry.main.engine") +@patch("trustregistry.main.check_migrations") +@patch("trustregistry.main.Config") +@patch("trustregistry.main.command") +@patch("trustregistry.main.logger") +async def test_lifespan_unexpected_error( + mock_logger, mock_command, mock_config, mock_check_migrations, mock_engine +): + mock_check_migrations.return_value = False + mock_config.return_value = MagicMock() + mock_command.upgrade.side_effect = ProgrammingError("Unexpected error", None, None) + + with pytest.raises(ProgrammingError): + async with lifespan(FastAPI()): + pass + + mock_logger.error.assert_called_once() + + @pytest.mark.anyio -async def test_lifespan(mock_engine, mock_inspect): +@patch("trustregistry.main.engine") +@patch("trustregistry.main.check_migrations") +@patch("trustregistry.main.logger") +async def test_lifespan_no_migrations_needed( + mock_logger, mock_check_migrations, mock_engine +): + mock_check_migrations.return_value = True + + async with lifespan(FastAPI()): + pass + + mock_logger.info.assert_called_once_with( + "Database is up to date. No migrations needed." + ) + + +@pytest.mark.parametrize( + "table_names,current_rev,head_rev,expected", + [ + ([], None, None, False), # alembic_version table doesn't exist + ( + ["alembic_version"], + "current_rev", + "head_rev", + False, + ), # revisions don't match + (["alembic_version"], "same_rev", "same_rev", True), # revisions match + ], +) +@patch("trustregistry.main.inspect") +@patch("trustregistry.main.MigrationContext") +@patch("trustregistry.main.Config") +@patch("trustregistry.main.ScriptDirectory") +def test_check_migrations( + mock_script_directory, + mock_config, + mock_migration_context, + mock_inspect, + table_names, + current_rev, + head_rev, + expected, +): + # Set up mocks mock_inspector = MagicMock() + mock_inspector.get_table_names.return_value = table_names mock_inspect.return_value = mock_inspector - mock_inspector.get_table_names.return_value = ["table1", "table2"] + + mock_context = MagicMock() + mock_context.get_current_revision.return_value = current_rev + mock_migration_context.configure.return_value = mock_context + + mock_script = MagicMock() + mock_script.get_current_head.return_value = head_rev + mock_script_directory.from_config.return_value = mock_script + + mock_engine = MagicMock() mock_connection = MagicMock() mock_engine.connect.return_value.__enter__.return_value = mock_connection - async with lifespan(FastAPI()): - pass + # Run the function + result = check_migrations(mock_engine) + + # Assert the result + assert result == expected - mock_engine.dispose.assert_called_once() - mock_engine.connect.assert_called_once() - mock_inspect.assert_called_once_with(mock_connection) + # Verify mock calls + mock_inspect.assert_called_with(mock_connection) mock_inspector.get_table_names.assert_called_once() + if table_names: # Only check these if alembic_version table exists + mock_migration_context.configure.assert_called_with(mock_connection) + mock_context.get_current_revision.assert_called_once() + mock_config.assert_called_with("alembic.ini") + mock_script_directory.from_config.assert_called_once() + mock_script.get_current_head.assert_called_once() @pytest.mark.anyio From 389d1a1ad6e6a5b22fc5094eaba25e7efb1021c9 Mon Sep 17 00:00:00 2001 From: cl0ete Date: Wed, 9 Oct 2024 15:43:51 +0200 Subject: [PATCH 12/56] remove unused --- trustregistry/tests/test_main.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/trustregistry/tests/test_main.py b/trustregistry/tests/test_main.py index 652af3304..91e7e54f4 100644 --- a/trustregistry/tests/test_main.py +++ b/trustregistry/tests/test_main.py @@ -26,13 +26,12 @@ def test_create_app(): @pytest.mark.anyio -@patch("trustregistry.main.engine") @patch("trustregistry.main.check_migrations") @patch("trustregistry.main.Config") @patch("trustregistry.main.command") @patch("trustregistry.main.logger") async def test_lifespan_migrations_needed( - mock_logger, mock_command, mock_config, mock_check_migrations, mock_engine + mock_logger, mock_command, mock_config, mock_check_migrations ): mock_check_migrations.return_value = False mock_config.return_value = MagicMock() @@ -46,13 +45,12 @@ async def test_lifespan_migrations_needed( @pytest.mark.anyio -@patch("trustregistry.main.engine") @patch("trustregistry.main.check_migrations") @patch("trustregistry.main.Config") @patch("trustregistry.main.command") @patch("trustregistry.main.logger") async def test_lifespan_already_exists_error( - mock_logger, mock_command, mock_config, mock_check_migrations, mock_engine + mock_logger, mock_command, mock_config, mock_check_migrations ): mock_check_migrations.return_value = False mock_config.return_value = MagicMock() @@ -73,13 +71,12 @@ async def test_lifespan_already_exists_error( @pytest.mark.anyio -@patch("trustregistry.main.engine") @patch("trustregistry.main.check_migrations") @patch("trustregistry.main.Config") @patch("trustregistry.main.command") @patch("trustregistry.main.logger") async def test_lifespan_unexpected_error( - mock_logger, mock_command, mock_config, mock_check_migrations, mock_engine + mock_logger, mock_command, mock_config, mock_check_migrations ): mock_check_migrations.return_value = False mock_config.return_value = MagicMock() @@ -93,11 +90,10 @@ async def test_lifespan_unexpected_error( @pytest.mark.anyio -@patch("trustregistry.main.engine") @patch("trustregistry.main.check_migrations") @patch("trustregistry.main.logger") async def test_lifespan_no_migrations_needed( - mock_logger, mock_check_migrations, mock_engine + mock_logger, mock_check_migrations ): mock_check_migrations.return_value = True From 0b7172d9077269b860157821a3ffe58fab82d41f Mon Sep 17 00:00:00 2001 From: cl0ete Date: Wed, 9 Oct 2024 15:44:16 +0200 Subject: [PATCH 13/56] :art: --- trustregistry/tests/test_main.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/trustregistry/tests/test_main.py b/trustregistry/tests/test_main.py index 91e7e54f4..21ad60c69 100644 --- a/trustregistry/tests/test_main.py +++ b/trustregistry/tests/test_main.py @@ -92,9 +92,7 @@ async def test_lifespan_unexpected_error( @pytest.mark.anyio @patch("trustregistry.main.check_migrations") @patch("trustregistry.main.logger") -async def test_lifespan_no_migrations_needed( - mock_logger, mock_check_migrations -): +async def test_lifespan_no_migrations_needed(mock_logger, mock_check_migrations): mock_check_migrations.return_value = True async with lifespan(FastAPI()): From df1cbbd2de8d5ee530ee69a9bdf7f5c05c381188 Mon Sep 17 00:00:00 2001 From: cl0ete Date: Wed, 9 Oct 2024 15:51:29 +0200 Subject: [PATCH 14/56] re-add mock_engine to tests --- trustregistry/tests/test_main.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/trustregistry/tests/test_main.py b/trustregistry/tests/test_main.py index 21ad60c69..652af3304 100644 --- a/trustregistry/tests/test_main.py +++ b/trustregistry/tests/test_main.py @@ -26,12 +26,13 @@ def test_create_app(): @pytest.mark.anyio +@patch("trustregistry.main.engine") @patch("trustregistry.main.check_migrations") @patch("trustregistry.main.Config") @patch("trustregistry.main.command") @patch("trustregistry.main.logger") async def test_lifespan_migrations_needed( - mock_logger, mock_command, mock_config, mock_check_migrations + mock_logger, mock_command, mock_config, mock_check_migrations, mock_engine ): mock_check_migrations.return_value = False mock_config.return_value = MagicMock() @@ -45,12 +46,13 @@ async def test_lifespan_migrations_needed( @pytest.mark.anyio +@patch("trustregistry.main.engine") @patch("trustregistry.main.check_migrations") @patch("trustregistry.main.Config") @patch("trustregistry.main.command") @patch("trustregistry.main.logger") async def test_lifespan_already_exists_error( - mock_logger, mock_command, mock_config, mock_check_migrations + mock_logger, mock_command, mock_config, mock_check_migrations, mock_engine ): mock_check_migrations.return_value = False mock_config.return_value = MagicMock() @@ -71,12 +73,13 @@ async def test_lifespan_already_exists_error( @pytest.mark.anyio +@patch("trustregistry.main.engine") @patch("trustregistry.main.check_migrations") @patch("trustregistry.main.Config") @patch("trustregistry.main.command") @patch("trustregistry.main.logger") async def test_lifespan_unexpected_error( - mock_logger, mock_command, mock_config, mock_check_migrations + mock_logger, mock_command, mock_config, mock_check_migrations, mock_engine ): mock_check_migrations.return_value = False mock_config.return_value = MagicMock() @@ -90,9 +93,12 @@ async def test_lifespan_unexpected_error( @pytest.mark.anyio +@patch("trustregistry.main.engine") @patch("trustregistry.main.check_migrations") @patch("trustregistry.main.logger") -async def test_lifespan_no_migrations_needed(mock_logger, mock_check_migrations): +async def test_lifespan_no_migrations_needed( + mock_logger, mock_check_migrations, mock_engine +): mock_check_migrations.return_value = True async with lifespan(FastAPI()): From 51dab689749201fc003087460de6a20766cc3aa4 Mon Sep 17 00:00:00 2001 From: cl0ete Date: Wed, 9 Oct 2024 15:53:45 +0200 Subject: [PATCH 15/56] # pylint: disable=unused-argument --- trustregistry/tests/test_main.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/trustregistry/tests/test_main.py b/trustregistry/tests/test_main.py index 652af3304..b944d98cd 100644 --- a/trustregistry/tests/test_main.py +++ b/trustregistry/tests/test_main.py @@ -32,7 +32,7 @@ def test_create_app(): @patch("trustregistry.main.command") @patch("trustregistry.main.logger") async def test_lifespan_migrations_needed( - mock_logger, mock_command, mock_config, mock_check_migrations, mock_engine + mock_logger, mock_command, mock_config, mock_check_migrations, mock_engine # pylint: disable=unused-argument ): mock_check_migrations.return_value = False mock_config.return_value = MagicMock() @@ -52,7 +52,7 @@ async def test_lifespan_migrations_needed( @patch("trustregistry.main.command") @patch("trustregistry.main.logger") async def test_lifespan_already_exists_error( - mock_logger, mock_command, mock_config, mock_check_migrations, mock_engine + mock_logger, mock_command, mock_config, mock_check_migrations, mock_engine # pylint: disable=unused-argument ): mock_check_migrations.return_value = False mock_config.return_value = MagicMock() @@ -79,7 +79,7 @@ async def test_lifespan_already_exists_error( @patch("trustregistry.main.command") @patch("trustregistry.main.logger") async def test_lifespan_unexpected_error( - mock_logger, mock_command, mock_config, mock_check_migrations, mock_engine + mock_logger, mock_command, mock_config, mock_check_migrations, mock_engine # pylint: disable=unused-argument ): mock_check_migrations.return_value = False mock_config.return_value = MagicMock() @@ -97,7 +97,7 @@ async def test_lifespan_unexpected_error( @patch("trustregistry.main.check_migrations") @patch("trustregistry.main.logger") async def test_lifespan_no_migrations_needed( - mock_logger, mock_check_migrations, mock_engine + mock_logger, mock_check_migrations, mock_engine # pylint: disable=unused-argument ): mock_check_migrations.return_value = True From 1ba3605c537bf2759099e2e8b3e8f7894b6dc686 Mon Sep 17 00:00:00 2001 From: cl0ete Date: Wed, 9 Oct 2024 15:54:03 +0200 Subject: [PATCH 16/56] :art: --- trustregistry/tests/test_main.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/trustregistry/tests/test_main.py b/trustregistry/tests/test_main.py index b944d98cd..dab831ace 100644 --- a/trustregistry/tests/test_main.py +++ b/trustregistry/tests/test_main.py @@ -32,7 +32,11 @@ def test_create_app(): @patch("trustregistry.main.command") @patch("trustregistry.main.logger") async def test_lifespan_migrations_needed( - mock_logger, mock_command, mock_config, mock_check_migrations, mock_engine # pylint: disable=unused-argument + mock_logger, + mock_command, + mock_config, + mock_check_migrations, + mock_engine, # pylint: disable=unused-argument ): mock_check_migrations.return_value = False mock_config.return_value = MagicMock() @@ -52,7 +56,11 @@ async def test_lifespan_migrations_needed( @patch("trustregistry.main.command") @patch("trustregistry.main.logger") async def test_lifespan_already_exists_error( - mock_logger, mock_command, mock_config, mock_check_migrations, mock_engine # pylint: disable=unused-argument + mock_logger, + mock_command, + mock_config, + mock_check_migrations, + mock_engine, # pylint: disable=unused-argument ): mock_check_migrations.return_value = False mock_config.return_value = MagicMock() @@ -79,7 +87,11 @@ async def test_lifespan_already_exists_error( @patch("trustregistry.main.command") @patch("trustregistry.main.logger") async def test_lifespan_unexpected_error( - mock_logger, mock_command, mock_config, mock_check_migrations, mock_engine # pylint: disable=unused-argument + mock_logger, + mock_command, + mock_config, + mock_check_migrations, + mock_engine, # pylint: disable=unused-argument ): mock_check_migrations.return_value = False mock_config.return_value = MagicMock() @@ -97,7 +109,7 @@ async def test_lifespan_unexpected_error( @patch("trustregistry.main.check_migrations") @patch("trustregistry.main.logger") async def test_lifespan_no_migrations_needed( - mock_logger, mock_check_migrations, mock_engine # pylint: disable=unused-argument + mock_logger, mock_check_migrations, mock_engine # pylint: disable=unused-argument ): mock_check_migrations.return_value = True From 3a1a043e0368c517afaede17177c9fe9ae6181e4 Mon Sep 17 00:00:00 2001 From: cl0ete Date: Fri, 11 Oct 2024 10:06:57 +0200 Subject: [PATCH 17/56] poetry lock --- trustregistry/poetry.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trustregistry/poetry.lock b/trustregistry/poetry.lock index 8e33fac85..70599f2c8 100644 --- a/trustregistry/poetry.lock +++ b/trustregistry/poetry.lock @@ -1597,4 +1597,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "34b0f429d76b4f42c2463061d705343e333caa6983252305bf5cb7df73b463ff" +content-hash = "c4663ee6143b6fde3f30710ecc8b0c5ca774c198365cd6192555162fd7b3f2ee" From 89f71330a7b60f9cc4aacdac398ac1eabbc1b7f5 Mon Sep 17 00:00:00 2001 From: cl0ete Date: Fri, 11 Oct 2024 13:17:24 +0200 Subject: [PATCH 18/56] remove url from logs --- trustregistry/migrations/env.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trustregistry/migrations/env.py b/trustregistry/migrations/env.py index d82934d9f..304716462 100644 --- a/trustregistry/migrations/env.py +++ b/trustregistry/migrations/env.py @@ -29,7 +29,7 @@ db_url = os.environ.get("POSTGRES_DATABASE_URL") if db_url: - logger.info(f"Using database URL from environment: {db_url}") + logger.debug(f"Using database URL from environment") config.set_main_option("sqlalchemy.url", db_url) else: logger.warning( From df5d789477116082de66ca37059b5695294c6f9e Mon Sep 17 00:00:00 2001 From: cl0ete Date: Fri, 11 Oct 2024 13:42:24 +0200 Subject: [PATCH 19/56] fix db stamping logic --- trustregistry/main.py | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/trustregistry/main.py b/trustregistry/main.py index b56bdb0a4..6f8efa5e3 100644 --- a/trustregistry/main.py +++ b/trustregistry/main.py @@ -25,23 +25,28 @@ ROOT_PATH = os.getenv("ROOT_PATH", "") -def check_migrations(engine: Engine) -> bool: # pylint: disable=redefined-outer-name +def check_migrations(engine: Engine, alembic_cfg: Config) -> bool: # pylint: disable=redefined-outer-name # Check if alembic_version table exists with engine.connect() as connection: inspector = inspect(connection) has_alembic_version = "alembic_version" in inspector.get_table_names() + script = ScriptDirectory.from_config(alembic_cfg) if not has_alembic_version: - return False + logger.info("Alembic version table not found. Stamping with initial revision...") + try: + initial_revision = script.get_base() + command.stamp(alembic_cfg, initial_revision) + logger.info(f"Database stamped with initial migration version: {initial_revision}") + except Exception as e: + logger.error(f"Error stamping database: {e}") + raise # Get current revision with engine.connect() as connection: context = MigrationContext.configure(connection) current_rev = context.get_current_revision() - # Get head revision - alembic_cfg = Config("alembic.ini") - script = ScriptDirectory.from_config(alembic_cfg) head_rev = script.get_current_head() return current_rev == head_rev @@ -51,22 +56,14 @@ def check_migrations(engine: Engine) -> bool: # pylint: disable=redefined-outer async def lifespan(_: FastAPI): alembic_cfg = Config("alembic.ini") - if not check_migrations(engine): + if not check_migrations(engine, alembic_cfg): logger.info("Applying database migrations...") try: - logger.info("Checking and applying database migrations...") command.upgrade(alembic_cfg, "head") logger.info("Database schema is up to date.") - except ProgrammingError as e: - if "already exists" in str(e): - logger.warning( - "Database schema already exists. Stamping with current version." - ) - command.stamp(alembic_cfg, "head") - logger.info("Database stamped with current migration version.") - else: - logger.error(f"Unexpected error during migration: {e}") - raise + except Exception as e: + logger.error(f"Error during migration: {e}") + raise else: logger.info("Database is up to date. No migrations needed.") From 3c968acdc49d58fdb807aaccd8228e816674a4ae Mon Sep 17 00:00:00 2001 From: cl0ete Date: Fri, 11 Oct 2024 13:42:53 +0200 Subject: [PATCH 20/56] :art: --- trustregistry/main.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/trustregistry/main.py b/trustregistry/main.py index 6f8efa5e3..2e35bcf1e 100644 --- a/trustregistry/main.py +++ b/trustregistry/main.py @@ -25,7 +25,9 @@ ROOT_PATH = os.getenv("ROOT_PATH", "") -def check_migrations(engine: Engine, alembic_cfg: Config) -> bool: # pylint: disable=redefined-outer-name +def check_migrations( + engine: Engine, alembic_cfg: Config +) -> bool: # pylint: disable=redefined-outer-name # Check if alembic_version table exists with engine.connect() as connection: inspector = inspect(connection) @@ -33,11 +35,15 @@ def check_migrations(engine: Engine, alembic_cfg: Config) -> bool: # pylint: di script = ScriptDirectory.from_config(alembic_cfg) if not has_alembic_version: - logger.info("Alembic version table not found. Stamping with initial revision...") + logger.info( + "Alembic version table not found. Stamping with initial revision..." + ) try: initial_revision = script.get_base() command.stamp(alembic_cfg, initial_revision) - logger.info(f"Database stamped with initial migration version: {initial_revision}") + logger.info( + f"Database stamped with initial migration version: {initial_revision}" + ) except Exception as e: logger.error(f"Error stamping database: {e}") raise From 862af31d46fe6b1c398a4701ca90dce8ed07c875 Mon Sep 17 00:00:00 2001 From: cl0ete Date: Fri, 11 Oct 2024 14:04:00 +0200 Subject: [PATCH 21/56] update tests for main --- trustregistry/tests/test_main.py | 143 +++++++++++++++++-------------- 1 file changed, 80 insertions(+), 63 deletions(-) diff --git a/trustregistry/tests/test_main.py b/trustregistry/tests/test_main.py index dab831ace..9ee6311b9 100644 --- a/trustregistry/tests/test_main.py +++ b/trustregistry/tests/test_main.py @@ -31,22 +31,35 @@ def test_create_app(): @patch("trustregistry.main.Config") @patch("trustregistry.main.command") @patch("trustregistry.main.logger") +@patch("trustregistry.main.inspect") async def test_lifespan_migrations_needed( + mock_inspect, mock_logger, mock_command, mock_config, mock_check_migrations, - mock_engine, # pylint: disable=unused-argument + mock_engine, ): mock_check_migrations.return_value = False mock_config.return_value = MagicMock() + mock_inspector = MagicMock() + mock_inspector.get_table_names.return_value = ["table1", "table2"] + mock_inspect.return_value = mock_inspector async with lifespan(FastAPI()): pass + mock_check_migrations.assert_called_once_with(mock_engine, mock_config.return_value) mock_command.upgrade.assert_called_once_with(mock_config.return_value, "head") mock_logger.info.assert_any_call("Applying database migrations...") mock_logger.info.assert_any_call("Database schema is up to date.") + mock_inspect.assert_called_once_with( + mock_engine.connect.return_value.__enter__.return_value + ) + mock_inspector.get_table_names.assert_called_once() + mock_logger.debug.assert_called_with( + "TrustRegistry tables created: `{}`", ["table1", "table2"] + ) @pytest.mark.anyio @@ -55,29 +68,30 @@ async def test_lifespan_migrations_needed( @patch("trustregistry.main.Config") @patch("trustregistry.main.command") @patch("trustregistry.main.logger") -async def test_lifespan_already_exists_error( +@patch("trustregistry.main.inspect") +async def test_lifespan_migration_error( + mock_inspect, mock_logger, mock_command, mock_config, mock_check_migrations, - mock_engine, # pylint: disable=unused-argument + mock_engine, ): mock_check_migrations.return_value = False mock_config.return_value = MagicMock() - mock_command.upgrade.side_effect = ProgrammingError( - "Table already exists", None, None - ) + mock_command.upgrade.side_effect = Exception("Migration error") + mock_inspector = MagicMock() + mock_inspector.get_table_names.return_value = ["table1", "table2"] + mock_inspect.return_value = mock_inspector - async with lifespan(FastAPI()): - pass + with pytest.raises(Exception, match="Migration error"): + async with lifespan(FastAPI()): + pass - mock_command.stamp.assert_called_once_with(mock_config.return_value, "head") - mock_logger.warning.assert_called_once_with( - "Database schema already exists. Stamping with current version." - ) - mock_logger.info.assert_called_with( - "Database stamped with current migration version." - ) + mock_check_migrations.assert_called_once_with(mock_engine, mock_config.return_value) + mock_command.upgrade.assert_called_once_with(mock_config.return_value, "head") + mock_logger.info.assert_called_with("Applying database migrations...") + mock_logger.error.assert_called_once_with("Error during migration: Migration error") @pytest.mark.anyio @@ -86,99 +100,102 @@ async def test_lifespan_already_exists_error( @patch("trustregistry.main.Config") @patch("trustregistry.main.command") @patch("trustregistry.main.logger") -async def test_lifespan_unexpected_error( +@patch("trustregistry.main.inspect") +async def test_lifespan_no_migrations_needed( + mock_inspect, mock_logger, mock_command, mock_config, mock_check_migrations, - mock_engine, # pylint: disable=unused-argument -): - mock_check_migrations.return_value = False - mock_config.return_value = MagicMock() - mock_command.upgrade.side_effect = ProgrammingError("Unexpected error", None, None) - - with pytest.raises(ProgrammingError): - async with lifespan(FastAPI()): - pass - - mock_logger.error.assert_called_once() - - -@pytest.mark.anyio -@patch("trustregistry.main.engine") -@patch("trustregistry.main.check_migrations") -@patch("trustregistry.main.logger") -async def test_lifespan_no_migrations_needed( - mock_logger, mock_check_migrations, mock_engine # pylint: disable=unused-argument + mock_engine, ): mock_check_migrations.return_value = True + mock_config.return_value = MagicMock() + mock_inspector = MagicMock() + mock_inspector.get_table_names.return_value = ["table1", "table2"] + mock_inspect.return_value = mock_inspector async with lifespan(FastAPI()): pass - mock_logger.info.assert_called_once_with( - "Database is up to date. No migrations needed." + mock_check_migrations.assert_called_once_with(mock_engine, mock_config.return_value) + mock_command.upgrade.assert_not_called() + mock_logger.info.assert_called_with("Database is up to date. No migrations needed.") + mock_inspect.assert_called_once_with( + mock_engine.connect.return_value.__enter__.return_value + ) + mock_inspector.get_table_names.assert_called_once() + mock_logger.debug.assert_called_with( + "TrustRegistry tables created: `{}`", ["table1", "table2"] ) @pytest.mark.parametrize( - "table_names,current_rev,head_rev,expected", + "has_alembic_version,current_rev,head_rev,expected", [ - ([], None, None, False), # alembic_version table doesn't exist - ( - ["alembic_version"], - "current_rev", - "head_rev", - False, - ), # revisions don't match - (["alembic_version"], "same_rev", "same_rev", True), # revisions match + (False, None, "head_rev", False), # alembic_version table doesn't exist + (True, "current_rev", "head_rev", False), # revisions don't match + (True, "same_rev", "same_rev", True), # revisions match ], ) @patch("trustregistry.main.inspect") @patch("trustregistry.main.MigrationContext") -@patch("trustregistry.main.Config") @patch("trustregistry.main.ScriptDirectory") +@patch("trustregistry.main.command") +@patch("trustregistry.main.logger") def test_check_migrations( + mock_logger, + mock_command, mock_script_directory, - mock_config, mock_migration_context, mock_inspect, - table_names, + has_alembic_version, current_rev, head_rev, expected, ): # Set up mocks + mock_engine = MagicMock() + mock_alembic_cfg = MagicMock() + mock_inspector = MagicMock() - mock_inspector.get_table_names.return_value = table_names + mock_inspector.get_table_names.return_value = ( + ["alembic_version"] if has_alembic_version else [] + ) mock_inspect.return_value = mock_inspector - mock_context = MagicMock() - mock_context.get_current_revision.return_value = current_rev - mock_migration_context.configure.return_value = mock_context - mock_script = MagicMock() mock_script.get_current_head.return_value = head_rev + mock_script.get_base.return_value = "initial_revision" mock_script_directory.from_config.return_value = mock_script - mock_engine = MagicMock() - mock_connection = MagicMock() - mock_engine.connect.return_value.__enter__.return_value = mock_connection + mock_context = MagicMock() + mock_context.get_current_revision.return_value = current_rev + mock_migration_context.configure.return_value = mock_context # Run the function - result = check_migrations(mock_engine) + result = check_migrations(mock_engine, mock_alembic_cfg) # Assert the result assert result == expected # Verify mock calls - mock_inspect.assert_called_with(mock_connection) + mock_inspect.assert_called() mock_inspector.get_table_names.assert_called_once() - if table_names: # Only check these if alembic_version table exists - mock_migration_context.configure.assert_called_with(mock_connection) + mock_script_directory.from_config.assert_called_once_with(mock_alembic_cfg) + + if not has_alembic_version: + mock_script.get_base.assert_called_once() + mock_command.stamp.assert_called_once_with(mock_alembic_cfg, "initial_revision") + mock_logger.info.assert_any_call( + "Alembic version table not found. Stamping with initial revision..." + ) + mock_logger.info.assert_any_call( + "Database stamped with initial migration version: initial_revision" + ) + else: + mock_migration_context.configure.assert_called() mock_context.get_current_revision.assert_called_once() - mock_config.assert_called_with("alembic.ini") - mock_script_directory.from_config.assert_called_once() mock_script.get_current_head.assert_called_once() From 41d01f92e1e2f83f5363b4e829b1f448121ffeea Mon Sep 17 00:00:00 2001 From: cl0ete Date: Fri, 11 Oct 2024 14:04:12 +0200 Subject: [PATCH 22/56] # pylint: disable=W0718 --- trustregistry/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trustregistry/main.py b/trustregistry/main.py index 2e35bcf1e..64b189a02 100644 --- a/trustregistry/main.py +++ b/trustregistry/main.py @@ -44,7 +44,7 @@ def check_migrations( logger.info( f"Database stamped with initial migration version: {initial_revision}" ) - except Exception as e: + except Exception as e: # pylint: disable=W0718 logger.error(f"Error stamping database: {e}") raise From 1f147057d51603b0ed49afa64082f5797d86cccc Mon Sep 17 00:00:00 2001 From: cl0ete Date: Fri, 11 Oct 2024 14:04:33 +0200 Subject: [PATCH 23/56] :art: --- trustregistry/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trustregistry/main.py b/trustregistry/main.py index 64b189a02..14ffca025 100644 --- a/trustregistry/main.py +++ b/trustregistry/main.py @@ -44,7 +44,7 @@ def check_migrations( logger.info( f"Database stamped with initial migration version: {initial_revision}" ) - except Exception as e: # pylint: disable=W0718 + except Exception as e: # pylint: disable=W0718 logger.error(f"Error stamping database: {e}") raise From be47c7d4d4ea359175a6f52be2cc1cf2e1a68dbe Mon Sep 17 00:00:00 2001 From: cl0ete Date: Fri, 27 Sep 2024 07:30:48 +0200 Subject: [PATCH 24/56] stamp the db --- trustregistry/main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/trustregistry/main.py b/trustregistry/main.py index 14ffca025..27d4f3485 100644 --- a/trustregistry/main.py +++ b/trustregistry/main.py @@ -8,6 +8,7 @@ from fastapi import Depends, FastAPI from scalar_fastapi import get_scalar_api_reference from sqlalchemy import inspect +from sqlalchemy.exc import ProgrammingError from sqlalchemy.engine import Engine from sqlalchemy.exc import ProgrammingError from sqlalchemy.orm import Session From 98a35a8ce6960c82dc7eafa50c1ecaa4f4e74462 Mon Sep 17 00:00:00 2001 From: cl0ete Date: Fri, 27 Sep 2024 07:31:10 +0200 Subject: [PATCH 25/56] :art: --- trustregistry/main.py | 1 - 1 file changed, 1 deletion(-) diff --git a/trustregistry/main.py b/trustregistry/main.py index 27d4f3485..14ffca025 100644 --- a/trustregistry/main.py +++ b/trustregistry/main.py @@ -8,7 +8,6 @@ from fastapi import Depends, FastAPI from scalar_fastapi import get_scalar_api_reference from sqlalchemy import inspect -from sqlalchemy.exc import ProgrammingError from sqlalchemy.engine import Engine from sqlalchemy.exc import ProgrammingError from sqlalchemy.orm import Session From ebeb2faa0ba2167f717eeedf7c1fe51c544ac332 Mon Sep 17 00:00:00 2001 From: cl0ete Date: Thu, 15 Aug 2024 11:03:41 +0200 Subject: [PATCH 26/56] add image_url to register_actor call --- app/routes/admin/tenants.py | 1 + 1 file changed, 1 insertion(+) diff --git a/app/routes/admin/tenants.py b/app/routes/admin/tenants.py index e0bc1bd15..cf632c8dc 100644 --- a/app/routes/admin/tenants.py +++ b/app/routes/admin/tenants.py @@ -143,6 +143,7 @@ async def create_tenant( roles=roles, did=onboard_result.did, didcomm_invitation=onboard_result.didcomm_invitation, + image_url=body.image_url, ) ) except HTTPException as http_error: From 0559ba00b3baef0f57f5527a4922f2b8bd1cdde3 Mon Sep 17 00:00:00 2001 From: cl0ete Date: Thu, 15 Aug 2024 11:08:25 +0200 Subject: [PATCH 27/56] add image_url to update tenant logic --- app/services/onboarding/tenants.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/services/onboarding/tenants.py b/app/services/onboarding/tenants.py index 89e5a7897..4c4efa933 100644 --- a/app/services/onboarding/tenants.py +++ b/app/services/onboarding/tenants.py @@ -32,6 +32,7 @@ async def handle_tenant_update( new_roles = update_request.roles or [] new_label = update_request.wallet_label + new_image_url = update_request.image_url # See if this wallet belongs to an actor actor = await fetch_actor_by_id(wallet_id) @@ -48,9 +49,10 @@ async def handle_tenant_update( if actor: existing_roles = actor.roles + existing_image_url = actor.image_url added_roles = list(set(new_roles) - set(existing_roles)) - if new_label or added_roles: # Only update actor if + if new_label or added_roles or new_image_url: # Only update actor if update_dict = {} if new_label: update_dict["name"] = new_label @@ -76,6 +78,9 @@ async def handle_tenant_update( update_dict["did"] = onboard_result.did update_dict["didcomm_invitation"] = onboard_result.didcomm_invitation + if new_image_url and new_image_url != existing_image_url: + update_dict["image_url"] = new_image_url + updated_actor = actor.model_copy(update=update_dict) await update_actor(updated_actor) From 3d2b8f974a1b3402e8f018df5689dc5ff1a0fdc7 Mon Sep 17 00:00:00 2001 From: cl0ete Date: Thu, 15 Aug 2024 11:08:50 +0200 Subject: [PATCH 28/56] update/fix tests --- app/tests/routes/admin_tenants/test_create_tenant.py | 1 + trustregistry/tests/e2e/test_actor.py | 2 ++ 2 files changed, 3 insertions(+) diff --git a/app/tests/routes/admin_tenants/test_create_tenant.py b/app/tests/routes/admin_tenants/test_create_tenant.py index da5843964..4631e0cd2 100644 --- a/app/tests/routes/admin_tenants/test_create_tenant.py +++ b/app/tests/routes/admin_tenants/test_create_tenant.py @@ -114,6 +114,7 @@ async def test_create_tenant_success(roles): roles=roles, did=did, didcomm_invitation=didcomm_invitation, + image_url=create_tenant_body.image_url, ) ) diff --git a/trustregistry/tests/e2e/test_actor.py b/trustregistry/tests/e2e/test_actor.py index b433a381b..779f1f905 100644 --- a/trustregistry/tests/e2e/test_actor.py +++ b/trustregistry/tests/e2e/test_actor.py @@ -12,6 +12,7 @@ "roles": ["issuer", "verifier"], "didcomm_invitation": "string", "did": "did:key:string", + "image_url": "https://example.com/image", } actor_id = new_actor["id"] actor_did = new_actor["did"] @@ -25,6 +26,7 @@ def generate_actor(): "roles": ["issuer", "verifier"], "didcomm_invitation": random_string(8), "did": f"did:key:{random_string(5)}", + "image_url": f"https://example.com/{random_string(8)}", } From e797538267bdf50ed9c8bb63dac295bbc95d9618 Mon Sep 17 00:00:00 2001 From: cl0ete Date: Thu, 15 Aug 2024 11:09:41 +0200 Subject: [PATCH 29/56] add image_url to actor model --- shared/models/trustregistry.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/shared/models/trustregistry.py b/shared/models/trustregistry.py index cc2b90881..668019cd2 100644 --- a/shared/models/trustregistry.py +++ b/shared/models/trustregistry.py @@ -13,7 +13,8 @@ class Actor(BaseModel): roles: List[TrustRegistryRole] did: str didcomm_invitation: Optional[str] = None - + image_url: Optional[str] = None + @field_validator("did") @classmethod def did_validator(cls, did: str): From ba2d1d35cbde005f8a1e34a76775a1f5b010f776 Mon Sep 17 00:00:00 2001 From: cl0ete Date: Thu, 15 Aug 2024 11:10:55 +0200 Subject: [PATCH 30/56] add image_url to update actor crud --- trustregistry/crud.py | 1 + 1 file changed, 1 insertion(+) diff --git a/trustregistry/crud.py b/trustregistry/crud.py index 9f7d9959c..242242fc1 100644 --- a/trustregistry/crud.py +++ b/trustregistry/crud.py @@ -181,6 +181,7 @@ def update_actor(db_session: Session, actor: Actor) -> db.Actor: roles=actor.roles, didcomm_invitation=actor.didcomm_invitation, did=actor.did, + image_url=actor.image_url if actor.image_url else db_actor.image_url, ) .returning(db.Actor) ) From a1fc83cbad1a5b48319c9571a001ce691669a244 Mon Sep 17 00:00:00 2001 From: cl0ete Date: Thu, 15 Aug 2024 11:11:16 +0200 Subject: [PATCH 31/56] add image_url to db actor model --- trustregistry/db.py | 1 + 1 file changed, 1 insertion(+) diff --git a/trustregistry/db.py b/trustregistry/db.py index 2135bff35..924dd7aab 100644 --- a/trustregistry/db.py +++ b/trustregistry/db.py @@ -33,6 +33,7 @@ class Actor(Base): String, unique=True, index=True ) did: Mapped[str] = mapped_column(String, unique=True, index=True) + image_url: Mapped[Optional[str]] = mapped_column(String, index=True) class Schema(Base): From 4aef63d1a1d622b53c3707a7a13a2a5e88dc0a05 Mon Sep 17 00:00:00 2001 From: cl0ete Date: Thu, 15 Aug 2024 11:18:32 +0200 Subject: [PATCH 32/56] :art: --- shared/models/trustregistry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/models/trustregistry.py b/shared/models/trustregistry.py index 668019cd2..d958e9025 100644 --- a/shared/models/trustregistry.py +++ b/shared/models/trustregistry.py @@ -14,7 +14,7 @@ class Actor(BaseModel): did: str didcomm_invitation: Optional[str] = None image_url: Optional[str] = None - + @field_validator("did") @classmethod def did_validator(cls, did: str): From c666ac6b71df178d66f433e2f244904bb12d81fe Mon Sep 17 00:00:00 2001 From: cl0ete Date: Thu, 15 Aug 2024 11:40:38 +0200 Subject: [PATCH 33/56] test new url is on TR with tenant update --- app/tests/e2e/test_tenants.py | 1 + 1 file changed, 1 insertion(+) diff --git a/app/tests/e2e/test_tenants.py b/app/tests/e2e/test_tenants.py index 00a11806a..f28fced0e 100644 --- a/app/tests/e2e/test_tenants.py +++ b/app/tests/e2e/test_tenants.py @@ -448,6 +448,7 @@ async def test_update_tenant_verifier_to_issuer( assert_that(new_actor).has_name(new_wallet_label) assert_that(new_actor).has_did(new_actor.did) assert_that(new_actor.roles).contains_only("issuer", "verifier") + assert_that(new_actor.image_url).is_equal_to(new_image_url) assert new_actor.didcomm_invitation is not None finally: From 9ac549d02f420e21277ef5010152cea83096b50a Mon Sep 17 00:00:00 2001 From: cl0ete Date: Fri, 16 Aug 2024 07:21:20 +0200 Subject: [PATCH 34/56] :art: --- app/services/trust_registry/actors.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/trust_registry/actors.py b/app/services/trust_registry/actors.py index 1cb666b38..1db276ac9 100644 --- a/app/services/trust_registry/actors.py +++ b/app/services/trust_registry/actors.py @@ -266,7 +266,7 @@ async def remove_actor_by_id(actor_id: str) -> None: """Remove actor from trust registry by id Args: - actor_id (str): identifier of the actor to remove + actor_id (str): identifier of the actor to remove Raises: TrustRegistryException: If an error occurred while removing the actor From 26641fa23231128e2a473b658cd80845623762dd Mon Sep 17 00:00:00 2001 From: cl0ete Date: Fri, 16 Aug 2024 07:21:47 +0200 Subject: [PATCH 35/56] :art: --- app/services/trust_registry/actors.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/services/trust_registry/actors.py b/app/services/trust_registry/actors.py index 1db276ac9..1cb666b38 100644 --- a/app/services/trust_registry/actors.py +++ b/app/services/trust_registry/actors.py @@ -266,7 +266,7 @@ async def remove_actor_by_id(actor_id: str) -> None: """Remove actor from trust registry by id Args: - actor_id (str): identifier of the actor to remove + actor_id (str): identifier of the actor to remove Raises: TrustRegistryException: If an error occurred while removing the actor From 68dad64e0d0fafb531da71557c94c377803c9131 Mon Sep 17 00:00:00 2001 From: cl0ete Date: Wed, 21 Aug 2024 16:04:11 +0200 Subject: [PATCH 36/56] add alembic to trustregistry --- trustregistry/pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/trustregistry/pyproject.toml b/trustregistry/pyproject.toml index 8233f686e..edb7a2ffe 100644 --- a/trustregistry/pyproject.toml +++ b/trustregistry/pyproject.toml @@ -29,6 +29,7 @@ pylint = "~3.3.0" pytest = "~8.3.2" pytest-cov = "~5.0.0" pytest-mock = "~3.14.0" +alembic = "~1.13.2" [build-system] requires = ["poetry-core>=1.8.3"] From 894041c24688f7464f468a7596a32c88fdbd1729 Mon Sep 17 00:00:00 2001 From: cl0ete Date: Wed, 21 Aug 2024 16:06:26 +0200 Subject: [PATCH 37/56] generate migration --- .../versions/5cc7dbda0123_actor_image_url.py | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 trustregistry/migrations/versions/5cc7dbda0123_actor_image_url.py diff --git a/trustregistry/migrations/versions/5cc7dbda0123_actor_image_url.py b/trustregistry/migrations/versions/5cc7dbda0123_actor_image_url.py new file mode 100644 index 000000000..b46780e1c --- /dev/null +++ b/trustregistry/migrations/versions/5cc7dbda0123_actor_image_url.py @@ -0,0 +1,32 @@ +"""Actor image_url + +Revision ID: 5cc7dbda0123 +Revises: +Create Date: 2024-08-21 15:52:01.005982 + +""" +from typing import Sequence, Union + +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision: str = '5cc7dbda0123' +down_revision: Union[str, None] = None +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.add_column('actors', sa.Column('image_url', sa.String(), nullable=True)) + op.create_index(op.f('ix_actors_image_url'), 'actors', ['image_url'], unique=False) + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.drop_index(op.f('ix_actors_image_url'), table_name='actors') + op.drop_column('actors', 'image_url') + # ### end Alembic commands ### From 2896e63ddaa3d7b6ead5625ac6c810bd03dbf1f1 Mon Sep 17 00:00:00 2001 From: cl0ete Date: Wed, 21 Aug 2024 16:07:38 +0200 Subject: [PATCH 38/56] expose trustregistry db to localhost --- docker-compose.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docker-compose.yaml b/docker-compose.yaml index ad1c26826..9965ae94b 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -89,6 +89,8 @@ services: - POSTGRES_USER=trustregistry - POSTGRES_PASSWORD=trustregistry - PGUSER=trustregistry + ports: + - 0.0.0.0:5432:5432 healthcheck: test: ["CMD-SHELL", "pg_isready", "-d", "${POSTGRES_DB}"] interval: 10s From fa2f1da074641a14a728ba9d2424e27a37abc0cd Mon Sep 17 00:00:00 2001 From: cl0ete Date: Wed, 21 Aug 2024 16:09:22 +0200 Subject: [PATCH 39/56] :art: --- .../versions/5cc7dbda0123_actor_image_url.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/trustregistry/migrations/versions/5cc7dbda0123_actor_image_url.py b/trustregistry/migrations/versions/5cc7dbda0123_actor_image_url.py index b46780e1c..47e6c6e9c 100644 --- a/trustregistry/migrations/versions/5cc7dbda0123_actor_image_url.py +++ b/trustregistry/migrations/versions/5cc7dbda0123_actor_image_url.py @@ -5,6 +5,7 @@ Create Date: 2024-08-21 15:52:01.005982 """ + from typing import Sequence, Union from alembic import op @@ -12,7 +13,7 @@ # revision identifiers, used by Alembic. -revision: str = '5cc7dbda0123' +revision: str = "5cc7dbda0123" down_revision: Union[str, None] = None branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None @@ -20,13 +21,13 @@ def upgrade() -> None: # ### commands auto generated by Alembic - please adjust! ### - op.add_column('actors', sa.Column('image_url', sa.String(), nullable=True)) - op.create_index(op.f('ix_actors_image_url'), 'actors', ['image_url'], unique=False) + op.add_column("actors", sa.Column("image_url", sa.String(), nullable=True)) + op.create_index(op.f("ix_actors_image_url"), "actors", ["image_url"], unique=False) # ### end Alembic commands ### def downgrade() -> None: # ### commands auto generated by Alembic - please adjust! ### - op.drop_index(op.f('ix_actors_image_url'), table_name='actors') - op.drop_column('actors', 'image_url') + op.drop_index(op.f("ix_actors_image_url"), table_name="actors") + op.drop_column("actors", "image_url") # ### end Alembic commands ### From b51370aad6be1daec5f4a20c2f9d84a49deb2202 Mon Sep 17 00:00:00 2001 From: cl0ete Date: Wed, 21 Aug 2024 16:10:45 +0200 Subject: [PATCH 40/56] :art: import sort --- .../migrations/versions/5cc7dbda0123_actor_image_url.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/trustregistry/migrations/versions/5cc7dbda0123_actor_image_url.py b/trustregistry/migrations/versions/5cc7dbda0123_actor_image_url.py index 47e6c6e9c..ade8ed9ea 100644 --- a/trustregistry/migrations/versions/5cc7dbda0123_actor_image_url.py +++ b/trustregistry/migrations/versions/5cc7dbda0123_actor_image_url.py @@ -8,9 +8,8 @@ from typing import Sequence, Union -from alembic import op import sqlalchemy as sa - +from alembic import op # revision identifiers, used by Alembic. revision: str = "5cc7dbda0123" From dc33ff428cd82fc093f3895d325de48f0c17dffa Mon Sep 17 00:00:00 2001 From: cl0ete Date: Thu, 26 Sep 2024 10:39:52 +0200 Subject: [PATCH 41/56] :art: --- trustregistry/migrations/env.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/trustregistry/migrations/env.py b/trustregistry/migrations/env.py index 304716462..63b8e40d9 100644 --- a/trustregistry/migrations/env.py +++ b/trustregistry/migrations/env.py @@ -12,8 +12,8 @@ config = context.config # Get db url from environment variable -db_url = os.environ.get("POSTGRES_DATABASE_URL", "test123") -print(f"db_url: {db_url}") +db_url = os.environ.get("POSTGRES_DATABASE_URL") + if db_url: config.set_main_option("sqlalchemy.url", db_url) From 8cb83b7ef3f9f206d11a02b3abe35266cdfa3ddc Mon Sep 17 00:00:00 2001 From: cl0ete Date: Thu, 26 Sep 2024 15:05:32 +0200 Subject: [PATCH 42/56] regenerate migration script for image_url --- ...url.py => 5bcfb2c0bc05_actor_image_url.py} | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) rename trustregistry/migrations/versions/{5cc7dbda0123_actor_image_url.py => 5bcfb2c0bc05_actor_image_url.py} (55%) diff --git a/trustregistry/migrations/versions/5cc7dbda0123_actor_image_url.py b/trustregistry/migrations/versions/5bcfb2c0bc05_actor_image_url.py similarity index 55% rename from trustregistry/migrations/versions/5cc7dbda0123_actor_image_url.py rename to trustregistry/migrations/versions/5bcfb2c0bc05_actor_image_url.py index ade8ed9ea..d87f84eb4 100644 --- a/trustregistry/migrations/versions/5cc7dbda0123_actor_image_url.py +++ b/trustregistry/migrations/versions/5bcfb2c0bc05_actor_image_url.py @@ -1,32 +1,32 @@ """Actor image_url -Revision ID: 5cc7dbda0123 -Revises: -Create Date: 2024-08-21 15:52:01.005982 +Revision ID: 5bcfb2c0bc05 +Revises: fd3e6dc8a75a +Create Date: 2024-09-26 15:03:08.338158 """ - from typing import Sequence, Union -import sqlalchemy as sa from alembic import op +import sqlalchemy as sa + # revision identifiers, used by Alembic. -revision: str = "5cc7dbda0123" -down_revision: Union[str, None] = None +revision: str = '5bcfb2c0bc05' +down_revision: Union[str, None] = 'fd3e6dc8a75a' branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: # ### commands auto generated by Alembic - please adjust! ### - op.add_column("actors", sa.Column("image_url", sa.String(), nullable=True)) - op.create_index(op.f("ix_actors_image_url"), "actors", ["image_url"], unique=False) + op.add_column('actors', sa.Column('image_url', sa.String(), nullable=True)) + op.create_index(op.f('ix_actors_image_url'), 'actors', ['image_url'], unique=False) # ### end Alembic commands ### def downgrade() -> None: # ### commands auto generated by Alembic - please adjust! ### - op.drop_index(op.f("ix_actors_image_url"), table_name="actors") - op.drop_column("actors", "image_url") + op.drop_index(op.f('ix_actors_image_url'), table_name='actors') + op.drop_column('actors', 'image_url') # ### end Alembic commands ### From 48a6c358a8e2b9552014a87bd7ff99bd0c759be7 Mon Sep 17 00:00:00 2001 From: cl0ete Date: Thu, 26 Sep 2024 15:06:29 +0200 Subject: [PATCH 43/56] :art: --- .../versions/5bcfb2c0bc05_actor_image_url.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/trustregistry/migrations/versions/5bcfb2c0bc05_actor_image_url.py b/trustregistry/migrations/versions/5bcfb2c0bc05_actor_image_url.py index d87f84eb4..e8870ca9f 100644 --- a/trustregistry/migrations/versions/5bcfb2c0bc05_actor_image_url.py +++ b/trustregistry/migrations/versions/5bcfb2c0bc05_actor_image_url.py @@ -5,28 +5,28 @@ Create Date: 2024-09-26 15:03:08.338158 """ + from typing import Sequence, Union -from alembic import op import sqlalchemy as sa - +from alembic import op # revision identifiers, used by Alembic. -revision: str = '5bcfb2c0bc05' -down_revision: Union[str, None] = 'fd3e6dc8a75a' +revision: str = "5bcfb2c0bc05" +down_revision: Union[str, None] = "fd3e6dc8a75a" branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: # ### commands auto generated by Alembic - please adjust! ### - op.add_column('actors', sa.Column('image_url', sa.String(), nullable=True)) - op.create_index(op.f('ix_actors_image_url'), 'actors', ['image_url'], unique=False) + op.add_column("actors", sa.Column("image_url", sa.String(), nullable=True)) + op.create_index(op.f("ix_actors_image_url"), "actors", ["image_url"], unique=False) # ### end Alembic commands ### def downgrade() -> None: # ### commands auto generated by Alembic - please adjust! ### - op.drop_index(op.f('ix_actors_image_url'), table_name='actors') - op.drop_column('actors', 'image_url') + op.drop_index(op.f("ix_actors_image_url"), table_name="actors") + op.drop_column("actors", "image_url") # ### end Alembic commands ### From 3b95a1aebd0a15b166d09d0bc5d963ab9affd71f Mon Sep 17 00:00:00 2001 From: cl0ete Date: Fri, 11 Oct 2024 10:13:30 +0200 Subject: [PATCH 44/56] poetry lock --- trustregistry/poetry.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trustregistry/poetry.lock b/trustregistry/poetry.lock index 70599f2c8..12ea3c8a5 100644 --- a/trustregistry/poetry.lock +++ b/trustregistry/poetry.lock @@ -1597,4 +1597,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "c4663ee6143b6fde3f30710ecc8b0c5ca774c198365cd6192555162fd7b3f2ee" +content-hash = "0522743fa030ec85aaeaffb76f15d33c4da51aa537aff3b24f50f5b61649601f" From 0fe3363935cdf43551decd3c989d66ed06d425eb Mon Sep 17 00:00:00 2001 From: cl0ete Date: Fri, 11 Oct 2024 14:20:51 +0200 Subject: [PATCH 45/56] clean up logging --- trustregistry/main.py | 11 +++++------ trustregistry/migrations/env.py | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/trustregistry/main.py b/trustregistry/main.py index 14ffca025..bb77e3b62 100644 --- a/trustregistry/main.py +++ b/trustregistry/main.py @@ -9,7 +9,6 @@ from scalar_fastapi import get_scalar_api_reference from sqlalchemy import inspect from sqlalchemy.engine import Engine -from sqlalchemy.exc import ProgrammingError from sqlalchemy.orm import Session from shared.constants import PROJECT_VERSION @@ -42,10 +41,10 @@ def check_migrations( initial_revision = script.get_base() command.stamp(alembic_cfg, initial_revision) logger.info( - f"Database stamped with initial migration version: {initial_revision}" + "Database stamped with initial migration version: {}", initial_revision ) - except Exception as e: # pylint: disable=W0718 - logger.error(f"Error stamping database: {e}") + except Exception: # pylint: disable=W0718 + logger.exception("Error stamping database") raise # Get current revision @@ -67,8 +66,8 @@ async def lifespan(_: FastAPI): try: command.upgrade(alembic_cfg, "head") logger.info("Database schema is up to date.") - except Exception as e: - logger.error(f"Error during migration: {e}") + except Exception: # pylint: disable=broad-except + logger.exception("Error during migration") raise else: logger.info("Database is up to date. No migrations needed.") diff --git a/trustregistry/migrations/env.py b/trustregistry/migrations/env.py index 63b8e40d9..95bdc92e7 100644 --- a/trustregistry/migrations/env.py +++ b/trustregistry/migrations/env.py @@ -29,7 +29,7 @@ db_url = os.environ.get("POSTGRES_DATABASE_URL") if db_url: - logger.debug(f"Using database URL from environment") + logger.debug("Using database URL from environment") config.set_main_option("sqlalchemy.url", db_url) else: logger.warning( From 1d02461f2ffd11f8622c2764364b5bcd757f915a Mon Sep 17 00:00:00 2001 From: cl0ete Date: Fri, 11 Oct 2024 14:22:25 +0200 Subject: [PATCH 46/56] # pylint: disable=redefined-outer-name --- trustregistry/main.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/trustregistry/main.py b/trustregistry/main.py index bb77e3b62..8a03c4b3f 100644 --- a/trustregistry/main.py +++ b/trustregistry/main.py @@ -25,8 +25,8 @@ def check_migrations( - engine: Engine, alembic_cfg: Config -) -> bool: # pylint: disable=redefined-outer-name + engine: Engine, alembic_cfg: Config # pylint: disable=redefined-outer-name +) -> bool: # Check if alembic_version table exists with engine.connect() as connection: inspector = inspect(connection) From 52f5adf14e0fd4405191bb497d0281826f5ff91c Mon Sep 17 00:00:00 2001 From: cl0ete Date: Fri, 11 Oct 2024 14:22:37 +0200 Subject: [PATCH 47/56] remove unused import --- trustregistry/tests/test_main.py | 1 - 1 file changed, 1 deletion(-) diff --git a/trustregistry/tests/test_main.py b/trustregistry/tests/test_main.py index 9ee6311b9..f78f2e7fb 100644 --- a/trustregistry/tests/test_main.py +++ b/trustregistry/tests/test_main.py @@ -2,7 +2,6 @@ import pytest from fastapi import FastAPI -from sqlalchemy.exc import ProgrammingError from sqlalchemy.orm import Session from trustregistry import db From 0df7ad64a28b32d16801a6c6448126d845bb5333 Mon Sep 17 00:00:00 2001 From: cl0ete Date: Fri, 11 Oct 2024 14:23:08 +0200 Subject: [PATCH 48/56] :art: --- trustregistry/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trustregistry/main.py b/trustregistry/main.py index 8a03c4b3f..1bf1e2ea2 100644 --- a/trustregistry/main.py +++ b/trustregistry/main.py @@ -25,7 +25,7 @@ def check_migrations( - engine: Engine, alembic_cfg: Config # pylint: disable=redefined-outer-name + engine: Engine, alembic_cfg: Config # pylint: disable=redefined-outer-name ) -> bool: # Check if alembic_version table exists with engine.connect() as connection: From 2a8a56f6d92d984b28402a4453a3f74bb1a7c8f9 Mon Sep 17 00:00:00 2001 From: cl0ete Date: Fri, 11 Oct 2024 15:38:16 +0200 Subject: [PATCH 49/56] fix migration logic for empty db --- trustregistry/main.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/trustregistry/main.py b/trustregistry/main.py index 1bf1e2ea2..aff3017e0 100644 --- a/trustregistry/main.py +++ b/trustregistry/main.py @@ -30,10 +30,12 @@ def check_migrations( # Check if alembic_version table exists with engine.connect() as connection: inspector = inspect(connection) - has_alembic_version = "alembic_version" in inspector.get_table_names() + table_names = inspector.get_table_names() + has_alembic_version = "alembic_version" in table_names + has_actors_table = "actors" in table_names script = ScriptDirectory.from_config(alembic_cfg) - if not has_alembic_version: + if not has_alembic_version and has_actors_table: logger.info( "Alembic version table not found. Stamping with initial revision..." ) @@ -47,6 +49,10 @@ def check_migrations( logger.exception("Error stamping database") raise + elif not has_alembic_version: + logger.info("Alembic version table not found.") + return False + # Get current revision with engine.connect() as connection: context = MigrationContext.configure(connection) From 50a99e717c3e4e99c8ef853e7d7e6359227b921b Mon Sep 17 00:00:00 2001 From: cl0ete Date: Fri, 11 Oct 2024 15:38:26 +0200 Subject: [PATCH 50/56] update tests --- trustregistry/tests/test_main.py | 46 ++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/trustregistry/tests/test_main.py b/trustregistry/tests/test_main.py index f78f2e7fb..0c7fe528a 100644 --- a/trustregistry/tests/test_main.py +++ b/trustregistry/tests/test_main.py @@ -76,6 +76,7 @@ async def test_lifespan_migration_error( mock_check_migrations, mock_engine, ): + # Mock return values mock_check_migrations.return_value = False mock_config.return_value = MagicMock() mock_command.upgrade.side_effect = Exception("Migration error") @@ -83,14 +84,16 @@ async def test_lifespan_migration_error( mock_inspector.get_table_names.return_value = ["table1", "table2"] mock_inspect.return_value = mock_inspector + # Test the lifespan context, expecting an Exception with pytest.raises(Exception, match="Migration error"): async with lifespan(FastAPI()): pass + # Assertions mock_check_migrations.assert_called_once_with(mock_engine, mock_config.return_value) mock_command.upgrade.assert_called_once_with(mock_config.return_value, "head") mock_logger.info.assert_called_with("Applying database migrations...") - mock_logger.error.assert_called_once_with("Error during migration: Migration error") + mock_logger.exception.assert_called_once_with("Error during migration") @pytest.mark.anyio @@ -130,11 +133,12 @@ async def test_lifespan_no_migrations_needed( @pytest.mark.parametrize( - "has_alembic_version,current_rev,head_rev,expected", + "has_alembic_version,has_actors_table,current_rev,head_rev,expected", [ - (False, None, "head_rev", False), # alembic_version table doesn't exist - (True, "current_rev", "head_rev", False), # revisions don't match - (True, "same_rev", "same_rev", True), # revisions match + (False, True, None, "head_rev", False), # alembic_version missing, actors exists + (False, False, None, "head_rev", False), # both alembic_version and actors missing + (True, True, "current_rev", "head_rev", False), # alembic_version exists, revisions don't match + (True, True, "same_rev", "same_rev", True), # alembic_version exists, revisions match ], ) @patch("trustregistry.main.inspect") @@ -149,6 +153,7 @@ def test_check_migrations( mock_migration_context, mock_inspect, has_alembic_version, + has_actors_table, current_rev, head_rev, expected, @@ -158,14 +163,18 @@ def test_check_migrations( mock_alembic_cfg = MagicMock() mock_inspector = MagicMock() - mock_inspector.get_table_names.return_value = ( - ["alembic_version"] if has_alembic_version else [] - ) + table_names = [] + if has_alembic_version: + table_names.append("alembic_version") + if has_actors_table: + table_names.append("actors") + + mock_inspector.get_table_names.return_value = table_names mock_inspect.return_value = mock_inspector mock_script = MagicMock() mock_script.get_current_head.return_value = head_rev - mock_script.get_base.return_value = "initial_revision" + mock_script.get_base.return_value = "initial_schema" mock_script_directory.from_config.return_value = mock_script mock_context = MagicMock() @@ -184,14 +193,17 @@ def test_check_migrations( mock_script_directory.from_config.assert_called_once_with(mock_alembic_cfg) if not has_alembic_version: - mock_script.get_base.assert_called_once() - mock_command.stamp.assert_called_once_with(mock_alembic_cfg, "initial_revision") - mock_logger.info.assert_any_call( - "Alembic version table not found. Stamping with initial revision..." - ) - mock_logger.info.assert_any_call( - "Database stamped with initial migration version: initial_revision" - ) + if has_actors_table: + mock_script.get_base.assert_called_once() + mock_command.stamp.assert_called_once_with(mock_alembic_cfg, "initial_schema") + mock_logger.info.assert_any_call( + "Alembic version table not found. Stamping with initial revision..." + ) + mock_logger.info.assert_any_call( + "Database stamped with initial migration version: {}", "initial_schema" + ) + else: + mock_logger.info.assert_any_call("Alembic version table not found.") else: mock_migration_context.configure.assert_called() mock_context.get_current_revision.assert_called_once() From 87e1a41de96707e960a0e93df746424ec587989e Mon Sep 17 00:00:00 2001 From: cl0ete Date: Fri, 11 Oct 2024 15:38:59 +0200 Subject: [PATCH 51/56] :art: --- trustregistry/tests/test_main.py | 36 +++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/trustregistry/tests/test_main.py b/trustregistry/tests/test_main.py index 0c7fe528a..0043ba8ef 100644 --- a/trustregistry/tests/test_main.py +++ b/trustregistry/tests/test_main.py @@ -135,10 +135,34 @@ async def test_lifespan_no_migrations_needed( @pytest.mark.parametrize( "has_alembic_version,has_actors_table,current_rev,head_rev,expected", [ - (False, True, None, "head_rev", False), # alembic_version missing, actors exists - (False, False, None, "head_rev", False), # both alembic_version and actors missing - (True, True, "current_rev", "head_rev", False), # alembic_version exists, revisions don't match - (True, True, "same_rev", "same_rev", True), # alembic_version exists, revisions match + ( + False, + True, + None, + "head_rev", + False, + ), # alembic_version missing, actors exists + ( + False, + False, + None, + "head_rev", + False, + ), # both alembic_version and actors missing + ( + True, + True, + "current_rev", + "head_rev", + False, + ), # alembic_version exists, revisions don't match + ( + True, + True, + "same_rev", + "same_rev", + True, + ), # alembic_version exists, revisions match ], ) @patch("trustregistry.main.inspect") @@ -195,7 +219,9 @@ def test_check_migrations( if not has_alembic_version: if has_actors_table: mock_script.get_base.assert_called_once() - mock_command.stamp.assert_called_once_with(mock_alembic_cfg, "initial_schema") + mock_command.stamp.assert_called_once_with( + mock_alembic_cfg, "initial_schema" + ) mock_logger.info.assert_any_call( "Alembic version table not found. Stamping with initial revision..." ) From dcadf8a4a7c94b90b1773501760bcb0b89f52582 Mon Sep 17 00:00:00 2001 From: cl0ete Date: Mon, 14 Oct 2024 09:56:28 +0200 Subject: [PATCH 52/56] update readme --- trustregistry/migrations/README | 1 - trustregistry/migrations/README.md | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) delete mode 100644 trustregistry/migrations/README create mode 100644 trustregistry/migrations/README.md diff --git a/trustregistry/migrations/README b/trustregistry/migrations/README deleted file mode 100644 index 98e4f9c44..000000000 --- a/trustregistry/migrations/README +++ /dev/null @@ -1 +0,0 @@ -Generic single-database configuration. \ No newline at end of file diff --git a/trustregistry/migrations/README.md b/trustregistry/migrations/README.md new file mode 100644 index 000000000..ed7ee6cde --- /dev/null +++ b/trustregistry/migrations/README.md @@ -0,0 +1,15 @@ +# Alembic Migrations + +## Overview + +This folder contains the migration scripts for the trust registry database. +These scripts are used to manage changes to the database schema in a consistent and version-controlled manner. + +### Files and Directories + +- `env.py`: This is the configuration file for Alembic, the database migration tool. + It sets up the database connection and other settings required for migrations. +- `script.py.mako`: This is a template file used by Alembic to generate new migration scripts. + It contains placeholders for the migration logic. +- `versions/`: This directory contains the individual migration scripts. + Each script is named with a unique identifier and describes a specific change to the database schema. From 4ebbe15e3a8e67c811b1421b282bf33f108ddf75 Mon Sep 17 00:00:00 2001 From: cl0ete Date: Mon, 14 Oct 2024 09:56:52 +0200 Subject: [PATCH 53/56] :art: --- trustregistry/tests/test_main.py | 36 +++++++------------------------- 1 file changed, 8 insertions(+), 28 deletions(-) diff --git a/trustregistry/tests/test_main.py b/trustregistry/tests/test_main.py index 0043ba8ef..a3ea42dc5 100644 --- a/trustregistry/tests/test_main.py +++ b/trustregistry/tests/test_main.py @@ -132,37 +132,17 @@ async def test_lifespan_no_migrations_needed( ) +# Test 1: alembic_version missing, actors exists +# Test 2: both alembic_version and actors missing +# Test 3: alembic_version exists, revisions don't match +# Test 4: alembic_version exists, revisions match @pytest.mark.parametrize( "has_alembic_version,has_actors_table,current_rev,head_rev,expected", [ - ( - False, - True, - None, - "head_rev", - False, - ), # alembic_version missing, actors exists - ( - False, - False, - None, - "head_rev", - False, - ), # both alembic_version and actors missing - ( - True, - True, - "current_rev", - "head_rev", - False, - ), # alembic_version exists, revisions don't match - ( - True, - True, - "same_rev", - "same_rev", - True, - ), # alembic_version exists, revisions match + (False, True, None, "head_rev", False), + (False, False, None, "head_rev", False), + (True, True, "current_rev", "head_rev", False), + (True, True, "same_rev", "same_rev", True), ], ) @patch("trustregistry.main.inspect") From f31be450ac0573dbfe1884823359906bfd48985f Mon Sep 17 00:00:00 2001 From: cl0ete Date: Mon, 14 Oct 2024 09:58:03 +0200 Subject: [PATCH 54/56] rename engine in check_migrations --- trustregistry/main.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/trustregistry/main.py b/trustregistry/main.py index aff3017e0..11fd4d72b 100644 --- a/trustregistry/main.py +++ b/trustregistry/main.py @@ -25,10 +25,10 @@ def check_migrations( - engine: Engine, alembic_cfg: Config # pylint: disable=redefined-outer-name + db_engine: Engine, alembic_cfg: Config ) -> bool: # Check if alembic_version table exists - with engine.connect() as connection: + with db_engine.connect() as connection: inspector = inspect(connection) table_names = inspector.get_table_names() has_alembic_version = "alembic_version" in table_names @@ -54,7 +54,7 @@ def check_migrations( return False # Get current revision - with engine.connect() as connection: + with db_engine.connect() as connection: context = MigrationContext.configure(connection) current_rev = context.get_current_revision() From 0c550beff44f7c243b5947638fa122fcefdb1276 Mon Sep 17 00:00:00 2001 From: cl0ete Date: Mon, 14 Oct 2024 09:58:46 +0200 Subject: [PATCH 55/56] remove alembic from dev-dependencies --- trustregistry/poetry.lock | 152 +++++++++++++++++------------------ trustregistry/pyproject.toml | 1 - 2 files changed, 76 insertions(+), 77 deletions(-) diff --git a/trustregistry/poetry.lock b/trustregistry/poetry.lock index 12ea3c8a5..6db6333a5 100644 --- a/trustregistry/poetry.lock +++ b/trustregistry/poetry.lock @@ -32,13 +32,13 @@ files = [ [[package]] name = "anyio" -version = "4.6.0" +version = "4.6.2" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false -python-versions = ">=3.9" +python-versions = ">=3.8" files = [ - {file = "anyio-4.6.0-py3-none-any.whl", hash = "sha256:c7d2e9d63e31599eeb636c8c5c03a7e108d73b345f064f1c19fdc87b79036a9a"}, - {file = "anyio-4.6.0.tar.gz", hash = "sha256:137b4559cbb034c477165047febb6ff83f390fc3b20bf181c1fc0a728cb8beeb"}, + {file = "anyio-4.6.2-py3-none-any.whl", hash = "sha256:6caec6b1391f6f6d7b2ef2258d2902d36753149f67478f7df4be8e54d03a8f54"}, + {file = "anyio-4.6.2.tar.gz", hash = "sha256:f72a7bb3dd0752b3bd8b17a844a019d7fbf6ae218c588f4f9ba1b2f600b12347"}, ] [package.dependencies] @@ -47,7 +47,7 @@ sniffio = ">=1.1" [package.extras] doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.21.0b1)"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "truststore (>=0.9.1)", "uvloop (>=0.21.0b1)"] trio = ["trio (>=0.26.1)"] [[package]] @@ -165,73 +165,73 @@ files = [ [[package]] name = "coverage" -version = "7.6.2" +version = "7.6.3" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.9" files = [ - {file = "coverage-7.6.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c9df1950fb92d49970cce38100d7e7293c84ed3606eaa16ea0b6bc27175bb667"}, - {file = "coverage-7.6.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:24500f4b0e03aab60ce575c85365beab64b44d4db837021e08339f61d1fbfe52"}, - {file = "coverage-7.6.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a663b180b6669c400b4630a24cc776f23a992d38ce7ae72ede2a397ce6b0f170"}, - {file = "coverage-7.6.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bfde025e2793a22efe8c21f807d276bd1d6a4bcc5ba6f19dbdfc4e7a12160909"}, - {file = "coverage-7.6.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:087932079c065d7b8ebadd3a0160656c55954144af6439886c8bcf78bbbcde7f"}, - {file = "coverage-7.6.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9c6b0c1cafd96213a0327cf680acb39f70e452caf8e9a25aeb05316db9c07f89"}, - {file = "coverage-7.6.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:6e85830eed5b5263ffa0c62428e43cb844296f3b4461f09e4bdb0d44ec190bc2"}, - {file = "coverage-7.6.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:62ab4231c01e156ece1b3a187c87173f31cbeee83a5e1f6dff17f288dca93345"}, - {file = "coverage-7.6.2-cp310-cp310-win32.whl", hash = "sha256:7b80fbb0da3aebde102a37ef0138aeedff45997e22f8962e5f16ae1742852676"}, - {file = "coverage-7.6.2-cp310-cp310-win_amd64.whl", hash = "sha256:d20c3d1f31f14d6962a4e2f549c21d31e670b90f777ef4171be540fb7fb70f02"}, - {file = "coverage-7.6.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bb21bac7783c1bf6f4bbe68b1e0ff0d20e7e7732cfb7995bc8d96e23aa90fc7b"}, - {file = "coverage-7.6.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a7b2e437fbd8fae5bc7716b9c7ff97aecc95f0b4d56e4ca08b3c8d8adcaadb84"}, - {file = "coverage-7.6.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:536f77f2bf5797983652d1d55f1a7272a29afcc89e3ae51caa99b2db4e89d658"}, - {file = "coverage-7.6.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f361296ca7054f0936b02525646b2731b32c8074ba6defab524b79b2b7eeac72"}, - {file = "coverage-7.6.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7926d8d034e06b479797c199747dd774d5e86179f2ce44294423327a88d66ca7"}, - {file = "coverage-7.6.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0bbae11c138585c89fb4e991faefb174a80112e1a7557d507aaa07675c62e66b"}, - {file = "coverage-7.6.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:fcad7d5d2bbfeae1026b395036a8aa5abf67e8038ae7e6a25c7d0f88b10a8e6a"}, - {file = "coverage-7.6.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f01e53575f27097d75d42de33b1b289c74b16891ce576d767ad8c48d17aeb5e0"}, - {file = "coverage-7.6.2-cp311-cp311-win32.whl", hash = "sha256:7781f4f70c9b0b39e1b129b10c7d43a4e0c91f90c60435e6da8288efc2b73438"}, - {file = "coverage-7.6.2-cp311-cp311-win_amd64.whl", hash = "sha256:9bcd51eeca35a80e76dc5794a9dd7cb04b97f0e8af620d54711793bfc1fbba4b"}, - {file = "coverage-7.6.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ebc94fadbd4a3f4215993326a6a00e47d79889391f5659bf310f55fe5d9f581c"}, - {file = "coverage-7.6.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9681516288e3dcf0aa7c26231178cc0be6cac9705cac06709f2353c5b406cfea"}, - {file = "coverage-7.6.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d9c5d13927d77af4fbe453953810db766f75401e764727e73a6ee4f82527b3e"}, - {file = "coverage-7.6.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b92f9ca04b3e719d69b02dc4a69debb795af84cb7afd09c5eb5d54b4a1ae2191"}, - {file = "coverage-7.6.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ff2ef83d6d0b527b5c9dad73819b24a2f76fdddcfd6c4e7a4d7e73ecb0656b4"}, - {file = "coverage-7.6.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:47ccb6e99a3031ffbbd6e7cc041e70770b4fe405370c66a54dbf26a500ded80b"}, - {file = "coverage-7.6.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a867d26f06bcd047ef716175b2696b315cb7571ccb951006d61ca80bbc356e9e"}, - {file = "coverage-7.6.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:cdfcf2e914e2ba653101157458afd0ad92a16731eeba9a611b5cbb3e7124e74b"}, - {file = "coverage-7.6.2-cp312-cp312-win32.whl", hash = "sha256:f9035695dadfb397bee9eeaf1dc7fbeda483bf7664a7397a629846800ce6e276"}, - {file = "coverage-7.6.2-cp312-cp312-win_amd64.whl", hash = "sha256:5ed69befa9a9fc796fe015a7040c9398722d6b97df73a6b608e9e275fa0932b0"}, - {file = "coverage-7.6.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4eea60c79d36a8f39475b1af887663bc3ae4f31289cd216f514ce18d5938df40"}, - {file = "coverage-7.6.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:aa68a6cdbe1bc6793a9dbfc38302c11599bbe1837392ae9b1d238b9ef3dafcf1"}, - {file = "coverage-7.6.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ec528ae69f0a139690fad6deac8a7d33629fa61ccce693fdd07ddf7e9931fba"}, - {file = "coverage-7.6.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ed5ac02126f74d190fa2cc14a9eb2a5d9837d5863920fa472b02eb1595cdc925"}, - {file = "coverage-7.6.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21c0ea0d4db8a36b275cb6fb2437a3715697a4ba3cb7b918d3525cc75f726304"}, - {file = "coverage-7.6.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:35a51598f29b2a19e26d0908bd196f771a9b1c5d9a07bf20be0adf28f1ad4f77"}, - {file = "coverage-7.6.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:c9192925acc33e146864b8cf037e2ed32a91fdf7644ae875f5d46cd2ef086a5f"}, - {file = "coverage-7.6.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:bf4eeecc9e10f5403ec06138978235af79c9a79af494eb6b1d60a50b49ed2869"}, - {file = "coverage-7.6.2-cp313-cp313-win32.whl", hash = "sha256:e4ee15b267d2dad3e8759ca441ad450c334f3733304c55210c2a44516e8d5530"}, - {file = "coverage-7.6.2-cp313-cp313-win_amd64.whl", hash = "sha256:c71965d1ced48bf97aab79fad56df82c566b4c498ffc09c2094605727c4b7e36"}, - {file = "coverage-7.6.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:7571e8bbecc6ac066256f9de40365ff833553e2e0c0c004f4482facb131820ef"}, - {file = "coverage-7.6.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:078a87519057dacb5d77e333f740708ec2a8f768655f1db07f8dfd28d7a005f0"}, - {file = "coverage-7.6.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e5e92e3e84a8718d2de36cd8387459cba9a4508337b8c5f450ce42b87a9e760"}, - {file = "coverage-7.6.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ebabdf1c76593a09ee18c1a06cd3022919861365219ea3aca0247ededf6facd6"}, - {file = "coverage-7.6.2-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:12179eb0575b8900912711688e45474f04ab3934aaa7b624dea7b3c511ecc90f"}, - {file = "coverage-7.6.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:39d3b964abfe1519b9d313ab28abf1d02faea26cd14b27f5283849bf59479ff5"}, - {file = "coverage-7.6.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:84c4315577f7cd511d6250ffd0f695c825efe729f4205c0340f7004eda51191f"}, - {file = "coverage-7.6.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ff797320dcbff57caa6b2301c3913784a010e13b1f6cf4ab3f563f3c5e7919db"}, - {file = "coverage-7.6.2-cp313-cp313t-win32.whl", hash = "sha256:2b636a301e53964550e2f3094484fa5a96e699db318d65398cfba438c5c92171"}, - {file = "coverage-7.6.2-cp313-cp313t-win_amd64.whl", hash = "sha256:d03a060ac1a08e10589c27d509bbdb35b65f2d7f3f8d81cf2fa199877c7bc58a"}, - {file = "coverage-7.6.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c37faddc8acd826cfc5e2392531aba734b229741d3daec7f4c777a8f0d4993e5"}, - {file = "coverage-7.6.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ab31fdd643f162c467cfe6a86e9cb5f1965b632e5e65c072d90854ff486d02cf"}, - {file = "coverage-7.6.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97df87e1a20deb75ac7d920c812e9326096aa00a9a4b6d07679b4f1f14b06c90"}, - {file = "coverage-7.6.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:343056c5e0737487a5291f5691f4dfeb25b3e3c8699b4d36b92bb0e586219d14"}, - {file = "coverage-7.6.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad4ef1c56b47b6b9024b939d503ab487231df1f722065a48f4fc61832130b90e"}, - {file = "coverage-7.6.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7fca4a92c8a7a73dee6946471bce6d1443d94155694b893b79e19ca2a540d86e"}, - {file = "coverage-7.6.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:69f251804e052fc46d29d0e7348cdc5fcbfc4861dc4a1ebedef7e78d241ad39e"}, - {file = "coverage-7.6.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:e8ea055b3ea046c0f66217af65bc193bbbeca1c8661dc5fd42698db5795d2627"}, - {file = "coverage-7.6.2-cp39-cp39-win32.whl", hash = "sha256:6c2ba1e0c24d8fae8f2cf0aeb2fc0a2a7f69b6d20bd8d3749fd6b36ecef5edf0"}, - {file = "coverage-7.6.2-cp39-cp39-win_amd64.whl", hash = "sha256:2186369a654a15628e9c1c9921409a6b3eda833e4b91f3ca2a7d9f77abb4987c"}, - {file = "coverage-7.6.2-pp39.pp310-none-any.whl", hash = "sha256:667952739daafe9616db19fbedbdb87917eee253ac4f31d70c7587f7ab531b4e"}, - {file = "coverage-7.6.2.tar.gz", hash = "sha256:a5f81e68aa62bc0cfca04f7b19eaa8f9c826b53fc82ab9e2121976dc74f131f3"}, + {file = "coverage-7.6.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6da42bbcec130b188169107ecb6ee7bd7b4c849d24c9370a0c884cf728d8e976"}, + {file = "coverage-7.6.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c222958f59b0ae091f4535851cbb24eb57fc0baea07ba675af718fb5302dddb2"}, + {file = "coverage-7.6.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ab84a8b698ad5a6c365b08061920138e7a7dd9a04b6feb09ba1bfae68346ce6d"}, + {file = "coverage-7.6.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:70a6756ce66cd6fe8486c775b30889f0dc4cb20c157aa8c35b45fd7868255c5c"}, + {file = "coverage-7.6.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c2e6fa98032fec8282f6b27e3f3986c6e05702828380618776ad794e938f53a"}, + {file = "coverage-7.6.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:921fbe13492caf6a69528f09d5d7c7d518c8d0e7b9f6701b7719715f29a71e6e"}, + {file = "coverage-7.6.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:6d99198203f0b9cb0b5d1c0393859555bc26b548223a769baf7e321a627ed4fc"}, + {file = "coverage-7.6.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:87cd2e29067ea397a47e352efb13f976eb1b03e18c999270bb50589323294c6e"}, + {file = "coverage-7.6.3-cp310-cp310-win32.whl", hash = "sha256:a3328c3e64ea4ab12b85999eb0779e6139295bbf5485f69d42cf794309e3d007"}, + {file = "coverage-7.6.3-cp310-cp310-win_amd64.whl", hash = "sha256:bca4c8abc50d38f9773c1ec80d43f3768df2e8576807d1656016b9d3eeaa96fd"}, + {file = "coverage-7.6.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c51ef82302386d686feea1c44dbeef744585da16fcf97deea2a8d6c1556f519b"}, + {file = "coverage-7.6.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0ca37993206402c6c35dc717f90d4c8f53568a8b80f0bf1a1b2b334f4d488fba"}, + {file = "coverage-7.6.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c77326300b839c44c3e5a8fe26c15b7e87b2f32dfd2fc9fee1d13604347c9b38"}, + {file = "coverage-7.6.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e484e479860e00da1f005cd19d1c5d4a813324e5951319ac3f3eefb497cc549"}, + {file = "coverage-7.6.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c6c0f4d53ef603397fc894a895b960ecd7d44c727df42a8d500031716d4e8d2"}, + {file = "coverage-7.6.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:37be7b5ea3ff5b7c4a9db16074dc94523b5f10dd1f3b362a827af66a55198175"}, + {file = "coverage-7.6.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:43b32a06c47539fe275106b376658638b418c7cfdfff0e0259fbf877e845f14b"}, + {file = "coverage-7.6.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ee77c7bef0724165e795b6b7bf9c4c22a9b8468a6bdb9c6b4281293c6b22a90f"}, + {file = "coverage-7.6.3-cp311-cp311-win32.whl", hash = "sha256:43517e1f6b19f610a93d8227e47790722c8bf7422e46b365e0469fc3d3563d97"}, + {file = "coverage-7.6.3-cp311-cp311-win_amd64.whl", hash = "sha256:04f2189716e85ec9192df307f7c255f90e78b6e9863a03223c3b998d24a3c6c6"}, + {file = "coverage-7.6.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:27bd5f18d8f2879e45724b0ce74f61811639a846ff0e5c0395b7818fae87aec6"}, + {file = "coverage-7.6.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d546cfa78844b8b9c1c0533de1851569a13f87449897bbc95d698d1d3cb2a30f"}, + {file = "coverage-7.6.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9975442f2e7a5cfcf87299c26b5a45266ab0696348420049b9b94b2ad3d40234"}, + {file = "coverage-7.6.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:583049c63106c0555e3ae3931edab5669668bbef84c15861421b94e121878d3f"}, + {file = "coverage-7.6.3-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2341a78ae3a5ed454d524206a3fcb3cec408c2a0c7c2752cd78b606a2ff15af4"}, + {file = "coverage-7.6.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a4fb91d5f72b7e06a14ff4ae5be625a81cd7e5f869d7a54578fc271d08d58ae3"}, + {file = "coverage-7.6.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e279f3db904e3b55f520f11f983cc8dc8a4ce9b65f11692d4718ed021ec58b83"}, + {file = "coverage-7.6.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:aa23ce39661a3e90eea5f99ec59b763b7d655c2cada10729ed920a38bfc2b167"}, + {file = "coverage-7.6.3-cp312-cp312-win32.whl", hash = "sha256:52ac29cc72ee7e25ace7807249638f94c9b6a862c56b1df015d2b2e388e51dbd"}, + {file = "coverage-7.6.3-cp312-cp312-win_amd64.whl", hash = "sha256:40e8b1983080439d4802d80b951f4a93d991ef3261f69e81095a66f86cf3c3c6"}, + {file = "coverage-7.6.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9134032f5aa445ae591c2ba6991d10136a1f533b1d2fa8f8c21126468c5025c6"}, + {file = "coverage-7.6.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:99670790f21a96665a35849990b1df447993880bb6463a0a1d757897f30da929"}, + {file = "coverage-7.6.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2dc7d6b380ca76f5e817ac9eef0c3686e7834c8346bef30b041a4ad286449990"}, + {file = "coverage-7.6.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f7b26757b22faf88fcf232f5f0e62f6e0fd9e22a8a5d0d5016888cdfe1f6c1c4"}, + {file = "coverage-7.6.3-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c59d6a4a4633fad297f943c03d0d2569867bd5372eb5684befdff8df8522e39"}, + {file = "coverage-7.6.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f263b18692f8ed52c8de7f40a0751e79015983dbd77b16906e5b310a39d3ca21"}, + {file = "coverage-7.6.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:79644f68a6ff23b251cae1c82b01a0b51bc40c8468ca9585c6c4b1aeee570e0b"}, + {file = "coverage-7.6.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:71967c35828c9ff94e8c7d405469a1fb68257f686bca7c1ed85ed34e7c2529c4"}, + {file = "coverage-7.6.3-cp313-cp313-win32.whl", hash = "sha256:e266af4da2c1a4cbc6135a570c64577fd3e6eb204607eaff99d8e9b710003c6f"}, + {file = "coverage-7.6.3-cp313-cp313-win_amd64.whl", hash = "sha256:ea52bd218d4ba260399a8ae4bb6b577d82adfc4518b93566ce1fddd4a49d1dce"}, + {file = "coverage-7.6.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:8d4c6ea0f498c7c79111033a290d060c517853a7bcb2f46516f591dab628ddd3"}, + {file = "coverage-7.6.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:331b200ad03dbaa44151d74daeb7da2cf382db424ab923574f6ecca7d3b30de3"}, + {file = "coverage-7.6.3-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54356a76b67cf8a3085818026bb556545ebb8353951923b88292556dfa9f812d"}, + {file = "coverage-7.6.3-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ebec65f5068e7df2d49466aab9128510c4867e532e07cb6960075b27658dca38"}, + {file = "coverage-7.6.3-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d33a785ea8354c480515e781554d3be582a86297e41ccbea627a5c632647f2cd"}, + {file = "coverage-7.6.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:f7ddb920106bbbbcaf2a274d56f46956bf56ecbde210d88061824a95bdd94e92"}, + {file = "coverage-7.6.3-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:70d24936ca6c15a3bbc91ee9c7fc661132c6f4c9d42a23b31b6686c05073bde5"}, + {file = "coverage-7.6.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c30e42ea11badb147f0d2e387115b15e2bd8205a5ad70d6ad79cf37f6ac08c91"}, + {file = "coverage-7.6.3-cp313-cp313t-win32.whl", hash = "sha256:365defc257c687ce3e7d275f39738dcd230777424117a6c76043459db131dd43"}, + {file = "coverage-7.6.3-cp313-cp313t-win_amd64.whl", hash = "sha256:23bb63ae3f4c645d2d82fa22697364b0046fbafb6261b258a58587441c5f7bd0"}, + {file = "coverage-7.6.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:da29ceabe3025a1e5a5aeeb331c5b1af686daab4ff0fb4f83df18b1180ea83e2"}, + {file = "coverage-7.6.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:df8c05a0f574d480947cba11b947dc41b1265d721c3777881da2fb8d3a1ddfba"}, + {file = "coverage-7.6.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec1e3b40b82236d100d259854840555469fad4db64f669ab817279eb95cd535c"}, + {file = "coverage-7.6.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b4adeb878a374126f1e5cf03b87f66279f479e01af0e9a654cf6d1509af46c40"}, + {file = "coverage-7.6.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:43d6a66e33b1455b98fc7312b124296dad97a2e191c80320587234a77b1b736e"}, + {file = "coverage-7.6.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1990b1f4e2c402beb317840030bb9f1b6a363f86e14e21b4212e618acdfce7f6"}, + {file = "coverage-7.6.3-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:12f9515d875859faedb4144fd38694a761cd2a61ef9603bf887b13956d0bbfbb"}, + {file = "coverage-7.6.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:99ded130555c021d99729fabd4ddb91a6f4cc0707df4b1daf912c7850c373b13"}, + {file = "coverage-7.6.3-cp39-cp39-win32.whl", hash = "sha256:c3a79f56dee9136084cf84a6c7c4341427ef36e05ae6415bf7d787c96ff5eaa3"}, + {file = "coverage-7.6.3-cp39-cp39-win_amd64.whl", hash = "sha256:aac7501ae73d4a02f4b7ac8fcb9dc55342ca98ffb9ed9f2dfb8a25d53eda0e4d"}, + {file = "coverage-7.6.3-pp39.pp310-none-any.whl", hash = "sha256:b9853509b4bf57ba7b1f99b9d866c422c9c5248799ab20e652bbb8a184a38181"}, + {file = "coverage-7.6.3.tar.gz", hash = "sha256:bb7d5fe92bd0dc235f63ebe9f8c6e0884f7360f88f3411bfed1350c872ef2054"}, ] [package.extras] @@ -378,18 +378,18 @@ mypy = ["mypy"] [[package]] name = "fastapi" -version = "0.115.0" +version = "0.115.2" description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" optional = false python-versions = ">=3.8" files = [ - {file = "fastapi-0.115.0-py3-none-any.whl", hash = "sha256:17ea427674467486e997206a5ab25760f6b09e069f099b96f5b55a32fb6f1631"}, - {file = "fastapi-0.115.0.tar.gz", hash = "sha256:f93b4ca3529a8ebc6fc3fcf710e5efa8de3df9b41570958abf1d97d843138004"}, + {file = "fastapi-0.115.2-py3-none-any.whl", hash = "sha256:61704c71286579cc5a598763905928f24ee98bfcc07aabe84cfefb98812bbc86"}, + {file = "fastapi-0.115.2.tar.gz", hash = "sha256:3995739e0b09fa12f984bce8fa9ae197b35d433750d3d312422d846e283697ee"}, ] [package.dependencies] pydantic = ">=1.7.4,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0 || >2.0.0,<2.0.1 || >2.0.1,<2.1.0 || >2.1.0,<3.0.0" -starlette = ">=0.37.2,<0.39.0" +starlette = ">=0.37.2,<0.41.0" typing-extensions = ">=4.8.0" [package.extras] @@ -1396,13 +1396,13 @@ sqlcipher = ["sqlcipher3_binary"] [[package]] name = "starlette" -version = "0.38.6" +version = "0.39.2" description = "The little ASGI library that shines." optional = false python-versions = ">=3.8" files = [ - {file = "starlette-0.38.6-py3-none-any.whl", hash = "sha256:4517a1409e2e73ee4951214ba012052b9e16f60e90d73cfb06192c19203bbb05"}, - {file = "starlette-0.38.6.tar.gz", hash = "sha256:863a1588f5574e70a821dadefb41e4881ea451a47a3cd1b4df359d4ffefe5ead"}, + {file = "starlette-0.39.2-py3-none-any.whl", hash = "sha256:134dd6deb655a9775991d352312d53f1879775e5cc8a481f966e83416a2c3f71"}, + {file = "starlette-0.39.2.tar.gz", hash = "sha256:caaa3b87ef8518ef913dac4f073dea44e85f73343ad2bdc17941931835b2a26a"}, ] [package.dependencies] @@ -1597,4 +1597,4 @@ type = ["pytest-mypy"] [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "0522743fa030ec85aaeaffb76f15d33c4da51aa537aff3b24f50f5b61649601f" +content-hash = "c4663ee6143b6fde3f30710ecc8b0c5ca774c198365cd6192555162fd7b3f2ee" diff --git a/trustregistry/pyproject.toml b/trustregistry/pyproject.toml index edb7a2ffe..8233f686e 100644 --- a/trustregistry/pyproject.toml +++ b/trustregistry/pyproject.toml @@ -29,7 +29,6 @@ pylint = "~3.3.0" pytest = "~8.3.2" pytest-cov = "~5.0.0" pytest-mock = "~3.14.0" -alembic = "~1.13.2" [build-system] requires = ["poetry-core>=1.8.3"] From f14082e54d74c5ea67a27f8cf4869d16f35a182a Mon Sep 17 00:00:00 2001 From: cl0ete Date: Mon, 14 Oct 2024 10:08:04 +0200 Subject: [PATCH 56/56] :art: --- trustregistry/main.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/trustregistry/main.py b/trustregistry/main.py index 11fd4d72b..3bdf6828f 100644 --- a/trustregistry/main.py +++ b/trustregistry/main.py @@ -24,9 +24,7 @@ ROOT_PATH = os.getenv("ROOT_PATH", "") -def check_migrations( - db_engine: Engine, alembic_cfg: Config -) -> bool: +def check_migrations(db_engine: Engine, alembic_cfg: Config) -> bool: # Check if alembic_version table exists with db_engine.connect() as connection: inspector = inspect(connection)