mirror of
https://gitlab.archlinux.org/archlinux/aurweb.git
synced 2025-02-03 10:43:03 +01:00
Merge branch 'sqlalchemy2' into 'master'
Draft: Upgrade to sqlalchemy 2 & fix db sessions See merge request archlinux/aurweb!756
This commit is contained in:
commit
8db5dc3328
19 changed files with 273 additions and 176 deletions
|
@ -25,7 +25,7 @@ import aurweb.pkgbase.util as pkgbaseutil
|
||||||
from aurweb import aur_logging, prometheus, util
|
from aurweb import aur_logging, prometheus, util
|
||||||
from aurweb.aur_redis import redis_connection
|
from aurweb.aur_redis import redis_connection
|
||||||
from aurweb.auth import BasicAuthBackend
|
from aurweb.auth import BasicAuthBackend
|
||||||
from aurweb.db import get_engine, query
|
from aurweb.db import get_engine, query, set_db_session_context
|
||||||
from aurweb.models import AcceptedTerm, Term
|
from aurweb.models import AcceptedTerm, Term
|
||||||
from aurweb.packages.util import get_pkg_or_base
|
from aurweb.packages.util import get_pkg_or_base
|
||||||
from aurweb.prometheus import instrumentator
|
from aurweb.prometheus import instrumentator
|
||||||
|
@ -308,3 +308,20 @@ async def id_redirect_middleware(request: Request, call_next: typing.Callable):
|
||||||
# Add application middlewares.
|
# Add application middlewares.
|
||||||
app.add_middleware(AuthenticationMiddleware, backend=BasicAuthBackend())
|
app.add_middleware(AuthenticationMiddleware, backend=BasicAuthBackend())
|
||||||
app.add_middleware(SessionMiddleware, secret_key=session_secret)
|
app.add_middleware(SessionMiddleware, secret_key=session_secret)
|
||||||
|
|
||||||
|
|
||||||
|
# Set context var for database session & remove it after our request
|
||||||
|
@app.middleware("http")
|
||||||
|
async def db_session_context(request: Request, call_next: typing.Callable):
|
||||||
|
# static content won't require a db session
|
||||||
|
if request.url.path.startswith("/static"):
|
||||||
|
return await util.error_or_result(call_next, request)
|
||||||
|
|
||||||
|
try:
|
||||||
|
set_db_session_context(hash(request))
|
||||||
|
response = await util.error_or_result(call_next, request)
|
||||||
|
|
||||||
|
finally:
|
||||||
|
set_db_session_context(None)
|
||||||
|
|
||||||
|
return response
|
||||||
|
|
61
aurweb/db.py
61
aurweb/db.py
|
@ -1,7 +1,39 @@
|
||||||
|
from contextvars import ContextVar
|
||||||
|
from threading import get_ident
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
# Supported database drivers.
|
# Supported database drivers.
|
||||||
DRIVERS = {"mysql": "mysql+mysqldb"}
|
DRIVERS = {"mysql": "mysql+mysqldb"}
|
||||||
|
|
||||||
|
|
||||||
|
class Committer:
|
||||||
|
def __init__(self, session):
|
||||||
|
self.session = session
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def __exit__(self, *args):
|
||||||
|
self.session.commit()
|
||||||
|
|
||||||
|
|
||||||
|
db_session_context: ContextVar[Optional[int]] = ContextVar(
|
||||||
|
"session_id", default=get_ident()
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def get_db_session_context():
|
||||||
|
id = db_session_context.get()
|
||||||
|
return id
|
||||||
|
|
||||||
|
|
||||||
|
def set_db_session_context(session_id: int):
|
||||||
|
if session_id is None:
|
||||||
|
get_session().remove()
|
||||||
|
|
||||||
|
db_session_context.set(session_id)
|
||||||
|
|
||||||
|
|
||||||
def make_random_value(table: str, column: str, length: int):
|
def make_random_value(table: str, column: str, length: int):
|
||||||
"""Generate a unique, random value for a string column in a table.
|
"""Generate a unique, random value for a string column in a table.
|
||||||
|
|
||||||
|
@ -61,38 +93,39 @@ def name() -> str:
|
||||||
return "db" + sha1
|
return "db" + sha1
|
||||||
|
|
||||||
|
|
||||||
# Module-private global memo used to store SQLAlchemy sessions.
|
# Module-private global memo used to store SQLAlchemy sessions registries.
|
||||||
_sessions = dict()
|
_session_registries = dict()
|
||||||
|
|
||||||
|
|
||||||
def get_session(engine=None):
|
def get_session(engine=None):
|
||||||
"""Return aurweb.db's global session."""
|
"""Return aurweb.db's global session."""
|
||||||
dbname = name()
|
dbname = name()
|
||||||
|
|
||||||
global _sessions
|
global _session_registries
|
||||||
if dbname not in _sessions:
|
if dbname not in _session_registries:
|
||||||
from sqlalchemy.orm import scoped_session, sessionmaker
|
from sqlalchemy.orm import scoped_session, sessionmaker
|
||||||
|
|
||||||
if not engine: # pragma: no cover
|
if not engine: # pragma: no cover
|
||||||
engine = get_engine()
|
engine = get_engine()
|
||||||
|
|
||||||
Session = scoped_session(
|
Session = scoped_session(
|
||||||
sessionmaker(autocommit=True, autoflush=False, bind=engine)
|
sessionmaker(autoflush=False, bind=engine),
|
||||||
|
scopefunc=get_db_session_context,
|
||||||
)
|
)
|
||||||
_sessions[dbname] = Session()
|
_session_registries[dbname] = Session
|
||||||
|
|
||||||
return _sessions.get(dbname)
|
return _session_registries.get(dbname)
|
||||||
|
|
||||||
|
|
||||||
def pop_session(dbname: str) -> None:
|
def pop_session(dbname: str) -> None:
|
||||||
"""
|
"""
|
||||||
Pop a Session out of the private _sessions memo.
|
Pop a Session registry out of the private _session_registries memo.
|
||||||
|
|
||||||
:param dbname: Database name
|
:param dbname: Database name
|
||||||
:raises KeyError: When `dbname` does not exist in the memo
|
:raises KeyError: When `dbname` does not exist in the memo
|
||||||
"""
|
"""
|
||||||
global _sessions
|
global _session_registries
|
||||||
_sessions.pop(dbname)
|
_session_registries.pop(dbname)
|
||||||
|
|
||||||
|
|
||||||
def refresh(model):
|
def refresh(model):
|
||||||
|
@ -158,7 +191,7 @@ def add(model):
|
||||||
|
|
||||||
def begin():
|
def begin():
|
||||||
"""Begin an SQLAlchemy SessionTransaction."""
|
"""Begin an SQLAlchemy SessionTransaction."""
|
||||||
return get_session().begin()
|
return Committer(get_session())
|
||||||
|
|
||||||
|
|
||||||
def retry_deadlock(func):
|
def retry_deadlock(func):
|
||||||
|
@ -217,7 +250,7 @@ def get_sqlalchemy_url():
|
||||||
parts = sqlalchemy.__version__.split(".")
|
parts = sqlalchemy.__version__.split(".")
|
||||||
major = int(parts[0])
|
major = int(parts[0])
|
||||||
minor = int(parts[1])
|
minor = int(parts[1])
|
||||||
if major == 1 and minor >= 4: # pragma: no cover
|
if (major == 1 and minor >= 4) or (major == 2): # pragma: no cover
|
||||||
constructor = URL.create
|
constructor = URL.create
|
||||||
|
|
||||||
aur_db_backend = aurweb.config.get("database", "backend")
|
aur_db_backend = aurweb.config.get("database", "backend")
|
||||||
|
@ -292,12 +325,14 @@ def get_engine(dbname: str = None, echo: bool = False):
|
||||||
if dbname not in _engines:
|
if dbname not in _engines:
|
||||||
db_backend = aurweb.config.get("database", "backend")
|
db_backend = aurweb.config.get("database", "backend")
|
||||||
connect_args = dict()
|
connect_args = dict()
|
||||||
|
kwargs = {"echo": echo, "connect_args": connect_args}
|
||||||
|
|
||||||
is_sqlite = bool(db_backend == "sqlite")
|
is_sqlite = bool(db_backend == "sqlite")
|
||||||
if is_sqlite: # pragma: no cover
|
if is_sqlite: # pragma: no cover
|
||||||
connect_args["check_same_thread"] = False
|
connect_args["check_same_thread"] = False
|
||||||
|
else:
|
||||||
|
kwargs["isolation_level"] = "READ_COMMITTED"
|
||||||
|
|
||||||
kwargs = {"echo": echo, "connect_args": connect_args}
|
|
||||||
from sqlalchemy import create_engine
|
from sqlalchemy import create_engine
|
||||||
|
|
||||||
_engines[dbname] = create_engine(get_sqlalchemy_url(), **kwargs)
|
_engines[dbname] = create_engine(get_sqlalchemy_url(), **kwargs)
|
||||||
|
|
|
@ -59,7 +59,8 @@ def run(args):
|
||||||
engine = aurweb.db.get_engine(echo=(args.verbose >= 1))
|
engine = aurweb.db.get_engine(echo=(args.verbose >= 1))
|
||||||
aurweb.schema.metadata.create_all(engine)
|
aurweb.schema.metadata.create_all(engine)
|
||||||
conn = engine.connect()
|
conn = engine.connect()
|
||||||
feed_initial_data(conn)
|
with conn.begin():
|
||||||
|
feed_initial_data(conn)
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
if args.use_alembic:
|
if args.use_alembic:
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from sqlalchemy.ext.declarative import declarative_base
|
from sqlalchemy.orm import declarative_base
|
||||||
|
|
||||||
from aurweb import util
|
from aurweb import util
|
||||||
|
|
||||||
|
|
|
@ -210,7 +210,7 @@ class PackageSearch:
|
||||||
# in terms of performance. We should improve this; there's no
|
# in terms of performance. We should improve this; there's no
|
||||||
# reason it should take _longer_.
|
# reason it should take _longer_.
|
||||||
column = getattr(
|
column = getattr(
|
||||||
case([(models.PackageVote.UsersID == self.user.ID, 1)], else_=0), order
|
case((models.PackageVote.UsersID == self.user.ID, 1), else_=0), order
|
||||||
)
|
)
|
||||||
name = getattr(models.Package.Name, order)
|
name = getattr(models.Package.Name, order)
|
||||||
self.query = self.query.order_by(column(), name())
|
self.query = self.query.order_by(column(), name())
|
||||||
|
@ -221,7 +221,7 @@ class PackageSearch:
|
||||||
# in terms of performance. We should improve this; there's no
|
# in terms of performance. We should improve this; there's no
|
||||||
# reason it should take _longer_.
|
# reason it should take _longer_.
|
||||||
column = getattr(
|
column = getattr(
|
||||||
case([(models.PackageNotification.UserID == self.user.ID, 1)], else_=0),
|
case((models.PackageNotification.UserID == self.user.ID, 1), else_=0),
|
||||||
order,
|
order,
|
||||||
)
|
)
|
||||||
name = getattr(models.Package.Name, order)
|
name = getattr(models.Package.Name, order)
|
||||||
|
|
|
@ -145,7 +145,7 @@ async def index(request: Request):
|
||||||
.order_by(
|
.order_by(
|
||||||
# Order primarily by the Status column being PENDING_ID,
|
# Order primarily by the Status column being PENDING_ID,
|
||||||
# and secondarily by RequestTS; both in descending order.
|
# and secondarily by RequestTS; both in descending order.
|
||||||
case([(models.PackageRequest.Status == PENDING_ID, 1)], else_=0).desc(),
|
case((models.PackageRequest.Status == PENDING_ID, 1), else_=0).desc(),
|
||||||
models.PackageRequest.RequestTS.desc(),
|
models.PackageRequest.RequestTS.desc(),
|
||||||
)
|
)
|
||||||
.limit(50)
|
.limit(50)
|
||||||
|
|
|
@ -110,7 +110,7 @@ async def requests( # noqa: C901
|
||||||
filtered.order_by(
|
filtered.order_by(
|
||||||
# Order primarily by the Status column being PENDING_ID,
|
# Order primarily by the Status column being PENDING_ID,
|
||||||
# and secondarily by RequestTS; both in descending order.
|
# and secondarily by RequestTS; both in descending order.
|
||||||
case([(PackageRequest.Status == PENDING_ID, 1)], else_=0).desc(),
|
case((PackageRequest.Status == PENDING_ID, 1), else_=0).desc(),
|
||||||
PackageRequest.RequestTS.desc(),
|
PackageRequest.RequestTS.desc(),
|
||||||
)
|
)
|
||||||
.limit(PP)
|
.limit(PP)
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
from sqlalchemy import text
|
||||||
|
|
||||||
import aurweb.db
|
import aurweb.db
|
||||||
from aurweb import models
|
from aurweb import models
|
||||||
|
|
||||||
|
@ -56,8 +58,10 @@ def setup_test_db(*args):
|
||||||
models.User.__tablename__,
|
models.User.__tablename__,
|
||||||
]
|
]
|
||||||
|
|
||||||
aurweb.db.get_session().execute("SET FOREIGN_KEY_CHECKS = 0")
|
session = aurweb.db.get_session()
|
||||||
|
session.execute(text("SET FOREIGN_KEY_CHECKS = 0"))
|
||||||
for table in tables:
|
for table in tables:
|
||||||
aurweb.db.get_session().execute(f"DELETE FROM {table}")
|
session.execute(text(f"DELETE FROM {table}"))
|
||||||
aurweb.db.get_session().execute("SET FOREIGN_KEY_CHECKS = 1")
|
session.execute(text("SET FOREIGN_KEY_CHECKS = 1"))
|
||||||
aurweb.db.get_session().expunge_all()
|
session.expunge_all()
|
||||||
|
session.commit()
|
||||||
|
|
257
poetry.lock
generated
257
poetry.lock
generated
|
@ -32,13 +32,13 @@ tz = ["python-dateutil"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "annotated-types"
|
name = "annotated-types"
|
||||||
version = "0.5.0"
|
version = "0.6.0"
|
||||||
description = "Reusable constraint types to use with typing.Annotated"
|
description = "Reusable constraint types to use with typing.Annotated"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "annotated_types-0.5.0-py3-none-any.whl", hash = "sha256:58da39888f92c276ad970249761ebea80ba544b77acddaa1a4d6cf78287d45fd"},
|
{file = "annotated_types-0.6.0-py3-none-any.whl", hash = "sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43"},
|
||||||
{file = "annotated_types-0.5.0.tar.gz", hash = "sha256:47cdc3490d9ac1506ce92c7aaa76c579dc3509ff11e098fc867e5130ab7be802"},
|
{file = "annotated_types-0.6.0.tar.gz", hash = "sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -140,13 +140,13 @@ typecheck = ["mypy"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bleach"
|
name = "bleach"
|
||||||
version = "6.0.0"
|
version = "6.1.0"
|
||||||
description = "An easy safelist-based HTML-sanitizing tool."
|
description = "An easy safelist-based HTML-sanitizing tool."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "bleach-6.0.0-py3-none-any.whl", hash = "sha256:33c16e3353dbd13028ab4799a0f89a83f113405c766e9c122df8a06f5b85b3f4"},
|
{file = "bleach-6.1.0-py3-none-any.whl", hash = "sha256:3225f354cfc436b9789c66c4ee030194bee0568fbf9cbdad3bc8b5c26c5f12b6"},
|
||||||
{file = "bleach-6.0.0.tar.gz", hash = "sha256:1a1a85c1595e07d8db14c5f09f09e6433502c51c595970edc090551f0db99414"},
|
{file = "bleach-6.1.0.tar.gz", hash = "sha256:0a31f1837963c41d46bbf1331b8778e1308ea0791db03cc4e7357b97cf42a8fe"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -154,7 +154,7 @@ six = ">=1.9.0"
|
||||||
webencodings = "*"
|
webencodings = "*"
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
css = ["tinycss2 (>=1.1.0,<1.2)"]
|
css = ["tinycss2 (>=1.1.0,<1.3)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "certifi"
|
name = "certifi"
|
||||||
|
@ -1007,20 +1007,20 @@ testing = ["pytest"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "markdown"
|
name = "markdown"
|
||||||
version = "3.4.4"
|
version = "3.5"
|
||||||
description = "Python implementation of John Gruber's Markdown."
|
description = "Python implementation of John Gruber's Markdown."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "Markdown-3.4.4-py3-none-any.whl", hash = "sha256:a4c1b65c0957b4bd9e7d86ddc7b3c9868fb9670660f6f99f6d1bca8954d5a941"},
|
{file = "Markdown-3.5-py3-none-any.whl", hash = "sha256:4afb124395ce5fc34e6d9886dab977fd9ae987fc6e85689f08278cf0c69d4bf3"},
|
||||||
{file = "Markdown-3.4.4.tar.gz", hash = "sha256:225c6123522495d4119a90b3a3ba31a1e87a70369e03f14799ea9c0d7183a3d6"},
|
{file = "Markdown-3.5.tar.gz", hash = "sha256:a807eb2e4778d9156c8f07876c6e4d50b5494c5665c4834f67b06459dfd877b3"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""}
|
importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""}
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
docs = ["mdx-gh-links (>=0.2)", "mkdocs (>=1.0)", "mkdocs-nature (>=0.4)"]
|
docs = ["mdx-gh-links (>=0.2)", "mkdocs (>=1.5)", "mkdocs-gen-files", "mkdocs-literate-nav", "mkdocs-nature (>=0.6)", "mkdocs-section-index", "mkdocstrings[python]"]
|
||||||
testing = ["coverage", "pyyaml"]
|
testing = ["coverage", "pyyaml"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1110,71 +1110,61 @@ files = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "orjson"
|
name = "orjson"
|
||||||
version = "3.9.7"
|
version = "3.9.9"
|
||||||
description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy"
|
description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "orjson-3.9.7-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:b6df858e37c321cefbf27fe7ece30a950bcc3a75618a804a0dcef7ed9dd9c92d"},
|
{file = "orjson-3.9.9-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:f28090060a31f4d11221f9ba48b2273b0d04b702f4dcaa197c38c64ce639cc51"},
|
||||||
{file = "orjson-3.9.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5198633137780d78b86bb54dafaaa9baea698b4f059456cd4554ab7009619221"},
|
{file = "orjson-3.9.9-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8038ba245d0c0a6337cfb6747ea0c51fe18b0cf1a4bc943d530fd66799fae33d"},
|
||||||
{file = "orjson-3.9.7-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e736815b30f7e3c9044ec06a98ee59e217a833227e10eb157f44071faddd7c5"},
|
{file = "orjson-3.9.9-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:543b36df56db195739c70d645ecd43e49b44d5ead5f8f645d2782af118249b37"},
|
||||||
{file = "orjson-3.9.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a19e4074bc98793458b4b3ba35a9a1d132179345e60e152a1bb48c538ab863c4"},
|
{file = "orjson-3.9.9-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8e7877256b5092f1e4e48fc0f1004728dc6901e7a4ffaa4acb0a9578610aa4ce"},
|
||||||
{file = "orjson-3.9.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80acafe396ab689a326ab0d80f8cc61dec0dd2c5dca5b4b3825e7b1e0132c101"},
|
{file = "orjson-3.9.9-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:12b83e0d8ba4ca88b894c3e00efc59fe6d53d9ffb5dbbb79d437a466fc1a513d"},
|
||||||
{file = "orjson-3.9.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:355efdbbf0cecc3bd9b12589b8f8e9f03c813a115efa53f8dc2a523bfdb01334"},
|
{file = "orjson-3.9.9-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ef06431f021453a47a9abb7f7853f04f031d31fbdfe1cc83e3c6aadde502cce"},
|
||||||
{file = "orjson-3.9.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3aab72d2cef7f1dd6104c89b0b4d6b416b0db5ca87cc2fac5f79c5601f549cc2"},
|
{file = "orjson-3.9.9-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0a1a4d9e64597e550428ba091e51a4bcddc7a335c8f9297effbfa67078972b5c"},
|
||||||
{file = "orjson-3.9.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:36b1df2e4095368ee388190687cb1b8557c67bc38400a942a1a77713580b50ae"},
|
{file = "orjson-3.9.9-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:879d2d1f6085c9c0831cec6716c63aaa89e41d8e036cabb19a315498c173fcc6"},
|
||||||
{file = "orjson-3.9.7-cp310-none-win32.whl", hash = "sha256:e94b7b31aa0d65f5b7c72dd8f8227dbd3e30354b99e7a9af096d967a77f2a580"},
|
{file = "orjson-3.9.9-cp310-none-win32.whl", hash = "sha256:d3f56e41bc79d30fdf077073072f2377d2ebf0b946b01f2009ab58b08907bc28"},
|
||||||
{file = "orjson-3.9.7-cp310-none-win_amd64.whl", hash = "sha256:82720ab0cf5bb436bbd97a319ac529aee06077ff7e61cab57cee04a596c4f9b4"},
|
{file = "orjson-3.9.9-cp310-none-win_amd64.whl", hash = "sha256:ab7bae2b8bf17620ed381e4101aeeb64b3ba2a45fc74c7617c633a923cb0f169"},
|
||||||
{file = "orjson-3.9.7-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1f8b47650f90e298b78ecf4df003f66f54acdba6a0f763cc4df1eab048fe3738"},
|
{file = "orjson-3.9.9-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:31d676bc236f6e919d100fb85d0a99812cff1ebffaa58106eaaec9399693e227"},
|
||||||
{file = "orjson-3.9.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f738fee63eb263530efd4d2e9c76316c1f47b3bbf38c1bf45ae9625feed0395e"},
|
{file = "orjson-3.9.9-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:678ffb5c0a6b1518b149cc328c610615d70d9297e351e12c01d0beed5d65360f"},
|
||||||
{file = "orjson-3.9.7-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:38e34c3a21ed41a7dbd5349e24c3725be5416641fdeedf8f56fcbab6d981c900"},
|
{file = "orjson-3.9.9-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a71b0cc21f2c324747bc77c35161e0438e3b5e72db6d3b515310457aba743f7f"},
|
||||||
{file = "orjson-3.9.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:21a3344163be3b2c7e22cef14fa5abe957a892b2ea0525ee86ad8186921b6cf0"},
|
{file = "orjson-3.9.9-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae72621f216d1d990468291b1ec153e1b46e0ed188a86d54e0941f3dabd09ee8"},
|
||||||
{file = "orjson-3.9.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23be6b22aab83f440b62a6f5975bcabeecb672bc627face6a83bc7aeb495dc7e"},
|
{file = "orjson-3.9.9-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:512e5a41af008e76451f5a344941d61f48dddcf7d7ddd3073deb555de64596a6"},
|
||||||
{file = "orjson-3.9.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5205ec0dfab1887dd383597012199f5175035e782cdb013c542187d280ca443"},
|
{file = "orjson-3.9.9-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f89dc338a12f4357f5bf1b098d3dea6072fb0b643fd35fec556f4941b31ae27"},
|
||||||
{file = "orjson-3.9.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8769806ea0b45d7bf75cad253fba9ac6700b7050ebb19337ff6b4e9060f963fa"},
|
{file = "orjson-3.9.9-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:957a45fb201c61b78bcf655a16afbe8a36c2c27f18a998bd6b5d8a35e358d4ad"},
|
||||||
{file = "orjson-3.9.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f9e01239abea2f52a429fe9d95c96df95f078f0172489d691b4a848ace54a476"},
|
{file = "orjson-3.9.9-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d1c01cf4b8e00c7e98a0a7cf606a30a26c32adf2560be2d7d5d6766d6f474b31"},
|
||||||
{file = "orjson-3.9.7-cp311-none-win32.whl", hash = "sha256:8bdb6c911dae5fbf110fe4f5cba578437526334df381b3554b6ab7f626e5eeca"},
|
{file = "orjson-3.9.9-cp311-none-win32.whl", hash = "sha256:397a185e5dd7f8ebe88a063fe13e34d61d394ebb8c70a443cee7661b9c89bda7"},
|
||||||
{file = "orjson-3.9.7-cp311-none-win_amd64.whl", hash = "sha256:9d62c583b5110e6a5cf5169ab616aa4ec71f2c0c30f833306f9e378cf51b6c86"},
|
{file = "orjson-3.9.9-cp311-none-win_amd64.whl", hash = "sha256:24301f2d99d670ded4fb5e2f87643bc7428a54ba49176e38deb2887e42fe82fb"},
|
||||||
{file = "orjson-3.9.7-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:1c3cee5c23979deb8d1b82dc4cc49be59cccc0547999dbe9adb434bb7af11cf7"},
|
{file = "orjson-3.9.9-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:bd55ea5cce3addc03f8fb0705be0cfed63b048acc4f20914ce5e1375b15a293b"},
|
||||||
{file = "orjson-3.9.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a347d7b43cb609e780ff8d7b3107d4bcb5b6fd09c2702aa7bdf52f15ed09fa09"},
|
{file = "orjson-3.9.9-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b28c1a65cd13fff5958ab8b350f0921121691464a7a1752936b06ed25c0c7b6e"},
|
||||||
{file = "orjson-3.9.7-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:154fd67216c2ca38a2edb4089584504fbb6c0694b518b9020ad35ecc97252bb9"},
|
{file = "orjson-3.9.9-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b97a67c47840467ccf116136450c50b6ed4e16a8919c81a4b4faef71e0a2b3f4"},
|
||||||
{file = "orjson-3.9.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ea3e63e61b4b0beeb08508458bdff2daca7a321468d3c4b320a758a2f554d31"},
|
{file = "orjson-3.9.9-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:75b805549cbbcb963e9c9068f1a05abd0ea4c34edc81f8d8ef2edb7e139e5b0f"},
|
||||||
{file = "orjson-3.9.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1eb0b0b2476f357eb2975ff040ef23978137aa674cd86204cfd15d2d17318588"},
|
{file = "orjson-3.9.9-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5424ecbafe57b2de30d3b5736c5d5835064d522185516a372eea069b92786ba6"},
|
||||||
{file = "orjson-3.9.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b9a20a03576c6b7022926f614ac5a6b0914486825eac89196adf3267c6489d"},
|
{file = "orjson-3.9.9-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d2cd6ef4726ef1b8c63e30d8287225a383dbd1de3424d287b37c1906d8d2855"},
|
||||||
{file = "orjson-3.9.7-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:915e22c93e7b7b636240c5a79da5f6e4e84988d699656c8e27f2ac4c95b8dcc0"},
|
{file = "orjson-3.9.9-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c959550e0705dc9f59de8fca1a316da0d9b115991806b217c82931ac81d75f74"},
|
||||||
{file = "orjson-3.9.7-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:f26fb3e8e3e2ee405c947ff44a3e384e8fa1843bc35830fe6f3d9a95a1147b6e"},
|
{file = "orjson-3.9.9-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ece2d8ed4c34903e7f1b64fb1e448a00e919a4cdb104fc713ad34b055b665fca"},
|
||||||
{file = "orjson-3.9.7-cp312-none-win_amd64.whl", hash = "sha256:d8692948cada6ee21f33db5e23460f71c8010d6dfcfe293c9b96737600a7df78"},
|
{file = "orjson-3.9.9-cp312-none-win_amd64.whl", hash = "sha256:f708ca623287186e5876256cb30599308bce9b2757f90d917b7186de54ce6547"},
|
||||||
{file = "orjson-3.9.7-cp37-cp37m-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:7bab596678d29ad969a524823c4e828929a90c09e91cc438e0ad79b37ce41166"},
|
{file = "orjson-3.9.9-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:335406231f9247f985df045f0c0c8f6b6d5d6b3ff17b41a57c1e8ef1a31b4d04"},
|
||||||
{file = "orjson-3.9.7-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63ef3d371ea0b7239ace284cab9cd00d9c92b73119a7c274b437adb09bda35e6"},
|
{file = "orjson-3.9.9-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d9b5440a5d215d9e1cfd4aee35fd4101a8b8ceb8329f549c16e3894ed9f18b5"},
|
||||||
{file = "orjson-3.9.7-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2f8fcf696bbbc584c0c7ed4adb92fd2ad7d153a50258842787bc1524e50d7081"},
|
{file = "orjson-3.9.9-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e98ca450cb4fb176dd572ce28c6623de6923752c70556be4ef79764505320acb"},
|
||||||
{file = "orjson-3.9.7-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:90fe73a1f0321265126cbba13677dcceb367d926c7a65807bd80916af4c17047"},
|
{file = "orjson-3.9.9-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a3bf6ca6bce22eb89dd0650ef49c77341440def966abcb7a2d01de8453df083a"},
|
||||||
{file = "orjson-3.9.7-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:45a47f41b6c3beeb31ac5cf0ff7524987cfcce0a10c43156eb3ee8d92d92bf22"},
|
{file = "orjson-3.9.9-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eb50d869b3c97c7c5187eda3759e8eb15deb1271d694bc5d6ba7040db9e29036"},
|
||||||
{file = "orjson-3.9.7-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a2937f528c84e64be20cb80e70cea76a6dfb74b628a04dab130679d4454395c"},
|
{file = "orjson-3.9.9-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fcf06c69ccc78e32d9f28aa382ab2ab08bf54b696dbe00ee566808fdf05da7d"},
|
||||||
{file = "orjson-3.9.7-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b4fb306c96e04c5863d52ba8d65137917a3d999059c11e659eba7b75a69167bd"},
|
{file = "orjson-3.9.9-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9a4402e7df1b5c9a4c71c7892e1c8f43f642371d13c73242bda5964be6231f95"},
|
||||||
{file = "orjson-3.9.7-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:410aa9d34ad1089898f3db461b7b744d0efcf9252a9415bbdf23540d4f67589f"},
|
{file = "orjson-3.9.9-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b20becf50d4aec7114dc902b58d85c6431b3a59b04caa977e6ce67b6fee0e159"},
|
||||||
{file = "orjson-3.9.7-cp37-none-win32.whl", hash = "sha256:26ffb398de58247ff7bde895fe30817a036f967b0ad0e1cf2b54bda5f8dcfdd9"},
|
{file = "orjson-3.9.9-cp38-none-win32.whl", hash = "sha256:1f352117eccac268a59fedac884b0518347f5e2b55b9f650c2463dd1e732eb61"},
|
||||||
{file = "orjson-3.9.7-cp37-none-win_amd64.whl", hash = "sha256:bcb9a60ed2101af2af450318cd89c6b8313e9f8df4e8fb12b657b2e97227cf08"},
|
{file = "orjson-3.9.9-cp38-none-win_amd64.whl", hash = "sha256:c4eb31a8e8a5e1d9af5aa9e247c2a52ad5cf7e968aaa9aaefdff98cfcc7f2e37"},
|
||||||
{file = "orjson-3.9.7-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5da9032dac184b2ae2da4bce423edff7db34bfd936ebd7d4207ea45840f03905"},
|
{file = "orjson-3.9.9-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4a308aeac326c2bafbca9abbae1e1fcf682b06e78a54dad0347b760525838d85"},
|
||||||
{file = "orjson-3.9.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7951af8f2998045c656ba8062e8edf5e83fd82b912534ab1de1345de08a41d2b"},
|
{file = "orjson-3.9.9-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e159b97f5676dcdac0d0f75ec856ef5851707f61d262851eb41a30e8fadad7c9"},
|
||||||
{file = "orjson-3.9.7-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b8e59650292aa3a8ea78073fc84184538783966528e442a1b9ed653aa282edcf"},
|
{file = "orjson-3.9.9-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f692e7aabad92fa0fff5b13a846fb586b02109475652207ec96733a085019d80"},
|
||||||
{file = "orjson-3.9.7-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9274ba499e7dfb8a651ee876d80386b481336d3868cba29af839370514e4dce0"},
|
{file = "orjson-3.9.9-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cffb77cf0cd3cbf20eb603f932e0dde51b45134bdd2d439c9f57924581bb395b"},
|
||||||
{file = "orjson-3.9.7-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ca1706e8b8b565e934c142db6a9592e6401dc430e4b067a97781a997070c5378"},
|
{file = "orjson-3.9.9-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c63eca397127ebf46b59c9c1fb77b30dd7a8fc808ac385e7a58a7e64bae6e106"},
|
||||||
{file = "orjson-3.9.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83cc275cf6dcb1a248e1876cdefd3f9b5f01063854acdfd687ec360cd3c9712a"},
|
{file = "orjson-3.9.9-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06f0c024a75e8ba5d9101facb4fb5a028cdabe3cdfe081534f2a9de0d5062af2"},
|
||||||
{file = "orjson-3.9.7-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:11c10f31f2c2056585f89d8229a56013bc2fe5de51e095ebc71868d070a8dd81"},
|
{file = "orjson-3.9.9-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:8cba20c9815c2a003b8ca4429b0ad4aa87cb6649af41365821249f0fd397148e"},
|
||||||
{file = "orjson-3.9.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:cf334ce1d2fadd1bf3e5e9bf15e58e0c42b26eb6590875ce65bd877d917a58aa"},
|
{file = "orjson-3.9.9-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:906cac73b7818c20cf0f6a7dde5a6f009c52aecc318416c7af5ea37f15ca7e66"},
|
||||||
{file = "orjson-3.9.7-cp38-none-win32.whl", hash = "sha256:76a0fc023910d8a8ab64daed8d31d608446d2d77c6474b616b34537aa7b79c7f"},
|
{file = "orjson-3.9.9-cp39-none-win32.whl", hash = "sha256:50232572dd300c49f134838c8e7e0917f29a91f97dbd608d23f2895248464b7f"},
|
||||||
{file = "orjson-3.9.7-cp38-none-win_amd64.whl", hash = "sha256:7a34a199d89d82d1897fd4a47820eb50947eec9cda5fd73f4578ff692a912f89"},
|
{file = "orjson-3.9.9-cp39-none-win_amd64.whl", hash = "sha256:920814e02e3dd7af12f0262bbc18b9fe353f75a0d0c237f6a67d270da1a1bb44"},
|
||||||
{file = "orjson-3.9.7-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:e7e7f44e091b93eb39db88bb0cb765db09b7a7f64aea2f35e7d86cbf47046c65"},
|
{file = "orjson-3.9.9.tar.gz", hash = "sha256:02e693843c2959befdd82d1ebae8b05ed12d1cb821605d5f9fe9f98ca5c9fd2b"},
|
||||||
{file = "orjson-3.9.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01d647b2a9c45a23a84c3e70e19d120011cba5f56131d185c1b78685457320bb"},
|
|
||||||
{file = "orjson-3.9.7-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0eb850a87e900a9c484150c414e21af53a6125a13f6e378cf4cc11ae86c8f9c5"},
|
|
||||||
{file = "orjson-3.9.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8f4b0042d8388ac85b8330b65406c84c3229420a05068445c13ca28cc222f1f7"},
|
|
||||||
{file = "orjson-3.9.7-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd3e7aae977c723cc1dbb82f97babdb5e5fbce109630fbabb2ea5053523c89d3"},
|
|
||||||
{file = "orjson-3.9.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c616b796358a70b1f675a24628e4823b67d9e376df2703e893da58247458956"},
|
|
||||||
{file = "orjson-3.9.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c3ba725cf5cf87d2d2d988d39c6a2a8b6fc983d78ff71bc728b0be54c869c884"},
|
|
||||||
{file = "orjson-3.9.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4891d4c934f88b6c29b56395dfc7014ebf7e10b9e22ffd9877784e16c6b2064f"},
|
|
||||||
{file = "orjson-3.9.7-cp39-none-win32.whl", hash = "sha256:14d3fb6cd1040a4a4a530b28e8085131ed94ebc90d72793c59a713de34b60838"},
|
|
||||||
{file = "orjson-3.9.7-cp39-none-win_amd64.whl", hash = "sha256:9ef82157bbcecd75d6296d5d8b2d792242afcd064eb1ac573f8847b52e58f677"},
|
|
||||||
{file = "orjson-3.9.7.tar.gz", hash = "sha256:85e39198f78e2f7e054d296395f6c96f5e02892337746ef5b6a1bf3ed5910142"},
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1687,73 +1677,88 @@ files = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sqlalchemy"
|
name = "sqlalchemy"
|
||||||
version = "1.4.49"
|
version = "2.0.22"
|
||||||
description = "Database Abstraction Library"
|
description = "Database Abstraction Library"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7"
|
python-versions = ">=3.7"
|
||||||
files = [
|
files = [
|
||||||
{file = "SQLAlchemy-1.4.49-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:2e126cf98b7fd38f1e33c64484406b78e937b1a280e078ef558b95bf5b6895f6"},
|
{file = "SQLAlchemy-2.0.22-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f146c61ae128ab43ea3a0955de1af7e1633942c2b2b4985ac51cc292daf33222"},
|
||||||
{file = "SQLAlchemy-1.4.49-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:03db81b89fe7ef3857b4a00b63dedd632d6183d4ea5a31c5d8a92e000a41fc71"},
|
{file = "SQLAlchemy-2.0.22-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:875de9414393e778b655a3d97d60465eb3fae7c919e88b70cc10b40b9f56042d"},
|
||||||
{file = "SQLAlchemy-1.4.49-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:95b9df9afd680b7a3b13b38adf6e3a38995da5e162cc7524ef08e3be4e5ed3e1"},
|
{file = "SQLAlchemy-2.0.22-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:13790cb42f917c45c9c850b39b9941539ca8ee7917dacf099cc0b569f3d40da7"},
|
||||||
{file = "SQLAlchemy-1.4.49-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a63e43bf3f668c11bb0444ce6e809c1227b8f067ca1068898f3008a273f52b09"},
|
{file = "SQLAlchemy-2.0.22-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e04ab55cf49daf1aeb8c622c54d23fa4bec91cb051a43cc24351ba97e1dd09f5"},
|
||||||
{file = "SQLAlchemy-1.4.49-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f835c050ebaa4e48b18403bed2c0fda986525896efd76c245bdd4db995e51a4c"},
|
{file = "SQLAlchemy-2.0.22-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:a42c9fa3abcda0dcfad053e49c4f752eef71ecd8c155221e18b99d4224621176"},
|
||||||
{file = "SQLAlchemy-1.4.49-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c21b172dfb22e0db303ff6419451f0cac891d2e911bb9fbf8003d717f1bcf91"},
|
{file = "SQLAlchemy-2.0.22-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:14cd3bcbb853379fef2cd01e7c64a5d6f1d005406d877ed9509afb7a05ff40a5"},
|
||||||
{file = "SQLAlchemy-1.4.49-cp310-cp310-win32.whl", hash = "sha256:5fb1ebdfc8373b5a291485757bd6431de8d7ed42c27439f543c81f6c8febd729"},
|
{file = "SQLAlchemy-2.0.22-cp310-cp310-win32.whl", hash = "sha256:d143c5a9dada696bcfdb96ba2de4a47d5a89168e71d05a076e88a01386872f97"},
|
||||||
{file = "SQLAlchemy-1.4.49-cp310-cp310-win_amd64.whl", hash = "sha256:f8a65990c9c490f4651b5c02abccc9f113a7f56fa482031ac8cb88b70bc8ccaa"},
|
{file = "SQLAlchemy-2.0.22-cp310-cp310-win_amd64.whl", hash = "sha256:ccd87c25e4c8559e1b918d46b4fa90b37f459c9b4566f1dfbce0eb8122571547"},
|
||||||
{file = "SQLAlchemy-1.4.49-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8923dfdf24d5aa8a3adb59723f54118dd4fe62cf59ed0d0d65d940579c1170a4"},
|
{file = "SQLAlchemy-2.0.22-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4f6ff392b27a743c1ad346d215655503cec64405d3b694228b3454878bf21590"},
|
||||||
{file = "SQLAlchemy-1.4.49-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a9ab2c507a7a439f13ca4499db6d3f50423d1d65dc9b5ed897e70941d9e135b0"},
|
{file = "SQLAlchemy-2.0.22-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f776c2c30f0e5f4db45c3ee11a5f2a8d9de68e81eb73ec4237de1e32e04ae81c"},
|
||||||
{file = "SQLAlchemy-1.4.49-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5debe7d49b8acf1f3035317e63d9ec8d5e4d904c6e75a2a9246a119f5f2fdf3d"},
|
{file = "SQLAlchemy-2.0.22-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c8f1792d20d2f4e875ce7a113f43c3561ad12b34ff796b84002a256f37ce9437"},
|
||||||
{file = "SQLAlchemy-1.4.49-cp311-cp311-win32.whl", hash = "sha256:82b08e82da3756765c2e75f327b9bf6b0f043c9c3925fb95fb51e1567fa4ee87"},
|
{file = "SQLAlchemy-2.0.22-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d80eeb5189d7d4b1af519fc3f148fe7521b9dfce8f4d6a0820e8f5769b005051"},
|
||||||
{file = "SQLAlchemy-1.4.49-cp311-cp311-win_amd64.whl", hash = "sha256:171e04eeb5d1c0d96a544caf982621a1711d078dbc5c96f11d6469169bd003f1"},
|
{file = "SQLAlchemy-2.0.22-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:69fd9e41cf9368afa034e1c81f3570afb96f30fcd2eb1ef29cb4d9371c6eece2"},
|
||||||
{file = "SQLAlchemy-1.4.49-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:36e58f8c4fe43984384e3fbe6341ac99b6b4e083de2fe838f0fdb91cebe9e9cb"},
|
{file = "SQLAlchemy-2.0.22-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:54bcceaf4eebef07dadfde424f5c26b491e4a64e61761dea9459103ecd6ccc95"},
|
||||||
{file = "SQLAlchemy-1.4.49-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b31e67ff419013f99ad6f8fc73ee19ea31585e1e9fe773744c0f3ce58c039c30"},
|
{file = "SQLAlchemy-2.0.22-cp311-cp311-win32.whl", hash = "sha256:7ee7ccf47aa503033b6afd57efbac6b9e05180f492aeed9fcf70752556f95624"},
|
||||||
{file = "SQLAlchemy-1.4.49-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c14b29d9e1529f99efd550cd04dbb6db6ba5d690abb96d52de2bff4ed518bc95"},
|
{file = "SQLAlchemy-2.0.22-cp311-cp311-win_amd64.whl", hash = "sha256:b560f075c151900587ade06706b0c51d04b3277c111151997ea0813455378ae0"},
|
||||||
{file = "SQLAlchemy-1.4.49-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c40f3470e084d31247aea228aa1c39bbc0904c2b9ccbf5d3cfa2ea2dac06f26d"},
|
{file = "SQLAlchemy-2.0.22-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:2c9bac865ee06d27a1533471405ad240a6f5d83195eca481f9fc4a71d8b87df8"},
|
||||||
{file = "SQLAlchemy-1.4.49-cp36-cp36m-win32.whl", hash = "sha256:706bfa02157b97c136547c406f263e4c6274a7b061b3eb9742915dd774bbc264"},
|
{file = "SQLAlchemy-2.0.22-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:625b72d77ac8ac23da3b1622e2da88c4aedaee14df47c8432bf8f6495e655de2"},
|
||||||
{file = "SQLAlchemy-1.4.49-cp36-cp36m-win_amd64.whl", hash = "sha256:a7f7b5c07ae5c0cfd24c2db86071fb2a3d947da7bd487e359cc91e67ac1c6d2e"},
|
{file = "SQLAlchemy-2.0.22-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b39a6e21110204a8c08d40ff56a73ba542ec60bab701c36ce721e7990df49fb9"},
|
||||||
{file = "SQLAlchemy-1.4.49-cp37-cp37m-macosx_11_0_x86_64.whl", hash = "sha256:4afbbf5ef41ac18e02c8dc1f86c04b22b7a2125f2a030e25bbb4aff31abb224b"},
|
{file = "SQLAlchemy-2.0.22-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53a766cb0b468223cafdf63e2d37f14a4757476157927b09300c8c5832d88560"},
|
||||||
{file = "SQLAlchemy-1.4.49-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:24e300c0c2147484a002b175f4e1361f102e82c345bf263242f0449672a4bccf"},
|
{file = "SQLAlchemy-2.0.22-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0e1ce8ebd2e040357dde01a3fb7d30d9b5736b3e54a94002641dfd0aa12ae6ce"},
|
||||||
{file = "SQLAlchemy-1.4.49-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:201de072b818f8ad55c80d18d1a788729cccf9be6d9dc3b9d8613b053cd4836d"},
|
{file = "SQLAlchemy-2.0.22-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:505f503763a767556fa4deae5194b2be056b64ecca72ac65224381a0acab7ebe"},
|
||||||
{file = "SQLAlchemy-1.4.49-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7653ed6817c710d0c95558232aba799307d14ae084cc9b1f4c389157ec50df5c"},
|
{file = "SQLAlchemy-2.0.22-cp312-cp312-win32.whl", hash = "sha256:154a32f3c7b00de3d090bc60ec8006a78149e221f1182e3edcf0376016be9396"},
|
||||||
{file = "SQLAlchemy-1.4.49-cp37-cp37m-win32.whl", hash = "sha256:647e0b309cb4512b1f1b78471fdaf72921b6fa6e750b9f891e09c6e2f0e5326f"},
|
{file = "SQLAlchemy-2.0.22-cp312-cp312-win_amd64.whl", hash = "sha256:129415f89744b05741c6f0b04a84525f37fbabe5dc3774f7edf100e7458c48cd"},
|
||||||
{file = "SQLAlchemy-1.4.49-cp37-cp37m-win_amd64.whl", hash = "sha256:ab73ed1a05ff539afc4a7f8cf371764cdf79768ecb7d2ec691e3ff89abbc541e"},
|
{file = "SQLAlchemy-2.0.22-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3940677d341f2b685a999bffe7078697b5848a40b5f6952794ffcf3af150c301"},
|
||||||
{file = "SQLAlchemy-1.4.49-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:37ce517c011560d68f1ffb28af65d7e06f873f191eb3a73af5671e9c3fada08a"},
|
{file = "SQLAlchemy-2.0.22-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55914d45a631b81a8a2cb1a54f03eea265cf1783241ac55396ec6d735be14883"},
|
||||||
{file = "SQLAlchemy-1.4.49-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1878ce508edea4a879015ab5215546c444233881301e97ca16fe251e89f1c55"},
|
{file = "SQLAlchemy-2.0.22-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2096d6b018d242a2bcc9e451618166f860bb0304f590d205173d317b69986c95"},
|
||||||
{file = "SQLAlchemy-1.4.49-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0e8e608983e6f85d0852ca61f97e521b62e67969e6e640fe6c6b575d4db68557"},
|
{file = "SQLAlchemy-2.0.22-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:19c6986cf2fb4bc8e0e846f97f4135a8e753b57d2aaaa87c50f9acbe606bd1db"},
|
||||||
{file = "SQLAlchemy-1.4.49-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ccf956da45290df6e809ea12c54c02ace7f8ff4d765d6d3dfb3655ee876ce58d"},
|
{file = "SQLAlchemy-2.0.22-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:6ac28bd6888fe3c81fbe97584eb0b96804bd7032d6100b9701255d9441373ec1"},
|
||||||
{file = "SQLAlchemy-1.4.49-cp38-cp38-win32.whl", hash = "sha256:f167c8175ab908ce48bd6550679cc6ea20ae169379e73c7720a28f89e53aa532"},
|
{file = "SQLAlchemy-2.0.22-cp37-cp37m-win32.whl", hash = "sha256:cb9a758ad973e795267da334a92dd82bb7555cb36a0960dcabcf724d26299db8"},
|
||||||
{file = "SQLAlchemy-1.4.49-cp38-cp38-win_amd64.whl", hash = "sha256:45806315aae81a0c202752558f0df52b42d11dd7ba0097bf71e253b4215f34f4"},
|
{file = "SQLAlchemy-2.0.22-cp37-cp37m-win_amd64.whl", hash = "sha256:40b1206a0d923e73aa54f0a6bd61419a96b914f1cd19900b6c8226899d9742ad"},
|
||||||
{file = "SQLAlchemy-1.4.49-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:b6d0c4b15d65087738a6e22e0ff461b407533ff65a73b818089efc8eb2b3e1de"},
|
{file = "SQLAlchemy-2.0.22-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3aa1472bf44f61dd27987cd051f1c893b7d3b17238bff8c23fceaef4f1133868"},
|
||||||
{file = "SQLAlchemy-1.4.49-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a843e34abfd4c797018fd8d00ffffa99fd5184c421f190b6ca99def4087689bd"},
|
{file = "SQLAlchemy-2.0.22-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:56a7e2bb639df9263bf6418231bc2a92a773f57886d371ddb7a869a24919face"},
|
||||||
{file = "SQLAlchemy-1.4.49-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1c890421651b45a681181301b3497e4d57c0d01dc001e10438a40e9a9c25ee77"},
|
{file = "SQLAlchemy-2.0.22-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ccca778c0737a773a1ad86b68bda52a71ad5950b25e120b6eb1330f0df54c3d0"},
|
||||||
{file = "SQLAlchemy-1.4.49-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d26f280b8f0a8f497bc10573849ad6dc62e671d2468826e5c748d04ed9e670d5"},
|
{file = "SQLAlchemy-2.0.22-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7c6c3e9350f9fb16de5b5e5fbf17b578811a52d71bb784cc5ff71acb7de2a7f9"},
|
||||||
{file = "SQLAlchemy-1.4.49-cp39-cp39-win32.whl", hash = "sha256:ec2268de67f73b43320383947e74700e95c6770d0c68c4e615e9897e46296294"},
|
{file = "SQLAlchemy-2.0.22-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:564e9f9e4e6466273dbfab0e0a2e5fe819eec480c57b53a2cdee8e4fdae3ad5f"},
|
||||||
{file = "SQLAlchemy-1.4.49-cp39-cp39-win_amd64.whl", hash = "sha256:bbdf16372859b8ed3f4d05f925a984771cd2abd18bd187042f24be4886c2a15f"},
|
{file = "SQLAlchemy-2.0.22-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:af66001d7b76a3fab0d5e4c1ec9339ac45748bc4a399cbc2baa48c1980d3c1f4"},
|
||||||
{file = "SQLAlchemy-1.4.49.tar.gz", hash = "sha256:06ff25cbae30c396c4b7737464f2a7fc37a67b7da409993b182b024cec80aed9"},
|
{file = "SQLAlchemy-2.0.22-cp38-cp38-win32.whl", hash = "sha256:9e55dff5ec115316dd7a083cdc1a52de63693695aecf72bc53a8e1468ce429e5"},
|
||||||
|
{file = "SQLAlchemy-2.0.22-cp38-cp38-win_amd64.whl", hash = "sha256:4e869a8ff7ee7a833b74868a0887e8462445ec462432d8cbeff5e85f475186da"},
|
||||||
|
{file = "SQLAlchemy-2.0.22-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9886a72c8e6371280cb247c5d32c9c8fa141dc560124348762db8a8b236f8692"},
|
||||||
|
{file = "SQLAlchemy-2.0.22-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a571bc8ac092a3175a1d994794a8e7a1f2f651e7c744de24a19b4f740fe95034"},
|
||||||
|
{file = "SQLAlchemy-2.0.22-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8db5ba8b7da759b727faebc4289a9e6a51edadc7fc32207a30f7c6203a181592"},
|
||||||
|
{file = "SQLAlchemy-2.0.22-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b0b3f2686c3f162123adba3cb8b626ed7e9b8433ab528e36ed270b4f70d1cdb"},
|
||||||
|
{file = "SQLAlchemy-2.0.22-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0c1fea8c0abcb070ffe15311853abfda4e55bf7dc1d4889497b3403629f3bf00"},
|
||||||
|
{file = "SQLAlchemy-2.0.22-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4bb062784f37b2d75fd9b074c8ec360ad5df71f933f927e9e95c50eb8e05323c"},
|
||||||
|
{file = "SQLAlchemy-2.0.22-cp39-cp39-win32.whl", hash = "sha256:58a3aba1bfb32ae7af68da3f277ed91d9f57620cf7ce651db96636790a78b736"},
|
||||||
|
{file = "SQLAlchemy-2.0.22-cp39-cp39-win_amd64.whl", hash = "sha256:92e512a6af769e4725fa5b25981ba790335d42c5977e94ded07db7d641490a85"},
|
||||||
|
{file = "SQLAlchemy-2.0.22-py3-none-any.whl", hash = "sha256:3076740335e4aaadd7deb3fe6dcb96b3015f1613bd190a4e1634e1b99b02ec86"},
|
||||||
|
{file = "SQLAlchemy-2.0.22.tar.gz", hash = "sha256:5434cc601aa17570d79e5377f5fd45ff92f9379e2abed0be5e8c2fba8d353d2b"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
greenlet = {version = "!=0.4.17", markers = "python_version >= \"3\" 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\")"}
|
greenlet = {version = "!=0.4.17", 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\""}
|
||||||
|
typing-extensions = ">=4.2.0"
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
aiomysql = ["aiomysql", "greenlet (!=0.4.17)"]
|
aiomysql = ["aiomysql (>=0.2.0)", "greenlet (!=0.4.17)"]
|
||||||
aiosqlite = ["aiosqlite", "greenlet (!=0.4.17)", "typing-extensions (!=3.10.0.1)"]
|
aiosqlite = ["aiosqlite", "greenlet (!=0.4.17)", "typing-extensions (!=3.10.0.1)"]
|
||||||
asyncio = ["greenlet (!=0.4.17)"]
|
asyncio = ["greenlet (!=0.4.17)"]
|
||||||
asyncmy = ["asyncmy (>=0.2.3,!=0.2.4)", "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)"]
|
mariadb-connector = ["mariadb (>=1.0.1,!=1.1.2,!=1.1.5)"]
|
||||||
mssql = ["pyodbc"]
|
mssql = ["pyodbc"]
|
||||||
mssql-pymssql = ["pymssql"]
|
mssql-pymssql = ["pymssql"]
|
||||||
mssql-pyodbc = ["pyodbc"]
|
mssql-pyodbc = ["pyodbc"]
|
||||||
mypy = ["mypy (>=0.910)", "sqlalchemy2-stubs"]
|
mypy = ["mypy (>=0.910)"]
|
||||||
mysql = ["mysqlclient (>=1.4.0)", "mysqlclient (>=1.4.0,<2)"]
|
mysql = ["mysqlclient (>=1.4.0)"]
|
||||||
mysql-connector = ["mysql-connector-python"]
|
mysql-connector = ["mysql-connector-python"]
|
||||||
oracle = ["cx-oracle (>=7)", "cx-oracle (>=7,<8)"]
|
oracle = ["cx-oracle (>=7)"]
|
||||||
|
oracle-oracledb = ["oracledb (>=1.0.1)"]
|
||||||
postgresql = ["psycopg2 (>=2.7)"]
|
postgresql = ["psycopg2 (>=2.7)"]
|
||||||
postgresql-asyncpg = ["asyncpg", "greenlet (!=0.4.17)"]
|
postgresql-asyncpg = ["asyncpg", "greenlet (!=0.4.17)"]
|
||||||
postgresql-pg8000 = ["pg8000 (>=1.16.6,!=1.29.0)"]
|
postgresql-pg8000 = ["pg8000 (>=1.29.1)"]
|
||||||
|
postgresql-psycopg = ["psycopg (>=3.0.7)"]
|
||||||
postgresql-psycopg2binary = ["psycopg2-binary"]
|
postgresql-psycopg2binary = ["psycopg2-binary"]
|
||||||
postgresql-psycopg2cffi = ["psycopg2cffi"]
|
postgresql-psycopg2cffi = ["psycopg2cffi"]
|
||||||
pymysql = ["pymysql", "pymysql (<1)"]
|
postgresql-psycopgbinary = ["psycopg[binary] (>=3.0.7)"]
|
||||||
|
pymysql = ["pymysql"]
|
||||||
sqlcipher = ["sqlcipher3-binary"]
|
sqlcipher = ["sqlcipher3-binary"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1965,4 +1970,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p
|
||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.0"
|
lock-version = "2.0"
|
||||||
python-versions = ">=3.9,<3.12"
|
python-versions = ">=3.9,<3.12"
|
||||||
content-hash = "87954b20049b8c138bd6c7767247aa017a8c5c64cc857a12ab9d78cf8ac787c7"
|
content-hash = "cfdf70424a62418aa4c3b233cb5ab2486415364bf5ef27198db1f07a579927c7"
|
||||||
|
|
|
@ -83,7 +83,7 @@ Authlib = "^1.2.1"
|
||||||
Jinja2 = "^3.1.2"
|
Jinja2 = "^3.1.2"
|
||||||
Markdown = "^3.4.4"
|
Markdown = "^3.4.4"
|
||||||
Werkzeug = "^3.0.0"
|
Werkzeug = "^3.0.0"
|
||||||
SQLAlchemy = "^1.4.49"
|
SQLAlchemy = "^2.0.22"
|
||||||
|
|
||||||
# ASGI
|
# ASGI
|
||||||
uvicorn = "^0.23.0"
|
uvicorn = "^0.23.0"
|
||||||
|
|
|
@ -43,7 +43,7 @@ from multiprocessing import Lock
|
||||||
|
|
||||||
import py
|
import py
|
||||||
import pytest
|
import pytest
|
||||||
from sqlalchemy import create_engine
|
from sqlalchemy import create_engine, text
|
||||||
from sqlalchemy.engine import URL
|
from sqlalchemy.engine import URL
|
||||||
from sqlalchemy.engine.base import Engine
|
from sqlalchemy.engine.base import Engine
|
||||||
from sqlalchemy.exc import ProgrammingError
|
from sqlalchemy.exc import ProgrammingError
|
||||||
|
@ -104,15 +104,16 @@ def _create_database(engine: Engine, dbname: str) -> None:
|
||||||
:param dbname: Database name to create
|
:param dbname: Database name to create
|
||||||
"""
|
"""
|
||||||
conn = engine.connect()
|
conn = engine.connect()
|
||||||
try:
|
with conn.begin():
|
||||||
conn.execute(f"CREATE DATABASE {dbname}")
|
try:
|
||||||
except ProgrammingError: # pragma: no cover
|
conn.execute(text(f"CREATE DATABASE {dbname}"))
|
||||||
# The database most likely already existed if we hit
|
except ProgrammingError: # pragma: no cover
|
||||||
# a ProgrammingError. Just drop the database and try
|
# The database most likely already existed if we hit
|
||||||
# again. If at that point things still fail, any
|
# a ProgrammingError. Just drop the database and try
|
||||||
# exception will be propogated up to the caller.
|
# again. If at that point things still fail, any
|
||||||
conn.execute(f"DROP DATABASE {dbname}")
|
# exception will be propogated up to the caller.
|
||||||
conn.execute(f"CREATE DATABASE {dbname}")
|
conn.execute(text(f"DROP DATABASE {dbname}"))
|
||||||
|
conn.execute(text(f"CREATE DATABASE {dbname}"))
|
||||||
conn.close()
|
conn.close()
|
||||||
initdb.run(AlembicArgs)
|
initdb.run(AlembicArgs)
|
||||||
|
|
||||||
|
@ -124,9 +125,10 @@ def _drop_database(engine: Engine, dbname: str) -> None:
|
||||||
:param engine: Engine returned by test_engine()
|
:param engine: Engine returned by test_engine()
|
||||||
:param dbname: Database name to drop
|
:param dbname: Database name to drop
|
||||||
"""
|
"""
|
||||||
aurweb.schema.metadata.drop_all(bind=engine)
|
# aurweb.schema.metadata.drop_all(bind=engine)
|
||||||
conn = engine.connect()
|
conn = engine.connect()
|
||||||
conn.execute(f"DROP DATABASE {dbname}")
|
with conn.begin():
|
||||||
|
conn.execute(text(f"DROP DATABASE {dbname}"))
|
||||||
conn.close()
|
conn.close()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -830,6 +830,7 @@ def test_post_account_edit_type_as_dev(client: TestClient, pm_user: User):
|
||||||
request.cookies = cookies
|
request.cookies = cookies
|
||||||
resp = request.post(endpoint, data=data)
|
resp = request.post(endpoint, data=data)
|
||||||
assert resp.status_code == int(HTTPStatus.OK)
|
assert resp.status_code == int(HTTPStatus.OK)
|
||||||
|
db.refresh(user2)
|
||||||
assert user2.AccountTypeID == at.DEVELOPER_ID
|
assert user2.AccountTypeID == at.DEVELOPER_ID
|
||||||
|
|
||||||
|
|
||||||
|
@ -850,6 +851,7 @@ def test_post_account_edit_invalid_type_as_pm(client: TestClient, pm_user: User)
|
||||||
request.cookies = cookies
|
request.cookies = cookies
|
||||||
resp = request.post(endpoint, data=data)
|
resp = request.post(endpoint, data=data)
|
||||||
assert resp.status_code == int(HTTPStatus.BAD_REQUEST)
|
assert resp.status_code == int(HTTPStatus.BAD_REQUEST)
|
||||||
|
db.refresh(user2)
|
||||||
assert user2.AccountTypeID == at.USER_ID
|
assert user2.AccountTypeID == at.USER_ID
|
||||||
|
|
||||||
errors = get_errors(resp.text)
|
errors = get_errors(resp.text)
|
||||||
|
@ -1020,6 +1022,7 @@ def test_post_account_edit_inactivity(client: TestClient, user: User):
|
||||||
assert resp.status_code == int(HTTPStatus.OK)
|
assert resp.status_code == int(HTTPStatus.OK)
|
||||||
|
|
||||||
# Make sure the user record got updated correctly.
|
# Make sure the user record got updated correctly.
|
||||||
|
db.refresh(user)
|
||||||
assert user.InactivityTS > 0
|
assert user.InactivityTS > 0
|
||||||
|
|
||||||
post_data.update({"J": False})
|
post_data.update({"J": False})
|
||||||
|
@ -1028,6 +1031,7 @@ def test_post_account_edit_inactivity(client: TestClient, user: User):
|
||||||
resp = request.post(f"/account/{user.Username}/edit", data=post_data)
|
resp = request.post(f"/account/{user.Username}/edit", data=post_data)
|
||||||
assert resp.status_code == int(HTTPStatus.OK)
|
assert resp.status_code == int(HTTPStatus.OK)
|
||||||
|
|
||||||
|
db.refresh(user)
|
||||||
assert user.InactivityTS == 0
|
assert user.InactivityTS == 0
|
||||||
|
|
||||||
|
|
||||||
|
@ -1050,6 +1054,7 @@ def test_post_account_edit_suspended(client: TestClient, user: User):
|
||||||
assert resp.status_code == int(HTTPStatus.OK)
|
assert resp.status_code == int(HTTPStatus.OK)
|
||||||
|
|
||||||
# Make sure the user record got updated correctly.
|
# Make sure the user record got updated correctly.
|
||||||
|
db.refresh(user)
|
||||||
assert user.Suspended
|
assert user.Suspended
|
||||||
# Let's make sure the DB got updated properly.
|
# Let's make sure the DB got updated properly.
|
||||||
assert user.session is None
|
assert user.session is None
|
||||||
|
@ -1207,6 +1212,7 @@ def test_post_account_edit_password(client: TestClient, user: User):
|
||||||
|
|
||||||
assert response.status_code == int(HTTPStatus.OK)
|
assert response.status_code == int(HTTPStatus.OK)
|
||||||
|
|
||||||
|
db.refresh(user)
|
||||||
assert user.valid_password("newPassword")
|
assert user.valid_password("newPassword")
|
||||||
|
|
||||||
|
|
||||||
|
@ -1273,6 +1279,7 @@ def test_post_account_edit_self_type_as_pm(client: TestClient, pm_user: User):
|
||||||
resp = request.post(endpoint, data=data)
|
resp = request.post(endpoint, data=data)
|
||||||
assert resp.status_code == int(HTTPStatus.OK)
|
assert resp.status_code == int(HTTPStatus.OK)
|
||||||
|
|
||||||
|
db.refresh(pm_user)
|
||||||
assert pm_user.AccountTypeID == USER_ID
|
assert pm_user.AccountTypeID == USER_ID
|
||||||
|
|
||||||
|
|
||||||
|
@ -1308,6 +1315,7 @@ def test_post_account_edit_other_user_type_as_pm(
|
||||||
assert resp.status_code == int(HTTPStatus.OK)
|
assert resp.status_code == int(HTTPStatus.OK)
|
||||||
|
|
||||||
# Let's make sure the DB got updated properly.
|
# Let's make sure the DB got updated properly.
|
||||||
|
db.refresh(user2)
|
||||||
assert user2.AccountTypeID == PACKAGE_MAINTAINER_ID
|
assert user2.AccountTypeID == PACKAGE_MAINTAINER_ID
|
||||||
|
|
||||||
# and also that this got logged out at DEBUG level.
|
# and also that this got logged out at DEBUG level.
|
||||||
|
|
|
@ -24,5 +24,6 @@ def test_run():
|
||||||
aurweb.initdb.run(Args())
|
aurweb.initdb.run(Args())
|
||||||
|
|
||||||
# Check that constant table rows got added via initdb.
|
# Check that constant table rows got added via initdb.
|
||||||
record = aurweb.db.query(AccountType, AccountType.AccountType == "User").first()
|
with aurweb.db.begin():
|
||||||
|
record = aurweb.db.query(AccountType, AccountType.AccountType == "User").first()
|
||||||
assert record is not None
|
assert record is not None
|
||||||
|
|
|
@ -768,6 +768,7 @@ def test_pm_proposal_vote(client, proposal):
|
||||||
assert response.status_code == int(HTTPStatus.OK)
|
assert response.status_code == int(HTTPStatus.OK)
|
||||||
|
|
||||||
# Check that the proposal record got updated.
|
# Check that the proposal record got updated.
|
||||||
|
db.refresh(voteinfo)
|
||||||
assert voteinfo.Yes == yes + 1
|
assert voteinfo.Yes == yes + 1
|
||||||
|
|
||||||
# Check that the new PMVote exists.
|
# Check that the new PMVote exists.
|
||||||
|
|
|
@ -1528,6 +1528,7 @@ def test_packages_post_disown_as_maintainer(
|
||||||
errors = get_errors(resp.text)
|
errors = get_errors(resp.text)
|
||||||
expected = "You did not select any packages to disown."
|
expected = "You did not select any packages to disown."
|
||||||
assert errors[0].text.strip() == expected
|
assert errors[0].text.strip() == expected
|
||||||
|
db.refresh(package)
|
||||||
assert package.PackageBase.Maintainer is not None
|
assert package.PackageBase.Maintainer is not None
|
||||||
|
|
||||||
# Try to disown `package` without giving the confirm argument.
|
# Try to disown `package` without giving the confirm argument.
|
||||||
|
@ -1552,6 +1553,7 @@ def test_packages_post_disown_as_maintainer(
|
||||||
data={"action": "disown", "IDs": [package.ID], "confirm": True},
|
data={"action": "disown", "IDs": [package.ID], "confirm": True},
|
||||||
)
|
)
|
||||||
assert resp.status_code == int(HTTPStatus.BAD_REQUEST)
|
assert resp.status_code == int(HTTPStatus.BAD_REQUEST)
|
||||||
|
db.refresh(package)
|
||||||
assert package.PackageBase.Maintainer is not None
|
assert package.PackageBase.Maintainer is not None
|
||||||
errors = get_errors(resp.text)
|
errors = get_errors(resp.text)
|
||||||
expected = "You are not allowed to disown one of the packages you selected."
|
expected = "You are not allowed to disown one of the packages you selected."
|
||||||
|
@ -1565,6 +1567,7 @@ def test_packages_post_disown_as_maintainer(
|
||||||
data={"action": "disown", "IDs": [package.ID], "confirm": True},
|
data={"action": "disown", "IDs": [package.ID], "confirm": True},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
db.get_session().expire_all()
|
||||||
assert package.PackageBase.Maintainer is None
|
assert package.PackageBase.Maintainer is None
|
||||||
successes = get_successes(resp.text)
|
successes = get_successes(resp.text)
|
||||||
expected = "The selected packages have been disowned."
|
expected = "The selected packages have been disowned."
|
||||||
|
@ -1649,6 +1652,7 @@ def test_packages_post_delete(
|
||||||
|
|
||||||
# Whoo. Now, let's finally make a valid request as `pm_user`
|
# Whoo. Now, let's finally make a valid request as `pm_user`
|
||||||
# to delete `package`.
|
# to delete `package`.
|
||||||
|
pkgname = package.PackageBase.Name
|
||||||
with client as request:
|
with client as request:
|
||||||
request.cookies = pm_cookies
|
request.cookies = pm_cookies
|
||||||
resp = request.post(
|
resp = request.post(
|
||||||
|
@ -1661,7 +1665,7 @@ def test_packages_post_delete(
|
||||||
assert successes[0].text.strip() == expected
|
assert successes[0].text.strip() == expected
|
||||||
|
|
||||||
# Expect that the package deletion was logged.
|
# Expect that the package deletion was logged.
|
||||||
pkgbases = [package.PackageBase.Name]
|
pkgbases = [pkgname]
|
||||||
expected = (
|
expected = (
|
||||||
f"Privileged user '{pm_user.Username}' deleted the "
|
f"Privileged user '{pm_user.Username}' deleted the "
|
||||||
f"following package bases: {str(pkgbases)}."
|
f"following package bases: {str(pkgbases)}."
|
||||||
|
|
|
@ -688,6 +688,7 @@ def test_pkgbase_comment_pin_as_co(
|
||||||
assert resp.status_code == int(HTTPStatus.SEE_OTHER)
|
assert resp.status_code == int(HTTPStatus.SEE_OTHER)
|
||||||
|
|
||||||
# Assert that PinnedTS got set.
|
# Assert that PinnedTS got set.
|
||||||
|
db.refresh(comment)
|
||||||
assert comment.PinnedTS > 0
|
assert comment.PinnedTS > 0
|
||||||
|
|
||||||
# Unpin the comment we just pinned.
|
# Unpin the comment we just pinned.
|
||||||
|
@ -698,6 +699,7 @@ def test_pkgbase_comment_pin_as_co(
|
||||||
assert resp.status_code == int(HTTPStatus.SEE_OTHER)
|
assert resp.status_code == int(HTTPStatus.SEE_OTHER)
|
||||||
|
|
||||||
# Let's assert that PinnedTS was unset.
|
# Let's assert that PinnedTS was unset.
|
||||||
|
db.refresh(comment)
|
||||||
assert comment.PinnedTS == 0
|
assert comment.PinnedTS == 0
|
||||||
|
|
||||||
|
|
||||||
|
@ -716,6 +718,7 @@ def test_pkgbase_comment_pin(
|
||||||
assert resp.status_code == int(HTTPStatus.SEE_OTHER)
|
assert resp.status_code == int(HTTPStatus.SEE_OTHER)
|
||||||
|
|
||||||
# Assert that PinnedTS got set.
|
# Assert that PinnedTS got set.
|
||||||
|
db.refresh(comment)
|
||||||
assert comment.PinnedTS > 0
|
assert comment.PinnedTS > 0
|
||||||
|
|
||||||
# Unpin the comment we just pinned.
|
# Unpin the comment we just pinned.
|
||||||
|
@ -726,6 +729,7 @@ def test_pkgbase_comment_pin(
|
||||||
assert resp.status_code == int(HTTPStatus.SEE_OTHER)
|
assert resp.status_code == int(HTTPStatus.SEE_OTHER)
|
||||||
|
|
||||||
# Let's assert that PinnedTS was unset.
|
# Let's assert that PinnedTS was unset.
|
||||||
|
db.refresh(comment)
|
||||||
assert comment.PinnedTS == 0
|
assert comment.PinnedTS == 0
|
||||||
|
|
||||||
|
|
||||||
|
@ -1040,6 +1044,7 @@ def test_pkgbase_flag(
|
||||||
request.cookies = cookies
|
request.cookies = cookies
|
||||||
resp = request.post(endpoint, data={"comments": "Test"})
|
resp = request.post(endpoint, data={"comments": "Test"})
|
||||||
assert resp.status_code == int(HTTPStatus.SEE_OTHER)
|
assert resp.status_code == int(HTTPStatus.SEE_OTHER)
|
||||||
|
db.refresh(pkgbase)
|
||||||
assert pkgbase.Flagger == user
|
assert pkgbase.Flagger == user
|
||||||
assert pkgbase.FlaggerComment == "Test"
|
assert pkgbase.FlaggerComment == "Test"
|
||||||
|
|
||||||
|
@ -1077,6 +1082,7 @@ def test_pkgbase_flag(
|
||||||
request.cookies = user2_cookies
|
request.cookies = user2_cookies
|
||||||
resp = request.post(endpoint)
|
resp = request.post(endpoint)
|
||||||
assert resp.status_code == int(HTTPStatus.SEE_OTHER)
|
assert resp.status_code == int(HTTPStatus.SEE_OTHER)
|
||||||
|
db.refresh(pkgbase)
|
||||||
assert pkgbase.Flagger == user
|
assert pkgbase.Flagger == user
|
||||||
|
|
||||||
# Now, test that the 'maintainer' user can.
|
# Now, test that the 'maintainer' user can.
|
||||||
|
@ -1085,6 +1091,7 @@ def test_pkgbase_flag(
|
||||||
request.cookies = maint_cookies
|
request.cookies = maint_cookies
|
||||||
resp = request.post(endpoint)
|
resp = request.post(endpoint)
|
||||||
assert resp.status_code == int(HTTPStatus.SEE_OTHER)
|
assert resp.status_code == int(HTTPStatus.SEE_OTHER)
|
||||||
|
db.refresh(pkgbase)
|
||||||
assert pkgbase.Flagger is None
|
assert pkgbase.Flagger is None
|
||||||
|
|
||||||
# Flag it again.
|
# Flag it again.
|
||||||
|
@ -1098,6 +1105,7 @@ def test_pkgbase_flag(
|
||||||
request.cookies = cookies
|
request.cookies = cookies
|
||||||
resp = request.post(endpoint)
|
resp = request.post(endpoint)
|
||||||
assert resp.status_code == int(HTTPStatus.SEE_OTHER)
|
assert resp.status_code == int(HTTPStatus.SEE_OTHER)
|
||||||
|
db.refresh(pkgbase)
|
||||||
assert pkgbase.Flagger is None
|
assert pkgbase.Flagger is None
|
||||||
|
|
||||||
|
|
||||||
|
@ -1170,6 +1178,7 @@ def test_pkgbase_vote(client: TestClient, user: User, package: Package):
|
||||||
|
|
||||||
vote = pkgbase.package_votes.filter(PackageVote.UsersID == user.ID).first()
|
vote = pkgbase.package_votes.filter(PackageVote.UsersID == user.ID).first()
|
||||||
assert vote is not None
|
assert vote is not None
|
||||||
|
db.refresh(pkgbase)
|
||||||
assert pkgbase.NumVotes == 1
|
assert pkgbase.NumVotes == 1
|
||||||
|
|
||||||
# Remove vote.
|
# Remove vote.
|
||||||
|
@ -1181,6 +1190,7 @@ def test_pkgbase_vote(client: TestClient, user: User, package: Package):
|
||||||
|
|
||||||
vote = pkgbase.package_votes.filter(PackageVote.UsersID == user.ID).first()
|
vote = pkgbase.package_votes.filter(PackageVote.UsersID == user.ID).first()
|
||||||
assert vote is None
|
assert vote is None
|
||||||
|
db.refresh(pkgbase)
|
||||||
assert pkgbase.NumVotes == 0
|
assert pkgbase.NumVotes == 0
|
||||||
|
|
||||||
|
|
||||||
|
@ -1592,9 +1602,9 @@ def test_pkgbase_merge_post(
|
||||||
assert resp.status_code == int(HTTPStatus.SEE_OTHER)
|
assert resp.status_code == int(HTTPStatus.SEE_OTHER)
|
||||||
|
|
||||||
# Save these relationships for later comparison.
|
# Save these relationships for later comparison.
|
||||||
comments = package.PackageBase.comments.all()
|
comments = [row.__dict__ for row in package.PackageBase.comments.all()]
|
||||||
notifs = package.PackageBase.notifications.all()
|
notifs = [row.__dict__ for row in package.PackageBase.notifications.all()]
|
||||||
votes = package.PackageBase.package_votes.all()
|
votes = [row.__dict__ for row in package.PackageBase.package_votes.all()]
|
||||||
|
|
||||||
# Merge the package into target.
|
# Merge the package into target.
|
||||||
endpoint = f"/pkgbase/{package.PackageBase.Name}/merge"
|
endpoint = f"/pkgbase/{package.PackageBase.Name}/merge"
|
||||||
|
@ -1612,9 +1622,13 @@ def test_pkgbase_merge_post(
|
||||||
|
|
||||||
# Assert that the original comments, notifs and votes we setup
|
# Assert that the original comments, notifs and votes we setup
|
||||||
# got migrated to target as intended.
|
# got migrated to target as intended.
|
||||||
assert comments == target.comments.all()
|
db.get_session().refresh(target)
|
||||||
assert notifs == target.notifications.all()
|
assert len(comments) == target.comments.count()
|
||||||
assert votes == target.package_votes.all()
|
assert comments[0]["PackageBaseID"] != target.ID
|
||||||
|
assert len(notifs) == target.notifications.count()
|
||||||
|
assert notifs[0]["PackageBaseID"] != target.ID
|
||||||
|
assert len(votes) == target.package_votes.count()
|
||||||
|
assert votes[0]["PackageBaseID"] != target.ID
|
||||||
|
|
||||||
# ...and that the package got deleted.
|
# ...and that the package got deleted.
|
||||||
package = db.query(Package).filter(Package.Name == pkgname).first()
|
package = db.query(Package).filter(Package.Name == pkgname).first()
|
||||||
|
|
|
@ -649,6 +649,7 @@ def test_orphan_request(
|
||||||
assert resp.headers.get("location") == f"/pkgbase/{pkgbase.Name}"
|
assert resp.headers.get("location") == f"/pkgbase/{pkgbase.Name}"
|
||||||
|
|
||||||
# We should have unset the maintainer.
|
# We should have unset the maintainer.
|
||||||
|
db.refresh(pkgbase)
|
||||||
assert pkgbase.Maintainer is None
|
assert pkgbase.Maintainer is None
|
||||||
|
|
||||||
# We should have removed the comaintainers.
|
# We should have removed the comaintainers.
|
||||||
|
@ -748,6 +749,7 @@ def test_orphan_as_maintainer(client: TestClient, auser: User, pkgbase: PackageB
|
||||||
# As the pkgbase maintainer, disowning the package just ends up
|
# As the pkgbase maintainer, disowning the package just ends up
|
||||||
# either promoting the lowest priority comaintainer or removing
|
# either promoting the lowest priority comaintainer or removing
|
||||||
# the associated maintainer relationship altogether.
|
# the associated maintainer relationship altogether.
|
||||||
|
db.refresh(pkgbase)
|
||||||
assert pkgbase.Maintainer is None
|
assert pkgbase.Maintainer is None
|
||||||
|
|
||||||
|
|
||||||
|
@ -1044,6 +1046,7 @@ def test_requests_close_post(client: TestClient, user: User, pkgreq: PackageRequ
|
||||||
resp = request.post(f"/requests/{pkgreq.ID}/close")
|
resp = request.post(f"/requests/{pkgreq.ID}/close")
|
||||||
assert resp.status_code == int(HTTPStatus.SEE_OTHER)
|
assert resp.status_code == int(HTTPStatus.SEE_OTHER)
|
||||||
|
|
||||||
|
db.refresh(pkgreq)
|
||||||
assert pkgreq.Status == REJECTED_ID
|
assert pkgreq.Status == REJECTED_ID
|
||||||
assert pkgreq.Closer == user
|
assert pkgreq.Closer == user
|
||||||
assert pkgreq.ClosureComment == str()
|
assert pkgreq.ClosureComment == str()
|
||||||
|
@ -1060,6 +1063,7 @@ def test_requests_close_post_rejected(
|
||||||
)
|
)
|
||||||
assert resp.status_code == int(HTTPStatus.SEE_OTHER)
|
assert resp.status_code == int(HTTPStatus.SEE_OTHER)
|
||||||
|
|
||||||
|
db.refresh(pkgreq)
|
||||||
assert pkgreq.Status == REJECTED_ID
|
assert pkgreq.Status == REJECTED_ID
|
||||||
assert pkgreq.Closer == user
|
assert pkgreq.Closer == user
|
||||||
assert pkgreq.ClosureComment == str()
|
assert pkgreq.ClosureComment == str()
|
||||||
|
|
|
@ -102,6 +102,7 @@ def test_user_language(client: TestClient, user: User):
|
||||||
req.cookies = {"AURSID": sid}
|
req.cookies = {"AURSID": sid}
|
||||||
response = req.post("/language", data=post_data)
|
response = req.post("/language", data=post_data)
|
||||||
assert response.status_code == int(HTTPStatus.SEE_OTHER)
|
assert response.status_code == int(HTTPStatus.SEE_OTHER)
|
||||||
|
db.refresh(user)
|
||||||
assert user.LangPreference == "de"
|
assert user.LangPreference == "de"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import pytest
|
import pytest
|
||||||
from sqlalchemy.exc import IntegrityError
|
from sqlalchemy.exc import IntegrityError, SAWarning
|
||||||
|
|
||||||
from aurweb import db, time
|
from aurweb import db, time
|
||||||
from aurweb.db import create, rollback
|
from aurweb.db import create, rollback
|
||||||
|
@ -109,7 +109,7 @@ def test_voteinfo_null_submitter_raises(user: User):
|
||||||
|
|
||||||
|
|
||||||
def test_voteinfo_null_agenda_raises(user: User):
|
def test_voteinfo_null_agenda_raises(user: User):
|
||||||
with pytest.raises(IntegrityError):
|
with pytest.raises(IntegrityError), pytest.warns(SAWarning):
|
||||||
with db.begin():
|
with db.begin():
|
||||||
create(
|
create(
|
||||||
VoteInfo,
|
VoteInfo,
|
||||||
|
@ -123,7 +123,7 @@ def test_voteinfo_null_agenda_raises(user: User):
|
||||||
|
|
||||||
|
|
||||||
def test_voteinfo_null_user_raises(user: User):
|
def test_voteinfo_null_user_raises(user: User):
|
||||||
with pytest.raises(IntegrityError):
|
with pytest.raises(IntegrityError), pytest.warns(SAWarning):
|
||||||
with db.begin():
|
with db.begin():
|
||||||
create(
|
create(
|
||||||
VoteInfo,
|
VoteInfo,
|
||||||
|
@ -137,7 +137,7 @@ def test_voteinfo_null_user_raises(user: User):
|
||||||
|
|
||||||
|
|
||||||
def test_voteinfo_null_submitted_raises(user: User):
|
def test_voteinfo_null_submitted_raises(user: User):
|
||||||
with pytest.raises(IntegrityError):
|
with pytest.raises(IntegrityError), pytest.warns(SAWarning):
|
||||||
with db.begin():
|
with db.begin():
|
||||||
create(
|
create(
|
||||||
VoteInfo,
|
VoteInfo,
|
||||||
|
@ -151,7 +151,7 @@ def test_voteinfo_null_submitted_raises(user: User):
|
||||||
|
|
||||||
|
|
||||||
def test_voteinfo_null_end_raises(user: User):
|
def test_voteinfo_null_end_raises(user: User):
|
||||||
with pytest.raises(IntegrityError):
|
with pytest.raises(IntegrityError), pytest.warns(SAWarning):
|
||||||
with db.begin():
|
with db.begin():
|
||||||
create(
|
create(
|
||||||
VoteInfo,
|
VoteInfo,
|
||||||
|
|
Loading…
Add table
Reference in a new issue