From 2bf6bc6e773691bc094bd83ffb8c4fde419b402f Mon Sep 17 00:00:00 2001 From: ducklet Date: Mon, 8 Apr 2024 22:09:18 +0200 Subject: [PATCH 01/25] wip --- unwind/models.py | 42 +++++++++++++++++++++++++++++++ unwind/web.py | 64 ++++++++++++++++++++++++++++++++++-------------- 2 files changed, 88 insertions(+), 18 deletions(-) diff --git a/unwind/models.py b/unwind/models.py index 6ea13e9..aae161b 100644 --- a/unwind/models.py +++ b/unwind/models.py @@ -457,6 +457,48 @@ class Rating: ratings = Rating.__table__ +# TODO +# - distinguish between ratings & watches +# - they are completely separate +# - I can rate something at any time, without having watched it, e.g. in a discussion with a friend I change my opinion on a movie +# - I can watch something without having fully formed an opinion yet, i.e. I don't want to rate it yet + + +@mapper_registry.mapped +@dataclass +class Watch: + __table__: ClassVar[Table] = Table( + "watches", + metadata, + Column("id", String, primary_key=True), # ULID + Column("movie_id", ForeignKey("movies.id"), nullable=False), # ULID + Column("user_id", ForeignKey("users.id"), nullable=False), # ULID + Column("started", String, nullable=False), # datetime + Column("finished", String), # datetime + Column("geoloc", String), # geo coords + Column("score", Integer), # + Column("favorite", Integer), # bool + ) + + id: ULID = field(default_factory=ULID) + + movie_id: ULID = None + movie: Relation[Movie] = None + + user_id: ULID = None + user: Relation[User] = None + + started: datetime | None = None + finished: datetime | None = None + + geoloc: str | None = None + score: int | None = None # range: [0,100] + favorite: bool | None = None + + +watches = Rating.__table__ + + class GroupUser(TypedDict): id: str name: str diff --git a/unwind/web.py b/unwind/web.py index b4ba575..294e676 100644 --- a/unwind/web.py +++ b/unwind/web.py @@ -49,12 +49,12 @@ class BearerAuthBackend(AuthenticationBackend): self.admin_tokens = {v: k for k, v in credentials.items()} async def authenticate(self, conn: HTTPConnection): - if "Authorization" not in conn.headers: + if "authorization" not in conn.headers: return # XXX should we remove the auth header after reading, for security reasons? - auth = conn.headers["Authorization"] + auth = conn.headers["authorization"] try: scheme, credentials = auth.split() except ValueError as err: @@ -62,23 +62,24 @@ class BearerAuthBackend(AuthenticationBackend): roles = [] - if scheme.lower() == "bearer": - is_admin = credentials in self.admin_tokens - if not is_admin: + match scheme.lower(): + case "bearer": + is_admin = credentials in self.admin_tokens + if not is_admin: + return + name = self.admin_tokens[credentials] + user = SimpleUser(name) + roles.append("admin") + + case "basic": + try: + name, secret = b64decode(credentials).decode().split(":") + except Exception as err: + raise AuthenticationError("Invalid auth credentials") from err + user = AuthedUser(name, secret) + + case _: return - name = self.admin_tokens[credentials] - user = SimpleUser(name) - roles.append("admin") - - elif scheme.lower() == "basic": - try: - name, secret = b64decode(credentials).decode().split(":") - except Exception as err: - raise AuthenticationError("Invalid auth credentials") from err - user = AuthedUser(name, secret) - - else: - return return AuthCredentials(["authenticated", *roles]), user @@ -366,6 +367,33 @@ async def progress_for_load_imdb_movies(request): return JSONResponse(resp) +@route("/users/{user_id}/watches", methods=["POST"]) +@requires(["authenticated"]) +async def users_watching_start(request): + # { + # id + # movie_id + # location (gps) + # started + # finished + # score + # fav + # } + pass + + +@route("/users/{user_id}/watches/{id}", methods=["PUT"]) +@requires(["authenticated"]) +async def users_watching_done(request): + # { + # ... + # finished + # score + # fav + # } + pass + + _import_lock = asyncio.Lock() From d9fc178d6d6fbed3d23242f67c7e51609f055ea7 Mon Sep 17 00:00:00 2001 From: ducklet Date: Mon, 8 Apr 2024 22:11:30 +0200 Subject: [PATCH 02/25] wip --- scripts/tests-cov-report | 4 ++++ unwind/models.py | 12 ++++++++++++ unwind/web.py | 34 +++++++++++++++++++--------------- 3 files changed, 35 insertions(+), 15 deletions(-) create mode 100755 scripts/tests-cov-report diff --git a/scripts/tests-cov-report b/scripts/tests-cov-report new file mode 100755 index 0000000..9bed8ab --- /dev/null +++ b/scripts/tests-cov-report @@ -0,0 +1,4 @@ +#!/bin/sh -eu + +cd "$RUN_DIR" +exec "$RUN_BIN" tests -x --cov-report html:cov_html diff --git a/unwind/models.py b/unwind/models.py index aae161b..6671a01 100644 --- a/unwind/models.py +++ b/unwind/models.py @@ -463,10 +463,22 @@ ratings = Rating.__table__ # - I can rate something at any time, without having watched it, e.g. in a discussion with a friend I change my opinion on a movie # - I can watch something without having fully formed an opinion yet, i.e. I don't want to rate it yet +# How are Rating.favorite and Rating.finished linked to Watches? +# - is Rating.favorite automatically Watches[-1].favorite, or any(Watches.favorite)? +# - Rating.favorite is nullable, so unless it's explicitly set we can default to Watches +# - is Rating.finished automatically any(Watches.finished)? +# - Rating.finished is nullable, so unless it's explicitly set we can default to Watches +# - can Rating.finished be set without a Watch? +# - yes +# - can Rating.favorite be set without a Watch? +# - yes + @mapper_registry.mapped @dataclass class Watch: + """A "check-in" event, the user started watching a movie.""" + __table__: ClassVar[Table] = Table( "watches", metadata, diff --git a/unwind/web.py b/unwind/web.py index 294e676..5cfeda9 100644 --- a/unwind/web.py +++ b/unwind/web.py @@ -141,7 +141,7 @@ async def json_from_body(request) -> dict: ... async def json_from_body(request, keys: list[str]) -> list: ... -async def json_from_body(request, keys: list[str] | None = None): +async def json_from_body(request, keys: list[str] | None = None) -> dict | list: if not await request.body(): data = {} @@ -151,13 +151,16 @@ async def json_from_body(request, keys: list[str] | None = None): except JSONDecodeError as err: raise HTTPException(422, "Invalid JSON content.") from err + if not isinstance(data, dict): + raise HTTPException(422, f"Unexpected JSON root type: {type(data)!a}.") + if not keys: return data try: return [data[k] for k in keys] except KeyError as err: - raise HTTPException(422, f"Missing data for key: {err.args[0]}") from err + raise HTTPException(422, f"Missing data for key: {err.args[0]!a}") from err def is_admin(request): @@ -367,9 +370,9 @@ async def progress_for_load_imdb_movies(request): return JSONResponse(resp) -@route("/users/{user_id}/watches", methods=["POST"]) +@route("/users/{user_id}/[movies/{movie_id}/]watches", methods=["POST"]) @requires(["authenticated"]) -async def users_watching_start(request): +async def add_watch_to_user(request): # { # id # movie_id @@ -379,19 +382,20 @@ async def users_watching_start(request): # score # fav # } - pass + user_id = as_ulid(request.path_params["user_id"]) + + geoloc, started = await json_from_body(request, ["geoloc", "started"]) -@route("/users/{user_id}/watches/{id}", methods=["PUT"]) +@route("/users/{user_id}/[movies/{movie_id}/]watches/{watch_id}", methods=["PUT"]) @requires(["authenticated"]) -async def users_watching_done(request): - # { - # ... - # finished - # score - # fav - # } - pass +async def update_watch_for_user(request): + user_id = as_ulid(request.path_params["user_id"]) + watch_id = as_ulid(request.path_params["watch_id"]) + + finished, score, favorite = await json_from_body( + request, ["finished", "score", "favorite"] + ) _import_lock = asyncio.Lock() @@ -686,7 +690,7 @@ def create_app(): Mount(f"{config.api_base}v1", routes=_routes), ], middleware=[ - Middleware(ResponseTimeMiddleware, header_name="Unwind-Elapsed"), + Middleware(ResponseTimeMiddleware, header_name="unwind-elapsed"), Middleware( AuthenticationMiddleware, backend=BearerAuthBackend(config.api_credentials), From feb60bf658ba2cb759a1ed74977a43d98494ad27 Mon Sep 17 00:00:00 2001 From: ducklet Date: Sat, 18 May 2024 18:44:27 +0200 Subject: [PATCH 03/25] feat: add Alembic This adds the `ratings_index` to code, which so far wasn't reflected in SQLAlchemy's metadata. --- alembic.ini | 39 +++++++++++++++ alembic/env.py | 103 ++++++++++++++++++++++++++++++++++++++ alembic/script.py.mako | 26 ++++++++++ poetry.lock | 111 ++++++++++++++++++++++++++++++++++++++++- pyproject.toml | 1 + unwind/db.py | 8 +-- unwind/models.py | 3 +- 7 files changed, 285 insertions(+), 6 deletions(-) create mode 100644 alembic.ini create mode 100644 alembic/env.py create mode 100644 alembic/script.py.mako diff --git a/alembic.ini b/alembic.ini new file mode 100644 index 0000000..d8a741e --- /dev/null +++ b/alembic.ini @@ -0,0 +1,39 @@ +[alembic] +script_location = alembic +file_template = %%(epoch)s-%%(rev)s_%%(slug)s +timezone = UTC + +# 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/alembic/env.py b/alembic/env.py new file mode 100644 index 0000000..23056ae --- /dev/null +++ b/alembic/env.py @@ -0,0 +1,103 @@ +import asyncio +from logging.config import fileConfig + +import sqlalchemy as sa +from sqlalchemy import pool +from sqlalchemy.engine import Connection +from sqlalchemy.ext.asyncio import async_engine_from_config + +from alembic import context +from unwind import db, models + +# this is the Alembic Config object, which provides +# access to the values within the .ini file in use. +config = context.config + +# 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) + + +def is_different_type( + context, + inspected_column: sa.Column, + metadata_column: sa.Column, + inspected_type: sa.types.TypeEngine, + metadata_type: sa.types.TypeEngine, +) -> bool | None: + # We used "TEXT" in our manual SQL, which in SQLite is the same as VARCHAR, but + # for SQLAlchemy/Alembic looks different. + equiv_types = [(sa.TEXT, sa.String)] + for types in equiv_types: + if isinstance(inspected_type, types) and isinstance(metadata_type, types): + return False + return None # defer to default compare implementation + + +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. + + """ + context.configure( + url=db._connection_uri(), + target_metadata=models.metadata, + literal_binds=True, + dialect_opts={"paramstyle": "named"}, + compare_type=is_different_type, + render_as_batch=True, + ) + + with context.begin_transaction(): + context.run_migrations() + + +def do_run_migrations(connection: Connection) -> None: + context.configure( + connection=connection, + target_metadata=models.metadata, + compare_type=is_different_type, + render_as_batch=True, + ) + + with context.begin_transaction(): + context.run_migrations() + + +async def run_async_migrations() -> None: + """In this scenario we need to create an Engine + and associate a connection with the context. + + """ + + connectable = async_engine_from_config( + config.get_section(config.config_ini_section, {}), + prefix="sqlalchemy.", + url=db._connection_uri(), + poolclass=pool.NullPool, + ) + + async with connectable.connect() as connection: + await connection.run_sync(do_run_migrations) + + await connectable.dispose() + + +def run_migrations_online_async() -> None: + """Run migrations in 'online' mode.""" + + asyncio.run(run_async_migrations()) + + +if context.is_offline_mode(): + run_migrations_offline() +else: + run_migrations_online_async() diff --git a/alembic/script.py.mako b/alembic/script.py.mako new file mode 100644 index 0000000..f31592a --- /dev/null +++ b/alembic/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 + +from alembic import op +import sqlalchemy as sa +${imports if imports else ""} + +# revision identifiers, used by Alembic. +revision: str = ${repr(up_revision)} +down_revision: str | None = ${repr(down_revision)} +branch_labels: str | Sequence[str] | None = ${repr(branch_labels)} +depends_on: str | Sequence[str] | None = ${repr(depends_on)} + + +def upgrade() -> None: + ${upgrades if upgrades else "pass"} + + +def downgrade() -> None: + ${downgrades if downgrades else "pass"} diff --git a/poetry.lock b/poetry.lock index dc71990..d01be12 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. [[package]] name = "aiosqlite" @@ -18,6 +18,25 @@ typing_extensions = ">=4.0" dev = ["attribution (==1.7.0)", "black (==24.2.0)", "coverage[toml] (==7.4.1)", "flake8 (==7.0.0)", "flake8-bugbear (==24.2.6)", "flit (==3.9.0)", "mypy (==1.8.0)", "ufmt (==2.3.0)", "usort (==1.0.8.post1)"] docs = ["sphinx (==7.2.6)", "sphinx-mdinclude (==0.5.3)"] +[[package]] +name = "alembic" +version = "1.13.1" +description = "A database migration tool for SQLAlchemy." +optional = false +python-versions = ">=3.8" +files = [ + {file = "alembic-1.13.1-py3-none-any.whl", hash = "sha256:2edcc97bed0bd3272611ce3a98d98279e9c209e7186e43e75bbb1b2bdfdbcc43"}, + {file = "alembic-1.13.1.tar.gz", hash = "sha256:4932c8558bf68f2ee92b9bbcb8218671c627064d5b08939437af6d77dc05e595"}, +] + +[package.dependencies] +Mako = "*" +SQLAlchemy = ">=1.3.0" +typing-extensions = ">=4" + +[package.extras] +tz = ["backports.zoneinfo"] + [[package]] name = "anyio" version = "4.3.0" @@ -346,6 +365,94 @@ files = [ {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, ] +[[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 = "nodeenv" version = "1.8.0" @@ -694,4 +801,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "038fed338d6b75c17eb8eb88d36c2411ff936dab23887b70594e5ba1da518451" +content-hash = "9dbc732b312d6d39fbf4e8b8af22739aad6c25312cee92736f19d3a106f93129" diff --git a/pyproject.toml b/pyproject.toml index b230473..134c089 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,6 +18,7 @@ ulid-py = "^1.1.0" uvicorn = "^0.29.0" httpx = "^0.27.0" sqlalchemy = {version = "^2.0", extras = ["aiosqlite"]} +alembic = "^1.13.1" [tool.poetry.group.build.dependencies] # When we run poetry export, typing-extensions is a transient dependency via diff --git a/unwind/db.py b/unwind/db.py index 7759f1b..d94e335 100644 --- a/unwind/db.py +++ b/unwind/db.py @@ -194,11 +194,13 @@ async def set_import_progress(conn: Connection, /, progress: float) -> Progress: return current -def _new_engine() -> AsyncEngine: - uri = f"sqlite+aiosqlite:///{config.storage_path}" +def _connection_uri() -> str: + return f"sqlite+aiosqlite:///{config.storage_path}" + +def _new_engine() -> AsyncEngine: return create_async_engine( - uri, + _connection_uri(), isolation_level="SERIALIZABLE", ) diff --git a/unwind/models.py b/unwind/models.py index 6ea13e9..23b0794 100644 --- a/unwind/models.py +++ b/unwind/models.py @@ -20,7 +20,7 @@ from typing import ( get_origin, ) -from sqlalchemy import Column, ForeignKey, Integer, String, Table +from sqlalchemy import Column, ForeignKey, Index, Integer, String, Table from sqlalchemy.orm import registry from .types import ULID @@ -455,6 +455,7 @@ class Rating: ratings = Rating.__table__ +Index("ratings_index", ratings.c.movie_id, ratings.c.user_id, unique=True) class GroupUser(TypedDict): From 5eb7211b59beb387a406d90d54c47121ccca0ee6 Mon Sep 17 00:00:00 2001 From: ducklet Date: Sat, 18 May 2024 18:51:01 +0200 Subject: [PATCH 04/25] fix: SQL integer column types We used NUMBER[sic!] as column type in our SQL, which does not exist. The way SQLite works this mapped to NUMERIC, which is not what we meant, we really wanted INTEGER here. --- .../1716049471-c08ae04dc482_fix_data_types.py | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 alembic/versions/1716049471-c08ae04dc482_fix_data_types.py diff --git a/alembic/versions/1716049471-c08ae04dc482_fix_data_types.py b/alembic/versions/1716049471-c08ae04dc482_fix_data_types.py new file mode 100644 index 0000000..5a72f3a --- /dev/null +++ b/alembic/versions/1716049471-c08ae04dc482_fix_data_types.py @@ -0,0 +1,69 @@ +"""fix data types + +Revision ID: c08ae04dc482 +Revises: +Create Date: 2024-05-18 16:24:31.152480+00:00 + +""" + +from typing import Sequence + +import sqlalchemy as sa + +from alembic import op + +# revision identifiers, used by Alembic. +revision: str = "c08ae04dc482" +down_revision: str | None = None +branch_labels: str | Sequence[str] | None = None +depends_on: str | Sequence[str] | None = None + + +def upgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table("ratings", schema=None) as batch_op: + batch_op.alter_column( + "score", + existing_type=sa.NUMERIC(), + type_=sa.Integer(), + existing_nullable=False, + ) + batch_op.alter_column( + "favorite", + existing_type=sa.NUMERIC(), + type_=sa.Integer(), + existing_nullable=True, + ) + batch_op.alter_column( + "finished", + existing_type=sa.NUMERIC(), + type_=sa.Integer(), + existing_nullable=True, + ) + + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table("ratings", schema=None) as batch_op: + batch_op.alter_column( + "finished", + existing_type=sa.Integer(), + type_=sa.NUMERIC(), + existing_nullable=True, + ) + batch_op.alter_column( + "favorite", + existing_type=sa.Integer(), + type_=sa.NUMERIC(), + existing_nullable=True, + ) + batch_op.alter_column( + "score", + existing_type=sa.Integer(), + type_=sa.NUMERIC(), + existing_nullable=False, + ) + + # ### end Alembic commands ### From f102e072567f79d1be6ecdf9516e25c457604e0d Mon Sep 17 00:00:00 2001 From: ducklet Date: Sat, 18 May 2024 23:32:10 +0200 Subject: [PATCH 05/25] feat: add a table to store award information --- ...716050110-62882ef5e3ff_add_awards_table.py | 44 ++++++++++ unwind/models.py | 88 ++++++++++++++++--- 2 files changed, 120 insertions(+), 12 deletions(-) create mode 100644 alembic/versions/1716050110-62882ef5e3ff_add_awards_table.py diff --git a/alembic/versions/1716050110-62882ef5e3ff_add_awards_table.py b/alembic/versions/1716050110-62882ef5e3ff_add_awards_table.py new file mode 100644 index 0000000..b66cee0 --- /dev/null +++ b/alembic/versions/1716050110-62882ef5e3ff_add_awards_table.py @@ -0,0 +1,44 @@ +"""add awards table + +Revision ID: 62882ef5e3ff +Revises: c08ae04dc482 +Create Date: 2024-05-18 16:35:10.145964+00:00 + +""" + +from typing import Sequence + +import sqlalchemy as sa + +from alembic import op + +# revision identifiers, used by Alembic. +revision: str = "62882ef5e3ff" +down_revision: str | None = "c08ae04dc482" +branch_labels: str | Sequence[str] | None = None +depends_on: str | Sequence[str] | None = None + + +def upgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.create_table( + "awards", + sa.Column("id", sa.String(), nullable=False), + sa.Column("movie_id", sa.String(), nullable=False), + sa.Column("category", sa.String(), nullable=False), + sa.Column("details", sa.String(), nullable=False), + sa.Column("created", sa.String(), nullable=False), + sa.Column("updated", sa.String(), nullable=False), + sa.ForeignKeyConstraint( + ["movie_id"], + ["movies.id"], + ), + sa.PrimaryKeyConstraint("id"), + ) + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.drop_table("awards") + # ### end Alembic commands ### diff --git a/unwind/models.py b/unwind/models.py index 23b0794..594635c 100644 --- a/unwind/models.py +++ b/unwind/models.py @@ -13,6 +13,8 @@ from typing import ( Mapping, Protocol, Type, + TypeAlias, + TypeAliasType, TypedDict, TypeVar, Union, @@ -25,8 +27,9 @@ from sqlalchemy.orm import registry from .types import ULID -JSON = int | float | str | None | list["JSON"] | dict[str, "JSON"] -JSONObject = dict[str, JSON] +JSONScalar: TypeAlias = int | float | str | None +type JSON = JSONScalar | list["JSON"] | dict[str, "JSON"] +type JSONObject = dict[str, JSON] T = TypeVar("T") @@ -126,6 +129,10 @@ def asplain( continue target: Any = f.type + if isinstance(target, TypeAliasType): + # Support type aliases. + target = target.__value__ + # XXX this doesn't properly support any kind of nested types if (otype := optional_type(f.type)) is not None: target = otype @@ -150,10 +157,13 @@ def asplain( elif target in {bool, str, int, float}: assert isinstance( v, target - ), f"Type mismatch: {f.name} ({target} != {type(v)})" + ), f"Type mismatch: {f.name!a} ({target!a} != {type(v)!a})" + d[f.name] = v + elif target in {Literal}: + assert isinstance(v, JSONScalar) d[f.name] = v else: - raise ValueError(f"Unsupported value type: {f.name}: {type(v)}") + raise ValueError(f"Unsupported value type: {f.name!a}: {type(v)!a}") return d @@ -196,18 +206,24 @@ def fromplain(cls: Type[T], d: Mapping, *, serialized: bool = False) -> T: def validate(o: object) -> None: for f in fields(o): - vtype = type(getattr(o, f.name)) - if vtype is f.type: + ftype = f.type + if isinstance(ftype, TypeAliasType): + # Support type aliases. + ftype = ftype.__value__ + + v = getattr(o, f.name) + vtype = type(v) + if vtype is ftype: continue - origin = get_origin(f.type) + origin = get_origin(ftype) if origin is vtype: continue - is_union = isinstance(f.type, UnionType) or origin is Union + is_union = isinstance(ftype, UnionType) or origin is Union if is_union: # Support unioned types. - utypes = get_args(f.type) + utypes = get_args(ftype) if vtype in utypes: continue @@ -216,7 +232,14 @@ def validate(o: object) -> None: if any(vtype is gtype for gtype in gtypes): continue - raise ValueError(f"Invalid value type: {f.name}: {vtype}") + if origin is Literal: + # Support literal types. + vals = get_args(ftype) + if v in vals: + continue + raise ValueError(f"Invalid value: {f.name!a}: {v!a}") + + raise ValueError(f"Invalid value type: {f.name!a}: {vtype!a}") def utcnow() -> datetime: @@ -365,10 +388,10 @@ dataclass containing the ID of the linked data. The contents of the Relation are ignored or discarded when using `asplain`, `fromplain`, and `validate`. """ -Relation = Annotated[T | None, _RelationSentinel] +Relation: TypeAlias = Annotated[T | None, _RelationSentinel] -Access = Literal[ +type Access = Literal[ "r", # read "i", # index "w", # write @@ -413,6 +436,9 @@ class User: self.groups.append({"id": group_id, "access": access}) +users = User.__table__ + + @mapper_registry.mapped @dataclass class Rating: @@ -477,3 +503,41 @@ class Group: id: ULID = field(default_factory=ULID) name: str = None users: list[GroupUser] = field(default_factory=list) + + +type AwardCategory = Literal[ + "imdb-top-250", "imdb-bottom-100", "imdb-pop-100", "oscars" +] + + +@mapper_registry.mapped +@dataclass +class Award: + __table__: ClassVar[Table] = Table( + "awards", + metadata, + Column("id", String, primary_key=True), # ULID + Column("movie_id", ForeignKey("movies.id"), nullable=False), # ULID + Column( + "category", String, nullable=False + ), # Enum: "imdb-top-250", "imdb-bottom-100", "imdb-pop-100", "oscars", ... + Column( + "details", String, nullable=False + ), # e.g. "23" (position in list), "2024, nominee, best director", "1977, winner, best picture", ... + Column("created", String, nullable=False), # datetime + Column("updated", String, nullable=False), # datetime + ) + + id: ULID = field(default_factory=ULID) + + movie_id: ULID = None + movie: Relation[Movie] = None + + category: AwardCategory = None + details: str = None + + created: datetime = field(default_factory=utcnow) + updated: datetime = field(default_factory=utcnow) + + +awards = Award.__table__ From 0747ca5658f02e410aa3145a0db6c2c9fe1a4cb8 Mon Sep 17 00:00:00 2001 From: ducklet Date: Sat, 18 May 2024 23:35:07 +0200 Subject: [PATCH 06/25] fix: always use named constraints in SQLAlchemy --- ...1987-f17c7ca9afa4_use_named_constraints.py | 41 +++++++++++++++++++ unwind/models.py | 10 +++++ 2 files changed, 51 insertions(+) create mode 100644 alembic/versions/1716051987-f17c7ca9afa4_use_named_constraints.py diff --git a/alembic/versions/1716051987-f17c7ca9afa4_use_named_constraints.py b/alembic/versions/1716051987-f17c7ca9afa4_use_named_constraints.py new file mode 100644 index 0000000..be21664 --- /dev/null +++ b/alembic/versions/1716051987-f17c7ca9afa4_use_named_constraints.py @@ -0,0 +1,41 @@ +"""use named constraints + +See https://alembic.sqlalchemy.org/en/latest/naming.html + +Revision ID: f17c7ca9afa4 +Revises: 62882ef5e3ff +Create Date: 2024-05-18 17:06:27.696713+00:00 + +""" + +from typing import Sequence + +from alembic import op + +# revision identifiers, used by Alembic. +revision: str = "f17c7ca9afa4" +down_revision: str | None = "62882ef5e3ff" +branch_labels: str | Sequence[str] | None = None +depends_on: str | Sequence[str] | None = None + + +def upgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table("movies") as batch_op: + batch_op.create_unique_constraint(batch_op.f("uq_movies_imdb_id"), ["imdb_id"]) + + with op.batch_alter_table("users", schema=None) as batch_op: + batch_op.create_unique_constraint(batch_op.f("uq_users_imdb_id"), ["imdb_id"]) + + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table("users", schema=None) as batch_op: + batch_op.drop_constraint(batch_op.f("uq_users_imdb_id"), type_="unique") + + with op.batch_alter_table("movies", schema=None) as batch_op: + batch_op.drop_constraint(batch_op.f("uq_movies_imdb_id"), type_="unique") + + # ### end Alembic commands ### diff --git a/unwind/models.py b/unwind/models.py index 594635c..4867599 100644 --- a/unwind/models.py +++ b/unwind/models.py @@ -41,6 +41,16 @@ class Model(Protocol): mapper_registry = registry() metadata = mapper_registry.metadata +# An explicit naming convention helps Alembic do its job, +# see https://alembic.sqlalchemy.org/en/latest/naming.html. +metadata.naming_convention = { + "ix": "ix_%(column_0_label)s", + "uq": "uq_%(table_name)s_%(column_0_name)s", + "ck": "ck_%(table_name)s_%(constraint_name)s", + "fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s", + "pk": "pk_%(table_name)s", +} + def annotations(tp: Type) -> tuple | None: return tp.__metadata__ if hasattr(tp, "__metadata__") else None # type: ignore From 1789b2ce453f8d4308a904930ba114ef8294e1c6 Mon Sep 17 00:00:00 2001 From: ducklet Date: Sat, 18 May 2024 23:38:33 +0200 Subject: [PATCH 07/25] fix: encode query params for GQL request --- unwind/imdb.py | 25 ++++++++++++++++--------- unwind/models.py | 6 ++---- unwind/utils.py | 4 ++++ 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/unwind/imdb.py b/unwind/imdb.py index cff1d68..0f46c24 100644 --- a/unwind/imdb.py +++ b/unwind/imdb.py @@ -12,6 +12,7 @@ import bs4 from . import db from .models import Movie, Rating, User from .request import adownload, asession, asoup_from_url, cache_path +from .utils import json_dump log = logging.getLogger(__name__) @@ -355,9 +356,12 @@ async def _load_ratings_page_legacy(url: str, soup: bs4.BeautifulSoup) -> _Ratin return page -async def load_and_store_ratings( - user_id: UserId, -) -> AsyncIterable[tuple[Rating, bool]]: +async def load_and_store_ratings(user_id: UserId) -> AsyncIterable[tuple[Rating, bool]]: + """Load user ratings from imdb.com and store them in our database. + + All loaded ratings are yielded together with the information whether each rating + was already present in our database. + """ async with db.new_connection() as conn: user = await db.get(conn, User, imdb_id=user_id) or User( imdb_id=user_id, name="", secret="" @@ -385,6 +389,7 @@ async def load_and_store_ratings( async def load_ratings(user_id: UserId) -> AsyncIterable[Rating]: + """Return all ratings for the given user from imdb.com.""" next_url = user_ratings_url(user_id) while next_url: @@ -443,13 +448,15 @@ async def load_top_250() -> list[MovieId]: qgl_api_url = "https://caching.graphql.imdb.com/" query = { "operationName": "Top250MoviesPagination", - "variables": {"first": 250, "locale": "en-US"}, - "extensions": { - "persistedQuery": { - "sha256Hash": "26114ee01d97e04f65d6c8c7212ae8b7888fa57ceed105450d1fce09df749b2d", - "version": 1, + "variables": json_dump({"first": 250, "locale": "en-US"}), + "extensions": json_dump( + { + "persistedQuery": { + "sha256Hash": "26114ee01d97e04f65d6c8c7212ae8b7888fa57ceed105450d1fce09df749b2d", + "version": 1, + } } - }, + ), } headers = { "accept": "application/graphql+json, application/json", diff --git a/unwind/models.py b/unwind/models.py index 4867599..a2ffffb 100644 --- a/unwind/models.py +++ b/unwind/models.py @@ -2,7 +2,6 @@ import json from dataclasses import dataclass, field from dataclasses import fields as _fields from datetime import datetime, timezone -from functools import partial from types import UnionType from typing import ( Annotated, @@ -26,6 +25,7 @@ from sqlalchemy import Column, ForeignKey, Index, Integer, String, Table from sqlalchemy.orm import registry from .types import ULID +from .utils import json_dump JSONScalar: TypeAlias = int | float | str | None type JSON = JSONScalar | list["JSON"] | dict[str, "JSON"] @@ -110,10 +110,8 @@ def optional_fields(o): yield f -json_dump = partial(json.dumps, separators=(",", ":")) - - def _id(x: T) -> T: + """Return the given argument, aka. the identity function.""" return x diff --git a/unwind/utils.py b/unwind/utils.py index 6ad4d32..d1733a8 100644 --- a/unwind/utils.py +++ b/unwind/utils.py @@ -1,8 +1,12 @@ import base64 import hashlib +import json import secrets +from functools import partial from typing import Any, TypedDict +json_dump = partial(json.dumps, separators=(",", ":")) + def b64encode(b: bytes) -> str: return base64.b64encode(b).decode().rstrip("=") From f7fc84c050357cdd49df9f58ce6925590a933b50 Mon Sep 17 00:00:00 2001 From: ducklet Date: Sat, 18 May 2024 23:46:56 +0200 Subject: [PATCH 08/25] feat: add CLI command to load IMDb charts This introduces a generalized module interface for CLI commands. --- unwind/__main__.py | 24 ++++++--- unwind/cli/__init__.py | 39 ++++++++++++++ unwind/cli/load_imdb_charts.py | 97 ++++++++++++++++++++++++++++++++++ unwind/db.py | 7 +++ 4 files changed, 160 insertions(+), 7 deletions(-) create mode 100644 unwind/cli/__init__.py create mode 100644 unwind/cli/load_imdb_charts.py diff --git a/unwind/__main__.py b/unwind/__main__.py index 82abfee..8ca995f 100644 --- a/unwind/__main__.py +++ b/unwind/__main__.py @@ -2,10 +2,11 @@ import argparse import asyncio import logging import secrets +import sys from base64 import b64encode from pathlib import Path -from . import config, db, models, utils +from . import cli, config, db, models, utils from .db import close_connection_pool, open_connection_pool from .imdb import refresh_user_ratings_from_imdb from .imdb_import import download_datasets, import_from_file @@ -70,8 +71,8 @@ async def run_download_imdb_dataset(basics_path: Path, ratings_path: Path): def getargs(): - parser = argparse.ArgumentParser() - commands = parser.add_subparsers(required=True) + parser = argparse.ArgumentParser(prog="unwind", allow_abbrev=False) + commands = parser.add_subparsers(title="commands", metavar="COMMAND", dest="mode") parser_import_imdb_dataset = commands.add_parser( "import-imdb-dataset", @@ -145,12 +146,20 @@ def getargs(): help="Allow overwriting an existing user. WARNING: This will reset the user's password!", ) + for module in cli.modules: + cmd = commands.add_parser(module.name, help=module.help, allow_abbrev=False) + module.add_args(cmd) + try: args = parser.parse_args() except TypeError: parser.print_usage() raise + if args.mode is None: + parser.print_help() + sys.exit(1) + return args @@ -162,10 +171,7 @@ def main(): ) log.debug(f"Log level: {config.loglevel}") - try: - args = getargs() - except Exception: - return + args = getargs() if args.mode == "load-user-ratings-from-imdb": asyncio.run(run_load_user_ratings_from_imdb()) @@ -176,5 +182,9 @@ def main(): elif args.mode == "download-imdb-dataset": asyncio.run(run_download_imdb_dataset(args.basics, args.ratings)) + modes = {m.name: m.main for m in cli.modules} + if handler := modes.get(args.mode): + asyncio.run(handler(args)) + main() diff --git a/unwind/cli/__init__.py b/unwind/cli/__init__.py new file mode 100644 index 0000000..dd6f8cc --- /dev/null +++ b/unwind/cli/__init__.py @@ -0,0 +1,39 @@ +import argparse +import importlib +from pathlib import Path +from types import ModuleType +from typing import Any, Callable, Coroutine, Iterable, Protocol, TypeGuard + +type CommandHandler = Callable[[argparse.Namespace], Coroutine[Any, Any, None]] + + +class CliModule(Protocol): + name: str + help: str + add_args: Callable[[argparse.ArgumentParser], None] + main: CommandHandler + + +def _is_cli_module(m: ModuleType) -> TypeGuard[CliModule]: + return ( + hasattr(m, "name") + and hasattr(m, "help") + and hasattr(m, "add_args") + and hasattr(m, "main") + ) + + +_clidir = Path(__file__).parent + + +def _load_cmds() -> Iterable[CliModule]: + """Return all CLI command modules.""" + for f in _clidir.iterdir(): + if f.suffix == ".py" and not f.name.startswith("__"): + m = importlib.import_module(f"{__package__}.{f.stem}") + if not _is_cli_module(m): + raise ValueError(f"Invalid CLI module: {m!a}") + yield m + + +modules = sorted(_load_cmds(), key=lambda m: m.name) diff --git a/unwind/cli/load_imdb_charts.py b/unwind/cli/load_imdb_charts.py new file mode 100644 index 0000000..2b82774 --- /dev/null +++ b/unwind/cli/load_imdb_charts.py @@ -0,0 +1,97 @@ +import argparse +import logging +from typing import Callable + +import sqlalchemy as sa + +from unwind import db, imdb, models, types, utils + +log = logging.getLogger(__name__) + +name = "load-imdb-charts" +help = "Load and import charts from imdb.com." + + +def add_args(cmd: argparse.ArgumentParser) -> None: + cmd.add_argument( + "--select", + action="append", + dest="charts", + default=[], + choices={"top250", "bottom100", "pop100"}, + help="Select which charts to refresh.", + ) + + +async def get_movie_ids( + conn: db.Connection, imdb_ids: list[imdb.MovieId] +) -> dict[imdb.MovieId, types.ULID]: + c = models.movies.c + query = sa.select(c.imdb_id, c.id).where(c.imdb_id.in_(imdb_ids)) + rows = await db.fetch_all(conn, query) + return {row.imdb_id: types.ULID(row.id) for row in rows} + + +async def remove_all_awards( + conn: db.Connection, category: models.AwardCategory +) -> None: + stmt = models.awards.delete().where(models.awards.c.category == category) + await conn.execute(stmt) + + +_award_handlers: dict[models.AwardCategory, Callable] = { + "imdb-pop-100": imdb.load_most_popular_100, + "imdb-top-250": imdb.load_top_250, + "imdb-bottom-100": imdb.load_bottom_100, +} + + +async def update_awards(conn: db.Connection, category: models.AwardCategory) -> None: + load_imdb_ids = _award_handlers[category] + imdb_ids = await load_imdb_ids() + + available = await get_movie_ids(conn, imdb_ids) + if missing := set(imdb_ids).difference(available): + log.warning( + "⚠️ Charts for category (%a) contained %i unknown movies: %a", + category, + len(missing), + missing, + ) + + await remove_all_awards(conn, category=category) + + for pos, imdb_id in enumerate(imdb_ids, 1): + if (movie_id := available.get(imdb_id)) is None: + continue + + award = models.Award( + movie_id=movie_id, + category=category, + details=utils.json_dump({"position": pos}), + ) + await db.add(conn, award) + + +async def main(args: argparse.Namespace) -> None: + await db.open_connection_pool() + + if not args.charts: + args.charts = {"top250", "bottom100", "pop100"} + + if "pop100" in args.charts: + async with db.transaction() as conn: + await update_awards(conn, "imdb-pop-100") + log.info("✨ Updated most popular 100 movies.") + + if "bottom100" in args.charts: + async with db.transaction() as conn: + await update_awards(conn, "imdb-bottom-100") + log.info("✨ Updated bottom 100 movies.") + + if "top250" in args.charts: + async with db.transaction() as conn: + await update_awards(conn, "imdb-top-250") + log.info("✨ Updated top 250 rated movies.") + + await db.close_connection_pool() diff --git a/unwind/db.py b/unwind/db.py index d94e335..b609c59 100644 --- a/unwind/db.py +++ b/unwind/db.py @@ -259,6 +259,13 @@ async def new_connection() -> AsyncGenerator[Connection, None]: async def transacted( conn: Connection, /, *, force_rollback: bool = False ) -> AsyncGenerator[None, None]: + """Start a transaction for the given connection. + + If `force_rollback` is `True` any changes will be rolled back at the end of the + transaction, unless they are explicitly committed. + Nesting transactions is allowed, but mixing values for `force_rollback` will likely + yield unexpected results. + """ transaction = contextlib.nullcontext() if conn.in_transaction() else conn.begin() async with transaction: From 22c44bfa6026146b2a20b21911ad46f625941c4e Mon Sep 17 00:00:00 2001 From: ducklet Date: Sun, 19 May 2024 00:12:06 +0200 Subject: [PATCH 09/25] chore: move existing CLI commands into separate files --- unwind/__main__.py | 153 ++-------------------- unwind/cli/add_user.py | 56 ++++++++ unwind/cli/download_imdb_dataset.py | 24 ++++ unwind/cli/import_imdb_dataset.py | 31 +++++ unwind/cli/load_user_ratings_from_imdb.py | 28 ++++ 5 files changed, 147 insertions(+), 145 deletions(-) create mode 100644 unwind/cli/add_user.py create mode 100644 unwind/cli/download_imdb_dataset.py create mode 100644 unwind/cli/import_imdb_dataset.py create mode 100644 unwind/cli/load_user_ratings_from_imdb.py diff --git a/unwind/__main__.py b/unwind/__main__.py index 8ca995f..0d5bde6 100644 --- a/unwind/__main__.py +++ b/unwind/__main__.py @@ -1,153 +1,25 @@ import argparse import asyncio import logging -import secrets import sys -from base64 import b64encode -from pathlib import Path -from . import cli, config, db, models, utils -from .db import close_connection_pool, open_connection_pool -from .imdb import refresh_user_ratings_from_imdb -from .imdb_import import download_datasets, import_from_file +from . import cli, config log = logging.getLogger(__name__) -async def run_add_user(user_id: str, name: str, overwrite_existing: bool): - if not user_id.startswith("ur"): - raise ValueError(f"Invalid IMDb user ID: {user_id!a}") - - await open_connection_pool() - - async with db.new_connection() as conn: - user = await db.get(conn, models.User, imdb_id=user_id) - - if user is not None: - if overwrite_existing: - log.warning("⚠️ Overwriting existing user: %a", user) - else: - log.error("❌ User already exists: %a", user) - return - - secret = secrets.token_bytes() - - user = models.User(name=name, imdb_id=user_id, secret=utils.phc_scrypt(secret)) - async with db.transaction() as conn: - await db.add_or_update_user(conn, user) - - user_data = { - "secret": b64encode(secret), - "user": models.asplain(user), - } - - log.info("✨ User created: %a", user_data) - - await close_connection_pool() - - -async def run_load_user_ratings_from_imdb(): - await open_connection_pool() - - i = 0 - async for _ in refresh_user_ratings_from_imdb(): - i += 1 - - log.info("✨ Imported %s new ratings.", i) - - await close_connection_pool() - - -async def run_import_imdb_dataset(basics_path: Path, ratings_path: Path): - await open_connection_pool() - - await import_from_file(basics_path=basics_path, ratings_path=ratings_path) - - await close_connection_pool() - - -async def run_download_imdb_dataset(basics_path: Path, ratings_path: Path): - await download_datasets(basics_path=basics_path, ratings_path=ratings_path) - - def getargs(): parser = argparse.ArgumentParser(prog="unwind", allow_abbrev=False) commands = parser.add_subparsers(title="commands", metavar="COMMAND", dest="mode") - parser_import_imdb_dataset = commands.add_parser( - "import-imdb-dataset", - help="Import IMDb datasets.", - description=""" - Import IMDb datasets. - New datasets available from https://www.imdb.com/interfaces/. - """, - ) - parser_import_imdb_dataset.add_argument( - dest="mode", - action="store_const", - const="import-imdb-dataset", - ) - parser_import_imdb_dataset.add_argument( - "--basics", metavar="basics_file.tsv.gz", type=Path, required=True - ) - parser_import_imdb_dataset.add_argument( - "--ratings", metavar="ratings_file.tsv.gz", type=Path, required=True - ) - - parser_download_imdb_dataset = commands.add_parser( - "download-imdb-dataset", - help="Download IMDb datasets.", - description=""" - Download IMDb datasets. - """, - ) - parser_download_imdb_dataset.add_argument( - dest="mode", - action="store_const", - const="download-imdb-dataset", - ) - parser_download_imdb_dataset.add_argument( - "--basics", metavar="basics_file.tsv.gz", type=Path, required=True - ) - parser_download_imdb_dataset.add_argument( - "--ratings", metavar="ratings_file.tsv.gz", type=Path, required=True - ) - - parser_load_user_ratings_from_imdb = commands.add_parser( - "load-user-ratings-from-imdb", - help="Load user ratings from imdb.com.", - description=""" - Refresh user ratings for all registered users live from IMDb's website. - """, - ) - parser_load_user_ratings_from_imdb.add_argument( - dest="mode", - action="store_const", - const="load-user-ratings-from-imdb", - ) - - parser_add_user = commands.add_parser( - "add-user", - help="Add a new user.", - description=""" - Add a new user. - """, - ) - parser_add_user.add_argument( - dest="mode", - action="store_const", - const="add-user", - ) - parser_add_user.add_argument("--name", required=True) - parser_add_user.add_argument("--imdb-id", required=True) - parser_add_user.add_argument( - "--overwrite-existing", - action="store_true", - help="Allow overwriting an existing user. WARNING: This will reset the user's password!", - ) - for module in cli.modules: - cmd = commands.add_parser(module.name, help=module.help, allow_abbrev=False) + help_, *descr = module.help.splitlines() + cmd = commands.add_parser( + module.name, + help=help_, + description="\n".join(descr) or help_, + allow_abbrev=False, + ) module.add_args(cmd) try: @@ -173,15 +45,6 @@ def main(): args = getargs() - if args.mode == "load-user-ratings-from-imdb": - asyncio.run(run_load_user_ratings_from_imdb()) - elif args.mode == "add-user": - asyncio.run(run_add_user(args.imdb_id, args.name, args.overwrite_existing)) - elif args.mode == "import-imdb-dataset": - asyncio.run(run_import_imdb_dataset(args.basics, args.ratings)) - elif args.mode == "download-imdb-dataset": - asyncio.run(run_download_imdb_dataset(args.basics, args.ratings)) - modes = {m.name: m.main for m in cli.modules} if handler := modes.get(args.mode): asyncio.run(handler(args)) diff --git a/unwind/cli/add_user.py b/unwind/cli/add_user.py new file mode 100644 index 0000000..cc3d305 --- /dev/null +++ b/unwind/cli/add_user.py @@ -0,0 +1,56 @@ +import argparse +import logging +import secrets + +from unwind import db, models, utils + +log = logging.getLogger(__name__) + +name = "add-user" +help = "Add a new user." + + +def add_args(cmd: argparse.ArgumentParser) -> None: + cmd.add_argument("--name", required=True) + cmd.add_argument("--imdb-id", required=True) + cmd.add_argument( + "--overwrite-existing", + action="store_true", + help="Allow overwriting an existing user. WARNING: This will reset the user's password!", + ) + + +async def main(args: argparse.Namespace) -> None: + user_id: str = args.imdb_id + name: str = args.name + overwrite_existing: bool = args.overwrite_existing + + if not user_id.startswith("ur"): + raise ValueError(f"Invalid IMDb user ID: {user_id!a}") + + await db.open_connection_pool() + + async with db.new_connection() as conn: + user = await db.get(conn, models.User, imdb_id=user_id) + + if user is not None: + if overwrite_existing: + log.warning("⚠️ Overwriting existing user: %a", user) + else: + log.error("❌ User already exists: %a", user) + return + + secret = secrets.token_bytes() + + user = models.User(name=name, imdb_id=user_id, secret=utils.phc_scrypt(secret)) + async with db.transaction() as conn: + await db.add_or_update_user(conn, user) + + user_data = { + "secret": utils.b64encode(secret), + "user": models.asplain(user), + } + + log.info("✨ User created: %a", user_data) + + await db.close_connection_pool() diff --git a/unwind/cli/download_imdb_dataset.py b/unwind/cli/download_imdb_dataset.py new file mode 100644 index 0000000..5b81045 --- /dev/null +++ b/unwind/cli/download_imdb_dataset.py @@ -0,0 +1,24 @@ +import argparse +import logging +from pathlib import Path + +from unwind.imdb_import import download_datasets + +log = logging.getLogger(__name__) + +name = "download-imdb-dataset" +help = "Download IMDb datasets." + + +def add_args(cmd: argparse.ArgumentParser) -> None: + cmd.add_argument("--basics", metavar="basics_file.tsv.gz", type=Path, required=True) + cmd.add_argument( + "--ratings", metavar="ratings_file.tsv.gz", type=Path, required=True + ) + + +async def main(args: argparse.Namespace) -> None: + basics_path: Path = args.basics + ratings_path: Path = args.ratings + + await download_datasets(basics_path=basics_path, ratings_path=ratings_path) diff --git a/unwind/cli/import_imdb_dataset.py b/unwind/cli/import_imdb_dataset.py new file mode 100644 index 0000000..3adb5da --- /dev/null +++ b/unwind/cli/import_imdb_dataset.py @@ -0,0 +1,31 @@ +import argparse +import logging +from pathlib import Path + +from unwind import db +from unwind.imdb_import import import_from_file + +log = logging.getLogger(__name__) + +name = "import-imdb-dataset" +help = """Import IMDb datasets. +New datasets available from https://www.imdb.com/interfaces/. +""" + + +def add_args(cmd: argparse.ArgumentParser) -> None: + cmd.add_argument("--basics", metavar="basics_file.tsv.gz", type=Path, required=True) + cmd.add_argument( + "--ratings", metavar="ratings_file.tsv.gz", type=Path, required=True + ) + + +async def main(args: argparse.Namespace) -> None: + basics_path: Path = args.basics + ratings_path: Path = args.ratings + + await db.open_connection_pool() + + await import_from_file(basics_path=basics_path, ratings_path=ratings_path) + + await db.close_connection_pool() diff --git a/unwind/cli/load_user_ratings_from_imdb.py b/unwind/cli/load_user_ratings_from_imdb.py new file mode 100644 index 0000000..b4a8e0f --- /dev/null +++ b/unwind/cli/load_user_ratings_from_imdb.py @@ -0,0 +1,28 @@ +import argparse +import logging + +from unwind import db +from unwind.imdb import refresh_user_ratings_from_imdb + +log = logging.getLogger(__name__) + +name = "load-user-ratings-from-imdb" +help = """Load user ratings from imdb.com. +Refresh user ratings for all registered users live from IMDb's website. +""" + + +def add_args(cmd: argparse.ArgumentParser) -> None: + pass + + +async def main(args: argparse.Namespace) -> None: + await db.open_connection_pool() + + i = 0 + async for _ in refresh_user_ratings_from_imdb(): + i += 1 + + log.info("✨ Imported %s new ratings.", i) + + await db.close_connection_pool() From 5e4e70c9dc3fd5f26def81aa1108d1aa49eb98a0 Mon Sep 17 00:00:00 2001 From: ducklet Date: Sun, 19 May 2024 00:15:30 +0200 Subject: [PATCH 10/25] fix: setting the log level should only affect Unwind itself Calling Unwind with DEBUG=1 caused a lot of debug messages from dependencies like HTTPX, aiosqlite, etc. --- unwind/__main__.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/unwind/__main__.py b/unwind/__main__.py index 0d5bde6..a193d8e 100644 --- a/unwind/__main__.py +++ b/unwind/__main__.py @@ -5,7 +5,7 @@ import sys from . import cli, config -log = logging.getLogger(__name__) +log = logging.getLogger(__package__) def getargs(): @@ -39,8 +39,9 @@ def main(): logging.basicConfig( format="%(asctime)s.%(msecs)03d [%(name)s:%(process)d] %(levelname)s: %(message)s", datefmt="%H:%M:%S", - level=config.loglevel, + # level=config.loglevel, ) + log.setLevel(config.loglevel) log.debug(f"Log level: {config.loglevel}") args = getargs() From 1ea09c1a4509ec0fa97804986e47eaaa3d1e19a9 Mon Sep 17 00:00:00 2001 From: ducklet Date: Sun, 19 May 2024 02:25:36 +0200 Subject: [PATCH 11/25] feat: use Alembic to initialize the database This completely removes the previous DB patching mechanism. When this is first run for an existing installation of Unwind, depending on its version it might lead to problems because the database's schema won't match the code. To avoid that issue, when upgrading Unwind to this version make sure to STOP the old application, install this new version but DON'T start it, instead use `alembic upgrade head` to run the outstanding patches, and only then start the application. --- alembic/env.py | 13 ++- ...66-8b06e4916840_remove_db_patches_table.py | 38 ++++++++ tests/test_db.py | 8 -- unwind/db.py | 91 +++++-------------- unwind/models.py | 17 ---- unwind/sql/00000000-init-0.sql | 36 -------- unwind/sql/00000000-init-1.sql | 40 -------- unwind/sql/00000000-init-2.sql | 46 ---------- unwind/sql/00000000-init-3.sql | 62 ------------- unwind/sql/00000000-init-4.sql | 37 -------- unwind/sql/00000001-fix-db.sql.disabled | 2 - unwind/sql/20210705-224139.sql | 8 -- .../sql/20210711-172808--progress-table.sql | 7 -- unwind/sql/20210720-213416.sql | 36 -------- unwind/sql/20210720-223416.sql | 24 ----- unwind/sql/20210721-213417.sql | 38 -------- unwind/sql/20210728-223416.sql | 24 ----- .../sql/20210801-201151--add-user-secret.sql | 22 ----- .../sql/20210802-212312--add-group-admins.sql | 45 --------- ...20240511-001949--remove-genres-notnull.sql | 38 -------- 20 files changed, 72 insertions(+), 560 deletions(-) create mode 100644 alembic/versions/1716077466-8b06e4916840_remove_db_patches_table.py delete mode 100644 unwind/sql/00000000-init-0.sql delete mode 100644 unwind/sql/00000000-init-1.sql delete mode 100644 unwind/sql/00000000-init-2.sql delete mode 100644 unwind/sql/00000000-init-3.sql delete mode 100644 unwind/sql/00000000-init-4.sql delete mode 100644 unwind/sql/00000001-fix-db.sql.disabled delete mode 100644 unwind/sql/20210705-224139.sql delete mode 100644 unwind/sql/20210711-172808--progress-table.sql delete mode 100644 unwind/sql/20210720-213416.sql delete mode 100644 unwind/sql/20210720-223416.sql delete mode 100644 unwind/sql/20210721-213417.sql delete mode 100644 unwind/sql/20210728-223416.sql delete mode 100644 unwind/sql/20210801-201151--add-user-secret.sql delete mode 100644 unwind/sql/20210802-212312--add-group-admins.sql delete mode 100644 unwind/sql/20240511-001949--remove-genres-notnull.sql diff --git a/alembic/env.py b/alembic/env.py index 23056ae..b3ea427 100644 --- a/alembic/env.py +++ b/alembic/env.py @@ -91,13 +91,18 @@ async def run_async_migrations() -> None: await connectable.dispose() -def run_migrations_online_async() -> None: +def run_migrations_online() -> None: """Run migrations in 'online' mode.""" - - asyncio.run(run_async_migrations()) + # Support having a (sync) connection passed in from another script. + if (conn := config.attributes.get("connection")) and isinstance( + conn, sa.Connection + ): + do_run_migrations(conn) + else: + asyncio.run(run_async_migrations()) if context.is_offline_mode(): run_migrations_offline() else: - run_migrations_online_async() + run_migrations_online() diff --git a/alembic/versions/1716077466-8b06e4916840_remove_db_patches_table.py b/alembic/versions/1716077466-8b06e4916840_remove_db_patches_table.py new file mode 100644 index 0000000..840cb33 --- /dev/null +++ b/alembic/versions/1716077466-8b06e4916840_remove_db_patches_table.py @@ -0,0 +1,38 @@ +"""remove db_patches table + +We replace our old patch process with Alembic's. + +Revision ID: 8b06e4916840 +Revises: f17c7ca9afa4 +Create Date: 2024-05-19 00:11:06.730421+00:00 + +""" + +from typing import Sequence + +import sqlalchemy as sa + +from alembic import op + +# revision identifiers, used by Alembic. +revision: str = "8b06e4916840" +down_revision: str | None = "f17c7ca9afa4" +branch_labels: str | Sequence[str] | None = None +depends_on: str | Sequence[str] | None = None + + +def upgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.drop_table("db_patches") + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.create_table( + "db_patches", + sa.Column("id", sa.INTEGER(), nullable=False), + sa.Column("current", sa.VARCHAR(), nullable=True), + sa.PrimaryKeyConstraint("id"), + ) + # ### end Alembic commands ### diff --git a/tests/test_db.py b/tests/test_db.py index 981e65b..c22359d 100644 --- a/tests/test_db.py +++ b/tests/test_db.py @@ -20,14 +20,6 @@ def a_movie(**kwds) -> models.Movie: return models.Movie(**args) -@pytest.mark.asyncio -async def test_current_patch_level(conn: db.Connection): - patch_level = "some-patch-level" - assert patch_level != await db.current_patch_level(conn) - await db.set_current_patch_level(conn, patch_level) - assert patch_level == await db.current_patch_level(conn) - - @pytest.mark.asyncio async def test_get(conn: db.Connection): m1 = a_movie() diff --git a/unwind/db.py b/unwind/db.py index b609c59..38b0107 100644 --- a/unwind/db.py +++ b/unwind/db.py @@ -4,9 +4,12 @@ from pathlib import Path from typing import Any, AsyncGenerator, Iterable, Literal, Sequence, Type, TypeVar import sqlalchemy as sa -from sqlalchemy.dialects.sqlite import insert from sqlalchemy.ext.asyncio import AsyncConnection, AsyncEngine, create_async_engine +import alembic.command +import alembic.config +import alembic.migration + from . import config from .models import ( Model, @@ -15,7 +18,6 @@ from .models import ( Rating, User, asplain, - db_patches, fromplain, metadata, movies, @@ -33,6 +35,25 @@ _engine: AsyncEngine | None = None type Connection = AsyncConnection +_project_dir = Path(__file__).parent.parent +_alembic_ini = _project_dir / "alembic.ini" + + +def _init(conn: sa.Connection) -> None: + # See https://alembic.sqlalchemy.org/en/latest/cookbook.html#building-an-up-to-date-database-from-scratch + context = alembic.migration.MigrationContext.configure(conn) + heads = context.get_current_heads() + + is_empty_db = not heads # We consider a DB empty if Alembic hasn't touched it yet. + if is_empty_db: + log.info("⚡️ Initializing empty database.") + metadata.create_all(conn) + + # We pass our existing connection to Alembic's env.py, to avoid running another asyncio loop there. + alembic_cfg = alembic.config.Config(_alembic_ini) + alembic_cfg.attributes["connection"] = conn + alembic.command.stamp(alembic_cfg, "head") + async def open_connection_pool() -> None: """Open the DB connection pool. @@ -41,11 +62,7 @@ async def open_connection_pool() -> None: """ async with transaction() as conn: await conn.execute(sa.text("PRAGMA journal_mode=WAL")) - - await conn.run_sync(metadata.create_all, tables=[db_patches]) - - async with new_connection() as conn: - await apply_db_patches(conn) + await conn.run_sync(_init) async def close_connection_pool() -> None: @@ -65,65 +82,7 @@ async def close_connection_pool() -> None: await engine.dispose() -async def current_patch_level(conn: Connection, /) -> str: - query = sa.select(db_patches.c.current) - current = await conn.scalar(query) - return current or "" - - -async def set_current_patch_level(conn: Connection, /, current: str) -> None: - stmt = insert(db_patches).values(id=1, current=current) - stmt = stmt.on_conflict_do_update(set_={"current": stmt.excluded.current}) - await conn.execute(stmt) - - -db_patches_dir = Path(__file__).parent / "sql" - - -async def apply_db_patches(conn: Connection, /) -> None: - """Apply all remaining patches to the database. - - Beware that patches will be applied in lexicographical order, - i.e. "10" comes before "9". - - The current patch state is recorded in the DB itself. - - Please note that every SQL statement in a patch file MUST be terminated - using two consecutive semi-colons (;). - Failing to do so will result in an error. - """ - applied_lvl = await current_patch_level(conn) - - did_patch = False - - for patchfile in sorted(db_patches_dir.glob("*.sql"), key=lambda p: p.stem): - patch_lvl = patchfile.stem - if patch_lvl <= applied_lvl: - continue - - log.info("Applying patch: %s", patch_lvl) - - sql = patchfile.read_text() - queries = sql.split(";;") - if len(queries) < 2: - log.error( - "Patch file is missing statement terminator (`;;'): %s", patchfile - ) - raise RuntimeError("No statement found.") - - async with transacted(conn): - for query in queries: - await conn.execute(sa.text(query)) - - await set_current_patch_level(conn, patch_lvl) - - did_patch = True - - if did_patch: - await _vacuum(conn) - - -async def _vacuum(conn: Connection, /) -> None: +async def vacuum(conn: Connection, /) -> None: """Vacuum the database. This function cannot be run on a connection with an open transaction. diff --git a/unwind/models.py b/unwind/models.py index a2ffffb..07b81fb 100644 --- a/unwind/models.py +++ b/unwind/models.py @@ -255,23 +255,6 @@ def utcnow() -> datetime: return datetime.now(timezone.utc) -@mapper_registry.mapped -@dataclass -class DbPatch: - __table__: ClassVar[Table] = Table( - "db_patches", - metadata, - Column("id", Integer, primary_key=True), - Column("current", String), - ) - - id: int - current: str - - -db_patches = DbPatch.__table__ - - @mapper_registry.mapped @dataclass class Progress: diff --git a/unwind/sql/00000000-init-0.sql b/unwind/sql/00000000-init-0.sql deleted file mode 100644 index d0bd446..0000000 --- a/unwind/sql/00000000-init-0.sql +++ /dev/null @@ -1,36 +0,0 @@ -PRAGMA foreign_keys = ON;; - -CREATE TABLE IF NOT EXISTS users ( - id TEXT NOT NULL PRIMARY KEY, - imdb_id TEXT NOT NULL UNIQUE, - name TEXT NOT NULL -);; - -CREATE TABLE IF NOT EXISTS movies ( - id TEXT NOT NULL PRIMARY KEY, - title TEXT NOT NULL, - release_year NUMBER NOT NULL, - media_type TEXT NOT NULL, - imdb_id TEXT NOT NULL UNIQUE, - score NUMBER NOT NULL, - runtime NUMBER, - genres TEXT NOT NULL, - updated TEXT NOT NULL -);; - -CREATE TABLE IF NOT EXISTS ratings ( - id TEXT NOT NULL PRIMARY KEY, - movie_id TEXT NOT NULL, - user_id TEXT NOT NULL, - score NUMBER NOT NULL, - rating_date TEXT NOT NULL, - favorite NUMBER, - finished NUMBER, - FOREIGN KEY(movie_id) REFERENCES movies(id), - FOREIGN KEY(user_id) REFERENCES users(id) -);; - -CREATE UNIQUE INDEX IF NOT EXISTS ratings_index ON ratings ( - movie_id, - user_id -);; diff --git a/unwind/sql/00000000-init-1.sql b/unwind/sql/00000000-init-1.sql deleted file mode 100644 index 85d40a6..0000000 --- a/unwind/sql/00000000-init-1.sql +++ /dev/null @@ -1,40 +0,0 @@ --- add original_title to movies table - --- see https://www.sqlite.org/lang_altertable.html#caution --- 1. Create new table --- 2. Copy data --- 3. Drop old table --- 4. Rename new into old - -CREATE TABLE _migrate_movies ( - id TEXT NOT NULL PRIMARY KEY, - title TEXT NOT NULL, - original_title TEXT, - release_year NUMBER NOT NULL, - media_type TEXT NOT NULL, - imdb_id TEXT NOT NULL UNIQUE, - score NUMBER, - runtime NUMBER, - genres TEXT NOT NULL, - updated TEXT NOT NULL -);; - -INSERT INTO _migrate_movies -SELECT - id, - title, - NULL, - release_year, - media_type, - imdb_id, - score, - runtime, - genres, - updated -FROM movies -WHERE true;; - -DROP TABLE movies;; - -ALTER TABLE _migrate_movies -RENAME TO movies;; diff --git a/unwind/sql/00000000-init-2.sql b/unwind/sql/00000000-init-2.sql deleted file mode 100644 index 68fad70..0000000 --- a/unwind/sql/00000000-init-2.sql +++ /dev/null @@ -1,46 +0,0 @@ --- only set original_title if it differs from title, --- and normalize media_type with an extra table. - -CREATE TABLE mediatypes ( - id INTEGER PRIMARY KEY NOT NULL, - name TEXT NOT NULL UNIQUE -);; - -INSERT INTO mediatypes (name) -SELECT DISTINCT media_type -FROM movies -WHERE true;; - -CREATE TABLE _migrate_movies ( - id TEXT PRIMARY KEY NOT NULL, - title TEXT NOT NULL, - original_title TEXT, - release_year INTEGER NOT NULL, - media_type_id INTEGER NOT NULL, - imdb_id TEXT NOT NULL UNIQUE, - score INTEGER, - runtime INTEGER, - genres TEXT NOT NULL, - updated TEXT NOT NULL, - FOREIGN KEY(media_type_id) REFERENCES mediatypes(id) -);; - -INSERT INTO _migrate_movies -SELECT - id, - title, - (CASE WHEN original_title=title THEN NULL ELSE original_title END), - release_year, - (SELECT id FROM mediatypes WHERE name=media_type) AS media_type_id, - imdb_id, - score, - runtime, - genres, - updated -FROM movies -WHERE true;; - -DROP TABLE movies;; - -ALTER TABLE _migrate_movies -RENAME TO movies;; diff --git a/unwind/sql/00000000-init-3.sql b/unwind/sql/00000000-init-3.sql deleted file mode 100644 index 98380c7..0000000 --- a/unwind/sql/00000000-init-3.sql +++ /dev/null @@ -1,62 +0,0 @@ --- add convenient view for movies - -CREATE VIEW IF NOT EXISTS movies_view -AS SELECT - movies.id, - movies.title, - movies.original_title, - movies.release_year, - mediatypes.name AS media_type, - movies.imdb_id, - movies.score, - movies.runtime, - movies.genres, - movies.updated -FROM movies -JOIN mediatypes ON mediatypes.id=movies.media_type_id;; - -CREATE TRIGGER IF NOT EXISTS insert_movies_view - INSTEAD OF INSERT - ON movies_view -BEGIN - INSERT INTO movies ( - id, - title, - original_title, - release_year, - media_type_id, - imdb_id, - score, - runtime, - genres, - updated - ) VALUES ( - NEW.id, - NEW.title, - NEW.original_title, - NEW.release_year, - (SELECT id FROM mediatypes WHERE name=NEW.media_type), - NEW.imdb_id, - NEW.score, - NEW.runtime, - NEW.genres, - NEW.updated - ); -END;; - -CREATE TRIGGER IF NOT EXISTS update_movies_view - INSTEAD OF UPDATE OF media_type - ON movies_view -BEGIN - UPDATE movies - SET media_type_id=(SELECT id FROM mediatypes WHERE name=NEW.media_type) - WHERE id=OLD.id; -END;; - -CREATE TRIGGER IF NOT EXISTS delete_movies_view - INSTEAD OF DELETE - ON movies_view -BEGIN - DELETE FROM movies - WHERE movies.id=OLD.id; -END;; diff --git a/unwind/sql/00000000-init-4.sql b/unwind/sql/00000000-init-4.sql deleted file mode 100644 index 984ef37..0000000 --- a/unwind/sql/00000000-init-4.sql +++ /dev/null @@ -1,37 +0,0 @@ --- denormalize movie media_type - -CREATE TABLE _migrate_movies ( - id TEXT PRIMARY KEY NOT NULL, - title TEXT NOT NULL, - original_title TEXT, - release_year INTEGER NOT NULL, - media_type TEXT NOT NULL, - imdb_id TEXT NOT NULL UNIQUE, - score INTEGER, - runtime INTEGER, - genres TEXT NOT NULL, - updated TEXT NOT NULL -);; - -INSERT INTO _migrate_movies -SELECT - id, - title, - original_title, - release_year, - (SELECT name FROM mediatypes WHERE id=media_type_id) AS media_type, - imdb_id, - score, - runtime, - genres, - updated -FROM movies -WHERE true;; - -DROP VIEW movies_view;; -DROP TABLE mediatypes;; - -DROP TABLE movies;; - -ALTER TABLE _migrate_movies -RENAME TO movies;; diff --git a/unwind/sql/00000001-fix-db.sql.disabled b/unwind/sql/00000001-fix-db.sql.disabled deleted file mode 100644 index e6376a8..0000000 --- a/unwind/sql/00000001-fix-db.sql.disabled +++ /dev/null @@ -1,2 +0,0 @@ --- see the commit of this file for details. -;; diff --git a/unwind/sql/20210705-224139.sql b/unwind/sql/20210705-224139.sql deleted file mode 100644 index e714b4e..0000000 --- a/unwind/sql/20210705-224139.sql +++ /dev/null @@ -1,8 +0,0 @@ --- add groups table - -CREATE TABLE groups ( - id TEXT PRIMARY KEY NOT NULL, - name TEXT NOT NULL, - secret TEXT NOT NULL, - users TEXT NOT NULL -- JSON array -);; diff --git a/unwind/sql/20210711-172808--progress-table.sql b/unwind/sql/20210711-172808--progress-table.sql deleted file mode 100644 index 1ee6a5f..0000000 --- a/unwind/sql/20210711-172808--progress-table.sql +++ /dev/null @@ -1,7 +0,0 @@ --- add progress table - -CREATE TABLE progress ( - id TEXT PRIMARY KEY NOT NULL, - state TEXT NOT NULL, - started TEXT NOT NULL -);; diff --git a/unwind/sql/20210720-213416.sql b/unwind/sql/20210720-213416.sql deleted file mode 100644 index 286e094..0000000 --- a/unwind/sql/20210720-213416.sql +++ /dev/null @@ -1,36 +0,0 @@ --- add IMDb vote count - -CREATE TABLE _migrate_movies ( - id TEXT PRIMARY KEY NOT NULL, - title TEXT NOT NULL, - original_title TEXT, - release_year INTEGER NOT NULL, - media_type TEXT NOT NULL, - imdb_id TEXT NOT NULL UNIQUE, - imdb_score INTEGER, - imdb_votes INTEGER, - runtime INTEGER, - genres TEXT NOT NULL, - updated TEXT NOT NULL -);; - -INSERT INTO _migrate_movies -SELECT - id, - title, - original_title, - release_year, - media_type, - imdb_id, - score AS imdb_score, - NULL AS imdb_votes, - runtime, - genres, - updated -FROM movies -WHERE true;; - -DROP TABLE movies;; - -ALTER TABLE _migrate_movies -RENAME TO movies;; diff --git a/unwind/sql/20210720-223416.sql b/unwind/sql/20210720-223416.sql deleted file mode 100644 index 95e1b78..0000000 --- a/unwind/sql/20210720-223416.sql +++ /dev/null @@ -1,24 +0,0 @@ --- add IMDb vote count - -CREATE TABLE _migrate_progress ( - id TEXT PRIMARY KEY NOT NULL, - type TEXT NOT NULL, - state TEXT NOT NULL, - started TEXT NOT NULL, - stopped TEXT -);; - -INSERT INTO _migrate_progress -SELECT - id, - 'import-imdb-movies' AS type, - state, - started, - NULL AS stopped -FROM progress -WHERE true;; - -DROP TABLE progress;; - -ALTER TABLE _migrate_progress -RENAME TO progress;; diff --git a/unwind/sql/20210721-213417.sql b/unwind/sql/20210721-213417.sql deleted file mode 100644 index 33e891a..0000000 --- a/unwind/sql/20210721-213417.sql +++ /dev/null @@ -1,38 +0,0 @@ --- add creation timestamp to movies - -CREATE TABLE _migrate_movies ( - id TEXT PRIMARY KEY NOT NULL, - title TEXT NOT NULL, - original_title TEXT, - release_year INTEGER NOT NULL, - media_type TEXT NOT NULL, - imdb_id TEXT NOT NULL UNIQUE, - imdb_score INTEGER, - imdb_votes INTEGER, - runtime INTEGER, - genres TEXT NOT NULL, - created TEXT NOT NULL, - updated TEXT NOT NULL -);; - -INSERT INTO _migrate_movies -SELECT - id, - title, - original_title, - release_year, - media_type, - imdb_id, - imdb_score, - imdb_votes, - runtime, - genres, - updated AS created, - updated -FROM movies -WHERE true;; - -DROP TABLE movies;; - -ALTER TABLE _migrate_movies -RENAME TO movies;; diff --git a/unwind/sql/20210728-223416.sql b/unwind/sql/20210728-223416.sql deleted file mode 100644 index 1581060..0000000 --- a/unwind/sql/20210728-223416.sql +++ /dev/null @@ -1,24 +0,0 @@ --- add IMDb vote count - -CREATE TABLE _migrate_progress ( - id TEXT PRIMARY KEY NOT NULL, - type TEXT NOT NULL, - state TEXT NOT NULL, - started TEXT NOT NULL, - stopped TEXT -);; - -INSERT INTO _migrate_progress -SELECT - id, - type, - '{"percent":' || state || '}' AS state, - started, - stopped -FROM progress -WHERE true;; - -DROP TABLE progress;; - -ALTER TABLE _migrate_progress -RENAME TO progress;; diff --git a/unwind/sql/20210801-201151--add-user-secret.sql b/unwind/sql/20210801-201151--add-user-secret.sql deleted file mode 100644 index 3294a56..0000000 --- a/unwind/sql/20210801-201151--add-user-secret.sql +++ /dev/null @@ -1,22 +0,0 @@ --- add secret to users - -CREATE TABLE _migrate_users ( - id TEXT PRIMARY KEY NOT NULL, - imdb_id TEXT NOT NULL UNIQUE, - name TEXT NOT NULL, - secret TEXT NOT NULL -);; - -INSERT INTO _migrate_users -SELECT - id, - imdb_id, - name, - '' AS secret -FROM users -WHERE true;; - -DROP TABLE users;; - -ALTER TABLE _migrate_users -RENAME TO users;; diff --git a/unwind/sql/20210802-212312--add-group-admins.sql b/unwind/sql/20210802-212312--add-group-admins.sql deleted file mode 100644 index 13f3105..0000000 --- a/unwind/sql/20210802-212312--add-group-admins.sql +++ /dev/null @@ -1,45 +0,0 @@ --- add group admins - ---- remove secrets from groups -CREATE TABLE _migrate_groups ( - id TEXT PRIMARY KEY NOT NULL, - name TEXT NOT NULL, - users TEXT NOT NULL -- JSON array -);; - -INSERT INTO _migrate_groups -SELECT - id, - name, - users -FROM groups -WHERE true;; - -DROP TABLE groups;; - -ALTER TABLE _migrate_groups -RENAME TO groups;; - ---- add group access to users -CREATE TABLE _migrate_users ( - id TEXT PRIMARY KEY NOT NULL, - imdb_id TEXT NOT NULL UNIQUE, - name TEXT NOT NULL, - secret TEXT NOT NULL, - groups TEXT NOT NULL -- JSON array -);; - -INSERT INTO _migrate_users -SELECT - id, - imdb_id, - name, - secret, - '[]' AS groups -FROM users -WHERE true;; - -DROP TABLE users;; - -ALTER TABLE _migrate_users -RENAME TO users;; diff --git a/unwind/sql/20240511-001949--remove-genres-notnull.sql b/unwind/sql/20240511-001949--remove-genres-notnull.sql deleted file mode 100644 index 98a7c16..0000000 --- a/unwind/sql/20240511-001949--remove-genres-notnull.sql +++ /dev/null @@ -1,38 +0,0 @@ --- remove NOTNULL constraint from movies.genres - -CREATE TABLE _migrate_movies ( - id TEXT PRIMARY KEY NOT NULL, - title TEXT NOT NULL, - original_title TEXT, - release_year INTEGER NOT NULL, - media_type TEXT NOT NULL, - imdb_id TEXT NOT NULL UNIQUE, - imdb_score INTEGER, - imdb_votes INTEGER, - runtime INTEGER, - genres TEXT, - created TEXT NOT NULL, - updated TEXT NOT NULL -);; - -INSERT INTO _migrate_movies -SELECT - id, - title, - original_title, - release_year, - media_type, - imdb_id, - imdb_score, - imdb_votes, - runtime, - genres, - created, - updated -FROM movies -WHERE true;; - -DROP TABLE movies;; - -ALTER TABLE _migrate_movies -RENAME TO movies;; From 76a69b6340d520e75638ea371776648406f305de Mon Sep 17 00:00:00 2001 From: ducklet Date: Sun, 19 May 2024 02:57:13 +0200 Subject: [PATCH 12/25] chore: replace TypeVar with native syntax --- unwind/db.py | 28 ++++++++++++---------------- unwind/imdb_import.py | 6 ++---- unwind/models.py | 18 +++++++++--------- unwind/request.py | 17 +++++++---------- 4 files changed, 30 insertions(+), 39 deletions(-) diff --git a/unwind/db.py b/unwind/db.py index 38b0107..16351c7 100644 --- a/unwind/db.py +++ b/unwind/db.py @@ -1,7 +1,7 @@ import contextlib import logging from pathlib import Path -from typing import Any, AsyncGenerator, Iterable, Literal, Sequence, Type, TypeVar +from typing import Any, AsyncGenerator, Iterable, Literal, Sequence, Type import sqlalchemy as sa from sqlalchemy.ext.asyncio import AsyncConnection, AsyncEngine, create_async_engine @@ -29,7 +29,6 @@ from .models import ( from .types import ULID log = logging.getLogger(__name__) -T = TypeVar("T") _engine: AsyncEngine | None = None @@ -240,7 +239,7 @@ async def add(conn: Connection, /, item: Model) -> None: # Support late initializing - used for optimization. if getattr(item, "_is_lazy", False): assert hasattr(item, "_lazy_init") - item._lazy_init() # pyright: ignore [reportGeneralTypeIssues] + item._lazy_init() # pyright: ignore[reportAttributeAccessIssue] table: sa.Table = item.__table__ values = asplain(item, serialize=True) @@ -262,17 +261,14 @@ async def fetch_one( return result.first() -ModelType = TypeVar("ModelType", bound=Model) - - -async def get( +async def get[T: Model]( conn: Connection, /, - model: Type[ModelType], + model: Type[T], *, order_by: tuple[sa.Column, Literal["asc", "desc"]] | None = None, **field_values, -) -> ModelType | None: +) -> T | None: """Load a model instance from the database. Passing `field_values` allows to filter the item to load. You have to encode the @@ -295,9 +291,9 @@ async def get( return fromplain(model, row._mapping, serialized=True) if row else None -async def get_many( - conn: Connection, /, model: Type[ModelType], **field_sets: set | list -) -> Iterable[ModelType]: +async def get_many[T: Model]( + conn: Connection, /, model: Type[T], **field_sets: set | list +) -> Iterable[T]: """Return the items with any values matching all given field sets. This is similar to `get_all`, but instead of a scalar value a list of values @@ -314,9 +310,9 @@ async def get_many( return (fromplain(model, row._mapping, serialized=True) for row in rows) -async def get_all( - conn: Connection, /, model: Type[ModelType], **field_values -) -> Iterable[ModelType]: +async def get_all[T: Model]( + conn: Connection, /, model: Type[T], **field_values +) -> Iterable[T]: """Filter all items by comparing all given field values. If no filters are given, all items will be returned. @@ -333,7 +329,7 @@ async def update(conn: Connection, /, item: Model) -> None: # Support late initializing - used for optimization. if getattr(item, "_is_lazy", False): assert hasattr(item, "_lazy_init") - item._lazy_init() # pyright: ignore [reportGeneralTypeIssues] + item._lazy_init() # pyright: ignore[reportAttributeAccessIssue] table: sa.Table = item.__table__ values = asplain(item, serialize=True) diff --git a/unwind/imdb_import.py b/unwind/imdb_import.py index 5464df0..28792e2 100644 --- a/unwind/imdb_import.py +++ b/unwind/imdb_import.py @@ -5,7 +5,7 @@ import logging from dataclasses import dataclass, fields from datetime import datetime, timezone from pathlib import Path -from typing import Generator, Literal, Type, TypeVar, overload +from typing import Generator, Literal, Type, overload from . import config, db, request from .db import add_or_update_many_movies @@ -14,8 +14,6 @@ from .models import Movie log = logging.getLogger(__name__) -T = TypeVar("T") - # See # - https://developer.imdb.com/non-commercial-datasets/ # - https://datasets.imdbws.com/ @@ -127,7 +125,7 @@ def read_imdb_tsv( @overload -def read_imdb_tsv( +def read_imdb_tsv[T]( path: Path, row_type: Type[T], *, unpack: Literal[True] = True ) -> Generator[T, None, None]: ... diff --git a/unwind/models.py b/unwind/models.py index 07b81fb..31e18c9 100644 --- a/unwind/models.py +++ b/unwind/models.py @@ -12,10 +12,8 @@ from typing import ( Mapping, Protocol, Type, - TypeAlias, TypeAliasType, TypedDict, - TypeVar, Union, get_args, get_origin, @@ -27,12 +25,10 @@ from sqlalchemy.orm import registry from .types import ULID from .utils import json_dump -JSONScalar: TypeAlias = int | float | str | None +type JSONScalar = int | float | str | None type JSON = JSONScalar | list["JSON"] | dict[str, "JSON"] type JSONObject = dict[str, JSON] -T = TypeVar("T") - class Model(Protocol): __table__: ClassVar[Table] @@ -53,6 +49,10 @@ metadata.naming_convention = { def annotations(tp: Type) -> tuple | None: + # Support type aliases and generic aliases. + if isinstance(tp, TypeAliasType) or hasattr(tp, "__value__"): + tp = tp.__value__ + return tp.__metadata__ if hasattr(tp, "__metadata__") else None # type: ignore @@ -110,7 +110,7 @@ def optional_fields(o): yield f -def _id(x: T) -> T: +def _id[T](x: T) -> T: """Return the given argument, aka. the identity function.""" return x @@ -168,7 +168,7 @@ def asplain( ), f"Type mismatch: {f.name!a} ({target!a} != {type(v)!a})" d[f.name] = v elif target in {Literal}: - assert isinstance(v, JSONScalar) + assert isinstance(v, JSONScalar.__value__) d[f.name] = v else: raise ValueError(f"Unsupported value type: {f.name!a}: {type(v)!a}") @@ -176,7 +176,7 @@ def asplain( return d -def fromplain(cls: Type[T], d: Mapping, *, serialized: bool = False) -> T: +def fromplain[T](cls: Type[T], d: Mapping, *, serialized: bool = False) -> T: """Return an instance of the given model using the given data. If `serialized` is `True`, collection types (lists, dicts, etc.) will be @@ -379,7 +379,7 @@ dataclass containing the ID of the linked data. The contents of the Relation are ignored or discarded when using `asplain`, `fromplain`, and `validate`. """ -Relation: TypeAlias = Annotated[T | None, _RelationSentinel] +type Relation[T] = Annotated[T | None, _RelationSentinel] type Access = Literal[ diff --git a/unwind/request.py b/unwind/request.py index f12936b..46d1e9b 100644 --- a/unwind/request.py +++ b/unwind/request.py @@ -11,7 +11,7 @@ from hashlib import md5 from pathlib import Path from random import random from time import sleep, time -from typing import Any, Callable, ParamSpec, TypeVar, cast, overload +from typing import Any, Callable, cast, overload import bs4 import httpx @@ -24,13 +24,10 @@ if config.debug and config.cachedir: config.cachedir.mkdir(exist_ok=True) -_shared_asession = None - _ASession_T = httpx.AsyncClient -_Response_T = httpx.Response +type _Response_T = httpx.Response -_T = TypeVar("_T") -_P = ParamSpec("_P") +_shared_asession: _ASession_T | None = None @asynccontextmanager @@ -59,17 +56,17 @@ async def asession(): _shared_asession = None -def _throttle( +def _throttle[T, **P]( times: int, per_seconds: float, jitter: Callable[[], float] | None = None -) -> Callable[[Callable[_P, _T]], Callable[_P, _T]]: +) -> Callable[[Callable[P, T]], Callable[P, T]]: calls: deque[float] = deque(maxlen=times) if jitter is None: jitter = lambda: 0.0 # noqa: E731 - def decorator(func: Callable[_P, _T]) -> Callable[_P, _T]: + def decorator(func: Callable[P, T]) -> Callable[P, T]: @wraps(func) - def inner(*args: _P.args, **kwds: _P.kwargs): + def inner(*args: P.args, **kwds: P.kwargs): # clean up while calls: if calls[0] + per_seconds > time(): From f0f69c1954b756c3347d92300875b3736756e3fa Mon Sep 17 00:00:00 2001 From: ducklet Date: Sun, 19 May 2024 11:10:08 +0200 Subject: [PATCH 13/25] chore: add more typing info --- unwind/web.py | 79 +++++++++++++++++++++++++------------------- unwind/web_models.py | 4 +-- 2 files changed, 47 insertions(+), 36 deletions(-) diff --git a/unwind/web.py b/unwind/web.py index b4ba575..6a2a0fc 100644 --- a/unwind/web.py +++ b/unwind/web.py @@ -3,7 +3,7 @@ import contextlib import logging import secrets from json.decoder import JSONDecodeError -from typing import Literal, overload +from typing import Any, Literal, Never, TypeGuard, overload from starlette.applications import Starlette from starlette.authentication import ( @@ -20,14 +20,14 @@ from starlette.middleware import Middleware from starlette.middleware.authentication import AuthenticationMiddleware from starlette.middleware.cors import CORSMiddleware from starlette.middleware.gzip import GZipMiddleware -from starlette.requests import HTTPConnection +from starlette.requests import HTTPConnection, Request from starlette.responses import JSONResponse from starlette.routing import Mount, Route from . import config, db, imdb, imdb_import, web_models from .db import close_connection_pool, find_movies, find_ratings, open_connection_pool from .middleware.responsetime import ResponseTimeMiddleware -from .models import Group, Movie, User, asplain +from .models import JSON, Access, Group, Movie, User, asplain from .types import ULID from .utils import b64decode, b64encode, phc_compare, phc_scrypt @@ -83,11 +83,11 @@ class BearerAuthBackend(AuthenticationBackend): return AuthCredentials(["authenticated", *roles]), user -def truthy(s: str): +def truthy(s: str | None) -> bool: return bool(s) and s.lower() in {"1", "yes", "true"} -_Yearcomp = Literal["<", "=", ">"] +type _Yearcomp = Literal["<", "=", ">"] def yearcomp(s: str) -> tuple[_Yearcomp, int] | None: @@ -103,7 +103,7 @@ def yearcomp(s: str) -> tuple[_Yearcomp, int] | None: def as_int( - x, *, max: int | None = None, min: int | None = 1, default: int | None = None + x: Any, *, max: int | None = None, min: int | None = 1, default: int | None = None ) -> int: try: if not isinstance(x, int): @@ -121,9 +121,9 @@ def as_int( return default -def as_ulid(s: str) -> ULID: +def as_ulid(s: Any) -> ULID: try: - if not s: + if not isinstance(s, str) or not s: raise ValueError("Invalid ULID.") return ULID(s) @@ -133,14 +133,17 @@ def as_ulid(s: str) -> ULID: @overload -async def json_from_body(request) -> dict: ... +async def json_from_body(request: Request) -> dict[str, JSON]: ... @overload -async def json_from_body(request, keys: list[str]) -> list: ... +async def json_from_body(request: Request, keys: list[str]) -> list[JSON]: ... -async def json_from_body(request, keys: list[str] | None = None): +async def json_from_body( + request: Request, keys: list[str] | None = None +) -> dict[str, JSON] | list[JSON]: + data: dict[str, JSON] if not await request.body(): data = {} @@ -150,6 +153,9 @@ async def json_from_body(request, keys: list[str] | None = None): except JSONDecodeError as err: raise HTTPException(422, "Invalid JSON content.") from err + if not isinstance(data, dict): + raise HTTPException(422, f"Invalid JSON type: {type(data)!a}") + if not keys: return data @@ -159,11 +165,11 @@ async def json_from_body(request, keys: list[str] | None = None): raise HTTPException(422, f"Missing data for key: {err.args[0]}") from err -def is_admin(request): +def is_admin(request: Request) -> bool: return "admin" in request.auth.scopes -async def auth_user(request) -> User | None: +async def auth_user(request: Request) -> User | None: if not isinstance(request.user, AuthedUser): return @@ -192,7 +198,7 @@ def route(path: str, *, methods: list[str] | None = None, **kwds): @route("/groups/{group_id}/ratings") -async def get_ratings_for_group(request): +async def get_ratings_for_group(request: Request) -> JSONResponse: group_id = as_ulid(request.path_params["group_id"]) async with db.new_connection() as conn: @@ -250,13 +256,13 @@ def not_found(reason: str = "Not Found"): return JSONResponse({"error": reason}, status_code=404) -def not_implemented(): +def not_implemented() -> Never: raise HTTPException(404, "Not yet implemented.") @route("/movies") @requires(["authenticated"]) -async def list_movies(request): +async def list_movies(request: Request) -> JSONResponse: params = request.query_params user = await auth_user(request) @@ -329,13 +335,13 @@ async def list_movies(request): @route("/movies", methods=["POST"]) @requires(["authenticated", "admin"]) -async def add_movie(request): +async def add_movie(request: Request) -> JSONResponse: not_implemented() @route("/movies/_reload_imdb", methods=["GET"]) @requires(["authenticated", "admin"]) -async def progress_for_load_imdb_movies(request): +async def progress_for_load_imdb_movies(request: Request) -> JSONResponse: async with db.new_connection() as conn: progress = await db.get_import_progress(conn) if not progress: @@ -371,7 +377,7 @@ _import_lock = asyncio.Lock() @route("/movies/_reload_imdb", methods=["POST"]) @requires(["authenticated", "admin"]) -async def load_imdb_movies(request): +async def load_imdb_movies(request: Request) -> JSONResponse: params = request.query_params force = truthy(params.get("force")) @@ -395,7 +401,7 @@ async def load_imdb_movies(request): @route("/users") @requires(["authenticated", "admin"]) -async def list_users(request): +async def list_users(request: Request) -> JSONResponse: async with db.new_connection() as conn: users = await db.get_all(conn, User) @@ -404,7 +410,7 @@ async def list_users(request): @route("/users", methods=["POST"]) @requires(["authenticated", "admin"]) -async def add_user(request): +async def add_user(request: Request) -> JSONResponse: name, imdb_id = await json_from_body(request, ["name", "imdb_id"]) # XXX restrict name @@ -426,7 +432,7 @@ async def add_user(request): @route("/users/{user_id}") @requires(["authenticated"]) -async def show_user(request): +async def show_user(request: Request) -> JSONResponse: user_id = as_ulid(request.path_params["user_id"]) if is_admin(request): @@ -455,7 +461,7 @@ async def show_user(request): @route("/users/{user_id}", methods=["DELETE"]) @requires(["authenticated", "admin"]) -async def remove_user(request): +async def remove_user(request: Request) -> JSONResponse: user_id = as_ulid(request.path_params["user_id"]) async with db.new_connection() as conn: @@ -473,7 +479,7 @@ async def remove_user(request): @route("/users/{user_id}", methods=["PATCH"]) @requires(["authenticated"]) -async def modify_user(request): +async def modify_user(request: Request) -> JSONResponse: user_id = as_ulid(request.path_params["user_id"]) if is_admin(request): @@ -520,9 +526,13 @@ async def modify_user(request): return JSONResponse(asplain(user)) +def is_valid_access(x: Any) -> TypeGuard[Access]: + return isinstance(x, str) and x in set("riw") + + @route("/users/{user_id}/groups", methods=["POST"]) @requires(["authenticated", "admin"]) -async def add_group_to_user(request): +async def add_group_to_user(request: Request) -> JSONResponse: user_id = as_ulid(request.path_params["user_id"]) async with db.new_connection() as conn: @@ -537,7 +547,7 @@ async def add_group_to_user(request): if not group: return not_found("Group not found") - if access not in set("riw"): + if not is_valid_access(access): raise HTTPException(422, "Invalid access level.") user.set_access(group_id, access) @@ -549,19 +559,19 @@ async def add_group_to_user(request): @route("/users/{user_id}/ratings") @requires(["private"]) -async def ratings_for_user(request): +async def ratings_for_user(request: Request) -> JSONResponse: not_implemented() @route("/users/{user_id}/ratings", methods=["PUT"]) @requires("authenticated") -async def set_rating_for_user(request): +async def set_rating_for_user(request: Request) -> JSONResponse: not_implemented() @route("/users/_reload_ratings", methods=["POST"]) @requires(["authenticated", "admin"]) -async def load_imdb_user_ratings(request): +async def load_imdb_user_ratings(request: Request) -> JSONResponse: ratings = [rating async for rating in imdb.refresh_user_ratings_from_imdb()] return JSONResponse({"new_ratings": [asplain(r) for r in ratings]}) @@ -569,7 +579,7 @@ async def load_imdb_user_ratings(request): @route("/groups") @requires(["authenticated", "admin"]) -async def list_groups(request): +async def list_groups(request: Request) -> JSONResponse: async with db.new_connection() as conn: groups = await db.get_all(conn, Group) @@ -578,7 +588,7 @@ async def list_groups(request): @route("/groups", methods=["POST"]) @requires(["authenticated", "admin"]) -async def add_group(request): +async def add_group(request: Request) -> JSONResponse: (name,) = await json_from_body(request, ["name"]) # XXX restrict name @@ -592,7 +602,7 @@ async def add_group(request): @route("/groups/{group_id}/users", methods=["POST"]) @requires(["authenticated"]) -async def add_user_to_group(request): +async def add_user_to_group(request: Request) -> JSONResponse: group_id = as_ulid(request.path_params["group_id"]) async with db.new_connection() as conn: group = await db.get(conn, Group, id=str(group_id)) @@ -628,11 +638,12 @@ async def add_user_to_group(request): return JSONResponse(asplain(group)) -async def http_exception(request, exc): +async def http_exception(request: Request, exc: Exception) -> JSONResponse: + assert isinstance(exc, HTTPException) return JSONResponse({"error": exc.detail}, status_code=exc.status_code) -def auth_error(request, err): +def auth_error(conn: HTTPConnection, err: Exception) -> JSONResponse: return unauthorized(str(err)) diff --git a/unwind/web_models.py b/unwind/web_models.py index 6e83e1d..6a2c331 100644 --- a/unwind/web_models.py +++ b/unwind/web_models.py @@ -3,8 +3,8 @@ from typing import Container, Iterable from . import imdb, models -URL = str -Score100 = int # [0, 100] +type URL = str +type Score100 = int # [0, 100] @dataclass From b0f5ec4cc92e077b6f1a393fa992de48e895830a Mon Sep 17 00:00:00 2001 From: ducklet Date: Sun, 19 May 2024 21:42:24 +0200 Subject: [PATCH 14/25] feat: add awards to REST response --- tests/test_web.py | 70 ++++++++++++++++++++++++++++++++++++++++++++ unwind/db.py | 22 ++++++++++++++ unwind/models.py | 29 ++++++++++++++++++ unwind/web.py | 8 +++-- unwind/web_models.py | 18 ++++++++++-- 5 files changed, 142 insertions(+), 5 deletions(-) diff --git a/tests/test_web.py b/tests/test_web.py index b1e7e4b..46cc28a 100644 --- a/tests/test_web.py +++ b/tests/test_web.py @@ -32,6 +32,74 @@ def admin_client() -> TestClient: return client +@pytest.mark.asyncio +async def test_get_ratings_for_group_with_awards( + conn: db.Connection, unauthorized_client: TestClient +): + user = models.User( + imdb_id="ur12345678", + name="user-1", + secret="secret-1", # noqa: S106 + groups=[], + ) + group = models.Group( + name="group-1", + users=[models.GroupUser(id=str(user.id), name=user.name)], + ) + user.groups = [models.UserGroup(id=str(group.id), access="r")] + path = app.url_path_for("get_ratings_for_group", group_id=str(group.id)) + + await db.add(conn, user) + await db.add(conn, group) + + movie1 = models.Movie( + title="test movie", + release_year=2013, + media_type="Movie", + imdb_id="tt12345678", + genres={"genre-1"}, + ) + await db.add(conn, movie1) + movie2 = models.Movie( + title="test movie 2", + release_year=2014, + media_type="Movie", + imdb_id="tt12345679", + genres={"genre-2"}, + ) + await db.add(conn, movie2) + + award1 = models.Award( + movie_id=movie1.id, category="imdb-top-250", details='{"position":23}' + ) + award2 = models.Award( + movie_id=movie2.id, category="imdb-top-250", details='{"position":99}' + ) + await db.add(conn, award1) + await db.add(conn, award2) + + rating = models.Rating( + movie_id=movie1.id, user_id=user.id, score=66, rating_date=datetime.now(tz=UTC) + ) + await db.add(conn, rating) + + rating_aggregate = { + "canonical_title": movie1.title, + "imdb_score": movie1.imdb_score, + "imdb_votes": movie1.imdb_votes, + "link": imdb.movie_url(movie1.imdb_id), + "media_type": movie1.media_type, + "original_title": movie1.original_title, + "user_scores": [rating.score], + "year": movie1.release_year, + "awards": ["imdb-top-250:23"], + } + + resp = unauthorized_client.get(path) + assert resp.status_code == 200 + assert resp.json() == [rating_aggregate] + + @pytest.mark.asyncio async def test_get_ratings_for_group( conn: db.Connection, unauthorized_client: TestClient @@ -82,6 +150,7 @@ async def test_get_ratings_for_group( "original_title": movie.original_title, "user_scores": [rating.score], "year": movie.release_year, + "awards": [], } resp = unauthorized_client.get(path) @@ -158,6 +227,7 @@ async def test_list_movies( "original_title": m.original_title, "user_scores": [], "year": m.release_year, + "awards": [], } response = authorized_client.get(path, params={"imdb_id": m.imdb_id}) diff --git a/unwind/db.py b/unwind/db.py index 16351c7..e416d8b 100644 --- a/unwind/db.py +++ b/unwind/db.py @@ -12,12 +12,14 @@ import alembic.migration from . import config from .models import ( + Award, Model, Movie, Progress, Rating, User, asplain, + awards, fromplain, metadata, movies, @@ -430,6 +432,26 @@ async def add_or_update_rating(conn: Connection, /, rating: Rating) -> bool: return False +type MovieImdbId = str + + +async def get_awards( + conn: Connection, /, imdb_ids: list[MovieImdbId] +) -> dict[MovieImdbId, list[Award]]: + query = ( + sa.select(Award, movies.c.imdb_id) + .join(movies, awards.c.movie_id == movies.c.id) + .where(movies.c.imdb_id.in_(imdb_ids)) + ) + rows = await fetch_all(conn, query) + awards_dict: dict[MovieImdbId, list[Award]] = {} + for row in rows: + awards_dict.setdefault(row.imdb_id, []).append( + fromplain(Award, row._mapping, serialized=True) + ) + return awards_dict + + def sql_escape(s: str, char: str = "#") -> str: return s.replace(char, 2 * char).replace("%", f"{char}%").replace("_", f"{char}_") diff --git a/unwind/models.py b/unwind/models.py index 31e18c9..2d59cd0 100644 --- a/unwind/models.py +++ b/unwind/models.py @@ -182,12 +182,17 @@ def fromplain[T](cls: Type[T], d: Mapping, *, serialized: bool = False) -> T: If `serialized` is `True`, collection types (lists, dicts, etc.) will be deserialized from string. This is the opposite operation of `serialize` for `asplain`. + Fields in the data that cannot be mapped to the given type are simply ignored. """ load = json.loads if serialized else _id dd: JSONObject = {} for f in fields(cls): target: Any = f.type + if isinstance(target, TypeAliasType): + # Support type aliases. + target = target.__value__ + otype = optional_type(f.type) is_opt = otype is not None if is_opt: @@ -198,6 +203,12 @@ def fromplain[T](cls: Type[T], d: Mapping, *, serialized: bool = False) -> T: v = d[f.name] if is_opt and v is None: dd[f.name] = v + elif target is Literal: + # Support literal types. + vals = get_args(f.type.__value__) + if v not in vals: + raise ValueError(f"Invalid value: {f.name!a}: {v!a}") + dd[f.name] = v elif isinstance(v, target): dd[f.name] = v elif target in {set, list}: @@ -530,5 +541,23 @@ class Award: created: datetime = field(default_factory=utcnow) updated: datetime = field(default_factory=utcnow) + @property + def _details(self) -> JSONObject: + return json.loads(self.details or "{}") + + @_details.setter + def _details(self, details: JSONObject): + self.details = json_dump(details) + + @property + def position(self) -> int: + return self._details["position"] + + @position.setter + def position(self, position: int): + details = self._details + details["position"] = position + self._details = details + awards = Award.__table__ diff --git a/unwind/web.py b/unwind/web.py index 6a2a0fc..ee024e9 100644 --- a/unwind/web.py +++ b/unwind/web.py @@ -235,11 +235,13 @@ async def get_ratings_for_group(request: Request) -> JSONResponse: user_ids=user_ids, ) - ratings = (web_models.Rating(**r) for r in rows) + ratings = [web_models.Rating(**r) for r in rows] - aggr = web_models.aggregate_ratings(ratings, user_ids) + awards = await db.get_awards(conn, imdb_ids=[r.movie_imdb_id for r in ratings]) - resp = tuple(asplain(r) for r in aggr) + aggrs = web_models.aggregate_ratings(ratings, user_ids, awards_dict=awards) + + resp = tuple(asplain(r) for r in aggrs) return JSONResponse(resp) diff --git a/unwind/web_models.py b/unwind/web_models.py index 6a2c331..0551ba3 100644 --- a/unwind/web_models.py +++ b/unwind/web_models.py @@ -44,6 +44,7 @@ class RatingAggregate: original_title: str | None user_scores: list[Score100] year: int + awards: list[str] @classmethod def from_movie(cls, movie: models.Movie, *, ratings: Iterable[models.Rating] = []): @@ -56,15 +57,27 @@ class RatingAggregate: original_title=movie.original_title, user_scores=[r.score for r in ratings], year=movie.release_year, + awards=[], ) +type ImdbMovieId = str +type UserId = str + + def aggregate_ratings( - ratings: Iterable[Rating], user_ids: Container[str] + ratings: Iterable[Rating], + user_ids: Container[UserId], + *, + awards_dict: dict[ImdbMovieId, list[models.Award]] | None = None, ) -> Iterable[RatingAggregate]: - aggr: dict[str, RatingAggregate] = {} + if awards_dict is None: + awards_dict = {} + + aggr: dict[ImdbMovieId, RatingAggregate] = {} for r in ratings: + awards = awards_dict.get(r.movie_imdb_id, []) mov = aggr.setdefault( r.movie_imdb_id, RatingAggregate( @@ -76,6 +89,7 @@ def aggregate_ratings( original_title=r.original_title, user_scores=[], year=r.release_year, + awards=[f"{a.category}:{a.position}" for a in awards], ), ) # XXX do we need this? why don't we just get the ratings we're supposed to aggregate? From dd39849b8de07a55fa9c5d912cc0ad3c87706837 Mon Sep 17 00:00:00 2001 From: ducklet Date: Sun, 19 May 2024 22:49:46 +0200 Subject: [PATCH 15/25] chore: typing --- unwind/db.py | 13 +++---- unwind/models.py | 80 +++++++++++++++++++++++++++----------------- unwind/types.py | 17 +++++++++- unwind/web.py | 4 +-- unwind/web_models.py | 25 ++++++-------- 5 files changed, 82 insertions(+), 57 deletions(-) diff --git a/unwind/db.py b/unwind/db.py index e416d8b..a8e23d8 100644 --- a/unwind/db.py +++ b/unwind/db.py @@ -28,7 +28,7 @@ from .models import ( ratings, utcnow, ) -from .types import ULID +from .types import ULID, ImdbMovieId, UserIdStr log = logging.getLogger(__name__) @@ -432,19 +432,16 @@ async def add_or_update_rating(conn: Connection, /, rating: Rating) -> bool: return False -type MovieImdbId = str - - async def get_awards( - conn: Connection, /, imdb_ids: list[MovieImdbId] -) -> dict[MovieImdbId, list[Award]]: + conn: Connection, /, imdb_ids: list[ImdbMovieId] +) -> dict[ImdbMovieId, list[Award]]: query = ( sa.select(Award, movies.c.imdb_id) .join(movies, awards.c.movie_id == movies.c.id) .where(movies.c.imdb_id.in_(imdb_ids)) ) rows = await fetch_all(conn, query) - awards_dict: dict[MovieImdbId, list[Award]] = {} + awards_dict: dict[ImdbMovieId, list[Award]] = {} for row in rows: awards_dict.setdefault(row.imdb_id, []).append( fromplain(Award, row._mapping, serialized=True) @@ -467,7 +464,7 @@ async def find_ratings( include_unrated: bool = False, yearcomp: tuple[Literal["<", "=", ">"], int] | None = None, limit_rows: int = 10, - user_ids: Iterable[str] = [], + user_ids: Iterable[UserIdStr] = [], ) -> Iterable[dict[str, Any]]: conditions = [] diff --git a/unwind/models.py b/unwind/models.py index 2d59cd0..f952686 100644 --- a/unwind/models.py +++ b/unwind/models.py @@ -10,6 +10,7 @@ from typing import ( Container, Literal, Mapping, + NewType, Protocol, Type, TypeAliasType, @@ -22,13 +23,21 @@ from typing import ( from sqlalchemy import Column, ForeignKey, Index, Integer, String, Table from sqlalchemy.orm import registry -from .types import ULID +from .types import ( + ULID, + AwardId, + GroupId, + ImdbMovieId, + JSONObject, + JSONScalar, + MovieId, + RatingId, + Score100, + UserId, + UserIdStr, +) from .utils import json_dump -type JSONScalar = int | float | str | None -type JSON = JSONScalar | list["JSON"] | dict[str, "JSON"] -type JSONObject = dict[str, JSON] - class Model(Protocol): __table__: ClassVar[Table] @@ -115,6 +124,19 @@ def _id[T](x: T) -> T: return x +def _unpack(type_: Any) -> Any: + """Return the wrapped type.""" + # Handle type aliases. + if isinstance(type_, TypeAliasType): + return _unpack(type_.__value__) + + # Handle newtypes. + if isinstance(type_, NewType): + return _unpack(type_.__supertype__) + + return type_ + + def asplain( o: object, *, filter_fields: Container[str] | None = None, serialize: bool = False ) -> dict[str, Any]: @@ -136,10 +158,7 @@ def asplain( if filter_fields is not None and f.name not in filter_fields: continue - target: Any = f.type - if isinstance(target, TypeAliasType): - # Support type aliases. - target = target.__value__ + target: Any = _unpack(f.type) # XXX this doesn't properly support any kind of nested types if (otype := optional_type(f.type)) is not None: @@ -147,6 +166,8 @@ def asplain( if (otype := get_origin(target)) is not None: target = otype + target = _unpack(target) + v = getattr(o, f.name) if is_optional(f.type) and v is None: d[f.name] = None @@ -188,10 +209,7 @@ def fromplain[T](cls: Type[T], d: Mapping, *, serialized: bool = False) -> T: dd: JSONObject = {} for f in fields(cls): - target: Any = f.type - if isinstance(target, TypeAliasType): - # Support type aliases. - target = target.__value__ + target: Any = _unpack(f.type) otype = optional_type(f.type) is_opt = otype is not None @@ -200,6 +218,8 @@ def fromplain[T](cls: Type[T], d: Mapping, *, serialized: bool = False) -> T: if (xtype := get_origin(target)) is not None: target = xtype + target = _unpack(target) + v = d[f.name] if is_opt and v is None: dd[f.name] = v @@ -225,10 +245,7 @@ def fromplain[T](cls: Type[T], d: Mapping, *, serialized: bool = False) -> T: def validate(o: object) -> None: for f in fields(o): - ftype = f.type - if isinstance(ftype, TypeAliasType): - # Support type aliases. - ftype = ftype.__value__ + ftype = _unpack(f.type) v = getattr(o, f.name) vtype = type(v) @@ -243,11 +260,12 @@ def validate(o: object) -> None: if is_union: # Support unioned types. utypes = get_args(ftype) + utypes = [_unpack(t) for t in utypes] if vtype in utypes: continue # Support generic types (set[str], list[int], etc.) - gtypes = [g for u in utypes if (g := get_origin(u)) is not None] + gtypes = [_unpack(g) for u in utypes if (g := get_origin(u)) is not None] if any(vtype is gtype for gtype in gtypes): continue @@ -337,15 +355,15 @@ class Movie: Column("updated", String, nullable=False), # datetime ) - id: ULID = field(default_factory=ULID) + id: MovieId = field(default_factory=ULID) title: str = None # canonical title (usually English) original_title: str | None = ( None # original title (usually transscribed to latin script) ) release_year: int = None # canonical release date media_type: str = None - imdb_id: str = None - imdb_score: int | None = None # range: [0,100] + imdb_id: ImdbMovieId = None + imdb_score: Score100 | None = None # range: [0,100] imdb_votes: int | None = None runtime: int | None = None # minutes genres: set[str] | None = None @@ -418,8 +436,8 @@ class User: Column("groups", String, nullable=False), # JSON array ) - id: ULID = field(default_factory=ULID) - imdb_id: str = None + id: UserId = field(default_factory=ULID) + imdb_id: ImdbMovieId = None name: str = None # canonical user name secret: str = None groups: list[UserGroup] = field(default_factory=list) @@ -456,15 +474,15 @@ class Rating: Column("finished", Integer), # bool ) - id: ULID = field(default_factory=ULID) + id: RatingId = field(default_factory=ULID) - movie_id: ULID = None + movie_id: MovieId = None movie: Relation[Movie] = None - user_id: ULID = None + user_id: UserId = None user: Relation[User] = None - score: int = None # range: [0,100] + score: Score100 = None # range: [0,100] rating_date: datetime = None favorite: bool | None = None finished: bool | None = None @@ -487,7 +505,7 @@ Index("ratings_index", ratings.c.movie_id, ratings.c.user_id, unique=True) class GroupUser(TypedDict): - id: str + id: UserIdStr name: str @@ -502,7 +520,7 @@ class Group: Column("users", String, nullable=False), # JSON array ) - id: ULID = field(default_factory=ULID) + id: GroupId = field(default_factory=ULID) name: str = None users: list[GroupUser] = field(default_factory=list) @@ -530,9 +548,9 @@ class Award: Column("updated", String, nullable=False), # datetime ) - id: ULID = field(default_factory=ULID) + id: AwardId = field(default_factory=ULID) - movie_id: ULID = None + movie_id: MovieId = None movie: Relation[Movie] = None category: AwardCategory = None diff --git a/unwind/types.py b/unwind/types.py index 94c0e00..76ce3e8 100644 --- a/unwind/types.py +++ b/unwind/types.py @@ -1,9 +1,13 @@ import re -from typing import cast +from typing import NewType, cast import ulid from ulid.hints import Buffer +type JSONScalar = int | float | str | None +type JSON = JSONScalar | list["JSON"] | dict[str, "JSON"] +type JSONObject = dict[str, JSON] + class ULID(ulid.ULID): """Extended ULID type. @@ -29,3 +33,14 @@ class ULID(ulid.ULID): buffer = cast(memoryview, ulid.new().memory) super().__init__(buffer) + + +AwardId = NewType("AwardId", ULID) +GroupId = NewType("GroupId", ULID) +ImdbMovieId = NewType("ImdbMovieId", str) +MovieId = NewType("MovieId", ULID) +MovieIdStr = NewType("MovieIdStr", str) +RatingId = NewType("RatingId", ULID) +Score100 = NewType("Score100", int) # [0, 100] +UserId = NewType("UserId", ULID) +UserIdStr = NewType("UserIdStr", str) diff --git a/unwind/web.py b/unwind/web.py index ee024e9..3f62a53 100644 --- a/unwind/web.py +++ b/unwind/web.py @@ -27,8 +27,8 @@ from starlette.routing import Mount, Route from . import config, db, imdb, imdb_import, web_models from .db import close_connection_pool, find_movies, find_ratings, open_connection_pool from .middleware.responsetime import ResponseTimeMiddleware -from .models import JSON, Access, Group, Movie, User, asplain -from .types import ULID +from .models import Access, Group, Movie, User, asplain +from .types import JSON, ULID from .utils import b64decode, b64encode, phc_compare, phc_scrypt log = logging.getLogger(__name__) diff --git a/unwind/web_models.py b/unwind/web_models.py index 0551ba3..42cb4dc 100644 --- a/unwind/web_models.py +++ b/unwind/web_models.py @@ -1,23 +1,22 @@ from dataclasses import dataclass from typing import Container, Iterable -from . import imdb, models +from . import imdb, models, types type URL = str -type Score100 = int # [0, 100] @dataclass class Rating: canonical_title: str - imdb_score: Score100 | None + imdb_score: types.Score100 | None imdb_votes: int | None media_type: str - movie_imdb_id: str + movie_imdb_id: types.ImdbMovieId original_title: str | None release_year: int - user_id: str | None - user_score: Score100 | None + user_id: types.UserIdStr | None + user_score: types.Score100 | None @classmethod def from_movie(cls, movie: models.Movie, *, rating: models.Rating | None = None): @@ -37,12 +36,12 @@ class Rating: @dataclass class RatingAggregate: canonical_title: str - imdb_score: Score100 | None + imdb_score: types.Score100 | None imdb_votes: int | None link: URL media_type: str original_title: str | None - user_scores: list[Score100] + user_scores: list[types.Score100] year: int awards: list[str] @@ -61,20 +60,16 @@ class RatingAggregate: ) -type ImdbMovieId = str -type UserId = str - - def aggregate_ratings( ratings: Iterable[Rating], - user_ids: Container[UserId], + user_ids: Container[types.UserIdStr], *, - awards_dict: dict[ImdbMovieId, list[models.Award]] | None = None, + awards_dict: dict[types.ImdbMovieId, list[models.Award]] | None = None, ) -> Iterable[RatingAggregate]: if awards_dict is None: awards_dict = {} - aggr: dict[ImdbMovieId, RatingAggregate] = {} + aggr: dict[types.ImdbMovieId, RatingAggregate] = {} for r in ratings: awards = awards_dict.get(r.movie_imdb_id, []) From 63f8a98dfab94dacc22b8206974c6468145048c1 Mon Sep 17 00:00:00 2001 From: ducklet Date: Mon, 20 May 2024 16:52:37 +0200 Subject: [PATCH 16/25] feat: run alembic patches at container start --- Dockerfile | 7 +++++-- entrypoint.sh | 4 ++++ 2 files changed, 9 insertions(+), 2 deletions(-) create mode 100755 entrypoint.sh diff --git a/Dockerfile b/Dockerfile index 66014c6..1571d75 100644 --- a/Dockerfile +++ b/Dockerfile @@ -18,15 +18,18 @@ RUN pip install --no-cache-dir --upgrade \ USER 10000:10001 -COPY run ./ +COPY alembic.ini entrypoint.sh pyproject.toml run ./ +COPY alembic ./alembic COPY scripts ./scripts COPY unwind ./unwind +RUN pip install --no-cache-dir --editable . + ENV UNWIND_DATA="/data" VOLUME $UNWIND_DATA ENV UNWIND_PORT=8097 EXPOSE $UNWIND_PORT -ENTRYPOINT ["/var/app/run"] +ENTRYPOINT ["/var/app/entrypoint.sh"] CMD ["server"] diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100755 index 0000000..7df7daa --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,4 @@ +#!/bin/sh -eu + +alembic upgrade head +exec ./run "$@" From f723459333c40d0b0024edd068ac2e734c6a36b2 Mon Sep 17 00:00:00 2001 From: ducklet Date: Mon, 20 May 2024 19:01:21 +0200 Subject: [PATCH 17/25] fix: open connection before using it --- unwind/web.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/unwind/web.py b/unwind/web.py index 3f62a53..cfd23cc 100644 --- a/unwind/web.py +++ b/unwind/web.py @@ -237,7 +237,8 @@ async def get_ratings_for_group(request: Request) -> JSONResponse: ratings = [web_models.Rating(**r) for r in rows] - awards = await db.get_awards(conn, imdb_ids=[r.movie_imdb_id for r in ratings]) + async with db.new_connection() as conn: + awards = await db.get_awards(conn, imdb_ids=[r.movie_imdb_id for r in ratings]) aggrs = web_models.aggregate_ratings(ratings, user_ids, awards_dict=awards) From 02a9621734380b14fe7f7732ee198ddfea347c87 Mon Sep 17 00:00:00 2001 From: ducklet Date: Sat, 25 May 2024 01:22:26 +0200 Subject: [PATCH 18/25] feat: add import script for Academy awards --- tests/test_web.py | 8 ++- unwind/cli/import_wikidata_oscars.py | 100 +++++++++++++++++++++++++++ unwind/cli/load_imdb_charts.py | 17 +---- unwind/db.py | 31 ++++++--- unwind/imdb.py | 37 +++++----- unwind/models.py | 10 +++ unwind/types.py | 6 +- unwind/web_models.py | 10 ++- 8 files changed, 170 insertions(+), 49 deletions(-) create mode 100644 unwind/cli/import_wikidata_oscars.py diff --git a/tests/test_web.py b/tests/test_web.py index 46cc28a..f9ddbd7 100644 --- a/tests/test_web.py +++ b/tests/test_web.py @@ -75,8 +75,10 @@ async def test_get_ratings_for_group_with_awards( award2 = models.Award( movie_id=movie2.id, category="imdb-top-250", details='{"position":99}' ) - await db.add(conn, award1) - await db.add(conn, award2) + award3 = models.Award( + movie_id=movie1.id, category="oscars", details='{"name":"Best Visual Effects"}' + ) + await db.add(conn, award1, award2, award3) rating = models.Rating( movie_id=movie1.id, user_id=user.id, score=66, rating_date=datetime.now(tz=UTC) @@ -92,7 +94,7 @@ async def test_get_ratings_for_group_with_awards( "original_title": movie1.original_title, "user_scores": [rating.score], "year": movie1.release_year, - "awards": ["imdb-top-250:23"], + "awards": ["imdb-top-250:23", "oscars:Best Visual Effects"], } resp = unauthorized_client.get(path) diff --git a/unwind/cli/import_wikidata_oscars.py b/unwind/cli/import_wikidata_oscars.py new file mode 100644 index 0000000..17a9918 --- /dev/null +++ b/unwind/cli/import_wikidata_oscars.py @@ -0,0 +1,100 @@ +import argparse +import json +import logging +from datetime import datetime +from pathlib import Path +from typing import Iterable + +from unwind import db, models, types + +log = logging.getLogger(__name__) + +name = "import-wikidata-oscars" +help = "Import Academy awards information from a Wikidata dump." + +# To generate the JSON file, run the following query +# at https://query.wikidata.org/ and export as (simpel) JSON: +""" +SELECT ?awardLabel ?filmLabel ?imdbId ?time WHERE { + ?award wdt:P31 wd:Q19020. + ?film wdt:P31 wd:Q11424; + p:P166 ?awardStat. + ?awardStat ps:P166 ?award. + OPTIONAL { + ?awardStat pq:P805 ?awardEdition. + ?awardEdition wdt:P585 ?time. + ?film wdt:P345 ?imdbId. + } + SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". } +} +ORDER BY DESC (?time) +""" + + +def add_args(cmd: argparse.ArgumentParser) -> None: + cmd.add_argument("--json-file", required=True, type=Path) + + +def load_awards(json_file: Path) -> Iterable[tuple[types.ImdbMovieId, models.Award]]: + with json_file.open() as fd: + data = json.load(fd) + + name_prefix = "Academy Award for " + special_names = { + "Special Achievement Academy Award": "Special Achievement", + "Academy Honorary Award": "Honorary", + } + for item in data: + name = item["awardLabel"] + if name in special_names: + name = special_names[name] + elif name.startswith(name_prefix): + name = name.removeprefix(name_prefix) + else: + raise ValueError(f"Award name is unexpected: {name!a}") + # award = models.Award(category="oscars",details={"name":name},created=created) + award = models.Award(category="oscars") + # award._details = {"name": name} + award.name = name + if (datestr := item.get("time")) is not None: + award.created = datetime.fromisoformat(datestr) + + if "imdbId" not in item: + log.warning("⚠️ IMDb ID missing for movie: %a", item["filmLabel"]) + else: + yield item["imdbId"], award + + +async def remove_all_oscars(conn: db.Connection) -> None: + stmt = models.awards.delete().where(models.awards.c.category == "oscars") + await conn.execute(stmt) + + +async def main(args: argparse.Namespace) -> None: + await db.open_connection_pool() + + json_file: Path = args.json_file + + awards = dict(load_awards(json_file)) + async with db.new_connection() as conn: + imdb_ids = list(awards) + available = await db.get_movie_ids(conn, imdb_ids) + if missing := set(imdb_ids).difference(available): + log.warning( + "⚠️ File (%a) contained %i unknown movies: %a", + str(json_file), + len(missing), + missing, + ) + + async with db.transaction() as conn: + await remove_all_oscars(conn) + + for imdb_id, unwind_id in available.items(): + award = awards[imdb_id] + award.movie_id = unwind_id + await db.add(conn, award) + + log.info(f"✨ Imported {len(available)} oscars.") + + await db.close_connection_pool() diff --git a/unwind/cli/load_imdb_charts.py b/unwind/cli/load_imdb_charts.py index 2b82774..3d6d7b5 100644 --- a/unwind/cli/load_imdb_charts.py +++ b/unwind/cli/load_imdb_charts.py @@ -2,9 +2,7 @@ import argparse import logging from typing import Callable -import sqlalchemy as sa - -from unwind import db, imdb, models, types, utils +from unwind import db, imdb, models log = logging.getLogger(__name__) @@ -23,15 +21,6 @@ def add_args(cmd: argparse.ArgumentParser) -> None: ) -async def get_movie_ids( - conn: db.Connection, imdb_ids: list[imdb.MovieId] -) -> dict[imdb.MovieId, types.ULID]: - c = models.movies.c - query = sa.select(c.imdb_id, c.id).where(c.imdb_id.in_(imdb_ids)) - rows = await db.fetch_all(conn, query) - return {row.imdb_id: types.ULID(row.id) for row in rows} - - async def remove_all_awards( conn: db.Connection, category: models.AwardCategory ) -> None: @@ -50,7 +39,7 @@ async def update_awards(conn: db.Connection, category: models.AwardCategory) -> load_imdb_ids = _award_handlers[category] imdb_ids = await load_imdb_ids() - available = await get_movie_ids(conn, imdb_ids) + available = await db.get_movie_ids(conn, imdb_ids) if missing := set(imdb_ids).difference(available): log.warning( "⚠️ Charts for category (%a) contained %i unknown movies: %a", @@ -68,8 +57,8 @@ async def update_awards(conn: db.Connection, category: models.AwardCategory) -> award = models.Award( movie_id=movie_id, category=category, - details=utils.json_dump({"position": pos}), ) + award.position = pos await db.add(conn, award) diff --git a/unwind/db.py b/unwind/db.py index a8e23d8..664a629 100644 --- a/unwind/db.py +++ b/unwind/db.py @@ -28,7 +28,7 @@ from .models import ( ratings, utcnow, ) -from .types import ULID, ImdbMovieId, UserIdStr +from .types import ULID, ImdbMovieId, MovieId, UserIdStr log = logging.getLogger(__name__) @@ -237,16 +237,17 @@ async def transacted( await conn.rollback() -async def add(conn: Connection, /, item: Model) -> None: - # Support late initializing - used for optimization. - if getattr(item, "_is_lazy", False): - assert hasattr(item, "_lazy_init") - item._lazy_init() # pyright: ignore[reportAttributeAccessIssue] +async def add(conn: Connection, /, *items: Model) -> None: + for item in items: + # Support late initializing - used for optimization. + if getattr(item, "_is_lazy", False): + assert hasattr(item, "_lazy_init") + item._lazy_init() # pyright: ignore[reportAttributeAccessIssue] - table: sa.Table = item.__table__ - values = asplain(item, serialize=True) - stmt = table.insert().values(values) - await conn.execute(stmt) + table: sa.Table = item.__table__ + values = asplain(item, serialize=True) + stmt = table.insert().values(values) + await conn.execute(stmt) async def fetch_all( @@ -449,6 +450,16 @@ async def get_awards( return awards_dict +async def get_movie_ids( + conn: Connection, imdb_ids: list[ImdbMovieId] +) -> dict[ImdbMovieId, MovieId]: + query = sa.select(movies.c.imdb_id, movies.c.id).where( + movies.c.imdb_id.in_(imdb_ids) + ) + rows = await fetch_all(conn, query) + return {row.imdb_id: MovieId(ULID(row.id)) for row in rows} + + def sql_escape(s: str, char: str = "#") -> str: return s.replace(char, 2 * char).replace("%", f"{char}%").replace("_", f"{char}_") diff --git a/unwind/imdb.py b/unwind/imdb.py index 0f46c24..1685ad3 100644 --- a/unwind/imdb.py +++ b/unwind/imdb.py @@ -4,7 +4,7 @@ import re from collections import namedtuple from dataclasses import dataclass, field from datetime import datetime -from typing import AsyncIterable, NewType +from typing import AsyncIterable from urllib.parse import urljoin import bs4 @@ -12,14 +12,11 @@ import bs4 from . import db from .models import Movie, Rating, User from .request import adownload, asession, asoup_from_url, cache_path +from .types import ImdbMovieId, ImdbRating, ImdbUserId, Score100 from .utils import json_dump log = logging.getLogger(__name__) -ImdbRating = NewType("ImdbRating", float) # Value range: [1.0, 10.0] -UnwindScore = NewType("UnwindScore", int) # Value range: [0, 100] -MovieId = NewType("MovieId", str) # Pattern: ttXXXXXXXX -UserId = NewType("UserId", str) # Pattern: urXXXXXXXX # div#ratings-container # div.lister-item.mode-detail @@ -75,7 +72,7 @@ def movie_url(imdb_id: str): return f"https://www.imdb.com/title/{imdb_id}/" -def imdb_rating_from_score(score: UnwindScore) -> ImdbRating: +def imdb_rating_from_score(score: Score100) -> ImdbRating: """Return the IMDb rating from an Unwind Movie score.""" assert 0 <= score <= 100 rating = round(score * 9 / 100 + 1, 1) @@ -83,7 +80,7 @@ def imdb_rating_from_score(score: UnwindScore) -> ImdbRating: return ImdbRating(rating) -def score_from_imdb_rating(rating: ImdbRating | int) -> UnwindScore: +def score_from_imdb_rating(rating: ImdbRating | int) -> Score100: """Return the Unwind Movie score for an IMDb rating.""" # Scale IMDb's 10 point rating to our score of [0, 100]. # There's a pitfall here! @@ -92,7 +89,7 @@ def score_from_imdb_rating(rating: ImdbRating | int) -> UnwindScore: assert 1.0 <= rating <= 10.0 score = round(100 * (rating - 1) / 9) assert 0 <= score <= 100 - return UnwindScore(score) + return Score100(score) # find_name: e.g. "Your Mom's Ratings" @@ -237,11 +234,11 @@ _ForgedRequest = namedtuple("_ForgedRequest", "url headers") class _RatingsPage: ratings: list[Rating] = field(default_factory=list) next_page_url: str | None = None - imdb_user_id: UserId | None = None + imdb_user_id: ImdbUserId | None = None imdb_user_name: str | None = None -async def _load_ratings_page(url: str, user_id: UserId) -> _RatingsPage: +async def _load_ratings_page(url: str, user_id: ImdbUserId) -> _RatingsPage: """Dispatch to handlers for different ratings page versions.""" soup = await asoup_from_url(url) @@ -255,7 +252,7 @@ async def _load_ratings_page(url: str, user_id: UserId) -> _RatingsPage: async def _load_ratings_page_2024( - user_id: UserId, url: str, soup: bs4.BeautifulSoup + user_id: ImdbUserId, url: str, soup: bs4.BeautifulSoup ) -> _RatingsPage: """Handle the ratings page from 2024.""" page = _RatingsPage() @@ -356,7 +353,9 @@ async def _load_ratings_page_legacy(url: str, soup: bs4.BeautifulSoup) -> _Ratin return page -async def load_and_store_ratings(user_id: UserId) -> AsyncIterable[tuple[Rating, bool]]: +async def load_and_store_ratings( + user_id: ImdbUserId, +) -> AsyncIterable[tuple[Rating, bool]]: """Load user ratings from imdb.com and store them in our database. All loaded ratings are yielded together with the information whether each rating @@ -388,7 +387,7 @@ async def load_and_store_ratings(user_id: UserId) -> AsyncIterable[tuple[Rating, yield rating, is_updated -async def load_ratings(user_id: UserId) -> AsyncIterable[Rating]: +async def load_ratings(user_id: ImdbUserId) -> AsyncIterable[Rating]: """Return all ratings for the given user from imdb.com.""" next_url = user_ratings_url(user_id) @@ -399,7 +398,7 @@ async def load_ratings(user_id: UserId) -> AsyncIterable[Rating]: yield rating -async def _ids_from_list_html(url: str) -> AsyncIterable[MovieId]: +async def _ids_from_list_html(url: str) -> AsyncIterable[ImdbMovieId]: """Return all IMDb movie IDs (`tt*`) from the given URL.""" # document.querySelectorAll('li.ipc-metadata-list-summary-item a.ipc-title-link-wrapper') # .href: '/title/tt1213644/?ref_=chtbtm_t_1' @@ -412,7 +411,7 @@ async def _ids_from_list_html(url: str) -> AsyncIterable[MovieId]: yield match_["id"] -async def load_most_popular_100() -> list[MovieId]: +async def load_most_popular_100() -> list[ImdbMovieId]: """Return the IMDb's top 100 most popular movies. IMDb Charts: Most Popular Movies @@ -425,7 +424,7 @@ async def load_most_popular_100() -> list[MovieId]: return ids -async def load_bottom_100() -> list[MovieId]: +async def load_bottom_100() -> list[ImdbMovieId]: """Return the IMDb's bottom 100 lowest rated movies. IMDb Charts: Lowest Rated Movies @@ -438,7 +437,7 @@ async def load_bottom_100() -> list[MovieId]: return ids -async def load_top_250() -> list[MovieId]: +async def load_top_250() -> list[ImdbMovieId]: """Return the IMDb's top 250 highest rated movies. IMDb Charts: IMDb Top 250 Movies @@ -483,13 +482,13 @@ async def load_top_250() -> list[MovieId]: @dataclass class _UserMovieRating: - movie_id: MovieId + movie_id: ImdbMovieId rating_date: datetime imdb_rating: ImdbRating async def _load_user_movie_ratings( - user_id: UserId, movie_ids: list[MovieId] + user_id: ImdbUserId, movie_ids: list[ImdbMovieId] ) -> AsyncIterable[_UserMovieRating]: qgl_api_url = "https://api.graphql.imdb.com/" headers = { diff --git a/unwind/models.py b/unwind/models.py index f952686..82837fc 100644 --- a/unwind/models.py +++ b/unwind/models.py @@ -577,5 +577,15 @@ class Award: details["position"] = position self._details = details + @property + def name(self) -> str: + return self._details["name"] + + @name.setter + def name(self, name: str): + details = self._details + details["name"] = name + self._details = details + awards = Award.__table__ diff --git a/unwind/types.py b/unwind/types.py index 76ce3e8..e035f13 100644 --- a/unwind/types.py +++ b/unwind/types.py @@ -37,10 +37,12 @@ class ULID(ulid.ULID): AwardId = NewType("AwardId", ULID) GroupId = NewType("GroupId", ULID) -ImdbMovieId = NewType("ImdbMovieId", str) +ImdbMovieId = NewType("ImdbMovieId", str) # Pattern: ttXXXXXXXX +ImdbRating = NewType("ImdbRating", float) # Value range: [1.0, 10.0] +ImdbUserId = NewType("ImdbUserId", str) # Pattern: urXXXXXXXX MovieId = NewType("MovieId", ULID) MovieIdStr = NewType("MovieIdStr", str) RatingId = NewType("RatingId", ULID) -Score100 = NewType("Score100", int) # [0, 100] +Score100 = NewType("Score100", int) # Value range: [0, 100] UserId = NewType("UserId", ULID) UserIdStr = NewType("UserIdStr", str) diff --git a/unwind/web_models.py b/unwind/web_models.py index 42cb4dc..aba0d82 100644 --- a/unwind/web_models.py +++ b/unwind/web_models.py @@ -60,6 +60,14 @@ class RatingAggregate: ) +def _serialize_award(award: models.Award) -> str: + if award.category == "oscars": + return f"{award.category}:{award.name}" + elif award.category.startswith("imdb-"): + return f"{award.category}:{award.position}" + raise RuntimeError(f"Unsupported category: {award.category}") + + def aggregate_ratings( ratings: Iterable[Rating], user_ids: Container[types.UserIdStr], @@ -84,7 +92,7 @@ def aggregate_ratings( original_title=r.original_title, user_scores=[], year=r.release_year, - awards=[f"{a.category}:{a.position}" for a in awards], + awards=sorted(_serialize_award(a) for a in awards), ), ) # XXX do we need this? why don't we just get the ratings we're supposed to aggregate? From 0a7933bbba5f0d9744e2a9807c12e8519ecdfa40 Mon Sep 17 00:00:00 2001 From: ducklet Date: Sat, 25 May 2024 18:23:13 +0200 Subject: [PATCH 19/25] fix: loading multiple oscars per movie --- tests/test_web.py | 11 +++++++++-- unwind/cli/import_wikidata_oscars.py | 10 ++++++---- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/tests/test_web.py b/tests/test_web.py index f9ddbd7..05affd7 100644 --- a/tests/test_web.py +++ b/tests/test_web.py @@ -78,7 +78,10 @@ async def test_get_ratings_for_group_with_awards( award3 = models.Award( movie_id=movie1.id, category="oscars", details='{"name":"Best Visual Effects"}' ) - await db.add(conn, award1, award2, award3) + award4 = models.Award( + movie_id=movie1.id, category="oscars", details='{"name":"Best Picture"}' + ) + await db.add(conn, award1, award2, award3, award4) rating = models.Rating( movie_id=movie1.id, user_id=user.id, score=66, rating_date=datetime.now(tz=UTC) @@ -94,7 +97,11 @@ async def test_get_ratings_for_group_with_awards( "original_title": movie1.original_title, "user_scores": [rating.score], "year": movie1.release_year, - "awards": ["imdb-top-250:23", "oscars:Best Visual Effects"], + "awards": [ + "imdb-top-250:23", + "oscars:Best Picture", + "oscars:Best Visual Effects", + ], } resp = unauthorized_client.get(path) diff --git a/unwind/cli/import_wikidata_oscars.py b/unwind/cli/import_wikidata_oscars.py index 17a9918..cafc341 100644 --- a/unwind/cli/import_wikidata_oscars.py +++ b/unwind/cli/import_wikidata_oscars.py @@ -75,7 +75,9 @@ async def main(args: argparse.Namespace) -> None: json_file: Path = args.json_file - awards = dict(load_awards(json_file)) + awards: dict[types.ImdbMovieId, list[models.Award]] = {} + for imdb_id, award in load_awards(json_file): + awards.setdefault(imdb_id, []).append(award) async with db.new_connection() as conn: imdb_ids = list(awards) available = await db.get_movie_ids(conn, imdb_ids) @@ -91,9 +93,9 @@ async def main(args: argparse.Namespace) -> None: await remove_all_oscars(conn) for imdb_id, unwind_id in available.items(): - award = awards[imdb_id] - award.movie_id = unwind_id - await db.add(conn, award) + for award in awards[imdb_id]: + award.movie_id = unwind_id + await db.add(conn, award) log.info(f"✨ Imported {len(available)} oscars.") From aaaf66c715bc56ffcce81f84125ccc631b7744b3 Mon Sep 17 00:00:00 2001 From: ducklet Date: Sun, 14 Jul 2024 15:47:24 +0200 Subject: [PATCH 20/25] run update --- poetry.lock | 330 +++++++------- pyproject.toml | 2 +- unwind-ui/package-lock.json | 843 ++++++++++++++++-------------------- 3 files changed, 533 insertions(+), 642 deletions(-) diff --git a/poetry.lock b/poetry.lock index d01be12..b2aa260 100644 --- a/poetry.lock +++ b/poetry.lock @@ -20,13 +20,13 @@ docs = ["sphinx (==7.2.6)", "sphinx-mdinclude (==0.5.3)"] [[package]] name = "alembic" -version = "1.13.1" +version = "1.13.2" description = "A database migration tool for SQLAlchemy." optional = false python-versions = ">=3.8" files = [ - {file = "alembic-1.13.1-py3-none-any.whl", hash = "sha256:2edcc97bed0bd3272611ce3a98d98279e9c209e7186e43e75bbb1b2bdfdbcc43"}, - {file = "alembic-1.13.1.tar.gz", hash = "sha256:4932c8558bf68f2ee92b9bbcb8218671c627064d5b08939437af6d77dc05e595"}, + {file = "alembic-1.13.2-py3-none-any.whl", hash = "sha256:6b8733129a6224a9a711e17c99b08462dbf7cc9670ba8f2e2ae9af860ceb1953"}, + {file = "alembic-1.13.2.tar.gz", hash = "sha256:1ff0ae32975f4fd96028c39ed9bb3c867fe3af956bd7bb37343b54c9fe7445ef"}, ] [package.dependencies] @@ -39,13 +39,13 @@ tz = ["backports.zoneinfo"] [[package]] name = "anyio" -version = "4.3.0" +version = "4.4.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.8" files = [ - {file = "anyio-4.3.0-py3-none-any.whl", hash = "sha256:048e05d0f6caeed70d731f3db756d35dcc1f35747c8c403364a8332c630441b8"}, - {file = "anyio-4.3.0.tar.gz", hash = "sha256:f75253795a87df48568485fd18cdd2a3fa5c4f7c5be8e5e36637733fce06fed6"}, + {file = "anyio-4.4.0-py3-none-any.whl", hash = "sha256:c1b2d8f46a8a812513012e1107cb0e68c17159a7a594208005a57dc776e1bdc7"}, + {file = "anyio-4.4.0.tar.gz", hash = "sha256:5aadc6a1bbb7cdb0bede386cac5e2940f5e2ff3aa20277e991cf028e0585ce94"}, ] [package.dependencies] @@ -80,13 +80,13 @@ lxml = ["lxml"] [[package]] name = "certifi" -version = "2024.2.2" +version = "2024.7.4" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"}, - {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"}, + {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, + {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, ] [[package]] @@ -116,63 +116,63 @@ files = [ [[package]] name = "coverage" -version = "7.5.1" +version = "7.6.0" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.8" files = [ - {file = "coverage-7.5.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c0884920835a033b78d1c73b6d3bbcda8161a900f38a488829a83982925f6c2e"}, - {file = "coverage-7.5.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:39afcd3d4339329c5f58de48a52f6e4e50f6578dd6099961cf22228feb25f38f"}, - {file = "coverage-7.5.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a7b0ceee8147444347da6a66be737c9d78f3353b0681715b668b72e79203e4a"}, - {file = "coverage-7.5.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a9ca3f2fae0088c3c71d743d85404cec8df9be818a005ea065495bedc33da35"}, - {file = "coverage-7.5.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fd215c0c7d7aab005221608a3c2b46f58c0285a819565887ee0b718c052aa4e"}, - {file = "coverage-7.5.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4bf0655ab60d754491004a5efd7f9cccefcc1081a74c9ef2da4735d6ee4a6223"}, - {file = "coverage-7.5.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:61c4bf1ba021817de12b813338c9be9f0ad5b1e781b9b340a6d29fc13e7c1b5e"}, - {file = "coverage-7.5.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:db66fc317a046556a96b453a58eced5024af4582a8dbdc0c23ca4dbc0d5b3146"}, - {file = "coverage-7.5.1-cp310-cp310-win32.whl", hash = "sha256:b016ea6b959d3b9556cb401c55a37547135a587db0115635a443b2ce8f1c7228"}, - {file = "coverage-7.5.1-cp310-cp310-win_amd64.whl", hash = "sha256:df4e745a81c110e7446b1cc8131bf986157770fa405fe90e15e850aaf7619bc8"}, - {file = "coverage-7.5.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:796a79f63eca8814ca3317a1ea443645c9ff0d18b188de470ed7ccd45ae79428"}, - {file = "coverage-7.5.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4fc84a37bfd98db31beae3c2748811a3fa72bf2007ff7902f68746d9757f3746"}, - {file = "coverage-7.5.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6175d1a0559986c6ee3f7fccfc4a90ecd12ba0a383dcc2da30c2b9918d67d8a3"}, - {file = "coverage-7.5.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1fc81d5878cd6274ce971e0a3a18a8803c3fe25457165314271cf78e3aae3aa2"}, - {file = "coverage-7.5.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:556cf1a7cbc8028cb60e1ff0be806be2eded2daf8129b8811c63e2b9a6c43bca"}, - {file = "coverage-7.5.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9981706d300c18d8b220995ad22627647be11a4276721c10911e0e9fa44c83e8"}, - {file = "coverage-7.5.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:d7fed867ee50edf1a0b4a11e8e5d0895150e572af1cd6d315d557758bfa9c057"}, - {file = "coverage-7.5.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ef48e2707fb320c8f139424a596f5b69955a85b178f15af261bab871873bb987"}, - {file = "coverage-7.5.1-cp311-cp311-win32.whl", hash = "sha256:9314d5678dcc665330df5b69c1e726a0e49b27df0461c08ca12674bcc19ef136"}, - {file = "coverage-7.5.1-cp311-cp311-win_amd64.whl", hash = "sha256:5fa567e99765fe98f4e7d7394ce623e794d7cabb170f2ca2ac5a4174437e90dd"}, - {file = "coverage-7.5.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b6cf3764c030e5338e7f61f95bd21147963cf6aa16e09d2f74f1fa52013c1206"}, - {file = "coverage-7.5.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2ec92012fefebee89a6b9c79bc39051a6cb3891d562b9270ab10ecfdadbc0c34"}, - {file = "coverage-7.5.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:16db7f26000a07efcf6aea00316f6ac57e7d9a96501e990a36f40c965ec7a95d"}, - {file = "coverage-7.5.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:beccf7b8a10b09c4ae543582c1319c6df47d78fd732f854ac68d518ee1fb97fa"}, - {file = "coverage-7.5.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8748731ad392d736cc9ccac03c9845b13bb07d020a33423fa5b3a36521ac6e4e"}, - {file = "coverage-7.5.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7352b9161b33fd0b643ccd1f21f3a3908daaddf414f1c6cb9d3a2fd618bf2572"}, - {file = "coverage-7.5.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:7a588d39e0925f6a2bff87154752481273cdb1736270642aeb3635cb9b4cad07"}, - {file = "coverage-7.5.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:68f962d9b72ce69ea8621f57551b2fa9c70509af757ee3b8105d4f51b92b41a7"}, - {file = "coverage-7.5.1-cp312-cp312-win32.whl", hash = "sha256:f152cbf5b88aaeb836127d920dd0f5e7edff5a66f10c079157306c4343d86c19"}, - {file = "coverage-7.5.1-cp312-cp312-win_amd64.whl", hash = "sha256:5a5740d1fb60ddf268a3811bcd353de34eb56dc24e8f52a7f05ee513b2d4f596"}, - {file = "coverage-7.5.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e2213def81a50519d7cc56ed643c9e93e0247f5bbe0d1247d15fa520814a7cd7"}, - {file = "coverage-7.5.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5037f8fcc2a95b1f0e80585bd9d1ec31068a9bcb157d9750a172836e98bc7a90"}, - {file = "coverage-7.5.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c3721c2c9e4c4953a41a26c14f4cef64330392a6d2d675c8b1db3b645e31f0e"}, - {file = "coverage-7.5.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca498687ca46a62ae590253fba634a1fe9836bc56f626852fb2720f334c9e4e5"}, - {file = "coverage-7.5.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0cdcbc320b14c3e5877ee79e649677cb7d89ef588852e9583e6b24c2e5072661"}, - {file = "coverage-7.5.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:57e0204b5b745594e5bc14b9b50006da722827f0b8c776949f1135677e88d0b8"}, - {file = "coverage-7.5.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8fe7502616b67b234482c3ce276ff26f39ffe88adca2acf0261df4b8454668b4"}, - {file = "coverage-7.5.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:9e78295f4144f9dacfed4f92935fbe1780021247c2fabf73a819b17f0ccfff8d"}, - {file = "coverage-7.5.1-cp38-cp38-win32.whl", hash = "sha256:1434e088b41594baa71188a17533083eabf5609e8e72f16ce8c186001e6b8c41"}, - {file = "coverage-7.5.1-cp38-cp38-win_amd64.whl", hash = "sha256:0646599e9b139988b63704d704af8e8df7fa4cbc4a1f33df69d97f36cb0a38de"}, - {file = "coverage-7.5.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4cc37def103a2725bc672f84bd939a6fe4522310503207aae4d56351644682f1"}, - {file = "coverage-7.5.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fc0b4d8bfeabd25ea75e94632f5b6e047eef8adaed0c2161ada1e922e7f7cece"}, - {file = "coverage-7.5.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d0a0f5e06881ecedfe6f3dd2f56dcb057b6dbeb3327fd32d4b12854df36bf26"}, - {file = "coverage-7.5.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9735317685ba6ec7e3754798c8871c2f49aa5e687cc794a0b1d284b2389d1bd5"}, - {file = "coverage-7.5.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d21918e9ef11edf36764b93101e2ae8cc82aa5efdc7c5a4e9c6c35a48496d601"}, - {file = "coverage-7.5.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c3e757949f268364b96ca894b4c342b41dc6f8f8b66c37878aacef5930db61be"}, - {file = "coverage-7.5.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:79afb6197e2f7f60c4824dd4b2d4c2ec5801ceb6ba9ce5d2c3080e5660d51a4f"}, - {file = "coverage-7.5.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d1d0d98d95dd18fe29dc66808e1accf59f037d5716f86a501fc0256455219668"}, - {file = "coverage-7.5.1-cp39-cp39-win32.whl", hash = "sha256:1cc0fe9b0b3a8364093c53b0b4c0c2dd4bb23acbec4c9240b5f284095ccf7981"}, - {file = "coverage-7.5.1-cp39-cp39-win_amd64.whl", hash = "sha256:dde0070c40ea8bb3641e811c1cfbf18e265d024deff6de52c5950677a8fb1e0f"}, - {file = "coverage-7.5.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:6537e7c10cc47c595828b8a8be04c72144725c383c4702703ff4e42e44577312"}, - {file = "coverage-7.5.1.tar.gz", hash = "sha256:54de9ef3a9da981f7af93eafde4ede199e0846cd819eb27c88e2b712aae9708c"}, + {file = "coverage-7.6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dff044f661f59dace805eedb4a7404c573b6ff0cdba4a524141bc63d7be5c7fd"}, + {file = "coverage-7.6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a8659fd33ee9e6ca03950cfdcdf271d645cf681609153f218826dd9805ab585c"}, + {file = "coverage-7.6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7792f0ab20df8071d669d929c75c97fecfa6bcab82c10ee4adb91c7a54055463"}, + {file = "coverage-7.6.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4b3cd1ca7cd73d229487fa5caca9e4bc1f0bca96526b922d61053ea751fe791"}, + {file = "coverage-7.6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7e128f85c0b419907d1f38e616c4f1e9f1d1b37a7949f44df9a73d5da5cd53c"}, + {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a94925102c89247530ae1dab7dc02c690942566f22e189cbd53579b0693c0783"}, + {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:dcd070b5b585b50e6617e8972f3fbbee786afca71b1936ac06257f7e178f00f6"}, + {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d50a252b23b9b4dfeefc1f663c568a221092cbaded20a05a11665d0dbec9b8fb"}, + {file = "coverage-7.6.0-cp310-cp310-win32.whl", hash = "sha256:0e7b27d04131c46e6894f23a4ae186a6a2207209a05df5b6ad4caee6d54a222c"}, + {file = "coverage-7.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:54dece71673b3187c86226c3ca793c5f891f9fc3d8aa183f2e3653da18566169"}, + {file = "coverage-7.6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c7b525ab52ce18c57ae232ba6f7010297a87ced82a2383b1afd238849c1ff933"}, + {file = "coverage-7.6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bea27c4269234e06f621f3fac3925f56ff34bc14521484b8f66a580aacc2e7d"}, + {file = "coverage-7.6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed8d1d1821ba5fc88d4a4f45387b65de52382fa3ef1f0115a4f7a20cdfab0e94"}, + {file = "coverage-7.6.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01c322ef2bbe15057bc4bf132b525b7e3f7206f071799eb8aa6ad1940bcf5fb1"}, + {file = "coverage-7.6.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03cafe82c1b32b770a29fd6de923625ccac3185a54a5e66606da26d105f37dac"}, + {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0d1b923fc4a40c5832be4f35a5dab0e5ff89cddf83bb4174499e02ea089daf57"}, + {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4b03741e70fb811d1a9a1d75355cf391f274ed85847f4b78e35459899f57af4d"}, + {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a73d18625f6a8a1cbb11eadc1d03929f9510f4131879288e3f7922097a429f63"}, + {file = "coverage-7.6.0-cp311-cp311-win32.whl", hash = "sha256:65fa405b837060db569a61ec368b74688f429b32fa47a8929a7a2f9b47183713"}, + {file = "coverage-7.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:6379688fb4cfa921ae349c76eb1a9ab26b65f32b03d46bb0eed841fd4cb6afb1"}, + {file = "coverage-7.6.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f7db0b6ae1f96ae41afe626095149ecd1b212b424626175a6633c2999eaad45b"}, + {file = "coverage-7.6.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bbdf9a72403110a3bdae77948b8011f644571311c2fb35ee15f0f10a8fc082e8"}, + {file = "coverage-7.6.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cc44bf0315268e253bf563f3560e6c004efe38f76db03a1558274a6e04bf5d5"}, + {file = "coverage-7.6.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da8549d17489cd52f85a9829d0e1d91059359b3c54a26f28bec2c5d369524807"}, + {file = "coverage-7.6.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0086cd4fc71b7d485ac93ca4239c8f75732c2ae3ba83f6be1c9be59d9e2c6382"}, + {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1fad32ee9b27350687035cb5fdf9145bc9cf0a094a9577d43e909948ebcfa27b"}, + {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:044a0985a4f25b335882b0966625270a8d9db3d3409ddc49a4eb00b0ef5e8cee"}, + {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:76d5f82213aa78098b9b964ea89de4617e70e0d43e97900c2778a50856dac605"}, + {file = "coverage-7.6.0-cp312-cp312-win32.whl", hash = "sha256:3c59105f8d58ce500f348c5b56163a4113a440dad6daa2294b5052a10db866da"}, + {file = "coverage-7.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:ca5d79cfdae420a1d52bf177de4bc2289c321d6c961ae321503b2ca59c17ae67"}, + {file = "coverage-7.6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d39bd10f0ae453554798b125d2f39884290c480f56e8a02ba7a6ed552005243b"}, + {file = "coverage-7.6.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:beb08e8508e53a568811016e59f3234d29c2583f6b6e28572f0954a6b4f7e03d"}, + {file = "coverage-7.6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2e16f4cd2bc4d88ba30ca2d3bbf2f21f00f382cf4e1ce3b1ddc96c634bc48ca"}, + {file = "coverage-7.6.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6616d1c9bf1e3faea78711ee42a8b972367d82ceae233ec0ac61cc7fec09fa6b"}, + {file = "coverage-7.6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad4567d6c334c46046d1c4c20024de2a1c3abc626817ae21ae3da600f5779b44"}, + {file = "coverage-7.6.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d17c6a415d68cfe1091d3296ba5749d3d8696e42c37fca5d4860c5bf7b729f03"}, + {file = "coverage-7.6.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:9146579352d7b5f6412735d0f203bbd8d00113a680b66565e205bc605ef81bc6"}, + {file = "coverage-7.6.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:cdab02a0a941af190df8782aafc591ef3ad08824f97850b015c8c6a8b3877b0b"}, + {file = "coverage-7.6.0-cp38-cp38-win32.whl", hash = "sha256:df423f351b162a702c053d5dddc0fc0ef9a9e27ea3f449781ace5f906b664428"}, + {file = "coverage-7.6.0-cp38-cp38-win_amd64.whl", hash = "sha256:f2501d60d7497fd55e391f423f965bbe9e650e9ffc3c627d5f0ac516026000b8"}, + {file = "coverage-7.6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7221f9ac9dad9492cecab6f676b3eaf9185141539d5c9689d13fd6b0d7de840c"}, + {file = "coverage-7.6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ddaaa91bfc4477d2871442bbf30a125e8fe6b05da8a0015507bfbf4718228ab2"}, + {file = "coverage-7.6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4cbe651f3904e28f3a55d6f371203049034b4ddbce65a54527a3f189ca3b390"}, + {file = "coverage-7.6.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:831b476d79408ab6ccfadaaf199906c833f02fdb32c9ab907b1d4aa0713cfa3b"}, + {file = "coverage-7.6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46c3d091059ad0b9c59d1034de74a7f36dcfa7f6d3bde782c49deb42438f2450"}, + {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:4d5fae0a22dc86259dee66f2cc6c1d3e490c4a1214d7daa2a93d07491c5c04b6"}, + {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:07ed352205574aad067482e53dd606926afebcb5590653121063fbf4e2175166"}, + {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:49c76cdfa13015c4560702574bad67f0e15ca5a2872c6a125f6327ead2b731dd"}, + {file = "coverage-7.6.0-cp39-cp39-win32.whl", hash = "sha256:482855914928c8175735a2a59c8dc5806cf7d8f032e4820d52e845d1f731dca2"}, + {file = "coverage-7.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:543ef9179bc55edfd895154a51792b01c017c87af0ebaae092720152e19e42ca"}, + {file = "coverage-7.6.0-pp38.pp39.pp310-none-any.whl", hash = "sha256:6fe885135c8a479d3e37a7aae61cbd3a0fb2deccb4dda3c25f92a49189f766d6"}, + {file = "coverage-7.6.0.tar.gz", hash = "sha256:289cc803fa1dc901f84701ac10c9ee873619320f2f9aff38794db4a4a0268d51"}, ] [package.extras] @@ -455,27 +455,24 @@ files = [ [[package]] name = "nodeenv" -version = "1.8.0" +version = "1.9.1" description = "Node.js virtual environment builder" optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ - {file = "nodeenv-1.8.0-py2.py3-none-any.whl", hash = "sha256:df865724bb3c3adc86b3876fa209771517b0cfe596beff01a92700e0e8be4cec"}, - {file = "nodeenv-1.8.0.tar.gz", hash = "sha256:d51e0c37e64fbf47d017feac3145cdbb58836d7eee8c6f6d3b6880c5456227d2"}, + {file = "nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9"}, + {file = "nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f"}, ] -[package.dependencies] -setuptools = "*" - [[package]] name = "packaging" -version = "24.0" +version = "24.1" description = "Core utilities for Python packages" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"}, - {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"}, + {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, + {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, ] [[package]] @@ -495,13 +492,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "pyright" -version = "1.1.362" +version = "1.1.371" description = "Command line wrapper for pyright" optional = false python-versions = ">=3.7" files = [ - {file = "pyright-1.1.362-py3-none-any.whl", hash = "sha256:969957cff45154d8a45a4ab1dae5bdc8223d8bd3c64654fa608ab3194dfff319"}, - {file = "pyright-1.1.362.tar.gz", hash = "sha256:6a477e448d4a07a6a0eab58b2a15a1bbed031eb3169fa809edee79cca168d83a"}, + {file = "pyright-1.1.371-py3-none-any.whl", hash = "sha256:cce52e42ff73943243e7e5e24f2a59dee81b97d99f4e3cf97370b27e8a1858cd"}, + {file = "pyright-1.1.371.tar.gz", hash = "sha256:777b508b92dda2db476214c400ce043aad8d8f3dd0e10d284c96e79f298308b5"}, ] [package.dependencies] @@ -513,13 +510,13 @@ dev = ["twine (>=3.4.1)"] [[package]] name = "pytest" -version = "8.2.0" +version = "8.2.2" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-8.2.0-py3-none-any.whl", hash = "sha256:1733f0620f6cda4095bbf0d9ff8022486e91892245bb9e7d5542c018f612f233"}, - {file = "pytest-8.2.0.tar.gz", hash = "sha256:d507d4482197eac0ba2bae2e9babf0672eb333017bcedaa5fb1a3d42c1174b3f"}, + {file = "pytest-8.2.2-py3-none-any.whl", hash = "sha256:c434598117762e2bd304e526244f67bf66bbd7b5d6cf22138be51ff661980343"}, + {file = "pytest-8.2.2.tar.gz", hash = "sha256:de4bb8104e201939ccdc688b27a89a7be2079b22e2bd2b07f806b6ba71117977"}, ] [package.dependencies] @@ -533,13 +530,13 @@ dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments [[package]] name = "pytest-asyncio" -version = "0.23.6" +version = "0.23.7" description = "Pytest support for asyncio" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-asyncio-0.23.6.tar.gz", hash = "sha256:ffe523a89c1c222598c76856e76852b787504ddb72dd5d9b6617ffa8aa2cde5f"}, - {file = "pytest_asyncio-0.23.6-py3-none-any.whl", hash = "sha256:68516fdd1018ac57b846c9846b954f0393b26f094764a28c955eabb0536a4e8a"}, + {file = "pytest_asyncio-0.23.7-py3-none-any.whl", hash = "sha256:009b48127fbe44518a547bddd25611551b0e43ccdbf1e67d12479f569832c20b"}, + {file = "pytest_asyncio-0.23.7.tar.gz", hash = "sha256:5f5c72948f4c49e7db4f29f2521d4031f1c27f86e57b046126654083d4770268"}, ] [package.dependencies] @@ -569,46 +566,31 @@ testing = ["fields", "hunter", "process-tests", "pytest-xdist", "virtualenv"] [[package]] name = "ruff" -version = "0.4.3" +version = "0.5.1" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.4.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b70800c290f14ae6fcbb41bbe201cf62dfca024d124a1f373e76371a007454ce"}, - {file = "ruff-0.4.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:08a0d6a22918ab2552ace96adeaca308833873a4d7d1d587bb1d37bae8728eb3"}, - {file = "ruff-0.4.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eba1f14df3c758dd7de5b55fbae7e1c8af238597961e5fb628f3de446c3c40c5"}, - {file = "ruff-0.4.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:819fb06d535cc76dfddbfe8d3068ff602ddeb40e3eacbc90e0d1272bb8d97113"}, - {file = "ruff-0.4.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfc9e955e6dc6359eb6f82ea150c4f4e82b660e5b58d9a20a0e42ec3bb6342b"}, - {file = "ruff-0.4.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:510a67d232d2ebe983fddea324dbf9d69b71c4d2dfeb8a862f4a127536dd4cfb"}, - {file = "ruff-0.4.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc9ff11cd9a092ee7680a56d21f302bdda14327772cd870d806610a3503d001f"}, - {file = "ruff-0.4.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:29efff25bf9ee685c2c8390563a5b5c006a3fee5230d28ea39f4f75f9d0b6f2f"}, - {file = "ruff-0.4.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b00e0bcccf0fc8d7186ed21e311dffd19761cb632241a6e4fe4477cc80ef6e"}, - {file = "ruff-0.4.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:262f5635e2c74d80b7507fbc2fac28fe0d4fef26373bbc62039526f7722bca1b"}, - {file = "ruff-0.4.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:7363691198719c26459e08cc17c6a3dac6f592e9ea3d2fa772f4e561b5fe82a3"}, - {file = "ruff-0.4.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:eeb039f8428fcb6725bb63cbae92ad67b0559e68b5d80f840f11914afd8ddf7f"}, - {file = "ruff-0.4.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:927b11c1e4d0727ce1a729eace61cee88a334623ec424c0b1c8fe3e5f9d3c865"}, - {file = "ruff-0.4.3-py3-none-win32.whl", hash = "sha256:25cacda2155778beb0d064e0ec5a3944dcca9c12715f7c4634fd9d93ac33fd30"}, - {file = "ruff-0.4.3-py3-none-win_amd64.whl", hash = "sha256:7a1c3a450bc6539ef00da6c819fb1b76b6b065dec585f91456e7c0d6a0bbc725"}, - {file = "ruff-0.4.3-py3-none-win_arm64.whl", hash = "sha256:71ca5f8ccf1121b95a59649482470c5601c60a416bf189d553955b0338e34614"}, - {file = "ruff-0.4.3.tar.gz", hash = "sha256:ff0a3ef2e3c4b6d133fbedcf9586abfbe38d076041f2dc18ffb2c7e0485d5a07"}, + {file = "ruff-0.5.1-py3-none-linux_armv6l.whl", hash = "sha256:6ecf968fcf94d942d42b700af18ede94b07521bd188aaf2cd7bc898dd8cb63b6"}, + {file = "ruff-0.5.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:204fb0a472f00f2e6280a7c8c7c066e11e20e23a37557d63045bf27a616ba61c"}, + {file = "ruff-0.5.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d235968460e8758d1e1297e1de59a38d94102f60cafb4d5382033c324404ee9d"}, + {file = "ruff-0.5.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38beace10b8d5f9b6bdc91619310af6d63dd2019f3fb2d17a2da26360d7962fa"}, + {file = "ruff-0.5.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e478d2f09cf06add143cf8c4540ef77b6599191e0c50ed976582f06e588c994"}, + {file = "ruff-0.5.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f0368d765eec8247b8550251c49ebb20554cc4e812f383ff9f5bf0d5d94190b0"}, + {file = "ruff-0.5.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:3a9a9a1b582e37669b0138b7c1d9d60b9edac880b80eb2baba6d0e566bdeca4d"}, + {file = "ruff-0.5.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bdd9f723e16003623423affabcc0a807a66552ee6a29f90eddad87a40c750b78"}, + {file = "ruff-0.5.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:be9fd62c1e99539da05fcdc1e90d20f74aec1b7a1613463ed77870057cd6bd96"}, + {file = "ruff-0.5.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e216fc75a80ea1fbd96af94a6233d90190d5b65cc3d5dfacf2bd48c3e067d3e1"}, + {file = "ruff-0.5.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:c4c2112e9883a40967827d5c24803525145e7dab315497fae149764979ac7929"}, + {file = "ruff-0.5.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:dfaf11c8a116394da3b65cd4b36de30d8552fa45b8119b9ef5ca6638ab964fa3"}, + {file = "ruff-0.5.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d7ceb9b2fe700ee09a0c6b192c5ef03c56eb82a0514218d8ff700f6ade004108"}, + {file = "ruff-0.5.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:bac6288e82f6296f82ed5285f597713acb2a6ae26618ffc6b429c597b392535c"}, + {file = "ruff-0.5.1-py3-none-win32.whl", hash = "sha256:5c441d9c24ec09e1cb190a04535c5379b36b73c4bc20aa180c54812c27d1cca4"}, + {file = "ruff-0.5.1-py3-none-win_amd64.whl", hash = "sha256:b1789bf2cd3d1b5a7d38397cac1398ddf3ad7f73f4de01b1e913e2abc7dfc51d"}, + {file = "ruff-0.5.1-py3-none-win_arm64.whl", hash = "sha256:2875b7596a740cbbd492f32d24be73e545a4ce0a3daf51e4f4e609962bfd3cd2"}, + {file = "ruff-0.5.1.tar.gz", hash = "sha256:3164488aebd89b1745b47fd00604fb4358d774465f20d1fcd907f9c0fc1b0655"}, ] -[[package]] -name = "setuptools" -version = "69.5.1" -description = "Easily download, build, install, upgrade, and uninstall Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "setuptools-69.5.1-py3-none-any.whl", hash = "sha256:c636ac361bc47580504644275c9ad802c50415c7522212252c033bd15f301f32"}, - {file = "setuptools-69.5.1.tar.gz", hash = "sha256:6c1fccdac05a97e598fb0ae3bbed5904ccb317337a51139dcd51453611bbb987"}, -] - -[package.extras] -docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "importlib-metadata", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "mypy (==1.9)", "packaging (>=23.2)", "pip (>=19.1)", "pytest (>=6,!=8.1.1)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist (>=3)", "tomli", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] -testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] - [[package]] name = "six" version = "1.16.0" @@ -644,65 +626,65 @@ files = [ [[package]] name = "sqlalchemy" -version = "2.0.30" +version = "2.0.31" description = "Database Abstraction Library" optional = false python-versions = ">=3.7" files = [ - {file = "SQLAlchemy-2.0.30-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3b48154678e76445c7ded1896715ce05319f74b1e73cf82d4f8b59b46e9c0ddc"}, - {file = "SQLAlchemy-2.0.30-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2753743c2afd061bb95a61a51bbb6a1a11ac1c44292fad898f10c9839a7f75b2"}, - {file = "SQLAlchemy-2.0.30-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a7bfc726d167f425d4c16269a9a10fe8630ff6d14b683d588044dcef2d0f6be7"}, - {file = "SQLAlchemy-2.0.30-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4f61ada6979223013d9ab83a3ed003ded6959eae37d0d685db2c147e9143797"}, - {file = "SQLAlchemy-2.0.30-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3a365eda439b7a00732638f11072907c1bc8e351c7665e7e5da91b169af794af"}, - {file = "SQLAlchemy-2.0.30-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bba002a9447b291548e8d66fd8c96a6a7ed4f2def0bb155f4f0a1309fd2735d5"}, - {file = "SQLAlchemy-2.0.30-cp310-cp310-win32.whl", hash = "sha256:0138c5c16be3600923fa2169532205d18891b28afa817cb49b50e08f62198bb8"}, - {file = "SQLAlchemy-2.0.30-cp310-cp310-win_amd64.whl", hash = "sha256:99650e9f4cf3ad0d409fed3eec4f071fadd032e9a5edc7270cd646a26446feeb"}, - {file = "SQLAlchemy-2.0.30-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:955991a09f0992c68a499791a753523f50f71a6885531568404fa0f231832aa0"}, - {file = "SQLAlchemy-2.0.30-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f69e4c756ee2686767eb80f94c0125c8b0a0b87ede03eacc5c8ae3b54b99dc46"}, - {file = "SQLAlchemy-2.0.30-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69c9db1ce00e59e8dd09d7bae852a9add716efdc070a3e2068377e6ff0d6fdaa"}, - {file = "SQLAlchemy-2.0.30-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1429a4b0f709f19ff3b0cf13675b2b9bfa8a7e79990003207a011c0db880a13"}, - {file = "SQLAlchemy-2.0.30-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:efedba7e13aa9a6c8407c48facfdfa108a5a4128e35f4c68f20c3407e4376aa9"}, - {file = "SQLAlchemy-2.0.30-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:16863e2b132b761891d6c49f0a0f70030e0bcac4fd208117f6b7e053e68668d0"}, - {file = "SQLAlchemy-2.0.30-cp311-cp311-win32.whl", hash = "sha256:2ecabd9ccaa6e914e3dbb2aa46b76dede7eadc8cbf1b8083c94d936bcd5ffb49"}, - {file = "SQLAlchemy-2.0.30-cp311-cp311-win_amd64.whl", hash = "sha256:0b3f4c438e37d22b83e640f825ef0f37b95db9aa2d68203f2c9549375d0b2260"}, - {file = "SQLAlchemy-2.0.30-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5a79d65395ac5e6b0c2890935bad892eabb911c4aa8e8015067ddb37eea3d56c"}, - {file = "SQLAlchemy-2.0.30-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9a5baf9267b752390252889f0c802ea13b52dfee5e369527da229189b8bd592e"}, - {file = "SQLAlchemy-2.0.30-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cb5a646930c5123f8461f6468901573f334c2c63c795b9af350063a736d0134"}, - {file = "SQLAlchemy-2.0.30-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:296230899df0b77dec4eb799bcea6fbe39a43707ce7bb166519c97b583cfcab3"}, - {file = "SQLAlchemy-2.0.30-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c62d401223f468eb4da32627bffc0c78ed516b03bb8a34a58be54d618b74d472"}, - {file = "SQLAlchemy-2.0.30-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3b69e934f0f2b677ec111b4d83f92dc1a3210a779f69bf905273192cf4ed433e"}, - {file = "SQLAlchemy-2.0.30-cp312-cp312-win32.whl", hash = "sha256:77d2edb1f54aff37e3318f611637171e8ec71472f1fdc7348b41dcb226f93d90"}, - {file = "SQLAlchemy-2.0.30-cp312-cp312-win_amd64.whl", hash = "sha256:b6c7ec2b1f4969fc19b65b7059ed00497e25f54069407a8701091beb69e591a5"}, - {file = "SQLAlchemy-2.0.30-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5a8e3b0a7e09e94be7510d1661339d6b52daf202ed2f5b1f9f48ea34ee6f2d57"}, - {file = "SQLAlchemy-2.0.30-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b60203c63e8f984df92035610c5fb76d941254cf5d19751faab7d33b21e5ddc0"}, - {file = "SQLAlchemy-2.0.30-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f1dc3eabd8c0232ee8387fbe03e0a62220a6f089e278b1f0aaf5e2d6210741ad"}, - {file = "SQLAlchemy-2.0.30-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:40ad017c672c00b9b663fcfcd5f0864a0a97828e2ee7ab0c140dc84058d194cf"}, - {file = "SQLAlchemy-2.0.30-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e42203d8d20dc704604862977b1470a122e4892791fe3ed165f041e4bf447a1b"}, - {file = "SQLAlchemy-2.0.30-cp37-cp37m-win32.whl", hash = "sha256:2a4f4da89c74435f2bc61878cd08f3646b699e7d2eba97144030d1be44e27584"}, - {file = "SQLAlchemy-2.0.30-cp37-cp37m-win_amd64.whl", hash = "sha256:b6bf767d14b77f6a18b6982cbbf29d71bede087edae495d11ab358280f304d8e"}, - {file = "SQLAlchemy-2.0.30-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bc0c53579650a891f9b83fa3cecd4e00218e071d0ba00c4890f5be0c34887ed3"}, - {file = "SQLAlchemy-2.0.30-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:311710f9a2ee235f1403537b10c7687214bb1f2b9ebb52702c5aa4a77f0b3af7"}, - {file = "SQLAlchemy-2.0.30-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:408f8b0e2c04677e9c93f40eef3ab22f550fecb3011b187f66a096395ff3d9fd"}, - {file = "SQLAlchemy-2.0.30-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:37a4b4fb0dd4d2669070fb05b8b8824afd0af57587393015baee1cf9890242d9"}, - {file = "SQLAlchemy-2.0.30-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a943d297126c9230719c27fcbbeab57ecd5d15b0bd6bfd26e91bfcfe64220621"}, - {file = "SQLAlchemy-2.0.30-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0a089e218654e740a41388893e090d2e2c22c29028c9d1353feb38638820bbeb"}, - {file = "SQLAlchemy-2.0.30-cp38-cp38-win32.whl", hash = "sha256:fa561138a64f949f3e889eb9ab8c58e1504ab351d6cf55259dc4c248eaa19da6"}, - {file = "SQLAlchemy-2.0.30-cp38-cp38-win_amd64.whl", hash = "sha256:7d74336c65705b986d12a7e337ba27ab2b9d819993851b140efdf029248e818e"}, - {file = "SQLAlchemy-2.0.30-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ae8c62fe2480dd61c532ccafdbce9b29dacc126fe8be0d9a927ca3e699b9491a"}, - {file = "SQLAlchemy-2.0.30-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2383146973a15435e4717f94c7509982770e3e54974c71f76500a0136f22810b"}, - {file = "SQLAlchemy-2.0.30-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8409de825f2c3b62ab15788635ccaec0c881c3f12a8af2b12ae4910a0a9aeef6"}, - {file = "SQLAlchemy-2.0.30-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0094c5dc698a5f78d3d1539853e8ecec02516b62b8223c970c86d44e7a80f6c7"}, - {file = "SQLAlchemy-2.0.30-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:edc16a50f5e1b7a06a2dcc1f2205b0b961074c123ed17ebda726f376a5ab0953"}, - {file = "SQLAlchemy-2.0.30-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f7703c2010355dd28f53deb644a05fc30f796bd8598b43f0ba678878780b6e4c"}, - {file = "SQLAlchemy-2.0.30-cp39-cp39-win32.whl", hash = "sha256:1f9a727312ff6ad5248a4367358e2cf7e625e98b1028b1d7ab7b806b7d757513"}, - {file = "SQLAlchemy-2.0.30-cp39-cp39-win_amd64.whl", hash = "sha256:a0ef36b28534f2a5771191be6edb44cc2673c7b2edf6deac6562400288664221"}, - {file = "SQLAlchemy-2.0.30-py3-none-any.whl", hash = "sha256:7108d569d3990c71e26a42f60474b4c02c8586c4681af5fd67e51a044fdea86a"}, - {file = "SQLAlchemy-2.0.30.tar.gz", hash = "sha256:2b1708916730f4830bc69d6f49d37f7698b5bd7530aca7f04f785f8849e95255"}, + {file = "SQLAlchemy-2.0.31-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f2a213c1b699d3f5768a7272de720387ae0122f1becf0901ed6eaa1abd1baf6c"}, + {file = "SQLAlchemy-2.0.31-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9fea3d0884e82d1e33226935dac990b967bef21315cbcc894605db3441347443"}, + {file = "SQLAlchemy-2.0.31-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3ad7f221d8a69d32d197e5968d798217a4feebe30144986af71ada8c548e9fa"}, + {file = "SQLAlchemy-2.0.31-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2bee229715b6366f86a95d497c347c22ddffa2c7c96143b59a2aa5cc9eebbc"}, + {file = "SQLAlchemy-2.0.31-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cd5b94d4819c0c89280b7c6109c7b788a576084bf0a480ae17c227b0bc41e109"}, + {file = "SQLAlchemy-2.0.31-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:750900a471d39a7eeba57580b11983030517a1f512c2cb287d5ad0fcf3aebd58"}, + {file = "SQLAlchemy-2.0.31-cp310-cp310-win32.whl", hash = "sha256:7bd112be780928c7f493c1a192cd8c5fc2a2a7b52b790bc5a84203fb4381c6be"}, + {file = "SQLAlchemy-2.0.31-cp310-cp310-win_amd64.whl", hash = "sha256:5a48ac4d359f058474fadc2115f78a5cdac9988d4f99eae44917f36aa1476327"}, + {file = "SQLAlchemy-2.0.31-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f68470edd70c3ac3b6cd5c2a22a8daf18415203ca1b036aaeb9b0fb6f54e8298"}, + {file = "SQLAlchemy-2.0.31-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2e2c38c2a4c5c634fe6c3c58a789712719fa1bf9b9d6ff5ebfce9a9e5b89c1ca"}, + {file = "SQLAlchemy-2.0.31-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd15026f77420eb2b324dcb93551ad9c5f22fab2c150c286ef1dc1160f110203"}, + {file = "SQLAlchemy-2.0.31-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2196208432deebdfe3b22185d46b08f00ac9d7b01284e168c212919891289396"}, + {file = "SQLAlchemy-2.0.31-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:352b2770097f41bff6029b280c0e03b217c2dcaddc40726f8f53ed58d8a85da4"}, + {file = "SQLAlchemy-2.0.31-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:56d51ae825d20d604583f82c9527d285e9e6d14f9a5516463d9705dab20c3740"}, + {file = "SQLAlchemy-2.0.31-cp311-cp311-win32.whl", hash = "sha256:6e2622844551945db81c26a02f27d94145b561f9d4b0c39ce7bfd2fda5776dac"}, + {file = "SQLAlchemy-2.0.31-cp311-cp311-win_amd64.whl", hash = "sha256:ccaf1b0c90435b6e430f5dd30a5aede4764942a695552eb3a4ab74ed63c5b8d3"}, + {file = "SQLAlchemy-2.0.31-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3b74570d99126992d4b0f91fb87c586a574a5872651185de8297c6f90055ae42"}, + {file = "SQLAlchemy-2.0.31-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f77c4f042ad493cb8595e2f503c7a4fe44cd7bd59c7582fd6d78d7e7b8ec52c"}, + {file = "SQLAlchemy-2.0.31-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cd1591329333daf94467e699e11015d9c944f44c94d2091f4ac493ced0119449"}, + {file = "SQLAlchemy-2.0.31-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:74afabeeff415e35525bf7a4ecdab015f00e06456166a2eba7590e49f8db940e"}, + {file = "SQLAlchemy-2.0.31-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b9c01990d9015df2c6f818aa8f4297d42ee71c9502026bb074e713d496e26b67"}, + {file = "SQLAlchemy-2.0.31-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:66f63278db425838b3c2b1c596654b31939427016ba030e951b292e32b99553e"}, + {file = "SQLAlchemy-2.0.31-cp312-cp312-win32.whl", hash = "sha256:0b0f658414ee4e4b8cbcd4a9bb0fd743c5eeb81fc858ca517217a8013d282c96"}, + {file = "SQLAlchemy-2.0.31-cp312-cp312-win_amd64.whl", hash = "sha256:fa4b1af3e619b5b0b435e333f3967612db06351217c58bfb50cee5f003db2a5a"}, + {file = "SQLAlchemy-2.0.31-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:f43e93057cf52a227eda401251c72b6fbe4756f35fa6bfebb5d73b86881e59b0"}, + {file = "SQLAlchemy-2.0.31-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d337bf94052856d1b330d5fcad44582a30c532a2463776e1651bd3294ee7e58b"}, + {file = "SQLAlchemy-2.0.31-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c06fb43a51ccdff3b4006aafee9fcf15f63f23c580675f7734245ceb6b6a9e05"}, + {file = "SQLAlchemy-2.0.31-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:b6e22630e89f0e8c12332b2b4c282cb01cf4da0d26795b7eae16702a608e7ca1"}, + {file = "SQLAlchemy-2.0.31-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:79a40771363c5e9f3a77f0e28b3302801db08040928146e6808b5b7a40749c88"}, + {file = "SQLAlchemy-2.0.31-cp37-cp37m-win32.whl", hash = "sha256:501ff052229cb79dd4c49c402f6cb03b5a40ae4771efc8bb2bfac9f6c3d3508f"}, + {file = "SQLAlchemy-2.0.31-cp37-cp37m-win_amd64.whl", hash = "sha256:597fec37c382a5442ffd471f66ce12d07d91b281fd474289356b1a0041bdf31d"}, + {file = "SQLAlchemy-2.0.31-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:dc6d69f8829712a4fd799d2ac8d79bdeff651c2301b081fd5d3fe697bd5b4ab9"}, + {file = "SQLAlchemy-2.0.31-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:23b9fbb2f5dd9e630db70fbe47d963c7779e9c81830869bd7d137c2dc1ad05fb"}, + {file = "SQLAlchemy-2.0.31-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a21c97efcbb9f255d5c12a96ae14da873233597dfd00a3a0c4ce5b3e5e79704"}, + {file = "SQLAlchemy-2.0.31-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26a6a9837589c42b16693cf7bf836f5d42218f44d198f9343dd71d3164ceeeac"}, + {file = "SQLAlchemy-2.0.31-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc251477eae03c20fae8db9c1c23ea2ebc47331bcd73927cdcaecd02af98d3c3"}, + {file = "SQLAlchemy-2.0.31-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:2fd17e3bb8058359fa61248c52c7b09a97cf3c820e54207a50af529876451808"}, + {file = "SQLAlchemy-2.0.31-cp38-cp38-win32.whl", hash = "sha256:c76c81c52e1e08f12f4b6a07af2b96b9b15ea67ccdd40ae17019f1c373faa227"}, + {file = "SQLAlchemy-2.0.31-cp38-cp38-win_amd64.whl", hash = "sha256:4b600e9a212ed59355813becbcf282cfda5c93678e15c25a0ef896b354423238"}, + {file = "SQLAlchemy-2.0.31-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b6cf796d9fcc9b37011d3f9936189b3c8074a02a4ed0c0fbbc126772c31a6d4"}, + {file = "SQLAlchemy-2.0.31-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:78fe11dbe37d92667c2c6e74379f75746dc947ee505555a0197cfba9a6d4f1a4"}, + {file = "SQLAlchemy-2.0.31-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2fc47dc6185a83c8100b37acda27658fe4dbd33b7d5e7324111f6521008ab4fe"}, + {file = "SQLAlchemy-2.0.31-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a41514c1a779e2aa9a19f67aaadeb5cbddf0b2b508843fcd7bafdf4c6864005"}, + {file = "SQLAlchemy-2.0.31-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:afb6dde6c11ea4525318e279cd93c8734b795ac8bb5dda0eedd9ebaca7fa23f1"}, + {file = "SQLAlchemy-2.0.31-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:3f9faef422cfbb8fd53716cd14ba95e2ef655400235c3dfad1b5f467ba179c8c"}, + {file = "SQLAlchemy-2.0.31-cp39-cp39-win32.whl", hash = "sha256:fc6b14e8602f59c6ba893980bea96571dd0ed83d8ebb9c4479d9ed5425d562e9"}, + {file = "SQLAlchemy-2.0.31-cp39-cp39-win_amd64.whl", hash = "sha256:3cb8a66b167b033ec72c3812ffc8441d4e9f5f78f5e31e54dcd4c90a4ca5bebc"}, + {file = "SQLAlchemy-2.0.31-py3-none-any.whl", hash = "sha256:69f3e3c08867a8e4856e92d7afb618b95cdee18e0bc1647b77599722c9a28911"}, + {file = "SQLAlchemy-2.0.31.tar.gz", hash = "sha256:b607489dd4a54de56984a0c7656247504bd5523d9d0ba799aef59d4add009484"}, ] [package.dependencies] aiosqlite = {version = "*", optional = true, markers = "extra == \"aiosqlite\""} -greenlet = {version = "!=0.4.17", optional = true, markers = "platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\" or extra == \"aiosqlite\""} +greenlet = {version = "!=0.4.17", optional = true, markers = "python_version < \"3.13\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\") or extra == \"aiosqlite\""} typing-extensions = {version = ">=4.6.0", optional = true, markers = "extra == \"aiosqlite\""} [package.extras] @@ -749,13 +731,13 @@ full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart (>=0.0.7 [[package]] name = "typing-extensions" -version = "4.11.0" +version = "4.12.2" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.11.0-py3-none-any.whl", hash = "sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a"}, - {file = "typing_extensions-4.11.0.tar.gz", hash = "sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0"}, + {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, + {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, ] [[package]] @@ -771,13 +753,13 @@ files = [ [[package]] name = "uvicorn" -version = "0.29.0" +version = "0.30.1" description = "The lightning-fast ASGI server." optional = false python-versions = ">=3.8" files = [ - {file = "uvicorn-0.29.0-py3-none-any.whl", hash = "sha256:2c2aac7ff4f4365c206fd773a39bf4ebd1047c238f8b8268ad996829323473de"}, - {file = "uvicorn-0.29.0.tar.gz", hash = "sha256:6a69214c0b6a087462412670b3ef21224fa48cae0e452b5883e8e8bdfdd11dd0"}, + {file = "uvicorn-0.30.1-py3-none-any.whl", hash = "sha256:cd17daa7f3b9d7a24de3617820e634d0933b69eed8e33a516071174427238c81"}, + {file = "uvicorn-0.30.1.tar.gz", hash = "sha256:d46cd8e0fd80240baffbcd9ec1012a712938754afcf81bce56c024c1656aece8"}, ] [package.dependencies] @@ -801,4 +783,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "9dbc732b312d6d39fbf4e8b8af22739aad6c25312cee92736f19d3a106f93129" +content-hash = "c0a9d4f094807ba59923de4ecf87985eba2cdcd7b78d7adbf430455b3cc6be5d" diff --git a/pyproject.toml b/pyproject.toml index 134c089..a7ca0e2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,7 +15,7 @@ beautifulsoup4 = "^4.9.3" html5lib = "^1.1" starlette = "^0.37.2" ulid-py = "^1.1.0" -uvicorn = "^0.29.0" +uvicorn = "^0.30.1" httpx = "^0.27.0" sqlalchemy = {version = "^2.0", extras = ["aiosqlite"]} alembic = "^1.13.1" diff --git a/unwind-ui/package-lock.json b/unwind-ui/package-lock.json index d01fcf0..8386cfc 100644 --- a/unwind-ui/package-lock.json +++ b/unwind-ui/package-lock.json @@ -20,9 +20,10 @@ } }, "node_modules/@babel/parser": { - "version": "7.24.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.5.tgz", - "integrity": "sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg==", + "version": "7.24.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.8.tgz", + "integrity": "sha512-WzfbgXOkGzZiXXCqk43kKwZjzwx4oulxZi3nq2TYL9mOjQv6kYwul9mz6ID36njuL7Xkp6nJEfok848Zj10j/w==", + "license": "MIT", "bin": { "parser": "bin/babel-parser.js" }, @@ -31,13 +32,14 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", - "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", "cpu": [ "ppc64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "aix" @@ -47,13 +49,14 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", - "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" @@ -63,13 +66,14 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", - "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" @@ -79,13 +83,14 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", - "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" @@ -95,13 +100,14 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", - "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -111,13 +117,14 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", - "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -127,13 +134,14 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", - "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "freebsd" @@ -143,13 +151,14 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", - "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "freebsd" @@ -159,13 +168,14 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", - "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -175,13 +185,14 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", - "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -191,13 +202,14 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", - "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", "cpu": [ "ia32" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -207,13 +219,14 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", - "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", "cpu": [ "loong64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -223,13 +236,14 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", - "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", "cpu": [ "mips64el" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -239,13 +253,14 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", - "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", "cpu": [ "ppc64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -255,13 +270,14 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", - "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", "cpu": [ "riscv64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -271,13 +287,14 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", - "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", "cpu": [ "s390x" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -287,13 +304,14 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", - "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" @@ -303,13 +321,14 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", - "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "netbsd" @@ -319,13 +338,14 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", - "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "openbsd" @@ -335,13 +355,14 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", - "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "sunos" @@ -351,13 +372,14 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", - "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -367,13 +389,14 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", - "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", "cpu": [ "ia32" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -383,13 +406,14 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", - "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -399,213 +423,230 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", + "license": "MIT" }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.17.2.tgz", - "integrity": "sha512-NM0jFxY8bB8QLkoKxIQeObCaDlJKewVlIEkuyYKm5An1tdVZ966w2+MPQ2l8LBZLjR+SgyV+nRkTIunzOYBMLQ==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.1.tgz", + "integrity": "sha512-lncuC4aHicncmbORnx+dUaAgzee9cm/PbIqgWz1PpXuwc+sa1Ct83tnqUDy/GFKleLiN7ZIeytM6KJ4cAn1SxA==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.17.2.tgz", - "integrity": "sha512-yeX/Usk7daNIVwkq2uGoq2BYJKZY1JfyLTaHO/jaiSwi/lsf8fTFoQW/n6IdAsx5tx+iotu2zCJwz8MxI6D/Bw==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.1.tgz", + "integrity": "sha512-F/tkdw0WSs4ojqz5Ovrw5r9odqzFjb5LIgHdHZG65dFI1lWTWRVy32KDJLKRISHgJvqUeUhdIvy43fX41znyDg==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "android" ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.17.2.tgz", - "integrity": "sha512-kcMLpE6uCwls023+kknm71ug7MZOrtXo+y5p/tsg6jltpDtgQY1Eq5sGfHcQfb+lfuKwhBmEURDga9N0ol4YPw==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.1.tgz", + "integrity": "sha512-vk+ma8iC1ebje/ahpxpnrfVQJibTMyHdWpOGZ3JpQ7Mgn/3QNHmPq7YwjZbIE7km73dH5M1e6MRRsnEBW7v5CQ==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.17.2.tgz", - "integrity": "sha512-AtKwD0VEx0zWkL0ZjixEkp5tbNLzX+FCqGG1SvOu993HnSz4qDI6S4kGzubrEJAljpVkhRSlg5bzpV//E6ysTQ==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.1.tgz", + "integrity": "sha512-IgpzXKauRe1Tafcej9STjSSuG0Ghu/xGYH+qG6JwsAUxXrnkvNHcq/NL6nz1+jzvWAnQkuAJ4uIwGB48K9OCGA==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "darwin" ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.17.2.tgz", - "integrity": "sha512-3reX2fUHqN7sffBNqmEyMQVj/CKhIHZd4y631duy0hZqI8Qoqf6lTtmAKvJFYa6bhU95B1D0WgzHkmTg33In0A==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.1.tgz", + "integrity": "sha512-P9bSiAUnSSM7EmyRK+e5wgpqai86QOSv8BwvkGjLwYuOpaeomiZWifEos517CwbG+aZl1T4clSE1YqqH2JRs+g==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.17.2.tgz", - "integrity": "sha512-uSqpsp91mheRgw96xtyAGP9FW5ChctTFEoXP0r5FAzj/3ZRv3Uxjtc7taRQSaQM/q85KEKjKsZuiZM3GyUivRg==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.1.tgz", + "integrity": "sha512-5RnjpACoxtS+aWOI1dURKno11d7krfpGDEn19jI8BuWmSBbUC4ytIADfROM1FZrFhQPSoP+KEa3NlEScznBTyQ==", "cpu": [ "arm" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.17.2.tgz", - "integrity": "sha512-EMMPHkiCRtE8Wdk3Qhtciq6BndLtstqZIroHiiGzB3C5LDJmIZcSzVtLRbwuXuUft1Cnv+9fxuDtDxz3k3EW2A==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.1.tgz", + "integrity": "sha512-8mwmGD668m8WaGbthrEYZ9CBmPug2QPGWxhJxh/vCgBjro5o96gL04WLlg5BA233OCWLqERy4YUzX3bJGXaJgQ==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.17.2.tgz", - "integrity": "sha512-NMPylUUZ1i0z/xJUIx6VUhISZDRT+uTWpBcjdv0/zkp7b/bQDF+NfnfdzuTiB1G6HTodgoFa93hp0O1xl+/UbA==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.1.tgz", + "integrity": "sha512-dJX9u4r4bqInMGOAQoGYdwDP8lQiisWb9et+T84l2WXk41yEej8v2iGKodmdKimT8cTAYt0jFb+UEBxnPkbXEQ==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.17.2.tgz", - "integrity": "sha512-T19My13y8uYXPw/L/k0JYaX1fJKFT/PWdXiHr8mTbXWxjVF1t+8Xl31DgBBvEKclw+1b00Chg0hxE2O7bTG7GQ==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.1.tgz", + "integrity": "sha512-V72cXdTl4EI0x6FNmho4D502sy7ed+LuVW6Ym8aI6DRQ9hQZdp5sj0a2usYOlqvFBNKQnLQGwmYnujo2HvjCxQ==", "cpu": [ "ppc64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.17.2.tgz", - "integrity": "sha512-BOaNfthf3X3fOWAB+IJ9kxTgPmMqPPH5f5k2DcCsRrBIbWnaJCgX2ll77dV1TdSy9SaXTR5iDXRL8n7AnoP5cg==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.1.tgz", + "integrity": "sha512-f+pJih7sxoKmbjghrM2RkWo2WHUW8UbfxIQiWo5yeCaCM0TveMEuAzKJte4QskBp1TIinpnRcxkquY+4WuY/tg==", "cpu": [ "riscv64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.17.2.tgz", - "integrity": "sha512-W0UP/x7bnn3xN2eYMql2T/+wpASLE5SjObXILTMPUBDB/Fg/FxC+gX4nvCfPBCbNhz51C+HcqQp2qQ4u25ok6g==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.1.tgz", + "integrity": "sha512-qb1hMMT3Fr/Qz1OKovCuUM11MUNLUuHeBC2DPPAWUYYUAOFWaxInaTwTQmc7Fl5La7DShTEpmYwgdt2hG+4TEg==", "cpu": [ "s390x" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.17.2.tgz", - "integrity": "sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.1.tgz", + "integrity": "sha512-7O5u/p6oKUFYjRbZkL2FLbwsyoJAjyeXHCU3O4ndvzg2OFO2GinFPSJFGbiwFDaCFc+k7gs9CF243PwdPQFh5g==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.17.2.tgz", - "integrity": "sha512-h1+yTWeYbRdAyJ/jMiVw0l6fOOm/0D1vNLui9iPuqgRGnXA0u21gAqOyB5iHjlM9MMfNOm9RHCQ7zLIzT0x11Q==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.1.tgz", + "integrity": "sha512-pDLkYITdYrH/9Cv/Vlj8HppDuLMDUBmgsM0+N+xLtFd18aXgM9Nyqupb/Uw+HeidhfYg2lD6CXvz6CjoVOaKjQ==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "linux" ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.17.2.tgz", - "integrity": "sha512-tmdtXMfKAjy5+IQsVtDiCfqbynAQE/TQRpWdVataHmhMb9DCoJxp9vLcCBjEQWMiUYxO1QprH/HbY9ragCEFLA==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.1.tgz", + "integrity": "sha512-W2ZNI323O/8pJdBGil1oCauuCzmVd9lDmWBBqxYZcOqWD6aWqJtVBQ1dFrF4dYpZPks6F+xCZHfzG5hYlSHZ6g==", "cpu": [ "arm64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.17.2.tgz", - "integrity": "sha512-7II/QCSTAHuE5vdZaQEwJq2ZACkBpQDOmQsE6D6XUbnBHW8IAhm4eTufL6msLJorzrHDFv3CF8oCA/hSIRuZeQ==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.1.tgz", + "integrity": "sha512-ELfEX1/+eGZYMaCIbK4jqLxO1gyTSOIlZr6pbC4SRYFaSIDVKOnZNMdoZ+ON0mrFDp4+H5MhwNC1H/AhE3zQLg==", "cpu": [ "ia32" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.17.2.tgz", - "integrity": "sha512-TGGO7v7qOq4CYmSBVEYpI1Y5xDuCEnbVC5Vth8mOsW0gDSzxNrVERPc790IGHsrT2dQSimgMr9Ub3Y1Jci5/8w==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.1.tgz", + "integrity": "sha512-yjk2MAkQmoaPYCSu35RLJ62+dz358nE83VfTePJRp8CG7aMg25mEJYpXFiD+NcevhX8LxD5OP5tktPXnXN7GDw==", "cpu": [ "x64" ], "dev": true, + "license": "MIT", "optional": true, "os": [ "win32" @@ -615,13 +656,15 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@vitejs/plugin-vue": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.0.4.tgz", - "integrity": "sha512-WS3hevEszI6CEVEx28F8RjTX97k3KsrcY6kvTg7+Whm5y3oYvcqzVeGCU3hxSAn4uY2CLCkeokkGKpoctccilQ==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.0.5.tgz", + "integrity": "sha512-LOjm7XeIimLBZyzinBQ6OSm3UBCNVCpLkxGC0oWmm2YPzVZoxMsdvNVimLTBzpAnR9hl/yn1SHGuRfe6/Td9rQ==", "dev": true, + "license": "MIT", "engines": { "node": "^18.0.0 || >=20.0.0" }, @@ -631,64 +674,68 @@ } }, "node_modules/@volar/language-core": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.2.1.tgz", - "integrity": "sha512-iHJAZKcYldZgyS8gx6DfIZApViVBeqbf6iPhqoZpG5A6F4zsZiFldKfwaKaBA3/wnOTWE2i8VUbXywI1WywCPg==", + "version": "2.4.0-alpha.15", + "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.4.0-alpha.15.tgz", + "integrity": "sha512-mt8z4Fm2WxfQYoQHPcKVjLQV6PgPqyKLbkCVY2cr5RSaamqCHjhKEpsFX66aL4D/7oYguuaUw9Bx03Vt0TpIIA==", "dev": true, + "license": "MIT", "dependencies": { - "@volar/source-map": "2.2.1" + "@volar/source-map": "2.4.0-alpha.15" } }, "node_modules/@volar/source-map": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.2.1.tgz", - "integrity": "sha512-w1Bgpguhbp7YTr7VUFu6gb4iAZjeEPsOX4zpgiuvlldbzvIWDWy4t0jVifsIsxZ99HAu+c3swiME7wt+GeNqhA==", + "version": "2.4.0-alpha.15", + "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.4.0-alpha.15.tgz", + "integrity": "sha512-8Htngw5TmBY4L3ClDqBGyfLhsB8EmoEXUH1xydyEtEoK0O6NX5ur4Jw8jgvscTlwzizyl/wsN1vn0cQXVbbXYg==", "dev": true, - "dependencies": { - "muggle-string": "^0.4.0" - } + "license": "MIT" }, "node_modules/@volar/typescript": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.2.1.tgz", - "integrity": "sha512-Z/tqluR7Hz5/5dCqQp7wo9C/6tSv/IYl+tTzgzUt2NjTq95bKSsuO4E+V06D0c+3aP9x5S9jggLqw451hpnc6Q==", + "version": "2.4.0-alpha.15", + "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.4.0-alpha.15.tgz", + "integrity": "sha512-U3StRBbDuxV6Woa4hvGS4kz3XcOzrWUKgFdEFN+ba1x3eaYg7+ytau8ul05xgA+UNGLXXsKur7fTUhDFyISk0w==", "dev": true, + "license": "MIT", "dependencies": { - "@volar/language-core": "2.2.1", - "path-browserify": "^1.0.1" + "@volar/language-core": "2.4.0-alpha.15", + "path-browserify": "^1.0.1", + "vscode-uri": "^3.0.8" } }, "node_modules/@vue/compiler-core": { - "version": "3.4.27", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.27.tgz", - "integrity": "sha512-E+RyqY24KnyDXsCuQrI+mlcdW3ALND6U7Gqa/+bVwbcpcR3BRRIckFoz7Qyd4TTlnugtwuI7YgjbvsLmxb+yvg==", + "version": "3.4.31", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.31.tgz", + "integrity": "sha512-skOiodXWTV3DxfDhB4rOf3OGalpITLlgCeOwb+Y9GJpfQ8ErigdBUHomBzvG78JoVE8MJoQsb+qhZiHfKeNeEg==", + "license": "MIT", "dependencies": { - "@babel/parser": "^7.24.4", - "@vue/shared": "3.4.27", + "@babel/parser": "^7.24.7", + "@vue/shared": "3.4.31", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.0" } }, "node_modules/@vue/compiler-dom": { - "version": "3.4.27", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.27.tgz", - "integrity": "sha512-kUTvochG/oVgE1w5ViSr3KUBh9X7CWirebA3bezTbB5ZKBQZwR2Mwj9uoSKRMFcz4gSMzzLXBPD6KpCLb9nvWw==", + "version": "3.4.31", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.31.tgz", + "integrity": "sha512-wK424WMXsG1IGMyDGyLqB+TbmEBFM78hIsOJ9QwUVLGrcSk0ak6zYty7Pj8ftm7nEtdU/DGQxAXp0/lM/2cEpQ==", + "license": "MIT", "dependencies": { - "@vue/compiler-core": "3.4.27", - "@vue/shared": "3.4.27" + "@vue/compiler-core": "3.4.31", + "@vue/shared": "3.4.31" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.4.27", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.27.tgz", - "integrity": "sha512-nDwntUEADssW8e0rrmE0+OrONwmRlegDA1pD6QhVeXxjIytV03yDqTey9SBDiALsvAd5U4ZrEKbMyVXhX6mCGA==", + "version": "3.4.31", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.31.tgz", + "integrity": "sha512-einJxqEw8IIJxzmnxmJBuK2usI+lJonl53foq+9etB2HAzlPjAS/wa7r0uUpXw5ByX3/0uswVSrjNb17vJm1kQ==", + "license": "MIT", "dependencies": { - "@babel/parser": "^7.24.4", - "@vue/compiler-core": "3.4.27", - "@vue/compiler-dom": "3.4.27", - "@vue/compiler-ssr": "3.4.27", - "@vue/shared": "3.4.27", + "@babel/parser": "^7.24.7", + "@vue/compiler-core": "3.4.31", + "@vue/compiler-dom": "3.4.31", + "@vue/compiler-ssr": "3.4.31", + "@vue/shared": "3.4.31", "estree-walker": "^2.0.2", "magic-string": "^0.30.10", "postcss": "^8.4.38", @@ -696,25 +743,28 @@ } }, "node_modules/@vue/compiler-ssr": { - "version": "3.4.27", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.27.tgz", - "integrity": "sha512-CVRzSJIltzMG5FcidsW0jKNQnNRYC8bT21VegyMMtHmhW3UOI7knmUehzswXLrExDLE6lQCZdrhD4ogI7c+vuw==", + "version": "3.4.31", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.31.tgz", + "integrity": "sha512-RtefmITAje3fJ8FSg1gwgDhdKhZVntIVbwupdyZDSifZTRMiWxWehAOTCc8/KZDnBOcYQ4/9VWxsTbd3wT0hAA==", + "license": "MIT", "dependencies": { - "@vue/compiler-dom": "3.4.27", - "@vue/shared": "3.4.27" + "@vue/compiler-dom": "3.4.31", + "@vue/shared": "3.4.31" } }, "node_modules/@vue/language-core": { - "version": "2.0.16", - "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-2.0.16.tgz", - "integrity": "sha512-Bc2sexRH99pznOph8mLw2BlRZ9edm7tW51kcBXgx8adAoOcZUWJj3UNSsdQ6H9Y8meGz7BoazVrVo/jUukIsPw==", + "version": "2.0.26", + "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-2.0.26.tgz", + "integrity": "sha512-/lt6SfQ3O1yDAhPsnLv9iSUgXd1dMHqUm/t3RctfqjuwQf1LnftZ414X3UBn6aXT4MiwXWtbNJ4Z0NZWwDWgJQ==", "dev": true, + "license": "MIT", "dependencies": { - "@volar/language-core": "~2.2.0", + "@volar/language-core": "~2.4.0-alpha.15", "@vue/compiler-dom": "^3.4.0", "@vue/shared": "^3.4.0", "computeds": "^0.0.1", "minimatch": "^9.0.3", + "muggle-string": "^0.4.1", "path-browserify": "^1.0.1", "vue-template-compiler": "^2.7.14" }, @@ -728,150 +778,103 @@ } }, "node_modules/@vue/reactivity": { - "version": "3.4.27", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.27.tgz", - "integrity": "sha512-kK0g4NknW6JX2yySLpsm2jlunZJl2/RJGZ0H9ddHdfBVHcNzxmQ0sS0b09ipmBoQpY8JM2KmUw+a6sO8Zo+zIA==", + "version": "3.4.31", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.31.tgz", + "integrity": "sha512-VGkTani8SOoVkZNds1PfJ/T1SlAIOf8E58PGAhIOUDYPC4GAmFA2u/E14TDAFcf3vVDKunc4QqCe/SHr8xC65Q==", + "license": "MIT", "dependencies": { - "@vue/shared": "3.4.27" + "@vue/shared": "3.4.31" } }, "node_modules/@vue/runtime-core": { - "version": "3.4.27", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.27.tgz", - "integrity": "sha512-7aYA9GEbOOdviqVvcuweTLe5Za4qBZkUY7SvET6vE8kyypxVgaT1ixHLg4urtOlrApdgcdgHoTZCUuTGap/5WA==", + "version": "3.4.31", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.31.tgz", + "integrity": "sha512-LDkztxeUPazxG/p8c5JDDKPfkCDBkkiNLVNf7XZIUnJ+66GVGkP+TIh34+8LtPisZ+HMWl2zqhIw0xN5MwU1cw==", + "license": "MIT", "dependencies": { - "@vue/reactivity": "3.4.27", - "@vue/shared": "3.4.27" + "@vue/reactivity": "3.4.31", + "@vue/shared": "3.4.31" } }, "node_modules/@vue/runtime-dom": { - "version": "3.4.27", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.27.tgz", - "integrity": "sha512-ScOmP70/3NPM+TW9hvVAz6VWWtZJqkbdf7w6ySsws+EsqtHvkhxaWLecrTorFxsawelM5Ys9FnDEMt6BPBDS0Q==", + "version": "3.4.31", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.31.tgz", + "integrity": "sha512-2Auws3mB7+lHhTFCg8E9ZWopA6Q6L455EcU7bzcQ4x6Dn4cCPuqj6S2oBZgN2a8vJRS/LSYYxwFFq2Hlx3Fsaw==", + "license": "MIT", "dependencies": { - "@vue/runtime-core": "3.4.27", - "@vue/shared": "3.4.27", + "@vue/reactivity": "3.4.31", + "@vue/runtime-core": "3.4.31", + "@vue/shared": "3.4.31", "csstype": "^3.1.3" } }, "node_modules/@vue/server-renderer": { - "version": "3.4.27", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.27.tgz", - "integrity": "sha512-dlAMEuvmeA3rJsOMJ2J1kXU7o7pOxgsNHVr9K8hB3ImIkSuBrIdy0vF66h8gf8Tuinf1TK3mPAz2+2sqyf3KzA==", + "version": "3.4.31", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.31.tgz", + "integrity": "sha512-D5BLbdvrlR9PE3by9GaUp1gQXlCNadIZytMIb8H2h3FMWJd4oUfkUTEH2wAr3qxoRz25uxbTcbqd3WKlm9EHQA==", + "license": "MIT", "dependencies": { - "@vue/compiler-ssr": "3.4.27", - "@vue/shared": "3.4.27" + "@vue/compiler-ssr": "3.4.31", + "@vue/shared": "3.4.31" }, "peerDependencies": { - "vue": "3.4.27" + "vue": "3.4.31" } }, "node_modules/@vue/shared": { - "version": "3.4.27", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.27.tgz", - "integrity": "sha512-DL3NmY2OFlqmYYrzp39yi3LDkKxa5vZVwxWdQ3rG0ekuWscHraeIbnI8t+aZK7qhYqEqWKTUdijadunb9pnrgA==" - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } + "version": "3.4.31", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.31.tgz", + "integrity": "sha512-Yp3wtJk//8cO4NItOPpi3QkLExAr/aLBGZMmTtW9WpdwBCJpRM6zj9WgWktXAl8IDIozwNMByT45JP3tO3ACWA==", + "license": "MIT" }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } + "dev": true, + "license": "MIT" }, "node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, + "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/bulma": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/bulma/-/bulma-1.0.0.tgz", - "integrity": "sha512-7n49v/gdHXaHcU9fVobqGXO2OguiCoMh6CLbeX7jq00XrZ5vOSE4LNS0S/0Q6rlBbckY6kk6W7LwqxS0nu4bug==", - "dependencies": { - "sass": "^1.71.1" - } - }, - "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/bulma/-/bulma-1.0.1.tgz", + "integrity": "sha512-+xv/BIAEQakHkR0QVz+s+RjNqfC53Mx9ZYexyaFNFo9wx5i76HXArNdwW7bccyJxa5mgV/T5DcVGqsAB19nBJQ==", + "license": "MIT" }, "node_modules/computeds": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/computeds/-/computeds-0.0.1.tgz", "integrity": "sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "license": "MIT" }, "node_modules/de-indent": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/entities": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", "engines": { "node": ">=0.12" }, @@ -880,11 +883,12 @@ } }, "node_modules/esbuild": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", - "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", "dev": true, "hasInstallScript": true, + "license": "MIT", "bin": { "esbuild": "bin/esbuild" }, @@ -892,52 +896,44 @@ "node": ">=12" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.20.2", - "@esbuild/android-arm": "0.20.2", - "@esbuild/android-arm64": "0.20.2", - "@esbuild/android-x64": "0.20.2", - "@esbuild/darwin-arm64": "0.20.2", - "@esbuild/darwin-x64": "0.20.2", - "@esbuild/freebsd-arm64": "0.20.2", - "@esbuild/freebsd-x64": "0.20.2", - "@esbuild/linux-arm": "0.20.2", - "@esbuild/linux-arm64": "0.20.2", - "@esbuild/linux-ia32": "0.20.2", - "@esbuild/linux-loong64": "0.20.2", - "@esbuild/linux-mips64el": "0.20.2", - "@esbuild/linux-ppc64": "0.20.2", - "@esbuild/linux-riscv64": "0.20.2", - "@esbuild/linux-s390x": "0.20.2", - "@esbuild/linux-x64": "0.20.2", - "@esbuild/netbsd-x64": "0.20.2", - "@esbuild/openbsd-x64": "0.20.2", - "@esbuild/sunos-x64": "0.20.2", - "@esbuild/win32-arm64": "0.20.2", - "@esbuild/win32-ia32": "0.20.2", - "@esbuild/win32-x64": "0.20.2" + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" } }, "node_modules/estree-walker": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==" - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "license": "MIT" }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, "hasInstallScript": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -946,82 +942,31 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true, + "license": "MIT", "bin": { "he": "bin/he" } }, - "node_modules/immutable": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.3.5.tgz", - "integrity": "sha512-8eabxkth9gZatlwl5TBuJnCsoTADlL6ftEr7A4qgdaTsPyreilDSnUk57SO+jfKcNtxPa22U5KK6DSeAYhpBJw==" - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "engines": { - "node": ">=0.12.0" - } - }, "node_modules/magic-string": { "version": "0.30.10", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", + "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" } }, "node_modules/minimatch": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", - "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==", + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, + "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" }, @@ -1036,7 +981,8 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.4.1.tgz", "integrity": "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/nanoid": { "version": "3.3.7", @@ -1048,6 +994,7 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -1055,40 +1002,23 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/path-browserify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "license": "ISC" }, "node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "version": "8.4.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", + "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", "funding": [ { "type": "opencollective", @@ -1103,9 +1033,10 @@ "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.0.0", + "picocolors": "^1.0.1", "source-map-js": "^1.2.0" }, "engines": { @@ -1113,10 +1044,11 @@ } }, "node_modules/prettier": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", - "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", + "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", "dev": true, + "license": "MIT", "bin": { "prettier": "bin/prettier.cjs" }, @@ -1127,22 +1059,12 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, "node_modules/rollup": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.17.2.tgz", - "integrity": "sha512-/9ClTJPByC0U4zNLowV1tMBe8yMEAxewtR3cUNX5BoEpGH3dQEWpJLr6CLp0fPdYRF/fzVOgvDb1zXuakwF5kQ==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.1.tgz", + "integrity": "sha512-Elx2UT8lzxxOXMpy5HWQGZqkrQOtrVDDa/bm9l10+U4rQnVzbL/LgZ4NOM1MPIDyHk69W4InuYDF5dzRh4Kw1A==", "dev": true, + "license": "MIT", "dependencies": { "@types/estree": "1.0.5" }, @@ -1154,46 +1076,31 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.17.2", - "@rollup/rollup-android-arm64": "4.17.2", - "@rollup/rollup-darwin-arm64": "4.17.2", - "@rollup/rollup-darwin-x64": "4.17.2", - "@rollup/rollup-linux-arm-gnueabihf": "4.17.2", - "@rollup/rollup-linux-arm-musleabihf": "4.17.2", - "@rollup/rollup-linux-arm64-gnu": "4.17.2", - "@rollup/rollup-linux-arm64-musl": "4.17.2", - "@rollup/rollup-linux-powerpc64le-gnu": "4.17.2", - "@rollup/rollup-linux-riscv64-gnu": "4.17.2", - "@rollup/rollup-linux-s390x-gnu": "4.17.2", - "@rollup/rollup-linux-x64-gnu": "4.17.2", - "@rollup/rollup-linux-x64-musl": "4.17.2", - "@rollup/rollup-win32-arm64-msvc": "4.17.2", - "@rollup/rollup-win32-ia32-msvc": "4.17.2", - "@rollup/rollup-win32-x64-msvc": "4.17.2", + "@rollup/rollup-android-arm-eabi": "4.18.1", + "@rollup/rollup-android-arm64": "4.18.1", + "@rollup/rollup-darwin-arm64": "4.18.1", + "@rollup/rollup-darwin-x64": "4.18.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.18.1", + "@rollup/rollup-linux-arm-musleabihf": "4.18.1", + "@rollup/rollup-linux-arm64-gnu": "4.18.1", + "@rollup/rollup-linux-arm64-musl": "4.18.1", + "@rollup/rollup-linux-powerpc64le-gnu": "4.18.1", + "@rollup/rollup-linux-riscv64-gnu": "4.18.1", + "@rollup/rollup-linux-s390x-gnu": "4.18.1", + "@rollup/rollup-linux-x64-gnu": "4.18.1", + "@rollup/rollup-linux-x64-musl": "4.18.1", + "@rollup/rollup-win32-arm64-msvc": "4.18.1", + "@rollup/rollup-win32-ia32-msvc": "4.18.1", + "@rollup/rollup-win32-x64-msvc": "4.18.1", "fsevents": "~2.3.2" } }, - "node_modules/sass": { - "version": "1.77.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.77.0.tgz", - "integrity": "sha512-eGj4HNfXqBWtSnvItNkn7B6icqH14i3CiCGbzMKs3BAPTq62pp9NBYsBgyN4cA+qssqo9r26lW4JSvlaUUWbgw==", - "dependencies": { - "chokidar": ">=3.0.0 <4.0.0", - "immutable": "^4.0.0", - "source-map-js": ">=0.6.2 <2.0.0" - }, - "bin": { - "sass": "sass.js" - }, - "engines": { - "node": ">=14.0.0" - } - }, "node_modules/semver": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.1.tgz", - "integrity": "sha512-f/vbBsu+fOiYt+lmwZV0rVwJScl46HppnOA1ZvIuBWKOTlllpyJ3bfVax76/OrhCH38dyxoDIA8K7uB963IYgA==", + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", "dev": true, + "license": "ISC", "bin": { "semver": "bin/semver.js" }, @@ -1205,26 +1112,17 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, "node_modules/typescript": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", - "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", + "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", "devOptional": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -1234,13 +1132,14 @@ } }, "node_modules/vite": { - "version": "5.2.11", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.11.tgz", - "integrity": "sha512-HndV31LWW05i1BLPMUCE1B9E9GFbOu1MbenhS58FuK6owSO5qHm7GiCotrNY1YE5rMeQSFBGmT5ZaLEjFizgiQ==", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.3.tgz", + "integrity": "sha512-NPQdeCU0Dv2z5fu+ULotpuq5yfCS1BzKUIPhNbP3YBfAMGJXbt2nS+sbTFu+qchaqWTD+H3JK++nRwr6XIcp6A==", "dev": true, + "license": "MIT", "dependencies": { - "esbuild": "^0.20.1", - "postcss": "^8.4.38", + "esbuild": "^0.21.3", + "postcss": "^8.4.39", "rollup": "^4.13.0" }, "bin": { @@ -1288,16 +1187,24 @@ } } }, + "node_modules/vscode-uri": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz", + "integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==", + "dev": true, + "license": "MIT" + }, "node_modules/vue": { - "version": "3.4.27", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.27.tgz", - "integrity": "sha512-8s/56uK6r01r1icG/aEOHqyMVxd1bkYcSe9j8HcKtr/xTOFWvnzIVTehNW+5Yt89f+DLBe4A569pnZLS5HzAMA==", + "version": "3.4.31", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.31.tgz", + "integrity": "sha512-njqRrOy7W3YLAlVqSKpBebtZpDVg21FPoaq1I7f/+qqBThK9ChAIjkRWgeP6Eat+8C+iia4P3OYqpATP21BCoQ==", + "license": "MIT", "dependencies": { - "@vue/compiler-dom": "3.4.27", - "@vue/compiler-sfc": "3.4.27", - "@vue/runtime-dom": "3.4.27", - "@vue/server-renderer": "3.4.27", - "@vue/shared": "3.4.27" + "@vue/compiler-dom": "3.4.31", + "@vue/compiler-sfc": "3.4.31", + "@vue/runtime-dom": "3.4.31", + "@vue/server-renderer": "3.4.31", + "@vue/shared": "3.4.31" }, "peerDependencies": { "typescript": "*" @@ -1313,26 +1220,28 @@ "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.16.tgz", "integrity": "sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==", "dev": true, + "license": "MIT", "dependencies": { "de-indent": "^1.0.2", "he": "^1.2.0" } }, "node_modules/vue-tsc": { - "version": "2.0.16", - "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-2.0.16.tgz", - "integrity": "sha512-/gHAWJa216PeEhfxtAToIbxdWgw01wuQzo48ZUqMYVEyNqDp+OYV9xMO5HaPS2P3Ls0+EsjguMZLY4cGobX4Ew==", + "version": "2.0.26", + "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-2.0.26.tgz", + "integrity": "sha512-tOhuwy2bIXbMhz82ef37qeiaQHMXKQkD6mOF6CCPl3/uYtST3l6fdNyfMxipudrQTxTfXVPlgJdMENBFfC1CfQ==", "dev": true, + "license": "MIT", "dependencies": { - "@volar/typescript": "~2.2.0", - "@vue/language-core": "2.0.16", + "@volar/typescript": "~2.4.0-alpha.15", + "@vue/language-core": "2.0.26", "semver": "^7.5.4" }, "bin": { "vue-tsc": "bin/vue-tsc.js" }, "peerDependencies": { - "typescript": "*" + "typescript": ">=5.0.0" } } } From d7530e6bb0f61a5022ff6ebe4d282c6922c714cb Mon Sep 17 00:00:00 2001 From: ducklet Date: Sun, 14 Jul 2024 16:09:02 +0200 Subject: [PATCH 21/25] fix: support new "most popular 100" & "bottom 100" HTML The previous version had all 100 movies rendered into the HTML. The new version has only the top 25 rendered into HTML, but the whole list has been made available as LD+JSON data. Since we can easily support both, we don't (yet) remove the old parser. --- tests/fixtures/bottom_100-20240714.html.bz2 | Bin 0 -> 178454 bytes .../most_popular_100-20240714.html.bz2 | Bin 0 -> 174956 bytes tests/test_imdb.py | 26 ++++++++--- unwind/imdb.py | 42 ++++++++++++++---- 4 files changed, 54 insertions(+), 14 deletions(-) create mode 100644 tests/fixtures/bottom_100-20240714.html.bz2 create mode 100644 tests/fixtures/most_popular_100-20240714.html.bz2 diff --git a/tests/fixtures/bottom_100-20240714.html.bz2 b/tests/fixtures/bottom_100-20240714.html.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..37ae7f51d952305bdfd01f2212d2eb3051bc9182 GIT binary patch literal 178454 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%0D@Ckw$c>b7YUlaD>*$xtSx~#DTmS7m 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%0AE9MLT&E$( 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

m-*IUhP4DMD#_?nI4uMrZ&MM)r6gImtLXnx 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 EKve{FtpET3 literal 0 HcmV?d00001 diff --git a/tests/test_imdb.py b/tests/test_imdb.py index 7f4efcf..d4a5db5 100644 --- a/tests/test_imdb.py +++ b/tests/test_imdb.py @@ -30,29 +30,43 @@ def test_score_conversion(score: int): assert score == score_from_imdb_rating(imdb_rating_from_score(score)) +@pytest.mark.parametrize( + "fixture", + ( + ("most_popular_100.html.bz2"), + ("most_popular_100-20240714.html.bz2"), + ), +) @pytest.mark.asyncio -async def test_load_most_popular_100(monkeypatch): - with bz2.open(fixturesdir / "most_popular_100.html.bz2", "rb") as f: +async def test_load_most_popular_100(monkeypatch, fixture: str): + with bz2.open(fixturesdir / fixture, "rb") as f: html = f.read() soup = bs4.BeautifulSoup(html, "html5lib") monkeypatch.setattr(imdb, "asoup_from_url", AsyncMock(return_value=soup)) movie_ids = await imdb.load_most_popular_100() - assert len(movie_ids) == 100 + assert len(set(movie_ids)) == 100 assert all(id_.startswith("tt") for id_ in movie_ids) +@pytest.mark.parametrize( + "fixture", + ( + ("bottom_100.html.bz2"), + ("bottom_100-20240714.html.bz2"), + ), +) @pytest.mark.asyncio -async def test_load_bottom_100(monkeypatch): - with bz2.open(fixturesdir / "bottom_100.html.bz2", "rb") as f: +async def test_load_bottom_100(monkeypatch, fixture: str): + with bz2.open(fixturesdir / fixture, "rb") as f: html = f.read() soup = bs4.BeautifulSoup(html, "html5lib") monkeypatch.setattr(imdb, "asoup_from_url", AsyncMock(return_value=soup)) movie_ids = await imdb.load_bottom_100() - assert len(movie_ids) == 100 + assert len(set(movie_ids)) == 100 assert all(id_.startswith("tt") for id_ in movie_ids) diff --git a/unwind/imdb.py b/unwind/imdb.py index 1685ad3..24e3311 100644 --- a/unwind/imdb.py +++ b/unwind/imdb.py @@ -4,7 +4,7 @@ import re from collections import namedtuple from dataclasses import dataclass, field from datetime import datetime -from typing import AsyncIterable +from typing import AsyncIterable, Iterable from urllib.parse import urljoin import bs4 @@ -106,7 +106,9 @@ find_year = re.compile( r"(\([IVX]+\) )?\((?P\d{4})(–( |\d{4})| (?P[^)]+))?\)" # noqa: RUF001 ).fullmatch # find_year_2: e.g. "2024", "1971–2003", "2024–" # noqa: RUF003 -find_year_2 = re.compile(r"(?P\d{4})(–(?P\d{4})?)?").fullmatch # noqa: RUF001 +find_year_2 = re.compile( + r"(?P\d{4})(–(?P\d{4})?)?" # noqa: RUF001 +).fullmatch find_movie_id = re.compile(r"/title/(?Ptt\d+)/").search find_movie_name = re.compile(r"\d+\. (?P.+)").fullmatch # find_vote_count: e.g. "(5.9K)", "(1K)", "(8)" @@ -398,17 +400,33 @@ async def load_ratings(user_id: ImdbUserId) -> AsyncIterable[Rating]: yield rating -async def _ids_from_list_html(url: str) -> AsyncIterable[ImdbMovieId]: - """Return all IMDb movie IDs (`tt*`) from the given URL.""" +def _ids_from_list_html(soup: bs4.BeautifulSoup) -> Iterable[ImdbMovieId]: + """Return all IMDb movie IDs (`tt*`) from the given soup.""" # document.querySelectorAll('li.ipc-metadata-list-summary-item a.ipc-title-link-wrapper') # .href: '/title/tt1213644/?ref_=chtbtm_t_1' # .text(): '1. Disaster Movie' - soup = await asoup_from_url(url) for item in soup.find_all("li", "ipc-metadata-list-summary-item"): if (link := item.find("a", "ipc-title-link-wrapper")) is not None: if (href := link.get("href")) is not None: if match_ := find_movie_id(href): - yield match_["id"] + yield ImdbMovieId(match_["id"]) + + +def _items_from_ldjson(soup: bs4.BeautifulSoup) -> Iterable[dict]: + """Return all items from the LD+JSON block in the given soup.""" + if (item := soup.find("script", type="application/ld+json")) is None: + raise RuntimeError("Could not find LD+JSON data.") + data = json.loads(item.string.strip()) + if data["@type"] != "ItemList": + raise RuntimeError(f"Expected ItemList, got {data['@type']!a}.") + for item in data["itemListElement"]: + yield item["item"] + + +def _ids_from_ldjson(soup: bs4.BeautifulSoup) -> Iterable[ImdbMovieId]: + for item in _items_from_ldjson(soup): + if match_ := find_movie_id(item["url"]): + yield ImdbMovieId(match_["id"]) async def load_most_popular_100() -> list[ImdbMovieId]: @@ -418,7 +436,11 @@ async def load_most_popular_100() -> list[ImdbMovieId]: As determined by IMDb users """ url = "https://www.imdb.com/chart/moviemeter/" - ids = [tid async for tid in _ids_from_list_html(url)] + soup = await asoup_from_url(url) + try: + ids = list(_ids_from_ldjson(soup)) + except RuntimeError: + ids = list(_ids_from_list_html(soup)) if len(ids) != 100: raise RuntimeError(f"Expected exactly 100 items, got {len(ids)}") return ids @@ -431,7 +453,11 @@ async def load_bottom_100() -> list[ImdbMovieId]: Bottom 100 as voted by IMDb users """ url = "https://www.imdb.com/chart/bottom/" - ids = [tid async for tid in _ids_from_list_html(url)] + soup = await asoup_from_url(url) + try: + ids = list(_ids_from_ldjson(soup)) + except RuntimeError: + ids = list(_ids_from_list_html(soup)) if len(ids) != 100: raise RuntimeError(f"Expected exactly 100 items, got {len(ids)}") return ids From 380d6ff1869dbd932f47f815b6cbb5ecba4d301d Mon Sep 17 00:00:00 2001 From: ducklet Date: Sun, 21 Jul 2024 14:46:45 +0200 Subject: [PATCH 22/25] fix: support new user ratings page markup We use __NEXT_DATA__ from the page to find the user's latest rated movies. We found that at least in one case (of a Video Game) the movie details were wrong. Normally this shouldn't be a problem though because we know all the movies already and we keep the values we already have. Otherwise the data from __NEXT_DATA__ seems more accurate and complete. --- .../ratings-ur655321-20240720.gql.json.bz2 | Bin 0 -> 3830 bytes .../ratings-ur655321-20240720.html.bz2 | Bin 0 -> 177521 bytes tests/test_imdb.py | 85 ++++++++-- unwind/imdb.py | 146 +++++++++++++++++- 4 files changed, 217 insertions(+), 14 deletions(-) create mode 100644 tests/fixtures/ratings-ur655321-20240720.gql.json.bz2 create mode 100644 tests/fixtures/ratings-ur655321-20240720.html.bz2 diff --git a/tests/fixtures/ratings-ur655321-20240720.gql.json.bz2 b/tests/fixtures/ratings-ur655321-20240720.gql.json.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..b56b8208cd651fefabb4baf580d301ddf64d581a GIT binary patch literal 3830 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 literal 0 HcmV?d00001 diff --git a/tests/fixtures/ratings-ur655321-20240720.html.bz2 b/tests/fixtures/ratings-ur655321-20240720.html.bz2 new file mode 100644 index 0000000000000000000000000000000000000000..01a633aa7b7058634b9536abf077a6d16d248833 GIT binary patch literal 177521 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 BxAy=5 literal 0 HcmV?d00001 diff --git a/tests/test_imdb.py b/tests/test_imdb.py index d4a5db5..aa3f55a 100644 --- a/tests/test_imdb.py +++ b/tests/test_imdb.py @@ -134,7 +134,7 @@ async def test_load_ratings_page_20240510(monkeypatch): if rating.movie.imdb_id == item["imdb_id"]: rating_dict = {key: getattr(rating.movie, key) for key in item.keys()} return rating_dict - raise AssertionError() + raise AssertionError(f"{item["imdb_id"]} not found in page.ratings") a_movie = { "title": "Kung Fu Panda 4", @@ -142,8 +142,9 @@ async def test_load_ratings_page_20240510(monkeypatch): "media_type": "Movie", "imdb_id": "tt21692408", "imdb_score": 59, - "imdb_votes": 36000, + "imdb_votes": 36069, "runtime": 94, + "genres": {"Action", "Adventure", "Animation"}, } assert a_movie == movie(a_movie) @@ -153,7 +154,8 @@ async def test_load_ratings_page_20240510(monkeypatch): "media_type": "TV Series", "imdb_id": "tt8888540", "imdb_score": 64, - "imdb_votes": 6000, + "imdb_votes": 6044, + "genres": {"Drama"}, } assert a_running_tvseries == movie(a_running_tvseries) @@ -163,29 +165,94 @@ async def test_load_ratings_page_20240510(monkeypatch): "media_type": "TV Series", "imdb_id": "tt0072500", "imdb_score": 87, - "imdb_votes": 100000, + "imdb_votes": 100261, + "genres": {"Comedy"}, } assert a_finished_tvseries == movie(a_finished_tvseries) a_tvepisode = { "title": "Columbo / No Time to Die", - "original_title": None, + "original_title": "Columbo / No Time to Die", "release_year": 1992, "media_type": "TV Episode", "imdb_id": "tt0103987", "imdb_score": 59, - "imdb_votes": 2100, + "imdb_votes": 2122, "runtime": 98, + "genres": {"Crime", "Drama", "Mystery"}, } assert a_tvepisode == movie(a_tvepisode) a_videogame = { "title": "Alan Wake", - "original_title": None, + "original_title": "Alan Wake", "release_year": 2010, "media_type": "Video Game", "imdb_id": "tt0466662", - "imdb_score": 82, - "imdb_votes": 7300, + # The data from __NEXT_DATA__ is wrong, the actual values should be: + # "imdb_score": 82, + # "imdb_votes": 7300, + # "genres": {"Action", "Adventure", "Horror"}, + "imdb_score": 67, # Wrong value, but correctly parsed from __NEXT_DATA__ + "imdb_votes": 11655, # Wrong value, but correctly parsed from __NEXT_DATA__ + "genres": {"Comedy", "Crime", "Drama"}, # Wrong value } assert a_videogame == movie(a_videogame) + + +@pytest.mark.asyncio +async def test_load_ratings_page_20240720(monkeypatch): + with bz2.open(fixturesdir / "ratings-ur655321-20240720.html.bz2", "rb") as f: + html = f.read() + soup = bs4.BeautifulSoup(html, "html5lib") + monkeypatch.setattr(imdb, "asoup_from_url", AsyncMock(return_value=soup)) + + with bz2.open(fixturesdir / "ratings-ur655321-20240720.gql.json.bz2", "rb") as f: + jsonstr = f.read() + async with imdb.asession() as s: + monkeypatch.setattr(s, "post", AsyncMock(return_value=_mock_response(jsonstr))) + page = await imdb._load_ratings_page("fakeurl", "ur655321") + assert len(page.ratings) == 100 + assert page.imdb_user_id is not None + assert page.imdb_user_id == "ur655321" + assert page.imdb_user_name == "AlexUltra" + assert page.next_page_url is None, "not supported for new ratings page" + + def movie(item: dict): + for rating in page.ratings: + assert rating.movie + if rating.movie.imdb_id == item["imdb_id"]: + rating_dict = {key: getattr(rating.movie, key) for key in item.keys()} + return rating_dict + raise AssertionError(f"{item["imdb_id"]} not found in page.ratings") + + a_movie = { + "title": "Kung Fu Panda 4", + "release_year": 2024, + "media_type": "Movie", + "imdb_id": "tt21692408", + "imdb_score": 59, + "imdb_votes": 48018, + "runtime": 94, + } + assert a_movie == movie(a_movie) + + a_running_tvseries = { + "title": "Palm Royale", + "release_year": 2024, + "media_type": "TV Series", + "imdb_id": "tt8888540", + "imdb_score": 63, + "imdb_votes": 9458, + } + assert a_running_tvseries == movie(a_running_tvseries) + + a_finished_tvseries = { + "title": "Fawlty Towers", + "release_year": 1975, + "media_type": "TV Series", + "imdb_id": "tt0072500", + "imdb_score": 87, + "imdb_votes": 100860, + } + assert a_finished_tvseries == movie(a_finished_tvseries) diff --git a/unwind/imdb.py b/unwind/imdb.py index 24e3311..3d844a5 100644 --- a/unwind/imdb.py +++ b/unwind/imdb.py @@ -4,7 +4,7 @@ import re from collections import namedtuple from dataclasses import dataclass, field from datetime import datetime -from typing import AsyncIterable, Iterable +from typing import Any, AsyncIterable, Iterable from urllib.parse import urljoin import bs4 @@ -116,9 +116,8 @@ find_vote_count = re.compile(r"\((?P\d+(\.\d+)?K?)\)").fullmatch def _first_string(tag: bs4.Tag) -> str | None: - for child in tag.children: - if isinstance(child, str): - return child + for s in tag.strings: + return s def _tv_episode_title(series_name: str, episode_name: str) -> str: @@ -244,7 +243,8 @@ async def _load_ratings_page(url: str, user_id: ImdbUserId) -> _RatingsPage: """Dispatch to handlers for different ratings page versions.""" soup = await asoup_from_url(url) - + if soup.find("script", id="__NEXT_DATA__", type="application/json") is not None: + return await _load_ratings_page_202407(user_id, url, soup) if soup.find("meta", property="imdb:pageConst") is not None: return await _load_ratings_page_2024(user_id, url, soup) elif soup.find("meta", property="pageId") is not None: @@ -253,6 +253,90 @@ async def _load_ratings_page(url: str, user_id: ImdbUserId) -> _RatingsPage: raise RuntimeError("Unknown ratings page version.") +def _get_or_None(d: dict[str, Any], keys: list[str]) -> Any | None: + for k in keys: + try: + d = d[k] + except KeyError: + return None + if d is None: + break + return d + + +def _parse_movies_from_nextdata_202407(nextdata: dict) -> Iterable[Movie]: + nextratings = nextdata["props"]["pageProps"]["mainColumnData"][ + "advancedTitleSearch" + ]["edges"] + for ratingdata in nextratings: + ratingdata = ratingdata["node"]["title"] + # endYear=ratingdata["releaseYear"]["endYear"] + imdb_rating = _get_or_None(ratingdata, ["ratingsSummary", "aggregateRating"]) + runtime_s = _get_or_None(ratingdata, ["runtime", "seconds"]) + + movie = Movie( + title=ratingdata["titleText"]["text"], + original_title=_get_or_None(ratingdata, ["originalTitleText", "text"]), + release_year=ratingdata["releaseYear"]["year"], + media_type=ratingdata["titleType"]["text"], + imdb_id=ratingdata["id"], + imdb_score=( + None if imdb_rating is None else score_from_imdb_rating(imdb_rating) + ), + imdb_votes=_get_or_None(ratingdata, ["ratingsSummary", "voteCount"]), + runtime=None if runtime_s is None else int(runtime_s / 60), + genres={ + genre["genre"]["text"] for genre in ratingdata["titleGenres"]["genres"] + }, + ) + + if movie.media_type == "TV Episode": + seriesdata = ratingdata["series"]["series"] + series_original_title = seriesdata["originalTitleText"]["text"] + series_title = seriesdata["titleText"]["text"] + # series_id = seriesdata["releaseYear"]["id"] + # series_year = seriesdata["releaseYear"]["year"] + # series_endyear = seriesdata["releaseYear"]["endYear"] + movie.title = _tv_episode_title(series_title, movie.title) + movie.original_title = _tv_episode_title( + series_original_title, movie.original_title + ) + + yield movie + + +async def _load_ratings_page_202407( + user_id: ImdbUserId, url: str, soup: bs4.BeautifulSoup +) -> _RatingsPage: + """Handle the ratings page from July 2024.""" + if ( + nextjson := soup.find("script", id="__NEXT_DATA__", type="application/json") + ) is None: + raise RuntimeError("No __NEXT_DATA__ BLOB found.") + + nextdata = json.loads(nextjson.string.strip()) + userdata = nextdata["props"]["pageProps"]["aboveTheFoldData"] + + page = _RatingsPage( + imdb_user_id=userdata["authorId"], + imdb_user_name=userdata["authorName"], + ) + + movies = _parse_movies_from_nextdata_202407(nextdata) + movies_dict = {m.imdb_id: m for m in movies} + async for rating in _load_user_movie_ratings(user_id, list(movies_dict.keys())): + movie = movies_dict[rating.movie_id] + rating = Rating( + movie=movie, + score=score_from_imdb_rating(rating.imdb_rating), + rating_date=rating.rating_date, + ) + + page.ratings.append(rating) + + return page + + async def _load_ratings_page_2024( user_id: ImdbUserId, url: str, soup: bs4.BeautifulSoup ) -> _RatingsPage: @@ -559,3 +643,55 @@ async def _load_user_movie_ratings( except KeyError as err: log.error("Unexpected data structure.", exc_info=err) raise + + +async def _load_user_ratings_202407( + user_id: ImdbUserId, movie_ids: list[ImdbMovieId] +) -> AsyncIterable[_UserMovieRating]: + """ + + This is a new API that showed up in July 2024. + It's used on a user's ratings page to load their ratings. + """ + raise NotImplementedError() + + qgl_api_url = "https://api.graphql.imdb.com/" + headers = { + "accept": "application/graphql+json, application/json", + "content-type": "application/json", + "origin": "https://www.imdb.com", + } + query = { + "operationName": "RatingsPage", + "variables": json.dumps( + { + # "after": ..., + "filter": { + "explicitContentConstraint": { + "explicitContentFilter": "INCLUDE_ADULT" + }, + "singleUserRatingConstraint": { + "filterType": "INCLUDE", + "userId": user_id, + }, + }, + "first": 100, + "locale": "en-US", + "sort": {"sortBy": "SINGLE_USER_RATING_DATE", "sortOrder": "ASC"}, + } + ), + "extensions": json.dumps( + { + "persistedQuery": { + "sha256Hash": "ae30a55f169252b5f0208d686f41aaff231d7f70bb75c257732c80234d71dbe9", + "version": 1, + } + } + ), + } + async with asession() as s: + r = await s.get(qgl_api_url, headers=headers, query=query, timeout=10) + r.raise_for_status() + data = r.json() + + # ... From 5c272b511091d51728b84933f065e1f6f7a6d028 Mon Sep 17 00:00:00 2001 From: ducklet Date: Sun, 21 Jul 2024 14:48:32 +0200 Subject: [PATCH 23/25] run update --- poetry.lock | 72 +++++----- pyproject.toml | 2 +- unwind-ui/package-lock.json | 276 ++++++++++++++++++------------------ 3 files changed, 175 insertions(+), 175 deletions(-) diff --git a/poetry.lock b/poetry.lock index b2aa260..2e995a1 100644 --- a/poetry.lock +++ b/poetry.lock @@ -492,13 +492,13 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "pyright" -version = "1.1.371" +version = "1.1.372" description = "Command line wrapper for pyright" optional = false python-versions = ">=3.7" files = [ - {file = "pyright-1.1.371-py3-none-any.whl", hash = "sha256:cce52e42ff73943243e7e5e24f2a59dee81b97d99f4e3cf97370b27e8a1858cd"}, - {file = "pyright-1.1.371.tar.gz", hash = "sha256:777b508b92dda2db476214c400ce043aad8d8f3dd0e10d284c96e79f298308b5"}, + {file = "pyright-1.1.372-py3-none-any.whl", hash = "sha256:25b15fb8967740f0949fd35b963777187f0a0404c0bd753cc966ec139f3eaa0b"}, + {file = "pyright-1.1.372.tar.gz", hash = "sha256:a9f5e0daa955daaa17e3d1ef76d3623e75f8afd5e37b437d3ff84d5b38c15420"}, ] [package.dependencies] @@ -510,33 +510,33 @@ dev = ["twine (>=3.4.1)"] [[package]] name = "pytest" -version = "8.2.2" +version = "8.3.1" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-8.2.2-py3-none-any.whl", hash = "sha256:c434598117762e2bd304e526244f67bf66bbd7b5d6cf22138be51ff661980343"}, - {file = "pytest-8.2.2.tar.gz", hash = "sha256:de4bb8104e201939ccdc688b27a89a7be2079b22e2bd2b07f806b6ba71117977"}, + {file = "pytest-8.3.1-py3-none-any.whl", hash = "sha256:e9600ccf4f563976e2c99fa02c7624ab938296551f280835ee6516df8bc4ae8c"}, + {file = "pytest-8.3.1.tar.gz", hash = "sha256:7e8e5c5abd6e93cb1cc151f23e57adc31fcf8cfd2a3ff2da63e23f732de35db6"}, ] [package.dependencies] colorama = {version = "*", markers = "sys_platform == \"win32\""} iniconfig = "*" packaging = "*" -pluggy = ">=1.5,<2.0" +pluggy = ">=1.5,<2" [package.extras] dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] [[package]] name = "pytest-asyncio" -version = "0.23.7" +version = "0.23.8" description = "Pytest support for asyncio" optional = false python-versions = ">=3.8" files = [ - {file = "pytest_asyncio-0.23.7-py3-none-any.whl", hash = "sha256:009b48127fbe44518a547bddd25611551b0e43ccdbf1e67d12479f569832c20b"}, - {file = "pytest_asyncio-0.23.7.tar.gz", hash = "sha256:5f5c72948f4c49e7db4f29f2521d4031f1c27f86e57b046126654083d4770268"}, + {file = "pytest_asyncio-0.23.8-py3-none-any.whl", hash = "sha256:50265d892689a5faefb84df80819d1ecef566eb3549cf915dfb33569359d1ce2"}, + {file = "pytest_asyncio-0.23.8.tar.gz", hash = "sha256:759b10b33a6dc61cce40a8bd5205e302978bbbcc00e279a8b61d9a6a3c82e4d3"}, ] [package.dependencies] @@ -566,29 +566,29 @@ testing = ["fields", "hunter", "process-tests", "pytest-xdist", "virtualenv"] [[package]] name = "ruff" -version = "0.5.1" +version = "0.5.4" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.5.1-py3-none-linux_armv6l.whl", hash = "sha256:6ecf968fcf94d942d42b700af18ede94b07521bd188aaf2cd7bc898dd8cb63b6"}, - {file = "ruff-0.5.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:204fb0a472f00f2e6280a7c8c7c066e11e20e23a37557d63045bf27a616ba61c"}, - {file = "ruff-0.5.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d235968460e8758d1e1297e1de59a38d94102f60cafb4d5382033c324404ee9d"}, - {file = "ruff-0.5.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38beace10b8d5f9b6bdc91619310af6d63dd2019f3fb2d17a2da26360d7962fa"}, - {file = "ruff-0.5.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e478d2f09cf06add143cf8c4540ef77b6599191e0c50ed976582f06e588c994"}, - {file = "ruff-0.5.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f0368d765eec8247b8550251c49ebb20554cc4e812f383ff9f5bf0d5d94190b0"}, - {file = "ruff-0.5.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:3a9a9a1b582e37669b0138b7c1d9d60b9edac880b80eb2baba6d0e566bdeca4d"}, - {file = "ruff-0.5.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bdd9f723e16003623423affabcc0a807a66552ee6a29f90eddad87a40c750b78"}, - {file = "ruff-0.5.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:be9fd62c1e99539da05fcdc1e90d20f74aec1b7a1613463ed77870057cd6bd96"}, - {file = "ruff-0.5.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e216fc75a80ea1fbd96af94a6233d90190d5b65cc3d5dfacf2bd48c3e067d3e1"}, - {file = "ruff-0.5.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:c4c2112e9883a40967827d5c24803525145e7dab315497fae149764979ac7929"}, - {file = "ruff-0.5.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:dfaf11c8a116394da3b65cd4b36de30d8552fa45b8119b9ef5ca6638ab964fa3"}, - {file = "ruff-0.5.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:d7ceb9b2fe700ee09a0c6b192c5ef03c56eb82a0514218d8ff700f6ade004108"}, - {file = "ruff-0.5.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:bac6288e82f6296f82ed5285f597713acb2a6ae26618ffc6b429c597b392535c"}, - {file = "ruff-0.5.1-py3-none-win32.whl", hash = "sha256:5c441d9c24ec09e1cb190a04535c5379b36b73c4bc20aa180c54812c27d1cca4"}, - {file = "ruff-0.5.1-py3-none-win_amd64.whl", hash = "sha256:b1789bf2cd3d1b5a7d38397cac1398ddf3ad7f73f4de01b1e913e2abc7dfc51d"}, - {file = "ruff-0.5.1-py3-none-win_arm64.whl", hash = "sha256:2875b7596a740cbbd492f32d24be73e545a4ce0a3daf51e4f4e609962bfd3cd2"}, - {file = "ruff-0.5.1.tar.gz", hash = "sha256:3164488aebd89b1745b47fd00604fb4358d774465f20d1fcd907f9c0fc1b0655"}, + {file = "ruff-0.5.4-py3-none-linux_armv6l.whl", hash = "sha256:82acef724fc639699b4d3177ed5cc14c2a5aacd92edd578a9e846d5b5ec18ddf"}, + {file = "ruff-0.5.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:da62e87637c8838b325e65beee485f71eb36202ce8e3cdbc24b9fcb8b99a37be"}, + {file = "ruff-0.5.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e98ad088edfe2f3b85a925ee96da652028f093d6b9b56b76fc242d8abb8e2059"}, + {file = "ruff-0.5.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c55efbecc3152d614cfe6c2247a3054cfe358cefbf794f8c79c8575456efe19"}, + {file = "ruff-0.5.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f9b85eaa1f653abd0a70603b8b7008d9e00c9fa1bbd0bf40dad3f0c0bdd06793"}, + {file = "ruff-0.5.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0cf497a47751be8c883059c4613ba2f50dd06ec672692de2811f039432875278"}, + {file = "ruff-0.5.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:09c14ed6a72af9ccc8d2e313d7acf7037f0faff43cde4b507e66f14e812e37f7"}, + {file = "ruff-0.5.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:628f6b8f97b8bad2490240aa84f3e68f390e13fabc9af5c0d3b96b485921cd60"}, + {file = "ruff-0.5.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3520a00c0563d7a7a7c324ad7e2cde2355733dafa9592c671fb2e9e3cd8194c1"}, + {file = "ruff-0.5.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93789f14ca2244fb91ed481456f6d0bb8af1f75a330e133b67d08f06ad85b516"}, + {file = "ruff-0.5.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:029454e2824eafa25b9df46882f7f7844d36fd8ce51c1b7f6d97e2615a57bbcc"}, + {file = "ruff-0.5.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:9492320eed573a13a0bc09a2957f17aa733fff9ce5bf00e66e6d4a88ec33813f"}, + {file = "ruff-0.5.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a6e1f62a92c645e2919b65c02e79d1f61e78a58eddaebca6c23659e7c7cb4ac7"}, + {file = "ruff-0.5.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:768fa9208df2bec4b2ce61dbc7c2ddd6b1be9fb48f1f8d3b78b3332c7d71c1ff"}, + {file = "ruff-0.5.4-py3-none-win32.whl", hash = "sha256:e1e7393e9c56128e870b233c82ceb42164966f25b30f68acbb24ed69ce9c3a4e"}, + {file = "ruff-0.5.4-py3-none-win_amd64.whl", hash = "sha256:58b54459221fd3f661a7329f177f091eb35cf7a603f01d9eb3eb11cc348d38c4"}, + {file = "ruff-0.5.4-py3-none-win_arm64.whl", hash = "sha256:bd53da65f1085fb5b307c38fd3c0829e76acf7b2a912d8d79cadcdb4875c1eb7"}, + {file = "ruff-0.5.4.tar.gz", hash = "sha256:2795726d5f71c4f4e70653273d1c23a8182f07dd8e48c12de5d867bfb7557eed"}, ] [[package]] @@ -714,13 +714,13 @@ sqlcipher = ["sqlcipher3_binary"] [[package]] name = "starlette" -version = "0.37.2" +version = "0.38.0" description = "The little ASGI library that shines." optional = false python-versions = ">=3.8" files = [ - {file = "starlette-0.37.2-py3-none-any.whl", hash = "sha256:6fe59f29268538e5d0d182f2791a479a0c64638e6935d1c6989e63fb2699c6ee"}, - {file = "starlette-0.37.2.tar.gz", hash = "sha256:9af890290133b79fc3db55474ade20f6220a364a0402e0b556e7cd5e1e093823"}, + {file = "starlette-0.38.0-py3-none-any.whl", hash = "sha256:dd58f5854ca4fc476710e48d61b29fa4ff3639d42604a786f9d2091e64b95c7e"}, + {file = "starlette-0.38.0.tar.gz", hash = "sha256:1ac2291e946a56bb5ca929dbb2332fc0dfd1e609c7e4d4f2056925cc0442874e"}, ] [package.dependencies] @@ -753,13 +753,13 @@ files = [ [[package]] name = "uvicorn" -version = "0.30.1" +version = "0.30.3" description = "The lightning-fast ASGI server." optional = false python-versions = ">=3.8" files = [ - {file = "uvicorn-0.30.1-py3-none-any.whl", hash = "sha256:cd17daa7f3b9d7a24de3617820e634d0933b69eed8e33a516071174427238c81"}, - {file = "uvicorn-0.30.1.tar.gz", hash = "sha256:d46cd8e0fd80240baffbcd9ec1012a712938754afcf81bce56c024c1656aece8"}, + {file = "uvicorn-0.30.3-py3-none-any.whl", hash = "sha256:94a3608da0e530cea8f69683aa4126364ac18e3826b6630d1a65f4638aade503"}, + {file = "uvicorn-0.30.3.tar.gz", hash = "sha256:0d114d0831ff1adbf231d358cbf42f17333413042552a624ea6a9b4c33dcfd81"}, ] [package.dependencies] @@ -783,4 +783,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "c0a9d4f094807ba59923de4ecf87985eba2cdcd7b78d7adbf430455b3cc6be5d" +content-hash = "be28fa6d62e8b58f1265c498cfd7c1e4c1dff067b59ac7a39204beee23e94c4f" diff --git a/pyproject.toml b/pyproject.toml index a7ca0e2..fc65c56 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,7 +13,7 @@ license = "LOL" python = "^3.12" beautifulsoup4 = "^4.9.3" html5lib = "^1.1" -starlette = "^0.37.2" +starlette = "^0.38.0" ulid-py = "^1.1.0" uvicorn = "^0.30.1" httpx = "^0.27.0" diff --git a/unwind-ui/package-lock.json b/unwind-ui/package-lock.json index 8386cfc..fa3c571 100644 --- a/unwind-ui/package-lock.json +++ b/unwind-ui/package-lock.json @@ -429,9 +429,9 @@ "license": "MIT" }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.1.tgz", - "integrity": "sha512-lncuC4aHicncmbORnx+dUaAgzee9cm/PbIqgWz1PpXuwc+sa1Ct83tnqUDy/GFKleLiN7ZIeytM6KJ4cAn1SxA==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.19.0.tgz", + "integrity": "sha512-JlPfZ/C7yn5S5p0yKk7uhHTTnFlvTgLetl2VxqE518QgyM7C9bSfFTYvB/Q/ftkq0RIPY4ySxTz+/wKJ/dXC0w==", "cpu": [ "arm" ], @@ -443,9 +443,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.18.1.tgz", - "integrity": "sha512-F/tkdw0WSs4ojqz5Ovrw5r9odqzFjb5LIgHdHZG65dFI1lWTWRVy32KDJLKRISHgJvqUeUhdIvy43fX41znyDg==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.19.0.tgz", + "integrity": "sha512-RDxUSY8D1tWYfn00DDi5myxKgOk6RvWPxhmWexcICt/MEC6yEMr4HNCu1sXXYLw8iAsg0D44NuU+qNq7zVWCrw==", "cpu": [ "arm64" ], @@ -457,9 +457,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.18.1.tgz", - "integrity": "sha512-vk+ma8iC1ebje/ahpxpnrfVQJibTMyHdWpOGZ3JpQ7Mgn/3QNHmPq7YwjZbIE7km73dH5M1e6MRRsnEBW7v5CQ==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.19.0.tgz", + "integrity": "sha512-emvKHL4B15x6nlNTBMtIaC9tLPRpeA5jMvRLXVbl/W9Ie7HhkrE7KQjvgS9uxgatL1HmHWDXk5TTS4IaNJxbAA==", "cpu": [ "arm64" ], @@ -471,9 +471,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.18.1.tgz", - "integrity": "sha512-IgpzXKauRe1Tafcej9STjSSuG0Ghu/xGYH+qG6JwsAUxXrnkvNHcq/NL6nz1+jzvWAnQkuAJ4uIwGB48K9OCGA==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.19.0.tgz", + "integrity": "sha512-fO28cWA1dC57qCd+D0rfLC4VPbh6EOJXrreBmFLWPGI9dpMlER2YwSPZzSGfq11XgcEpPukPTfEVFtw2q2nYJg==", "cpu": [ "x64" ], @@ -485,9 +485,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.18.1.tgz", - "integrity": "sha512-P9bSiAUnSSM7EmyRK+e5wgpqai86QOSv8BwvkGjLwYuOpaeomiZWifEos517CwbG+aZl1T4clSE1YqqH2JRs+g==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.19.0.tgz", + "integrity": "sha512-2Rn36Ubxdv32NUcfm0wB1tgKqkQuft00PtM23VqLuCUR4N5jcNWDoV5iBC9jeGdgS38WK66ElncprqgMUOyomw==", "cpu": [ "arm" ], @@ -499,9 +499,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.18.1.tgz", - "integrity": "sha512-5RnjpACoxtS+aWOI1dURKno11d7krfpGDEn19jI8BuWmSBbUC4ytIADfROM1FZrFhQPSoP+KEa3NlEScznBTyQ==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.19.0.tgz", + "integrity": "sha512-gJuzIVdq/X1ZA2bHeCGCISe0VWqCoNT8BvkQ+BfsixXwTOndhtLUpOg0A1Fcx/+eA6ei6rMBzlOz4JzmiDw7JQ==", "cpu": [ "arm" ], @@ -513,9 +513,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.18.1.tgz", - "integrity": "sha512-8mwmGD668m8WaGbthrEYZ9CBmPug2QPGWxhJxh/vCgBjro5o96gL04WLlg5BA233OCWLqERy4YUzX3bJGXaJgQ==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.19.0.tgz", + "integrity": "sha512-0EkX2HYPkSADo9cfeGFoQ7R0/wTKb7q6DdwI4Yn/ULFE1wuRRCHybxpl2goQrx4c/yzK3I8OlgtBu4xvted0ug==", "cpu": [ "arm64" ], @@ -527,9 +527,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.18.1.tgz", - "integrity": "sha512-dJX9u4r4bqInMGOAQoGYdwDP8lQiisWb9et+T84l2WXk41yEej8v2iGKodmdKimT8cTAYt0jFb+UEBxnPkbXEQ==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.19.0.tgz", + "integrity": "sha512-GlIQRj9px52ISomIOEUq/IojLZqzkvRpdP3cLgIE1wUWaiU5Takwlzpz002q0Nxxr1y2ZgxC2obWxjr13lvxNQ==", "cpu": [ "arm64" ], @@ -541,9 +541,9 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.18.1.tgz", - "integrity": "sha512-V72cXdTl4EI0x6FNmho4D502sy7ed+LuVW6Ym8aI6DRQ9hQZdp5sj0a2usYOlqvFBNKQnLQGwmYnujo2HvjCxQ==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.19.0.tgz", + "integrity": "sha512-N6cFJzssruDLUOKfEKeovCKiHcdwVYOT1Hs6dovDQ61+Y9n3Ek4zXvtghPPelt6U0AH4aDGnDLb83uiJMkWYzQ==", "cpu": [ "ppc64" ], @@ -555,9 +555,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.18.1.tgz", - "integrity": "sha512-f+pJih7sxoKmbjghrM2RkWo2WHUW8UbfxIQiWo5yeCaCM0TveMEuAzKJte4QskBp1TIinpnRcxkquY+4WuY/tg==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.19.0.tgz", + "integrity": "sha512-2DnD3mkS2uuam/alF+I7M84koGwvn3ZVD7uG+LEWpyzo/bq8+kKnus2EVCkcvh6PlNB8QPNFOz6fWd5N8o1CYg==", "cpu": [ "riscv64" ], @@ -569,9 +569,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.18.1.tgz", - "integrity": "sha512-qb1hMMT3Fr/Qz1OKovCuUM11MUNLUuHeBC2DPPAWUYYUAOFWaxInaTwTQmc7Fl5La7DShTEpmYwgdt2hG+4TEg==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.19.0.tgz", + "integrity": "sha512-D6pkaF7OpE7lzlTOFCB2m3Ngzu2ykw40Nka9WmKGUOTS3xcIieHe82slQlNq69sVB04ch73thKYIWz/Ian8DUA==", "cpu": [ "s390x" ], @@ -583,9 +583,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.1.tgz", - "integrity": "sha512-7O5u/p6oKUFYjRbZkL2FLbwsyoJAjyeXHCU3O4ndvzg2OFO2GinFPSJFGbiwFDaCFc+k7gs9CF243PwdPQFh5g==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.19.0.tgz", + "integrity": "sha512-HBndjQLP8OsdJNSxpNIN0einbDmRFg9+UQeZV1eiYupIRuZsDEoeGU43NQsS34Pp166DtwQOnpcbV/zQxM+rWA==", "cpu": [ "x64" ], @@ -597,9 +597,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.18.1.tgz", - "integrity": "sha512-pDLkYITdYrH/9Cv/Vlj8HppDuLMDUBmgsM0+N+xLtFd18aXgM9Nyqupb/Uw+HeidhfYg2lD6CXvz6CjoVOaKjQ==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.19.0.tgz", + "integrity": "sha512-HxfbvfCKJe/RMYJJn0a12eiOI9OOtAUF4G6ozrFUK95BNyoJaSiBjIOHjZskTUffUrB84IPKkFG9H9nEvJGW6A==", "cpu": [ "x64" ], @@ -611,9 +611,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.18.1.tgz", - "integrity": "sha512-W2ZNI323O/8pJdBGil1oCauuCzmVd9lDmWBBqxYZcOqWD6aWqJtVBQ1dFrF4dYpZPks6F+xCZHfzG5hYlSHZ6g==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.19.0.tgz", + "integrity": "sha512-HxDMKIhmcguGTiP5TsLNolwBUK3nGGUEoV/BO9ldUBoMLBssvh4J0X8pf11i1fTV7WShWItB1bKAKjX4RQeYmg==", "cpu": [ "arm64" ], @@ -625,9 +625,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.18.1.tgz", - "integrity": "sha512-ELfEX1/+eGZYMaCIbK4jqLxO1gyTSOIlZr6pbC4SRYFaSIDVKOnZNMdoZ+ON0mrFDp4+H5MhwNC1H/AhE3zQLg==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.19.0.tgz", + "integrity": "sha512-xItlIAZZaiG/u0wooGzRsx11rokP4qyc/79LkAOdznGRAbOFc+SfEdfUOszG1odsHNgwippUJavag/+W/Etc6Q==", "cpu": [ "ia32" ], @@ -639,9 +639,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.18.1.tgz", - "integrity": "sha512-yjk2MAkQmoaPYCSu35RLJ62+dz358nE83VfTePJRp8CG7aMg25mEJYpXFiD+NcevhX8LxD5OP5tktPXnXN7GDw==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.19.0.tgz", + "integrity": "sha512-xNo5fV5ycvCCKqiZcpB65VMR11NJB+StnxHz20jdqRAktfdfzhgjTiJ2doTDQE/7dqGaV5I7ZGqKpgph6lCIag==", "cpu": [ "x64" ], @@ -674,82 +674,82 @@ } }, "node_modules/@volar/language-core": { - "version": "2.4.0-alpha.15", - "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.4.0-alpha.15.tgz", - "integrity": "sha512-mt8z4Fm2WxfQYoQHPcKVjLQV6PgPqyKLbkCVY2cr5RSaamqCHjhKEpsFX66aL4D/7oYguuaUw9Bx03Vt0TpIIA==", + "version": "2.4.0-alpha.17", + "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.4.0-alpha.17.tgz", + "integrity": "sha512-FF9g89QZUVJpgZvrNpA+v5Sgo7MdUjeA1celxCe4nFTpfp4P/FUdZ1lgeYy7ZS5r13oC4Ei6HqWpfLN7PFM60w==", "dev": true, "license": "MIT", "dependencies": { - "@volar/source-map": "2.4.0-alpha.15" + "@volar/source-map": "2.4.0-alpha.17" } }, "node_modules/@volar/source-map": { - "version": "2.4.0-alpha.15", - "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.4.0-alpha.15.tgz", - "integrity": "sha512-8Htngw5TmBY4L3ClDqBGyfLhsB8EmoEXUH1xydyEtEoK0O6NX5ur4Jw8jgvscTlwzizyl/wsN1vn0cQXVbbXYg==", + "version": "2.4.0-alpha.17", + "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.4.0-alpha.17.tgz", + "integrity": "sha512-6LOuR2nIloQCSNMNcUPRPLjL5CInIE1pYZ8lifOCSxQRiz8GcWaOm34kAvdm7pzPQqMRHBBnV/Ihkdt/w7oWAQ==", "dev": true, "license": "MIT" }, "node_modules/@volar/typescript": { - "version": "2.4.0-alpha.15", - "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.4.0-alpha.15.tgz", - "integrity": "sha512-U3StRBbDuxV6Woa4hvGS4kz3XcOzrWUKgFdEFN+ba1x3eaYg7+ytau8ul05xgA+UNGLXXsKur7fTUhDFyISk0w==", + "version": "2.4.0-alpha.17", + "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.4.0-alpha.17.tgz", + "integrity": "sha512-oJlz5xJd0O1Xe/I7AV3kPpV6gXlcyxfpMcj/w4/wGY5AxFHxyy5i7VhaE/BVk99zsT6M2KxcZyUSsL55RlNXlQ==", "dev": true, "license": "MIT", "dependencies": { - "@volar/language-core": "2.4.0-alpha.15", + "@volar/language-core": "2.4.0-alpha.17", "path-browserify": "^1.0.1", "vscode-uri": "^3.0.8" } }, "node_modules/@vue/compiler-core": { - "version": "3.4.31", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.31.tgz", - "integrity": "sha512-skOiodXWTV3DxfDhB4rOf3OGalpITLlgCeOwb+Y9GJpfQ8ErigdBUHomBzvG78JoVE8MJoQsb+qhZiHfKeNeEg==", + "version": "3.4.33", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.33.tgz", + "integrity": "sha512-MoIREbkdPQlnGfSKDMgzTqzqx5nmEjIc0ydLVYlTACGBsfvOJ4tHSbZXKVF536n6fB+0eZaGEOqsGThPpdvF5A==", "license": "MIT", "dependencies": { "@babel/parser": "^7.24.7", - "@vue/shared": "3.4.31", + "@vue/shared": "3.4.33", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.0" } }, "node_modules/@vue/compiler-dom": { - "version": "3.4.31", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.31.tgz", - "integrity": "sha512-wK424WMXsG1IGMyDGyLqB+TbmEBFM78hIsOJ9QwUVLGrcSk0ak6zYty7Pj8ftm7nEtdU/DGQxAXp0/lM/2cEpQ==", + "version": "3.4.33", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.33.tgz", + "integrity": "sha512-GzB8fxEHKw0gGet5BKlpfXEqoBnzSVWwMnT+dc25wE7pFEfrU/QsvjZMP9rD4iVXHBBoemTct8mN0GJEI6ZX5A==", "license": "MIT", "dependencies": { - "@vue/compiler-core": "3.4.31", - "@vue/shared": "3.4.31" + "@vue/compiler-core": "3.4.33", + "@vue/shared": "3.4.33" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.4.31", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.31.tgz", - "integrity": "sha512-einJxqEw8IIJxzmnxmJBuK2usI+lJonl53foq+9etB2HAzlPjAS/wa7r0uUpXw5ByX3/0uswVSrjNb17vJm1kQ==", + "version": "3.4.33", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.33.tgz", + "integrity": "sha512-7rk7Vbkn21xMwIUpHQR4hCVejwE6nvhBOiDgoBcR03qvGqRKA7dCBSsHZhwhYUsmjlbJ7OtD5UFIyhP6BY+c8A==", "license": "MIT", "dependencies": { "@babel/parser": "^7.24.7", - "@vue/compiler-core": "3.4.31", - "@vue/compiler-dom": "3.4.31", - "@vue/compiler-ssr": "3.4.31", - "@vue/shared": "3.4.31", + "@vue/compiler-core": "3.4.33", + "@vue/compiler-dom": "3.4.33", + "@vue/compiler-ssr": "3.4.33", + "@vue/shared": "3.4.33", "estree-walker": "^2.0.2", "magic-string": "^0.30.10", - "postcss": "^8.4.38", + "postcss": "^8.4.39", "source-map-js": "^1.2.0" } }, "node_modules/@vue/compiler-ssr": { - "version": "3.4.31", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.31.tgz", - "integrity": "sha512-RtefmITAje3fJ8FSg1gwgDhdKhZVntIVbwupdyZDSifZTRMiWxWehAOTCc8/KZDnBOcYQ4/9VWxsTbd3wT0hAA==", + "version": "3.4.33", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.33.tgz", + "integrity": "sha512-0WveC9Ai+eT/1b6LCV5IfsufBZ0HP7pSSTdDjcuW302tTEgoBw8rHVHKPbGUtzGReUFCRXbv6zQDDgucnV2WzQ==", "license": "MIT", "dependencies": { - "@vue/compiler-dom": "3.4.31", - "@vue/shared": "3.4.31" + "@vue/compiler-dom": "3.4.33", + "@vue/shared": "3.4.33" } }, "node_modules/@vue/language-core": { @@ -778,53 +778,53 @@ } }, "node_modules/@vue/reactivity": { - "version": "3.4.31", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.31.tgz", - "integrity": "sha512-VGkTani8SOoVkZNds1PfJ/T1SlAIOf8E58PGAhIOUDYPC4GAmFA2u/E14TDAFcf3vVDKunc4QqCe/SHr8xC65Q==", + "version": "3.4.33", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.33.tgz", + "integrity": "sha512-B24QIelahDbyHipBgbUItQblbd4w5HpG3KccL+YkGyo3maXyS253FzcTR3pSz739OTphmzlxP7JxEMWBpewilA==", "license": "MIT", "dependencies": { - "@vue/shared": "3.4.31" + "@vue/shared": "3.4.33" } }, "node_modules/@vue/runtime-core": { - "version": "3.4.31", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.31.tgz", - "integrity": "sha512-LDkztxeUPazxG/p8c5JDDKPfkCDBkkiNLVNf7XZIUnJ+66GVGkP+TIh34+8LtPisZ+HMWl2zqhIw0xN5MwU1cw==", + "version": "3.4.33", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.33.tgz", + "integrity": "sha512-6wavthExzT4iAxpe8q37/rDmf44nyOJGISJPxCi9YsQO+8w9v0gLCFLfH5TzD1V1AYrTAdiF4Y1cgUmP68jP6w==", "license": "MIT", "dependencies": { - "@vue/reactivity": "3.4.31", - "@vue/shared": "3.4.31" + "@vue/reactivity": "3.4.33", + "@vue/shared": "3.4.33" } }, "node_modules/@vue/runtime-dom": { - "version": "3.4.31", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.31.tgz", - "integrity": "sha512-2Auws3mB7+lHhTFCg8E9ZWopA6Q6L455EcU7bzcQ4x6Dn4cCPuqj6S2oBZgN2a8vJRS/LSYYxwFFq2Hlx3Fsaw==", + "version": "3.4.33", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.33.tgz", + "integrity": "sha512-iHsMCUSFJ+4z432Bn9kZzHX+zOXa6+iw36DaVRmKYZpPt9jW9riF32SxNwB124i61kp9+AZtheQ/mKoJLerAaQ==", "license": "MIT", "dependencies": { - "@vue/reactivity": "3.4.31", - "@vue/runtime-core": "3.4.31", - "@vue/shared": "3.4.31", + "@vue/reactivity": "3.4.33", + "@vue/runtime-core": "3.4.33", + "@vue/shared": "3.4.33", "csstype": "^3.1.3" } }, "node_modules/@vue/server-renderer": { - "version": "3.4.31", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.31.tgz", - "integrity": "sha512-D5BLbdvrlR9PE3by9GaUp1gQXlCNadIZytMIb8H2h3FMWJd4oUfkUTEH2wAr3qxoRz25uxbTcbqd3WKlm9EHQA==", + "version": "3.4.33", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.33.tgz", + "integrity": "sha512-jTH0d6gQcaYideFP/k0WdEu8PpRS9MF8d0b6SfZzNi+ap972pZ0TNIeTaESwdOtdY0XPVj54XEJ6K0wXxir4fw==", "license": "MIT", "dependencies": { - "@vue/compiler-ssr": "3.4.31", - "@vue/shared": "3.4.31" + "@vue/compiler-ssr": "3.4.33", + "@vue/shared": "3.4.33" }, "peerDependencies": { - "vue": "3.4.31" + "vue": "3.4.33" } }, "node_modules/@vue/shared": { - "version": "3.4.31", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.31.tgz", - "integrity": "sha512-Yp3wtJk//8cO4NItOPpi3QkLExAr/aLBGZMmTtW9WpdwBCJpRM6zj9WgWktXAl8IDIozwNMByT45JP3tO3ACWA==", + "version": "3.4.33", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.33.tgz", + "integrity": "sha512-aoRY0jQk3A/cuvdkodTrM4NMfxco8n55eG4H7ML/CRy7OryHfiqvug4xrCBBMbbN+dvXAetDDwZW9DXWWjBntA==", "license": "MIT" }, "node_modules/balanced-match": { @@ -1060,9 +1060,9 @@ } }, "node_modules/rollup": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.18.1.tgz", - "integrity": "sha512-Elx2UT8lzxxOXMpy5HWQGZqkrQOtrVDDa/bm9l10+U4rQnVzbL/LgZ4NOM1MPIDyHk69W4InuYDF5dzRh4Kw1A==", + "version": "4.19.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.19.0.tgz", + "integrity": "sha512-5r7EYSQIowHsK4eTZ0Y81qpZuJz+MUuYeqmmYmRMl1nwhdmbiYqt5jwzf6u7wyOzJgYqtCRMtVRKOtHANBz7rA==", "dev": true, "license": "MIT", "dependencies": { @@ -1076,29 +1076,29 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.18.1", - "@rollup/rollup-android-arm64": "4.18.1", - "@rollup/rollup-darwin-arm64": "4.18.1", - "@rollup/rollup-darwin-x64": "4.18.1", - "@rollup/rollup-linux-arm-gnueabihf": "4.18.1", - "@rollup/rollup-linux-arm-musleabihf": "4.18.1", - "@rollup/rollup-linux-arm64-gnu": "4.18.1", - "@rollup/rollup-linux-arm64-musl": "4.18.1", - "@rollup/rollup-linux-powerpc64le-gnu": "4.18.1", - "@rollup/rollup-linux-riscv64-gnu": "4.18.1", - "@rollup/rollup-linux-s390x-gnu": "4.18.1", - "@rollup/rollup-linux-x64-gnu": "4.18.1", - "@rollup/rollup-linux-x64-musl": "4.18.1", - "@rollup/rollup-win32-arm64-msvc": "4.18.1", - "@rollup/rollup-win32-ia32-msvc": "4.18.1", - "@rollup/rollup-win32-x64-msvc": "4.18.1", + "@rollup/rollup-android-arm-eabi": "4.19.0", + "@rollup/rollup-android-arm64": "4.19.0", + "@rollup/rollup-darwin-arm64": "4.19.0", + "@rollup/rollup-darwin-x64": "4.19.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.19.0", + "@rollup/rollup-linux-arm-musleabihf": "4.19.0", + "@rollup/rollup-linux-arm64-gnu": "4.19.0", + "@rollup/rollup-linux-arm64-musl": "4.19.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.19.0", + "@rollup/rollup-linux-riscv64-gnu": "4.19.0", + "@rollup/rollup-linux-s390x-gnu": "4.19.0", + "@rollup/rollup-linux-x64-gnu": "4.19.0", + "@rollup/rollup-linux-x64-musl": "4.19.0", + "@rollup/rollup-win32-arm64-msvc": "4.19.0", + "@rollup/rollup-win32-ia32-msvc": "4.19.0", + "@rollup/rollup-win32-x64-msvc": "4.19.0", "fsevents": "~2.3.2" } }, "node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", "dev": true, "license": "ISC", "bin": { @@ -1132,9 +1132,9 @@ } }, "node_modules/vite": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.3.tgz", - "integrity": "sha512-NPQdeCU0Dv2z5fu+ULotpuq5yfCS1BzKUIPhNbP3YBfAMGJXbt2nS+sbTFu+qchaqWTD+H3JK++nRwr6XIcp6A==", + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.4.tgz", + "integrity": "sha512-Cw+7zL3ZG9/NZBB8C+8QbQZmR54GwqIz+WMI4b3JgdYJvX+ny9AjJXqkGQlDXSXRP9rP0B4tbciRMOVEKulVOA==", "dev": true, "license": "MIT", "dependencies": { @@ -1195,16 +1195,16 @@ "license": "MIT" }, "node_modules/vue": { - "version": "3.4.31", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.31.tgz", - "integrity": "sha512-njqRrOy7W3YLAlVqSKpBebtZpDVg21FPoaq1I7f/+qqBThK9ChAIjkRWgeP6Eat+8C+iia4P3OYqpATP21BCoQ==", + "version": "3.4.33", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.33.tgz", + "integrity": "sha512-VdMCWQOummbhctl4QFMcW6eNtXHsFyDlX60O/tsSQuCcuDOnJ1qPOhhVla65Niece7xq/P2zyZReIO5mP+LGTQ==", "license": "MIT", "dependencies": { - "@vue/compiler-dom": "3.4.31", - "@vue/compiler-sfc": "3.4.31", - "@vue/runtime-dom": "3.4.31", - "@vue/server-renderer": "3.4.31", - "@vue/shared": "3.4.31" + "@vue/compiler-dom": "3.4.33", + "@vue/compiler-sfc": "3.4.33", + "@vue/runtime-dom": "3.4.33", + "@vue/server-renderer": "3.4.33", + "@vue/shared": "3.4.33" }, "peerDependencies": { "typescript": "*" From 2814be897584f88ce58ece3225d5ef9c9c8f0728 Mon Sep 17 00:00:00 2001 From: ducklet Date: Thu, 15 May 2025 21:56:57 +0200 Subject: [PATCH 24/25] feat: switch to Uv --- poetry.lock | 786 ------------------------------------------- pyproject.toml | 60 ++-- scripts/app | 4 +- scripts/build-docker | 9 +- scripts/install | 2 +- scripts/lint-py | 6 +- scripts/outdated | 6 +- scripts/tests | 2 +- scripts/update | 27 +- uv.lock | 488 +++++++++++++++++++++++++++ 10 files changed, 538 insertions(+), 852 deletions(-) delete mode 100644 poetry.lock create mode 100644 uv.lock diff --git a/poetry.lock b/poetry.lock deleted file mode 100644 index 2e995a1..0000000 --- a/poetry.lock +++ /dev/null @@ -1,786 +0,0 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. - -[[package]] -name = "aiosqlite" -version = "0.20.0" -description = "asyncio bridge to the standard sqlite3 module" -optional = false -python-versions = ">=3.8" -files = [ - {file = "aiosqlite-0.20.0-py3-none-any.whl", hash = "sha256:36a1deaca0cac40ebe32aac9977a6e2bbc7f5189f23f4a54d5908986729e5bd6"}, - {file = "aiosqlite-0.20.0.tar.gz", hash = "sha256:6d35c8c256637f4672f843c31021464090805bf925385ac39473fb16eaaca3d7"}, -] - -[package.dependencies] -typing_extensions = ">=4.0" - -[package.extras] -dev = ["attribution (==1.7.0)", "black (==24.2.0)", "coverage[toml] (==7.4.1)", "flake8 (==7.0.0)", "flake8-bugbear (==24.2.6)", "flit (==3.9.0)", "mypy (==1.8.0)", "ufmt (==2.3.0)", "usort (==1.0.8.post1)"] -docs = ["sphinx (==7.2.6)", "sphinx-mdinclude (==0.5.3)"] - -[[package]] -name = "alembic" -version = "1.13.2" -description = "A database migration tool for SQLAlchemy." -optional = false -python-versions = ">=3.8" -files = [ - {file = "alembic-1.13.2-py3-none-any.whl", hash = "sha256:6b8733129a6224a9a711e17c99b08462dbf7cc9670ba8f2e2ae9af860ceb1953"}, - {file = "alembic-1.13.2.tar.gz", hash = "sha256:1ff0ae32975f4fd96028c39ed9bb3c867fe3af956bd7bb37343b54c9fe7445ef"}, -] - -[package.dependencies] -Mako = "*" -SQLAlchemy = ">=1.3.0" -typing-extensions = ">=4" - -[package.extras] -tz = ["backports.zoneinfo"] - -[[package]] -name = "anyio" -version = "4.4.0" -description = "High level compatibility layer for multiple asynchronous event loop implementations" -optional = false -python-versions = ">=3.8" -files = [ - {file = "anyio-4.4.0-py3-none-any.whl", hash = "sha256:c1b2d8f46a8a812513012e1107cb0e68c17159a7a594208005a57dc776e1bdc7"}, - {file = "anyio-4.4.0.tar.gz", hash = "sha256:5aadc6a1bbb7cdb0bede386cac5e2940f5e2ff3aa20277e991cf028e0585ce94"}, -] - -[package.dependencies] -idna = ">=2.8" -sniffio = ">=1.1" - -[package.extras] -doc = ["Sphinx (>=7)", "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.17)"] -trio = ["trio (>=0.23)"] - -[[package]] -name = "beautifulsoup4" -version = "4.12.3" -description = "Screen-scraping library" -optional = false -python-versions = ">=3.6.0" -files = [ - {file = "beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed"}, - {file = "beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051"}, -] - -[package.dependencies] -soupsieve = ">1.2" - -[package.extras] -cchardet = ["cchardet"] -chardet = ["chardet"] -charset-normalizer = ["charset-normalizer"] -html5lib = ["html5lib"] -lxml = ["lxml"] - -[[package]] -name = "certifi" -version = "2024.7.4" -description = "Python package for providing Mozilla's CA Bundle." -optional = false -python-versions = ">=3.6" -files = [ - {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, - {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, -] - -[[package]] -name = "click" -version = "8.1.7" -description = "Composable command line interface toolkit" -optional = false -python-versions = ">=3.7" -files = [ - {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, - {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "platform_system == \"Windows\""} - -[[package]] -name = "colorama" -version = "0.4.6" -description = "Cross-platform colored terminal text." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -files = [ - {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, - {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, -] - -[[package]] -name = "coverage" -version = "7.6.0" -description = "Code coverage measurement for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "coverage-7.6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dff044f661f59dace805eedb4a7404c573b6ff0cdba4a524141bc63d7be5c7fd"}, - {file = "coverage-7.6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a8659fd33ee9e6ca03950cfdcdf271d645cf681609153f218826dd9805ab585c"}, - {file = "coverage-7.6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7792f0ab20df8071d669d929c75c97fecfa6bcab82c10ee4adb91c7a54055463"}, - {file = "coverage-7.6.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4b3cd1ca7cd73d229487fa5caca9e4bc1f0bca96526b922d61053ea751fe791"}, - {file = "coverage-7.6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7e128f85c0b419907d1f38e616c4f1e9f1d1b37a7949f44df9a73d5da5cd53c"}, - {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a94925102c89247530ae1dab7dc02c690942566f22e189cbd53579b0693c0783"}, - {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:dcd070b5b585b50e6617e8972f3fbbee786afca71b1936ac06257f7e178f00f6"}, - {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d50a252b23b9b4dfeefc1f663c568a221092cbaded20a05a11665d0dbec9b8fb"}, - {file = "coverage-7.6.0-cp310-cp310-win32.whl", hash = "sha256:0e7b27d04131c46e6894f23a4ae186a6a2207209a05df5b6ad4caee6d54a222c"}, - {file = "coverage-7.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:54dece71673b3187c86226c3ca793c5f891f9fc3d8aa183f2e3653da18566169"}, - {file = "coverage-7.6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c7b525ab52ce18c57ae232ba6f7010297a87ced82a2383b1afd238849c1ff933"}, - {file = "coverage-7.6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bea27c4269234e06f621f3fac3925f56ff34bc14521484b8f66a580aacc2e7d"}, - {file = "coverage-7.6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed8d1d1821ba5fc88d4a4f45387b65de52382fa3ef1f0115a4f7a20cdfab0e94"}, - {file = "coverage-7.6.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01c322ef2bbe15057bc4bf132b525b7e3f7206f071799eb8aa6ad1940bcf5fb1"}, - {file = "coverage-7.6.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03cafe82c1b32b770a29fd6de923625ccac3185a54a5e66606da26d105f37dac"}, - {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0d1b923fc4a40c5832be4f35a5dab0e5ff89cddf83bb4174499e02ea089daf57"}, - {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4b03741e70fb811d1a9a1d75355cf391f274ed85847f4b78e35459899f57af4d"}, - {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a73d18625f6a8a1cbb11eadc1d03929f9510f4131879288e3f7922097a429f63"}, - {file = "coverage-7.6.0-cp311-cp311-win32.whl", hash = "sha256:65fa405b837060db569a61ec368b74688f429b32fa47a8929a7a2f9b47183713"}, - {file = "coverage-7.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:6379688fb4cfa921ae349c76eb1a9ab26b65f32b03d46bb0eed841fd4cb6afb1"}, - {file = "coverage-7.6.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f7db0b6ae1f96ae41afe626095149ecd1b212b424626175a6633c2999eaad45b"}, - {file = "coverage-7.6.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bbdf9a72403110a3bdae77948b8011f644571311c2fb35ee15f0f10a8fc082e8"}, - {file = "coverage-7.6.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cc44bf0315268e253bf563f3560e6c004efe38f76db03a1558274a6e04bf5d5"}, - {file = "coverage-7.6.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da8549d17489cd52f85a9829d0e1d91059359b3c54a26f28bec2c5d369524807"}, - {file = "coverage-7.6.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0086cd4fc71b7d485ac93ca4239c8f75732c2ae3ba83f6be1c9be59d9e2c6382"}, - {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1fad32ee9b27350687035cb5fdf9145bc9cf0a094a9577d43e909948ebcfa27b"}, - {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:044a0985a4f25b335882b0966625270a8d9db3d3409ddc49a4eb00b0ef5e8cee"}, - {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:76d5f82213aa78098b9b964ea89de4617e70e0d43e97900c2778a50856dac605"}, - {file = "coverage-7.6.0-cp312-cp312-win32.whl", hash = "sha256:3c59105f8d58ce500f348c5b56163a4113a440dad6daa2294b5052a10db866da"}, - {file = "coverage-7.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:ca5d79cfdae420a1d52bf177de4bc2289c321d6c961ae321503b2ca59c17ae67"}, - {file = "coverage-7.6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d39bd10f0ae453554798b125d2f39884290c480f56e8a02ba7a6ed552005243b"}, - {file = "coverage-7.6.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:beb08e8508e53a568811016e59f3234d29c2583f6b6e28572f0954a6b4f7e03d"}, - {file = "coverage-7.6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2e16f4cd2bc4d88ba30ca2d3bbf2f21f00f382cf4e1ce3b1ddc96c634bc48ca"}, - {file = "coverage-7.6.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6616d1c9bf1e3faea78711ee42a8b972367d82ceae233ec0ac61cc7fec09fa6b"}, - {file = "coverage-7.6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad4567d6c334c46046d1c4c20024de2a1c3abc626817ae21ae3da600f5779b44"}, - {file = "coverage-7.6.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d17c6a415d68cfe1091d3296ba5749d3d8696e42c37fca5d4860c5bf7b729f03"}, - {file = "coverage-7.6.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:9146579352d7b5f6412735d0f203bbd8d00113a680b66565e205bc605ef81bc6"}, - {file = "coverage-7.6.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:cdab02a0a941af190df8782aafc591ef3ad08824f97850b015c8c6a8b3877b0b"}, - {file = "coverage-7.6.0-cp38-cp38-win32.whl", hash = "sha256:df423f351b162a702c053d5dddc0fc0ef9a9e27ea3f449781ace5f906b664428"}, - {file = "coverage-7.6.0-cp38-cp38-win_amd64.whl", hash = "sha256:f2501d60d7497fd55e391f423f965bbe9e650e9ffc3c627d5f0ac516026000b8"}, - {file = "coverage-7.6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7221f9ac9dad9492cecab6f676b3eaf9185141539d5c9689d13fd6b0d7de840c"}, - {file = "coverage-7.6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ddaaa91bfc4477d2871442bbf30a125e8fe6b05da8a0015507bfbf4718228ab2"}, - {file = "coverage-7.6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4cbe651f3904e28f3a55d6f371203049034b4ddbce65a54527a3f189ca3b390"}, - {file = "coverage-7.6.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:831b476d79408ab6ccfadaaf199906c833f02fdb32c9ab907b1d4aa0713cfa3b"}, - {file = "coverage-7.6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46c3d091059ad0b9c59d1034de74a7f36dcfa7f6d3bde782c49deb42438f2450"}, - {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:4d5fae0a22dc86259dee66f2cc6c1d3e490c4a1214d7daa2a93d07491c5c04b6"}, - {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:07ed352205574aad067482e53dd606926afebcb5590653121063fbf4e2175166"}, - {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:49c76cdfa13015c4560702574bad67f0e15ca5a2872c6a125f6327ead2b731dd"}, - {file = "coverage-7.6.0-cp39-cp39-win32.whl", hash = "sha256:482855914928c8175735a2a59c8dc5806cf7d8f032e4820d52e845d1f731dca2"}, - {file = "coverage-7.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:543ef9179bc55edfd895154a51792b01c017c87af0ebaae092720152e19e42ca"}, - {file = "coverage-7.6.0-pp38.pp39.pp310-none-any.whl", hash = "sha256:6fe885135c8a479d3e37a7aae61cbd3a0fb2deccb4dda3c25f92a49189f766d6"}, - {file = "coverage-7.6.0.tar.gz", hash = "sha256:289cc803fa1dc901f84701ac10c9ee873619320f2f9aff38794db4a4a0268d51"}, -] - -[package.extras] -toml = ["tomli"] - -[[package]] -name = "greenlet" -version = "3.0.3" -description = "Lightweight in-process concurrent programming" -optional = false -python-versions = ">=3.7" -files = [ - {file = "greenlet-3.0.3-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:9da2bd29ed9e4f15955dd1595ad7bc9320308a3b766ef7f837e23ad4b4aac31a"}, - {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d353cadd6083fdb056bb46ed07e4340b0869c305c8ca54ef9da3421acbdf6881"}, - {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dca1e2f3ca00b84a396bc1bce13dd21f680f035314d2379c4160c98153b2059b"}, - {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ed7fb269f15dc662787f4119ec300ad0702fa1b19d2135a37c2c4de6fadfd4a"}, - {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd4f49ae60e10adbc94b45c0b5e6a179acc1736cf7a90160b404076ee283cf83"}, - {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:73a411ef564e0e097dbe7e866bb2dda0f027e072b04da387282b02c308807405"}, - {file = "greenlet-3.0.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7f362975f2d179f9e26928c5b517524e89dd48530a0202570d55ad6ca5d8a56f"}, - {file = "greenlet-3.0.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:649dde7de1a5eceb258f9cb00bdf50e978c9db1b996964cd80703614c86495eb"}, - {file = "greenlet-3.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:68834da854554926fbedd38c76e60c4a2e3198c6fbed520b106a8986445caaf9"}, - {file = "greenlet-3.0.3-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:b1b5667cced97081bf57b8fa1d6bfca67814b0afd38208d52538316e9422fc61"}, - {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:52f59dd9c96ad2fc0d5724107444f76eb20aaccb675bf825df6435acb7703559"}, - {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:afaff6cf5200befd5cec055b07d1c0a5a06c040fe5ad148abcd11ba6ab9b114e"}, - {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe754d231288e1e64323cfad462fcee8f0288654c10bdf4f603a39ed923bef33"}, - {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2797aa5aedac23af156bbb5a6aa2cd3427ada2972c828244eb7d1b9255846379"}, - {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b7f009caad047246ed379e1c4dbcb8b020f0a390667ea74d2387be2998f58a22"}, - {file = "greenlet-3.0.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c5e1536de2aad7bf62e27baf79225d0d64360d4168cf2e6becb91baf1ed074f3"}, - {file = "greenlet-3.0.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:894393ce10ceac937e56ec00bb71c4c2f8209ad516e96033e4b3b1de270e200d"}, - {file = "greenlet-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:1ea188d4f49089fc6fb283845ab18a2518d279c7cd9da1065d7a84e991748728"}, - {file = "greenlet-3.0.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:70fb482fdf2c707765ab5f0b6655e9cfcf3780d8d87355a063547b41177599be"}, - {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4d1ac74f5c0c0524e4a24335350edad7e5f03b9532da7ea4d3c54d527784f2e"}, - {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:149e94a2dd82d19838fe4b2259f1b6b9957d5ba1b25640d2380bea9c5df37676"}, - {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15d79dd26056573940fcb8c7413d84118086f2ec1a8acdfa854631084393efcc"}, - {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:881b7db1ebff4ba09aaaeae6aa491daeb226c8150fc20e836ad00041bcb11230"}, - {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fcd2469d6a2cf298f198f0487e0a5b1a47a42ca0fa4dfd1b6862c999f018ebbf"}, - {file = "greenlet-3.0.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1f672519db1796ca0d8753f9e78ec02355e862d0998193038c7073045899f305"}, - {file = "greenlet-3.0.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2516a9957eed41dd8f1ec0c604f1cdc86758b587d964668b5b196a9db5bfcde6"}, - {file = "greenlet-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:bba5387a6975598857d86de9eac14210a49d554a77eb8261cc68b7d082f78ce2"}, - {file = "greenlet-3.0.3-cp37-cp37m-macosx_11_0_universal2.whl", hash = "sha256:5b51e85cb5ceda94e79d019ed36b35386e8c37d22f07d6a751cb659b180d5274"}, - {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:daf3cb43b7cf2ba96d614252ce1684c1bccee6b2183a01328c98d36fcd7d5cb0"}, - {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99bf650dc5d69546e076f413a87481ee1d2d09aaaaaca058c9251b6d8c14783f"}, - {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2dd6e660effd852586b6a8478a1d244b8dc90ab5b1321751d2ea15deb49ed414"}, - {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3391d1e16e2a5a1507d83e4a8b100f4ee626e8eca43cf2cadb543de69827c4c"}, - {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e1f145462f1fa6e4a4ae3c0f782e580ce44d57c8f2c7aae1b6fa88c0b2efdb41"}, - {file = "greenlet-3.0.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1a7191e42732df52cb5f39d3527217e7ab73cae2cb3694d241e18f53d84ea9a7"}, - {file = "greenlet-3.0.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0448abc479fab28b00cb472d278828b3ccca164531daab4e970a0458786055d6"}, - {file = "greenlet-3.0.3-cp37-cp37m-win32.whl", hash = "sha256:b542be2440edc2d48547b5923c408cbe0fc94afb9f18741faa6ae970dbcb9b6d"}, - {file = "greenlet-3.0.3-cp37-cp37m-win_amd64.whl", hash = "sha256:01bc7ea167cf943b4c802068e178bbf70ae2e8c080467070d01bfa02f337ee67"}, - {file = "greenlet-3.0.3-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:1996cb9306c8595335bb157d133daf5cf9f693ef413e7673cb07e3e5871379ca"}, - {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ddc0f794e6ad661e321caa8d2f0a55ce01213c74722587256fb6566049a8b04"}, - {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c9db1c18f0eaad2f804728c67d6c610778456e3e1cc4ab4bbd5eeb8e6053c6fc"}, - {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7170375bcc99f1a2fbd9c306f5be8764eaf3ac6b5cb968862cad4c7057756506"}, - {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b66c9c1e7ccabad3a7d037b2bcb740122a7b17a53734b7d72a344ce39882a1b"}, - {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:098d86f528c855ead3479afe84b49242e174ed262456c342d70fc7f972bc13c4"}, - {file = "greenlet-3.0.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:81bb9c6d52e8321f09c3d165b2a78c680506d9af285bfccbad9fb7ad5a5da3e5"}, - {file = "greenlet-3.0.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fd096eb7ffef17c456cfa587523c5f92321ae02427ff955bebe9e3c63bc9f0da"}, - {file = "greenlet-3.0.3-cp38-cp38-win32.whl", hash = "sha256:d46677c85c5ba00a9cb6f7a00b2bfa6f812192d2c9f7d9c4f6a55b60216712f3"}, - {file = "greenlet-3.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:419b386f84949bf0e7c73e6032e3457b82a787c1ab4a0e43732898a761cc9dbf"}, - {file = "greenlet-3.0.3-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:da70d4d51c8b306bb7a031d5cff6cc25ad253affe89b70352af5f1cb68e74b53"}, - {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:086152f8fbc5955df88382e8a75984e2bb1c892ad2e3c80a2508954e52295257"}, - {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d73a9fe764d77f87f8ec26a0c85144d6a951a6c438dfe50487df5595c6373eac"}, - {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7dcbe92cc99f08c8dd11f930de4d99ef756c3591a5377d1d9cd7dd5e896da71"}, - {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1551a8195c0d4a68fac7a4325efac0d541b48def35feb49d803674ac32582f61"}, - {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:64d7675ad83578e3fc149b617a444fab8efdafc9385471f868eb5ff83e446b8b"}, - {file = "greenlet-3.0.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b37eef18ea55f2ffd8f00ff8fe7c8d3818abd3e25fb73fae2ca3b672e333a7a6"}, - {file = "greenlet-3.0.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:77457465d89b8263bca14759d7c1684df840b6811b2499838cc5b040a8b5b113"}, - {file = "greenlet-3.0.3-cp39-cp39-win32.whl", hash = "sha256:57e8974f23e47dac22b83436bdcf23080ade568ce77df33159e019d161ce1d1e"}, - {file = "greenlet-3.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:c5ee858cfe08f34712f548c3c363e807e7186f03ad7a5039ebadb29e8c6be067"}, - {file = "greenlet-3.0.3.tar.gz", hash = "sha256:43374442353259554ce33599da8b692d5aa96f8976d567d4badf263371fbe491"}, -] - -[package.extras] -docs = ["Sphinx", "furo"] -test = ["objgraph", "psutil"] - -[[package]] -name = "h11" -version = "0.14.0" -description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" -optional = false -python-versions = ">=3.7" -files = [ - {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, - {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, -] - -[[package]] -name = "honcho" -version = "1.1.0" -description = "Honcho: a Python clone of Foreman. For managing Procfile-based applications." -optional = false -python-versions = "*" -files = [ - {file = "honcho-1.1.0-py2.py3-none-any.whl", hash = "sha256:a4d6e3a88a7b51b66351ecfc6e9d79d8f4b87351db9ad7e923f5632cc498122f"}, - {file = "honcho-1.1.0.tar.gz", hash = "sha256:c5eca0bded4bef6697a23aec0422fd4f6508ea3581979a3485fc4b89357eb2a9"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "sys_platform == \"win32\""} - -[package.extras] -export = ["jinja2 (>=2.7,<3)"] - -[[package]] -name = "html5lib" -version = "1.1" -description = "HTML parser based on the WHATWG HTML specification" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -files = [ - {file = "html5lib-1.1-py2.py3-none-any.whl", hash = "sha256:0d78f8fde1c230e99fe37986a60526d7049ed4bf8a9fadbad5f00e22e58e041d"}, - {file = "html5lib-1.1.tar.gz", hash = "sha256:b2e5b40261e20f354d198eae92afc10d750afb487ed5e50f9c4eaf07c184146f"}, -] - -[package.dependencies] -six = ">=1.9" -webencodings = "*" - -[package.extras] -all = ["chardet (>=2.2)", "genshi", "lxml"] -chardet = ["chardet (>=2.2)"] -genshi = ["genshi"] -lxml = ["lxml"] - -[[package]] -name = "httpcore" -version = "1.0.5" -description = "A minimal low-level HTTP client." -optional = false -python-versions = ">=3.8" -files = [ - {file = "httpcore-1.0.5-py3-none-any.whl", hash = "sha256:421f18bac248b25d310f3cacd198d55b8e6125c107797b609ff9b7a6ba7991b5"}, - {file = "httpcore-1.0.5.tar.gz", hash = "sha256:34a38e2f9291467ee3b44e89dd52615370e152954ba21721378a87b2960f7a61"}, -] - -[package.dependencies] -certifi = "*" -h11 = ">=0.13,<0.15" - -[package.extras] -asyncio = ["anyio (>=4.0,<5.0)"] -http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] -trio = ["trio (>=0.22.0,<0.26.0)"] - -[[package]] -name = "httpx" -version = "0.27.0" -description = "The next generation HTTP client." -optional = false -python-versions = ">=3.8" -files = [ - {file = "httpx-0.27.0-py3-none-any.whl", hash = "sha256:71d5465162c13681bff01ad59b2cc68dd838ea1f10e51574bac27103f00c91a5"}, - {file = "httpx-0.27.0.tar.gz", hash = "sha256:a0cb88a46f32dc874e04ee956e4c2764aba2aa228f650b06788ba6bda2962ab5"}, -] - -[package.dependencies] -anyio = "*" -certifi = "*" -httpcore = "==1.*" -idna = "*" -sniffio = "*" - -[package.extras] -brotli = ["brotli", "brotlicffi"] -cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] -http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] - -[[package]] -name = "idna" -version = "3.7" -description = "Internationalized Domain Names in Applications (IDNA)" -optional = false -python-versions = ">=3.5" -files = [ - {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, - {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, -] - -[[package]] -name = "iniconfig" -version = "2.0.0" -description = "brain-dead simple config-ini parsing" -optional = false -python-versions = ">=3.7" -files = [ - {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, - {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, -] - -[[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 = "nodeenv" -version = "1.9.1" -description = "Node.js virtual environment builder" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -files = [ - {file = "nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9"}, - {file = "nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f"}, -] - -[[package]] -name = "packaging" -version = "24.1" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, -] - -[[package]] -name = "pluggy" -version = "1.5.0" -description = "plugin and hook calling mechanisms for python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, - {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, -] - -[package.extras] -dev = ["pre-commit", "tox"] -testing = ["pytest", "pytest-benchmark"] - -[[package]] -name = "pyright" -version = "1.1.372" -description = "Command line wrapper for pyright" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pyright-1.1.372-py3-none-any.whl", hash = "sha256:25b15fb8967740f0949fd35b963777187f0a0404c0bd753cc966ec139f3eaa0b"}, - {file = "pyright-1.1.372.tar.gz", hash = "sha256:a9f5e0daa955daaa17e3d1ef76d3623e75f8afd5e37b437d3ff84d5b38c15420"}, -] - -[package.dependencies] -nodeenv = ">=1.6.0" - -[package.extras] -all = ["twine (>=3.4.1)"] -dev = ["twine (>=3.4.1)"] - -[[package]] -name = "pytest" -version = "8.3.1" -description = "pytest: simple powerful testing with Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pytest-8.3.1-py3-none-any.whl", hash = "sha256:e9600ccf4f563976e2c99fa02c7624ab938296551f280835ee6516df8bc4ae8c"}, - {file = "pytest-8.3.1.tar.gz", hash = "sha256:7e8e5c5abd6e93cb1cc151f23e57adc31fcf8cfd2a3ff2da63e23f732de35db6"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "sys_platform == \"win32\""} -iniconfig = "*" -packaging = "*" -pluggy = ">=1.5,<2" - -[package.extras] -dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] - -[[package]] -name = "pytest-asyncio" -version = "0.23.8" -description = "Pytest support for asyncio" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pytest_asyncio-0.23.8-py3-none-any.whl", hash = "sha256:50265d892689a5faefb84df80819d1ecef566eb3549cf915dfb33569359d1ce2"}, - {file = "pytest_asyncio-0.23.8.tar.gz", hash = "sha256:759b10b33a6dc61cce40a8bd5205e302978bbbcc00e279a8b61d9a6a3c82e4d3"}, -] - -[package.dependencies] -pytest = ">=7.0.0,<9" - -[package.extras] -docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1.0)"] -testing = ["coverage (>=6.2)", "hypothesis (>=5.7.1)"] - -[[package]] -name = "pytest-cov" -version = "5.0.0" -description = "Pytest plugin for measuring coverage." -optional = false -python-versions = ">=3.8" -files = [ - {file = "pytest-cov-5.0.0.tar.gz", hash = "sha256:5837b58e9f6ebd335b0f8060eecce69b662415b16dc503883a02f45dfeb14857"}, - {file = "pytest_cov-5.0.0-py3-none-any.whl", hash = "sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652"}, -] - -[package.dependencies] -coverage = {version = ">=5.2.1", extras = ["toml"]} -pytest = ">=4.6" - -[package.extras] -testing = ["fields", "hunter", "process-tests", "pytest-xdist", "virtualenv"] - -[[package]] -name = "ruff" -version = "0.5.4" -description = "An extremely fast Python linter and code formatter, written in Rust." -optional = false -python-versions = ">=3.7" -files = [ - {file = "ruff-0.5.4-py3-none-linux_armv6l.whl", hash = "sha256:82acef724fc639699b4d3177ed5cc14c2a5aacd92edd578a9e846d5b5ec18ddf"}, - {file = "ruff-0.5.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:da62e87637c8838b325e65beee485f71eb36202ce8e3cdbc24b9fcb8b99a37be"}, - {file = "ruff-0.5.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e98ad088edfe2f3b85a925ee96da652028f093d6b9b56b76fc242d8abb8e2059"}, - {file = "ruff-0.5.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c55efbecc3152d614cfe6c2247a3054cfe358cefbf794f8c79c8575456efe19"}, - {file = "ruff-0.5.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f9b85eaa1f653abd0a70603b8b7008d9e00c9fa1bbd0bf40dad3f0c0bdd06793"}, - {file = "ruff-0.5.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0cf497a47751be8c883059c4613ba2f50dd06ec672692de2811f039432875278"}, - {file = "ruff-0.5.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:09c14ed6a72af9ccc8d2e313d7acf7037f0faff43cde4b507e66f14e812e37f7"}, - {file = "ruff-0.5.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:628f6b8f97b8bad2490240aa84f3e68f390e13fabc9af5c0d3b96b485921cd60"}, - {file = "ruff-0.5.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3520a00c0563d7a7a7c324ad7e2cde2355733dafa9592c671fb2e9e3cd8194c1"}, - {file = "ruff-0.5.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93789f14ca2244fb91ed481456f6d0bb8af1f75a330e133b67d08f06ad85b516"}, - {file = "ruff-0.5.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:029454e2824eafa25b9df46882f7f7844d36fd8ce51c1b7f6d97e2615a57bbcc"}, - {file = "ruff-0.5.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:9492320eed573a13a0bc09a2957f17aa733fff9ce5bf00e66e6d4a88ec33813f"}, - {file = "ruff-0.5.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a6e1f62a92c645e2919b65c02e79d1f61e78a58eddaebca6c23659e7c7cb4ac7"}, - {file = "ruff-0.5.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:768fa9208df2bec4b2ce61dbc7c2ddd6b1be9fb48f1f8d3b78b3332c7d71c1ff"}, - {file = "ruff-0.5.4-py3-none-win32.whl", hash = "sha256:e1e7393e9c56128e870b233c82ceb42164966f25b30f68acbb24ed69ce9c3a4e"}, - {file = "ruff-0.5.4-py3-none-win_amd64.whl", hash = "sha256:58b54459221fd3f661a7329f177f091eb35cf7a603f01d9eb3eb11cc348d38c4"}, - {file = "ruff-0.5.4-py3-none-win_arm64.whl", hash = "sha256:bd53da65f1085fb5b307c38fd3c0829e76acf7b2a912d8d79cadcdb4875c1eb7"}, - {file = "ruff-0.5.4.tar.gz", hash = "sha256:2795726d5f71c4f4e70653273d1c23a8182f07dd8e48c12de5d867bfb7557eed"}, -] - -[[package]] -name = "six" -version = "1.16.0" -description = "Python 2 and 3 compatibility utilities" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, -] - -[[package]] -name = "sniffio" -version = "1.3.1" -description = "Sniff out which async library your code is running under" -optional = false -python-versions = ">=3.7" -files = [ - {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, - {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, -] - -[[package]] -name = "soupsieve" -version = "2.5" -description = "A modern CSS selector implementation for Beautiful Soup." -optional = false -python-versions = ">=3.8" -files = [ - {file = "soupsieve-2.5-py3-none-any.whl", hash = "sha256:eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7"}, - {file = "soupsieve-2.5.tar.gz", hash = "sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690"}, -] - -[[package]] -name = "sqlalchemy" -version = "2.0.31" -description = "Database Abstraction Library" -optional = false -python-versions = ">=3.7" -files = [ - {file = "SQLAlchemy-2.0.31-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f2a213c1b699d3f5768a7272de720387ae0122f1becf0901ed6eaa1abd1baf6c"}, - {file = "SQLAlchemy-2.0.31-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9fea3d0884e82d1e33226935dac990b967bef21315cbcc894605db3441347443"}, - {file = "SQLAlchemy-2.0.31-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3ad7f221d8a69d32d197e5968d798217a4feebe30144986af71ada8c548e9fa"}, - {file = "SQLAlchemy-2.0.31-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f2bee229715b6366f86a95d497c347c22ddffa2c7c96143b59a2aa5cc9eebbc"}, - {file = "SQLAlchemy-2.0.31-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:cd5b94d4819c0c89280b7c6109c7b788a576084bf0a480ae17c227b0bc41e109"}, - {file = "SQLAlchemy-2.0.31-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:750900a471d39a7eeba57580b11983030517a1f512c2cb287d5ad0fcf3aebd58"}, - {file = "SQLAlchemy-2.0.31-cp310-cp310-win32.whl", hash = "sha256:7bd112be780928c7f493c1a192cd8c5fc2a2a7b52b790bc5a84203fb4381c6be"}, - {file = "SQLAlchemy-2.0.31-cp310-cp310-win_amd64.whl", hash = "sha256:5a48ac4d359f058474fadc2115f78a5cdac9988d4f99eae44917f36aa1476327"}, - {file = "SQLAlchemy-2.0.31-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f68470edd70c3ac3b6cd5c2a22a8daf18415203ca1b036aaeb9b0fb6f54e8298"}, - {file = "SQLAlchemy-2.0.31-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2e2c38c2a4c5c634fe6c3c58a789712719fa1bf9b9d6ff5ebfce9a9e5b89c1ca"}, - {file = "SQLAlchemy-2.0.31-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd15026f77420eb2b324dcb93551ad9c5f22fab2c150c286ef1dc1160f110203"}, - {file = "SQLAlchemy-2.0.31-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2196208432deebdfe3b22185d46b08f00ac9d7b01284e168c212919891289396"}, - {file = "SQLAlchemy-2.0.31-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:352b2770097f41bff6029b280c0e03b217c2dcaddc40726f8f53ed58d8a85da4"}, - {file = "SQLAlchemy-2.0.31-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:56d51ae825d20d604583f82c9527d285e9e6d14f9a5516463d9705dab20c3740"}, - {file = "SQLAlchemy-2.0.31-cp311-cp311-win32.whl", hash = "sha256:6e2622844551945db81c26a02f27d94145b561f9d4b0c39ce7bfd2fda5776dac"}, - {file = "SQLAlchemy-2.0.31-cp311-cp311-win_amd64.whl", hash = "sha256:ccaf1b0c90435b6e430f5dd30a5aede4764942a695552eb3a4ab74ed63c5b8d3"}, - {file = "SQLAlchemy-2.0.31-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3b74570d99126992d4b0f91fb87c586a574a5872651185de8297c6f90055ae42"}, - {file = "SQLAlchemy-2.0.31-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f77c4f042ad493cb8595e2f503c7a4fe44cd7bd59c7582fd6d78d7e7b8ec52c"}, - {file = "SQLAlchemy-2.0.31-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cd1591329333daf94467e699e11015d9c944f44c94d2091f4ac493ced0119449"}, - {file = "SQLAlchemy-2.0.31-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:74afabeeff415e35525bf7a4ecdab015f00e06456166a2eba7590e49f8db940e"}, - {file = "SQLAlchemy-2.0.31-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b9c01990d9015df2c6f818aa8f4297d42ee71c9502026bb074e713d496e26b67"}, - {file = "SQLAlchemy-2.0.31-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:66f63278db425838b3c2b1c596654b31939427016ba030e951b292e32b99553e"}, - {file = "SQLAlchemy-2.0.31-cp312-cp312-win32.whl", hash = "sha256:0b0f658414ee4e4b8cbcd4a9bb0fd743c5eeb81fc858ca517217a8013d282c96"}, - {file = "SQLAlchemy-2.0.31-cp312-cp312-win_amd64.whl", hash = "sha256:fa4b1af3e619b5b0b435e333f3967612db06351217c58bfb50cee5f003db2a5a"}, - {file = "SQLAlchemy-2.0.31-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:f43e93057cf52a227eda401251c72b6fbe4756f35fa6bfebb5d73b86881e59b0"}, - {file = "SQLAlchemy-2.0.31-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d337bf94052856d1b330d5fcad44582a30c532a2463776e1651bd3294ee7e58b"}, - {file = "SQLAlchemy-2.0.31-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c06fb43a51ccdff3b4006aafee9fcf15f63f23c580675f7734245ceb6b6a9e05"}, - {file = "SQLAlchemy-2.0.31-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:b6e22630e89f0e8c12332b2b4c282cb01cf4da0d26795b7eae16702a608e7ca1"}, - {file = "SQLAlchemy-2.0.31-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:79a40771363c5e9f3a77f0e28b3302801db08040928146e6808b5b7a40749c88"}, - {file = "SQLAlchemy-2.0.31-cp37-cp37m-win32.whl", hash = "sha256:501ff052229cb79dd4c49c402f6cb03b5a40ae4771efc8bb2bfac9f6c3d3508f"}, - {file = "SQLAlchemy-2.0.31-cp37-cp37m-win_amd64.whl", hash = "sha256:597fec37c382a5442ffd471f66ce12d07d91b281fd474289356b1a0041bdf31d"}, - {file = "SQLAlchemy-2.0.31-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:dc6d69f8829712a4fd799d2ac8d79bdeff651c2301b081fd5d3fe697bd5b4ab9"}, - {file = "SQLAlchemy-2.0.31-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:23b9fbb2f5dd9e630db70fbe47d963c7779e9c81830869bd7d137c2dc1ad05fb"}, - {file = "SQLAlchemy-2.0.31-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a21c97efcbb9f255d5c12a96ae14da873233597dfd00a3a0c4ce5b3e5e79704"}, - {file = "SQLAlchemy-2.0.31-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26a6a9837589c42b16693cf7bf836f5d42218f44d198f9343dd71d3164ceeeac"}, - {file = "SQLAlchemy-2.0.31-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:dc251477eae03c20fae8db9c1c23ea2ebc47331bcd73927cdcaecd02af98d3c3"}, - {file = "SQLAlchemy-2.0.31-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:2fd17e3bb8058359fa61248c52c7b09a97cf3c820e54207a50af529876451808"}, - {file = "SQLAlchemy-2.0.31-cp38-cp38-win32.whl", hash = "sha256:c76c81c52e1e08f12f4b6a07af2b96b9b15ea67ccdd40ae17019f1c373faa227"}, - {file = "SQLAlchemy-2.0.31-cp38-cp38-win_amd64.whl", hash = "sha256:4b600e9a212ed59355813becbcf282cfda5c93678e15c25a0ef896b354423238"}, - {file = "SQLAlchemy-2.0.31-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b6cf796d9fcc9b37011d3f9936189b3c8074a02a4ed0c0fbbc126772c31a6d4"}, - {file = "SQLAlchemy-2.0.31-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:78fe11dbe37d92667c2c6e74379f75746dc947ee505555a0197cfba9a6d4f1a4"}, - {file = "SQLAlchemy-2.0.31-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2fc47dc6185a83c8100b37acda27658fe4dbd33b7d5e7324111f6521008ab4fe"}, - {file = "SQLAlchemy-2.0.31-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a41514c1a779e2aa9a19f67aaadeb5cbddf0b2b508843fcd7bafdf4c6864005"}, - {file = "SQLAlchemy-2.0.31-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:afb6dde6c11ea4525318e279cd93c8734b795ac8bb5dda0eedd9ebaca7fa23f1"}, - {file = "SQLAlchemy-2.0.31-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:3f9faef422cfbb8fd53716cd14ba95e2ef655400235c3dfad1b5f467ba179c8c"}, - {file = "SQLAlchemy-2.0.31-cp39-cp39-win32.whl", hash = "sha256:fc6b14e8602f59c6ba893980bea96571dd0ed83d8ebb9c4479d9ed5425d562e9"}, - {file = "SQLAlchemy-2.0.31-cp39-cp39-win_amd64.whl", hash = "sha256:3cb8a66b167b033ec72c3812ffc8441d4e9f5f78f5e31e54dcd4c90a4ca5bebc"}, - {file = "SQLAlchemy-2.0.31-py3-none-any.whl", hash = "sha256:69f3e3c08867a8e4856e92d7afb618b95cdee18e0bc1647b77599722c9a28911"}, - {file = "SQLAlchemy-2.0.31.tar.gz", hash = "sha256:b607489dd4a54de56984a0c7656247504bd5523d9d0ba799aef59d4add009484"}, -] - -[package.dependencies] -aiosqlite = {version = "*", optional = true, markers = "extra == \"aiosqlite\""} -greenlet = {version = "!=0.4.17", optional = true, markers = "python_version < \"3.13\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\") or extra == \"aiosqlite\""} -typing-extensions = {version = ">=4.6.0", optional = true, markers = "extra == \"aiosqlite\""} - -[package.extras] -aiomysql = ["aiomysql (>=0.2.0)", "greenlet (!=0.4.17)"] -aioodbc = ["aioodbc", "greenlet (!=0.4.17)"] -aiosqlite = ["aiosqlite", "greenlet (!=0.4.17)", "typing_extensions (!=3.10.0.1)"] -asyncio = ["greenlet (!=0.4.17)"] -asyncmy = ["asyncmy (>=0.2.3,!=0.2.4,!=0.2.6)", "greenlet (!=0.4.17)"] -mariadb-connector = ["mariadb (>=1.0.1,!=1.1.2,!=1.1.5)"] -mssql = ["pyodbc"] -mssql-pymssql = ["pymssql"] -mssql-pyodbc = ["pyodbc"] -mypy = ["mypy (>=0.910)"] -mysql = ["mysqlclient (>=1.4.0)"] -mysql-connector = ["mysql-connector-python"] -oracle = ["cx_oracle (>=8)"] -oracle-oracledb = ["oracledb (>=1.0.1)"] -postgresql = ["psycopg2 (>=2.7)"] -postgresql-asyncpg = ["asyncpg", "greenlet (!=0.4.17)"] -postgresql-pg8000 = ["pg8000 (>=1.29.1)"] -postgresql-psycopg = ["psycopg (>=3.0.7)"] -postgresql-psycopg2binary = ["psycopg2-binary"] -postgresql-psycopg2cffi = ["psycopg2cffi"] -postgresql-psycopgbinary = ["psycopg[binary] (>=3.0.7)"] -pymysql = ["pymysql"] -sqlcipher = ["sqlcipher3_binary"] - -[[package]] -name = "starlette" -version = "0.38.0" -description = "The little ASGI library that shines." -optional = false -python-versions = ">=3.8" -files = [ - {file = "starlette-0.38.0-py3-none-any.whl", hash = "sha256:dd58f5854ca4fc476710e48d61b29fa4ff3639d42604a786f9d2091e64b95c7e"}, - {file = "starlette-0.38.0.tar.gz", hash = "sha256:1ac2291e946a56bb5ca929dbb2332fc0dfd1e609c7e4d4f2056925cc0442874e"}, -] - -[package.dependencies] -anyio = ">=3.4.0,<5" - -[package.extras] -full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart (>=0.0.7)", "pyyaml"] - -[[package]] -name = "typing-extensions" -version = "4.12.2" -description = "Backported and Experimental Type Hints for Python 3.8+" -optional = false -python-versions = ">=3.8" -files = [ - {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, - {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, -] - -[[package]] -name = "ulid-py" -version = "1.1.0" -description = "Universally Unique Lexicographically Sortable Identifier" -optional = false -python-versions = "*" -files = [ - {file = "ulid-py-1.1.0.tar.gz", hash = "sha256:dc6884be91558df077c3011b9fb0c87d1097cb8fc6534b11f310161afd5738f0"}, - {file = "ulid_py-1.1.0-py2.py3-none-any.whl", hash = "sha256:b56a0f809ef90d6020b21b89a87a48edc7c03aea80e5ed5174172e82d76e3987"}, -] - -[[package]] -name = "uvicorn" -version = "0.30.3" -description = "The lightning-fast ASGI server." -optional = false -python-versions = ">=3.8" -files = [ - {file = "uvicorn-0.30.3-py3-none-any.whl", hash = "sha256:94a3608da0e530cea8f69683aa4126364ac18e3826b6630d1a65f4638aade503"}, - {file = "uvicorn-0.30.3.tar.gz", hash = "sha256:0d114d0831ff1adbf231d358cbf42f17333413042552a624ea6a9b4c33dcfd81"}, -] - -[package.dependencies] -click = ">=7.0" -h11 = ">=0.8" - -[package.extras] -standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.4)"] - -[[package]] -name = "webencodings" -version = "0.5.1" -description = "Character encoding aliases for legacy web content" -optional = false -python-versions = "*" -files = [ - {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, - {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, -] - -[metadata] -lock-version = "2.0" -python-versions = "^3.12" -content-hash = "be28fa6d62e8b58f1265c498cfd7c1e4c1dff067b59ac7a39204beee23e94c4f" diff --git a/pyproject.toml b/pyproject.toml index fc65c56..5b8a9a9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,46 +1,34 @@ [project] name = "unwind" -requires-python = ">=3.12" - -[tool.poetry] -name = "unwind" version = "0" description = "" -authors = ["ducklet "] -license = "LOL" +authors = [{ name = "ducklet", email = "ducklet@noreply.code.dumpr.org" }] +requires-python = ">=3.12" +license = "blessing" +dependencies = [ + "beautifulsoup4>=4.9.3,<5", + "html5lib~=1.1", + "starlette>=0.38.0,<0.39", + "ulid-py>=1.1.0,<2", + "uvicorn>=0.30.1,<0.31", + "httpx>=0.27.0,<0.28", + "sqlalchemy[aiosqlite]~=2.0", + "alembic>=1.13.1,<2", +] -[tool.poetry.dependencies] -python = "^3.12" -beautifulsoup4 = "^4.9.3" -html5lib = "^1.1" -starlette = "^0.38.0" -ulid-py = "^1.1.0" -uvicorn = "^0.30.1" -httpx = "^0.27.0" -sqlalchemy = {version = "^2.0", extras = ["aiosqlite"]} -alembic = "^1.13.1" - -[tool.poetry.group.build.dependencies] -# When we run poetry export, typing-extensions is a transient dependency via -# sqlalchemy, but the hash won't be included in the requirements.txt. -# By making it a direct dependency we can fix this issue, otherwise this could -# be removed. -typing-extensions = "*" - -[tool.poetry.group.dev] -optional = true - -[tool.poetry.group.dev.dependencies] -pytest = "*" -pyright = "*" -pytest-asyncio = "*" -pytest-cov = "*" -ruff = "*" -honcho = "*" +[dependency-groups] +dev = [ + "pytest", + "pyright", + "pytest-asyncio", + "pytest-cov", + "ruff", + "honcho", +] [build-system] -requires = ["poetry-core>=1.0.0"] -build-backend = "poetry.core.masonry.api" +requires = ["hatchling"] +build-backend = "hatchling.build" [tool.pyright] pythonVersion = "3.12" diff --git a/scripts/app b/scripts/app index f3bc18f..abc0213 100755 --- a/scripts/app +++ b/scripts/app @@ -4,4 +4,6 @@ cd "$RUN_DIR" [ -z "${DEBUG:-}" ] || set -x -exec poetry run python -m unwind "$@" +python_bin=$(uv run command -v python) + +exec "$python_bin" -m unwind "$@" diff --git a/scripts/build-docker b/scripts/build-docker index b8a6861..f229009 100755 --- a/scripts/build-docker +++ b/scripts/build-docker @@ -33,9 +33,12 @@ githash_long=$(git rev-parse HEAD) version="$githash_short" echo "$version" >"$builddir"/version -poetry export \ - --with=build \ - --output="$builddir"/requirements.txt +uv export \ + --frozen \ + --format=requirements.txt \ + --no-dev \ + --no-emit-project \ + >"$builddir"/requirements.txt $DOCKER_BIN build \ --pull \ diff --git a/scripts/install b/scripts/install index 25e424b..e4bbf24 100755 --- a/scripts/install +++ b/scripts/install @@ -4,7 +4,7 @@ cd "$RUN_DIR" [ -z "${DEBUG:-}" ] || set -x -poetry install --with=dev --sync +uv sync --frozen cd unwind-ui npm ci diff --git a/scripts/lint-py b/scripts/lint-py index ae69e6f..101779d 100755 --- a/scripts/lint-py +++ b/scripts/lint-py @@ -4,7 +4,7 @@ cd "$RUN_DIR" [ -z "${DEBUG:-}" ] || set -x -poetry run ruff check --fix . ||: -poetry run ruff format . +uv run ruff check --fix . ||: +uv run ruff format . -poetry run pyright +uv run pyright diff --git a/scripts/outdated b/scripts/outdated index a02b59f..0b1ee72 100755 --- a/scripts/outdated +++ b/scripts/outdated @@ -4,8 +4,10 @@ cd "$RUN_DIR" [ -z "${DEBUG:-}" ] || set -x -echo '# Poetry:' -poetry show --outdated --top-level --with=build,dev +echo '# Uv:' +uv tree --outdated \ +| grep --color=never ' (latest: ' \ +| sed -E 's/^[│├└─ ]*//' echo ' # Npm:' diff --git a/scripts/tests b/scripts/tests index 95b7eca..932fffc 100755 --- a/scripts/tests +++ b/scripts/tests @@ -11,4 +11,4 @@ trap 'rm "$dbfile" "${dbfile}-shm" "${dbfile}-wal"' EXIT TERM INT QUIT [ -z "${DEBUG:-}" ] || set -x UNWIND_STORAGE="$dbfile" \ - exec poetry run pytest --cov "$@" + exec uv run pytest --cov "$@" diff --git a/scripts/update b/scripts/update index 913d3eb..9b0d485 100755 --- a/scripts/update +++ b/scripts/update @@ -13,34 +13,23 @@ cd "$RUN_DIR" [ -z "${DEBUG:-}" ] || set -x -# Poetry +# Uv -poetry update --with=build,dev +uv sync --upgrade -poetry show --outdated --top-level \ -| cut -d ' ' -f 1 \ -| while read -r pkg; do - poetry add "$pkg@latest" -done +uv tree --outdated --no-dev \ +| sed -nE 's/.*─ ([^ ]+) (v[^ ]+) \(latest: v([^)]+)\)/\1>=\3/p' \ +| xargs uv add -poetry show --outdated --top-level --only=build \ -| cut -d ' ' -f 1 \ -| while read -r pkg; do - poetry add --group=build "$pkg@latest" -done - -poetry show --outdated --top-level --only=dev \ -| cut -d ' ' -f 1 \ -| while read -r pkg; do - poetry add --group=dev "$pkg@latest" -done +uv tree --outdated --only-dev \ +| sed -nE 's/.*─ ([^ ]+) (v[^ ]+) \(latest: v([^)]+)\)/\1>=\3/p' \ +| xargs uv add --dev # Npm cd unwind-ui npm update -npm install $(npm outdated --json --silent | jq -r 'keys|map("\(.)@latest")|@sh') npm outdated --json --silent \ | jq -r 'keys|map(@sh"\(.)@latest")|join("\n")' \ diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000..6d41a6e --- /dev/null +++ b/uv.lock @@ -0,0 +1,488 @@ +version = 1 +revision = 2 +requires-python = ">=3.12" + +[[package]] +name = "aiosqlite" +version = "0.20.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0d/3a/22ff5415bf4d296c1e92b07fd746ad42c96781f13295a074d58e77747848/aiosqlite-0.20.0.tar.gz", hash = "sha256:6d35c8c256637f4672f843c31021464090805bf925385ac39473fb16eaaca3d7", size = 21691, upload-time = "2024-02-20T06:12:53.915Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/00/c4/c93eb22025a2de6b83263dfe3d7df2e19138e345bca6f18dba7394120930/aiosqlite-0.20.0-py3-none-any.whl", hash = "sha256:36a1deaca0cac40ebe32aac9977a6e2bbc7f5189f23f4a54d5908986729e5bd6", size = 15564, upload-time = "2024-02-20T06:12:50.657Z" }, +] + +[[package]] +name = "alembic" +version = "1.13.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mako" }, + { name = "sqlalchemy" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/e2/efa88e86029cada2da5941ec664d50d9a3b2a91f5066405c6f90e5016c16/alembic-1.13.2.tar.gz", hash = "sha256:1ff0ae32975f4fd96028c39ed9bb3c867fe3af956bd7bb37343b54c9fe7445ef", size = 1206463, upload-time = "2024-06-26T15:46:17.728Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/df/ed/c884465c33c25451e4a5cd4acad154c29e5341e3214e220e7f3478aa4b0d/alembic-1.13.2-py3-none-any.whl", hash = "sha256:6b8733129a6224a9a711e17c99b08462dbf7cc9670ba8f2e2ae9af860ceb1953", size = 232990, upload-time = "2024-06-26T15:46:21.088Z" }, +] + +[[package]] +name = "anyio" +version = "4.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "idna" }, + { name = "sniffio" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e6/e3/c4c8d473d6780ef1853d630d581f70d655b4f8d7553c6997958c283039a2/anyio-4.4.0.tar.gz", hash = "sha256:5aadc6a1bbb7cdb0bede386cac5e2940f5e2ff3aa20277e991cf028e0585ce94", size = 163930, upload-time = "2024-05-26T22:02:15.75Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/a2/10639a79341f6c019dedc95bd48a4928eed9f1d1197f4c04f546fc7ae0ff/anyio-4.4.0-py3-none-any.whl", hash = "sha256:c1b2d8f46a8a812513012e1107cb0e68c17159a7a594208005a57dc776e1bdc7", size = 86780, upload-time = "2024-05-26T22:02:13.671Z" }, +] + +[[package]] +name = "beautifulsoup4" +version = "4.12.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "soupsieve" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b3/ca/824b1195773ce6166d388573fc106ce56d4a805bd7427b624e063596ec58/beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051", size = 581181, upload-time = "2024-01-17T16:53:17.902Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b1/fe/e8c672695b37eecc5cbf43e1d0638d88d66ba3a44c4d321c796f4e59167f/beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed", size = 147925, upload-time = "2024-01-17T16:53:12.779Z" }, +] + +[[package]] +name = "certifi" +version = "2024.7.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c2/02/a95f2b11e207f68bc64d7aae9666fed2e2b3f307748d5123dffb72a1bbea/certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b", size = 164065, upload-time = "2024-07-04T01:36:11.653Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1c/d5/c84e1a17bf61d4df64ca866a1c9a913874b4e9bdc131ec689a0ad013fb36/certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90", size = 162960, upload-time = "2024-07-04T01:36:09.038Z" }, +] + +[[package]] +name = "click" +version = "8.1.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/96/d3/f04c7bfcf5c1862a2a5b845c6b2b360488cf47af55dfa79c98f6a6bf98b5/click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de", size = 336121, upload-time = "2023-08-17T17:29:11.868Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", size = 97941, upload-time = "2023-08-17T17:29:10.08Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "coverage" +version = "7.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/64/c8/a94ce9e17756aed521085ae716d627623374d34f92c1daf7162272ecb030/coverage-7.6.0.tar.gz", hash = "sha256:289cc803fa1dc901f84701ac10c9ee873619320f2f9aff38794db4a4a0268d51", size = 797590, upload-time = "2024-07-11T17:28:12.31Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/57/3a/287ea47cca84c92528b5f9b34b971f845b637d37c3eead9f10aede3531da/coverage-7.6.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f7db0b6ae1f96ae41afe626095149ecd1b212b424626175a6633c2999eaad45b", size = 206079, upload-time = "2024-07-11T17:26:56.219Z" }, + { url = "https://files.pythonhosted.org/packages/7b/14/3432bbdabeaa79de25421d24161ab472578ffe73fc56b0aa9411bea66335/coverage-7.6.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bbdf9a72403110a3bdae77948b8011f644571311c2fb35ee15f0f10a8fc082e8", size = 206320, upload-time = "2024-07-11T17:26:58.834Z" }, + { url = "https://files.pythonhosted.org/packages/0e/2a/f62d42a48449b26cfdf940661cf28bccc27e199dc0e956c738a6b1c942af/coverage-7.6.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cc44bf0315268e253bf563f3560e6c004efe38f76db03a1558274a6e04bf5d5", size = 239454, upload-time = "2024-07-11T17:27:00.739Z" }, + { url = "https://files.pythonhosted.org/packages/0c/a2/d7c0988df525298b2c19c482cec27f76bbeba6c3ed7f85d9f79d8996e509/coverage-7.6.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da8549d17489cd52f85a9829d0e1d91059359b3c54a26f28bec2c5d369524807", size = 236478, upload-time = "2024-07-11T17:27:03.483Z" }, + { url = "https://files.pythonhosted.org/packages/f2/aa/0419103c357bfd95a65d7b2e2249f9f1d79194241c5e87819cd81d36b96c/coverage-7.6.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0086cd4fc71b7d485ac93ca4239c8f75732c2ae3ba83f6be1c9be59d9e2c6382", size = 238563, upload-time = "2024-07-11T17:27:07.354Z" }, + { url = "https://files.pythonhosted.org/packages/2a/ce/375f8fbbabc51e3dfce91355460912c930a4e241ffbafc1f3a35f43ac90b/coverage-7.6.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1fad32ee9b27350687035cb5fdf9145bc9cf0a094a9577d43e909948ebcfa27b", size = 238039, upload-time = "2024-07-11T17:27:10.171Z" }, + { url = "https://files.pythonhosted.org/packages/fd/ca/5eb0004e0bf66db1d4a18c67e4aece76ff409b061d85f31843c28c9a531c/coverage-7.6.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:044a0985a4f25b335882b0966625270a8d9db3d3409ddc49a4eb00b0ef5e8cee", size = 236357, upload-time = "2024-07-11T17:27:12.694Z" }, + { url = "https://files.pythonhosted.org/packages/64/ea/848f064727fe172e80f8a7abc77664c593b6bece14d5acab7d7087f1244e/coverage-7.6.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:76d5f82213aa78098b9b964ea89de4617e70e0d43e97900c2778a50856dac605", size = 238003, upload-time = "2024-07-11T17:27:15.079Z" }, + { url = "https://files.pythonhosted.org/packages/c2/b1/8f54a56789aecc930e227fc5900d18628d6efae4a8ad24981d58fc14b1e3/coverage-7.6.0-cp312-cp312-win32.whl", hash = "sha256:3c59105f8d58ce500f348c5b56163a4113a440dad6daa2294b5052a10db866da", size = 208686, upload-time = "2024-07-11T17:27:18.045Z" }, + { url = "https://files.pythonhosted.org/packages/cb/db/242c44433c5d342c8bf83864131e56af8c1c1ea5645a825b1800c19ad9bf/coverage-7.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:ca5d79cfdae420a1d52bf177de4bc2289c321d6c961ae321503b2ca59c17ae67", size = 209455, upload-time = "2024-07-11T17:27:20.559Z" }, +] + +[[package]] +name = "greenlet" +version = "3.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/17/14/3bddb1298b9a6786539ac609ba4b7c9c0842e12aa73aaa4d8d73ec8f8185/greenlet-3.0.3.tar.gz", hash = "sha256:43374442353259554ce33599da8b692d5aa96f8976d567d4badf263371fbe491", size = 182013, upload-time = "2023-12-21T22:02:54.659Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a2/2f/461615adc53ba81e99471303b15ac6b2a6daa8d2a0f7f77fd15605e16d5b/greenlet-3.0.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:70fb482fdf2c707765ab5f0b6655e9cfcf3780d8d87355a063547b41177599be", size = 273085, upload-time = "2023-12-21T22:03:01.176Z" }, + { url = "https://files.pythonhosted.org/packages/e9/55/2c3cfa3cdbb940cf7321fbcf544f0e9c74898eed43bf678abf416812d132/greenlet-3.0.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4d1ac74f5c0c0524e4a24335350edad7e5f03b9532da7ea4d3c54d527784f2e", size = 660514, upload-time = "2023-12-21T22:29:28.62Z" }, + { url = "https://files.pythonhosted.org/packages/38/77/efb21ab402651896c74f24a172eb4d7479f9f53898bd5e56b9e20bb24ffd/greenlet-3.0.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:149e94a2dd82d19838fe4b2259f1b6b9957d5ba1b25640d2380bea9c5df37676", size = 674295, upload-time = "2023-12-21T22:26:24.101Z" }, + { url = "https://files.pythonhosted.org/packages/74/3a/92f188ace0190f0066dca3636cf1b09481d0854c46e92ec5e29c7cefe5b1/greenlet-3.0.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15d79dd26056573940fcb8c7413d84118086f2ec1a8acdfa854631084393efcc", size = 669395, upload-time = "2023-12-21T22:31:35.992Z" }, + { url = "https://files.pythonhosted.org/packages/63/0f/847ed02cdfce10f0e6e3425cd054296bddb11a17ef1b34681fa01a055187/greenlet-3.0.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:881b7db1ebff4ba09aaaeae6aa491daeb226c8150fc20e836ad00041bcb11230", size = 670455, upload-time = "2023-12-21T22:03:16.291Z" }, + { url = "https://files.pythonhosted.org/packages/bd/37/56b0da468a85e7704f3b2bc045015301bdf4be2184a44868c71f6dca6fe2/greenlet-3.0.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fcd2469d6a2cf298f198f0487e0a5b1a47a42ca0fa4dfd1b6862c999f018ebbf", size = 625692, upload-time = "2023-12-21T22:03:06.294Z" }, + { url = "https://files.pythonhosted.org/packages/7c/68/b5f4084c0a252d7e9c0d95fc1cfc845d08622037adb74e05be3a49831186/greenlet-3.0.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1f672519db1796ca0d8753f9e78ec02355e862d0998193038c7073045899f305", size = 1152597, upload-time = "2023-12-21T22:31:00.412Z" }, + { url = "https://files.pythonhosted.org/packages/a4/fa/31e22345518adcd69d1d6ab5087a12c178aa7f3c51103f6d5d702199d243/greenlet-3.0.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2516a9957eed41dd8f1ec0c604f1cdc86758b587d964668b5b196a9db5bfcde6", size = 1181043, upload-time = "2023-12-21T22:04:20.032Z" }, + { url = "https://files.pythonhosted.org/packages/53/80/3d94d5999b4179d91bcc93745d1b0815b073d61be79dd546b840d17adb18/greenlet-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:bba5387a6975598857d86de9eac14210a49d554a77eb8261cc68b7d082f78ce2", size = 293635, upload-time = "2023-12-21T22:26:01.555Z" }, +] + +[[package]] +name = "h11" +version = "0.14.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f5/38/3af3d3633a34a3316095b39c8e8fb4853a28a536e55d347bd8d8e9a14b03/h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", size = 100418, upload-time = "2022-09-25T15:40:01.519Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761", size = 58259, upload-time = "2022-09-25T15:39:59.68Z" }, +] + +[[package]] +name = "honcho" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0e/7c/c0aa47711b5ada100273cbe190b33cc12297065ce559989699fd6c1ec0cb/honcho-1.1.0.tar.gz", hash = "sha256:c5eca0bded4bef6697a23aec0422fd4f6508ea3581979a3485fc4b89357eb2a9", size = 32699, upload-time = "2021-10-30T15:18:04.759Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/fa/e23333eeb1f5b31a053759eb785389cac9c4cdf1f8867dda8cae9c74535f/honcho-1.1.0-py2.py3-none-any.whl", hash = "sha256:a4d6e3a88a7b51b66351ecfc6e9d79d8f4b87351db9ad7e923f5632cc498122f", size = 21336, upload-time = "2021-10-30T15:18:02.579Z" }, +] + +[[package]] +name = "html5lib" +version = "1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, + { name = "webencodings" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ac/b6/b55c3f49042f1df3dcd422b7f224f939892ee94f22abcf503a9b7339eaf2/html5lib-1.1.tar.gz", hash = "sha256:b2e5b40261e20f354d198eae92afc10d750afb487ed5e50f9c4eaf07c184146f", size = 272215, upload-time = "2020-06-22T23:32:38.834Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6c/dd/a834df6482147d48e225a49515aabc28974ad5a4ca3215c18a882565b028/html5lib-1.1-py2.py3-none-any.whl", hash = "sha256:0d78f8fde1c230e99fe37986a60526d7049ed4bf8a9fadbad5f00e22e58e041d", size = 112173, upload-time = "2020-06-22T23:32:36.781Z" }, +] + +[[package]] +name = "httpcore" +version = "1.0.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "h11" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/17/b0/5e8b8674f8d203335a62fdfcfa0d11ebe09e23613c3391033cbba35f7926/httpcore-1.0.5.tar.gz", hash = "sha256:34a38e2f9291467ee3b44e89dd52615370e152954ba21721378a87b2960f7a61", size = 83234, upload-time = "2024-03-27T18:29:07.397Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/d4/e5d7e4f2174f8a4d63c8897d79eb8fe2503f7ecc03282fee1fa2719c2704/httpcore-1.0.5-py3-none-any.whl", hash = "sha256:421f18bac248b25d310f3cacd198d55b8e6125c107797b609ff9b7a6ba7991b5", size = 77926, upload-time = "2024-03-27T18:29:04.098Z" }, +] + +[[package]] +name = "httpx" +version = "0.27.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "certifi" }, + { name = "httpcore" }, + { name = "idna" }, + { name = "sniffio" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5c/2d/3da5bdf4408b8b2800061c339f240c1802f2e82d55e50bd39c5a881f47f0/httpx-0.27.0.tar.gz", hash = "sha256:a0cb88a46f32dc874e04ee956e4c2764aba2aa228f650b06788ba6bda2962ab5", size = 126413, upload-time = "2024-02-21T13:07:52.434Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/41/7b/ddacf6dcebb42466abd03f368782142baa82e08fc0c1f8eaa05b4bae87d5/httpx-0.27.0-py3-none-any.whl", hash = "sha256:71d5465162c13681bff01ad59b2cc68dd838ea1f10e51574bac27103f00c91a5", size = 75590, upload-time = "2024-02-21T13:07:50.455Z" }, +] + +[[package]] +name = "idna" +version = "3.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/21/ed/f86a79a07470cb07819390452f178b3bef1d375f2ec021ecfc709fc7cf07/idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc", size = 189575, upload-time = "2024-04-11T03:34:43.276Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e5/3e/741d8c82801c347547f8a2a06aa57dbb1992be9e948df2ea0eda2c8b79e8/idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0", size = 66836, upload-time = "2024-04-11T03:34:41.447Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", size = 4646, upload-time = "2023-01-07T11:08:11.254Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892, upload-time = "2023-01-07T11:08:09.864Z" }, +] + +[[package]] +name = "mako" +version = "1.3.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/67/03/fb5ba97ff65ce64f6d35b582aacffc26b693a98053fa831ab43a437cbddb/Mako-1.3.5.tar.gz", hash = "sha256:48dbc20568c1d276a2698b36d968fa76161bf127194907ea6fc594fa81f943bc", size = 392738, upload-time = "2024-05-14T12:22:05.966Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/03/62/70f5a0c2dd208f9f3f2f9afd103aec42ee4d9ad2401d78342f75e9b8da36/Mako-1.3.5-py3-none-any.whl", hash = "sha256:260f1dbc3a519453a9c856dedfe4beb4e50bd5a26d96386cb6c80856556bb91a", size = 78565, upload-time = "2024-05-14T12:22:08.522Z" }, +] + +[[package]] +name = "markupsafe" +version = "2.1.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/87/5b/aae44c6655f3801e81aa3eef09dbbf012431987ba564d7231722f68df02d/MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b", size = 19384, upload-time = "2024-02-02T16:31:22.863Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/53/bd/583bf3e4c8d6a321938c13f49d44024dbe5ed63e0a7ba127e454a66da974/MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1", size = 18215, upload-time = "2024-02-02T16:30:33.081Z" }, + { url = "https://files.pythonhosted.org/packages/48/d6/e7cd795fc710292c3af3a06d80868ce4b02bfbbf370b7cee11d282815a2a/MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4", size = 14069, upload-time = "2024-02-02T16:30:34.148Z" }, + { url = "https://files.pythonhosted.org/packages/51/b5/5d8ec796e2a08fc814a2c7d2584b55f889a55cf17dd1a90f2beb70744e5c/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee", size = 29452, upload-time = "2024-02-02T16:30:35.149Z" }, + { url = "https://files.pythonhosted.org/packages/0a/0d/2454f072fae3b5a137c119abf15465d1771319dfe9e4acbb31722a0fff91/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5", size = 28462, upload-time = "2024-02-02T16:30:36.166Z" }, + { url = "https://files.pythonhosted.org/packages/2d/75/fd6cb2e68780f72d47e6671840ca517bda5ef663d30ada7616b0462ad1e3/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b", size = 27869, upload-time = "2024-02-02T16:30:37.834Z" }, + { url = "https://files.pythonhosted.org/packages/b0/81/147c477391c2750e8fc7705829f7351cf1cd3be64406edcf900dc633feb2/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a", size = 33906, upload-time = "2024-02-02T16:30:39.366Z" }, + { url = "https://files.pythonhosted.org/packages/8b/ff/9a52b71839d7a256b563e85d11050e307121000dcebc97df120176b3ad93/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f", size = 32296, upload-time = "2024-02-02T16:30:40.413Z" }, + { url = "https://files.pythonhosted.org/packages/88/07/2dc76aa51b481eb96a4c3198894f38b480490e834479611a4053fbf08623/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169", size = 33038, upload-time = "2024-02-02T16:30:42.243Z" }, + { url = "https://files.pythonhosted.org/packages/96/0c/620c1fb3661858c0e37eb3cbffd8c6f732a67cd97296f725789679801b31/MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad", size = 16572, upload-time = "2024-02-02T16:30:43.326Z" }, + { url = "https://files.pythonhosted.org/packages/3f/14/c3554d512d5f9100a95e737502f4a2323a1959f6d0d01e0d0997b35f7b10/MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb", size = 17127, upload-time = "2024-02-02T16:30:44.418Z" }, +] + +[[package]] +name = "nodeenv" +version = "1.9.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437, upload-time = "2024-06-04T18:44:11.171Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314, upload-time = "2024-06-04T18:44:08.352Z" }, +] + +[[package]] +name = "packaging" +version = "24.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/51/65/50db4dda066951078f0a96cf12f4b9ada6e4b811516bf0262c0f4f7064d4/packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002", size = 148788, upload-time = "2024-06-09T23:19:24.956Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/08/aa/cc0199a5f0ad350994d660967a8efb233fe0416e4639146c089643407ce6/packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124", size = 53985, upload-time = "2024-06-09T23:19:21.909Z" }, +] + +[[package]] +name = "pluggy" +version = "1.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955, upload-time = "2024-04-20T21:34:42.531Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556, upload-time = "2024-04-20T21:34:40.434Z" }, +] + +[[package]] +name = "pyright" +version = "1.1.372" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nodeenv" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4a/aa/516d4f7604bd4084c1ea454a1746d84dc5f09cb29184bcbb505cc362e437/pyright-1.1.372.tar.gz", hash = "sha256:a9f5e0daa955daaa17e3d1ef76d3623e75f8afd5e37b437d3ff84d5b38c15420", size = 17477, upload-time = "2024-07-17T08:43:08.319Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f9/28/b5ef3ea1f25d19a3291d1631433f7abcdad572ab7865b4be23da42f2a71b/pyright-1.1.372-py3-none-any.whl", hash = "sha256:25b15fb8967740f0949fd35b963777187f0a0404c0bd753cc966ec139f3eaa0b", size = 18227, upload-time = "2024-07-17T08:43:04.68Z" }, +] + +[[package]] +name = "pytest" +version = "8.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/bc/7f/a6f79e033aa8318b6dfe2173fa6409ee75dafccf409d90884bf921433d88/pytest-8.3.1.tar.gz", hash = "sha256:7e8e5c5abd6e93cb1cc151f23e57adc31fcf8cfd2a3ff2da63e23f732de35db6", size = 1438997, upload-time = "2024-07-20T16:25:02.851Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b9/77/ccea391104f576a6e54a54334fc26d29c28aa0ec85714c781fbd2c34ac86/pytest-8.3.1-py3-none-any.whl", hash = "sha256:e9600ccf4f563976e2c99fa02c7624ab938296551f280835ee6516df8bc4ae8c", size = 341628, upload-time = "2024-07-20T16:24:59.674Z" }, +] + +[[package]] +name = "pytest-asyncio" +version = "0.23.8" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/de/b4/0b378b7bf26a8ae161c3890c0b48a91a04106c5713ce81b4b080ea2f4f18/pytest_asyncio-0.23.8.tar.gz", hash = "sha256:759b10b33a6dc61cce40a8bd5205e302978bbbcc00e279a8b61d9a6a3c82e4d3", size = 46920, upload-time = "2024-07-17T17:39:34.617Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ee/82/62e2d63639ecb0fbe8a7ee59ef0bc69a4669ec50f6d3459f74ad4e4189a2/pytest_asyncio-0.23.8-py3-none-any.whl", hash = "sha256:50265d892689a5faefb84df80819d1ecef566eb3549cf915dfb33569359d1ce2", size = 17663, upload-time = "2024-07-17T17:39:32.478Z" }, +] + +[[package]] +name = "pytest-cov" +version = "5.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "coverage" }, + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/74/67/00efc8d11b630c56f15f4ad9c7f9223f1e5ec275aaae3fa9118c6a223ad2/pytest-cov-5.0.0.tar.gz", hash = "sha256:5837b58e9f6ebd335b0f8060eecce69b662415b16dc503883a02f45dfeb14857", size = 63042, upload-time = "2024-03-24T20:16:34.856Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/3a/af5b4fa5961d9a1e6237b530eb87dd04aea6eb83da09d2a4073d81b54ccf/pytest_cov-5.0.0-py3-none-any.whl", hash = "sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652", size = 21990, upload-time = "2024-03-24T20:16:32.444Z" }, +] + +[[package]] +name = "ruff" +version = "0.5.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8e/1a/5955fa22ab088c1f4d8458b4cbc158c6db72143361e8d46e179c48576aab/ruff-0.5.4.tar.gz", hash = "sha256:2795726d5f71c4f4e70653273d1c23a8182f07dd8e48c12de5d867bfb7557eed", size = 2424702, upload-time = "2024-07-20T18:02:31.49Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5b/34/2235ecce6794345f42ad334d1b14384c70b202f77509e5678b68a640fe78/ruff-0.5.4-py3-none-linux_armv6l.whl", hash = "sha256:82acef724fc639699b4d3177ed5cc14c2a5aacd92edd578a9e846d5b5ec18ddf", size = 9499774, upload-time = "2024-07-20T18:01:29.707Z" }, + { url = "https://files.pythonhosted.org/packages/11/23/ffe51028ba274223191d3f96b059108cf7690eb93985a7fdb077c3d1191b/ruff-0.5.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:da62e87637c8838b325e65beee485f71eb36202ce8e3cdbc24b9fcb8b99a37be", size = 8550240, upload-time = "2024-07-20T18:01:35.372Z" }, + { url = "https://files.pythonhosted.org/packages/28/75/843aa3d10a39ab60fbd63f65c825f647907a9732ac27e24d3f94dd2db618/ruff-0.5.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e98ad088edfe2f3b85a925ee96da652028f093d6b9b56b76fc242d8abb8e2059", size = 8160520, upload-time = "2024-07-20T18:01:39.019Z" }, + { url = "https://files.pythonhosted.org/packages/19/88/3d0f5244905088cc2fd136fae8ce81f46d145e2449051313c462032d144d/ruff-0.5.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c55efbecc3152d614cfe6c2247a3054cfe358cefbf794f8c79c8575456efe19", size = 9911606, upload-time = "2024-07-20T18:01:42.765Z" }, + { url = "https://files.pythonhosted.org/packages/1f/ff/6546020836408351e7558dedacc6e5ca7f652f76a9d05ac4882c787d45b1/ruff-0.5.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f9b85eaa1f653abd0a70603b8b7008d9e00c9fa1bbd0bf40dad3f0c0bdd06793", size = 9286353, upload-time = "2024-07-20T18:01:45.872Z" }, + { url = "https://files.pythonhosted.org/packages/b6/bf/51e0c5f12a9bf3c7596cf7f45e1b102f8b49f1da39943e03739890bbf6a4/ruff-0.5.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0cf497a47751be8c883059c4613ba2f50dd06ec672692de2811f039432875278", size = 10082929, upload-time = "2024-07-20T18:01:48.942Z" }, + { url = "https://files.pythonhosted.org/packages/b5/0e/a44cb6edb629788de892fc7bb8ac8b47059df94d7ec9c4e52e04bab5be95/ruff-0.5.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:09c14ed6a72af9ccc8d2e313d7acf7037f0faff43cde4b507e66f14e812e37f7", size = 10832586, upload-time = "2024-07-20T18:01:52.58Z" }, + { url = "https://files.pythonhosted.org/packages/97/ca/e3810f701ae472e5fe3180d56fe6fcc92ea94c7490097a0f731f5602f26f/ruff-0.5.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:628f6b8f97b8bad2490240aa84f3e68f390e13fabc9af5c0d3b96b485921cd60", size = 10421967, upload-time = "2024-07-20T18:01:56.478Z" }, + { url = "https://files.pythonhosted.org/packages/01/47/a62df6ccd6e5d019271df203ea6564f2022c49f85c0bf6ada708cd7b4a5e/ruff-0.5.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3520a00c0563d7a7a7c324ad7e2cde2355733dafa9592c671fb2e9e3cd8194c1", size = 11371031, upload-time = "2024-07-20T18:01:59.956Z" }, + { url = "https://files.pythonhosted.org/packages/a1/02/64f24893eea23c447460e6509e9dd0ae18d7a797f67fee1bafed964ebbae/ruff-0.5.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93789f14ca2244fb91ed481456f6d0bb8af1f75a330e133b67d08f06ad85b516", size = 10103164, upload-time = "2024-07-20T18:02:03.834Z" }, + { url = "https://files.pythonhosted.org/packages/ca/78/683b6c6976fcc33e4a03a0e234e0b9f9b8682f807a661225c829b248de82/ruff-0.5.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:029454e2824eafa25b9df46882f7f7844d36fd8ce51c1b7f6d97e2615a57bbcc", size = 9920056, upload-time = "2024-07-20T18:02:07.05Z" }, + { url = "https://files.pythonhosted.org/packages/78/3a/6c67c5d670aae2a51a11713aff819d729ed92cb0b1d962b8df27e4657650/ruff-0.5.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:9492320eed573a13a0bc09a2957f17aa733fff9ce5bf00e66e6d4a88ec33813f", size = 9361286, upload-time = "2024-07-20T18:02:10.841Z" }, + { url = "https://files.pythonhosted.org/packages/0d/f5/da3a0e2fd0bcbdb3d2ff579ef9cb3ca2af71b9bee97fa917c9a9e0500b67/ruff-0.5.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a6e1f62a92c645e2919b65c02e79d1f61e78a58eddaebca6c23659e7c7cb4ac7", size = 9720829, upload-time = "2024-07-20T18:02:14.602Z" }, + { url = "https://files.pythonhosted.org/packages/4a/56/5062119a5c9e06d98cd6406bfc1eab7616a7c67494a4d05b6052d99dd147/ruff-0.5.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:768fa9208df2bec4b2ce61dbc7c2ddd6b1be9fb48f1f8d3b78b3332c7d71c1ff", size = 10143530, upload-time = "2024-07-20T18:02:18.547Z" }, + { url = "https://files.pythonhosted.org/packages/e6/76/16f8f1c8d0cba6c96ab6f292146fc0acb6dd633a989f524d3b3ef1ee8364/ruff-0.5.4-py3-none-win32.whl", hash = "sha256:e1e7393e9c56128e870b233c82ceb42164966f25b30f68acbb24ed69ce9c3a4e", size = 7794271, upload-time = "2024-07-20T18:02:21.606Z" }, + { url = "https://files.pythonhosted.org/packages/82/35/d6c3c83fb8817328db73c15b1836ccb0c3ce56b72d0d01d98b3a452bec58/ruff-0.5.4-py3-none-win_amd64.whl", hash = "sha256:58b54459221fd3f661a7329f177f091eb35cf7a603f01d9eb3eb11cc348d38c4", size = 8579021, upload-time = "2024-07-20T18:02:24.966Z" }, + { url = "https://files.pythonhosted.org/packages/3c/ef/3e732c0152280775f728ab99691c718ee9a4ae79bf5af1dd9258f7fe7fef/ruff-0.5.4-py3-none-win_arm64.whl", hash = "sha256:bd53da65f1085fb5b307c38fd3c0829e76acf7b2a912d8d79cadcdb4875c1eb7", size = 8034239, upload-time = "2024-07-20T18:02:28.226Z" }, +] + +[[package]] +name = "six" +version = "1.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/71/39/171f1c67cd00715f190ba0b100d606d440a28c93c7714febeca8b79af85e/six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", size = 34041, upload-time = "2021-05-05T14:18:18.379Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d9/5a/e7c31adbe875f2abbb91bd84cf2dc52d792b5a01506781dbcf25c91daf11/six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254", size = 11053, upload-time = "2021-05-05T14:18:17.237Z" }, +] + +[[package]] +name = "sniffio" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372, upload-time = "2024-02-25T23:20:04.057Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" }, +] + +[[package]] +name = "soupsieve" +version = "2.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ce/21/952a240de1c196c7e3fbcd4e559681f0419b1280c617db21157a0390717b/soupsieve-2.5.tar.gz", hash = "sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690", size = 100943, upload-time = "2023-09-02T12:48:22.131Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4c/f3/038b302fdfbe3be7da016777069f26ceefe11a681055ea1f7817546508e3/soupsieve-2.5-py3-none-any.whl", hash = "sha256:eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7", size = 36131, upload-time = "2023-09-02T12:48:20.552Z" }, +] + +[[package]] +name = "sqlalchemy" +version = "2.0.31" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "greenlet", marker = "(python_full_version < '3.13' and platform_machine == 'AMD64') or (python_full_version < '3.13' and platform_machine == 'WIN32') or (python_full_version < '3.13' and platform_machine == 'aarch64') or (python_full_version < '3.13' and platform_machine == 'amd64') or (python_full_version < '3.13' and platform_machine == 'ppc64le') or (python_full_version < '3.13' and platform_machine == 'win32') or (python_full_version < '3.13' and platform_machine == 'x86_64')" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ba/7d/e3312ae374fe7a4af7e1494735125a714a0907317c829ab8d8a31d89ded4/SQLAlchemy-2.0.31.tar.gz", hash = "sha256:b607489dd4a54de56984a0c7656247504bd5523d9d0ba799aef59d4add009484", size = 9524110, upload-time = "2024-06-18T21:38:37.304Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fc/26/1a44b4c9286bccdc2ac344da6487227595512aa60d45c6617b1b6cd859b6/SQLAlchemy-2.0.31-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3b74570d99126992d4b0f91fb87c586a574a5872651185de8297c6f90055ae42", size = 2083132, upload-time = "2024-06-18T22:07:44.845Z" }, + { url = "https://files.pythonhosted.org/packages/27/97/21efc51a670e2772156890e241120aac7dae6c92d1bf56e811fb3bec3373/SQLAlchemy-2.0.31-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f77c4f042ad493cb8595e2f503c7a4fe44cd7bd59c7582fd6d78d7e7b8ec52c", size = 2073619, upload-time = "2024-06-18T22:07:54.357Z" }, + { url = "https://files.pythonhosted.org/packages/ef/87/778b09abc441b6db4014efb9ef87be0c6959cbd46ee3280faad297f30c12/SQLAlchemy-2.0.31-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cd1591329333daf94467e699e11015d9c944f44c94d2091f4ac493ced0119449", size = 3222863, upload-time = "2024-06-18T23:44:28.479Z" }, + { url = "https://files.pythonhosted.org/packages/60/f8/7794f3055d50e96cee04c19c7faeedacb323c7762f334660ba03bed95485/SQLAlchemy-2.0.31-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:74afabeeff415e35525bf7a4ecdab015f00e06456166a2eba7590e49f8db940e", size = 3233968, upload-time = "2024-06-18T22:18:54.371Z" }, + { url = "https://files.pythonhosted.org/packages/e5/ed/aa6ad258a9478874c4b921e8e78d04d237667fc48550a94df79e827ae91f/SQLAlchemy-2.0.31-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b9c01990d9015df2c6f818aa8f4297d42ee71c9502026bb074e713d496e26b67", size = 3170897, upload-time = "2024-06-18T23:44:36.786Z" }, + { url = "https://files.pythonhosted.org/packages/7f/da/d8f8515caf3ef357ad02bb4fd38474fb72c21ee788e2995d9395bcf5185e/SQLAlchemy-2.0.31-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:66f63278db425838b3c2b1c596654b31939427016ba030e951b292e32b99553e", size = 3197274, upload-time = "2024-06-18T22:19:01.43Z" }, + { url = "https://files.pythonhosted.org/packages/99/b3/02a2aeb619f5e366b29d9f5eeeaadbe2bd383eab22ce10a00ced870c63f0/SQLAlchemy-2.0.31-cp312-cp312-win32.whl", hash = "sha256:0b0f658414ee4e4b8cbcd4a9bb0fd743c5eeb81fc858ca517217a8013d282c96", size = 2053430, upload-time = "2024-06-18T22:02:25.431Z" }, + { url = "https://files.pythonhosted.org/packages/d0/ff/5746886a796799d45285573c8a6564b4b84c730142ab974d7a3f7bacee6c/SQLAlchemy-2.0.31-cp312-cp312-win_amd64.whl", hash = "sha256:fa4b1af3e619b5b0b435e333f3967612db06351217c58bfb50cee5f003db2a5a", size = 2079376, upload-time = "2024-06-18T22:02:32.276Z" }, + { url = "https://files.pythonhosted.org/packages/f3/89/ff21b6c7ccdb254fba5444d15afe193d9a71f4fa054b4823d4384d10718e/SQLAlchemy-2.0.31-py3-none-any.whl", hash = "sha256:69f3e3c08867a8e4856e92d7afb618b95cdee18e0bc1647b77599722c9a28911", size = 1874629, upload-time = "2024-06-18T22:19:04.764Z" }, +] + +[package.optional-dependencies] +aiosqlite = [ + { name = "aiosqlite" }, + { name = "greenlet" }, + { name = "typing-extensions" }, +] + +[[package]] +name = "starlette" +version = "0.38.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/13/1c/a0005d1b8e775823b4aa2c4b4ce1b540833c6364ed5de55b6a8754bdc17c/starlette-0.38.0.tar.gz", hash = "sha256:1ac2291e946a56bb5ca929dbb2332fc0dfd1e609c7e4d4f2056925cc0442874e", size = 2844584, upload-time = "2024-07-20T09:18:25.38Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/93/98/a7598e7b2c7c6342b6e61c8a7a85c5d83fb8191a291695c95ce43402f4b7/starlette-0.38.0-py3-none-any.whl", hash = "sha256:dd58f5854ca4fc476710e48d61b29fa4ff3639d42604a786f9d2091e64b95c7e", size = 72053, upload-time = "2024-07-20T09:18:22.348Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.12.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321, upload-time = "2024-06-07T18:52:15.995Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438, upload-time = "2024-06-07T18:52:13.582Z" }, +] + +[[package]] +name = "ulid-py" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3b/53/d14a8ec344048e21431821cb49e9a6722384f982b889c2dd449428dbdcc1/ulid-py-1.1.0.tar.gz", hash = "sha256:dc6884be91558df077c3011b9fb0c87d1097cb8fc6534b11f310161afd5738f0", size = 22514, upload-time = "2020-09-15T15:35:09.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/42/7c/a12c879fe6c2b136a718c142115ff99397fbf62b4929d970d58ae386d55f/ulid_py-1.1.0-py2.py3-none-any.whl", hash = "sha256:b56a0f809ef90d6020b21b89a87a48edc7c03aea80e5ed5174172e82d76e3987", size = 25753, upload-time = "2020-09-15T15:35:08.075Z" }, +] + +[[package]] +name = "unwind" +version = "0" +source = { editable = "." } +dependencies = [ + { name = "alembic" }, + { name = "beautifulsoup4" }, + { name = "html5lib" }, + { name = "httpx" }, + { name = "sqlalchemy", extra = ["aiosqlite"] }, + { name = "starlette" }, + { name = "ulid-py" }, + { name = "uvicorn" }, +] + +[package.dev-dependencies] +dev = [ + { name = "honcho" }, + { name = "pyright" }, + { name = "pytest" }, + { name = "pytest-asyncio" }, + { name = "pytest-cov" }, + { name = "ruff" }, +] + +[package.metadata] +requires-dist = [ + { name = "alembic", specifier = ">=1.13.1,<2" }, + { name = "beautifulsoup4", specifier = ">=4.9.3,<5" }, + { name = "html5lib", specifier = "~=1.1" }, + { name = "httpx", specifier = ">=0.27.0,<0.28" }, + { name = "sqlalchemy", extras = ["aiosqlite"], specifier = "~=2.0" }, + { name = "starlette", specifier = ">=0.38.0,<0.39" }, + { name = "ulid-py", specifier = ">=1.1.0,<2" }, + { name = "uvicorn", specifier = ">=0.30.1,<0.31" }, +] + +[package.metadata.requires-dev] +dev = [ + { name = "honcho" }, + { name = "pyright" }, + { name = "pytest" }, + { name = "pytest-asyncio" }, + { name = "pytest-cov" }, + { name = "ruff" }, +] + +[[package]] +name = "uvicorn" +version = "0.30.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "h11" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/77/40/b650be95700dc83d14c5f2b9eac9deb23cbca757a12ee20e473b5ef1ac48/uvicorn-0.30.3.tar.gz", hash = "sha256:0d114d0831ff1adbf231d358cbf42f17333413042552a624ea6a9b4c33dcfd81", size = 42762, upload-time = "2024-07-20T08:59:54.277Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/63/84/2a26b4eac1cf0c6b5b176dd4346cc4912af5e1b0efc150b865e28636ac34/uvicorn-0.30.3-py3-none-any.whl", hash = "sha256:94a3608da0e530cea8f69683aa4126364ac18e3826b6630d1a65f4638aade503", size = 62760, upload-time = "2024-07-20T08:59:51.926Z" }, +] + +[[package]] +name = "webencodings" +version = "0.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0b/02/ae6ceac1baeda530866a85075641cec12989bd8d31af6d5ab4a3e8c92f47/webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923", size = 9721, upload-time = "2017-04-05T20:21:34.189Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/24/2a3e3df732393fed8b3ebf2ec078f05546de641fe1b667ee316ec1dcf3b7/webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78", size = 11774, upload-time = "2017-04-05T20:21:32.581Z" }, +] From 2ce8924d1b87f47994feabcbfe6769d8fd0c1198 Mon Sep 17 00:00:00 2001 From: ducklet Date: Thu, 15 May 2025 21:56:18 +0200 Subject: [PATCH 25/25] chore: upgrade to Python 3.13 & run update --- .python-version | 2 +- Dockerfile | 5 +- pyproject.toml | 10 +- tests/test_imdb.py | 4 +- unwind-ui/package-lock.json | 892 ++++++++++++++++++++++-------------- unwind-ui/package.json | 2 +- unwind/imdb.py | 8 +- unwind/models.py | 6 +- unwind/web.py | 4 +- uv.lock | 316 +++++++------ 10 files changed, 731 insertions(+), 518 deletions(-) diff --git a/.python-version b/.python-version index e4fba21..24ee5b1 100644 --- a/.python-version +++ b/.python-version @@ -1 +1 @@ -3.12 +3.13 diff --git a/Dockerfile b/Dockerfile index 1571d75..5510349 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,8 +13,9 @@ WORKDIR /var/app COPY build/requirements.txt ./ -RUN pip install --no-cache-dir --upgrade \ - --requirement requirements.txt +RUN pip install --no-cache-dir \ + --require-hashes \ + --requirement requirements.txt USER 10000:10001 diff --git a/pyproject.toml b/pyproject.toml index 5b8a9a9..f869584 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,15 +3,15 @@ name = "unwind" version = "0" description = "" authors = [{ name = "ducklet", email = "ducklet@noreply.code.dumpr.org" }] -requires-python = ">=3.12" +requires-python = ">=3.13" license = "blessing" dependencies = [ "beautifulsoup4>=4.9.3,<5", "html5lib~=1.1", - "starlette>=0.38.0,<0.39", + "starlette>=0.46.2", "ulid-py>=1.1.0,<2", - "uvicorn>=0.30.1,<0.31", - "httpx>=0.27.0,<0.28", + "uvicorn>=0.34.2", + "httpx>=0.28.1", "sqlalchemy[aiosqlite]~=2.0", "alembic>=1.13.1,<2", ] @@ -31,7 +31,7 @@ requires = ["hatchling"] build-backend = "hatchling.build" [tool.pyright] -pythonVersion = "3.12" +pythonVersion = "3.13" [tool.ruff.lint] select = [ diff --git a/tests/test_imdb.py b/tests/test_imdb.py index aa3f55a..d8efa61 100644 --- a/tests/test_imdb.py +++ b/tests/test_imdb.py @@ -134,7 +134,7 @@ async def test_load_ratings_page_20240510(monkeypatch): if rating.movie.imdb_id == item["imdb_id"]: rating_dict = {key: getattr(rating.movie, key) for key in item.keys()} return rating_dict - raise AssertionError(f"{item["imdb_id"]} not found in page.ratings") + raise AssertionError(f"{item['imdb_id']} not found in page.ratings") a_movie = { "title": "Kung Fu Panda 4", @@ -224,7 +224,7 @@ async def test_load_ratings_page_20240720(monkeypatch): if rating.movie.imdb_id == item["imdb_id"]: rating_dict = {key: getattr(rating.movie, key) for key in item.keys()} return rating_dict - raise AssertionError(f"{item["imdb_id"]} not found in page.ratings") + raise AssertionError(f"{item['imdb_id']} not found in page.ratings") a_movie = { "title": "Kung Fu Panda 4", diff --git a/unwind-ui/package-lock.json b/unwind-ui/package-lock.json index fa3c571..482df58 100644 --- a/unwind-ui/package-lock.json +++ b/unwind-ui/package-lock.json @@ -15,15 +15,36 @@ "@vue/compiler-sfc": "^3.0.5", "prettier": "^3.2.5", "typescript": "^5.4.5", - "vite": "^5.2.11", + "vite": "^6.3.5", "vue-tsc": "^2.0.16" } }, - "node_modules/@babel/parser": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.8.tgz", - "integrity": "sha512-WzfbgXOkGzZiXXCqk43kKwZjzwx4oulxZi3nq2TYL9mOjQv6kYwul9mz6ID36njuL7Xkp6nJEfok848Zj10j/w==", + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.2.tgz", + "integrity": "sha512-QYLs8299NA7WM/bZAdp+CviYYkVoYXlDW2rzliy3chxd1PQjej7JORuMJDJXJUb9g0TT+B99EwaVLKmX+sPXWw==", + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.1" + }, "bin": { "parser": "bin/babel-parser.js" }, @@ -31,10 +52,23 @@ "node": ">=6.0.0" } }, + "node_modules/@babel/types": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.1.tgz", + "integrity": "sha512-+EzkxvLNfiUeKMgy/3luqfsCWFRXLb7U6wNQTk60tovuckwB15B191tJWvpp4HjiQWdJkCxO3Wbvc6jlk3Xb2Q==", + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.4.tgz", + "integrity": "sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q==", "cpu": [ "ppc64" ], @@ -45,13 +79,13 @@ "aix" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.4.tgz", + "integrity": "sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ==", "cpu": [ "arm" ], @@ -62,13 +96,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.4.tgz", + "integrity": "sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A==", "cpu": [ "arm64" ], @@ -79,13 +113,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.4.tgz", + "integrity": "sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ==", "cpu": [ "x64" ], @@ -96,13 +130,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.4.tgz", + "integrity": "sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g==", "cpu": [ "arm64" ], @@ -113,13 +147,13 @@ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.4.tgz", + "integrity": "sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A==", "cpu": [ "x64" ], @@ -130,13 +164,13 @@ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.4.tgz", + "integrity": "sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ==", "cpu": [ "arm64" ], @@ -147,13 +181,13 @@ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.4.tgz", + "integrity": "sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ==", "cpu": [ "x64" ], @@ -164,13 +198,13 @@ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.4.tgz", + "integrity": "sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ==", "cpu": [ "arm" ], @@ -181,13 +215,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.4.tgz", + "integrity": "sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ==", "cpu": [ "arm64" ], @@ -198,13 +232,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.4.tgz", + "integrity": "sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ==", "cpu": [ "ia32" ], @@ -215,13 +249,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.4.tgz", + "integrity": "sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA==", "cpu": [ "loong64" ], @@ -232,13 +266,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.4.tgz", + "integrity": "sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg==", "cpu": [ "mips64el" ], @@ -249,13 +283,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.4.tgz", + "integrity": "sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag==", "cpu": [ "ppc64" ], @@ -266,13 +300,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.4.tgz", + "integrity": "sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA==", "cpu": [ "riscv64" ], @@ -283,13 +317,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.4.tgz", + "integrity": "sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g==", "cpu": [ "s390x" ], @@ -300,13 +334,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.4.tgz", + "integrity": "sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA==", "cpu": [ "x64" ], @@ -317,13 +351,30 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.4.tgz", + "integrity": "sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.4.tgz", + "integrity": "sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw==", "cpu": [ "x64" ], @@ -334,13 +385,30 @@ "netbsd" ], "engines": { - "node": ">=12" + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.4.tgz", + "integrity": "sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.4.tgz", + "integrity": "sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw==", "cpu": [ "x64" ], @@ -351,13 +419,13 @@ "openbsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.4.tgz", + "integrity": "sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q==", "cpu": [ "x64" ], @@ -368,13 +436,13 @@ "sunos" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.4.tgz", + "integrity": "sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ==", "cpu": [ "arm64" ], @@ -385,13 +453,13 @@ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.4.tgz", + "integrity": "sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg==", "cpu": [ "ia32" ], @@ -402,13 +470,13 @@ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.4.tgz", + "integrity": "sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ==", "cpu": [ "x64" ], @@ -419,7 +487,7 @@ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@jridgewell/sourcemap-codec": { @@ -429,9 +497,9 @@ "license": "MIT" }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.19.0.tgz", - "integrity": "sha512-JlPfZ/C7yn5S5p0yKk7uhHTTnFlvTgLetl2VxqE518QgyM7C9bSfFTYvB/Q/ftkq0RIPY4ySxTz+/wKJ/dXC0w==", + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.40.2.tgz", + "integrity": "sha512-JkdNEq+DFxZfUwxvB58tHMHBHVgX23ew41g1OQinthJ+ryhdRk67O31S7sYw8u2lTjHUPFxwar07BBt1KHp/hg==", "cpu": [ "arm" ], @@ -443,9 +511,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.19.0.tgz", - "integrity": "sha512-RDxUSY8D1tWYfn00DDi5myxKgOk6RvWPxhmWexcICt/MEC6yEMr4HNCu1sXXYLw8iAsg0D44NuU+qNq7zVWCrw==", + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.40.2.tgz", + "integrity": "sha512-13unNoZ8NzUmnndhPTkWPWbX3vtHodYmy+I9kuLxN+F+l+x3LdVF7UCu8TWVMt1POHLh6oDHhnOA04n8oJZhBw==", "cpu": [ "arm64" ], @@ -457,9 +525,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.19.0.tgz", - "integrity": "sha512-emvKHL4B15x6nlNTBMtIaC9tLPRpeA5jMvRLXVbl/W9Ie7HhkrE7KQjvgS9uxgatL1HmHWDXk5TTS4IaNJxbAA==", + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.40.2.tgz", + "integrity": "sha512-Gzf1Hn2Aoe8VZzevHostPX23U7N5+4D36WJNHK88NZHCJr7aVMG4fadqkIf72eqVPGjGc0HJHNuUaUcxiR+N/w==", "cpu": [ "arm64" ], @@ -471,9 +539,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.19.0.tgz", - "integrity": "sha512-fO28cWA1dC57qCd+D0rfLC4VPbh6EOJXrreBmFLWPGI9dpMlER2YwSPZzSGfq11XgcEpPukPTfEVFtw2q2nYJg==", + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.40.2.tgz", + "integrity": "sha512-47N4hxa01a4x6XnJoskMKTS8XZ0CZMd8YTbINbi+w03A2w4j1RTlnGHOz/P0+Bg1LaVL6ufZyNprSg+fW5nYQQ==", "cpu": [ "x64" ], @@ -484,10 +552,38 @@ "darwin" ] }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.40.2.tgz", + "integrity": "sha512-8t6aL4MD+rXSHHZUR1z19+9OFJ2rl1wGKvckN47XFRVO+QL/dUSpKA2SLRo4vMg7ELA8pzGpC+W9OEd1Z/ZqoQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.40.2.tgz", + "integrity": "sha512-C+AyHBzfpsOEYRFjztcYUFsH4S7UsE9cDtHCtma5BK8+ydOZYgMmWg1d/4KBytQspJCld8ZIujFMAdKG1xyr4Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.19.0.tgz", - "integrity": "sha512-2Rn36Ubxdv32NUcfm0wB1tgKqkQuft00PtM23VqLuCUR4N5jcNWDoV5iBC9jeGdgS38WK66ElncprqgMUOyomw==", + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.40.2.tgz", + "integrity": "sha512-de6TFZYIvJwRNjmW3+gaXiZ2DaWL5D5yGmSYzkdzjBDS3W+B9JQ48oZEsmMvemqjtAFzE16DIBLqd6IQQRuG9Q==", "cpu": [ "arm" ], @@ -499,9 +595,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.19.0.tgz", - "integrity": "sha512-gJuzIVdq/X1ZA2bHeCGCISe0VWqCoNT8BvkQ+BfsixXwTOndhtLUpOg0A1Fcx/+eA6ei6rMBzlOz4JzmiDw7JQ==", + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.40.2.tgz", + "integrity": "sha512-urjaEZubdIkacKc930hUDOfQPysezKla/O9qV+O89enqsqUmQm8Xj8O/vh0gHg4LYfv7Y7UsE3QjzLQzDYN1qg==", "cpu": [ "arm" ], @@ -513,9 +609,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.19.0.tgz", - "integrity": "sha512-0EkX2HYPkSADo9cfeGFoQ7R0/wTKb7q6DdwI4Yn/ULFE1wuRRCHybxpl2goQrx4c/yzK3I8OlgtBu4xvted0ug==", + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.40.2.tgz", + "integrity": "sha512-KlE8IC0HFOC33taNt1zR8qNlBYHj31qGT1UqWqtvR/+NuCVhfufAq9fxO8BMFC22Wu0rxOwGVWxtCMvZVLmhQg==", "cpu": [ "arm64" ], @@ -527,9 +623,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.19.0.tgz", - "integrity": "sha512-GlIQRj9px52ISomIOEUq/IojLZqzkvRpdP3cLgIE1wUWaiU5Takwlzpz002q0Nxxr1y2ZgxC2obWxjr13lvxNQ==", + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.40.2.tgz", + "integrity": "sha512-j8CgxvfM0kbnhu4XgjnCWJQyyBOeBI1Zq91Z850aUddUmPeQvuAy6OiMdPS46gNFgy8gN1xkYyLgwLYZG3rBOg==", "cpu": [ "arm64" ], @@ -540,10 +636,24 @@ "linux" ] }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.40.2.tgz", + "integrity": "sha512-Ybc/1qUampKuRF4tQXc7G7QY9YRyeVSykfK36Y5Qc5dmrIxwFhrOzqaVTNoZygqZ1ZieSWTibfFhQ5qK8jpWxw==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.19.0.tgz", - "integrity": "sha512-N6cFJzssruDLUOKfEKeovCKiHcdwVYOT1Hs6dovDQ61+Y9n3Ek4zXvtghPPelt6U0AH4aDGnDLb83uiJMkWYzQ==", + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.40.2.tgz", + "integrity": "sha512-3FCIrnrt03CCsZqSYAOW/k9n625pjpuMzVfeI+ZBUSDT3MVIFDSPfSUgIl9FqUftxcUXInvFah79hE1c9abD+Q==", "cpu": [ "ppc64" ], @@ -555,9 +665,23 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.19.0.tgz", - "integrity": "sha512-2DnD3mkS2uuam/alF+I7M84koGwvn3ZVD7uG+LEWpyzo/bq8+kKnus2EVCkcvh6PlNB8QPNFOz6fWd5N8o1CYg==", + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.40.2.tgz", + "integrity": "sha512-QNU7BFHEvHMp2ESSY3SozIkBPaPBDTsfVNGx3Xhv+TdvWXFGOSH2NJvhD1zKAT6AyuuErJgbdvaJhYVhVqrWTg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.40.2.tgz", + "integrity": "sha512-5W6vNYkhgfh7URiXTO1E9a0cy4fSgfE4+Hl5agb/U1sa0kjOLMLC1wObxwKxecE17j0URxuTrYZZME4/VH57Hg==", "cpu": [ "riscv64" ], @@ -569,9 +693,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.19.0.tgz", - "integrity": "sha512-D6pkaF7OpE7lzlTOFCB2m3Ngzu2ykw40Nka9WmKGUOTS3xcIieHe82slQlNq69sVB04ch73thKYIWz/Ian8DUA==", + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.40.2.tgz", + "integrity": "sha512-B7LKIz+0+p348JoAL4X/YxGx9zOx3sR+o6Hj15Y3aaApNfAshK8+mWZEf759DXfRLeL2vg5LYJBB7DdcleYCoQ==", "cpu": [ "s390x" ], @@ -583,9 +707,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.19.0.tgz", - "integrity": "sha512-HBndjQLP8OsdJNSxpNIN0einbDmRFg9+UQeZV1eiYupIRuZsDEoeGU43NQsS34Pp166DtwQOnpcbV/zQxM+rWA==", + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.40.2.tgz", + "integrity": "sha512-lG7Xa+BmBNwpjmVUbmyKxdQJ3Q6whHjMjzQplOs5Z+Gj7mxPtWakGHqzMqNER68G67kmCX9qX57aRsW5V0VOng==", "cpu": [ "x64" ], @@ -597,9 +721,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.19.0.tgz", - "integrity": "sha512-HxfbvfCKJe/RMYJJn0a12eiOI9OOtAUF4G6ozrFUK95BNyoJaSiBjIOHjZskTUffUrB84IPKkFG9H9nEvJGW6A==", + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.40.2.tgz", + "integrity": "sha512-tD46wKHd+KJvsmije4bUskNuvWKFcTOIM9tZ/RrmIvcXnbi0YK/cKS9FzFtAm7Oxi2EhV5N2OpfFB348vSQRXA==", "cpu": [ "x64" ], @@ -611,9 +735,9 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.19.0.tgz", - "integrity": "sha512-HxDMKIhmcguGTiP5TsLNolwBUK3nGGUEoV/BO9ldUBoMLBssvh4J0X8pf11i1fTV7WShWItB1bKAKjX4RQeYmg==", + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.40.2.tgz", + "integrity": "sha512-Bjv/HG8RRWLNkXwQQemdsWw4Mg+IJ29LK+bJPW2SCzPKOUaMmPEppQlu/Fqk1d7+DX3V7JbFdbkh/NMmurT6Pg==", "cpu": [ "arm64" ], @@ -625,9 +749,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.19.0.tgz", - "integrity": "sha512-xItlIAZZaiG/u0wooGzRsx11rokP4qyc/79LkAOdznGRAbOFc+SfEdfUOszG1odsHNgwippUJavag/+W/Etc6Q==", + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.40.2.tgz", + "integrity": "sha512-dt1llVSGEsGKvzeIO76HToiYPNPYPkmjhMHhP00T9S4rDern8P2ZWvWAQUEJ+R1UdMWJ/42i/QqJ2WV765GZcA==", "cpu": [ "ia32" ], @@ -639,9 +763,9 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.19.0.tgz", - "integrity": "sha512-xNo5fV5ycvCCKqiZcpB65VMR11NJB+StnxHz20jdqRAktfdfzhgjTiJ2doTDQE/7dqGaV5I7ZGqKpgph6lCIag==", + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.40.2.tgz", + "integrity": "sha512-bwspbWB04XJpeElvsp+DCylKfF4trJDa2Y9Go8O6A7YLX2LIKGcNK/CYImJN6ZP4DcuOHB4Utl3iCbnR62DudA==", "cpu": [ "x64" ], @@ -653,120 +777,131 @@ ] }, "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", + "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", "dev": true, "license": "MIT" }, "node_modules/@vitejs/plugin-vue": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.0.5.tgz", - "integrity": "sha512-LOjm7XeIimLBZyzinBQ6OSm3UBCNVCpLkxGC0oWmm2YPzVZoxMsdvNVimLTBzpAnR9hl/yn1SHGuRfe6/Td9rQ==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.2.4.tgz", + "integrity": "sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==", "dev": true, "license": "MIT", "engines": { "node": "^18.0.0 || >=20.0.0" }, "peerDependencies": { - "vite": "^5.0.0", + "vite": "^5.0.0 || ^6.0.0", "vue": "^3.2.25" } }, "node_modules/@volar/language-core": { - "version": "2.4.0-alpha.17", - "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.4.0-alpha.17.tgz", - "integrity": "sha512-FF9g89QZUVJpgZvrNpA+v5Sgo7MdUjeA1celxCe4nFTpfp4P/FUdZ1lgeYy7ZS5r13oC4Ei6HqWpfLN7PFM60w==", + "version": "2.4.13", + "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.4.13.tgz", + "integrity": "sha512-MnQJ7eKchJx5Oz+YdbqyFUk8BN6jasdJv31n/7r6/WwlOOv7qzvot6B66887l2ST3bUW4Mewml54euzpJWA6bg==", "dev": true, "license": "MIT", "dependencies": { - "@volar/source-map": "2.4.0-alpha.17" + "@volar/source-map": "2.4.13" } }, "node_modules/@volar/source-map": { - "version": "2.4.0-alpha.17", - "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.4.0-alpha.17.tgz", - "integrity": "sha512-6LOuR2nIloQCSNMNcUPRPLjL5CInIE1pYZ8lifOCSxQRiz8GcWaOm34kAvdm7pzPQqMRHBBnV/Ihkdt/w7oWAQ==", + "version": "2.4.13", + "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.4.13.tgz", + "integrity": "sha512-l/EBcc2FkvHgz2ZxV+OZK3kMSroMr7nN3sZLF2/f6kWW66q8+tEL4giiYyFjt0BcubqJhBt6soYIrAPhg/Yr+Q==", "dev": true, "license": "MIT" }, "node_modules/@volar/typescript": { - "version": "2.4.0-alpha.17", - "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.4.0-alpha.17.tgz", - "integrity": "sha512-oJlz5xJd0O1Xe/I7AV3kPpV6gXlcyxfpMcj/w4/wGY5AxFHxyy5i7VhaE/BVk99zsT6M2KxcZyUSsL55RlNXlQ==", + "version": "2.4.13", + "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.4.13.tgz", + "integrity": "sha512-Ukz4xv84swJPupZeoFsQoeJEOm7U9pqsEnaGGgt5ni3SCTa22m8oJP5Nng3Wed7Uw5RBELdLxxORX8YhJPyOgQ==", "dev": true, "license": "MIT", "dependencies": { - "@volar/language-core": "2.4.0-alpha.17", + "@volar/language-core": "2.4.13", "path-browserify": "^1.0.1", "vscode-uri": "^3.0.8" } }, "node_modules/@vue/compiler-core": { - "version": "3.4.33", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.33.tgz", - "integrity": "sha512-MoIREbkdPQlnGfSKDMgzTqzqx5nmEjIc0ydLVYlTACGBsfvOJ4tHSbZXKVF536n6fB+0eZaGEOqsGThPpdvF5A==", + "version": "3.5.14", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.14.tgz", + "integrity": "sha512-k7qMHMbKvoCXIxPhquKQVw3Twid3Kg4s7+oYURxLGRd56LiuHJVrvFKI4fm2AM3c8apqODPfVJGoh8nePbXMRA==", "license": "MIT", "dependencies": { - "@babel/parser": "^7.24.7", - "@vue/shared": "3.4.33", + "@babel/parser": "^7.27.2", + "@vue/shared": "3.5.14", "entities": "^4.5.0", "estree-walker": "^2.0.2", - "source-map-js": "^1.2.0" + "source-map-js": "^1.2.1" } }, "node_modules/@vue/compiler-dom": { - "version": "3.4.33", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.33.tgz", - "integrity": "sha512-GzB8fxEHKw0gGet5BKlpfXEqoBnzSVWwMnT+dc25wE7pFEfrU/QsvjZMP9rD4iVXHBBoemTct8mN0GJEI6ZX5A==", + "version": "3.5.14", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.14.tgz", + "integrity": "sha512-1aOCSqxGOea5I80U2hQJvXYpPm/aXo95xL/m/mMhgyPUsKe9jhjwWpziNAw7tYRnbz1I61rd9Mld4W9KmmRoug==", "license": "MIT", "dependencies": { - "@vue/compiler-core": "3.4.33", - "@vue/shared": "3.4.33" + "@vue/compiler-core": "3.5.14", + "@vue/shared": "3.5.14" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.4.33", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.33.tgz", - "integrity": "sha512-7rk7Vbkn21xMwIUpHQR4hCVejwE6nvhBOiDgoBcR03qvGqRKA7dCBSsHZhwhYUsmjlbJ7OtD5UFIyhP6BY+c8A==", + "version": "3.5.14", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.14.tgz", + "integrity": "sha512-9T6m/9mMr81Lj58JpzsiSIjBgv2LiVoWjIVa7kuXHICUi8LiDSIotMpPRXYJsXKqyARrzjT24NAwttrMnMaCXA==", "license": "MIT", "dependencies": { - "@babel/parser": "^7.24.7", - "@vue/compiler-core": "3.4.33", - "@vue/compiler-dom": "3.4.33", - "@vue/compiler-ssr": "3.4.33", - "@vue/shared": "3.4.33", + "@babel/parser": "^7.27.2", + "@vue/compiler-core": "3.5.14", + "@vue/compiler-dom": "3.5.14", + "@vue/compiler-ssr": "3.5.14", + "@vue/shared": "3.5.14", "estree-walker": "^2.0.2", - "magic-string": "^0.30.10", - "postcss": "^8.4.39", - "source-map-js": "^1.2.0" + "magic-string": "^0.30.17", + "postcss": "^8.5.3", + "source-map-js": "^1.2.1" } }, "node_modules/@vue/compiler-ssr": { - "version": "3.4.33", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.33.tgz", - "integrity": "sha512-0WveC9Ai+eT/1b6LCV5IfsufBZ0HP7pSSTdDjcuW302tTEgoBw8rHVHKPbGUtzGReUFCRXbv6zQDDgucnV2WzQ==", + "version": "3.5.14", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.14.tgz", + "integrity": "sha512-Y0G7PcBxr1yllnHuS/NxNCSPWnRGH4Ogrp0tsLA5QemDZuJLs99YjAKQ7KqkHE0vCg4QTKlQzXLKCMF7WPSl7Q==", "license": "MIT", "dependencies": { - "@vue/compiler-dom": "3.4.33", - "@vue/shared": "3.4.33" + "@vue/compiler-dom": "3.5.14", + "@vue/shared": "3.5.14" } }, - "node_modules/@vue/language-core": { - "version": "2.0.26", - "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-2.0.26.tgz", - "integrity": "sha512-/lt6SfQ3O1yDAhPsnLv9iSUgXd1dMHqUm/t3RctfqjuwQf1LnftZ414X3UBn6aXT4MiwXWtbNJ4Z0NZWwDWgJQ==", + "node_modules/@vue/compiler-vue2": { + "version": "2.7.16", + "resolved": "https://registry.npmjs.org/@vue/compiler-vue2/-/compiler-vue2-2.7.16.tgz", + "integrity": "sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==", "dev": true, "license": "MIT", "dependencies": { - "@volar/language-core": "~2.4.0-alpha.15", - "@vue/compiler-dom": "^3.4.0", - "@vue/shared": "^3.4.0", - "computeds": "^0.0.1", + "de-indent": "^1.0.2", + "he": "^1.2.0" + } + }, + "node_modules/@vue/language-core": { + "version": "2.2.10", + "resolved": "https://registry.npmjs.org/@vue/language-core/-/language-core-2.2.10.tgz", + "integrity": "sha512-+yNoYx6XIKuAO8Mqh1vGytu8jkFEOH5C8iOv3i8Z/65A7x9iAOXA97Q+PqZ3nlm2lxf5rOJuIGI/wDtx/riNYw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@volar/language-core": "~2.4.11", + "@vue/compiler-dom": "^3.5.0", + "@vue/compiler-vue2": "^2.7.16", + "@vue/shared": "^3.5.0", + "alien-signals": "^1.0.3", "minimatch": "^9.0.3", "muggle-string": "^0.4.1", - "path-browserify": "^1.0.1", - "vue-template-compiler": "^2.7.14" + "path-browserify": "^1.0.1" }, "peerDependencies": { "typescript": "*" @@ -778,53 +913,60 @@ } }, "node_modules/@vue/reactivity": { - "version": "3.4.33", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.33.tgz", - "integrity": "sha512-B24QIelahDbyHipBgbUItQblbd4w5HpG3KccL+YkGyo3maXyS253FzcTR3pSz739OTphmzlxP7JxEMWBpewilA==", + "version": "3.5.14", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.14.tgz", + "integrity": "sha512-7cK1Hp343Fu/SUCCO52vCabjvsYu7ZkOqyYu7bXV9P2yyfjUMUXHZafEbq244sP7gf+EZEz+77QixBTuEqkQQw==", "license": "MIT", "dependencies": { - "@vue/shared": "3.4.33" + "@vue/shared": "3.5.14" } }, "node_modules/@vue/runtime-core": { - "version": "3.4.33", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.33.tgz", - "integrity": "sha512-6wavthExzT4iAxpe8q37/rDmf44nyOJGISJPxCi9YsQO+8w9v0gLCFLfH5TzD1V1AYrTAdiF4Y1cgUmP68jP6w==", + "version": "3.5.14", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.14.tgz", + "integrity": "sha512-w9JWEANwHXNgieAhxPpEpJa+0V5G0hz3NmjAZwlOebtfKyp2hKxKF0+qSh0Xs6/PhfGihuSdqMprMVcQU/E6ag==", "license": "MIT", "dependencies": { - "@vue/reactivity": "3.4.33", - "@vue/shared": "3.4.33" + "@vue/reactivity": "3.5.14", + "@vue/shared": "3.5.14" } }, "node_modules/@vue/runtime-dom": { - "version": "3.4.33", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.33.tgz", - "integrity": "sha512-iHsMCUSFJ+4z432Bn9kZzHX+zOXa6+iw36DaVRmKYZpPt9jW9riF32SxNwB124i61kp9+AZtheQ/mKoJLerAaQ==", + "version": "3.5.14", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.14.tgz", + "integrity": "sha512-lCfR++IakeI35TVR80QgOelsUIdcKjd65rWAMfdSlCYnaEY5t3hYwru7vvcWaqmrK+LpI7ZDDYiGU5V3xjMacw==", "license": "MIT", "dependencies": { - "@vue/reactivity": "3.4.33", - "@vue/runtime-core": "3.4.33", - "@vue/shared": "3.4.33", + "@vue/reactivity": "3.5.14", + "@vue/runtime-core": "3.5.14", + "@vue/shared": "3.5.14", "csstype": "^3.1.3" } }, "node_modules/@vue/server-renderer": { - "version": "3.4.33", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.33.tgz", - "integrity": "sha512-jTH0d6gQcaYideFP/k0WdEu8PpRS9MF8d0b6SfZzNi+ap972pZ0TNIeTaESwdOtdY0XPVj54XEJ6K0wXxir4fw==", + "version": "3.5.14", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.14.tgz", + "integrity": "sha512-Rf/ISLqokIvcySIYnv3tNWq40PLpNLDLSJwwVWzG6MNtyIhfbcrAxo5ZL9nARJhqjZyWWa40oRb2IDuejeuv6w==", "license": "MIT", "dependencies": { - "@vue/compiler-ssr": "3.4.33", - "@vue/shared": "3.4.33" + "@vue/compiler-ssr": "3.5.14", + "@vue/shared": "3.5.14" }, "peerDependencies": { - "vue": "3.4.33" + "vue": "3.5.14" } }, "node_modules/@vue/shared": { - "version": "3.4.33", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.33.tgz", - "integrity": "sha512-aoRY0jQk3A/cuvdkodTrM4NMfxco8n55eG4H7ML/CRy7OryHfiqvug4xrCBBMbbN+dvXAetDDwZW9DXWWjBntA==", + "version": "3.5.14", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.14.tgz", + "integrity": "sha512-oXTwNxVfc9EtP1zzXAlSlgARLXNC84frFYkS0HHz0h3E4WZSP9sywqjqzGCP9Y34M8ipNmd380pVgmMuwELDyQ==", + "license": "MIT" + }, + "node_modules/alien-signals": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/alien-signals/-/alien-signals-1.0.13.tgz", + "integrity": "sha512-OGj9yyTnJEttvzhTUWuscOvtqxq5vrhF7vL9oS0xJ2mK0ItPYP1/y+vCFebfxoEyAz0++1AIwJ5CMr+Fk3nDmg==", + "dev": true, "license": "MIT" }, "node_modules/balanced-match": { @@ -845,16 +987,9 @@ } }, "node_modules/bulma": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/bulma/-/bulma-1.0.1.tgz", - "integrity": "sha512-+xv/BIAEQakHkR0QVz+s+RjNqfC53Mx9ZYexyaFNFo9wx5i76HXArNdwW7bccyJxa5mgV/T5DcVGqsAB19nBJQ==", - "license": "MIT" - }, - "node_modules/computeds": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/computeds/-/computeds-0.0.1.tgz", - "integrity": "sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==", - "dev": true, + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/bulma/-/bulma-1.0.4.tgz", + "integrity": "sha512-Ffb6YGXDiZYX3cqvSbHWqQ8+LkX6tVoTcZuVB3lm93sbAVXlO0D6QlOTMnV6g18gILpAXqkG2z9hf9z4hCjz2g==", "license": "MIT" }, "node_modules/csstype": { @@ -883,9 +1018,9 @@ } }, "node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.4.tgz", + "integrity": "sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -893,32 +1028,34 @@ "esbuild": "bin/esbuild" }, "engines": { - "node": ">=12" + "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" + "@esbuild/aix-ppc64": "0.25.4", + "@esbuild/android-arm": "0.25.4", + "@esbuild/android-arm64": "0.25.4", + "@esbuild/android-x64": "0.25.4", + "@esbuild/darwin-arm64": "0.25.4", + "@esbuild/darwin-x64": "0.25.4", + "@esbuild/freebsd-arm64": "0.25.4", + "@esbuild/freebsd-x64": "0.25.4", + "@esbuild/linux-arm": "0.25.4", + "@esbuild/linux-arm64": "0.25.4", + "@esbuild/linux-ia32": "0.25.4", + "@esbuild/linux-loong64": "0.25.4", + "@esbuild/linux-mips64el": "0.25.4", + "@esbuild/linux-ppc64": "0.25.4", + "@esbuild/linux-riscv64": "0.25.4", + "@esbuild/linux-s390x": "0.25.4", + "@esbuild/linux-x64": "0.25.4", + "@esbuild/netbsd-arm64": "0.25.4", + "@esbuild/netbsd-x64": "0.25.4", + "@esbuild/openbsd-arm64": "0.25.4", + "@esbuild/openbsd-x64": "0.25.4", + "@esbuild/sunos-x64": "0.25.4", + "@esbuild/win32-arm64": "0.25.4", + "@esbuild/win32-ia32": "0.25.4", + "@esbuild/win32-x64": "0.25.4" } }, "node_modules/estree-walker": { @@ -927,6 +1064,21 @@ "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "license": "MIT" }, + "node_modules/fdir": { + "version": "6.4.4", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.4.tgz", + "integrity": "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -953,12 +1105,12 @@ } }, "node_modules/magic-string": { - "version": "0.30.10", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", - "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" + "@jridgewell/sourcemap-codec": "^1.5.0" } }, "node_modules/minimatch": { @@ -985,9 +1137,9 @@ "license": "MIT" }, "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", "funding": [ { "type": "github", @@ -1010,15 +1162,28 @@ "license": "MIT" }, "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", "license": "ISC" }, + "node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/postcss": { - "version": "8.4.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.39.tgz", - "integrity": "sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==", + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.3.tgz", + "integrity": "sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==", "funding": [ { "type": "opencollective", @@ -1035,18 +1200,18 @@ ], "license": "MIT", "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.1", - "source-map-js": "^1.2.0" + "nanoid": "^3.3.8", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" }, "engines": { "node": "^10 || ^12 || >=14" } }, "node_modules/prettier": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", - "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz", + "integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==", "dev": true, "license": "MIT", "bin": { @@ -1060,13 +1225,13 @@ } }, "node_modules/rollup": { - "version": "4.19.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.19.0.tgz", - "integrity": "sha512-5r7EYSQIowHsK4eTZ0Y81qpZuJz+MUuYeqmmYmRMl1nwhdmbiYqt5jwzf6u7wyOzJgYqtCRMtVRKOtHANBz7rA==", + "version": "4.40.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.40.2.tgz", + "integrity": "sha512-tfUOg6DTP4rhQ3VjOO6B4wyrJnGOX85requAXvqYTHsOgb2TFJdZ3aWpT8W2kPoypSGP7dZUyzxJ9ee4buM5Fg==", "dev": true, "license": "MIT", "dependencies": { - "@types/estree": "1.0.5" + "@types/estree": "1.0.7" }, "bin": { "rollup": "dist/bin/rollup" @@ -1076,51 +1241,59 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.19.0", - "@rollup/rollup-android-arm64": "4.19.0", - "@rollup/rollup-darwin-arm64": "4.19.0", - "@rollup/rollup-darwin-x64": "4.19.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.19.0", - "@rollup/rollup-linux-arm-musleabihf": "4.19.0", - "@rollup/rollup-linux-arm64-gnu": "4.19.0", - "@rollup/rollup-linux-arm64-musl": "4.19.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.19.0", - "@rollup/rollup-linux-riscv64-gnu": "4.19.0", - "@rollup/rollup-linux-s390x-gnu": "4.19.0", - "@rollup/rollup-linux-x64-gnu": "4.19.0", - "@rollup/rollup-linux-x64-musl": "4.19.0", - "@rollup/rollup-win32-arm64-msvc": "4.19.0", - "@rollup/rollup-win32-ia32-msvc": "4.19.0", - "@rollup/rollup-win32-x64-msvc": "4.19.0", + "@rollup/rollup-android-arm-eabi": "4.40.2", + "@rollup/rollup-android-arm64": "4.40.2", + "@rollup/rollup-darwin-arm64": "4.40.2", + "@rollup/rollup-darwin-x64": "4.40.2", + "@rollup/rollup-freebsd-arm64": "4.40.2", + "@rollup/rollup-freebsd-x64": "4.40.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.40.2", + "@rollup/rollup-linux-arm-musleabihf": "4.40.2", + "@rollup/rollup-linux-arm64-gnu": "4.40.2", + "@rollup/rollup-linux-arm64-musl": "4.40.2", + "@rollup/rollup-linux-loongarch64-gnu": "4.40.2", + "@rollup/rollup-linux-powerpc64le-gnu": "4.40.2", + "@rollup/rollup-linux-riscv64-gnu": "4.40.2", + "@rollup/rollup-linux-riscv64-musl": "4.40.2", + "@rollup/rollup-linux-s390x-gnu": "4.40.2", + "@rollup/rollup-linux-x64-gnu": "4.40.2", + "@rollup/rollup-linux-x64-musl": "4.40.2", + "@rollup/rollup-win32-arm64-msvc": "4.40.2", + "@rollup/rollup-win32-ia32-msvc": "4.40.2", + "@rollup/rollup-win32-x64-msvc": "4.40.2", "fsevents": "~2.3.2" } }, - "node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, + "node_modules/tinyglobby": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.13.tgz", + "integrity": "sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.4.4", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, "node_modules/typescript": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", - "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", "devOptional": true, "license": "Apache-2.0", "bin": { @@ -1132,21 +1305,24 @@ } }, "node_modules/vite": { - "version": "5.3.4", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.3.4.tgz", - "integrity": "sha512-Cw+7zL3ZG9/NZBB8C+8QbQZmR54GwqIz+WMI4b3JgdYJvX+ny9AjJXqkGQlDXSXRP9rP0B4tbciRMOVEKulVOA==", + "version": "6.3.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz", + "integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==", "dev": true, "license": "MIT", "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.39", - "rollup": "^4.13.0" + "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", + "postcss": "^8.5.3", + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" }, "bin": { "vite": "bin/vite.js" }, "engines": { - "node": "^18.0.0 || >=20.0.0" + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" }, "funding": { "url": "https://github.com/vitejs/vite?sponsor=1" @@ -1155,18 +1331,25 @@ "fsevents": "~2.3.3" }, "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", + "sass-embedded": "*", "stylus": "*", "sugarss": "*", - "terser": "^5.4.0" + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" }, "peerDependenciesMeta": { "@types/node": { "optional": true }, + "jiti": { + "optional": true + }, "less": { "optional": true }, @@ -1176,6 +1359,9 @@ "sass": { "optional": true }, + "sass-embedded": { + "optional": true + }, "stylus": { "optional": true }, @@ -1184,27 +1370,33 @@ }, "terser": { "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true } } }, "node_modules/vscode-uri": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz", - "integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.1.0.tgz", + "integrity": "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==", "dev": true, "license": "MIT" }, "node_modules/vue": { - "version": "3.4.33", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.33.tgz", - "integrity": "sha512-VdMCWQOummbhctl4QFMcW6eNtXHsFyDlX60O/tsSQuCcuDOnJ1qPOhhVla65Niece7xq/P2zyZReIO5mP+LGTQ==", + "version": "3.5.14", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.14.tgz", + "integrity": "sha512-LbOm50/vZFG6Mhy6KscQYXZMQ0LMCC/y40HDJPPvGFQ+i/lUH+PJHR6C3assgOQiXdl6tAfsXHbXYVBZZu65ew==", "license": "MIT", "dependencies": { - "@vue/compiler-dom": "3.4.33", - "@vue/compiler-sfc": "3.4.33", - "@vue/runtime-dom": "3.4.33", - "@vue/server-renderer": "3.4.33", - "@vue/shared": "3.4.33" + "@vue/compiler-dom": "3.5.14", + "@vue/compiler-sfc": "3.5.14", + "@vue/runtime-dom": "3.5.14", + "@vue/server-renderer": "3.5.14", + "@vue/shared": "3.5.14" }, "peerDependencies": { "typescript": "*" @@ -1215,27 +1407,15 @@ } } }, - "node_modules/vue-template-compiler": { - "version": "2.7.16", - "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.16.tgz", - "integrity": "sha512-AYbUWAJHLGGQM7+cNTELw+KsOG9nl2CnSv467WobS5Cv9uk3wFcnr1Etsz2sEIHEZvw1U+o9mRlEO6QbZvUPGQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "de-indent": "^1.0.2", - "he": "^1.2.0" - } - }, "node_modules/vue-tsc": { - "version": "2.0.26", - "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-2.0.26.tgz", - "integrity": "sha512-tOhuwy2bIXbMhz82ef37qeiaQHMXKQkD6mOF6CCPl3/uYtST3l6fdNyfMxipudrQTxTfXVPlgJdMENBFfC1CfQ==", + "version": "2.2.10", + "resolved": "https://registry.npmjs.org/vue-tsc/-/vue-tsc-2.2.10.tgz", + "integrity": "sha512-jWZ1xSaNbabEV3whpIDMbjVSVawjAyW+x1n3JeGQo7S0uv2n9F/JMgWW90tGWNFRKya4YwKMZgCtr0vRAM7DeQ==", "dev": true, "license": "MIT", "dependencies": { - "@volar/typescript": "~2.4.0-alpha.15", - "@vue/language-core": "2.0.26", - "semver": "^7.5.4" + "@volar/typescript": "~2.4.11", + "@vue/language-core": "2.2.10" }, "bin": { "vue-tsc": "bin/vue-tsc.js" diff --git a/unwind-ui/package.json b/unwind-ui/package.json index c49115b..a87ca11 100644 --- a/unwind-ui/package.json +++ b/unwind-ui/package.json @@ -16,7 +16,7 @@ "@vue/compiler-sfc": "^3.0.5", "prettier": "^3.2.5", "typescript": "^5.4.5", - "vite": "^5.2.11", + "vite": "^6.3.5", "vue-tsc": "^2.0.16" }, "prettier": { diff --git a/unwind/imdb.py b/unwind/imdb.py index 3d844a5..9afdd11 100644 --- a/unwind/imdb.py +++ b/unwind/imdb.py @@ -3,7 +3,7 @@ import logging import re from collections import namedtuple from dataclasses import dataclass, field -from datetime import datetime +from datetime import datetime, timezone from typing import Any, AsyncIterable, Iterable from urllib.parse import urljoin @@ -125,7 +125,7 @@ def _tv_episode_title(series_name: str, episode_name: str) -> str: def _movie_and_rating_from_item_legacy(item: bs4.Tag) -> tuple[Movie, Rating]: - genres = (genre := item.find("span", "genre")) and genre.string or "" + genres = ((genre := item.find("span", "genre")) and genre.string) or "" movie = Movie( title=item.h3.a.string.strip(), genres={s.strip() for s in genres.split(",")}, @@ -165,7 +165,9 @@ def _movie_and_rating_from_item_legacy(item: bs4.Tag) -> tuple[Movie, Rating]: ratings_item = item.find("div", "ipl-rating-widget") if match := find_rating_date(ratings_item.find_next("p", "text-muted").string): - rating.rating_date = datetime.strptime(match["date"], "%d %b %Y") + rating.rating_date = datetime.strptime(match["date"], "%d %b %Y").replace( + tzinfo=timezone.utc + ) if match := ratings_item.find("div", "ipl-rating-star--other-user"): if rating_item := match.find("span", "ipl-rating-star__rating"): rating.score = score_from_imdb_rating(float(rating_item.string)) diff --git a/unwind/models.py b/unwind/models.py index 82837fc..d5d149f 100644 --- a/unwind/models.py +++ b/unwind/models.py @@ -184,9 +184,9 @@ def asplain( assert isinstance(v, list) d[f.name] = dump(list(v)) elif target in {bool, str, int, float}: - assert isinstance( - v, target - ), f"Type mismatch: {f.name!a} ({target!a} != {type(v)!a})" + assert isinstance(v, target), ( + f"Type mismatch: {f.name!a} ({target!a} != {type(v)!a})" + ) d[f.name] = v elif target in {Literal}: assert isinstance(v, JSONScalar.__value__) diff --git a/unwind/web.py b/unwind/web.py index cfd23cc..3812e79 100644 --- a/unwind/web.py +++ b/unwind/web.py @@ -280,7 +280,7 @@ async def list_movies(request: Request) -> JSONResponse: if not group: return not_found("Group not found.") - is_allowed = is_admin(request) or user and user.has_access(group_id) + is_allowed = is_admin(request) or (user and user.has_access(group_id)) if not is_allowed: return forbidden("No access to group.") @@ -290,7 +290,7 @@ async def list_movies(request: Request) -> JSONResponse: user_id = as_ulid(user_id) # Currently a user may only directly access their own ratings. - is_allowed = is_admin(request) or user and user.id == user_id + is_allowed = is_admin(request) or (user and user.id == user_id) if not is_allowed: return forbidden("No access to user.") diff --git a/uv.lock b/uv.lock index 6d41a6e..3c58fee 100644 --- a/uv.lock +++ b/uv.lock @@ -1,77 +1,78 @@ version = 1 revision = 2 -requires-python = ">=3.12" +requires-python = ">=3.13" [[package]] name = "aiosqlite" -version = "0.20.0" +version = "0.21.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/0d/3a/22ff5415bf4d296c1e92b07fd746ad42c96781f13295a074d58e77747848/aiosqlite-0.20.0.tar.gz", hash = "sha256:6d35c8c256637f4672f843c31021464090805bf925385ac39473fb16eaaca3d7", size = 21691, upload-time = "2024-02-20T06:12:53.915Z" } +sdist = { url = "https://files.pythonhosted.org/packages/13/7d/8bca2bf9a247c2c5dfeec1d7a5f40db6518f88d314b8bca9da29670d2671/aiosqlite-0.21.0.tar.gz", hash = "sha256:131bb8056daa3bc875608c631c678cda73922a2d4ba8aec373b19f18c17e7aa3", size = 13454, upload-time = "2025-02-03T07:30:16.235Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/00/c4/c93eb22025a2de6b83263dfe3d7df2e19138e345bca6f18dba7394120930/aiosqlite-0.20.0-py3-none-any.whl", hash = "sha256:36a1deaca0cac40ebe32aac9977a6e2bbc7f5189f23f4a54d5908986729e5bd6", size = 15564, upload-time = "2024-02-20T06:12:50.657Z" }, + { url = "https://files.pythonhosted.org/packages/f5/10/6c25ed6de94c49f88a91fa5018cb4c0f3625f31d5be9f771ebe5cc7cd506/aiosqlite-0.21.0-py3-none-any.whl", hash = "sha256:2549cf4057f95f53dcba16f2b64e8e2791d7e1adedb13197dd8ed77bb226d7d0", size = 15792, upload-time = "2025-02-03T07:30:13.6Z" }, ] [[package]] name = "alembic" -version = "1.13.2" +version = "1.15.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mako" }, { name = "sqlalchemy" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/66/e2/efa88e86029cada2da5941ec664d50d9a3b2a91f5066405c6f90e5016c16/alembic-1.13.2.tar.gz", hash = "sha256:1ff0ae32975f4fd96028c39ed9bb3c867fe3af956bd7bb37343b54c9fe7445ef", size = 1206463, upload-time = "2024-06-26T15:46:17.728Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e6/57/e314c31b261d1e8a5a5f1908065b4ff98270a778ce7579bd4254477209a7/alembic-1.15.2.tar.gz", hash = "sha256:1c72391bbdeffccfe317eefba686cb9a3c078005478885413b95c3b26c57a8a7", size = 1925573, upload-time = "2025-03-28T13:52:00.443Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/df/ed/c884465c33c25451e4a5cd4acad154c29e5341e3214e220e7f3478aa4b0d/alembic-1.13.2-py3-none-any.whl", hash = "sha256:6b8733129a6224a9a711e17c99b08462dbf7cc9670ba8f2e2ae9af860ceb1953", size = 232990, upload-time = "2024-06-26T15:46:21.088Z" }, + { url = "https://files.pythonhosted.org/packages/41/18/d89a443ed1ab9bcda16264716f809c663866d4ca8de218aa78fd50b38ead/alembic-1.15.2-py3-none-any.whl", hash = "sha256:2e76bd916d547f6900ec4bb5a90aeac1485d2c92536923d0b138c02b126edc53", size = 231911, upload-time = "2025-03-28T13:52:02.218Z" }, ] [[package]] name = "anyio" -version = "4.4.0" +version = "4.9.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "idna" }, { name = "sniffio" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e6/e3/c4c8d473d6780ef1853d630d581f70d655b4f8d7553c6997958c283039a2/anyio-4.4.0.tar.gz", hash = "sha256:5aadc6a1bbb7cdb0bede386cac5e2940f5e2ff3aa20277e991cf028e0585ce94", size = 163930, upload-time = "2024-05-26T22:02:15.75Z" } +sdist = { url = "https://files.pythonhosted.org/packages/95/7d/4c1bd541d4dffa1b52bd83fb8527089e097a106fc90b467a7313b105f840/anyio-4.9.0.tar.gz", hash = "sha256:673c0c244e15788651a4ff38710fea9675823028a6f08a5eda409e0c9840a028", size = 190949, upload-time = "2025-03-17T00:02:54.77Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7b/a2/10639a79341f6c019dedc95bd48a4928eed9f1d1197f4c04f546fc7ae0ff/anyio-4.4.0-py3-none-any.whl", hash = "sha256:c1b2d8f46a8a812513012e1107cb0e68c17159a7a594208005a57dc776e1bdc7", size = 86780, upload-time = "2024-05-26T22:02:13.671Z" }, + { url = "https://files.pythonhosted.org/packages/a1/ee/48ca1a7c89ffec8b6a0c5d02b89c305671d5ffd8d3c94acf8b8c408575bb/anyio-4.9.0-py3-none-any.whl", hash = "sha256:9f76d541cad6e36af7beb62e978876f3b41e3e04f2c1fbf0884604c0a9c4d93c", size = 100916, upload-time = "2025-03-17T00:02:52.713Z" }, ] [[package]] name = "beautifulsoup4" -version = "4.12.3" +version = "4.13.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "soupsieve" }, + { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b3/ca/824b1195773ce6166d388573fc106ce56d4a805bd7427b624e063596ec58/beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051", size = 581181, upload-time = "2024-01-17T16:53:17.902Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/e4/0c4c39e18fd76d6a628d4dd8da40543d136ce2d1752bd6eeeab0791f4d6b/beautifulsoup4-4.13.4.tar.gz", hash = "sha256:dbb3c4e1ceae6aefebdaf2423247260cd062430a410e38c66f2baa50a8437195", size = 621067, upload-time = "2025-04-15T17:05:13.836Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b1/fe/e8c672695b37eecc5cbf43e1d0638d88d66ba3a44c4d321c796f4e59167f/beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed", size = 147925, upload-time = "2024-01-17T16:53:12.779Z" }, + { url = "https://files.pythonhosted.org/packages/50/cd/30110dc0ffcf3b131156077b90e9f60ed75711223f306da4db08eff8403b/beautifulsoup4-4.13.4-py3-none-any.whl", hash = "sha256:9bbbb14bfde9d79f38b8cd5f8c7c85f4b8f2523190ebed90e950a8dea4cb1c4b", size = 187285, upload-time = "2025-04-15T17:05:12.221Z" }, ] [[package]] name = "certifi" -version = "2024.7.4" +version = "2025.4.26" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c2/02/a95f2b11e207f68bc64d7aae9666fed2e2b3f307748d5123dffb72a1bbea/certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b", size = 164065, upload-time = "2024-07-04T01:36:11.653Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e8/9e/c05b3920a3b7d20d3d3310465f50348e5b3694f4f88c6daf736eef3024c4/certifi-2025.4.26.tar.gz", hash = "sha256:0a816057ea3cdefcef70270d2c515e4506bbc954f417fa5ade2021213bb8f0c6", size = 160705, upload-time = "2025-04-26T02:12:29.51Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1c/d5/c84e1a17bf61d4df64ca866a1c9a913874b4e9bdc131ec689a0ad013fb36/certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90", size = 162960, upload-time = "2024-07-04T01:36:09.038Z" }, + { url = "https://files.pythonhosted.org/packages/4a/7e/3db2bd1b1f9e95f7cddca6d6e75e2f2bd9f51b1246e546d88addca0106bd/certifi-2025.4.26-py3-none-any.whl", hash = "sha256:30350364dfe371162649852c63336a15c70c6510c2ad5015b21c2345311805f3", size = 159618, upload-time = "2025-04-26T02:12:27.662Z" }, ] [[package]] name = "click" -version = "8.1.7" +version = "8.2.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/96/d3/f04c7bfcf5c1862a2a5b845c6b2b360488cf47af55dfa79c98f6a6bf98b5/click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de", size = 336121, upload-time = "2023-08-17T17:29:11.868Z" } +sdist = { url = "https://files.pythonhosted.org/packages/cd/0f/62ca20172d4f87d93cf89665fbaedcd560ac48b465bd1d92bfc7ea6b0a41/click-8.2.0.tar.gz", hash = "sha256:f5452aeddd9988eefa20f90f05ab66f17fce1ee2a36907fd30b05bbb5953814d", size = 235857, upload-time = "2025-05-10T22:21:03.111Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", size = 97941, upload-time = "2023-08-17T17:29:10.08Z" }, + { url = "https://files.pythonhosted.org/packages/a2/58/1f37bf81e3c689cc74ffa42102fa8915b59085f54a6e4a80bc6265c0f6bf/click-8.2.0-py3-none-any.whl", hash = "sha256:6b303f0b2aa85f1cb4e5303078fadcbcd4e476f114fab9b5007005711839325c", size = 102156, upload-time = "2025-05-10T22:21:01.352Z" }, ] [[package]] @@ -85,58 +86,77 @@ wheels = [ [[package]] name = "coverage" -version = "7.6.0" +version = "7.8.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/64/c8/a94ce9e17756aed521085ae716d627623374d34f92c1daf7162272ecb030/coverage-7.6.0.tar.gz", hash = "sha256:289cc803fa1dc901f84701ac10c9ee873619320f2f9aff38794db4a4a0268d51", size = 797590, upload-time = "2024-07-11T17:28:12.31Z" } +sdist = { url = "https://files.pythonhosted.org/packages/19/4f/2251e65033ed2ce1e68f00f91a0294e0f80c80ae8c3ebbe2f12828c4cd53/coverage-7.8.0.tar.gz", hash = "sha256:7a3d62b3b03b4b6fd41a085f3574874cf946cb4604d2b4d3e8dca8cd570ca501", size = 811872, upload-time = "2025-03-30T20:36:45.376Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/57/3a/287ea47cca84c92528b5f9b34b971f845b637d37c3eead9f10aede3531da/coverage-7.6.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f7db0b6ae1f96ae41afe626095149ecd1b212b424626175a6633c2999eaad45b", size = 206079, upload-time = "2024-07-11T17:26:56.219Z" }, - { url = "https://files.pythonhosted.org/packages/7b/14/3432bbdabeaa79de25421d24161ab472578ffe73fc56b0aa9411bea66335/coverage-7.6.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bbdf9a72403110a3bdae77948b8011f644571311c2fb35ee15f0f10a8fc082e8", size = 206320, upload-time = "2024-07-11T17:26:58.834Z" }, - { url = "https://files.pythonhosted.org/packages/0e/2a/f62d42a48449b26cfdf940661cf28bccc27e199dc0e956c738a6b1c942af/coverage-7.6.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cc44bf0315268e253bf563f3560e6c004efe38f76db03a1558274a6e04bf5d5", size = 239454, upload-time = "2024-07-11T17:27:00.739Z" }, - { url = "https://files.pythonhosted.org/packages/0c/a2/d7c0988df525298b2c19c482cec27f76bbeba6c3ed7f85d9f79d8996e509/coverage-7.6.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da8549d17489cd52f85a9829d0e1d91059359b3c54a26f28bec2c5d369524807", size = 236478, upload-time = "2024-07-11T17:27:03.483Z" }, - { url = "https://files.pythonhosted.org/packages/f2/aa/0419103c357bfd95a65d7b2e2249f9f1d79194241c5e87819cd81d36b96c/coverage-7.6.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0086cd4fc71b7d485ac93ca4239c8f75732c2ae3ba83f6be1c9be59d9e2c6382", size = 238563, upload-time = "2024-07-11T17:27:07.354Z" }, - { url = "https://files.pythonhosted.org/packages/2a/ce/375f8fbbabc51e3dfce91355460912c930a4e241ffbafc1f3a35f43ac90b/coverage-7.6.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1fad32ee9b27350687035cb5fdf9145bc9cf0a094a9577d43e909948ebcfa27b", size = 238039, upload-time = "2024-07-11T17:27:10.171Z" }, - { url = "https://files.pythonhosted.org/packages/fd/ca/5eb0004e0bf66db1d4a18c67e4aece76ff409b061d85f31843c28c9a531c/coverage-7.6.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:044a0985a4f25b335882b0966625270a8d9db3d3409ddc49a4eb00b0ef5e8cee", size = 236357, upload-time = "2024-07-11T17:27:12.694Z" }, - { url = "https://files.pythonhosted.org/packages/64/ea/848f064727fe172e80f8a7abc77664c593b6bece14d5acab7d7087f1244e/coverage-7.6.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:76d5f82213aa78098b9b964ea89de4617e70e0d43e97900c2778a50856dac605", size = 238003, upload-time = "2024-07-11T17:27:15.079Z" }, - { url = "https://files.pythonhosted.org/packages/c2/b1/8f54a56789aecc930e227fc5900d18628d6efae4a8ad24981d58fc14b1e3/coverage-7.6.0-cp312-cp312-win32.whl", hash = "sha256:3c59105f8d58ce500f348c5b56163a4113a440dad6daa2294b5052a10db866da", size = 208686, upload-time = "2024-07-11T17:27:18.045Z" }, - { url = "https://files.pythonhosted.org/packages/cb/db/242c44433c5d342c8bf83864131e56af8c1c1ea5645a825b1800c19ad9bf/coverage-7.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:ca5d79cfdae420a1d52bf177de4bc2289c321d6c961ae321503b2ca59c17ae67", size = 209455, upload-time = "2024-07-11T17:27:20.559Z" }, + { url = "https://files.pythonhosted.org/packages/f3/21/87e9b97b568e223f3438d93072479c2f36cc9b3f6b9f7094b9d50232acc0/coverage-7.8.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5ac46d0c2dd5820ce93943a501ac5f6548ea81594777ca585bf002aa8854cacd", size = 211708, upload-time = "2025-03-30T20:35:47.417Z" }, + { url = "https://files.pythonhosted.org/packages/75/be/882d08b28a0d19c9c4c2e8a1c6ebe1f79c9c839eb46d4fca3bd3b34562b9/coverage-7.8.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:771eb7587a0563ca5bb6f622b9ed7f9d07bd08900f7589b4febff05f469bea00", size = 211981, upload-time = "2025-03-30T20:35:49.002Z" }, + { url = "https://files.pythonhosted.org/packages/7a/1d/ce99612ebd58082fbe3f8c66f6d8d5694976c76a0d474503fa70633ec77f/coverage-7.8.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42421e04069fb2cbcbca5a696c4050b84a43b05392679d4068acbe65449b5c64", size = 245495, upload-time = "2025-03-30T20:35:51.073Z" }, + { url = "https://files.pythonhosted.org/packages/dc/8d/6115abe97df98db6b2bd76aae395fcc941d039a7acd25f741312ced9a78f/coverage-7.8.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:554fec1199d93ab30adaa751db68acec2b41c5602ac944bb19187cb9a41a8067", size = 242538, upload-time = "2025-03-30T20:35:52.941Z" }, + { url = "https://files.pythonhosted.org/packages/cb/74/2f8cc196643b15bc096d60e073691dadb3dca48418f08bc78dd6e899383e/coverage-7.8.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5aaeb00761f985007b38cf463b1d160a14a22c34eb3f6a39d9ad6fc27cb73008", size = 244561, upload-time = "2025-03-30T20:35:54.658Z" }, + { url = "https://files.pythonhosted.org/packages/22/70/c10c77cd77970ac965734fe3419f2c98665f6e982744a9bfb0e749d298f4/coverage-7.8.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:581a40c7b94921fffd6457ffe532259813fc68eb2bdda60fa8cc343414ce3733", size = 244633, upload-time = "2025-03-30T20:35:56.221Z" }, + { url = "https://files.pythonhosted.org/packages/38/5a/4f7569d946a07c952688debee18c2bb9ab24f88027e3d71fd25dbc2f9dca/coverage-7.8.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f319bae0321bc838e205bf9e5bc28f0a3165f30c203b610f17ab5552cff90323", size = 242712, upload-time = "2025-03-30T20:35:57.801Z" }, + { url = "https://files.pythonhosted.org/packages/bb/a1/03a43b33f50475a632a91ea8c127f7e35e53786dbe6781c25f19fd5a65f8/coverage-7.8.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:04bfec25a8ef1c5f41f5e7e5c842f6b615599ca8ba8391ec33a9290d9d2db3a3", size = 244000, upload-time = "2025-03-30T20:35:59.378Z" }, + { url = "https://files.pythonhosted.org/packages/6a/89/ab6c43b1788a3128e4d1b7b54214548dcad75a621f9d277b14d16a80d8a1/coverage-7.8.0-cp313-cp313-win32.whl", hash = "sha256:dd19608788b50eed889e13a5d71d832edc34fc9dfce606f66e8f9f917eef910d", size = 214195, upload-time = "2025-03-30T20:36:01.005Z" }, + { url = "https://files.pythonhosted.org/packages/12/12/6bf5f9a8b063d116bac536a7fb594fc35cb04981654cccb4bbfea5dcdfa0/coverage-7.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:a9abbccd778d98e9c7e85038e35e91e67f5b520776781d9a1e2ee9d400869487", size = 214998, upload-time = "2025-03-30T20:36:03.006Z" }, + { url = "https://files.pythonhosted.org/packages/2a/e6/1e9df74ef7a1c983a9c7443dac8aac37a46f1939ae3499424622e72a6f78/coverage-7.8.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:18c5ae6d061ad5b3e7eef4363fb27a0576012a7447af48be6c75b88494c6cf25", size = 212541, upload-time = "2025-03-30T20:36:04.638Z" }, + { url = "https://files.pythonhosted.org/packages/04/51/c32174edb7ee49744e2e81c4b1414ac9df3dacfcb5b5f273b7f285ad43f6/coverage-7.8.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:95aa6ae391a22bbbce1b77ddac846c98c5473de0372ba5c463480043a07bff42", size = 212767, upload-time = "2025-03-30T20:36:06.503Z" }, + { url = "https://files.pythonhosted.org/packages/e9/8f/f454cbdb5212f13f29d4a7983db69169f1937e869a5142bce983ded52162/coverage-7.8.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e013b07ba1c748dacc2a80e69a46286ff145935f260eb8c72df7185bf048f502", size = 256997, upload-time = "2025-03-30T20:36:08.137Z" }, + { url = "https://files.pythonhosted.org/packages/e6/74/2bf9e78b321216d6ee90a81e5c22f912fc428442c830c4077b4a071db66f/coverage-7.8.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d766a4f0e5aa1ba056ec3496243150698dc0481902e2b8559314368717be82b1", size = 252708, upload-time = "2025-03-30T20:36:09.781Z" }, + { url = "https://files.pythonhosted.org/packages/92/4d/50d7eb1e9a6062bee6e2f92e78b0998848a972e9afad349b6cdde6fa9e32/coverage-7.8.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad80e6b4a0c3cb6f10f29ae4c60e991f424e6b14219d46f1e7d442b938ee68a4", size = 255046, upload-time = "2025-03-30T20:36:11.409Z" }, + { url = "https://files.pythonhosted.org/packages/40/9e/71fb4e7402a07c4198ab44fc564d09d7d0ffca46a9fb7b0a7b929e7641bd/coverage-7.8.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b87eb6fc9e1bb8f98892a2458781348fa37e6925f35bb6ceb9d4afd54ba36c73", size = 256139, upload-time = "2025-03-30T20:36:13.86Z" }, + { url = "https://files.pythonhosted.org/packages/49/1a/78d37f7a42b5beff027e807c2843185961fdae7fe23aad5a4837c93f9d25/coverage-7.8.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:d1ba00ae33be84066cfbe7361d4e04dec78445b2b88bdb734d0d1cbab916025a", size = 254307, upload-time = "2025-03-30T20:36:16.074Z" }, + { url = "https://files.pythonhosted.org/packages/58/e9/8fb8e0ff6bef5e170ee19d59ca694f9001b2ec085dc99b4f65c128bb3f9a/coverage-7.8.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f3c38e4e5ccbdc9198aecc766cedbb134b2d89bf64533973678dfcf07effd883", size = 255116, upload-time = "2025-03-30T20:36:18.033Z" }, + { url = "https://files.pythonhosted.org/packages/56/b0/d968ecdbe6fe0a863de7169bbe9e8a476868959f3af24981f6a10d2b6924/coverage-7.8.0-cp313-cp313t-win32.whl", hash = "sha256:379fe315e206b14e21db5240f89dc0774bdd3e25c3c58c2c733c99eca96f1ada", size = 214909, upload-time = "2025-03-30T20:36:19.644Z" }, + { url = "https://files.pythonhosted.org/packages/87/e9/d6b7ef9fecf42dfb418d93544af47c940aa83056c49e6021a564aafbc91f/coverage-7.8.0-cp313-cp313t-win_amd64.whl", hash = "sha256:2e4b6b87bb0c846a9315e3ab4be2d52fac905100565f4b92f02c445c8799e257", size = 216068, upload-time = "2025-03-30T20:36:21.282Z" }, + { url = "https://files.pythonhosted.org/packages/59/f1/4da7717f0063a222db253e7121bd6a56f6fb1ba439dcc36659088793347c/coverage-7.8.0-py3-none-any.whl", hash = "sha256:dbf364b4c5e7bae9250528167dfe40219b62e2d573c854d74be213e1e52069f7", size = 203435, upload-time = "2025-03-30T20:36:43.61Z" }, ] [[package]] name = "greenlet" -version = "3.0.3" +version = "3.2.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/17/14/3bddb1298b9a6786539ac609ba4b7c9c0842e12aa73aaa4d8d73ec8f8185/greenlet-3.0.3.tar.gz", hash = "sha256:43374442353259554ce33599da8b692d5aa96f8976d567d4badf263371fbe491", size = 182013, upload-time = "2023-12-21T22:02:54.659Z" } +sdist = { url = "https://files.pythonhosted.org/packages/34/c1/a82edae11d46c0d83481aacaa1e578fea21d94a1ef400afd734d47ad95ad/greenlet-3.2.2.tar.gz", hash = "sha256:ad053d34421a2debba45aa3cc39acf454acbcd025b3fc1a9f8a0dee237abd485", size = 185797, upload-time = "2025-05-09T19:47:35.066Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a2/2f/461615adc53ba81e99471303b15ac6b2a6daa8d2a0f7f77fd15605e16d5b/greenlet-3.0.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:70fb482fdf2c707765ab5f0b6655e9cfcf3780d8d87355a063547b41177599be", size = 273085, upload-time = "2023-12-21T22:03:01.176Z" }, - { url = "https://files.pythonhosted.org/packages/e9/55/2c3cfa3cdbb940cf7321fbcf544f0e9c74898eed43bf678abf416812d132/greenlet-3.0.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4d1ac74f5c0c0524e4a24335350edad7e5f03b9532da7ea4d3c54d527784f2e", size = 660514, upload-time = "2023-12-21T22:29:28.62Z" }, - { url = "https://files.pythonhosted.org/packages/38/77/efb21ab402651896c74f24a172eb4d7479f9f53898bd5e56b9e20bb24ffd/greenlet-3.0.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:149e94a2dd82d19838fe4b2259f1b6b9957d5ba1b25640d2380bea9c5df37676", size = 674295, upload-time = "2023-12-21T22:26:24.101Z" }, - { url = "https://files.pythonhosted.org/packages/74/3a/92f188ace0190f0066dca3636cf1b09481d0854c46e92ec5e29c7cefe5b1/greenlet-3.0.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15d79dd26056573940fcb8c7413d84118086f2ec1a8acdfa854631084393efcc", size = 669395, upload-time = "2023-12-21T22:31:35.992Z" }, - { url = "https://files.pythonhosted.org/packages/63/0f/847ed02cdfce10f0e6e3425cd054296bddb11a17ef1b34681fa01a055187/greenlet-3.0.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:881b7db1ebff4ba09aaaeae6aa491daeb226c8150fc20e836ad00041bcb11230", size = 670455, upload-time = "2023-12-21T22:03:16.291Z" }, - { url = "https://files.pythonhosted.org/packages/bd/37/56b0da468a85e7704f3b2bc045015301bdf4be2184a44868c71f6dca6fe2/greenlet-3.0.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fcd2469d6a2cf298f198f0487e0a5b1a47a42ca0fa4dfd1b6862c999f018ebbf", size = 625692, upload-time = "2023-12-21T22:03:06.294Z" }, - { url = "https://files.pythonhosted.org/packages/7c/68/b5f4084c0a252d7e9c0d95fc1cfc845d08622037adb74e05be3a49831186/greenlet-3.0.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1f672519db1796ca0d8753f9e78ec02355e862d0998193038c7073045899f305", size = 1152597, upload-time = "2023-12-21T22:31:00.412Z" }, - { url = "https://files.pythonhosted.org/packages/a4/fa/31e22345518adcd69d1d6ab5087a12c178aa7f3c51103f6d5d702199d243/greenlet-3.0.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2516a9957eed41dd8f1ec0c604f1cdc86758b587d964668b5b196a9db5bfcde6", size = 1181043, upload-time = "2023-12-21T22:04:20.032Z" }, - { url = "https://files.pythonhosted.org/packages/53/80/3d94d5999b4179d91bcc93745d1b0815b073d61be79dd546b840d17adb18/greenlet-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:bba5387a6975598857d86de9eac14210a49d554a77eb8261cc68b7d082f78ce2", size = 293635, upload-time = "2023-12-21T22:26:01.555Z" }, + { url = "https://files.pythonhosted.org/packages/89/30/97b49779fff8601af20972a62cc4af0c497c1504dfbb3e93be218e093f21/greenlet-3.2.2-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:3ab7194ee290302ca15449f601036007873028712e92ca15fc76597a0aeb4c59", size = 269150, upload-time = "2025-05-09T14:50:30.784Z" }, + { url = "https://files.pythonhosted.org/packages/21/30/877245def4220f684bc2e01df1c2e782c164e84b32e07373992f14a2d107/greenlet-3.2.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2dc5c43bb65ec3669452af0ab10729e8fdc17f87a1f2ad7ec65d4aaaefabf6bf", size = 637381, upload-time = "2025-05-09T15:24:12.893Z" }, + { url = "https://files.pythonhosted.org/packages/8e/16/adf937908e1f913856b5371c1d8bdaef5f58f251d714085abeea73ecc471/greenlet-3.2.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:decb0658ec19e5c1f519faa9a160c0fc85a41a7e6654b3ce1b44b939f8bf1325", size = 651427, upload-time = "2025-05-09T15:24:51.074Z" }, + { url = "https://files.pythonhosted.org/packages/ad/49/6d79f58fa695b618654adac64e56aff2eeb13344dc28259af8f505662bb1/greenlet-3.2.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6fadd183186db360b61cb34e81117a096bff91c072929cd1b529eb20dd46e6c5", size = 645795, upload-time = "2025-05-09T15:29:26.673Z" }, + { url = "https://files.pythonhosted.org/packages/5a/e6/28ed5cb929c6b2f001e96b1d0698c622976cd8f1e41fe7ebc047fa7c6dd4/greenlet-3.2.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1919cbdc1c53ef739c94cf2985056bcc0838c1f217b57647cbf4578576c63825", size = 648398, upload-time = "2025-05-09T14:53:36.61Z" }, + { url = "https://files.pythonhosted.org/packages/9d/70/b200194e25ae86bc57077f695b6cc47ee3118becf54130c5514456cf8dac/greenlet-3.2.2-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3885f85b61798f4192d544aac7b25a04ece5fe2704670b4ab73c2d2c14ab740d", size = 606795, upload-time = "2025-05-09T14:53:47.039Z" }, + { url = "https://files.pythonhosted.org/packages/f8/c8/ba1def67513a941154ed8f9477ae6e5a03f645be6b507d3930f72ed508d3/greenlet-3.2.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:85f3e248507125bf4af607a26fd6cb8578776197bd4b66e35229cdf5acf1dfbf", size = 1117976, upload-time = "2025-05-09T15:27:06.542Z" }, + { url = "https://files.pythonhosted.org/packages/c3/30/d0e88c1cfcc1b3331d63c2b54a0a3a4a950ef202fb8b92e772ca714a9221/greenlet-3.2.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:1e76106b6fc55fa3d6fe1c527f95ee65e324a13b62e243f77b48317346559708", size = 1145509, upload-time = "2025-05-09T14:54:02.223Z" }, + { url = "https://files.pythonhosted.org/packages/90/2e/59d6491834b6e289051b252cf4776d16da51c7c6ca6a87ff97e3a50aa0cd/greenlet-3.2.2-cp313-cp313-win_amd64.whl", hash = "sha256:fe46d4f8e94e637634d54477b0cfabcf93c53f29eedcbdeecaf2af32029b4421", size = 296023, upload-time = "2025-05-09T14:53:24.157Z" }, + { url = "https://files.pythonhosted.org/packages/65/66/8a73aace5a5335a1cba56d0da71b7bd93e450f17d372c5b7c5fa547557e9/greenlet-3.2.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba30e88607fb6990544d84caf3c706c4b48f629e18853fc6a646f82db9629418", size = 629911, upload-time = "2025-05-09T15:24:22.376Z" }, + { url = "https://files.pythonhosted.org/packages/48/08/c8b8ebac4e0c95dcc68ec99198842e7db53eda4ab3fb0a4e785690883991/greenlet-3.2.2-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:055916fafad3e3388d27dd68517478933a97edc2fc54ae79d3bec827de2c64c4", size = 635251, upload-time = "2025-05-09T15:24:52.205Z" }, + { url = "https://files.pythonhosted.org/packages/37/26/7db30868f73e86b9125264d2959acabea132b444b88185ba5c462cb8e571/greenlet-3.2.2-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2593283bf81ca37d27d110956b79e8723f9aa50c4bcdc29d3c0543d4743d2763", size = 632620, upload-time = "2025-05-09T15:29:28.051Z" }, + { url = "https://files.pythonhosted.org/packages/10/ec/718a3bd56249e729016b0b69bee4adea0dfccf6ca43d147ef3b21edbca16/greenlet-3.2.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89c69e9a10670eb7a66b8cef6354c24671ba241f46152dd3eed447f79c29fb5b", size = 628851, upload-time = "2025-05-09T14:53:38.472Z" }, + { url = "https://files.pythonhosted.org/packages/9b/9d/d1c79286a76bc62ccdc1387291464af16a4204ea717f24e77b0acd623b99/greenlet-3.2.2-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:02a98600899ca1ca5d3a2590974c9e3ec259503b2d6ba6527605fcd74e08e207", size = 593718, upload-time = "2025-05-09T14:53:48.313Z" }, + { url = "https://files.pythonhosted.org/packages/cd/41/96ba2bf948f67b245784cd294b84e3d17933597dffd3acdb367a210d1949/greenlet-3.2.2-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:b50a8c5c162469c3209e5ec92ee4f95c8231b11db6a04db09bbe338176723bb8", size = 1105752, upload-time = "2025-05-09T15:27:08.217Z" }, + { url = "https://files.pythonhosted.org/packages/68/3b/3b97f9d33c1f2eb081759da62bd6162159db260f602f048bc2f36b4c453e/greenlet-3.2.2-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:45f9f4853fb4cc46783085261c9ec4706628f3b57de3e68bae03e8f8b3c0de51", size = 1125170, upload-time = "2025-05-09T14:54:04.082Z" }, + { url = "https://files.pythonhosted.org/packages/31/df/b7d17d66c8d0f578d2885a3d8f565e9e4725eacc9d3fdc946d0031c055c4/greenlet-3.2.2-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:9ea5231428af34226c05f927e16fc7f6fa5e39e3ad3cd24ffa48ba53a47f4240", size = 269899, upload-time = "2025-05-09T14:54:01.581Z" }, ] [[package]] name = "h11" -version = "0.14.0" +version = "0.16.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f5/38/3af3d3633a34a3316095b39c8e8fb4853a28a536e55d347bd8d8e9a14b03/h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", size = 100418, upload-time = "2022-09-25T15:40:01.519Z" } +sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761", size = 58259, upload-time = "2022-09-25T15:39:59.68Z" }, + { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, ] [[package]] name = "honcho" -version = "1.1.0" +version = "2.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/0e/7c/c0aa47711b5ada100273cbe190b33cc12297065ce559989699fd6c1ec0cb/honcho-1.1.0.tar.gz", hash = "sha256:c5eca0bded4bef6697a23aec0422fd4f6508ea3581979a3485fc4b89357eb2a9", size = 32699, upload-time = "2021-10-30T15:18:04.759Z" } +sdist = { url = "https://files.pythonhosted.org/packages/65/c8/d860888358bf5c8a6e7d78d1b508b59b0e255afd5655f243b8f65166dafd/honcho-2.0.0.tar.gz", hash = "sha256:af3815c03c634bf67d50f114253ea9fef72ecff26e4fd06b29234789ac5b8b2e", size = 45618, upload-time = "2024-10-06T14:26:53.871Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b3/fa/e23333eeb1f5b31a053759eb785389cac9c4cdf1f8867dda8cae9c74535f/honcho-1.1.0-py2.py3-none-any.whl", hash = "sha256:a4d6e3a88a7b51b66351ecfc6e9d79d8f4b87351db9ad7e923f5632cc498122f", size = 21336, upload-time = "2021-10-30T15:18:02.579Z" }, + { url = "https://files.pythonhosted.org/packages/48/1c/25631fc359955569e63f5446dbb7022c320edf9846cbe892ee5113433a7e/honcho-2.0.0-py3-none-any.whl", hash = "sha256:56dcd04fc72d362a4befb9303b1a1a812cba5da283526fbc6509be122918ddf3", size = 22093, upload-time = "2024-10-06T14:26:52.181Z" }, ] [[package]] @@ -154,79 +174,88 @@ wheels = [ [[package]] name = "httpcore" -version = "1.0.5" +version = "1.0.9" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi" }, { name = "h11" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/17/b0/5e8b8674f8d203335a62fdfcfa0d11ebe09e23613c3391033cbba35f7926/httpcore-1.0.5.tar.gz", hash = "sha256:34a38e2f9291467ee3b44e89dd52615370e152954ba21721378a87b2960f7a61", size = 83234, upload-time = "2024-03-27T18:29:07.397Z" } +sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/78/d4/e5d7e4f2174f8a4d63c8897d79eb8fe2503f7ecc03282fee1fa2719c2704/httpcore-1.0.5-py3-none-any.whl", hash = "sha256:421f18bac248b25d310f3cacd198d55b8e6125c107797b609ff9b7a6ba7991b5", size = 77926, upload-time = "2024-03-27T18:29:04.098Z" }, + { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" }, ] [[package]] name = "httpx" -version = "0.27.0" +version = "0.28.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, { name = "certifi" }, { name = "httpcore" }, { name = "idna" }, - { name = "sniffio" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/5c/2d/3da5bdf4408b8b2800061c339f240c1802f2e82d55e50bd39c5a881f47f0/httpx-0.27.0.tar.gz", hash = "sha256:a0cb88a46f32dc874e04ee956e4c2764aba2aa228f650b06788ba6bda2962ab5", size = 126413, upload-time = "2024-02-21T13:07:52.434Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/41/7b/ddacf6dcebb42466abd03f368782142baa82e08fc0c1f8eaa05b4bae87d5/httpx-0.27.0-py3-none-any.whl", hash = "sha256:71d5465162c13681bff01ad59b2cc68dd838ea1f10e51574bac27103f00c91a5", size = 75590, upload-time = "2024-02-21T13:07:50.455Z" }, + { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" }, ] [[package]] name = "idna" -version = "3.7" +version = "3.10" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/21/ed/f86a79a07470cb07819390452f178b3bef1d375f2ec021ecfc709fc7cf07/idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc", size = 189575, upload-time = "2024-04-11T03:34:43.276Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490, upload-time = "2024-09-15T18:07:39.745Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e5/3e/741d8c82801c347547f8a2a06aa57dbb1992be9e948df2ea0eda2c8b79e8/idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0", size = 66836, upload-time = "2024-04-11T03:34:41.447Z" }, + { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload-time = "2024-09-15T18:07:37.964Z" }, ] [[package]] name = "iniconfig" -version = "2.0.0" +version = "2.1.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", size = 4646, upload-time = "2023-01-07T11:08:11.254Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", size = 4793, upload-time = "2025-03-19T20:09:59.721Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892, upload-time = "2023-01-07T11:08:09.864Z" }, + { url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050, upload-time = "2025-03-19T20:10:01.071Z" }, ] [[package]] name = "mako" -version = "1.3.5" +version = "1.3.10" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markupsafe" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/67/03/fb5ba97ff65ce64f6d35b582aacffc26b693a98053fa831ab43a437cbddb/Mako-1.3.5.tar.gz", hash = "sha256:48dbc20568c1d276a2698b36d968fa76161bf127194907ea6fc594fa81f943bc", size = 392738, upload-time = "2024-05-14T12:22:05.966Z" } +sdist = { url = "https://files.pythonhosted.org/packages/9e/38/bd5b78a920a64d708fe6bc8e0a2c075e1389d53bef8413725c63ba041535/mako-1.3.10.tar.gz", hash = "sha256:99579a6f39583fa7e5630a28c3c1f440e4e97a414b80372649c0ce338da2ea28", size = 392474, upload-time = "2025-04-10T12:44:31.16Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/03/62/70f5a0c2dd208f9f3f2f9afd103aec42ee4d9ad2401d78342f75e9b8da36/Mako-1.3.5-py3-none-any.whl", hash = "sha256:260f1dbc3a519453a9c856dedfe4beb4e50bd5a26d96386cb6c80856556bb91a", size = 78565, upload-time = "2024-05-14T12:22:08.522Z" }, + { url = "https://files.pythonhosted.org/packages/87/fb/99f81ac72ae23375f22b7afdb7642aba97c00a713c217124420147681a2f/mako-1.3.10-py3-none-any.whl", hash = "sha256:baef24a52fc4fc514a0887ac600f9f1cff3d82c61d4d700a1fa84d597b88db59", size = 78509, upload-time = "2025-04-10T12:50:53.297Z" }, ] [[package]] name = "markupsafe" -version = "2.1.5" +version = "3.0.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/87/5b/aae44c6655f3801e81aa3eef09dbbf012431987ba564d7231722f68df02d/MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b", size = 19384, upload-time = "2024-02-02T16:31:22.863Z" } +sdist = { url = "https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537, upload-time = "2024-10-18T15:21:54.129Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/53/bd/583bf3e4c8d6a321938c13f49d44024dbe5ed63e0a7ba127e454a66da974/MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1", size = 18215, upload-time = "2024-02-02T16:30:33.081Z" }, - { url = "https://files.pythonhosted.org/packages/48/d6/e7cd795fc710292c3af3a06d80868ce4b02bfbbf370b7cee11d282815a2a/MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4", size = 14069, upload-time = "2024-02-02T16:30:34.148Z" }, - { url = "https://files.pythonhosted.org/packages/51/b5/5d8ec796e2a08fc814a2c7d2584b55f889a55cf17dd1a90f2beb70744e5c/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee", size = 29452, upload-time = "2024-02-02T16:30:35.149Z" }, - { url = "https://files.pythonhosted.org/packages/0a/0d/2454f072fae3b5a137c119abf15465d1771319dfe9e4acbb31722a0fff91/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5", size = 28462, upload-time = "2024-02-02T16:30:36.166Z" }, - { url = "https://files.pythonhosted.org/packages/2d/75/fd6cb2e68780f72d47e6671840ca517bda5ef663d30ada7616b0462ad1e3/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b", size = 27869, upload-time = "2024-02-02T16:30:37.834Z" }, - { url = "https://files.pythonhosted.org/packages/b0/81/147c477391c2750e8fc7705829f7351cf1cd3be64406edcf900dc633feb2/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a", size = 33906, upload-time = "2024-02-02T16:30:39.366Z" }, - { url = "https://files.pythonhosted.org/packages/8b/ff/9a52b71839d7a256b563e85d11050e307121000dcebc97df120176b3ad93/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f", size = 32296, upload-time = "2024-02-02T16:30:40.413Z" }, - { url = "https://files.pythonhosted.org/packages/88/07/2dc76aa51b481eb96a4c3198894f38b480490e834479611a4053fbf08623/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169", size = 33038, upload-time = "2024-02-02T16:30:42.243Z" }, - { url = "https://files.pythonhosted.org/packages/96/0c/620c1fb3661858c0e37eb3cbffd8c6f732a67cd97296f725789679801b31/MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad", size = 16572, upload-time = "2024-02-02T16:30:43.326Z" }, - { url = "https://files.pythonhosted.org/packages/3f/14/c3554d512d5f9100a95e737502f4a2323a1959f6d0d01e0d0997b35f7b10/MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb", size = 17127, upload-time = "2024-02-02T16:30:44.418Z" }, + { url = "https://files.pythonhosted.org/packages/83/0e/67eb10a7ecc77a0c2bbe2b0235765b98d164d81600746914bebada795e97/MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", size = 14274, upload-time = "2024-10-18T15:21:24.577Z" }, + { url = "https://files.pythonhosted.org/packages/2b/6d/9409f3684d3335375d04e5f05744dfe7e9f120062c9857df4ab490a1031a/MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", size = 12352, upload-time = "2024-10-18T15:21:25.382Z" }, + { url = "https://files.pythonhosted.org/packages/d2/f5/6eadfcd3885ea85fe2a7c128315cc1bb7241e1987443d78c8fe712d03091/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", size = 24122, upload-time = "2024-10-18T15:21:26.199Z" }, + { url = "https://files.pythonhosted.org/packages/0c/91/96cf928db8236f1bfab6ce15ad070dfdd02ed88261c2afafd4b43575e9e9/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", size = 23085, upload-time = "2024-10-18T15:21:27.029Z" }, + { url = "https://files.pythonhosted.org/packages/c2/cf/c9d56af24d56ea04daae7ac0940232d31d5a8354f2b457c6d856b2057d69/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", size = 22978, upload-time = "2024-10-18T15:21:27.846Z" }, + { url = "https://files.pythonhosted.org/packages/2a/9f/8619835cd6a711d6272d62abb78c033bda638fdc54c4e7f4272cf1c0962b/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", size = 24208, upload-time = "2024-10-18T15:21:28.744Z" }, + { url = "https://files.pythonhosted.org/packages/f9/bf/176950a1792b2cd2102b8ffeb5133e1ed984547b75db47c25a67d3359f77/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", size = 23357, upload-time = "2024-10-18T15:21:29.545Z" }, + { url = "https://files.pythonhosted.org/packages/ce/4f/9a02c1d335caabe5c4efb90e1b6e8ee944aa245c1aaaab8e8a618987d816/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", size = 23344, upload-time = "2024-10-18T15:21:30.366Z" }, + { url = "https://files.pythonhosted.org/packages/ee/55/c271b57db36f748f0e04a759ace9f8f759ccf22b4960c270c78a394f58be/MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", size = 15101, upload-time = "2024-10-18T15:21:31.207Z" }, + { url = "https://files.pythonhosted.org/packages/29/88/07df22d2dd4df40aba9f3e402e6dc1b8ee86297dddbad4872bd5e7b0094f/MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", size = 15603, upload-time = "2024-10-18T15:21:32.032Z" }, + { url = "https://files.pythonhosted.org/packages/62/6a/8b89d24db2d32d433dffcd6a8779159da109842434f1dd2f6e71f32f738c/MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", size = 14510, upload-time = "2024-10-18T15:21:33.625Z" }, + { url = "https://files.pythonhosted.org/packages/7a/06/a10f955f70a2e5a9bf78d11a161029d278eeacbd35ef806c3fd17b13060d/MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", size = 12486, upload-time = "2024-10-18T15:21:34.611Z" }, + { url = "https://files.pythonhosted.org/packages/34/cf/65d4a571869a1a9078198ca28f39fba5fbb910f952f9dbc5220afff9f5e6/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", size = 25480, upload-time = "2024-10-18T15:21:35.398Z" }, + { url = "https://files.pythonhosted.org/packages/0c/e3/90e9651924c430b885468b56b3d597cabf6d72be4b24a0acd1fa0e12af67/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", size = 23914, upload-time = "2024-10-18T15:21:36.231Z" }, + { url = "https://files.pythonhosted.org/packages/66/8c/6c7cf61f95d63bb866db39085150df1f2a5bd3335298f14a66b48e92659c/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", size = 23796, upload-time = "2024-10-18T15:21:37.073Z" }, + { url = "https://files.pythonhosted.org/packages/bb/35/cbe9238ec3f47ac9a7c8b3df7a808e7cb50fe149dc7039f5f454b3fba218/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", size = 25473, upload-time = "2024-10-18T15:21:37.932Z" }, + { url = "https://files.pythonhosted.org/packages/e6/32/7621a4382488aa283cc05e8984a9c219abad3bca087be9ec77e89939ded9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", size = 24114, upload-time = "2024-10-18T15:21:39.799Z" }, + { url = "https://files.pythonhosted.org/packages/0d/80/0985960e4b89922cb5a0bac0ed39c5b96cbc1a536a99f30e8c220a996ed9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", size = 24098, upload-time = "2024-10-18T15:21:40.813Z" }, + { url = "https://files.pythonhosted.org/packages/82/78/fedb03c7d5380df2427038ec8d973587e90561b2d90cd472ce9254cf348b/MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", size = 15208, upload-time = "2024-10-18T15:21:41.814Z" }, + { url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739, upload-time = "2024-10-18T15:21:42.784Z" }, ] [[package]] @@ -240,37 +269,38 @@ wheels = [ [[package]] name = "packaging" -version = "24.1" +version = "25.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/51/65/50db4dda066951078f0a96cf12f4b9ada6e4b811516bf0262c0f4f7064d4/packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002", size = 148788, upload-time = "2024-06-09T23:19:24.956Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/08/aa/cc0199a5f0ad350994d660967a8efb233fe0416e4639146c089643407ce6/packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124", size = 53985, upload-time = "2024-06-09T23:19:21.909Z" }, + { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, ] [[package]] name = "pluggy" -version = "1.5.0" +version = "1.6.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955, upload-time = "2024-04-20T21:34:42.531Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556, upload-time = "2024-04-20T21:34:40.434Z" }, + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, ] [[package]] name = "pyright" -version = "1.1.372" +version = "1.1.400" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "nodeenv" }, + { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/4a/aa/516d4f7604bd4084c1ea454a1746d84dc5f09cb29184bcbb505cc362e437/pyright-1.1.372.tar.gz", hash = "sha256:a9f5e0daa955daaa17e3d1ef76d3623e75f8afd5e37b437d3ff84d5b38c15420", size = 17477, upload-time = "2024-07-17T08:43:08.319Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6c/cb/c306618a02d0ee8aed5fb8d0fe0ecfed0dbf075f71468f03a30b5f4e1fe0/pyright-1.1.400.tar.gz", hash = "sha256:b8a3ba40481aa47ba08ffb3228e821d22f7d391f83609211335858bf05686bdb", size = 3846546, upload-time = "2025-04-24T12:55:18.907Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f9/28/b5ef3ea1f25d19a3291d1631433f7abcdad572ab7865b4be23da42f2a71b/pyright-1.1.372-py3-none-any.whl", hash = "sha256:25b15fb8967740f0949fd35b963777187f0a0404c0bd753cc966ec139f3eaa0b", size = 18227, upload-time = "2024-07-17T08:43:04.68Z" }, + { url = "https://files.pythonhosted.org/packages/c8/a5/5d285e4932cf149c90e3c425610c5efaea005475d5f96f1bfdb452956c62/pyright-1.1.400-py3-none-any.whl", hash = "sha256:c80d04f98b5a4358ad3a35e241dbf2a408eee33a40779df365644f8054d2517e", size = 5563460, upload-time = "2025-04-24T12:55:17.002Z" }, ] [[package]] name = "pytest" -version = "8.3.1" +version = "8.3.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, @@ -278,68 +308,68 @@ dependencies = [ { name = "packaging" }, { name = "pluggy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/bc/7f/a6f79e033aa8318b6dfe2173fa6409ee75dafccf409d90884bf921433d88/pytest-8.3.1.tar.gz", hash = "sha256:7e8e5c5abd6e93cb1cc151f23e57adc31fcf8cfd2a3ff2da63e23f732de35db6", size = 1438997, upload-time = "2024-07-20T16:25:02.851Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ae/3c/c9d525a414d506893f0cd8a8d0de7706446213181570cdbd766691164e40/pytest-8.3.5.tar.gz", hash = "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845", size = 1450891, upload-time = "2025-03-02T12:54:54.503Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b9/77/ccea391104f576a6e54a54334fc26d29c28aa0ec85714c781fbd2c34ac86/pytest-8.3.1-py3-none-any.whl", hash = "sha256:e9600ccf4f563976e2c99fa02c7624ab938296551f280835ee6516df8bc4ae8c", size = 341628, upload-time = "2024-07-20T16:24:59.674Z" }, + { url = "https://files.pythonhosted.org/packages/30/3d/64ad57c803f1fa1e963a7946b6e0fea4a70df53c1a7fed304586539c2bac/pytest-8.3.5-py3-none-any.whl", hash = "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820", size = 343634, upload-time = "2025-03-02T12:54:52.069Z" }, ] [[package]] name = "pytest-asyncio" -version = "0.23.8" +version = "0.26.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/de/b4/0b378b7bf26a8ae161c3890c0b48a91a04106c5713ce81b4b080ea2f4f18/pytest_asyncio-0.23.8.tar.gz", hash = "sha256:759b10b33a6dc61cce40a8bd5205e302978bbbcc00e279a8b61d9a6a3c82e4d3", size = 46920, upload-time = "2024-07-17T17:39:34.617Z" } +sdist = { url = "https://files.pythonhosted.org/packages/8e/c4/453c52c659521066969523e87d85d54139bbd17b78f09532fb8eb8cdb58e/pytest_asyncio-0.26.0.tar.gz", hash = "sha256:c4df2a697648241ff39e7f0e4a73050b03f123f760673956cf0d72a4990e312f", size = 54156, upload-time = "2025-03-25T06:22:28.883Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ee/82/62e2d63639ecb0fbe8a7ee59ef0bc69a4669ec50f6d3459f74ad4e4189a2/pytest_asyncio-0.23.8-py3-none-any.whl", hash = "sha256:50265d892689a5faefb84df80819d1ecef566eb3549cf915dfb33569359d1ce2", size = 17663, upload-time = "2024-07-17T17:39:32.478Z" }, + { url = "https://files.pythonhosted.org/packages/20/7f/338843f449ace853647ace35870874f69a764d251872ed1b4de9f234822c/pytest_asyncio-0.26.0-py3-none-any.whl", hash = "sha256:7b51ed894f4fbea1340262bdae5135797ebbe21d8638978e35d31c6d19f72fb0", size = 19694, upload-time = "2025-03-25T06:22:27.807Z" }, ] [[package]] name = "pytest-cov" -version = "5.0.0" +version = "6.1.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "coverage" }, { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/74/67/00efc8d11b630c56f15f4ad9c7f9223f1e5ec275aaae3fa9118c6a223ad2/pytest-cov-5.0.0.tar.gz", hash = "sha256:5837b58e9f6ebd335b0f8060eecce69b662415b16dc503883a02f45dfeb14857", size = 63042, upload-time = "2024-03-24T20:16:34.856Z" } +sdist = { url = "https://files.pythonhosted.org/packages/25/69/5f1e57f6c5a39f81411b550027bf72842c4567ff5fd572bed1edc9e4b5d9/pytest_cov-6.1.1.tar.gz", hash = "sha256:46935f7aaefba760e716c2ebfbe1c216240b9592966e7da99ea8292d4d3e2a0a", size = 66857, upload-time = "2025-04-05T14:07:51.592Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/78/3a/af5b4fa5961d9a1e6237b530eb87dd04aea6eb83da09d2a4073d81b54ccf/pytest_cov-5.0.0-py3-none-any.whl", hash = "sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652", size = 21990, upload-time = "2024-03-24T20:16:32.444Z" }, + { url = "https://files.pythonhosted.org/packages/28/d0/def53b4a790cfb21483016430ed828f64830dd981ebe1089971cd10cab25/pytest_cov-6.1.1-py3-none-any.whl", hash = "sha256:bddf29ed2d0ab6f4df17b4c55b0a657287db8684af9c42ea546b21b1041b3dde", size = 23841, upload-time = "2025-04-05T14:07:49.641Z" }, ] [[package]] name = "ruff" -version = "0.5.4" +version = "0.11.10" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8e/1a/5955fa22ab088c1f4d8458b4cbc158c6db72143361e8d46e179c48576aab/ruff-0.5.4.tar.gz", hash = "sha256:2795726d5f71c4f4e70653273d1c23a8182f07dd8e48c12de5d867bfb7557eed", size = 2424702, upload-time = "2024-07-20T18:02:31.49Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e8/4c/4a3c5a97faaae6b428b336dcca81d03ad04779f8072c267ad2bd860126bf/ruff-0.11.10.tar.gz", hash = "sha256:d522fb204b4959909ecac47da02830daec102eeb100fb50ea9554818d47a5fa6", size = 4165632, upload-time = "2025-05-15T14:08:56.76Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5b/34/2235ecce6794345f42ad334d1b14384c70b202f77509e5678b68a640fe78/ruff-0.5.4-py3-none-linux_armv6l.whl", hash = "sha256:82acef724fc639699b4d3177ed5cc14c2a5aacd92edd578a9e846d5b5ec18ddf", size = 9499774, upload-time = "2024-07-20T18:01:29.707Z" }, - { url = "https://files.pythonhosted.org/packages/11/23/ffe51028ba274223191d3f96b059108cf7690eb93985a7fdb077c3d1191b/ruff-0.5.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:da62e87637c8838b325e65beee485f71eb36202ce8e3cdbc24b9fcb8b99a37be", size = 8550240, upload-time = "2024-07-20T18:01:35.372Z" }, - { url = "https://files.pythonhosted.org/packages/28/75/843aa3d10a39ab60fbd63f65c825f647907a9732ac27e24d3f94dd2db618/ruff-0.5.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e98ad088edfe2f3b85a925ee96da652028f093d6b9b56b76fc242d8abb8e2059", size = 8160520, upload-time = "2024-07-20T18:01:39.019Z" }, - { url = "https://files.pythonhosted.org/packages/19/88/3d0f5244905088cc2fd136fae8ce81f46d145e2449051313c462032d144d/ruff-0.5.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c55efbecc3152d614cfe6c2247a3054cfe358cefbf794f8c79c8575456efe19", size = 9911606, upload-time = "2024-07-20T18:01:42.765Z" }, - { url = "https://files.pythonhosted.org/packages/1f/ff/6546020836408351e7558dedacc6e5ca7f652f76a9d05ac4882c787d45b1/ruff-0.5.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f9b85eaa1f653abd0a70603b8b7008d9e00c9fa1bbd0bf40dad3f0c0bdd06793", size = 9286353, upload-time = "2024-07-20T18:01:45.872Z" }, - { url = "https://files.pythonhosted.org/packages/b6/bf/51e0c5f12a9bf3c7596cf7f45e1b102f8b49f1da39943e03739890bbf6a4/ruff-0.5.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0cf497a47751be8c883059c4613ba2f50dd06ec672692de2811f039432875278", size = 10082929, upload-time = "2024-07-20T18:01:48.942Z" }, - { url = "https://files.pythonhosted.org/packages/b5/0e/a44cb6edb629788de892fc7bb8ac8b47059df94d7ec9c4e52e04bab5be95/ruff-0.5.4-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:09c14ed6a72af9ccc8d2e313d7acf7037f0faff43cde4b507e66f14e812e37f7", size = 10832586, upload-time = "2024-07-20T18:01:52.58Z" }, - { url = "https://files.pythonhosted.org/packages/97/ca/e3810f701ae472e5fe3180d56fe6fcc92ea94c7490097a0f731f5602f26f/ruff-0.5.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:628f6b8f97b8bad2490240aa84f3e68f390e13fabc9af5c0d3b96b485921cd60", size = 10421967, upload-time = "2024-07-20T18:01:56.478Z" }, - { url = "https://files.pythonhosted.org/packages/01/47/a62df6ccd6e5d019271df203ea6564f2022c49f85c0bf6ada708cd7b4a5e/ruff-0.5.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3520a00c0563d7a7a7c324ad7e2cde2355733dafa9592c671fb2e9e3cd8194c1", size = 11371031, upload-time = "2024-07-20T18:01:59.956Z" }, - { url = "https://files.pythonhosted.org/packages/a1/02/64f24893eea23c447460e6509e9dd0ae18d7a797f67fee1bafed964ebbae/ruff-0.5.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93789f14ca2244fb91ed481456f6d0bb8af1f75a330e133b67d08f06ad85b516", size = 10103164, upload-time = "2024-07-20T18:02:03.834Z" }, - { url = "https://files.pythonhosted.org/packages/ca/78/683b6c6976fcc33e4a03a0e234e0b9f9b8682f807a661225c829b248de82/ruff-0.5.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:029454e2824eafa25b9df46882f7f7844d36fd8ce51c1b7f6d97e2615a57bbcc", size = 9920056, upload-time = "2024-07-20T18:02:07.05Z" }, - { url = "https://files.pythonhosted.org/packages/78/3a/6c67c5d670aae2a51a11713aff819d729ed92cb0b1d962b8df27e4657650/ruff-0.5.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:9492320eed573a13a0bc09a2957f17aa733fff9ce5bf00e66e6d4a88ec33813f", size = 9361286, upload-time = "2024-07-20T18:02:10.841Z" }, - { url = "https://files.pythonhosted.org/packages/0d/f5/da3a0e2fd0bcbdb3d2ff579ef9cb3ca2af71b9bee97fa917c9a9e0500b67/ruff-0.5.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a6e1f62a92c645e2919b65c02e79d1f61e78a58eddaebca6c23659e7c7cb4ac7", size = 9720829, upload-time = "2024-07-20T18:02:14.602Z" }, - { url = "https://files.pythonhosted.org/packages/4a/56/5062119a5c9e06d98cd6406bfc1eab7616a7c67494a4d05b6052d99dd147/ruff-0.5.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:768fa9208df2bec4b2ce61dbc7c2ddd6b1be9fb48f1f8d3b78b3332c7d71c1ff", size = 10143530, upload-time = "2024-07-20T18:02:18.547Z" }, - { url = "https://files.pythonhosted.org/packages/e6/76/16f8f1c8d0cba6c96ab6f292146fc0acb6dd633a989f524d3b3ef1ee8364/ruff-0.5.4-py3-none-win32.whl", hash = "sha256:e1e7393e9c56128e870b233c82ceb42164966f25b30f68acbb24ed69ce9c3a4e", size = 7794271, upload-time = "2024-07-20T18:02:21.606Z" }, - { url = "https://files.pythonhosted.org/packages/82/35/d6c3c83fb8817328db73c15b1836ccb0c3ce56b72d0d01d98b3a452bec58/ruff-0.5.4-py3-none-win_amd64.whl", hash = "sha256:58b54459221fd3f661a7329f177f091eb35cf7a603f01d9eb3eb11cc348d38c4", size = 8579021, upload-time = "2024-07-20T18:02:24.966Z" }, - { url = "https://files.pythonhosted.org/packages/3c/ef/3e732c0152280775f728ab99691c718ee9a4ae79bf5af1dd9258f7fe7fef/ruff-0.5.4-py3-none-win_arm64.whl", hash = "sha256:bd53da65f1085fb5b307c38fd3c0829e76acf7b2a912d8d79cadcdb4875c1eb7", size = 8034239, upload-time = "2024-07-20T18:02:28.226Z" }, + { url = "https://files.pythonhosted.org/packages/2f/9f/596c628f8824a2ce4cd12b0f0b4c0629a62dfffc5d0f742c19a1d71be108/ruff-0.11.10-py3-none-linux_armv6l.whl", hash = "sha256:859a7bfa7bc8888abbea31ef8a2b411714e6a80f0d173c2a82f9041ed6b50f58", size = 10316243, upload-time = "2025-05-15T14:08:12.884Z" }, + { url = "https://files.pythonhosted.org/packages/3c/38/c1e0b77ab58b426f8c332c1d1d3432d9fc9a9ea622806e208220cb133c9e/ruff-0.11.10-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:968220a57e09ea5e4fd48ed1c646419961a0570727c7e069842edd018ee8afed", size = 11083636, upload-time = "2025-05-15T14:08:16.551Z" }, + { url = "https://files.pythonhosted.org/packages/23/41/b75e15961d6047d7fe1b13886e56e8413be8467a4e1be0a07f3b303cd65a/ruff-0.11.10-py3-none-macosx_11_0_arm64.whl", hash = "sha256:1067245bad978e7aa7b22f67113ecc6eb241dca0d9b696144256c3a879663bca", size = 10441624, upload-time = "2025-05-15T14:08:19.032Z" }, + { url = "https://files.pythonhosted.org/packages/b6/2c/e396b6703f131406db1811ea3d746f29d91b41bbd43ad572fea30da1435d/ruff-0.11.10-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4854fd09c7aed5b1590e996a81aeff0c9ff51378b084eb5a0b9cd9518e6cff2", size = 10624358, upload-time = "2025-05-15T14:08:21.542Z" }, + { url = "https://files.pythonhosted.org/packages/bd/8c/ee6cca8bdaf0f9a3704796022851a33cd37d1340bceaf4f6e991eb164e2e/ruff-0.11.10-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8b4564e9f99168c0f9195a0fd5fa5928004b33b377137f978055e40008a082c5", size = 10176850, upload-time = "2025-05-15T14:08:23.682Z" }, + { url = "https://files.pythonhosted.org/packages/e9/ce/4e27e131a434321b3b7c66512c3ee7505b446eb1c8a80777c023f7e876e6/ruff-0.11.10-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b6a9cc5b62c03cc1fea0044ed8576379dbaf751d5503d718c973d5418483641", size = 11759787, upload-time = "2025-05-15T14:08:25.733Z" }, + { url = "https://files.pythonhosted.org/packages/58/de/1e2e77fc72adc7cf5b5123fd04a59ed329651d3eab9825674a9e640b100b/ruff-0.11.10-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:607ecbb6f03e44c9e0a93aedacb17b4eb4f3563d00e8b474298a201622677947", size = 12430479, upload-time = "2025-05-15T14:08:28.013Z" }, + { url = "https://files.pythonhosted.org/packages/07/ed/af0f2340f33b70d50121628ef175523cc4c37619e98d98748c85764c8d88/ruff-0.11.10-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7b3a522fa389402cd2137df9ddefe848f727250535c70dafa840badffb56b7a4", size = 11919760, upload-time = "2025-05-15T14:08:30.956Z" }, + { url = "https://files.pythonhosted.org/packages/24/09/d7b3d3226d535cb89234390f418d10e00a157b6c4a06dfbe723e9322cb7d/ruff-0.11.10-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2f071b0deed7e9245d5820dac235cbdd4ef99d7b12ff04c330a241ad3534319f", size = 14041747, upload-time = "2025-05-15T14:08:33.297Z" }, + { url = "https://files.pythonhosted.org/packages/62/b3/a63b4e91850e3f47f78795e6630ee9266cb6963de8f0191600289c2bb8f4/ruff-0.11.10-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a60e3a0a617eafba1f2e4186d827759d65348fa53708ca547e384db28406a0b", size = 11550657, upload-time = "2025-05-15T14:08:35.639Z" }, + { url = "https://files.pythonhosted.org/packages/46/63/a4f95c241d79402ccdbdb1d823d156c89fbb36ebfc4289dce092e6c0aa8f/ruff-0.11.10-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:da8ec977eaa4b7bf75470fb575bea2cb41a0e07c7ea9d5a0a97d13dbca697bf2", size = 10489671, upload-time = "2025-05-15T14:08:38.437Z" }, + { url = "https://files.pythonhosted.org/packages/6a/9b/c2238bfebf1e473495659c523d50b1685258b6345d5ab0b418ca3f010cd7/ruff-0.11.10-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:ddf8967e08227d1bd95cc0851ef80d2ad9c7c0c5aab1eba31db49cf0a7b99523", size = 10160135, upload-time = "2025-05-15T14:08:41.247Z" }, + { url = "https://files.pythonhosted.org/packages/ba/ef/ba7251dd15206688dbfba7d413c0312e94df3b31b08f5d695580b755a899/ruff-0.11.10-py3-none-musllinux_1_2_i686.whl", hash = "sha256:5a94acf798a82db188f6f36575d80609072b032105d114b0f98661e1679c9125", size = 11170179, upload-time = "2025-05-15T14:08:43.762Z" }, + { url = "https://files.pythonhosted.org/packages/73/9f/5c336717293203ba275dbfa2ea16e49b29a9fd9a0ea8b6febfc17e133577/ruff-0.11.10-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:3afead355f1d16d95630df28d4ba17fb2cb9c8dfac8d21ced14984121f639bad", size = 11626021, upload-time = "2025-05-15T14:08:46.451Z" }, + { url = "https://files.pythonhosted.org/packages/d9/2b/162fa86d2639076667c9aa59196c020dc6d7023ac8f342416c2f5ec4bda0/ruff-0.11.10-py3-none-win32.whl", hash = "sha256:dc061a98d32a97211af7e7f3fa1d4ca2fcf919fb96c28f39551f35fc55bdbc19", size = 10494958, upload-time = "2025-05-15T14:08:49.601Z" }, + { url = "https://files.pythonhosted.org/packages/24/f3/66643d8f32f50a4b0d09a4832b7d919145ee2b944d43e604fbd7c144d175/ruff-0.11.10-py3-none-win_amd64.whl", hash = "sha256:5cc725fbb4d25b0f185cb42df07ab6b76c4489b4bfb740a175f3a59c70e8a224", size = 11650285, upload-time = "2025-05-15T14:08:52.392Z" }, + { url = "https://files.pythonhosted.org/packages/95/3a/2e8704d19f376c799748ff9cb041225c1d59f3e7711bc5596c8cfdc24925/ruff-0.11.10-py3-none-win_arm64.whl", hash = "sha256:ef69637b35fb8b210743926778d0e45e1bffa850a7c61e428c6b971549b5f5d1", size = 10765278, upload-time = "2025-05-15T14:08:54.56Z" }, ] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/71/39/171f1c67cd00715f190ba0b100d606d440a28c93c7714febeca8b79af85e/six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", size = 34041, upload-time = "2021-05-05T14:18:18.379Z" } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d9/5a/e7c31adbe875f2abbb91bd84cf2dc52d792b5a01506781dbcf25c91daf11/six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254", size = 11053, upload-time = "2021-05-05T14:18:17.237Z" }, + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, ] [[package]] @@ -353,32 +383,32 @@ wheels = [ [[package]] name = "soupsieve" -version = "2.5" +version = "2.7" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ce/21/952a240de1c196c7e3fbcd4e559681f0419b1280c617db21157a0390717b/soupsieve-2.5.tar.gz", hash = "sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690", size = 100943, upload-time = "2023-09-02T12:48:22.131Z" } +sdist = { url = "https://files.pythonhosted.org/packages/3f/f4/4a80cd6ef364b2e8b65b15816a843c0980f7a5a2b4dc701fc574952aa19f/soupsieve-2.7.tar.gz", hash = "sha256:ad282f9b6926286d2ead4750552c8a6142bc4c783fd66b0293547c8fe6ae126a", size = 103418, upload-time = "2025-04-20T18:50:08.518Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/4c/f3/038b302fdfbe3be7da016777069f26ceefe11a681055ea1f7817546508e3/soupsieve-2.5-py3-none-any.whl", hash = "sha256:eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7", size = 36131, upload-time = "2023-09-02T12:48:20.552Z" }, + { url = "https://files.pythonhosted.org/packages/e7/9c/0e6afc12c269578be5c0c1c9f4b49a8d32770a080260c333ac04cc1c832d/soupsieve-2.7-py3-none-any.whl", hash = "sha256:6e60cc5c1ffaf1cebcc12e8188320b72071e922c2e897f737cadce79ad5d30c4", size = 36677, upload-time = "2025-04-20T18:50:07.196Z" }, ] [[package]] name = "sqlalchemy" -version = "2.0.31" +version = "2.0.41" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "greenlet", marker = "(python_full_version < '3.13' and platform_machine == 'AMD64') or (python_full_version < '3.13' and platform_machine == 'WIN32') or (python_full_version < '3.13' and platform_machine == 'aarch64') or (python_full_version < '3.13' and platform_machine == 'amd64') or (python_full_version < '3.13' and platform_machine == 'ppc64le') or (python_full_version < '3.13' and platform_machine == 'win32') or (python_full_version < '3.13' and platform_machine == 'x86_64')" }, + { name = "greenlet", marker = "(python_full_version < '3.14' and platform_machine == 'AMD64') or (python_full_version < '3.14' and platform_machine == 'WIN32') or (python_full_version < '3.14' and platform_machine == 'aarch64') or (python_full_version < '3.14' and platform_machine == 'amd64') or (python_full_version < '3.14' and platform_machine == 'ppc64le') or (python_full_version < '3.14' and platform_machine == 'win32') or (python_full_version < '3.14' and platform_machine == 'x86_64')" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ba/7d/e3312ae374fe7a4af7e1494735125a714a0907317c829ab8d8a31d89ded4/SQLAlchemy-2.0.31.tar.gz", hash = "sha256:b607489dd4a54de56984a0c7656247504bd5523d9d0ba799aef59d4add009484", size = 9524110, upload-time = "2024-06-18T21:38:37.304Z" } +sdist = { url = "https://files.pythonhosted.org/packages/63/66/45b165c595ec89aa7dcc2c1cd222ab269bc753f1fc7a1e68f8481bd957bf/sqlalchemy-2.0.41.tar.gz", hash = "sha256:edba70118c4be3c2b1f90754d308d0b79c6fe2c0fdc52d8ddf603916f83f4db9", size = 9689424, upload-time = "2025-05-14T17:10:32.339Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/fc/26/1a44b4c9286bccdc2ac344da6487227595512aa60d45c6617b1b6cd859b6/SQLAlchemy-2.0.31-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3b74570d99126992d4b0f91fb87c586a574a5872651185de8297c6f90055ae42", size = 2083132, upload-time = "2024-06-18T22:07:44.845Z" }, - { url = "https://files.pythonhosted.org/packages/27/97/21efc51a670e2772156890e241120aac7dae6c92d1bf56e811fb3bec3373/SQLAlchemy-2.0.31-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f77c4f042ad493cb8595e2f503c7a4fe44cd7bd59c7582fd6d78d7e7b8ec52c", size = 2073619, upload-time = "2024-06-18T22:07:54.357Z" }, - { url = "https://files.pythonhosted.org/packages/ef/87/778b09abc441b6db4014efb9ef87be0c6959cbd46ee3280faad297f30c12/SQLAlchemy-2.0.31-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cd1591329333daf94467e699e11015d9c944f44c94d2091f4ac493ced0119449", size = 3222863, upload-time = "2024-06-18T23:44:28.479Z" }, - { url = "https://files.pythonhosted.org/packages/60/f8/7794f3055d50e96cee04c19c7faeedacb323c7762f334660ba03bed95485/SQLAlchemy-2.0.31-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:74afabeeff415e35525bf7a4ecdab015f00e06456166a2eba7590e49f8db940e", size = 3233968, upload-time = "2024-06-18T22:18:54.371Z" }, - { url = "https://files.pythonhosted.org/packages/e5/ed/aa6ad258a9478874c4b921e8e78d04d237667fc48550a94df79e827ae91f/SQLAlchemy-2.0.31-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b9c01990d9015df2c6f818aa8f4297d42ee71c9502026bb074e713d496e26b67", size = 3170897, upload-time = "2024-06-18T23:44:36.786Z" }, - { url = "https://files.pythonhosted.org/packages/7f/da/d8f8515caf3ef357ad02bb4fd38474fb72c21ee788e2995d9395bcf5185e/SQLAlchemy-2.0.31-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:66f63278db425838b3c2b1c596654b31939427016ba030e951b292e32b99553e", size = 3197274, upload-time = "2024-06-18T22:19:01.43Z" }, - { url = "https://files.pythonhosted.org/packages/99/b3/02a2aeb619f5e366b29d9f5eeeaadbe2bd383eab22ce10a00ced870c63f0/SQLAlchemy-2.0.31-cp312-cp312-win32.whl", hash = "sha256:0b0f658414ee4e4b8cbcd4a9bb0fd743c5eeb81fc858ca517217a8013d282c96", size = 2053430, upload-time = "2024-06-18T22:02:25.431Z" }, - { url = "https://files.pythonhosted.org/packages/d0/ff/5746886a796799d45285573c8a6564b4b84c730142ab974d7a3f7bacee6c/SQLAlchemy-2.0.31-cp312-cp312-win_amd64.whl", hash = "sha256:fa4b1af3e619b5b0b435e333f3967612db06351217c58bfb50cee5f003db2a5a", size = 2079376, upload-time = "2024-06-18T22:02:32.276Z" }, - { url = "https://files.pythonhosted.org/packages/f3/89/ff21b6c7ccdb254fba5444d15afe193d9a71f4fa054b4823d4384d10718e/SQLAlchemy-2.0.31-py3-none-any.whl", hash = "sha256:69f3e3c08867a8e4856e92d7afb618b95cdee18e0bc1647b77599722c9a28911", size = 1874629, upload-time = "2024-06-18T22:19:04.764Z" }, + { url = "https://files.pythonhosted.org/packages/d3/ad/2e1c6d4f235a97eeef52d0200d8ddda16f6c4dd70ae5ad88c46963440480/sqlalchemy-2.0.41-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4eeb195cdedaf17aab6b247894ff2734dcead6c08f748e617bfe05bd5a218443", size = 2115491, upload-time = "2025-05-14T17:55:31.177Z" }, + { url = "https://files.pythonhosted.org/packages/cf/8d/be490e5db8400dacc89056f78a52d44b04fbf75e8439569d5b879623a53b/sqlalchemy-2.0.41-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d4ae769b9c1c7757e4ccce94b0641bc203bbdf43ba7a2413ab2523d8d047d8dc", size = 2102827, upload-time = "2025-05-14T17:55:34.921Z" }, + { url = "https://files.pythonhosted.org/packages/a0/72/c97ad430f0b0e78efaf2791342e13ffeafcbb3c06242f01a3bb8fe44f65d/sqlalchemy-2.0.41-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a62448526dd9ed3e3beedc93df9bb6b55a436ed1474db31a2af13b313a70a7e1", size = 3225224, upload-time = "2025-05-14T17:50:41.418Z" }, + { url = "https://files.pythonhosted.org/packages/5e/51/5ba9ea3246ea068630acf35a6ba0d181e99f1af1afd17e159eac7e8bc2b8/sqlalchemy-2.0.41-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc56c9788617b8964ad02e8fcfeed4001c1f8ba91a9e1f31483c0dffb207002a", size = 3230045, upload-time = "2025-05-14T17:51:54.722Z" }, + { url = "https://files.pythonhosted.org/packages/78/2f/8c14443b2acea700c62f9b4a8bad9e49fc1b65cfb260edead71fd38e9f19/sqlalchemy-2.0.41-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c153265408d18de4cc5ded1941dcd8315894572cddd3c58df5d5b5705b3fa28d", size = 3159357, upload-time = "2025-05-14T17:50:43.483Z" }, + { url = "https://files.pythonhosted.org/packages/fc/b2/43eacbf6ccc5276d76cea18cb7c3d73e294d6fb21f9ff8b4eef9b42bbfd5/sqlalchemy-2.0.41-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f67766965996e63bb46cfbf2ce5355fc32d9dd3b8ad7e536a920ff9ee422e23", size = 3197511, upload-time = "2025-05-14T17:51:57.308Z" }, + { url = "https://files.pythonhosted.org/packages/fa/2e/677c17c5d6a004c3c45334ab1dbe7b7deb834430b282b8a0f75ae220c8eb/sqlalchemy-2.0.41-cp313-cp313-win32.whl", hash = "sha256:bfc9064f6658a3d1cadeaa0ba07570b83ce6801a1314985bf98ec9b95d74e15f", size = 2082420, upload-time = "2025-05-14T17:55:52.69Z" }, + { url = "https://files.pythonhosted.org/packages/e9/61/e8c1b9b6307c57157d328dd8b8348ddc4c47ffdf1279365a13b2b98b8049/sqlalchemy-2.0.41-cp313-cp313-win_amd64.whl", hash = "sha256:82ca366a844eb551daff9d2e6e7a9e5e76d2612c8564f58db6c19a726869c1df", size = 2108329, upload-time = "2025-05-14T17:55:54.495Z" }, + { url = "https://files.pythonhosted.org/packages/1c/fc/9ba22f01b5cdacc8f5ed0d22304718d2c758fce3fd49a5372b886a86f37c/sqlalchemy-2.0.41-py3-none-any.whl", hash = "sha256:57df5dc6fdb5ed1a88a1ed2195fd31927e705cad62dedd86b46972752a80f576", size = 1911224, upload-time = "2025-05-14T17:39:42.154Z" }, ] [package.optional-dependencies] @@ -390,23 +420,23 @@ aiosqlite = [ [[package]] name = "starlette" -version = "0.38.0" +version = "0.46.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/13/1c/a0005d1b8e775823b4aa2c4b4ce1b540833c6364ed5de55b6a8754bdc17c/starlette-0.38.0.tar.gz", hash = "sha256:1ac2291e946a56bb5ca929dbb2332fc0dfd1e609c7e4d4f2056925cc0442874e", size = 2844584, upload-time = "2024-07-20T09:18:25.38Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ce/20/08dfcd9c983f6a6f4a1000d934b9e6d626cff8d2eeb77a89a68eef20a2b7/starlette-0.46.2.tar.gz", hash = "sha256:7f7361f34eed179294600af672f565727419830b54b7b084efe44bb82d2fccd5", size = 2580846, upload-time = "2025-04-13T13:56:17.942Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/93/98/a7598e7b2c7c6342b6e61c8a7a85c5d83fb8191a291695c95ce43402f4b7/starlette-0.38.0-py3-none-any.whl", hash = "sha256:dd58f5854ca4fc476710e48d61b29fa4ff3639d42604a786f9d2091e64b95c7e", size = 72053, upload-time = "2024-07-20T09:18:22.348Z" }, + { url = "https://files.pythonhosted.org/packages/8b/0c/9d30a4ebeb6db2b25a841afbb80f6ef9a854fc3b41be131d249a977b4959/starlette-0.46.2-py3-none-any.whl", hash = "sha256:595633ce89f8ffa71a015caed34a5b2dc1c0cdb3f0f1fbd1e69339cf2abeec35", size = 72037, upload-time = "2025-04-13T13:56:16.21Z" }, ] [[package]] name = "typing-extensions" -version = "4.12.2" +version = "4.13.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321, upload-time = "2024-06-07T18:52:15.995Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/37/23083fcd6e35492953e8d2aaaa68b860eb422b34627b13f2ce3eb6106061/typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef", size = 106967, upload-time = "2025-04-10T14:19:05.416Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438, upload-time = "2024-06-07T18:52:13.582Z" }, + { url = "https://files.pythonhosted.org/packages/8b/54/b1ae86c0973cc6f0210b53d508ca3641fb6d0c56823f288d108bc7ab3cc8/typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c", size = 45806, upload-time = "2025-04-10T14:19:03.967Z" }, ] [[package]] @@ -448,11 +478,11 @@ requires-dist = [ { name = "alembic", specifier = ">=1.13.1,<2" }, { name = "beautifulsoup4", specifier = ">=4.9.3,<5" }, { name = "html5lib", specifier = "~=1.1" }, - { name = "httpx", specifier = ">=0.27.0,<0.28" }, + { name = "httpx", specifier = ">=0.28.1" }, { name = "sqlalchemy", extras = ["aiosqlite"], specifier = "~=2.0" }, - { name = "starlette", specifier = ">=0.38.0,<0.39" }, + { name = "starlette", specifier = ">=0.46.2" }, { name = "ulid-py", specifier = ">=1.1.0,<2" }, - { name = "uvicorn", specifier = ">=0.30.1,<0.31" }, + { name = "uvicorn", specifier = ">=0.34.2" }, ] [package.metadata.requires-dev] @@ -467,15 +497,15 @@ dev = [ [[package]] name = "uvicorn" -version = "0.30.3" +version = "0.34.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, { name = "h11" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/77/40/b650be95700dc83d14c5f2b9eac9deb23cbca757a12ee20e473b5ef1ac48/uvicorn-0.30.3.tar.gz", hash = "sha256:0d114d0831ff1adbf231d358cbf42f17333413042552a624ea6a9b4c33dcfd81", size = 42762, upload-time = "2024-07-20T08:59:54.277Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/ae/9bbb19b9e1c450cf9ecaef06463e40234d98d95bf572fab11b4f19ae5ded/uvicorn-0.34.2.tar.gz", hash = "sha256:0e929828f6186353a80b58ea719861d2629d766293b6d19baf086ba31d4f3328", size = 76815, upload-time = "2025-04-19T06:02:50.101Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/63/84/2a26b4eac1cf0c6b5b176dd4346cc4912af5e1b0efc150b865e28636ac34/uvicorn-0.30.3-py3-none-any.whl", hash = "sha256:94a3608da0e530cea8f69683aa4126364ac18e3826b6630d1a65f4638aade503", size = 62760, upload-time = "2024-07-20T08:59:51.926Z" }, + { url = "https://files.pythonhosted.org/packages/b1/4b/4cef6ce21a2aaca9d852a6e84ef4f135d99fcd74fa75105e2fc0c8308acd/uvicorn-0.34.2-py3-none-any.whl", hash = "sha256:deb49af569084536d269fe0a6d67e3754f104cf03aba7c11c40f01aadf33c403", size = 62483, upload-time = "2025-04-19T06:02:48.42Z" }, ] [[package]]