Compare commits
No commits in common. "c6e82f292d6f5570e971f73a220e891e9c968391" and "083b588289fa6f49b5ff5a7d4220878d84fc94c5" have entirely different histories.
c6e82f292d
...
083b588289
115
alembic.ini
115
alembic.ini
@ -1,115 +0,0 @@
|
|||||||
# A generic, single database configuration.
|
|
||||||
|
|
||||||
[alembic]
|
|
||||||
# path to migration scripts.
|
|
||||||
# Use forward slashes (/) also on windows to provide an os agnostic path
|
|
||||||
script_location = lkeep/database/alembic
|
|
||||||
|
|
||||||
# template used to generate migration file names; The default value is %%(rev)s_%%(slug)s
|
|
||||||
# Uncomment the line below if you want the files to be prepended with date and time
|
|
||||||
file_template = %%(year)d_%%(month).2d_%%(day).2d_%%(hour).2d%%(minute).2d-%%(rev)s_%%(slug)s
|
|
||||||
|
|
||||||
# sys.path path, will be prepended to sys.path if present.
|
|
||||||
# defaults to the current working directory.
|
|
||||||
prepend_sys_path = .
|
|
||||||
|
|
||||||
# timezone to use when rendering the date within the migration file
|
|
||||||
# as well as the filename.
|
|
||||||
# If specified, requires the python>=3.9 or backports.zoneinfo library.
|
|
||||||
# Any required deps can installed by adding `alembic[tz]` to the pip requirements
|
|
||||||
# string value is passed to ZoneInfo()
|
|
||||||
# leave blank for localtime
|
|
||||||
# timezone =
|
|
||||||
|
|
||||||
# max length of characters to apply to the "slug" field
|
|
||||||
# truncate_slug_length = 40
|
|
||||||
|
|
||||||
# set to 'true' to run the environment during
|
|
||||||
# the 'revision' command, regardless of autogenerate
|
|
||||||
# revision_environment = false
|
|
||||||
|
|
||||||
# set to 'true' to allow .pyc and .pyo files without
|
|
||||||
# a source .py file to be detected as revisions in the
|
|
||||||
# versions/ directory
|
|
||||||
# sourceless = false
|
|
||||||
|
|
||||||
# version location specification; This defaults
|
|
||||||
# to lkeep/database/alembic/versions. When using multiple version
|
|
||||||
# directories, initial revisions must be specified with --version-path.
|
|
||||||
# The path separator used here should be the separator specified by "version_path_separator" below.
|
|
||||||
# version_locations = %(here)s/bar:%(here)s/bat:lkeep/database/alembic/versions
|
|
||||||
|
|
||||||
# version path separator; As mentioned above, this is the character used to split
|
|
||||||
# version_locations. The default within new alembic.ini files is "os", which uses os.pathsep.
|
|
||||||
# If this key is omitted entirely, it falls back to the legacy behavior of splitting on spaces and/or commas.
|
|
||||||
# Valid values for version_path_separator are:
|
|
||||||
#
|
|
||||||
# version_path_separator = :
|
|
||||||
# version_path_separator = ;
|
|
||||||
# version_path_separator = space
|
|
||||||
# version_path_separator = newline
|
|
||||||
version_path_separator = os # Use os.pathsep. Default configuration used for new projects.
|
|
||||||
|
|
||||||
# set to 'true' to search source files recursively
|
|
||||||
# in each "version_locations" directory
|
|
||||||
# new in Alembic version 1.10
|
|
||||||
# recursive_version_locations = false
|
|
||||||
|
|
||||||
# the output encoding used when revision files
|
|
||||||
# are written from script.py.mako
|
|
||||||
# output_encoding = utf-8
|
|
||||||
|
|
||||||
# sqlalchemy.url = driver://user:pass@localhost/dbname
|
|
||||||
|
|
||||||
|
|
||||||
[post_write_hooks]
|
|
||||||
# post_write_hooks defines scripts or Python functions that are run
|
|
||||||
# on newly generated revision scripts. See the documentation for further
|
|
||||||
# detail and examples
|
|
||||||
|
|
||||||
# format using "black" - use the console_scripts runner, against the "black" entrypoint
|
|
||||||
# hooks = black
|
|
||||||
# black.type = console_scripts
|
|
||||||
# black.entrypoint = black
|
|
||||||
# black.options = -l 79 REVISION_SCRIPT_FILENAME
|
|
||||||
|
|
||||||
# lint with attempts to fix using "ruff" - use the exec runner, execute a binary
|
|
||||||
hooks = ruff
|
|
||||||
ruff.type = exec
|
|
||||||
ruff.executable = poetry
|
|
||||||
ruff.options = run ruff format REVISION_SCRIPT_FILENAME
|
|
||||||
|
|
||||||
# Logging configuration
|
|
||||||
[loggers]
|
|
||||||
keys = root,sqlalchemy,alembic
|
|
||||||
|
|
||||||
[handlers]
|
|
||||||
keys = console
|
|
||||||
|
|
||||||
[formatters]
|
|
||||||
keys = generic
|
|
||||||
|
|
||||||
[logger_root]
|
|
||||||
level = WARNING
|
|
||||||
handlers = console
|
|
||||||
qualname =
|
|
||||||
|
|
||||||
[logger_sqlalchemy]
|
|
||||||
level = WARNING
|
|
||||||
handlers =
|
|
||||||
qualname = sqlalchemy.engine
|
|
||||||
|
|
||||||
[logger_alembic]
|
|
||||||
level = INFO
|
|
||||||
handlers =
|
|
||||||
qualname = alembic
|
|
||||||
|
|
||||||
[handler_console]
|
|
||||||
class = StreamHandler
|
|
||||||
args = (sys.stderr,)
|
|
||||||
level = NOTSET
|
|
||||||
formatter = generic
|
|
||||||
|
|
||||||
[formatter_generic]
|
|
||||||
format = %(levelname)-5.5s [%(name)s] %(message)s
|
|
||||||
datefmt = %H:%M:%S
|
|
@ -1,7 +0,0 @@
|
|||||||
"""
|
|
||||||
Проект: Lkeep
|
|
||||||
Автор: Иван Ашихмин
|
|
||||||
Год: 2025
|
|
||||||
Специально для проекта "Код на салфетке"
|
|
||||||
https://pressanybutton.ru/category/servis-na-fastapi/
|
|
||||||
"""
|
|
@ -1,7 +0,0 @@
|
|||||||
"""
|
|
||||||
Проект: Lkeep
|
|
||||||
Автор: Иван Ашихмин
|
|
||||||
Год: 2025
|
|
||||||
Специально для проекта "Код на салфетке"
|
|
||||||
https://pressanybutton.ru/category/servis-na-fastapi/
|
|
||||||
"""
|
|
@ -1,11 +1,3 @@
|
|||||||
"""
|
|
||||||
Проект: Lkeep
|
|
||||||
Автор: Иван Ашихмин
|
|
||||||
Год: 2025
|
|
||||||
Специально для проекта "Код на салфетке"
|
|
||||||
https://pressanybutton.ru/category/servis-na-fastapi/
|
|
||||||
"""
|
|
||||||
|
|
||||||
from pydantic import SecretStr
|
from pydantic import SecretStr
|
||||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||||
|
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
"""
|
|
||||||
Проект: Lkeep
|
|
||||||
Автор: Иван Ашихмин
|
|
||||||
Год: 2025
|
|
||||||
Специально для проекта "Код на салфетке"
|
|
||||||
https://pressanybutton.ru/category/servis-na-fastapi/
|
|
||||||
"""
|
|
@ -1 +0,0 @@
|
|||||||
Generic single-database configuration with an async dbapi.
|
|
@ -1,92 +0,0 @@
|
|||||||
import asyncio
|
|
||||||
from logging.config import fileConfig
|
|
||||||
|
|
||||||
from alembic import context
|
|
||||||
from sqlalchemy import pool
|
|
||||||
from sqlalchemy.engine import Connection
|
|
||||||
from sqlalchemy.ext.asyncio import async_engine_from_config
|
|
||||||
|
|
||||||
from lkeep.core.settings import settings
|
|
||||||
from lkeep.database.models import Base
|
|
||||||
|
|
||||||
# this is the Alembic Config object, which provides
|
|
||||||
# access to the values within the .ini file in use.
|
|
||||||
config = context.config
|
|
||||||
config.set_main_option("sqlalchemy.url", settings.db_settings.db_url)
|
|
||||||
|
|
||||||
# Interpret the config file for Python logging.
|
|
||||||
# This line sets up loggers basically.
|
|
||||||
if config.config_file_name is not None:
|
|
||||||
fileConfig(config.config_file_name)
|
|
||||||
|
|
||||||
# add your model's MetaData object here
|
|
||||||
# for 'autogenerate' support
|
|
||||||
# from myapp import mymodel
|
|
||||||
# target_metadata = mymodel.Base.metadata
|
|
||||||
target_metadata = Base.metadata
|
|
||||||
|
|
||||||
# other values from the config, defined by the needs of env.py,
|
|
||||||
# can be acquired:
|
|
||||||
# my_important_option = config.get_main_option("my_important_option")
|
|
||||||
# ... etc.
|
|
||||||
|
|
||||||
|
|
||||||
def run_migrations_offline() -> None:
|
|
||||||
"""Run migrations in 'offline' mode.
|
|
||||||
|
|
||||||
This configures the context with just a URL
|
|
||||||
and not an Engine, though an Engine is acceptable
|
|
||||||
here as well. By skipping the Engine creation
|
|
||||||
we don't even need a DBAPI to be available.
|
|
||||||
|
|
||||||
Calls to context.execute() here emit the given string to the
|
|
||||||
script output.
|
|
||||||
|
|
||||||
"""
|
|
||||||
url = config.get_main_option("sqlalchemy.url")
|
|
||||||
context.configure(
|
|
||||||
url=url,
|
|
||||||
target_metadata=target_metadata,
|
|
||||||
literal_binds=True,
|
|
||||||
dialect_opts={"paramstyle": "named"},
|
|
||||||
)
|
|
||||||
|
|
||||||
with context.begin_transaction():
|
|
||||||
context.run_migrations()
|
|
||||||
|
|
||||||
|
|
||||||
def do_run_migrations(connection: Connection) -> None:
|
|
||||||
context.configure(connection=connection, target_metadata=target_metadata)
|
|
||||||
|
|
||||||
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.",
|
|
||||||
poolclass=pool.NullPool,
|
|
||||||
)
|
|
||||||
|
|
||||||
async with connectable.connect() as connection:
|
|
||||||
await connection.run_sync(do_run_migrations)
|
|
||||||
|
|
||||||
await connectable.dispose()
|
|
||||||
|
|
||||||
|
|
||||||
def run_migrations_online() -> None:
|
|
||||||
"""Run migrations in 'online' mode."""
|
|
||||||
|
|
||||||
asyncio.run(run_async_migrations())
|
|
||||||
|
|
||||||
|
|
||||||
if context.is_offline_mode():
|
|
||||||
run_migrations_offline()
|
|
||||||
else:
|
|
||||||
run_migrations_online()
|
|
@ -1,26 +0,0 @@
|
|||||||
"""${message}
|
|
||||||
|
|
||||||
Revision ID: ${up_revision}
|
|
||||||
Revises: ${down_revision | comma,n}
|
|
||||||
Create Date: ${create_date}
|
|
||||||
|
|
||||||
"""
|
|
||||||
from typing import Sequence, Union
|
|
||||||
|
|
||||||
from alembic import op
|
|
||||||
import sqlalchemy as sa
|
|
||||||
${imports if imports else ""}
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
|
||||||
revision: str = ${repr(up_revision)}
|
|
||||||
down_revision: Union[str, None] = ${repr(down_revision)}
|
|
||||||
branch_labels: Union[str, Sequence[str], None] = ${repr(branch_labels)}
|
|
||||||
depends_on: Union[str, Sequence[str], None] = ${repr(depends_on)}
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade() -> None:
|
|
||||||
${upgrades if upgrades else "pass"}
|
|
||||||
|
|
||||||
|
|
||||||
def downgrade() -> None:
|
|
||||||
${downgrades if downgrades else "pass"}
|
|
@ -1,52 +0,0 @@
|
|||||||
"""Create User Table
|
|
||||||
|
|
||||||
Revision ID: ccf7560dd457
|
|
||||||
Revises:
|
|
||||||
Create Date: 2025-01-10 17:06:05.585011
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
from collections.abc import Sequence
|
|
||||||
|
|
||||||
import sqlalchemy as sa
|
|
||||||
from alembic import op
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
|
||||||
revision: str = "ccf7560dd457"
|
|
||||||
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! ###
|
|
||||||
op.create_table(
|
|
||||||
"user",
|
|
||||||
sa.Column("email", sa.String(length=100), nullable=False),
|
|
||||||
sa.Column("hashed_password", sa.Text(), nullable=False),
|
|
||||||
sa.Column("is_active", sa.Boolean(), nullable=False),
|
|
||||||
sa.Column("is_superuser", sa.Boolean(), nullable=False),
|
|
||||||
sa.Column("is_verified", sa.Boolean(), nullable=False),
|
|
||||||
sa.Column("id", sa.UUID(), nullable=False),
|
|
||||||
sa.Column(
|
|
||||||
"created_at",
|
|
||||||
sa.DateTime(timezone=True),
|
|
||||||
server_default=sa.text("now()"),
|
|
||||||
nullable=False,
|
|
||||||
),
|
|
||||||
sa.Column(
|
|
||||||
"updated_at",
|
|
||||||
sa.DateTime(timezone=True),
|
|
||||||
server_default=sa.text("now()"),
|
|
||||||
nullable=False,
|
|
||||||
),
|
|
||||||
sa.PrimaryKeyConstraint("id"),
|
|
||||||
sa.UniqueConstraint("email"),
|
|
||||||
)
|
|
||||||
# ### end Alembic commands ###
|
|
||||||
|
|
||||||
|
|
||||||
def downgrade() -> None:
|
|
||||||
# ### commands auto generated by Alembic - please adjust! ###
|
|
||||||
op.drop_table("user")
|
|
||||||
# ### end Alembic commands ###
|
|
@ -1,7 +0,0 @@
|
|||||||
"""
|
|
||||||
Проект: Lkeep
|
|
||||||
Автор: Иван Ашихмин
|
|
||||||
Год: 2025
|
|
||||||
Специально для проекта "Код на салфетке"
|
|
||||||
https://pressanybutton.ru/category/servis-na-fastapi/
|
|
||||||
"""
|
|
@ -1,23 +0,0 @@
|
|||||||
"""
|
|
||||||
Проект: Lkeep
|
|
||||||
Автор: Иван Ашихмин
|
|
||||||
Год: 2025
|
|
||||||
Специально для проекта "Код на салфетке"
|
|
||||||
https://pressanybutton.ru/category/servis-na-fastapi/
|
|
||||||
"""
|
|
||||||
|
|
||||||
import uuid
|
|
||||||
|
|
||||||
from sqlalchemy import UUID
|
|
||||||
from sqlalchemy.orm import Mapped, mapped_column
|
|
||||||
|
|
||||||
|
|
||||||
class IDMixin:
|
|
||||||
"""
|
|
||||||
Класс-миксин для добавления уникального идентификатора к объектам.
|
|
||||||
|
|
||||||
:ivar id: Уникальный идентификатор объекта.
|
|
||||||
:type id: uuid.UUID
|
|
||||||
"""
|
|
||||||
|
|
||||||
id: Mapped[uuid.UUID] = mapped_column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
|
|
@ -1,53 +0,0 @@
|
|||||||
"""
|
|
||||||
Проект: Lkeep
|
|
||||||
Автор: Иван Ашихмин
|
|
||||||
Год: 2025
|
|
||||||
Специально для проекта "Код на салфетке"
|
|
||||||
https://pressanybutton.ru/category/servis-na-fastapi/
|
|
||||||
"""
|
|
||||||
|
|
||||||
import datetime
|
|
||||||
|
|
||||||
from sqlalchemy import DateTime, func
|
|
||||||
from sqlalchemy.orm import Mapped, mapped_column
|
|
||||||
|
|
||||||
|
|
||||||
class CreatedAtMixin:
|
|
||||||
"""
|
|
||||||
Класс-миксин, добавляющий атрибут created_at для отслеживания времени создания объектов.
|
|
||||||
|
|
||||||
:ivar created_at: Время создания объекта.
|
|
||||||
:type created_at: datetime.datetime
|
|
||||||
"""
|
|
||||||
|
|
||||||
created_at: Mapped[datetime.datetime] = mapped_column(
|
|
||||||
DateTime(timezone=True),
|
|
||||||
server_default=func.now(),
|
|
||||||
default=datetime.datetime.now,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class UpdatedAtMixin:
|
|
||||||
"""
|
|
||||||
Класс-миксин, добавляющий атрибут `updated_at`, который автоматически обновляется при каждом изменении записи.
|
|
||||||
|
|
||||||
:ivar updated_at: Время последнего обновления записи.
|
|
||||||
:type updated_at: Mapped[datetime.datetime]
|
|
||||||
"""
|
|
||||||
|
|
||||||
updated_at: Mapped[datetime.datetime] = mapped_column(
|
|
||||||
DateTime(timezone=True), server_default=func.now(), onupdate=func.now()
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class TimestampsMixin(CreatedAtMixin, UpdatedAtMixin):
|
|
||||||
"""
|
|
||||||
Класс-миксин для добавления временных меток создания и обновления в классы.
|
|
||||||
|
|
||||||
:ivar created_at: Время создания записи.
|
|
||||||
:type created_at: datetime.datetime
|
|
||||||
:ivar updated_at: Время последнего обновления записи.
|
|
||||||
:type updated_at: datetime.datetime
|
|
||||||
"""
|
|
||||||
|
|
||||||
pass
|
|
@ -1,13 +0,0 @@
|
|||||||
"""
|
|
||||||
Проект: Lkeep
|
|
||||||
Автор: Иван Ашихмин
|
|
||||||
Год: 2025
|
|
||||||
Специально для проекта "Код на салфетке"
|
|
||||||
https://pressanybutton.ru/category/servis-na-fastapi/
|
|
||||||
"""
|
|
||||||
|
|
||||||
from lkeep.database.models.base import Base
|
|
||||||
from lkeep.database.models.user import User
|
|
||||||
|
|
||||||
|
|
||||||
__all__ = ("Base", "User")
|
|
@ -1,25 +0,0 @@
|
|||||||
"""
|
|
||||||
Проект: Lkeep
|
|
||||||
Автор: Иван Ашихмин
|
|
||||||
Год: 2025
|
|
||||||
Специально для проекта "Код на салфетке"
|
|
||||||
https://pressanybutton.ru/category/servis-na-fastapi/
|
|
||||||
"""
|
|
||||||
|
|
||||||
from sqlalchemy.orm import DeclarativeBase, declared_attr
|
|
||||||
|
|
||||||
|
|
||||||
class Base(DeclarativeBase):
|
|
||||||
"""
|
|
||||||
Базовый класс для моделей ORM, использующих SQLAlchemy.
|
|
||||||
"""
|
|
||||||
|
|
||||||
@declared_attr.directive
|
|
||||||
def __tablename__(cls) -> str:
|
|
||||||
"""
|
|
||||||
Определяет название таблицы в базе данных на основе имени класса.
|
|
||||||
|
|
||||||
:return: Название таблицы в формате snake_case.
|
|
||||||
:rtype: str
|
|
||||||
"""
|
|
||||||
return cls.__name__.lower()
|
|
@ -1,37 +0,0 @@
|
|||||||
"""
|
|
||||||
Проект: Lkeep
|
|
||||||
Автор: Иван Ашихмин
|
|
||||||
Год: 2025
|
|
||||||
Специально для проекта "Код на салфетке"
|
|
||||||
https://pressanybutton.ru/category/servis-na-fastapi/
|
|
||||||
"""
|
|
||||||
|
|
||||||
from sqlalchemy import Boolean, String, Text
|
|
||||||
from sqlalchemy.orm import Mapped, mapped_column
|
|
||||||
|
|
||||||
from lkeep.database.mixins.id_mixins import IDMixin
|
|
||||||
from lkeep.database.mixins.timestamp_mixins import TimestampsMixin
|
|
||||||
from lkeep.database.models.base import Base
|
|
||||||
|
|
||||||
|
|
||||||
class User(IDMixin, TimestampsMixin, Base):
|
|
||||||
"""
|
|
||||||
Класс User представляет пользователя в системе.
|
|
||||||
|
|
||||||
:ivar email: Email адрес пользователя.
|
|
||||||
:type email: str
|
|
||||||
:ivar hashed_password: Хэшированный пароль пользователя.
|
|
||||||
:type hashed_password: str
|
|
||||||
:ivar is_active: Флаг активности пользователя (True или False).
|
|
||||||
:type is_active: bool
|
|
||||||
:ivar is_superuser: Флаг суперпользователя (True или False).
|
|
||||||
:type is_superuser: bool
|
|
||||||
:ivar is_verified: Флаг подтверждения аккаунта (True или False).
|
|
||||||
:type is_verified: bool
|
|
||||||
"""
|
|
||||||
|
|
||||||
email: Mapped[str] = mapped_column(String(100), unique=True, nullable=False)
|
|
||||||
hashed_password: Mapped[str] = mapped_column(Text, unique=False, nullable=False)
|
|
||||||
is_active: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False)
|
|
||||||
is_superuser: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False)
|
|
||||||
is_verified: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False)
|
|
@ -1,11 +1,3 @@
|
|||||||
"""
|
|
||||||
Проект: Lkeep
|
|
||||||
Автор: Иван Ашихмин
|
|
||||||
Год: 2025
|
|
||||||
Специально для проекта "Код на салфетке"
|
|
||||||
https://pressanybutton.ru/category/servis-na-fastapi/
|
|
||||||
"""
|
|
||||||
|
|
||||||
import uvicorn
|
import uvicorn
|
||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
|
|
||||||
|
70
poetry.lock
generated
70
poetry.lock
generated
@ -1,25 +1,5 @@
|
|||||||
# This file is automatically @generated by Poetry 2.0.0 and should not be changed by hand.
|
# This file is automatically @generated by Poetry 2.0.0 and should not be changed by hand.
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "alembic"
|
|
||||||
version = "1.14.0"
|
|
||||||
description = "A database migration tool for SQLAlchemy."
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=3.8"
|
|
||||||
groups = ["main"]
|
|
||||||
files = [
|
|
||||||
{file = "alembic-1.14.0-py3-none-any.whl", hash = "sha256:99bd884ca390466db5e27ffccff1d179ec5c05c965cfefc0607e69f9e411cb25"},
|
|
||||||
{file = "alembic-1.14.0.tar.gz", hash = "sha256:b00892b53b3642d0b8dbedba234dbf1924b69be83a9a769d5a624b01094e304b"},
|
|
||||||
]
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
Mako = "*"
|
|
||||||
SQLAlchemy = ">=1.3.0"
|
|
||||||
typing-extensions = ">=4"
|
|
||||||
|
|
||||||
[package.extras]
|
|
||||||
tz = ["backports.zoneinfo"]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "annotated-types"
|
name = "annotated-types"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
@ -534,26 +514,6 @@ MarkupSafe = ">=2.0"
|
|||||||
[package.extras]
|
[package.extras]
|
||||||
i18n = ["Babel (>=2.7)"]
|
i18n = ["Babel (>=2.7)"]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "mako"
|
|
||||||
version = "1.3.8"
|
|
||||||
description = "A super-fast templating language that borrows the best ideas from the existing templating languages."
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=3.8"
|
|
||||||
groups = ["main"]
|
|
||||||
files = [
|
|
||||||
{file = "Mako-1.3.8-py3-none-any.whl", hash = "sha256:42f48953c7eb91332040ff567eb7eea69b22e7a4affbc5ba8e845e8f730f6627"},
|
|
||||||
{file = "mako-1.3.8.tar.gz", hash = "sha256:577b97e414580d3e088d47c2dbbe9594aa7a5146ed2875d4dfa9075af2dd3cc8"},
|
|
||||||
]
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
MarkupSafe = ">=0.9.2"
|
|
||||||
|
|
||||||
[package.extras]
|
|
||||||
babel = ["Babel"]
|
|
||||||
lingua = ["lingua"]
|
|
||||||
testing = ["pytest"]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "markdown-it-py"
|
name = "markdown-it-py"
|
||||||
version = "3.0.0"
|
version = "3.0.0"
|
||||||
@ -1006,34 +966,6 @@ click = ">=8.1.7"
|
|||||||
rich = ">=13.7.1"
|
rich = ">=13.7.1"
|
||||||
typing-extensions = ">=4.12.2"
|
typing-extensions = ">=4.12.2"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "ruff"
|
|
||||||
version = "0.9.0"
|
|
||||||
description = "An extremely fast Python linter and code formatter, written in Rust."
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=3.7"
|
|
||||||
groups = ["main"]
|
|
||||||
files = [
|
|
||||||
{file = "ruff-0.9.0-py3-none-linux_armv6l.whl", hash = "sha256:949b3513f931741e006cf267bf89611edff04e1f012013424022add3ce78f319"},
|
|
||||||
{file = "ruff-0.9.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:99fbcb8c7fe94ae1e462ab2a1ef17cb20b25fb6438b9f198b1bcf5207a0a7916"},
|
|
||||||
{file = "ruff-0.9.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:0b022afd8eb0fcfce1e0adec84322abf4d6ce3cd285b3b99c4f17aae7decf749"},
|
|
||||||
{file = "ruff-0.9.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:336567ce92c9ca8ec62780d07b5fa11fbc881dc7bb40958f93a7d621e7ab4589"},
|
|
||||||
{file = "ruff-0.9.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d338336c44bda602dc8e8766836ac0441e5b0dfeac3af1bd311a97ebaf087a75"},
|
|
||||||
{file = "ruff-0.9.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d9b3ececf523d733e90b540e7afcc0494189e8999847f8855747acd5a9a8c45f"},
|
|
||||||
{file = "ruff-0.9.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:a11c0872a31232e473e2e0e2107f3d294dbadd2f83fb281c3eb1c22a24866924"},
|
|
||||||
{file = "ruff-0.9.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b5fd06220c17a9cc0dc7fc6552f2ac4db74e8e8bff9c401d160ac59d00566f54"},
|
|
||||||
{file = "ruff-0.9.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0457e775c74bf3976243f910805242b7dcd389e1d440deccbd1194ca17a5728c"},
|
|
||||||
{file = "ruff-0.9.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05415599bbcb318f730ea1b46a39e4fbf71f6a63fdbfa1dda92efb55f19d7ecf"},
|
|
||||||
{file = "ruff-0.9.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:fbf9864b009e43cfc1c8bed1a6a4c529156913105780af4141ca4342148517f5"},
|
|
||||||
{file = "ruff-0.9.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:37b3da222b12e2bb2ce628e02586ab4846b1ed7f31f42a5a0683b213453b2d49"},
|
|
||||||
{file = "ruff-0.9.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:733c0fcf2eb0c90055100b4ed1af9c9d87305b901a8feb6a0451fa53ed88199d"},
|
|
||||||
{file = "ruff-0.9.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:8221a454bfe5ccdf8017512fd6bb60e6ec30f9ea252b8a80e5b73619f6c3cefd"},
|
|
||||||
{file = "ruff-0.9.0-py3-none-win32.whl", hash = "sha256:d345f2178afd192c7991ddee59155c58145e12ad81310b509bd2e25c5b0247b3"},
|
|
||||||
{file = "ruff-0.9.0-py3-none-win_amd64.whl", hash = "sha256:0cbc0905d94d21305872f7f8224e30f4bbcd532bc21b2225b2446d8fc7220d19"},
|
|
||||||
{file = "ruff-0.9.0-py3-none-win_arm64.whl", hash = "sha256:7b1148771c6ca88f820d761350a053a5794bc58e0867739ea93eb5e41ad978cd"},
|
|
||||||
{file = "ruff-0.9.0.tar.gz", hash = "sha256:143f68fa5560ecf10fc49878b73cee3eab98b777fcf43b0e62d43d42f5ef9d8b"},
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "shellingham"
|
name = "shellingham"
|
||||||
version = "1.5.4"
|
version = "1.5.4"
|
||||||
@ -1426,4 +1358,4 @@ files = [
|
|||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.1"
|
lock-version = "2.1"
|
||||||
python-versions = ">=3.12"
|
python-versions = ">=3.12"
|
||||||
content-hash = "b171a7f89cc3ee2207778b1e189fbb1821fccda26de00d0181156d0e183a5b75"
|
content-hash = "513258d12f2f7d29fd9ea86316d77864389435c71203627ef001f28141d3bc76"
|
||||||
|
@ -13,9 +13,7 @@ dependencies = [
|
|||||||
"pre-commit (>=4.0.1,<5.0.0)",
|
"pre-commit (>=4.0.1,<5.0.0)",
|
||||||
"sqlalchemy (>=2.0.37,<3.0.0)",
|
"sqlalchemy (>=2.0.37,<3.0.0)",
|
||||||
"asyncpg (>=0.30.0,<0.31.0)",
|
"asyncpg (>=0.30.0,<0.31.0)",
|
||||||
"pydantic-settings (>=2.7.1,<3.0.0)",
|
"pydantic-settings (>=2.7.1,<3.0.0)"
|
||||||
"alembic (>=1.14.0,<2.0.0)",
|
|
||||||
"ruff (>=0.9.0,<0.10.0)",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user