diff --git a/pyproject.toml b/pyproject.toml index 38a6d1a..c29afc2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,6 +21,14 @@ dependencies = [ "torchvision>=0.24.1", "types-requests>=2.32.4.20250913", "types-markdown>=3.10.0.20251106", + "sqlalchemy>=2.0.44", + "inject>=5.3.0", + "aiofiles>=25.1.0", + "botocore>=1.42.9", + "types-aiofiles>=25.1.0.20251011", + "betterconf>=4.5.0", + "dataclasses-ujson>=0.0.34", + "asyncpg>=0.31.0", ] [project.optional-dependencies] @@ -49,7 +57,3 @@ name = "pytorch-cpu" url = "https://download.pytorch.org/whl/cpu" explicit = true -[tool.uv.workspace] -members = [ - "kivy", -] diff --git a/server/config/__init__.py b/server/config/__init__.py new file mode 100644 index 0000000..2ed1a49 --- /dev/null +++ b/server/config/__init__.py @@ -0,0 +1,41 @@ +"""Config for application""" + +from functools import lru_cache + +from betterconf import betterconf, field +from betterconf.caster import to_bool, to_int, to_list + + +@betterconf +class AppConfig: + # pylint: disable=R0903 + """ + Class of configuration the application + """ + + app_debug: bool = field("APP_DEBUG", default=False, caster=to_bool) + app_origin: list = field("APP_ORIGIN", default=[], caster=to_list) + app_host: str = field("APP_HOST", default="0.0.0.0") + app_port: int = field("APP_PORT", default=8000, caster=to_int) + app_public_url: str = field("APP_PUBLIC_URL", default="http://127.0.0.1:8000") + + sentry_dns: str = field("SENTRY_DNS", default="") + log_level: str = field("LOG_LEVEL", "INFO") + + db_uri: str = field( + "DB_URI", "postgresql+asyncpg://svcuser:svcpass@localhost:5432/svc" + ) + db_pass_salt: str = field("DB_PASS_SALT", "") + db_search_path: str = field("DB_SEARCH_PATH", "public") + + fs_local_mount_dir: str = field("FS_LOCAL_MOUNT_DIR", default="./tmp/files") + fs_s3_bucket: str = field("FS_S3_BUCKET", "") + fs_s3_access_key_id: str = field("FS_ACCESS_KEY_ID", "") + fs_s3_access_key: str = field("FS_SECRET_ACCESS_KEY", "") + fs_s3_endpoint: str = field("FS_S3_ENDPOINT", "") + + +@lru_cache +def get_app_config() -> AppConfig: + # pylint: disable=C0116 + return AppConfig() diff --git a/server/services/__init__.py b/server/infra/__init__.py similarity index 100% rename from server/services/__init__.py rename to server/infra/__init__.py diff --git a/server/infra/cache.py b/server/infra/cache.py new file mode 100644 index 0000000..14e6aae --- /dev/null +++ b/server/infra/cache.py @@ -0,0 +1,33 @@ +from abc import ABCMeta, abstractmethod +from typing import Optional + + +class CacheRepository(metaclass=ABCMeta): + @abstractmethod + async def get(self, key: str) -> Optional[str]: + pass + + @abstractmethod + async def set(self, key: str, data: str, _exp_min: Optional[int] = None): + pass + + @abstractmethod + async def delete(self, key: str): + pass + + +# TODO: сделать через общий кеш, например, redis. Работу с редис вынести в infra +class LocalCacheRepository(CacheRepository): + _data: dict[str, str] + + def __init__(self) -> None: + self._data = {} + + async def get(self, key: str) -> Optional[str]: + return self._data.get(key) + + async def set(self, key: str, data: str, _exp_min: Optional[int] = None): + self._data[key] = data + + async def delete(self, key: str): + del self._data[key] diff --git a/server/infra/db/__init__.py b/server/infra/db/__init__.py new file mode 100644 index 0000000..5771c10 --- /dev/null +++ b/server/infra/db/__init__.py @@ -0,0 +1,12 @@ +from server.infra.db.abc import AbstractDB, AbstractSession, ExecuteFun +from server.infra.db.mock import MockDB, MockSession +from server.infra.db.pg import AsyncDB + +__all__ = [ + "AsyncDB", + "AbstractDB", + "ExecuteFun", + "AbstractSession", + "MockDB", + "MockSession", +] diff --git a/server/infra/db/abc.py b/server/infra/db/abc.py new file mode 100644 index 0000000..1c3f0e5 --- /dev/null +++ b/server/infra/db/abc.py @@ -0,0 +1,41 @@ +"""Abstract realiztion for DB""" + +from typing import Any, AsyncContextManager, Awaitable, Callable, TypeAlias + +from server.config import AppConfig + +ExecuteFun: TypeAlias = Callable[[Any], Awaitable[None]] + + +class ConnectError(Exception): + """Custom error wor failed connections""" + + +class AbstractSession: + async def __aenter__(self) -> "AbstractSession": + raise NotImplementedError + + async def __aexit__(self, exc_type, exc, tb): + raise NotImplementedError + + def begin(self) -> AsyncContextManager: + raise NotImplementedError + + async def execute(self, data: Any): + raise NotImplementedError + + async def commit(self): + raise NotImplementedError + + +class AbstractDB: + """Abstract realiztion for DB""" + + def __init__(self, cnf: AppConfig): + raise NotImplementedError + + def session_master(self) -> AbstractSession: + raise NotImplementedError + + def session_slave(self) -> AbstractSession: + raise NotImplementedError diff --git a/server/infra/db/db_mapper.py b/server/infra/db/db_mapper.py new file mode 100644 index 0000000..37eec4a --- /dev/null +++ b/server/infra/db/db_mapper.py @@ -0,0 +1,11 @@ +from typing import Type, TypeVar + +from sqlalchemy.orm import registry + +mapper_registry = registry() + +DC = TypeVar("DC") + + +def dict_to_dataclass(data: dict, class_type: Type[DC]) -> DC: + return class_type(**data) diff --git a/server/infra/db/mock.py b/server/infra/db/mock.py new file mode 100644 index 0000000..2f8b334 --- /dev/null +++ b/server/infra/db/mock.py @@ -0,0 +1,45 @@ +from typing import Any, AsyncContextManager + +from server.config import AppConfig +from server.infra.db.abc import AbstractDB, AbstractSession + + +class MockBeginSession(AbstractSession): + async def __aenter__(self): + pass + + async def __aexit__(self, exc_type, exc, tb): + pass + + +class MockSession(AbstractSession): + async def __aenter__(self) -> "AbstractSession": + return self + + async def __aexit__(self, exc_type, exc, tb): + pass + + def begin(self) -> AsyncContextManager: + return MockBeginSession() + + async def execute(self, data: Any): + pass + + async def commit(self): + pass + + +class MockDB(AbstractDB): + """Mock realiztion for DB""" + + def __init__(self, cnf: AppConfig): + pass + + async def __aenter__(self): + pass + + async def __aenxit__(self, exc_type, exc, tb): + pass + + def session(self) -> MockSession: + return MockSession() diff --git a/server/infra/db/pg.py b/server/infra/db/pg.py new file mode 100644 index 0000000..3128a36 --- /dev/null +++ b/server/infra/db/pg.py @@ -0,0 +1,41 @@ +"""Postgres DB realization""" + +from sqlalchemy.ext import asyncio + +from server.config import AppConfig +from server.infra.db.abc import AbstractDB, ConnectError + + +class AsyncDB(AbstractDB): + engine: asyncio.AsyncEngine + async_session: asyncio.async_sessionmaker[asyncio.AsyncSession] + + def __init__(self, cnf: AppConfig): + con_arg = {} + if "postgresql+asyncpg" in str(cnf.db_uri): + con_arg = {"server_settings": {"search_path": cnf.db_search_path}} + self.engine = asyncio.create_async_engine( + str(cnf.db_uri), + echo=bool(cnf.app_debug), + connect_args=con_arg, + pool_recycle=1800, + ) + + # self.engine.execution_options(stream_results=True) + if self.engine is None: + raise ConnectError + session = asyncio.async_sessionmaker(self.engine, expire_on_commit=False) + if session is None: + raise ConnectError + self.async_session = session + + async def connect(self): + """connect with DB""" + pass + + @property + def session(self): + return asyncio.async_sessionmaker(self.engine, expire_on_commit=False) + + def new_session(self): + return asyncio.async_sessionmaker(self.engine, expire_on_commit=False)() diff --git a/server/infra/logger/__init__.py b/server/infra/logger/__init__.py new file mode 100644 index 0000000..233bba6 --- /dev/null +++ b/server/infra/logger/__init__.py @@ -0,0 +1,76 @@ +"""The logger configuration""" + +import logging +from logging import config as log_config + +from server import config + +cnf = config.get_app_config() + + +LOGGING_CONFIG = { + "version": 1, + "disable_existing_loggers": True, + "formatters": { + "standard": { + "use_colors": True, + "format": "%(filename)s:%(lineno)d -> %(asctime)s [%(levelname)s]: %(message)s", + }, + "uvicorn_default": { + "()": "uvicorn.logging.DefaultFormatter", + "format": "%(levelprefix)s %(message)s", + "use_colors": True, + }, + "uvicorn_access": { + "()": "uvicorn.logging.AccessFormatter", + "format": '%(levelprefix)s %(client_addr)s - "%(request_line)s" %(status_code)s', # noqa: E501 + }, + }, + "handlers": { + "default": { + "level": cnf.log_level, + "formatter": "standard", + "class": "logging.StreamHandler", + "stream": "ext://sys.stdout", + }, + "sentry": { + "level": "ERROR", + "class": "sentry_sdk.integrations.logging.EventHandler", + }, + "uvicorn_default": { + "level": "INFO", + "formatter": "uvicorn_default", + "class": "logging.StreamHandler", + "stream": "ext://sys.stdout", + }, + "uvicorn_access": { + "level": "INFO", + "formatter": "uvicorn_access", + "class": "logging.StreamHandler", + "stream": "ext://sys.stdout", + }, + }, + "loggers": { + "": {"handlers": ["default"], "level": cnf.log_level, "propagate": False}, + "uvicorn.access": { + "handlers": ["uvicorn_access"], + "level": "INFO", + "propagate": False, + }, + "uvicorn.error": { + "handlers": ["uvicorn_default"], + "level": "INFO", + "propagate": False, + }, + "uvicorn.asgi": { + "handlers": ["uvicorn_default"], + "level": "INFO", + "propagate": False, + }, + }, +} + + +def get_logger() -> logging.Logger: + log_config.dictConfig(LOGGING_CONFIG) + return logging.getLogger() diff --git a/server/infra/tools/__init__.py b/server/infra/tools/__init__.py new file mode 100644 index 0000000..62fbae8 --- /dev/null +++ b/server/infra/tools/__init__.py @@ -0,0 +1,21 @@ +from server.infra.tools.db.filter import ( + Filter, + FilterLeftField, + FilterQuery, + FilterSign, + data_by_filter, + indexes_by_id, + sqlalchemy_conditions, + sqlalchemy_restrictions, +) + +__all__ = [ + "FilterSign", + "FilterLeftField", + "Filter", + "FilterQuery", + "data_by_filter", + "sqlalchemy_conditions", + "indexes_by_id", + "sqlalchemy_restrictions", +] diff --git a/server/services/recognizer/domain.py b/server/infra/tools/db/__init__.py similarity index 100% rename from server/services/recognizer/domain.py rename to server/infra/tools/db/__init__.py diff --git a/server/infra/tools/db/filter.py b/server/infra/tools/db/filter.py new file mode 100644 index 0000000..3ac0498 --- /dev/null +++ b/server/infra/tools/db/filter.py @@ -0,0 +1,303 @@ +from copy import copy +from dataclasses import Field, asdict, dataclass +from enum import Enum +from typing import Any, ClassVar, Optional, Protocol, assert_never + +from sqlalchemy import Select, and_, or_ + + +class FilterSign(Enum): + NOT_EQ = "not_eq" + EQ = "eq" + LT = "lt" + LE = "le" + GT = "gt" + GE = "ge" + IS = "is" + IS_NOT = "is_not" + OR = "or" + AND = "and" + IN = "in" + + +class FilterLeftField(Protocol): + name: str + + +@dataclass(frozen=True) +class Filter: + right: Any + sign: FilterSign + left: Optional[FilterLeftField] = None + + @staticmethod + def not_eq(f1: Any, f2: Any): + return Filter(left=f1, right=f2, sign=FilterSign.NOT_EQ) + + @staticmethod + def eq(f1: Any, f2: Any): + return Filter(left=f1, right=f2, sign=FilterSign.EQ) + + @staticmethod + def lt(f1: Any, f2: Any): + return Filter(left=f1, right=f2, sign=FilterSign.LT) + + @staticmethod + def le(f1: Any, f2: Any): + return Filter(left=f1, right=f2, sign=FilterSign.LE) + + @staticmethod + def gt(f1: Any, f2: Any): + return Filter(left=f1, right=f2, sign=FilterSign.GT) + + @staticmethod + def ge(f1: Any, f2: Any): + return Filter(left=f1, right=f2, sign=FilterSign.GE) + + @staticmethod + def is_none(f1: Any): + return Filter(left=f1, right=None, sign=FilterSign.IS_NOT) + + @staticmethod + def is_not_none(f1: Any): + return Filter(left=f1, right=None, sign=FilterSign.IS) + + @staticmethod + def or_(f1: list["Filter"]): + return Filter(left=None, right=f1, sign=FilterSign.OR) + + @staticmethod + def in_(f1: Any, f2: list[Any]): + return Filter(left=f1, right=f2, sign=FilterSign.IN) + + +@dataclass +class RestrictionField: + field: Any + direction: str + + +@dataclass +class QueryRestriction: + filters: Optional[list[Filter]] = None + limit: Optional[int] = None + offset: Optional[int] = None + sort: Optional[list[RestrictionField]] = None + + +@dataclass(frozen=False) +class FilterQuery: + filters: list[Filter] + limit: Optional[int] = None + offset: Optional[int] = None + sort: Optional[list[RestrictionField]] = None + + @staticmethod + def mass_and(fields: list[object], values: list[Any]) -> "FilterQuery": + return FilterQuery( + filters=[Filter.eq(field, val) for field, val in zip(fields, values)] + ) + + @staticmethod + def mass_or(fields: list[object], values: list[Any]) -> "FilterQuery": + return FilterQuery( + filters=[ + Filter.or_( + [Filter.eq(field, val) for field, val in zip(fields, values)] + ) + ] + ) + + @staticmethod + def eq(field: object, value: Any) -> "FilterQuery": + return FilterQuery(filters=[Filter.eq(field, value)]) + + @staticmethod + def in_(field: object, value: list[Any]) -> "FilterQuery": + return FilterQuery(filters=[Filter.in_(field, value)]) + + def add_and(self, field: object, value: Any): + self.filters.append(Filter.eq(field, value)) + + def add_query_restistions(self, q_restriction: Optional[QueryRestriction] = None): + if not q_restriction: + return None + if q_restriction.limit: + self.limit = q_restriction.limit + if q_restriction.offset: + self.offset = q_restriction.offset + if q_restriction.sort: + self.sort = q_restriction.sort + if q_restriction.filters: + self.filters += q_restriction.filters + return None + + +class DataclassInstance(Protocol): + __dataclass_fields__: ClassVar[dict[str, Field[Any]]] + + +async def indexes_by_id( + input_data: list, values: list[str], id_name="id" +) -> Optional[list[int]]: + r_data: list[int] = [] + for i, _ in enumerate(input_data): + if getattr(input_data[i], id_name) in values: + r_data.append(i) + if not r_data: + return None + return r_data + + +def data_by_filter[T: DataclassInstance]( + input_data: list[T], q: FilterQuery +) -> list[T]: + # can't do query AND(OR() + AND()) + data: list[T] = [] + data_or: list[T] = [] + data_and: list[T] = [] + is_found = False + for d in input_data: + dict_class = asdict(d) + for f in q.filters: + if f.sign == FilterSign.OR: + for f_or in f.right: + data_or += data_by_filter(input_data, q=FilterQuery(filters=[f_or])) + continue + if f.sign == FilterSign.AND: + data_and += data_by_filter(input_data, q=FilterQuery(filters=f.right)) + continue + if f.left is None: + continue + if f.sign != FilterSign.IS and dict_class.get(f.left.name) is None: + break + if f.sign != FilterSign.IS_NOT and dict_class.get(f.left.name) is None: + break + match f.sign: + case FilterSign.NOT_EQ: + is_found = dict_class.get(f.left.name) != f.right + if is_found: + continue + break + case FilterSign.EQ: + is_found = dict_class.get(f.left.name) == f.right + if is_found: + continue + break + case FilterSign.LT: + is_found = dict_class.get(f.left.name) < f.right + if is_found: + continue + break + case FilterSign.LE: + is_found = dict_class.get(f.left.name) <= f.right + if is_found: + continue + break + case FilterSign.GT: + is_found = dict_class.get(f.left.name) > f.right + if is_found: + continue + break + case FilterSign.GE: + is_found = dict_class.get(f.left.name) >= f.right + if is_found: + continue + break + case FilterSign.IS: + is_found = dict_class.get(f.left.name) is None + if is_found: + continue + break + case FilterSign.IS_NOT: + is_found = dict_class.get(f.left.name) is not None + if is_found: + continue + break + case FilterSign.IN: + is_found = dict_class.get(f.left.name) in f.right + if is_found: + continue + break + case _ as arg: + assert_never(arg) + if is_found: + data.append(copy(d)) + if q.limit: + limit = q.limit + if limit > len(data) - 1: + limit = len(data) - 1 + return data[:limit] + if data_and: + if not data: + data = data_and + else: + data = list(set(data) & set(data_and)) + if data_or: + if not data: + data = data_or + else: + data = list(set(data) & set(data_or)) + return data + + +def sqlalchemy_conditions(q: FilterQuery): + conditions = [] + for f in q.filters: + if f.sign == FilterSign.OR: + conditions.append( + or_(*sqlalchemy_conditions(q=FilterQuery(filters=f.right))) + ) + continue + if f.sign == FilterSign.AND: + conditions.append( + and_(*sqlalchemy_conditions(q=FilterQuery(filters=f.right))) + ) + continue + if f.left is None: + continue + match f.sign: + case FilterSign.NOT_EQ: + conditions.append(f.left != f.right) + case FilterSign.EQ: + conditions.append(f.left == f.right) + case FilterSign.LT: + conditions.append(f.left < f.right) + case FilterSign.LE: + if f.left is None: + continue + conditions.append(f.left <= f.right) + case FilterSign.GT: + conditions.append(f.left > f.right) + case FilterSign.GE: + conditions.append(f.left >= f.right) + case FilterSign.IS: + conditions.append(f.left.is_(None)) # type: ignore + case FilterSign.IS_NOT: + conditions.append(f.left.is_not(None)) # type: ignore + case FilterSign.IN: + conditions.append(f.left.in_(f.right)) # type: ignore + case _ as arg: + assert_never(arg) + return conditions + + +def sqlalchemy_restrictions( + f: FilterQuery, q: Select, dict_to_sort: Optional[dict] = None +) -> Select: + if f.limit: + q = q.limit(f.limit) + if f.offset: + q = q.offset(f.offset) + if f.sort: + for s in f.sort: + field = s.field + if dict_to_sort and str(s.field) in dict_to_sort: + if s.direction == "desc": + q = q.order_by(dict_to_sort[str(s.field)].desc()) # type: ignore + continue + return q.order_by(dict_to_sort[str(s.field)]) # type: ignore + if s.direction == "desc": + field = s.field.desc() # type: ignore + q = q.order_by(field) # type: ignore + return q diff --git a/server/infra/web/__init__.py b/server/infra/web/__init__.py new file mode 100644 index 0000000..6e1fbe6 --- /dev/null +++ b/server/infra/web/__init__.py @@ -0,0 +1,5 @@ +from server.infra.web.description import DescriptionController +from server.infra.web.seo import SeoController +from server.infra.web.recognizer import BreedsController + +__all__ = ("DescriptionController", "SeoController", "BreedsController") diff --git a/server/infra/web/description.py b/server/infra/web/description.py new file mode 100644 index 0000000..37d79bf --- /dev/null +++ b/server/infra/web/description.py @@ -0,0 +1,56 @@ +import inject +import markdown +from litestar import ( + Controller, + get, +) +from litestar.exceptions import HTTPException +from litestar.response import Template + +from server.modules.descriptions import CharactersService +from server.modules.recognizer import RecognizerService + + +class DescriptionController(Controller): + path = "/" + + @get("/") + async def dogs(self) -> Template: + return Template(template_name="dogs.html") + + @get("/cats") + async def cats(self) -> Template: + return Template(template_name="cats.html") + + @get("/contacts") + async def contacts(self) -> Template: + return Template(template_name="contacts.html") + + @get("/donate") + async def donate(self) -> Template: + return Template(template_name="donate.html") + + @get("/dogs-characteristics") + async def dogs_characteristics(self) -> Template: + characters_service: CharactersService = inject.instance(CharactersService) + breeds = await characters_service.get_characters() + return Template( + template_name="dogs-characteristics.html", context={"breeds": breeds} + ) + + @get("/dogs-characteristics/{name:str}") + async def beer_description(self, name: str) -> Template: + characters_service: CharactersService = inject.instance(CharactersService) + breed = await characters_service.get_character(name) + if breed is None: + raise HTTPException(status_code=404, detail="Порода не найдена") + recognizer_service: RecognizerService = inject.instance(RecognizerService) + images = await recognizer_service.images_dogs() + return Template( + template_name="beers-description.html", + context={ + "text": markdown.markdown(breed.description), + "title": breed.name, + "images": [f"/static/assets/dog/{name}/{i}" for i in images[name]], + }, + ) diff --git a/server/infra/web/recognizer.py b/server/infra/web/recognizer.py new file mode 100644 index 0000000..2481bde --- /dev/null +++ b/server/infra/web/recognizer.py @@ -0,0 +1,30 @@ +import inject +from litestar import ( + Controller, + post, +) +from litestar.enums import RequestEncodingType +from litestar.datastructures import UploadFile +from litestar.params import Body + +from server.modules.recognizer import RecognizerService + + +class BreedsController(Controller): + path = "/beerds" + + @post("/dogs") + async def beerds_dogs( + self, data: UploadFile = Body(media_type=RequestEncodingType.MULTI_PART) + ) -> dict: + recognizer_service: RecognizerService = inject.instance(RecognizerService) + body = await data.read() + return await recognizer_service.predict_dog_image(body) + + @post("/cats") + async def beerds_cats( + self, data: UploadFile = Body(media_type=RequestEncodingType.MULTI_PART) + ) -> dict: + recognizer_service: RecognizerService = inject.instance(RecognizerService) + body = await data.read() + return await recognizer_service.predict_cat_image(body) diff --git a/server/infra/web/seo.py b/server/infra/web/seo.py new file mode 100644 index 0000000..caf6566 --- /dev/null +++ b/server/infra/web/seo.py @@ -0,0 +1,62 @@ +import inject +from litestar import ( + Controller, + get, + MediaType, +) + +from server.modules.descriptions import CharactersService, Breed + + +class SeoController(Controller): + @get("/sitemap.xml", media_type=MediaType.XML) + async def sitemaps(self) -> bytes: + characters_service: CharactersService = inject.instance(CharactersService) + breeds: list[Breed] = await characters_service.get_characters() + lastmod = "2025-10-04T19:01:03+00:00" + beers_url = "" + for b in breeds: + beers_url += f""" + + https://xn-----6kcp3cadbabfh8a0a.xn--p1ai/dogs-characteristics/{b.alias} + {lastmod} + +""" + return f""" + + + + + + https://xn-----6kcp3cadbabfh8a0a.xn--p1ai/ + {lastmod} + + + https://xn-----6kcp3cadbabfh8a0a.xn--p1ai/cats + {lastmod} + + + https://xn-----6kcp3cadbabfh8a0a.xn--p1ai/donate + {lastmod} + + + https://xn-----6kcp3cadbabfh8a0a.xn--p1ai/dogs-characteristics + {lastmod} + +{beers_url} + + +""".encode() + + @get("/robots.txt", media_type=MediaType.TEXT) + async def robots(self) -> str: + return """ +User-agent: * +Allow: / + +Sitemap: https://xn-----6kcp3cadbabfh8a0a.xn--p1ai/sitemap.xml +""" diff --git a/server/main.py b/server/main.py index fccdf5f..99cd273 100644 --- a/server/main.py +++ b/server/main.py @@ -1,150 +1,44 @@ +import asyncio from pathlib import Path import os -import markdown +import inject from litestar import ( - Controller, - get, - post, - MediaType, Litestar, ) -from litestar.enums import RequestEncodingType -from litestar.datastructures import UploadFile -from litestar.params import Body -from litestar.exceptions import HTTPException from litestar.contrib.jinja import JinjaTemplateEngine from litestar.template.config import TemplateConfig -from litestar.response import Template from litestar.static_files import create_static_files_router - -from server.services.descriptions import CharactersService, Breed, CharactersRepository -from server.services.recognizer import RecognizerService, RecognizerRepository +from server.config import get_app_config +from server.infra.web import BreedsController, DescriptionController, SeoController +from server.infra.db import AsyncDB +from server.modules.descriptions import CharactersService, CharactersRepository +from server.modules.recognizer import RecognizerService, RecognizerRepository os.environ["CUDA_VISIBLE_DEVICES"] = "-1" -recognizer_service = RecognizerService(RecognizerRepository()) -characters_service = CharactersService(CharactersRepository()) +loop = asyncio.new_event_loop() -class BreedsController(Controller): - path = "/beerds" +def inject_config(binder: inject.Binder): + """initialization inject_config for server FastApi""" - @post("/dogs") - async def beerds_dogs( - self, data: UploadFile = Body(media_type=RequestEncodingType.MULTI_PART) - ) -> dict: - body = await data.read() - return await recognizer_service.predict_dog_image(body) - - @post("/cats") - async def beerds_cats( - self, data: UploadFile = Body(media_type=RequestEncodingType.MULTI_PART) - ) -> dict: - body = await data.read() - return await recognizer_service.predict_cat_image(body) - - -class DescriptionController(Controller): - path = "/" - - @get("/") - async def dogs(self) -> Template: - return Template(template_name="dogs.html") - - @get("/cats") - async def cats(self) -> Template: - return Template(template_name="cats.html") - - @get("/contacts") - async def contacts(self) -> Template: - return Template(template_name="contacts.html") - - @get("/donate") - async def donate(self) -> Template: - return Template(template_name="donate.html") - - @get("/dogs-characteristics") - async def dogs_characteristics(self) -> Template: - breeds = await characters_service.get_characters() - return Template( - template_name="dogs-characteristics.html", context={"breeds": breeds} - ) - - @get("/dogs-characteristics/{name:str}") - async def beer_description(self, name: str) -> Template: - breed = await characters_service.get_character(name) - if breed is None: - raise HTTPException(status_code=404, detail="Порода не найдена") - images = await recognizer_service.images_dogs() - return Template( - template_name="beers-description.html", - context={ - "text": markdown.markdown(breed.description), - "title": breed.name, - "images": [f"/static/assets/dog/{name}/{i}" for i in images[name]], - }, - ) - - @get("/sitemap.xml", media_type=MediaType.XML) - async def sitemaps(self) -> bytes: - breeds: list[Breed] = await characters_service.get_characters() - lastmod = "2025-10-04T19:01:03+00:00" - beers_url = "" - for b in breeds: - beers_url += f""" - - https://xn-----6kcp3cadbabfh8a0a.xn--p1ai/dogs-characteristics/{b.alias} - {lastmod} - -""" - return f""" - - - - - - https://xn-----6kcp3cadbabfh8a0a.xn--p1ai/ - {lastmod} - - - https://xn-----6kcp3cadbabfh8a0a.xn--p1ai/cats - {lastmod} - - - https://xn-----6kcp3cadbabfh8a0a.xn--p1ai/donate - {lastmod} - - - https://xn-----6kcp3cadbabfh8a0a.xn--p1ai/dogs-characteristics - {lastmod} - -{beers_url} - - -""".encode() - - @get("/robots.txt", media_type=MediaType.TEXT) - async def robots(self) -> str: - return """ -User-agent: * -Allow: / - -Sitemap: https://xn-----6kcp3cadbabfh8a0a.xn--p1ai/sitemap.xml -""" + cnf = get_app_config() + db = AsyncDB(cnf) + loop.run_until_complete(db.connect()) + binder.bind(RecognizerService, RecognizerService(RecognizerRepository())) + binder.bind(CharactersService, CharactersService(CharactersRepository())) +inject.configure(inject_config) app = Litestar( debug=True, route_handlers=[ BreedsController, DescriptionController, + SeoController, create_static_files_router(path="/static", directories=["server/static"]), ], template_config=TemplateConfig( diff --git a/server/modules/__init__.py b/server/modules/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/server/modules/attachments/__init__.py b/server/modules/attachments/__init__.py new file mode 100644 index 0000000..9830d62 --- /dev/null +++ b/server/modules/attachments/__init__.py @@ -0,0 +1,31 @@ +""" +Working with media files - uploading, storing, receiving +""" + +from server.modules.attachments.domains.attachments import Attachment +from server.modules.attachments.repositories.attachments import ( + AttachmentRepository, + DBAttachmentRepository, + MockAttachmentRepository, +) +from server.modules.attachments.services.attachment import ( + AtachmentService, + LocalStorageDriver, + MediaType, + MockStorageDriver, + S3StorageDriver, + StorageDriversType, +) + +__all__ = [ + "AtachmentService", + "Attachment", + "AttachmentRepository", + "MockAttachmentRepository", + "DBAttachmentRepository", + "LocalStorageDriver", + "MockStorageDriver", + "S3StorageDriver", + "MediaType", + "StorageDriversType", +] diff --git a/server/modules/attachments/domains/__init__.py b/server/modules/attachments/domains/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/server/modules/attachments/domains/attachments.py b/server/modules/attachments/domains/attachments.py new file mode 100644 index 0000000..0d79639 --- /dev/null +++ b/server/modules/attachments/domains/attachments.py @@ -0,0 +1,18 @@ +from dataclasses import dataclass +from datetime import datetime + +from dataclasses_ujson.dataclasses_ujson import UJsonMixin # type: ignore + + +@dataclass(frozen=True) +class Attachment(UJsonMixin): + id: str + created_at: datetime + updated_at: datetime + size: int + storage_driver_name: str + path: str + media_type: str + created_by: str + content_type: str + is_deleted: bool = False diff --git a/server/modules/attachments/repositories/__init__.py b/server/modules/attachments/repositories/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/server/modules/attachments/repositories/attachments.py b/server/modules/attachments/repositories/attachments.py new file mode 100644 index 0000000..69b235e --- /dev/null +++ b/server/modules/attachments/repositories/attachments.py @@ -0,0 +1,161 @@ +from abc import ABCMeta, abstractmethod +from datetime import UTC, datetime +from typing import Tuple + +from sqlalchemy import CursorResult, delete, insert, select, update + +from server.config import get_app_config +from server.infra.db import AbstractDB, AbstractSession, AsyncDB, MockDB +from server.modules.attachments.domains.attachments import Attachment + + +class AttachmentRepository(metaclass=ABCMeta): + @abstractmethod + async def get_by_id( + self, session: AbstractSession, attach_id: list[str] + ) -> list[Attachment]: + """Get Attachment by ID""" + pass + + @abstractmethod + async def create(self, data: Attachment): + """Create entry in DB""" + pass + + @abstractmethod + async def delete(self, attach_id: str): + """Get Attachment by ID""" + pass + + @abstractmethod + async def update(self, attach_id: str, **kwargs): + pass + + @abstractmethod + def db(self) -> AbstractDB: + pass + + +class MockAttachmentRepository(AttachmentRepository): + _data: dict[str, Attachment] + + def __init__(self): + self._data = { + "jian4": Attachment( + id="jian4", + size=0, + storage_driver_name="mock", + path="jian4", + media_type="audio", + created_by="created_by", + content_type="audio/mp3", + ), + "zai4": Attachment( + id="zai4", + size=0, + storage_driver_name="mock", + path="zai4", + media_type="audio", + created_by="created_by", + content_type="audio/mp3", + ), + "cheng2": Attachment( + id="cheng2", + size=0, + storage_driver_name="mock", + path="cheng2", + media_type="audio", + created_by="created_by", + content_type="audio/mp3", + ), + "shi4": Attachment( + id="shi4", + size=0, + storage_driver_name="mock", + path="shi4", + media_type="audio", + created_by="created_by", + content_type="audio/mp3", + ), + "nv3": Attachment( + id="nv3", + size=0, + storage_driver_name="mock", + path="nv3", + media_type="audio", + created_by="created_by", + content_type="audio/mp3", + ), + } + self._db = MockDB(get_app_config()) + + async def get_by_id( + self, session: AbstractSession, attach_id: list[str] + ) -> list[Attachment]: + f: list[Attachment] = [] + for f_id in attach_id: + f_item = self._data.get(f_id) + if f_item is None: + continue + f.append(f_item) + return f + + async def create(self, data: Attachment): + self._data[data.id] = data + + async def delete(self, attach_id: str): + del self._data[attach_id] + + async def update(self, attach_id: str, **kwargs): + pass + + def db(self) -> AbstractDB: + return self._db + + +class DBAttachmentRepository(AttachmentRepository): + _db: AsyncDB + + def __init__(self, db: AsyncDB): + self._db = db + + async def get_by_id( + self, session: AbstractSession, attach_id: list[str] + ) -> list[Attachment]: + q = select(Attachment).where( + Attachment.id.in_(attach_id) # type: ignore + ) + attachment: list[Attachment] = [] + result: CursorResult[Tuple[Attachment]] = await session.execute(q) # type: ignore + for d in result.all(): + attachment.append(d[0]) + return attachment + + async def create(self, data: Attachment): + new_dict = data.to_serializable(delete_private=True, time_to_str=False) + insert_data = insert(Attachment).values(**new_dict) + async with self._db.session_master() as session: + async with session.begin(): + await session.execute(insert_data) + await session.commit() + return data.id + + async def delete(self, attach_id: str): + q = delete(Attachment).where( + Attachment.id == attach_id # type: ignore + ) + async with self._db.session_master() as session: + async with session.begin(): + await session.execute(q) + await session.commit() + + async def update(self, attach_id: str, **kwargs): + kwargs["updated_at"] = datetime.now(UTC) + q = update(Attachment).values(kwargs).where(Attachment.id == attach_id) # type: ignore + async with self._db.session_master() as session: + async with session.begin(): + await session.execute(q) + await session.commit() + + def db(self) -> AbstractDB: + return self._db diff --git a/server/modules/attachments/services/__init__.py b/server/modules/attachments/services/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/server/modules/attachments/services/attachment.py b/server/modules/attachments/services/attachment.py new file mode 100644 index 0000000..2dccc61 --- /dev/null +++ b/server/modules/attachments/services/attachment.py @@ -0,0 +1,349 @@ +import hashlib +import os.path +from abc import ABCMeta, abstractmethod +from datetime import UTC, datetime +from enum import Enum +from io import BytesIO +from pathlib import Path +from typing import Any, AsyncIterable, AsyncIterator, Optional +import uuid + +import aioboto3 # type: ignore +import aiofiles +import magic # type: ignore +from botocore.client import BaseClient # type: ignore +from botocore.exceptions import ClientError # type: ignore +from PIL import Image + +from server.config import AppConfig, get_app_config +from server.infra.db import AbstractSession +from server.infra.logger import get_logger +from server.modules.attachments.domains.attachments import Attachment +from server.modules.attachments.repositories.attachments import AttachmentRepository + + +class StorageDriversType(str, Enum): + MOCK = "mock" + LOCAL = "local" + S3 = "s3" + + +class MediaType(str, Enum): + AUDIO = "audio" + VIDEO = "video" + IMAGE = "image" + SVG_IMAGE = "svg_image" + OTHER = "other" + + +class StorageDriver(metaclass=ABCMeta): + @abstractmethod + def get_name(self) -> str: + pass + + @abstractmethod + async def put(self, data: bytes) -> str: + pass + + @abstractmethod + async def take(self, path: str) -> Optional[bytes]: + pass + + @abstractmethod + async def stream(self, path: str) -> AsyncIterable[Any]: + pass + + @abstractmethod + async def delete(self, path: str): + pass + + +class LocalStorageDriver(StorageDriver): + _mount_dir: Path + + def __init__(self) -> None: + self._mount_dir = Path(get_app_config().fs_local_mount_dir) # type: ignore + + def get_name(self) -> str: + return StorageDriversType.LOCAL.value + + async def put(self, data: bytes) -> str: + dir_path = self._mount_dir / Path(datetime.now(UTC).strftime("%d")) + if not os.path.isdir(dir_path): + os.mkdir(dir_path) + path = dir_path / Path(hashlib.file_digest(BytesIO(data), "sha256").hexdigest()) + if os.path.isfile(path) and os.stat(path).st_size == len(data): + return str(path) + async with aiofiles.open(path, "wb") as f: + await f.write(data) + return str(path) + + async def take(self, path: str) -> Optional[bytes]: + if not os.path.isfile(path): + return None + async with aiofiles.open(path, "rb") as f: + return await f.read() + + async def stream(self, path: str): + async with aiofiles.open(path, mode="rb") as f: + while chunk := await f.read(1024): + yield chunk + + async def delete(self, path: str): + if not os.path.isfile(path): + return + os.remove(path) + + +class MockStorageDriver(StorageDriver): + _store: dict[str, bytes] + + def __init__(self) -> None: + self._store = {} + + def get_name(self) -> str: + return StorageDriversType.MOCK.value + + async def stream(self, path: str) -> AsyncIterable: + raise NotImplementedError + + async def put(self, data: bytes) -> str: + path = str(uuid.uuid4()) + self._store[path] = data + return path + + async def take(self, path: str) -> Optional[bytes]: + return self._store.get(path) + + async def delete(self, path: str): + del self._store[path] + + +class S3StorageDriver(StorageDriver): + _prefix: str = "pvc-435e5137-052f-43b1-ace2-e350c9d50c76" + + def __init__(self, cnf: AppConfig) -> None: + self._chunk_size: int = 69 * 1024 + self._cnf = cnf + self._logger = get_logger() + self._session = aioboto3.Session( + aws_access_key_id=str(cnf.fs_s3_access_key_id), + aws_secret_access_key=str(cnf.fs_s3_access_key), + ) + + def get_name(self) -> str: + return StorageDriversType.S3.value + + async def _client(self) -> BaseClient: + return self._session.client("s3", endpoint_url=self._cnf.fs_s3_endpoint) + + def _normalize_path(self, path: str) -> str: + return f"{S3StorageDriver._prefix}{path}".replace( + self._cnf.fs_local_mount_dir, "" + ) + + async def put(self, data: bytes) -> str: + sign = hashlib.file_digest(BytesIO(data), "sha256").hexdigest() + day = datetime.now(UTC).strftime("%d") + path = str(Path(S3StorageDriver._prefix) / day / sign) + + async with await self._client() as s3: + await s3.upload_fileobj( + Fileobj=BytesIO(data), + Bucket=self._cnf.fs_s3_bucket, + Key=path, + ExtraArgs={ + "ChecksumAlgorithm": "SHA256", + "ChecksumSHA256": sign, + }, + ) + return path.replace(S3StorageDriver._prefix, "") + + async def stream(self, path: str): + path = self._normalize_path(path) + self._logger.debug( + f"stream s3 path {path}, bucket {self._cnf.fs_s3_bucket}, endpoint {self._cnf.fs_s3_endpoint}" + ) + + try: + async with await self._client() as s3: + obj = await s3.get_object(Bucket=self._cnf.fs_s3_bucket, Key=path) + body = obj["Body"] + while chunk := await body.read(self._chunk_size): + yield chunk + except ClientError as e: + if e.response.get("Error", {}).get("Code") != "NoSuchKey": + self._logger.error(f"stream client error: {str(e)}, path: {path}") + raise FileNotFoundError + except Exception as e: + self._logger.error( + f"stream error: {type(e).__name__} {str(e)}, path: {path}" + ) + raise FileNotFoundError + + async def take(self, path: str) -> Optional[bytes]: + buffer = BytesIO() + async for chunk in self.stream(path): + if chunk: + buffer.write(chunk) + content = buffer.getvalue() + return content if content else None + + async def delete(self, path: str) -> None: + async with await self._client() as s3: + await s3.delete_object( + Bucket=self._cnf.fs_s3_bucket, Key=self._normalize_path(path) + ) + + +RESIZE_MAX_SIZE = 100_000 +RESIZE_PARAMS = (500, 500) + + +class AtachmentService: + _driver: StorageDriver + _repository: AttachmentRepository + _cnf: AppConfig + + def __init__(self, driver: StorageDriver, attach_repository: AttachmentRepository): + self._driver = driver + self._repository = attach_repository + self._cnf = get_app_config() + + def media_type(self, content_type: str) -> MediaType: + if content_type == "": + return MediaType.OTHER + firt_part = content_type.split("/")[0] + match firt_part: + case str(MediaType.SVG_IMAGE): + return MediaType.SVG_IMAGE + case str(MediaType.IMAGE): + return MediaType.IMAGE + case str(MediaType.AUDIO): + return MediaType.AUDIO + case str(MediaType.VIDEO): + return MediaType.VIDEO + case _: + return MediaType.OTHER + + def content_type(self, file: bytes) -> str: + return magic.from_buffer(file[0:2048], mime=True) + + def extension(self, content_type: str | None) -> str: + if not content_type: + return "jpg" + if len(content_type.split("/")) != 2: + return "jpg" + return content_type.split("/")[1].split("+")[0] + + def id_from_url(self, url: str) -> str: + if ".original" not in url: + raise ValueError(f"wrong url: {url}") + parts = url.split(".original")[0] + return parts.replace("/", "") + + def url(self, attachment_id: str, content_type: str | None = None) -> str: + return f"{self._cnf.app_public_url}/api/v0/attachment/{attachment_id}.original.{ + self.extension(content_type) + }" + + async def create(self, file: bytes, user_id: str) -> Attachment: + path = await self._driver.put(file) + content_type = self.content_type(file) + attach = Attachment( + size=len(file), + storage_driver_name=str(self._driver.get_name()), + path=path, + media_type=self.media_type(content_type), + content_type=content_type, + created_by=user_id, + id=str(uuid.uuid4()), + created_at=datetime.now(UTC), + updated_at=datetime.now(UTC), + ) + await self._repository.create(attach) + return attach + + async def get_info( + self, session: AbstractSession | None, attach_id: list[str] + ) -> list[Attachment]: + if not attach_id: + return [] + if session is not None: + return await self._repository.get_by_id(session, attach_id) + async with self._repository.db().session_slave() as session: + return await self._repository.get_by_id(session, attach_id) + + def get_name(self, attachment: Attachment) -> str: + return f"{attachment.id}.{self.extension(attachment.content_type)}" + + async def get_data( + self, session: AbstractSession, attach_id: str + ) -> Optional[bytes]: + file = await self._repository.get_by_id(session, [attach_id]) + if not file: + return None + return await self._driver.take(file[0].path) + + async def get_stream( + self, session: AbstractSession | None, attach_id: str + ) -> AsyncIterator[bytes]: + async def _stream_iterator(is_empty: bool): + if is_empty: + return + yield first_chunk + async for chunk in stream: # type: ignore + yield chunk + + if session: + file = await self._repository.get_by_id(session, [attach_id]) + else: + async with self._repository.db().session_slave() as session: + file = await self._repository.get_by_id(session, [attach_id]) + if not file: + raise FileNotFoundError + + stream = self._driver.stream(file[0].path) + try: + first_chunk = await stream.__anext__() # type: ignore + except StopAsyncIteration: + return _stream_iterator(is_empty=True) + return _stream_iterator(is_empty=False) + + async def image_resize(self, session: AbstractSession, attach_id: list[str]): + info = await self.get_info(session, attach_id) + get_logger().info( + f"image_resize {len(info)}", + ) + if not info: + return + for item in info: + if item.media_type != MediaType.IMAGE.value: + continue + if item.is_deleted: + continue + data = await self.get_data(session, item.id) + if data is None: + continue + if len(data) <= RESIZE_MAX_SIZE: + get_logger().info( + f"skip because size: {len(data)}", + ) + continue + img = Image.open(BytesIO(data)) + img.thumbnail(RESIZE_PARAMS) + buffer = BytesIO() + img.save(buffer, format="JPEG", quality=70) + buffer.seek(0) + d = buffer.read() + if d == 0: + return + buffer.close() + get_logger().info( + f"delete:{item.path}", + ) + path = await self._driver.put(d) + await self._repository.update( + item.id, path=path, content_type="image/jpeg", size=len(d) + ) + await self._driver.delete(item.path) diff --git a/server/modules/descriptions/__init__.py b/server/modules/descriptions/__init__.py new file mode 100644 index 0000000..242e02c --- /dev/null +++ b/server/modules/descriptions/__init__.py @@ -0,0 +1,13 @@ +from server.modules.descriptions.repository import ( + CharactersRepository, + ACharactersRepository, +) +from server.modules.descriptions.service import CharactersService +from server.modules.descriptions.domain import Breed + +__all__ = ( + "CharactersRepository", + "ACharactersRepository", + "CharactersService", + "Breed", +) diff --git a/server/services/descriptions/domain.py b/server/modules/descriptions/domain.py similarity index 100% rename from server/services/descriptions/domain.py rename to server/modules/descriptions/domain.py diff --git a/server/services/descriptions/repository/__init__.py b/server/modules/descriptions/repository/__init__.py similarity index 64% rename from server/services/descriptions/repository/__init__.py rename to server/modules/descriptions/repository/__init__.py index 001ed29..6316855 100644 --- a/server/services/descriptions/repository/__init__.py +++ b/server/modules/descriptions/repository/__init__.py @@ -1,4 +1,4 @@ -from server.services.descriptions.repository.repository import ( +from server.modules.descriptions.repository.repository import ( CharactersRepository, ACharactersRepository, ) diff --git a/server/services/descriptions/repository/breed_descriptions/австралийский келпи.txt b/server/modules/descriptions/repository/breed_descriptions/австралийский келпи.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/австралийский келпи.txt rename to server/modules/descriptions/repository/breed_descriptions/австралийский келпи.txt diff --git a/server/services/descriptions/repository/breed_descriptions/австралийский терьер.txt b/server/modules/descriptions/repository/breed_descriptions/австралийский терьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/австралийский терьер.txt rename to server/modules/descriptions/repository/breed_descriptions/австралийский терьер.txt diff --git a/server/services/descriptions/repository/breed_descriptions/австралийский_шелковистый_терьер.txt b/server/modules/descriptions/repository/breed_descriptions/австралийский_шелковистый_терьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/австралийский_шелковистый_терьер.txt rename to server/modules/descriptions/repository/breed_descriptions/австралийский_шелковистый_терьер.txt diff --git a/server/services/descriptions/repository/breed_descriptions/американская_эскимосская_собака.txt b/server/modules/descriptions/repository/breed_descriptions/американская_эскимосская_собака.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/американская_эскимосская_собака.txt rename to server/modules/descriptions/repository/breed_descriptions/американская_эскимосская_собака.txt diff --git a/server/services/descriptions/repository/breed_descriptions/американский_бульдог.txt b/server/modules/descriptions/repository/breed_descriptions/американский_бульдог.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/американский_бульдог.txt rename to server/modules/descriptions/repository/breed_descriptions/американский_бульдог.txt diff --git a/server/services/descriptions/repository/breed_descriptions/американский_стаффордширский_терьер.txt b/server/modules/descriptions/repository/breed_descriptions/американский_стаффордширский_терьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/американский_стаффордширский_терьер.txt rename to server/modules/descriptions/repository/breed_descriptions/американский_стаффордширский_терьер.txt diff --git a/server/services/descriptions/repository/breed_descriptions/английский_кокер_спаниель.txt b/server/modules/descriptions/repository/breed_descriptions/английский_кокер_спаниель.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/английский_кокер_спаниель.txt rename to server/modules/descriptions/repository/breed_descriptions/английский_кокер_спаниель.txt diff --git a/server/services/descriptions/repository/breed_descriptions/английский_сеттер.txt b/server/modules/descriptions/repository/breed_descriptions/английский_сеттер.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/английский_сеттер.txt rename to server/modules/descriptions/repository/breed_descriptions/английский_сеттер.txt diff --git a/server/services/descriptions/repository/breed_descriptions/английский_спрингер-спаниель.txt b/server/modules/descriptions/repository/breed_descriptions/английский_спрингер-спаниель.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/английский_спрингер-спаниель.txt rename to server/modules/descriptions/repository/breed_descriptions/английский_спрингер-спаниель.txt diff --git a/server/services/descriptions/repository/breed_descriptions/английский_фоксхаунд.txt b/server/modules/descriptions/repository/breed_descriptions/английский_фоксхаунд.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/английский_фоксхаунд.txt rename to server/modules/descriptions/repository/breed_descriptions/английский_фоксхаунд.txt diff --git a/server/services/descriptions/repository/breed_descriptions/аппенцеллер_зенненхунд.txt b/server/modules/descriptions/repository/breed_descriptions/аппенцеллер_зенненхунд.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/аппенцеллер_зенненхунд.txt rename to server/modules/descriptions/repository/breed_descriptions/аппенцеллер_зенненхунд.txt diff --git a/server/services/descriptions/repository/breed_descriptions/афганская_борзая.txt b/server/modules/descriptions/repository/breed_descriptions/афганская_борзая.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/афганская_борзая.txt rename to server/modules/descriptions/repository/breed_descriptions/афганская_борзая.txt diff --git a/server/services/descriptions/repository/breed_descriptions/аффенпинчер.txt b/server/modules/descriptions/repository/breed_descriptions/аффенпинчер.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/аффенпинчер.txt rename to server/modules/descriptions/repository/breed_descriptions/аффенпинчер.txt diff --git a/server/services/descriptions/repository/breed_descriptions/басенджи.txt b/server/modules/descriptions/repository/breed_descriptions/басенджи.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/басенджи.txt rename to server/modules/descriptions/repository/breed_descriptions/басенджи.txt diff --git a/server/services/descriptions/repository/breed_descriptions/бассет_хаунд.txt b/server/modules/descriptions/repository/breed_descriptions/бассет_хаунд.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/бассет_хаунд.txt rename to server/modules/descriptions/repository/breed_descriptions/бассет_хаунд.txt diff --git a/server/services/descriptions/repository/breed_descriptions/бедлингтон-терьер.txt b/server/modules/descriptions/repository/breed_descriptions/бедлингтон-терьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/бедлингтон-терьер.txt rename to server/modules/descriptions/repository/breed_descriptions/бедлингтон-терьер.txt diff --git a/server/services/descriptions/repository/breed_descriptions/бернский_зенненхунд.txt b/server/modules/descriptions/repository/breed_descriptions/бернский_зенненхунд.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/бернский_зенненхунд.txt rename to server/modules/descriptions/repository/breed_descriptions/бернский_зенненхунд.txt diff --git a/server/services/descriptions/repository/breed_descriptions/бигль.txt b/server/modules/descriptions/repository/breed_descriptions/бигль.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/бигль.txt rename to server/modules/descriptions/repository/breed_descriptions/бигль.txt diff --git a/server/services/descriptions/repository/breed_descriptions/бладхаунд.txt b/server/modules/descriptions/repository/breed_descriptions/бладхаунд.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/бладхаунд.txt rename to server/modules/descriptions/repository/breed_descriptions/бладхаунд.txt diff --git a/server/services/descriptions/repository/breed_descriptions/бобтейл.txt b/server/modules/descriptions/repository/breed_descriptions/бобтейл.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/бобтейл.txt rename to server/modules/descriptions/repository/breed_descriptions/бобтейл.txt diff --git a/server/services/descriptions/repository/breed_descriptions/боксер.txt b/server/modules/descriptions/repository/breed_descriptions/боксер.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/боксер.txt rename to server/modules/descriptions/repository/breed_descriptions/боксер.txt diff --git a/server/services/descriptions/repository/breed_descriptions/большой_швейцарский_зенненхунд.txt b/server/modules/descriptions/repository/breed_descriptions/большой_швейцарский_зенненхунд.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/большой_швейцарский_зенненхунд.txt rename to server/modules/descriptions/repository/breed_descriptions/большой_швейцарский_зенненхунд.txt diff --git a/server/services/descriptions/repository/breed_descriptions/бордер-колли.txt b/server/modules/descriptions/repository/breed_descriptions/бордер-колли.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/бордер-колли.txt rename to server/modules/descriptions/repository/breed_descriptions/бордер-колли.txt diff --git a/server/services/descriptions/repository/breed_descriptions/бордер-терьер.txt b/server/modules/descriptions/repository/breed_descriptions/бордер-терьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/бордер-терьер.txt rename to server/modules/descriptions/repository/breed_descriptions/бордер-терьер.txt diff --git a/server/services/descriptions/repository/breed_descriptions/бостон-терьер.txt b/server/modules/descriptions/repository/breed_descriptions/бостон-терьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/бостон-терьер.txt rename to server/modules/descriptions/repository/breed_descriptions/бостон-терьер.txt diff --git a/server/services/descriptions/repository/breed_descriptions/бретонский_эпаньоль.txt b/server/modules/descriptions/repository/breed_descriptions/бретонский_эпаньоль.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/бретонский_эпаньоль.txt rename to server/modules/descriptions/repository/breed_descriptions/бретонский_эпаньоль.txt diff --git a/server/services/descriptions/repository/breed_descriptions/бриар.txt b/server/modules/descriptions/repository/breed_descriptions/бриар.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/бриар.txt rename to server/modules/descriptions/repository/breed_descriptions/бриар.txt diff --git a/server/services/descriptions/repository/breed_descriptions/бульмастиф.txt b/server/modules/descriptions/repository/breed_descriptions/бульмастиф.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/бульмастиф.txt rename to server/modules/descriptions/repository/breed_descriptions/бульмастиф.txt diff --git a/server/services/descriptions/repository/breed_descriptions/веймаранер.txt b/server/modules/descriptions/repository/breed_descriptions/веймаранер.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/веймаранер.txt rename to server/modules/descriptions/repository/breed_descriptions/веймаранер.txt diff --git a/server/services/descriptions/repository/breed_descriptions/вельш-корги_кардиган.txt b/server/modules/descriptions/repository/breed_descriptions/вельш-корги_кардиган.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/вельш-корги_кардиган.txt rename to server/modules/descriptions/repository/breed_descriptions/вельш-корги_кардиган.txt diff --git a/server/services/descriptions/repository/breed_descriptions/вельш-корги_пемброк.txt b/server/modules/descriptions/repository/breed_descriptions/вельш-корги_пемброк.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/вельш-корги_пемброк.txt rename to server/modules/descriptions/repository/breed_descriptions/вельш-корги_пемброк.txt diff --git a/server/services/descriptions/repository/breed_descriptions/вельш-спрингер-спаниель.txt b/server/modules/descriptions/repository/breed_descriptions/вельш-спрингер-спаниель.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/вельш-спрингер-спаниель.txt rename to server/modules/descriptions/repository/breed_descriptions/вельш-спрингер-спаниель.txt diff --git a/server/services/descriptions/repository/breed_descriptions/венгерская_выжла.txt b/server/modules/descriptions/repository/breed_descriptions/венгерская_выжла.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/венгерская_выжла.txt rename to server/modules/descriptions/repository/breed_descriptions/венгерская_выжла.txt diff --git a/server/services/descriptions/repository/breed_descriptions/вест-хайленд-уайт-терьер.txt b/server/modules/descriptions/repository/breed_descriptions/вест-хайленд-уайт-терьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/вест-хайленд-уайт-терьер.txt rename to server/modules/descriptions/repository/breed_descriptions/вест-хайленд-уайт-терьер.txt diff --git a/server/services/descriptions/repository/breed_descriptions/гаванский_бишон.txt b/server/modules/descriptions/repository/breed_descriptions/гаванский_бишон.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/гаванский_бишон.txt rename to server/modules/descriptions/repository/breed_descriptions/гаванский_бишон.txt diff --git a/server/services/descriptions/repository/breed_descriptions/гиеновидная_собака.txt b/server/modules/descriptions/repository/breed_descriptions/гиеновидная_собака.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/гиеновидная_собака.txt rename to server/modules/descriptions/repository/breed_descriptions/гиеновидная_собака.txt diff --git a/server/services/descriptions/repository/breed_descriptions/грюнендаль.txt b/server/modules/descriptions/repository/breed_descriptions/грюнендаль.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/грюнендаль.txt rename to server/modules/descriptions/repository/breed_descriptions/грюнендаль.txt diff --git a/server/services/descriptions/repository/breed_descriptions/денди-динмонт-терьер.txt b/server/modules/descriptions/repository/breed_descriptions/денди-динмонт-терьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/денди-динмонт-терьер.txt rename to server/modules/descriptions/repository/breed_descriptions/денди-динмонт-терьер.txt diff --git a/server/services/descriptions/repository/breed_descriptions/динго.txt b/server/modules/descriptions/repository/breed_descriptions/динго.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/динго.txt rename to server/modules/descriptions/repository/breed_descriptions/динго.txt diff --git a/server/services/descriptions/repository/breed_descriptions/дирхаунд.txt b/server/modules/descriptions/repository/breed_descriptions/дирхаунд.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/дирхаунд.txt rename to server/modules/descriptions/repository/breed_descriptions/дирхаунд.txt diff --git a/server/services/descriptions/repository/breed_descriptions/доберман.txt b/server/modules/descriptions/repository/breed_descriptions/доберман.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/доберман.txt rename to server/modules/descriptions/repository/breed_descriptions/доберман.txt diff --git a/server/services/descriptions/repository/breed_descriptions/дхоль.txt b/server/modules/descriptions/repository/breed_descriptions/дхоль.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/дхоль.txt rename to server/modules/descriptions/repository/breed_descriptions/дхоль.txt diff --git a/server/services/descriptions/repository/breed_descriptions/жесткошёрстный_фокстерьер.txt b/server/modules/descriptions/repository/breed_descriptions/жесткошёрстный_фокстерьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/жесткошёрстный_фокстерьер.txt rename to server/modules/descriptions/repository/breed_descriptions/жесткошёрстный_фокстерьер.txt diff --git a/server/services/descriptions/repository/breed_descriptions/золотистый_ретривер.txt b/server/modules/descriptions/repository/breed_descriptions/золотистый_ретривер.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/золотистый_ретривер.txt rename to server/modules/descriptions/repository/breed_descriptions/золотистый_ретривер.txt diff --git a/server/services/descriptions/repository/breed_descriptions/ирландский_водяной_спаниель.txt b/server/modules/descriptions/repository/breed_descriptions/ирландский_водяной_спаниель.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/ирландский_водяной_спаниель.txt rename to server/modules/descriptions/repository/breed_descriptions/ирландский_водяной_спаниель.txt diff --git a/server/services/descriptions/repository/breed_descriptions/ирландский_волкодав.txt b/server/modules/descriptions/repository/breed_descriptions/ирландский_волкодав.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/ирландский_волкодав.txt rename to server/modules/descriptions/repository/breed_descriptions/ирландский_волкодав.txt diff --git a/server/services/descriptions/repository/breed_descriptions/ирландский_красный_сеттер.txt b/server/modules/descriptions/repository/breed_descriptions/ирландский_красный_сеттер.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/ирландский_красный_сеттер.txt rename to server/modules/descriptions/repository/breed_descriptions/ирландский_красный_сеттер.txt diff --git a/server/services/descriptions/repository/breed_descriptions/ирландский_мягкошёрстный_пшеничный_терьер.txt b/server/modules/descriptions/repository/breed_descriptions/ирландский_мягкошёрстный_пшеничный_терьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/ирландский_мягкошёрстный_пшеничный_терьер.txt rename to server/modules/descriptions/repository/breed_descriptions/ирландский_мягкошёрстный_пшеничный_терьер.txt diff --git a/server/services/descriptions/repository/breed_descriptions/ирландский_терьер.txt b/server/modules/descriptions/repository/breed_descriptions/ирландский_терьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/ирландский_терьер.txt rename to server/modules/descriptions/repository/breed_descriptions/ирландский_терьер.txt diff --git a/server/services/descriptions/repository/breed_descriptions/йоркширский_терьер.txt b/server/modules/descriptions/repository/breed_descriptions/йоркширский_терьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/йоркширский_терьер.txt rename to server/modules/descriptions/repository/breed_descriptions/йоркширский_терьер.txt diff --git a/server/services/descriptions/repository/breed_descriptions/карликовый _пинчер.txt b/server/modules/descriptions/repository/breed_descriptions/карликовый _пинчер.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/карликовый _пинчер.txt rename to server/modules/descriptions/repository/breed_descriptions/карликовый _пинчер.txt diff --git a/server/services/descriptions/repository/breed_descriptions/карликовый_пинчер.txt b/server/modules/descriptions/repository/breed_descriptions/карликовый_пинчер.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/карликовый_пинчер.txt rename to server/modules/descriptions/repository/breed_descriptions/карликовый_пинчер.txt diff --git a/server/services/descriptions/repository/breed_descriptions/кеесхонд.txt b/server/modules/descriptions/repository/breed_descriptions/кеесхонд.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/кеесхонд.txt rename to server/modules/descriptions/repository/breed_descriptions/кеесхонд.txt diff --git a/server/services/descriptions/repository/breed_descriptions/керн-терьер.txt b/server/modules/descriptions/repository/breed_descriptions/керн-терьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/керн-терьер.txt rename to server/modules/descriptions/repository/breed_descriptions/керн-терьер.txt diff --git a/server/services/descriptions/repository/breed_descriptions/керри-блю-терьер.txt b/server/modules/descriptions/repository/breed_descriptions/керри-блю-терьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/керри-блю-терьер.txt rename to server/modules/descriptions/repository/breed_descriptions/керри-блю-терьер.txt diff --git a/server/services/descriptions/repository/breed_descriptions/кинг-чарльз-спаниель.txt b/server/modules/descriptions/repository/breed_descriptions/кинг-чарльз-спаниель.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/кинг-чарльз-спаниель.txt rename to server/modules/descriptions/repository/breed_descriptions/кинг-чарльз-спаниель.txt diff --git a/server/services/descriptions/repository/breed_descriptions/кламбер-спаниель.txt b/server/modules/descriptions/repository/breed_descriptions/кламбер-спаниель.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/кламбер-спаниель.txt rename to server/modules/descriptions/repository/breed_descriptions/кламбер-спаниель.txt diff --git a/server/services/descriptions/repository/breed_descriptions/кокер-спаниель.txt b/server/modules/descriptions/repository/breed_descriptions/кокер-спаниель.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/кокер-спаниель.txt rename to server/modules/descriptions/repository/breed_descriptions/кокер-спаниель.txt diff --git a/server/services/descriptions/repository/breed_descriptions/колли.txt b/server/modules/descriptions/repository/breed_descriptions/колли.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/колли.txt rename to server/modules/descriptions/repository/breed_descriptions/колли.txt diff --git a/server/services/descriptions/repository/breed_descriptions/комондор.txt b/server/modules/descriptions/repository/breed_descriptions/комондор.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/комондор.txt rename to server/modules/descriptions/repository/breed_descriptions/комондор.txt diff --git a/server/services/descriptions/repository/breed_descriptions/континентальный_той-спаниель.txt b/server/modules/descriptions/repository/breed_descriptions/континентальный_той-спаниель.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/континентальный_той-спаниель.txt rename to server/modules/descriptions/repository/breed_descriptions/континентальный_той-спаниель.txt diff --git a/server/services/descriptions/repository/breed_descriptions/крапчато-голубой_кунхаунд.txt b/server/modules/descriptions/repository/breed_descriptions/крапчато-голубой_кунхаунд.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/крапчато-голубой_кунхаунд.txt rename to server/modules/descriptions/repository/breed_descriptions/крапчато-голубой_кунхаунд.txt diff --git a/server/services/descriptions/repository/breed_descriptions/красный_кунхаунд.txt b/server/modules/descriptions/repository/breed_descriptions/красный_кунхаунд.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/красный_кунхаунд.txt rename to server/modules/descriptions/repository/breed_descriptions/красный_кунхаунд.txt diff --git a/server/services/descriptions/repository/breed_descriptions/ксолоитцкуинтли.txt b/server/modules/descriptions/repository/breed_descriptions/ксолоитцкуинтли.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/ксолоитцкуинтли.txt rename to server/modules/descriptions/repository/breed_descriptions/ксолоитцкуинтли.txt diff --git a/server/services/descriptions/repository/breed_descriptions/кувас.txt b/server/modules/descriptions/repository/breed_descriptions/кувас.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/кувас.txt rename to server/modules/descriptions/repository/breed_descriptions/кувас.txt diff --git a/server/services/descriptions/repository/breed_descriptions/курцхаар.txt b/server/modules/descriptions/repository/breed_descriptions/курцхаар.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/курцхаар.txt rename to server/modules/descriptions/repository/breed_descriptions/курцхаар.txt diff --git a/server/services/descriptions/repository/breed_descriptions/курчавошёрстный_ретривер.txt b/server/modules/descriptions/repository/breed_descriptions/курчавошёрстный_ретривер.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/курчавошёрстный_ретривер.txt rename to server/modules/descriptions/repository/breed_descriptions/курчавошёрстный_ретривер.txt diff --git a/server/services/descriptions/repository/breed_descriptions/лабрадор-ретривер.txt b/server/modules/descriptions/repository/breed_descriptions/лабрадор-ретривер.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/лабрадор-ретривер.txt rename to server/modules/descriptions/repository/breed_descriptions/лабрадор-ретривер.txt diff --git a/server/services/descriptions/repository/breed_descriptions/левретка.txt b/server/modules/descriptions/repository/breed_descriptions/левретка.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/левретка.txt rename to server/modules/descriptions/repository/breed_descriptions/левретка.txt diff --git a/server/services/descriptions/repository/breed_descriptions/лейкленд-терьер.txt b/server/modules/descriptions/repository/breed_descriptions/лейкленд-терьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/лейкленд-терьер.txt rename to server/modules/descriptions/repository/breed_descriptions/лейкленд-терьер.txt diff --git a/server/services/descriptions/repository/breed_descriptions/леонбергер.txt b/server/modules/descriptions/repository/breed_descriptions/леонбергер.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/леонбергер.txt rename to server/modules/descriptions/repository/breed_descriptions/леонбергер.txt diff --git a/server/services/descriptions/repository/breed_descriptions/лхасский_апсо.txt b/server/modules/descriptions/repository/breed_descriptions/лхасский_апсо.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/лхасский_апсо.txt rename to server/modules/descriptions/repository/breed_descriptions/лхасский_апсо.txt diff --git a/server/services/descriptions/repository/breed_descriptions/маламут.txt b/server/modules/descriptions/repository/breed_descriptions/маламут.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/маламут.txt rename to server/modules/descriptions/repository/breed_descriptions/маламут.txt diff --git a/server/services/descriptions/repository/breed_descriptions/малинуа.txt b/server/modules/descriptions/repository/breed_descriptions/малинуа.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/малинуа.txt rename to server/modules/descriptions/repository/breed_descriptions/малинуа.txt diff --git a/server/services/descriptions/repository/breed_descriptions/малые_бельгийские_собаки.txt b/server/modules/descriptions/repository/breed_descriptions/малые_бельгийские_собаки.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/малые_бельгийские_собаки.txt rename to server/modules/descriptions/repository/breed_descriptions/малые_бельгийские_собаки.txt diff --git a/server/services/descriptions/repository/breed_descriptions/мальтийская_болонка.txt b/server/modules/descriptions/repository/breed_descriptions/мальтийская_болонка.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/мальтийская_болонка.txt rename to server/modules/descriptions/repository/breed_descriptions/мальтийская_болонка.txt diff --git a/server/services/descriptions/repository/breed_descriptions/миниатюрный_пудель.txt b/server/modules/descriptions/repository/breed_descriptions/миниатюрный_пудель.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/миниатюрный_пудель.txt rename to server/modules/descriptions/repository/breed_descriptions/миниатюрный_пудель.txt diff --git a/server/services/descriptions/repository/breed_descriptions/миттельшнауцер.txt b/server/modules/descriptions/repository/breed_descriptions/миттельшнауцер.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/миттельшнауцер.txt rename to server/modules/descriptions/repository/breed_descriptions/миттельшнауцер.txt diff --git a/server/services/descriptions/repository/breed_descriptions/мопс.txt b/server/modules/descriptions/repository/breed_descriptions/мопс.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/мопс.txt rename to server/modules/descriptions/repository/breed_descriptions/мопс.txt diff --git a/server/services/descriptions/repository/breed_descriptions/немецкая_овчарка.txt b/server/modules/descriptions/repository/breed_descriptions/немецкая_овчарка.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/немецкая_овчарка.txt rename to server/modules/descriptions/repository/breed_descriptions/немецкая_овчарка.txt diff --git a/server/services/descriptions/repository/breed_descriptions/немецкий_дог.txt b/server/modules/descriptions/repository/breed_descriptions/немецкий_дог.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/немецкий_дог.txt rename to server/modules/descriptions/repository/breed_descriptions/немецкий_дог.txt diff --git a/server/services/descriptions/repository/breed_descriptions/норвежский_серый_элкхунд.txt b/server/modules/descriptions/repository/breed_descriptions/норвежский_серый_элкхунд.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/норвежский_серый_элкхунд.txt rename to server/modules/descriptions/repository/breed_descriptions/норвежский_серый_элкхунд.txt diff --git a/server/services/descriptions/repository/breed_descriptions/норвич-терьер.txt b/server/modules/descriptions/repository/breed_descriptions/норвич-терьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/норвич-терьер.txt rename to server/modules/descriptions/repository/breed_descriptions/норвич-терьер.txt diff --git a/server/services/descriptions/repository/breed_descriptions/норфолк-терьер.txt b/server/modules/descriptions/repository/breed_descriptions/норфолк-терьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/норфолк-терьер.txt rename to server/modules/descriptions/repository/breed_descriptions/норфолк-терьер.txt diff --git a/server/services/descriptions/repository/breed_descriptions/ньюфаундленд.txt b/server/modules/descriptions/repository/breed_descriptions/ньюфаундленд.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/ньюфаундленд.txt rename to server/modules/descriptions/repository/breed_descriptions/ньюфаундленд.txt diff --git a/server/services/descriptions/repository/breed_descriptions/оттерхаунд.txt b/server/modules/descriptions/repository/breed_descriptions/оттерхаунд.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/оттерхаунд.txt rename to server/modules/descriptions/repository/breed_descriptions/оттерхаунд.txt diff --git a/server/services/descriptions/repository/breed_descriptions/пекинес.txt b/server/modules/descriptions/repository/breed_descriptions/пекинес.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/пекинес.txt rename to server/modules/descriptions/repository/breed_descriptions/пекинес.txt diff --git a/server/services/descriptions/repository/breed_descriptions/пиренейская _горная_собака.txt b/server/modules/descriptions/repository/breed_descriptions/пиренейская _горная_собака.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/пиренейская _горная_собака.txt rename to server/modules/descriptions/repository/breed_descriptions/пиренейская _горная_собака.txt diff --git a/server/services/descriptions/repository/breed_descriptions/померанский_шпиц.txt b/server/modules/descriptions/repository/breed_descriptions/померанский_шпиц.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/померанский_шпиц.txt rename to server/modules/descriptions/repository/breed_descriptions/померанский_шпиц.txt diff --git a/server/services/descriptions/repository/breed_descriptions/прямошёрстный_ретривер.txt b/server/modules/descriptions/repository/breed_descriptions/прямошёрстный_ретривер.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/прямошёрстный_ретривер.txt rename to server/modules/descriptions/repository/breed_descriptions/прямошёрстный_ретривер.txt diff --git a/server/services/descriptions/repository/breed_descriptions/ризеншнауцер.txt b/server/modules/descriptions/repository/breed_descriptions/ризеншнауцер.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/ризеншнауцер.txt rename to server/modules/descriptions/repository/breed_descriptions/ризеншнауцер.txt diff --git a/server/services/descriptions/repository/breed_descriptions/родезийский риджбек.txt b/server/modules/descriptions/repository/breed_descriptions/родезийский риджбек.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/родезийский риджбек.txt rename to server/modules/descriptions/repository/breed_descriptions/родезийский риджбек.txt diff --git a/server/services/descriptions/repository/breed_descriptions/ротвейлер.txt b/server/modules/descriptions/repository/breed_descriptions/ротвейлер.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/ротвейлер.txt rename to server/modules/descriptions/repository/breed_descriptions/ротвейлер.txt diff --git a/server/services/descriptions/repository/breed_descriptions/русская_псовая_борзая.txt b/server/modules/descriptions/repository/breed_descriptions/русская_псовая_борзая.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/русская_псовая_борзая.txt rename to server/modules/descriptions/repository/breed_descriptions/русская_псовая_борзая.txt diff --git a/server/services/descriptions/repository/breed_descriptions/русский_той.txt b/server/modules/descriptions/repository/breed_descriptions/русский_той.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/русский_той.txt rename to server/modules/descriptions/repository/breed_descriptions/русский_той.txt diff --git a/server/services/descriptions/repository/breed_descriptions/салюки.txt b/server/modules/descriptions/repository/breed_descriptions/салюки.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/салюки.txt rename to server/modules/descriptions/repository/breed_descriptions/салюки.txt diff --git a/server/services/descriptions/repository/breed_descriptions/самоед.txt b/server/modules/descriptions/repository/breed_descriptions/самоед.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/самоед.txt rename to server/modules/descriptions/repository/breed_descriptions/самоед.txt diff --git a/server/services/descriptions/repository/breed_descriptions/сенбернар.txt b/server/modules/descriptions/repository/breed_descriptions/сенбернар.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/сенбернар.txt rename to server/modules/descriptions/repository/breed_descriptions/сенбернар.txt diff --git a/server/services/descriptions/repository/breed_descriptions/сибирский_хаски.txt b/server/modules/descriptions/repository/breed_descriptions/сибирский_хаски.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/сибирский_хаски.txt rename to server/modules/descriptions/repository/breed_descriptions/сибирский_хаски.txt diff --git a/server/services/descriptions/repository/breed_descriptions/силихем-терьер.txt b/server/modules/descriptions/repository/breed_descriptions/силихем-терьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/силихем-терьер.txt rename to server/modules/descriptions/repository/breed_descriptions/силихем-терьер.txt diff --git a/server/services/descriptions/repository/breed_descriptions/стандартный_пудель.txt b/server/modules/descriptions/repository/breed_descriptions/стандартный_пудель.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/стандартный_пудель.txt rename to server/modules/descriptions/repository/breed_descriptions/стандартный_пудель.txt diff --git a/server/services/descriptions/repository/breed_descriptions/стаффордширский_бультерьер.txt b/server/modules/descriptions/repository/breed_descriptions/стаффордширский_бультерьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/стаффордширский_бультерьер.txt rename to server/modules/descriptions/repository/breed_descriptions/стаффордширский_бультерьер.txt diff --git a/server/services/descriptions/repository/breed_descriptions/суссекс-спаниель.txt b/server/modules/descriptions/repository/breed_descriptions/суссекс-спаниель.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/суссекс-спаниель.txt rename to server/modules/descriptions/repository/breed_descriptions/суссекс-спаниель.txt diff --git a/server/services/descriptions/repository/breed_descriptions/схипперке.txt b/server/modules/descriptions/repository/breed_descriptions/схипперке.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/схипперке.txt rename to server/modules/descriptions/repository/breed_descriptions/схипперке.txt diff --git a/server/services/descriptions/repository/breed_descriptions/тибетский_мастиф.txt b/server/modules/descriptions/repository/breed_descriptions/тибетский_мастиф.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/тибетский_мастиф.txt rename to server/modules/descriptions/repository/breed_descriptions/тибетский_мастиф.txt diff --git a/server/services/descriptions/repository/breed_descriptions/тибетский_терьер.txt b/server/modules/descriptions/repository/breed_descriptions/тибетский_терьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/тибетский_терьер.txt rename to server/modules/descriptions/repository/breed_descriptions/тибетский_терьер.txt diff --git a/server/services/descriptions/repository/breed_descriptions/той_пудель.txt b/server/modules/descriptions/repository/breed_descriptions/той_пудель.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/той_пудель.txt rename to server/modules/descriptions/repository/breed_descriptions/той_пудель.txt diff --git a/server/services/descriptions/repository/breed_descriptions/триин-уокер_кунхаунд.txt b/server/modules/descriptions/repository/breed_descriptions/триин-уокер_кунхаунд.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/триин-уокер_кунхаунд.txt rename to server/modules/descriptions/repository/breed_descriptions/триин-уокер_кунхаунд.txt diff --git a/server/services/descriptions/repository/breed_descriptions/уиппет.txt b/server/modules/descriptions/repository/breed_descriptions/уиппет.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/уиппет.txt rename to server/modules/descriptions/repository/breed_descriptions/уиппет.txt diff --git a/server/services/descriptions/repository/breed_descriptions/фландрский_бувье.txt b/server/modules/descriptions/repository/breed_descriptions/фландрский_бувье.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/фландрский_бувье.txt rename to server/modules/descriptions/repository/breed_descriptions/фландрский_бувье.txt diff --git a/server/services/descriptions/repository/breed_descriptions/французский_бульдог.txt b/server/modules/descriptions/repository/breed_descriptions/французский_бульдог.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/французский_бульдог.txt rename to server/modules/descriptions/repository/breed_descriptions/французский_бульдог.txt diff --git a/server/services/descriptions/repository/breed_descriptions/цвергшнауцер.txt b/server/modules/descriptions/repository/breed_descriptions/цвергшнауцер.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/цвергшнауцер.txt rename to server/modules/descriptions/repository/breed_descriptions/цвергшнауцер.txt diff --git a/server/services/descriptions/repository/breed_descriptions/чау-чау.txt b/server/modules/descriptions/repository/breed_descriptions/чау-чау.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/чау-чау.txt rename to server/modules/descriptions/repository/breed_descriptions/чау-чау.txt diff --git a/server/services/descriptions/repository/breed_descriptions/чесапик-бей-ретривер.txt b/server/modules/descriptions/repository/breed_descriptions/чесапик-бей-ретривер.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/чесапик-бей-ретривер.txt rename to server/modules/descriptions/repository/breed_descriptions/чесапик-бей-ретривер.txt diff --git a/server/services/descriptions/repository/breed_descriptions/чихуахуа.txt b/server/modules/descriptions/repository/breed_descriptions/чихуахуа.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/чихуахуа.txt rename to server/modules/descriptions/repository/breed_descriptions/чихуахуа.txt diff --git a/server/services/descriptions/repository/breed_descriptions/чёрно-подпалый_кунхаунд.txt b/server/modules/descriptions/repository/breed_descriptions/чёрно-подпалый_кунхаунд.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/чёрно-подпалый_кунхаунд.txt rename to server/modules/descriptions/repository/breed_descriptions/чёрно-подпалый_кунхаунд.txt diff --git a/server/services/descriptions/repository/breed_descriptions/шелти.txt b/server/modules/descriptions/repository/breed_descriptions/шелти.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/шелти.txt rename to server/modules/descriptions/repository/breed_descriptions/шелти.txt diff --git a/server/services/descriptions/repository/breed_descriptions/ши-тцу.txt b/server/modules/descriptions/repository/breed_descriptions/ши-тцу.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/ши-тцу.txt rename to server/modules/descriptions/repository/breed_descriptions/ши-тцу.txt diff --git a/server/services/descriptions/repository/breed_descriptions/шиба_ину.txt b/server/modules/descriptions/repository/breed_descriptions/шиба_ину.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/шиба_ину.txt rename to server/modules/descriptions/repository/breed_descriptions/шиба_ину.txt diff --git a/server/services/descriptions/repository/breed_descriptions/шотландский_сеттер.txt b/server/modules/descriptions/repository/breed_descriptions/шотландский_сеттер.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/шотландский_сеттер.txt rename to server/modules/descriptions/repository/breed_descriptions/шотландский_сеттер.txt diff --git a/server/services/descriptions/repository/breed_descriptions/шотландский_терьер.txt b/server/modules/descriptions/repository/breed_descriptions/шотландский_терьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/шотландский_терьер.txt rename to server/modules/descriptions/repository/breed_descriptions/шотландский_терьер.txt diff --git a/server/services/descriptions/repository/breed_descriptions/энтлебухер_зенненхунд.txt b/server/modules/descriptions/repository/breed_descriptions/энтлебухер_зенненхунд.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/энтлебухер_зенненхунд.txt rename to server/modules/descriptions/repository/breed_descriptions/энтлебухер_зенненхунд.txt diff --git a/server/services/descriptions/repository/breed_descriptions/эрдельтерьер.txt b/server/modules/descriptions/repository/breed_descriptions/эрдельтерьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/эрдельтерьер.txt rename to server/modules/descriptions/repository/breed_descriptions/эрдельтерьер.txt diff --git a/server/services/descriptions/repository/breed_descriptions/японский хин.txt b/server/modules/descriptions/repository/breed_descriptions/японский хин.txt similarity index 100% rename from server/services/descriptions/repository/breed_descriptions/японский хин.txt rename to server/modules/descriptions/repository/breed_descriptions/японский хин.txt diff --git a/server/services/descriptions/repository/breed_signs/австралийский келпи.txt b/server/modules/descriptions/repository/breed_signs/австралийский келпи.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/австралийский келпи.txt rename to server/modules/descriptions/repository/breed_signs/австралийский келпи.txt diff --git a/server/services/descriptions/repository/breed_signs/австралийский терьер.txt b/server/modules/descriptions/repository/breed_signs/австралийский терьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/австралийский терьер.txt rename to server/modules/descriptions/repository/breed_signs/австралийский терьер.txt diff --git a/server/services/descriptions/repository/breed_signs/австралийский_шелковистый_терьер.txt b/server/modules/descriptions/repository/breed_signs/австралийский_шелковистый_терьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/австралийский_шелковистый_терьер.txt rename to server/modules/descriptions/repository/breed_signs/австралийский_шелковистый_терьер.txt diff --git a/server/services/descriptions/repository/breed_signs/американская_эскимосская_собака.txt b/server/modules/descriptions/repository/breed_signs/американская_эскимосская_собака.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/американская_эскимосская_собака.txt rename to server/modules/descriptions/repository/breed_signs/американская_эскимосская_собака.txt diff --git a/server/services/descriptions/repository/breed_signs/американский_бульдог.txt b/server/modules/descriptions/repository/breed_signs/американский_бульдог.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/американский_бульдог.txt rename to server/modules/descriptions/repository/breed_signs/американский_бульдог.txt diff --git a/server/services/descriptions/repository/breed_signs/американский_стаффордширский_терьер.txt b/server/modules/descriptions/repository/breed_signs/американский_стаффордширский_терьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/американский_стаффордширский_терьер.txt rename to server/modules/descriptions/repository/breed_signs/американский_стаффордширский_терьер.txt diff --git a/server/services/descriptions/repository/breed_signs/английский_сеттер.txt b/server/modules/descriptions/repository/breed_signs/английский_сеттер.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/английский_сеттер.txt rename to server/modules/descriptions/repository/breed_signs/английский_сеттер.txt diff --git a/server/services/descriptions/repository/breed_signs/английский_спрингер-спаниель.txt b/server/modules/descriptions/repository/breed_signs/английский_спрингер-спаниель.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/английский_спрингер-спаниель.txt rename to server/modules/descriptions/repository/breed_signs/английский_спрингер-спаниель.txt diff --git a/server/services/descriptions/repository/breed_signs/английский_фоксхаунд.txt b/server/modules/descriptions/repository/breed_signs/английский_фоксхаунд.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/английский_фоксхаунд.txt rename to server/modules/descriptions/repository/breed_signs/английский_фоксхаунд.txt diff --git a/server/services/descriptions/repository/breed_signs/аппенцеллер_зенненхунд.txt b/server/modules/descriptions/repository/breed_signs/аппенцеллер_зенненхунд.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/аппенцеллер_зенненхунд.txt rename to server/modules/descriptions/repository/breed_signs/аппенцеллер_зенненхунд.txt diff --git a/server/services/descriptions/repository/breed_signs/аффенпинчер.txt b/server/modules/descriptions/repository/breed_signs/аффенпинчер.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/аффенпинчер.txt rename to server/modules/descriptions/repository/breed_signs/аффенпинчер.txt diff --git a/server/services/descriptions/repository/breed_signs/басенджи.txt b/server/modules/descriptions/repository/breed_signs/басенджи.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/басенджи.txt rename to server/modules/descriptions/repository/breed_signs/басенджи.txt diff --git a/server/services/descriptions/repository/breed_signs/бассет_хаунд.txt b/server/modules/descriptions/repository/breed_signs/бассет_хаунд.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/бассет_хаунд.txt rename to server/modules/descriptions/repository/breed_signs/бассет_хаунд.txt diff --git a/server/services/descriptions/repository/breed_signs/бедлингтон-терьер.txt b/server/modules/descriptions/repository/breed_signs/бедлингтон-терьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/бедлингтон-терьер.txt rename to server/modules/descriptions/repository/breed_signs/бедлингтон-терьер.txt diff --git a/server/services/descriptions/repository/breed_signs/бигль.txt b/server/modules/descriptions/repository/breed_signs/бигль.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/бигль.txt rename to server/modules/descriptions/repository/breed_signs/бигль.txt diff --git a/server/services/descriptions/repository/breed_signs/бобтейл.txt b/server/modules/descriptions/repository/breed_signs/бобтейл.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/бобтейл.txt rename to server/modules/descriptions/repository/breed_signs/бобтейл.txt diff --git a/server/services/descriptions/repository/breed_signs/боксер.txt b/server/modules/descriptions/repository/breed_signs/боксер.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/боксер.txt rename to server/modules/descriptions/repository/breed_signs/боксер.txt diff --git a/server/services/descriptions/repository/breed_signs/большой_швейцарский_зенненхунд.txt b/server/modules/descriptions/repository/breed_signs/большой_швейцарский_зенненхунд.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/большой_швейцарский_зенненхунд.txt rename to server/modules/descriptions/repository/breed_signs/большой_швейцарский_зенненхунд.txt diff --git a/server/services/descriptions/repository/breed_signs/бордер-колли.txt b/server/modules/descriptions/repository/breed_signs/бордер-колли.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/бордер-колли.txt rename to server/modules/descriptions/repository/breed_signs/бордер-колли.txt diff --git a/server/services/descriptions/repository/breed_signs/бордер-терьер.txt b/server/modules/descriptions/repository/breed_signs/бордер-терьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/бордер-терьер.txt rename to server/modules/descriptions/repository/breed_signs/бордер-терьер.txt diff --git a/server/services/descriptions/repository/breed_signs/бостон-терьер.txt b/server/modules/descriptions/repository/breed_signs/бостон-терьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/бостон-терьер.txt rename to server/modules/descriptions/repository/breed_signs/бостон-терьер.txt diff --git a/server/services/descriptions/repository/breed_signs/бретонский_эпаньоль.txt b/server/modules/descriptions/repository/breed_signs/бретонский_эпаньоль.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/бретонский_эпаньоль.txt rename to server/modules/descriptions/repository/breed_signs/бретонский_эпаньоль.txt diff --git a/server/services/descriptions/repository/breed_signs/бриар.txt b/server/modules/descriptions/repository/breed_signs/бриар.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/бриар.txt rename to server/modules/descriptions/repository/breed_signs/бриар.txt diff --git a/server/services/descriptions/repository/breed_signs/бульмастиф.txt b/server/modules/descriptions/repository/breed_signs/бульмастиф.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/бульмастиф.txt rename to server/modules/descriptions/repository/breed_signs/бульмастиф.txt diff --git a/server/services/descriptions/repository/breed_signs/веймаранер.txt b/server/modules/descriptions/repository/breed_signs/веймаранер.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/веймаранер.txt rename to server/modules/descriptions/repository/breed_signs/веймаранер.txt diff --git a/server/services/descriptions/repository/breed_signs/вельш-корги_кардиган.txt b/server/modules/descriptions/repository/breed_signs/вельш-корги_кардиган.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/вельш-корги_кардиган.txt rename to server/modules/descriptions/repository/breed_signs/вельш-корги_кардиган.txt diff --git a/server/services/descriptions/repository/breed_signs/вельш-корги_пемброк.txt b/server/modules/descriptions/repository/breed_signs/вельш-корги_пемброк.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/вельш-корги_пемброк.txt rename to server/modules/descriptions/repository/breed_signs/вельш-корги_пемброк.txt diff --git a/server/services/descriptions/repository/breed_signs/вельш-спрингер-спаниель.txt b/server/modules/descriptions/repository/breed_signs/вельш-спрингер-спаниель.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/вельш-спрингер-спаниель.txt rename to server/modules/descriptions/repository/breed_signs/вельш-спрингер-спаниель.txt diff --git a/server/services/descriptions/repository/breed_signs/венгерская_выжла.txt b/server/modules/descriptions/repository/breed_signs/венгерская_выжла.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/венгерская_выжла.txt rename to server/modules/descriptions/repository/breed_signs/венгерская_выжла.txt diff --git a/server/services/descriptions/repository/breed_signs/вест-хайленд-уайт-терьер.txt b/server/modules/descriptions/repository/breed_signs/вест-хайленд-уайт-терьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/вест-хайленд-уайт-терьер.txt rename to server/modules/descriptions/repository/breed_signs/вест-хайленд-уайт-терьер.txt diff --git a/server/services/descriptions/repository/breed_signs/гаванский_бишон.txt b/server/modules/descriptions/repository/breed_signs/гаванский_бишон.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/гаванский_бишон.txt rename to server/modules/descriptions/repository/breed_signs/гаванский_бишон.txt diff --git a/server/services/descriptions/repository/breed_signs/гиеновидная_собака.txt b/server/modules/descriptions/repository/breed_signs/гиеновидная_собака.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/гиеновидная_собака.txt rename to server/modules/descriptions/repository/breed_signs/гиеновидная_собака.txt diff --git a/server/services/descriptions/repository/breed_signs/грюнендаль.txt b/server/modules/descriptions/repository/breed_signs/грюнендаль.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/грюнендаль.txt rename to server/modules/descriptions/repository/breed_signs/грюнендаль.txt diff --git a/server/services/descriptions/repository/breed_signs/денди-динмонт-терьер.txt b/server/modules/descriptions/repository/breed_signs/денди-динмонт-терьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/денди-динмонт-терьер.txt rename to server/modules/descriptions/repository/breed_signs/денди-динмонт-терьер.txt diff --git a/server/services/descriptions/repository/breed_signs/динго.txt b/server/modules/descriptions/repository/breed_signs/динго.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/динго.txt rename to server/modules/descriptions/repository/breed_signs/динго.txt diff --git a/server/services/descriptions/repository/breed_signs/дирхаунд.txt b/server/modules/descriptions/repository/breed_signs/дирхаунд.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/дирхаунд.txt rename to server/modules/descriptions/repository/breed_signs/дирхаунд.txt diff --git a/server/services/descriptions/repository/breed_signs/доберман.txt b/server/modules/descriptions/repository/breed_signs/доберман.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/доберман.txt rename to server/modules/descriptions/repository/breed_signs/доберман.txt diff --git a/server/services/descriptions/repository/breed_signs/дхоль.txt b/server/modules/descriptions/repository/breed_signs/дхоль.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/дхоль.txt rename to server/modules/descriptions/repository/breed_signs/дхоль.txt diff --git a/server/services/descriptions/repository/breed_signs/жесткошёрстный_фокстерьер.txt b/server/modules/descriptions/repository/breed_signs/жесткошёрстный_фокстерьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/жесткошёрстный_фокстерьер.txt rename to server/modules/descriptions/repository/breed_signs/жесткошёрстный_фокстерьер.txt diff --git a/server/services/descriptions/repository/breed_signs/золотистый_ретривер.txt b/server/modules/descriptions/repository/breed_signs/золотистый_ретривер.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/золотистый_ретривер.txt rename to server/modules/descriptions/repository/breed_signs/золотистый_ретривер.txt diff --git a/server/services/descriptions/repository/breed_signs/ирландский_волкодав.txt b/server/modules/descriptions/repository/breed_signs/ирландский_волкодав.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/ирландский_волкодав.txt rename to server/modules/descriptions/repository/breed_signs/ирландский_волкодав.txt diff --git a/server/services/descriptions/repository/breed_signs/ирландский_красный_сеттер.txt b/server/modules/descriptions/repository/breed_signs/ирландский_красный_сеттер.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/ирландский_красный_сеттер.txt rename to server/modules/descriptions/repository/breed_signs/ирландский_красный_сеттер.txt diff --git a/server/services/descriptions/repository/breed_signs/ирландский_мягкошёрстный_пшеничный_терьер.txt b/server/modules/descriptions/repository/breed_signs/ирландский_мягкошёрстный_пшеничный_терьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/ирландский_мягкошёрстный_пшеничный_терьер.txt rename to server/modules/descriptions/repository/breed_signs/ирландский_мягкошёрстный_пшеничный_терьер.txt diff --git a/server/services/descriptions/repository/breed_signs/ирландский_терьер.txt b/server/modules/descriptions/repository/breed_signs/ирландский_терьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/ирландский_терьер.txt rename to server/modules/descriptions/repository/breed_signs/ирландский_терьер.txt diff --git a/server/services/descriptions/repository/breed_signs/йоркширский_терьер.txt b/server/modules/descriptions/repository/breed_signs/йоркширский_терьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/йоркширский_терьер.txt rename to server/modules/descriptions/repository/breed_signs/йоркширский_терьер.txt diff --git a/server/services/descriptions/repository/breed_signs/карликовый _пинчер.txt b/server/modules/descriptions/repository/breed_signs/карликовый _пинчер.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/карликовый _пинчер.txt rename to server/modules/descriptions/repository/breed_signs/карликовый _пинчер.txt diff --git a/server/services/descriptions/repository/breed_signs/кеесхонд.txt b/server/modules/descriptions/repository/breed_signs/кеесхонд.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/кеесхонд.txt rename to server/modules/descriptions/repository/breed_signs/кеесхонд.txt diff --git a/server/services/descriptions/repository/breed_signs/керн-терьер.txt b/server/modules/descriptions/repository/breed_signs/керн-терьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/керн-терьер.txt rename to server/modules/descriptions/repository/breed_signs/керн-терьер.txt diff --git a/server/services/descriptions/repository/breed_signs/керри-блю-терьер.txt b/server/modules/descriptions/repository/breed_signs/керри-блю-терьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/керри-блю-терьер.txt rename to server/modules/descriptions/repository/breed_signs/керри-блю-терьер.txt diff --git a/server/services/descriptions/repository/breed_signs/кинг-чарльз-спаниель.txt b/server/modules/descriptions/repository/breed_signs/кинг-чарльз-спаниель.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/кинг-чарльз-спаниель.txt rename to server/modules/descriptions/repository/breed_signs/кинг-чарльз-спаниель.txt diff --git a/server/services/descriptions/repository/breed_signs/кламбер-спаниель.txt b/server/modules/descriptions/repository/breed_signs/кламбер-спаниель.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/кламбер-спаниель.txt rename to server/modules/descriptions/repository/breed_signs/кламбер-спаниель.txt diff --git a/server/services/descriptions/repository/breed_signs/кокер-спаниель.txt b/server/modules/descriptions/repository/breed_signs/кокер-спаниель.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/кокер-спаниель.txt rename to server/modules/descriptions/repository/breed_signs/кокер-спаниель.txt diff --git a/server/services/descriptions/repository/breed_signs/колли.txt b/server/modules/descriptions/repository/breed_signs/колли.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/колли.txt rename to server/modules/descriptions/repository/breed_signs/колли.txt diff --git a/server/services/descriptions/repository/breed_signs/комондор.txt b/server/modules/descriptions/repository/breed_signs/комондор.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/комондор.txt rename to server/modules/descriptions/repository/breed_signs/комондор.txt diff --git a/server/services/descriptions/repository/breed_signs/континентальный_той-спаниель.txt b/server/modules/descriptions/repository/breed_signs/континентальный_той-спаниель.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/континентальный_той-спаниель.txt rename to server/modules/descriptions/repository/breed_signs/континентальный_той-спаниель.txt diff --git a/server/services/descriptions/repository/breed_signs/крапчато-голубой_кунхаунд.txt b/server/modules/descriptions/repository/breed_signs/крапчато-голубой_кунхаунд.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/крапчато-голубой_кунхаунд.txt rename to server/modules/descriptions/repository/breed_signs/крапчато-голубой_кунхаунд.txt diff --git a/server/services/descriptions/repository/breed_signs/красный_кунхаунд.txt b/server/modules/descriptions/repository/breed_signs/красный_кунхаунд.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/красный_кунхаунд.txt rename to server/modules/descriptions/repository/breed_signs/красный_кунхаунд.txt diff --git a/server/services/descriptions/repository/breed_signs/ксолоитцкуинтли.txt b/server/modules/descriptions/repository/breed_signs/ксолоитцкуинтли.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/ксолоитцкуинтли.txt rename to server/modules/descriptions/repository/breed_signs/ксолоитцкуинтли.txt diff --git a/server/services/descriptions/repository/breed_signs/кувас.txt b/server/modules/descriptions/repository/breed_signs/кувас.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/кувас.txt rename to server/modules/descriptions/repository/breed_signs/кувас.txt diff --git a/server/services/descriptions/repository/breed_signs/курцхаар.txt b/server/modules/descriptions/repository/breed_signs/курцхаар.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/курцхаар.txt rename to server/modules/descriptions/repository/breed_signs/курцхаар.txt diff --git a/server/services/descriptions/repository/breed_signs/курчавошёрстный_ретривер.txt b/server/modules/descriptions/repository/breed_signs/курчавошёрстный_ретривер.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/курчавошёрстный_ретривер.txt rename to server/modules/descriptions/repository/breed_signs/курчавошёрстный_ретривер.txt diff --git a/server/services/descriptions/repository/breed_signs/лабрадор-ретривер.txt b/server/modules/descriptions/repository/breed_signs/лабрадор-ретривер.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/лабрадор-ретривер.txt rename to server/modules/descriptions/repository/breed_signs/лабрадор-ретривер.txt diff --git a/server/services/descriptions/repository/breed_signs/левретка.txt b/server/modules/descriptions/repository/breed_signs/левретка.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/левретка.txt rename to server/modules/descriptions/repository/breed_signs/левретка.txt diff --git a/server/services/descriptions/repository/breed_signs/лейкленд-терьер.txt b/server/modules/descriptions/repository/breed_signs/лейкленд-терьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/лейкленд-терьер.txt rename to server/modules/descriptions/repository/breed_signs/лейкленд-терьер.txt diff --git a/server/services/descriptions/repository/breed_signs/леонбергер.txt b/server/modules/descriptions/repository/breed_signs/леонбергер.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/леонбергер.txt rename to server/modules/descriptions/repository/breed_signs/леонбергер.txt diff --git a/server/services/descriptions/repository/breed_signs/лхасский_апсо.txt b/server/modules/descriptions/repository/breed_signs/лхасский_апсо.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/лхасский_апсо.txt rename to server/modules/descriptions/repository/breed_signs/лхасский_апсо.txt diff --git a/server/services/descriptions/repository/breed_signs/маламут.txt b/server/modules/descriptions/repository/breed_signs/маламут.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/маламут.txt rename to server/modules/descriptions/repository/breed_signs/маламут.txt diff --git a/server/services/descriptions/repository/breed_signs/малинуа.txt b/server/modules/descriptions/repository/breed_signs/малинуа.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/малинуа.txt rename to server/modules/descriptions/repository/breed_signs/малинуа.txt diff --git a/server/services/descriptions/repository/breed_signs/малые_бельгийские_собаки.txt b/server/modules/descriptions/repository/breed_signs/малые_бельгийские_собаки.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/малые_бельгийские_собаки.txt rename to server/modules/descriptions/repository/breed_signs/малые_бельгийские_собаки.txt diff --git a/server/services/descriptions/repository/breed_signs/мальтийская_болонка.txt b/server/modules/descriptions/repository/breed_signs/мальтийская_болонка.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/мальтийская_болонка.txt rename to server/modules/descriptions/repository/breed_signs/мальтийская_болонка.txt diff --git a/server/services/descriptions/repository/breed_signs/миниатюрный_пудель.txt b/server/modules/descriptions/repository/breed_signs/миниатюрный_пудель.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/миниатюрный_пудель.txt rename to server/modules/descriptions/repository/breed_signs/миниатюрный_пудель.txt diff --git a/server/services/descriptions/repository/breed_signs/миттельшнауцер.txt b/server/modules/descriptions/repository/breed_signs/миттельшнауцер.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/миттельшнауцер.txt rename to server/modules/descriptions/repository/breed_signs/миттельшнауцер.txt diff --git a/server/services/descriptions/repository/breed_signs/мопс.txt b/server/modules/descriptions/repository/breed_signs/мопс.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/мопс.txt rename to server/modules/descriptions/repository/breed_signs/мопс.txt diff --git a/server/services/descriptions/repository/breed_signs/немецкая_овчарка.txt b/server/modules/descriptions/repository/breed_signs/немецкая_овчарка.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/немецкая_овчарка.txt rename to server/modules/descriptions/repository/breed_signs/немецкая_овчарка.txt diff --git a/server/services/descriptions/repository/breed_signs/немецкий_дог.txt b/server/modules/descriptions/repository/breed_signs/немецкий_дог.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/немецкий_дог.txt rename to server/modules/descriptions/repository/breed_signs/немецкий_дог.txt diff --git a/server/services/descriptions/repository/breed_signs/норвежский_серый_элкхунд.txt b/server/modules/descriptions/repository/breed_signs/норвежский_серый_элкхунд.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/норвежский_серый_элкхунд.txt rename to server/modules/descriptions/repository/breed_signs/норвежский_серый_элкхунд.txt diff --git a/server/services/descriptions/repository/breed_signs/норвич-терьер.txt b/server/modules/descriptions/repository/breed_signs/норвич-терьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/норвич-терьер.txt rename to server/modules/descriptions/repository/breed_signs/норвич-терьер.txt diff --git a/server/services/descriptions/repository/breed_signs/норфолк-терьер.txt b/server/modules/descriptions/repository/breed_signs/норфолк-терьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/норфолк-терьер.txt rename to server/modules/descriptions/repository/breed_signs/норфолк-терьер.txt diff --git a/server/services/descriptions/repository/breed_signs/ньюфаундленд.txt b/server/modules/descriptions/repository/breed_signs/ньюфаундленд.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/ньюфаундленд.txt rename to server/modules/descriptions/repository/breed_signs/ньюфаундленд.txt diff --git a/server/services/descriptions/repository/breed_signs/оттерхаунд.txt b/server/modules/descriptions/repository/breed_signs/оттерхаунд.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/оттерхаунд.txt rename to server/modules/descriptions/repository/breed_signs/оттерхаунд.txt diff --git a/server/services/descriptions/repository/breed_signs/пекинес.txt b/server/modules/descriptions/repository/breed_signs/пекинес.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/пекинес.txt rename to server/modules/descriptions/repository/breed_signs/пекинес.txt diff --git a/server/services/descriptions/repository/breed_signs/пиренейская _горная_собака.txt b/server/modules/descriptions/repository/breed_signs/пиренейская _горная_собака.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/пиренейская _горная_собака.txt rename to server/modules/descriptions/repository/breed_signs/пиренейская _горная_собака.txt diff --git a/server/services/descriptions/repository/breed_signs/поденко_ибиценко.txt b/server/modules/descriptions/repository/breed_signs/поденко_ибиценко.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/поденко_ибиценко.txt rename to server/modules/descriptions/repository/breed_signs/поденко_ибиценко.txt diff --git a/server/services/descriptions/repository/breed_signs/померанский_шпиц.txt b/server/modules/descriptions/repository/breed_signs/померанский_шпиц.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/померанский_шпиц.txt rename to server/modules/descriptions/repository/breed_signs/померанский_шпиц.txt diff --git a/server/services/descriptions/repository/breed_signs/прямошёрстный_ретривер.txt b/server/modules/descriptions/repository/breed_signs/прямошёрстный_ретривер.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/прямошёрстный_ретривер.txt rename to server/modules/descriptions/repository/breed_signs/прямошёрстный_ретривер.txt diff --git a/server/services/descriptions/repository/breed_signs/ризеншнауцер.txt b/server/modules/descriptions/repository/breed_signs/ризеншнауцер.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/ризеншнауцер.txt rename to server/modules/descriptions/repository/breed_signs/ризеншнауцер.txt diff --git a/server/services/descriptions/repository/breed_signs/родезийский риджбек.txt b/server/modules/descriptions/repository/breed_signs/родезийский риджбек.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/родезийский риджбек.txt rename to server/modules/descriptions/repository/breed_signs/родезийский риджбек.txt diff --git a/server/services/descriptions/repository/breed_signs/ротвейлер.txt b/server/modules/descriptions/repository/breed_signs/ротвейлер.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/ротвейлер.txt rename to server/modules/descriptions/repository/breed_signs/ротвейлер.txt diff --git a/server/services/descriptions/repository/breed_signs/русская_псовая_борзая.txt b/server/modules/descriptions/repository/breed_signs/русская_псовая_борзая.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/русская_псовая_борзая.txt rename to server/modules/descriptions/repository/breed_signs/русская_псовая_борзая.txt diff --git a/server/services/descriptions/repository/breed_signs/русский_той.txt b/server/modules/descriptions/repository/breed_signs/русский_той.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/русский_той.txt rename to server/modules/descriptions/repository/breed_signs/русский_той.txt diff --git a/server/services/descriptions/repository/breed_signs/салюки.txt b/server/modules/descriptions/repository/breed_signs/салюки.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/салюки.txt rename to server/modules/descriptions/repository/breed_signs/салюки.txt diff --git a/server/services/descriptions/repository/breed_signs/самоед.txt b/server/modules/descriptions/repository/breed_signs/самоед.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/самоед.txt rename to server/modules/descriptions/repository/breed_signs/самоед.txt diff --git a/server/services/descriptions/repository/breed_signs/сенбернар.txt b/server/modules/descriptions/repository/breed_signs/сенбернар.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/сенбернар.txt rename to server/modules/descriptions/repository/breed_signs/сенбернар.txt diff --git a/server/services/descriptions/repository/breed_signs/сибирский_хаски.txt b/server/modules/descriptions/repository/breed_signs/сибирский_хаски.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/сибирский_хаски.txt rename to server/modules/descriptions/repository/breed_signs/сибирский_хаски.txt diff --git a/server/services/descriptions/repository/breed_signs/силихем-терьер.txt b/server/modules/descriptions/repository/breed_signs/силихем-терьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/силихем-терьер.txt rename to server/modules/descriptions/repository/breed_signs/силихем-терьер.txt diff --git a/server/services/descriptions/repository/breed_signs/стандартный_пудель.txt b/server/modules/descriptions/repository/breed_signs/стандартный_пудель.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/стандартный_пудель.txt rename to server/modules/descriptions/repository/breed_signs/стандартный_пудель.txt diff --git a/server/services/descriptions/repository/breed_signs/стаффордширский_бультерьер.txt b/server/modules/descriptions/repository/breed_signs/стаффордширский_бультерьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/стаффордширский_бультерьер.txt rename to server/modules/descriptions/repository/breed_signs/стаффордширский_бультерьер.txt diff --git a/server/services/descriptions/repository/breed_signs/суссекс-спаниель.txt b/server/modules/descriptions/repository/breed_signs/суссекс-спаниель.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/суссекс-спаниель.txt rename to server/modules/descriptions/repository/breed_signs/суссекс-спаниель.txt diff --git a/server/services/descriptions/repository/breed_signs/схипперке.txt b/server/modules/descriptions/repository/breed_signs/схипперке.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/схипперке.txt rename to server/modules/descriptions/repository/breed_signs/схипперке.txt diff --git a/server/services/descriptions/repository/breed_signs/тибетский_мастиф.txt b/server/modules/descriptions/repository/breed_signs/тибетский_мастиф.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/тибетский_мастиф.txt rename to server/modules/descriptions/repository/breed_signs/тибетский_мастиф.txt diff --git a/server/services/descriptions/repository/breed_signs/тибетский_терьер.txt b/server/modules/descriptions/repository/breed_signs/тибетский_терьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/тибетский_терьер.txt rename to server/modules/descriptions/repository/breed_signs/тибетский_терьер.txt diff --git a/server/services/descriptions/repository/breed_signs/той_пудель.txt b/server/modules/descriptions/repository/breed_signs/той_пудель.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/той_пудель.txt rename to server/modules/descriptions/repository/breed_signs/той_пудель.txt diff --git a/server/services/descriptions/repository/breed_signs/триин-уокер_кунхаунд.txt b/server/modules/descriptions/repository/breed_signs/триин-уокер_кунхаунд.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/триин-уокер_кунхаунд.txt rename to server/modules/descriptions/repository/breed_signs/триин-уокер_кунхаунд.txt diff --git a/server/services/descriptions/repository/breed_signs/уиппет.txt b/server/modules/descriptions/repository/breed_signs/уиппет.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/уиппет.txt rename to server/modules/descriptions/repository/breed_signs/уиппет.txt diff --git a/server/services/descriptions/repository/breed_signs/фландрский_бувье.txt b/server/modules/descriptions/repository/breed_signs/фландрский_бувье.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/фландрский_бувье.txt rename to server/modules/descriptions/repository/breed_signs/фландрский_бувье.txt diff --git a/server/services/descriptions/repository/breed_signs/французский_бульдог.txt b/server/modules/descriptions/repository/breed_signs/французский_бульдог.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/французский_бульдог.txt rename to server/modules/descriptions/repository/breed_signs/французский_бульдог.txt diff --git a/server/services/descriptions/repository/breed_signs/цвергшнауцер.txt b/server/modules/descriptions/repository/breed_signs/цвергшнауцер.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/цвергшнауцер.txt rename to server/modules/descriptions/repository/breed_signs/цвергшнауцер.txt diff --git a/server/services/descriptions/repository/breed_signs/чау-чау.txt b/server/modules/descriptions/repository/breed_signs/чау-чау.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/чау-чау.txt rename to server/modules/descriptions/repository/breed_signs/чау-чау.txt diff --git a/server/services/descriptions/repository/breed_signs/чесапик-бей-ретривер.txt b/server/modules/descriptions/repository/breed_signs/чесапик-бей-ретривер.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/чесапик-бей-ретривер.txt rename to server/modules/descriptions/repository/breed_signs/чесапик-бей-ретривер.txt diff --git a/server/services/descriptions/repository/breed_signs/чихуахуа.txt b/server/modules/descriptions/repository/breed_signs/чихуахуа.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/чихуахуа.txt rename to server/modules/descriptions/repository/breed_signs/чихуахуа.txt diff --git a/server/services/descriptions/repository/breed_signs/чёрно-подпалый_кунхаунд.txt b/server/modules/descriptions/repository/breed_signs/чёрно-подпалый_кунхаунд.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/чёрно-подпалый_кунхаунд.txt rename to server/modules/descriptions/repository/breed_signs/чёрно-подпалый_кунхаунд.txt diff --git a/server/services/descriptions/repository/breed_signs/шелти.txt b/server/modules/descriptions/repository/breed_signs/шелти.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/шелти.txt rename to server/modules/descriptions/repository/breed_signs/шелти.txt diff --git a/server/services/descriptions/repository/breed_signs/ши-тцу.txt b/server/modules/descriptions/repository/breed_signs/ши-тцу.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/ши-тцу.txt rename to server/modules/descriptions/repository/breed_signs/ши-тцу.txt diff --git a/server/services/descriptions/repository/breed_signs/шиба_ину.txt b/server/modules/descriptions/repository/breed_signs/шиба_ину.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/шиба_ину.txt rename to server/modules/descriptions/repository/breed_signs/шиба_ину.txt diff --git a/server/services/descriptions/repository/breed_signs/шотландский_сеттер.txt b/server/modules/descriptions/repository/breed_signs/шотландский_сеттер.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/шотландский_сеттер.txt rename to server/modules/descriptions/repository/breed_signs/шотландский_сеттер.txt diff --git a/server/services/descriptions/repository/breed_signs/шотландский_терьер.txt b/server/modules/descriptions/repository/breed_signs/шотландский_терьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/шотландский_терьер.txt rename to server/modules/descriptions/repository/breed_signs/шотландский_терьер.txt diff --git a/server/services/descriptions/repository/breed_signs/энтлебухер_зенненхунд.txt b/server/modules/descriptions/repository/breed_signs/энтлебухер_зенненхунд.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/энтлебухер_зенненхунд.txt rename to server/modules/descriptions/repository/breed_signs/энтлебухер_зенненхунд.txt diff --git a/server/services/descriptions/repository/breed_signs/эрдельтерьер.txt b/server/modules/descriptions/repository/breed_signs/эрдельтерьер.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/эрдельтерьер.txt rename to server/modules/descriptions/repository/breed_signs/эрдельтерьер.txt diff --git a/server/services/descriptions/repository/breed_signs/японский хин.txt b/server/modules/descriptions/repository/breed_signs/японский хин.txt similarity index 100% rename from server/services/descriptions/repository/breed_signs/японский хин.txt rename to server/modules/descriptions/repository/breed_signs/японский хин.txt diff --git a/server/services/descriptions/repository/repository.py b/server/modules/descriptions/repository/repository.py similarity index 50% rename from server/services/descriptions/repository/repository.py rename to server/modules/descriptions/repository/repository.py index 9b248b3..aa7d51c 100644 --- a/server/services/descriptions/repository/repository.py +++ b/server/modules/descriptions/repository/repository.py @@ -3,7 +3,8 @@ from pathlib import Path from aiocache import cached, Cache # type: ignore -from server.services.descriptions.domain import Breed +from server.infra.db import AsyncDB +from server.modules.descriptions.domain import Breed class ACharactersRepository(metaclass=ABCMeta): @@ -21,7 +22,42 @@ class CharactersRepository(ACharactersRepository): @cached(ttl=60, cache=Cache.MEMORY) async def get_characters(self) -> list[Breed]: - breed_dir = Path("server/services/descriptions/repository/breed_descriptions") + breed_dir = Path("server/modules/descriptions/repository/breed_descriptions") + breeds: list[Breed] = [] + + # Идем по каждому текстовому файлу с описанием породы + for breed_file in breed_dir.glob("*.txt"): + breed_name = breed_file.stem # имя файла без расширения - название породы + description = breed_file.read_text( + encoding="utf-8" + ) # читаем описание из файла + breeds.append( + Breed( + name=breed_name.replace("_", " "), + alias=breed_file.stem, + description=description.strip(), + ) + ) + breeds.sort(key=lambda b: b.name) + return breeds + + async def get_character(self, alias: str) -> Breed | None: + breeds = await self.get_characters() + data = [b for b in breeds if b.alias == alias] + if len(data) == 0: + return None + return data[0] + + +class PGCharactersRepository(ACharactersRepository): + _db: AsyncDB + + def __init__(self, db: AsyncDB): + self._db = db + + @cached(ttl=60, cache=Cache.MEMORY) + async def get_characters(self) -> list[Breed]: + breed_dir = Path("server/modules/descriptions/repository/breed_descriptions") breeds: list[Breed] = [] # Идем по каждому текстовому файлу с описанием породы diff --git a/server/services/descriptions/service.py b/server/modules/descriptions/service.py similarity index 75% rename from server/services/descriptions/service.py rename to server/modules/descriptions/service.py index 33d0ad2..d0bac29 100644 --- a/server/services/descriptions/service.py +++ b/server/modules/descriptions/service.py @@ -1,5 +1,5 @@ -from server.services.descriptions.domain import Breed -from server.services.descriptions.repository import ACharactersRepository +from server.modules.descriptions.domain import Breed +from server.modules.descriptions.repository import ACharactersRepository class CharactersService: diff --git a/server/modules/rate/domain/__init__.py b/server/modules/rate/domain/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/server/modules/rate/repository/__init__.py b/server/modules/rate/repository/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/server/modules/rate/service/__init__.py b/server/modules/rate/service/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/server/services/recognizer/__init__.py b/server/modules/recognizer/__init__.py similarity index 53% rename from server/services/recognizer/__init__.py rename to server/modules/recognizer/__init__.py index 2a7f6b1..279b8b1 100644 --- a/server/services/recognizer/__init__.py +++ b/server/modules/recognizer/__init__.py @@ -1,7 +1,7 @@ -from server.services.recognizer.repository import ( +from server.modules.recognizer.repository import ( RecognizerRepository, ARecognizerRepository, ) -from server.services.recognizer.service import RecognizerService +from server.modules.recognizer.service import RecognizerService __all__ = ("RecognizerRepository", "ARecognizerRepository", "RecognizerService") diff --git a/server/modules/recognizer/domain.py b/server/modules/recognizer/domain.py new file mode 100644 index 0000000..e69de29 diff --git a/server/services/recognizer/repository/__init__.py b/server/modules/recognizer/repository/__init__.py similarity index 64% rename from server/services/recognizer/repository/__init__.py rename to server/modules/recognizer/repository/__init__.py index 6f6143f..5c7799a 100644 --- a/server/services/recognizer/repository/__init__.py +++ b/server/modules/recognizer/repository/__init__.py @@ -1,4 +1,4 @@ -from server.services.recognizer.repository.repository import ( +from server.modules.recognizer.repository.repository import ( RecognizerRepository, ARecognizerRepository, ) diff --git a/server/services/recognizer/repository/meta/images.json b/server/modules/recognizer/repository/meta/images.json similarity index 100% rename from server/services/recognizer/repository/meta/images.json rename to server/modules/recognizer/repository/meta/images.json diff --git a/server/services/recognizer/repository/meta/labels_cats.json b/server/modules/recognizer/repository/meta/labels_cats.json similarity index 100% rename from server/services/recognizer/repository/meta/labels_cats.json rename to server/modules/recognizer/repository/meta/labels_cats.json diff --git a/server/services/recognizer/repository/meta/labels_dogs.json b/server/modules/recognizer/repository/meta/labels_dogs.json similarity index 100% rename from server/services/recognizer/repository/meta/labels_dogs.json rename to server/modules/recognizer/repository/meta/labels_dogs.json diff --git a/server/services/recognizer/repository/repository.py b/server/modules/recognizer/repository/repository.py similarity index 77% rename from server/services/recognizer/repository/repository.py rename to server/modules/recognizer/repository/repository.py index 45bf6f6..0be0291 100644 --- a/server/services/recognizer/repository/repository.py +++ b/server/modules/recognizer/repository/repository.py @@ -29,18 +29,18 @@ class RecognizerRepository(ARecognizerRepository): @cached(ttl=60, cache=Cache.MEMORY) async def images_dogs(self) -> dict: - with open("server/services/recognizer/repository/meta/images.json", "r") as f: + with open("server/modules/recognizer/repository/meta/images.json", "r") as f: return ujson.loads(f.read())["dog"] @cached(ttl=60, cache=Cache.MEMORY) async def images_cats(self) -> dict: - with open("server/services/recognizer/repository/meta/images.json", "r") as f: + with open("server/modules/recognizer/repository/meta/images.json", "r") as f: return ujson.loads(f.read())["cat"] @lru_cache def labels_cats(self) -> dict: with open( - "server/services/recognizer/repository/meta/labels_cats.json", "r" + "server/modules/recognizer/repository/meta/labels_cats.json", "r" ) as f: data_labels = f.read() return ujson.loads(data_labels) @@ -48,7 +48,7 @@ class RecognizerRepository(ARecognizerRepository): @lru_cache def labels_dogs(self) -> dict: with open( - "server/services/recognizer/repository/meta/labels_dogs.json", "r" + "server/modules/recognizer/repository/meta/labels_dogs.json", "r" ) as f: data_labels = f.read() return ujson.loads(data_labels) diff --git a/server/services/recognizer/service.py b/server/modules/recognizer/service.py similarity index 93% rename from server/services/recognizer/service.py rename to server/modules/recognizer/service.py index 59d6737..6d22305 100644 --- a/server/services/recognizer/service.py +++ b/server/modules/recognizer/service.py @@ -8,7 +8,7 @@ os.environ["CUDA_VISIBLE_DEVICES"] = "-1" import torch from torchvision import transforms # type: ignore -from server.services.recognizer.repository import ARecognizerRepository +from server.modules.recognizer.repository import ARecognizerRepository TorchModel = NewType("TorchModel", torch.nn.Module) @@ -40,7 +40,7 @@ class RecognizerService: predicted_data = self._predict(image, DOG_MODEL) results = {} images = [] - description = {} + description: dict[str, list] = {} images_dogs = await self._repository.images_dogs() for d in predicted_data: predicted_idx, probabilities = d @@ -55,7 +55,9 @@ class RecognizerService: ], } ) - description.setdefault(name, []).append(f"/dogs-characteristics/{name.replace(" ", "_")}") + description.setdefault(name, []).append( + f"/dogs-characteristics/{name.replace(' ', '_')}" + ) results[probabilities] = name return { "results": results, diff --git a/server/services/descriptions/__init__.py b/server/services/descriptions/__init__.py deleted file mode 100644 index 9df84b7..0000000 --- a/server/services/descriptions/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -from server.services.descriptions.repository import ( - CharactersRepository, - ACharactersRepository, -) -from server.services.descriptions.service import CharactersService -from server.services.descriptions.domain import Breed - -__all__ = ( - "CharactersRepository", - "ACharactersRepository", - "CharactersService", - "Breed", -) diff --git a/server/templates/base.html b/server/templates/base.html index 7ecd5af..4bbb1af 100644 --- a/server/templates/base.html +++ b/server/templates/base.html @@ -45,6 +45,6 @@ {% block form %}{% endblock %} - + diff --git a/uv.lock b/uv.lock index 92617c7..0070fa7 100644 --- a/uv.lock +++ b/uv.lock @@ -13,7 +13,13 @@ version = "0.1.0" source = { virtual = "." } dependencies = [ { name = "aiocache" }, + { name = "aiofiles" }, + { name = "asyncpg" }, + { name = "betterconf" }, + { name = "botocore" }, + { name = "dataclasses-ujson" }, { name = "granian" }, + { name = "inject" }, { name = "jinja2" }, { name = "litestar" }, { name = "markdown" }, @@ -22,10 +28,10 @@ dependencies = [ { name = "pillow" }, { name = "pydantic" }, { name = "ruff" }, - { name = "torch", version = "2.9.1", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform == 'darwin'" }, - { name = "torch", version = "2.9.1+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform != 'darwin'" }, - { name = "torchvision", version = "0.24.1", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "(platform_machine == 'aarch64' and sys_platform == 'linux') or sys_platform == 'darwin'" }, - { name = "torchvision", version = "0.24.1+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, + { name = "sqlalchemy" }, + { name = "torch" }, + { name = "torchvision" }, + { name = "types-aiofiles" }, { name = "types-markdown" }, { name = "types-requests" }, { name = "ujson" }, @@ -39,17 +45,21 @@ default = [ { name = "pyqt5" }, { name = "requests" }, { name = "ruff" }, - { name = "torch", version = "2.9.1", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform == 'darwin'" }, - { name = "torch", version = "2.9.1+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform != 'darwin'" }, - { name = "torchvision", version = "0.24.1", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "(platform_machine == 'aarch64' and sys_platform == 'linux') or sys_platform == 'darwin'" }, - { name = "torchvision", version = "0.24.1+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, + { name = "torch" }, + { name = "torchvision" }, { name = "types-requests" }, ] [package.metadata] requires-dist = [ { name = "aiocache" }, + { name = "aiofiles", specifier = ">=25.1.0" }, + { name = "asyncpg", specifier = ">=0.31.0" }, + { name = "betterconf", specifier = ">=4.5.0" }, + { name = "botocore", specifier = ">=1.42.9" }, + { name = "dataclasses-ujson", specifier = ">=0.0.34" }, { name = "granian", specifier = "==2.5" }, + { name = "inject", specifier = ">=5.3.0" }, { name = "jinja2", specifier = ">=3.1.6" }, { name = "litestar", specifier = "==2.18.0" }, { name = "markdown", specifier = ">=3.9" }, @@ -63,10 +73,12 @@ requires-dist = [ { name = "requests", marker = "extra == 'default'", specifier = ">=2.32.3" }, { name = "ruff", specifier = ">=0.14.5" }, { name = "ruff", marker = "extra == 'default'", specifier = ">=0.11.5" }, + { name = "sqlalchemy", specifier = ">=2.0.44" }, { name = "torch", specifier = ">=2.9.1" }, - { name = "torch", marker = "extra == 'default'", specifier = ">=2.9.1", index = "https://download.pytorch.org/whl/cpu", conflict = { package = "ai", extra = "default" } }, + { name = "torch", marker = "extra == 'default'", specifier = ">=2.9.1" }, { name = "torchvision", specifier = ">=0.24.1" }, - { name = "torchvision", marker = "extra == 'default'", specifier = ">=0.21.0", index = "https://download.pytorch.org/whl/cpu", conflict = { package = "ai", extra = "default" } }, + { name = "torchvision", marker = "extra == 'default'", specifier = ">=0.21.0" }, + { name = "types-aiofiles", specifier = ">=25.1.0.20251011" }, { name = "types-markdown", specifier = ">=3.10.0.20251106" }, { name = "types-requests", specifier = ">=2.32.4.20250913" }, { name = "types-requests", marker = "extra == 'default'", specifier = ">=2.32.0.20250328" }, @@ -84,6 +96,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/37/d7/15d67e05b235d1ed8c3ce61688fe4d84130e72af1657acadfaac3479f4cf/aiocache-0.12.3-py2.py3-none-any.whl", hash = "sha256:889086fc24710f431937b87ad3720a289f7fc31c4fd8b68e9f918b9bacd8270d", size = 28199 }, ] +[[package]] +name = "aiofiles" +version = "25.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/41/c3/534eac40372d8ee36ef40df62ec129bee4fdb5ad9706e58a29be53b2c970/aiofiles-25.1.0.tar.gz", hash = "sha256:a8d728f0a29de45dc521f18f07297428d56992a742f0cd2701ba86e44d23d5b2", size = 46354 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bc/8a/340a1555ae33d7354dbca4faa54948d76d89a27ceef032c8c3bc661d003e/aiofiles-25.1.0-py3-none-any.whl", hash = "sha256:abe311e527c862958650f9438e859c1fa7568a141b22abcd015e120e86a85695", size = 14668 }, +] + [[package]] name = "annotated-types" version = "0.7.0" @@ -106,6 +127,61 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/19/24/44299477fe7dcc9cb58d0a57d5a7588d6af2ff403fdd2d47a246c91a3246/anyio-3.7.1-py3-none-any.whl", hash = "sha256:91dee416e570e92c64041bd18b900d1d6fa78dff7048769ce5ac5ddad004fbb5", size = 80896 }, ] +[[package]] +name = "asyncpg" +version = "0.31.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/fe/cc/d18065ce2380d80b1bcce927c24a2642efd38918e33fd724bc4bca904877/asyncpg-0.31.0.tar.gz", hash = "sha256:c989386c83940bfbd787180f2b1519415e2d3d6277a70d9d0f0145ac73500735", size = 993667 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/95/11/97b5c2af72a5d0b9bc3fa30cd4b9ce22284a9a943a150fdc768763caf035/asyncpg-0.31.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c204fab1b91e08b0f47e90a75d1b3c62174dab21f670ad6c5d0f243a228f015b", size = 661111 }, + { url = "https://files.pythonhosted.org/packages/1b/71/157d611c791a5e2d0423f09f027bd499935f0906e0c2a416ce712ba51ef3/asyncpg-0.31.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:54a64f91839ba59008eccf7aad2e93d6e3de688d796f35803235ea1c4898ae1e", size = 636928 }, + { url = "https://files.pythonhosted.org/packages/2e/fc/9e3486fb2bbe69d4a867c0b76d68542650a7ff1574ca40e84c3111bb0c6e/asyncpg-0.31.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c0e0822b1038dc7253b337b0f3f676cadc4ac31b126c5d42691c39691962e403", size = 3424067 }, + { url = "https://files.pythonhosted.org/packages/12/c6/8c9d076f73f07f995013c791e018a1cd5f31823c2a3187fc8581706aa00f/asyncpg-0.31.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bef056aa502ee34204c161c72ca1f3c274917596877f825968368b2c33f585f4", size = 3518156 }, + { url = "https://files.pythonhosted.org/packages/ae/3b/60683a0baf50fbc546499cfb53132cb6835b92b529a05f6a81471ab60d0c/asyncpg-0.31.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0bfbcc5b7ffcd9b75ab1558f00db2ae07db9c80637ad1b2469c43df79d7a5ae2", size = 3319636 }, + { url = "https://files.pythonhosted.org/packages/50/dc/8487df0f69bd398a61e1792b3cba0e47477f214eff085ba0efa7eac9ce87/asyncpg-0.31.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:22bc525ebbdc24d1261ecbf6f504998244d4e3be1721784b5f64664d61fbe602", size = 3472079 }, + { url = "https://files.pythonhosted.org/packages/13/a1/c5bbeeb8531c05c89135cb8b28575ac2fac618bcb60119ee9696c3faf71c/asyncpg-0.31.0-cp313-cp313-win32.whl", hash = "sha256:f890de5e1e4f7e14023619399a471ce4b71f5418cd67a51853b9910fdfa73696", size = 527606 }, + { url = "https://files.pythonhosted.org/packages/91/66/b25ccb84a246b470eb943b0107c07edcae51804912b824054b3413995a10/asyncpg-0.31.0-cp313-cp313-win_amd64.whl", hash = "sha256:dc5f2fa9916f292e5c5c8b2ac2813763bcd7f58e130055b4ad8a0531314201ab", size = 596569 }, + { url = "https://files.pythonhosted.org/packages/3c/36/e9450d62e84a13aea6580c83a47a437f26c7ca6fa0f0fd40b6670793ea30/asyncpg-0.31.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:f6b56b91bb0ffc328c4e3ed113136cddd9deefdf5f79ab448598b9772831df44", size = 660867 }, + { url = "https://files.pythonhosted.org/packages/82/4b/1d0a2b33b3102d210439338e1beea616a6122267c0df459ff0265cd5807a/asyncpg-0.31.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:334dec28cf20d7f5bb9e45b39546ddf247f8042a690bff9b9573d00086e69cb5", size = 638349 }, + { url = "https://files.pythonhosted.org/packages/41/aa/e7f7ac9a7974f08eff9183e392b2d62516f90412686532d27e196c0f0eeb/asyncpg-0.31.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:98cc158c53f46de7bb677fd20c417e264fc02b36d901cc2a43bd6cb0dc6dbfd2", size = 3410428 }, + { url = "https://files.pythonhosted.org/packages/6f/de/bf1b60de3dede5c2731e6788617a512bc0ebd9693eac297ee74086f101d7/asyncpg-0.31.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9322b563e2661a52e3cdbc93eed3be7748b289f792e0011cb2720d278b366ce2", size = 3471678 }, + { url = "https://files.pythonhosted.org/packages/46/78/fc3ade003e22d8bd53aaf8f75f4be48f0b460fa73738f0391b9c856a9147/asyncpg-0.31.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:19857a358fc811d82227449b7ca40afb46e75b33eb8897240c3839dd8b744218", size = 3313505 }, + { url = "https://files.pythonhosted.org/packages/bf/e9/73eb8a6789e927816f4705291be21f2225687bfa97321e40cd23055e903a/asyncpg-0.31.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ba5f8886e850882ff2c2ace5732300e99193823e8107e2c53ef01c1ebfa1e85d", size = 3434744 }, + { url = "https://files.pythonhosted.org/packages/08/4b/f10b880534413c65c5b5862f79b8e81553a8f364e5238832ad4c0af71b7f/asyncpg-0.31.0-cp314-cp314-win32.whl", hash = "sha256:cea3a0b2a14f95834cee29432e4ddc399b95700eb1d51bbc5bfee8f31fa07b2b", size = 532251 }, + { url = "https://files.pythonhosted.org/packages/d3/2d/7aa40750b7a19efa5d66e67fc06008ca0f27ba1bd082e457ad82f59aba49/asyncpg-0.31.0-cp314-cp314-win_amd64.whl", hash = "sha256:04d19392716af6b029411a0264d92093b6e5e8285ae97a39957b9a9c14ea72be", size = 604901 }, + { url = "https://files.pythonhosted.org/packages/ce/fe/b9dfe349b83b9dee28cc42360d2c86b2cdce4cb551a2c2d27e156bcac84d/asyncpg-0.31.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:bdb957706da132e982cc6856bb2f7b740603472b54c3ebc77fe60ea3e57e1bd2", size = 702280 }, + { url = "https://files.pythonhosted.org/packages/6a/81/e6be6e37e560bd91e6c23ea8a6138a04fd057b08cf63d3c5055c98e81c1d/asyncpg-0.31.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6d11b198111a72f47154fa03b85799f9be63701e068b43f84ac25da0bda9cb31", size = 682931 }, + { url = "https://files.pythonhosted.org/packages/a6/45/6009040da85a1648dd5bc75b3b0a062081c483e75a1a29041ae63a0bf0dc/asyncpg-0.31.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:18c83b03bc0d1b23e6230f5bf8d4f217dc9bc08644ce0502a9d91dc9e634a9c7", size = 3581608 }, + { url = "https://files.pythonhosted.org/packages/7e/06/2e3d4d7608b0b2b3adbee0d0bd6a2d29ca0fc4d8a78f8277df04e2d1fd7b/asyncpg-0.31.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e009abc333464ff18b8f6fd146addffd9aaf63e79aa3bb40ab7a4c332d0c5e9e", size = 3498738 }, + { url = "https://files.pythonhosted.org/packages/7d/aa/7d75ede780033141c51d83577ea23236ba7d3a23593929b32b49db8ed36e/asyncpg-0.31.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:3b1fbcb0e396a5ca435a8826a87e5c2c2cc0c8c68eb6fadf82168056b0e53a8c", size = 3401026 }, + { url = "https://files.pythonhosted.org/packages/ba/7a/15e37d45e7f7c94facc1e9148c0e455e8f33c08f0b8a0b1deb2c5171771b/asyncpg-0.31.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:8df714dba348efcc162d2adf02d213e5fab1bd9f557e1305633e851a61814a7a", size = 3429426 }, + { url = "https://files.pythonhosted.org/packages/13/d5/71437c5f6ae5f307828710efbe62163974e71237d5d46ebd2869ea052d10/asyncpg-0.31.0-cp314-cp314t-win32.whl", hash = "sha256:1b41f1afb1033f2b44f3234993b15096ddc9cd71b21a42dbd87fc6a57b43d65d", size = 614495 }, + { url = "https://files.pythonhosted.org/packages/3c/d7/8fb3044eaef08a310acfe23dae9a8e2e07d305edc29a53497e52bc76eca7/asyncpg-0.31.0-cp314-cp314t-win_amd64.whl", hash = "sha256:bd4107bb7cdd0e9e65fae66a62afd3a249663b844fa34d479f6d5b3bef9c04c3", size = 706062 }, +] + +[[package]] +name = "betterconf" +version = "4.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e5/30/71b6a8d16547db3003265dc03a7a677660bc1c244c46b1a8640e53f3bd87/betterconf-4.5.0.tar.gz", hash = "sha256:aebc050d24cf8fdf837b204411c57afcbc837158a7fa21713d31b240b2a1f1d3", size = 10561 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/3c/86921e4e407f25413819e04471606c32377f47887af7873e0613f5036946/betterconf-4.5.0-py3-none-any.whl", hash = "sha256:ee6ad8ae4c49a7f977555dcb435eb258eb044e10a2f43fdd77bb67b8ff682118", size = 11769 }, +] + +[[package]] +name = "botocore" +version = "1.42.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jmespath" }, + { name = "python-dateutil" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fd/f3/2d2cfb500e2dc00b0e33e3c8743306e6330f3cf219d19e9260dab2f3d6c2/botocore-1.42.9.tar.gz", hash = "sha256:74f69bfd116cc7c8215481284957eecdb48580e071dd50cb8c64356a866abd8c", size = 14861916 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1f/2a/e9275f40042f7a09915c4be86b092cb02dc4bd74e77ab8864f485d998af1/botocore-1.42.9-py3-none-any.whl", hash = "sha256:f99ba2ca34e24c4ebec150376c815646970753c032eb84f230874b2975a185a8", size = 14537810 }, +] + [[package]] name = "certifi" version = "2025.11.12" @@ -241,6 +317,16 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30", size = 8321 }, ] +[[package]] +name = "dataclasses-ujson" +version = "0.0.34" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "types-ujson" }, + { name = "ujson" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5f/73/c8aa3fa926f3368f65ec9bb7a74aa42349ed9aa43c54391102a5f0e7ab5c/dataclasses_ujson-0.0.34.tar.gz", hash = "sha256:14b70f85ef57f55e46e0a5233b5d70dd2d40d7e3aa202cfe105c03dd23ed109c", size = 4763 } + [[package]] name = "faker" version = "38.0.0" @@ -351,6 +437,37 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0e/37/20e42e881d6cebaf72ba4ceee319c8241f35c6f7f89485bec20cfe8b6320/granian-2.5.0-cp314-cp314t-win_amd64.whl", hash = "sha256:468cb5b61ee86f2075e714ad3d4f4b3bec4b10067fcf0c8341f76fd11b08c7df", size = 2298993 }, ] +[[package]] +name = "greenlet" +version = "3.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c7/e5/40dbda2736893e3e53d25838e0f19a2b417dfc122b9989c91918db30b5d3/greenlet-3.3.0.tar.gz", hash = "sha256:a82bb225a4e9e4d653dd2fb7b8b2d36e4fb25bc0165422a11e48b88e9e6f78fb", size = 190651 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/02/2f/28592176381b9ab2cafa12829ba7b472d177f3acc35d8fbcf3673d966fff/greenlet-3.3.0-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:a1e41a81c7e2825822f4e068c48cb2196002362619e2d70b148f20a831c00739", size = 275140 }, + { url = "https://files.pythonhosted.org/packages/2c/80/fbe937bf81e9fca98c981fe499e59a3f45df2a04da0baa5c2be0dca0d329/greenlet-3.3.0-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9f515a47d02da4d30caaa85b69474cec77b7929b2e936ff7fb853d42f4bf8808", size = 599219 }, + { url = "https://files.pythonhosted.org/packages/c2/ff/7c985128f0514271b8268476af89aee6866df5eec04ac17dcfbc676213df/greenlet-3.3.0-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7d2d9fd66bfadf230b385fdc90426fcd6eb64db54b40c495b72ac0feb5766c54", size = 610211 }, + { url = "https://files.pythonhosted.org/packages/79/07/c47a82d881319ec18a4510bb30463ed6891f2ad2c1901ed5ec23d3de351f/greenlet-3.3.0-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:30a6e28487a790417d036088b3bcb3f3ac7d8babaa7d0139edbaddebf3af9492", size = 624311 }, + { url = "https://files.pythonhosted.org/packages/fd/8e/424b8c6e78bd9837d14ff7df01a9829fc883ba2ab4ea787d4f848435f23f/greenlet-3.3.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:087ea5e004437321508a8d6f20efc4cfec5e3c30118e1417ea96ed1d93950527", size = 612833 }, + { url = "https://files.pythonhosted.org/packages/b5/ba/56699ff9b7c76ca12f1cdc27a886d0f81f2189c3455ff9f65246780f713d/greenlet-3.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ab97cf74045343f6c60a39913fa59710e4bd26a536ce7ab2397adf8b27e67c39", size = 1567256 }, + { url = "https://files.pythonhosted.org/packages/1e/37/f31136132967982d698c71a281a8901daf1a8fbab935dce7c0cf15f942cc/greenlet-3.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5375d2e23184629112ca1ea89a53389dddbffcf417dad40125713d88eb5f96e8", size = 1636483 }, + { url = "https://files.pythonhosted.org/packages/7e/71/ba21c3fb8c5dce83b8c01f458a42e99ffdb1963aeec08fff5a18588d8fd7/greenlet-3.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:9ee1942ea19550094033c35d25d20726e4f1c40d59545815e1128ac58d416d38", size = 301833 }, + { url = "https://files.pythonhosted.org/packages/d7/7c/f0a6d0ede2c7bf092d00bc83ad5bafb7e6ec9b4aab2fbdfa6f134dc73327/greenlet-3.3.0-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:60c2ef0f578afb3c8d92ea07ad327f9a062547137afe91f38408f08aacab667f", size = 275671 }, + { url = "https://files.pythonhosted.org/packages/44/06/dac639ae1a50f5969d82d2e3dd9767d30d6dbdbab0e1a54010c8fe90263c/greenlet-3.3.0-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a5d554d0712ba1de0a6c94c640f7aeba3f85b3a6e1f2899c11c2c0428da9365", size = 646360 }, + { url = "https://files.pythonhosted.org/packages/e0/94/0fb76fe6c5369fba9bf98529ada6f4c3a1adf19e406a47332245ef0eb357/greenlet-3.3.0-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3a898b1e9c5f7307ebbde4102908e6cbfcb9ea16284a3abe15cab996bee8b9b3", size = 658160 }, + { url = "https://files.pythonhosted.org/packages/93/79/d2c70cae6e823fac36c3bbc9077962105052b7ef81db2f01ec3b9bf17e2b/greenlet-3.3.0-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:dcd2bdbd444ff340e8d6bdf54d2f206ccddbb3ccfdcd3c25bf4afaa7b8f0cf45", size = 671388 }, + { url = "https://files.pythonhosted.org/packages/b8/14/bab308fc2c1b5228c3224ec2bf928ce2e4d21d8046c161e44a2012b5203e/greenlet-3.3.0-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5773edda4dc00e173820722711d043799d3adb4f01731f40619e07ea2750b955", size = 660166 }, + { url = "https://files.pythonhosted.org/packages/4b/d2/91465d39164eaa0085177f61983d80ffe746c5a1860f009811d498e7259c/greenlet-3.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ac0549373982b36d5fd5d30beb8a7a33ee541ff98d2b502714a09f1169f31b55", size = 1615193 }, + { url = "https://files.pythonhosted.org/packages/42/1b/83d110a37044b92423084d52d5d5a3b3a73cafb51b547e6d7366ff62eff1/greenlet-3.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d198d2d977460358c3b3a4dc844f875d1adb33817f0613f663a656f463764ccc", size = 1683653 }, + { url = "https://files.pythonhosted.org/packages/7c/9a/9030e6f9aa8fd7808e9c31ba4c38f87c4f8ec324ee67431d181fe396d705/greenlet-3.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:73f51dd0e0bdb596fb0417e475fa3c5e32d4c83638296e560086b8d7da7c4170", size = 305387 }, + { url = "https://files.pythonhosted.org/packages/a0/66/bd6317bc5932accf351fc19f177ffba53712a202f9df10587da8df257c7e/greenlet-3.3.0-cp314-cp314t-macosx_11_0_universal2.whl", hash = "sha256:d6ed6f85fae6cdfdb9ce04c9bf7a08d666cfcfb914e7d006f44f840b46741931", size = 282638 }, + { url = "https://files.pythonhosted.org/packages/30/cf/cc81cb030b40e738d6e69502ccbd0dd1bced0588e958f9e757945de24404/greenlet-3.3.0-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d9125050fcf24554e69c4cacb086b87b3b55dc395a8b3ebe6487b045b2614388", size = 651145 }, + { url = "https://files.pythonhosted.org/packages/9c/ea/1020037b5ecfe95ca7df8d8549959baceb8186031da83d5ecceff8b08cd2/greenlet-3.3.0-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:87e63ccfa13c0a0f6234ed0add552af24cc67dd886731f2261e46e241608bee3", size = 654236 }, + { url = "https://files.pythonhosted.org/packages/69/cc/1e4bae2e45ca2fa55299f4e85854606a78ecc37fead20d69322f96000504/greenlet-3.3.0-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2662433acbca297c9153a4023fe2161c8dcfdcc91f10433171cf7e7d94ba2221", size = 662506 }, + { url = "https://files.pythonhosted.org/packages/57/b9/f8025d71a6085c441a7eaff0fd928bbb275a6633773667023d19179fe815/greenlet-3.3.0-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3c6e9b9c1527a78520357de498b0e709fb9e2f49c3a513afd5a249007261911b", size = 653783 }, + { url = "https://files.pythonhosted.org/packages/f6/c7/876a8c7a7485d5d6b5c6821201d542ef28be645aa024cfe1145b35c120c1/greenlet-3.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:286d093f95ec98fdd92fcb955003b8a3d054b4e2cab3e2707a5039e7b50520fd", size = 1614857 }, + { url = "https://files.pythonhosted.org/packages/4f/dc/041be1dff9f23dac5f48a43323cd0789cb798342011c19a248d9c9335536/greenlet-3.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6c10513330af5b8ae16f023e8ddbfb486ab355d04467c4679c5cfe4659975dd9", size = 1676034 }, +] + [[package]] name = "h11" version = "0.16.0" @@ -397,6 +514,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008 }, ] +[[package]] +name = "inject" +version = "5.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3e/b6/762d2dac6b587698abde000dc0fe85dfe9cd469cbda8856699a84adee82a/inject-5.3.0.tar.gz", hash = "sha256:bc9db0fe05a42990dbdaf570db085c409bc8d1a9dea6d06143049476b922abba", size = 26482 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/98/6e/b00ef8fe9a43aa3a6f5687b710832f0d876c0812bd0ce1c3af3e71bf7dd1/inject-5.3.0-py2.py3-none-any.whl", hash = "sha256:4758eb6c464d3e2badbbf65ac991c64752b05429d6af4c3c0e5b2765efaf7e73", size = 14349 }, +] + [[package]] name = "jinja2" version = "3.1.6" @@ -409,6 +535,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899 }, ] +[[package]] +name = "jmespath" +version = "1.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/00/2a/e867e8531cf3e36b41201936b7fa7ba7b5702dbef42922193f05c8976cd6/jmespath-1.0.1.tar.gz", hash = "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe", size = 25843 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/31/b4/b9b800c45527aadd64d5b442f9b932b00648617eb5d63d2c7a6587b7cafc/jmespath-1.0.1-py3-none-any.whl", hash = "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980", size = 20256 }, +] + [[package]] name = "kiwisolver" version = "1.4.9" @@ -839,6 +974,140 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/54/23/08c002201a8e7e1f9afba93b97deceb813252d9cfd0d3351caed123dcf97/numpy-2.3.4-cp314-cp314t-win_arm64.whl", hash = "sha256:8b5a9a39c45d852b62693d9b3f3e0fe052541f804296ff401a72a1b60edafb29", size = 10547532 }, ] +[[package]] +name = "nvidia-cublas-cu12" +version = "12.8.4.1" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/dc/61/e24b560ab2e2eaeb3c839129175fb330dfcfc29e5203196e5541a4c44682/nvidia_cublas_cu12-12.8.4.1-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:8ac4e771d5a348c551b2a426eda6193c19aa630236b418086020df5ba9667142", size = 594346921 }, +] + +[[package]] +name = "nvidia-cuda-cupti-cu12" +version = "12.8.90" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f8/02/2adcaa145158bf1a8295d83591d22e4103dbfd821bcaf6f3f53151ca4ffa/nvidia_cuda_cupti_cu12-12.8.90-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ea0cb07ebda26bb9b29ba82cda34849e73c166c18162d3913575b0c9db9a6182", size = 10248621 }, +] + +[[package]] +name = "nvidia-cuda-nvrtc-cu12" +version = "12.8.93" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/05/6b/32f747947df2da6994e999492ab306a903659555dddc0fbdeb9d71f75e52/nvidia_cuda_nvrtc_cu12-12.8.93-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl", hash = "sha256:a7756528852ef889772a84c6cd89d41dfa74667e24cca16bb31f8f061e3e9994", size = 88040029 }, +] + +[[package]] +name = "nvidia-cuda-runtime-cu12" +version = "12.8.90" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0d/9b/a997b638fcd068ad6e4d53b8551a7d30fe8b404d6f1804abf1df69838932/nvidia_cuda_runtime_cu12-12.8.90-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:adade8dcbd0edf427b7204d480d6066d33902cab2a4707dcfc48a2d0fd44ab90", size = 954765 }, +] + +[[package]] +name = "nvidia-cudnn-cu12" +version = "9.10.2.21" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-cublas-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/ba/51/e123d997aa098c61d029f76663dedbfb9bc8dcf8c60cbd6adbe42f76d049/nvidia_cudnn_cu12-9.10.2.21-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:949452be657fa16687d0930933f032835951ef0892b37d2d53824d1a84dc97a8", size = 706758467 }, +] + +[[package]] +name = "nvidia-cufft-cu12" +version = "11.3.3.83" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-nvjitlink-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/1f/13/ee4e00f30e676b66ae65b4f08cb5bcbb8392c03f54f2d5413ea99a5d1c80/nvidia_cufft_cu12-11.3.3.83-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4d2dd21ec0b88cf61b62e6b43564355e5222e4a3fb394cac0db101f2dd0d4f74", size = 193118695 }, +] + +[[package]] +name = "nvidia-cufile-cu12" +version = "1.13.1.3" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bb/fe/1bcba1dfbfb8d01be8d93f07bfc502c93fa23afa6fd5ab3fc7c1df71038a/nvidia_cufile_cu12-1.13.1.3-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1d069003be650e131b21c932ec3d8969c1715379251f8d23a1860554b1cb24fc", size = 1197834 }, +] + +[[package]] +name = "nvidia-curand-cu12" +version = "10.3.9.90" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/aa/6584b56dc84ebe9cf93226a5cde4d99080c8e90ab40f0c27bda7a0f29aa1/nvidia_curand_cu12-10.3.9.90-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:b32331d4f4df5d6eefa0554c565b626c7216f87a06a4f56fab27c3b68a830ec9", size = 63619976 }, +] + +[[package]] +name = "nvidia-cusolver-cu12" +version = "11.7.3.90" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-cublas-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, + { name = "nvidia-cusparse-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, + { name = "nvidia-nvjitlink-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/85/48/9a13d2975803e8cf2777d5ed57b87a0b6ca2cc795f9a4f59796a910bfb80/nvidia_cusolver_cu12-11.7.3.90-py3-none-manylinux_2_27_x86_64.whl", hash = "sha256:4376c11ad263152bd50ea295c05370360776f8c3427b30991df774f9fb26c450", size = 267506905 }, +] + +[[package]] +name = "nvidia-cusparse-cu12" +version = "12.5.8.93" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "nvidia-nvjitlink-cu12", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, +] +wheels = [ + { url = "https://files.pythonhosted.org/packages/c2/f5/e1854cb2f2bcd4280c44736c93550cc300ff4b8c95ebe370d0aa7d2b473d/nvidia_cusparse_cu12-12.5.8.93-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1ec05d76bbbd8b61b06a80e1eaf8cf4959c3d4ce8e711b65ebd0443bb0ebb13b", size = 288216466 }, +] + +[[package]] +name = "nvidia-cusparselt-cu12" +version = "0.7.1" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/56/79/12978b96bd44274fe38b5dde5cfb660b1d114f70a65ef962bcbbed99b549/nvidia_cusparselt_cu12-0.7.1-py3-none-manylinux2014_x86_64.whl", hash = "sha256:f1bb701d6b930d5a7cea44c19ceb973311500847f81b634d802b7b539dc55623", size = 287193691 }, +] + +[[package]] +name = "nvidia-nccl-cu12" +version = "2.27.5" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6e/89/f7a07dc961b60645dbbf42e80f2bc85ade7feb9a491b11a1e973aa00071f/nvidia_nccl_cu12-2.27.5-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ad730cf15cb5d25fe849c6e6ca9eb5b76db16a80f13f425ac68d8e2e55624457", size = 322348229 }, +] + +[[package]] +name = "nvidia-nvjitlink-cu12" +version = "12.8.93" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f6/74/86a07f1d0f42998ca31312f998bd3b9a7eff7f52378f4f270c8679c77fb9/nvidia_nvjitlink_cu12-12.8.93-py3-none-manylinux2010_x86_64.manylinux_2_12_x86_64.whl", hash = "sha256:81ff63371a7ebd6e6451970684f916be2eab07321b73c9d244dc2b4da7f73b88", size = 39254836 }, +] + +[[package]] +name = "nvidia-nvshmem-cu12" +version = "3.3.20" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3b/6c/99acb2f9eb85c29fc6f3a7ac4dccfd992e22666dd08a642b303311326a97/nvidia_nvshmem_cu12-3.3.20-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d00f26d3f9b2e3c3065be895e3059d6479ea5c638a3f38c9fec49b1b9dd7c1e5", size = 124657145 }, +] + +[[package]] +name = "nvidia-nvtx-cu12" +version = "12.8.90" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a2/eb/86626c1bbc2edb86323022371c39aa48df6fd8b0a1647bc274577f72e90b/nvidia_nvtx_cu12-12.8.90-py3-none-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5b17e2001cc0d751a5bc2c6ec6d26ad95913324a4adb86788c944f8ce9ba441f", size = 89954 }, +] + [[package]] name = "packaging" version = "25.0" @@ -1200,6 +1469,27 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, ] +[[package]] +name = "sqlalchemy" +version = "2.0.44" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "greenlet", marker = "platform_machine == 'AMD64' or platform_machine == 'WIN32' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'ppc64le' or platform_machine == 'win32' or platform_machine == 'x86_64'" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f0/f2/840d7b9496825333f532d2e3976b8eadbf52034178aac53630d09fe6e1ef/sqlalchemy-2.0.44.tar.gz", hash = "sha256:0ae7454e1ab1d780aee69fd2aae7d6b8670a581d8847f2d1e0f7ddfbf47e5a22", size = 9819830 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/45/d3/c67077a2249fdb455246e6853166360054c331db4613cda3e31ab1cadbef/sqlalchemy-2.0.44-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ff486e183d151e51b1d694c7aa1695747599bb00b9f5f604092b54b74c64a8e1", size = 2135479 }, + { url = "https://files.pythonhosted.org/packages/2b/91/eabd0688330d6fd114f5f12c4f89b0d02929f525e6bf7ff80aa17ca802af/sqlalchemy-2.0.44-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0b1af8392eb27b372ddb783b317dea0f650241cea5bd29199b22235299ca2e45", size = 2123212 }, + { url = "https://files.pythonhosted.org/packages/b0/bb/43e246cfe0e81c018076a16036d9b548c4cc649de241fa27d8d9ca6f85ab/sqlalchemy-2.0.44-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2b61188657e3a2b9ac4e8f04d6cf8e51046e28175f79464c67f2fd35bceb0976", size = 3255353 }, + { url = "https://files.pythonhosted.org/packages/b9/96/c6105ed9a880abe346b64d3b6ddef269ddfcab04f7f3d90a0bf3c5a88e82/sqlalchemy-2.0.44-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b87e7b91a5d5973dda5f00cd61ef72ad75a1db73a386b62877d4875a8840959c", size = 3260222 }, + { url = "https://files.pythonhosted.org/packages/44/16/1857e35a47155b5ad927272fee81ae49d398959cb749edca6eaa399b582f/sqlalchemy-2.0.44-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:15f3326f7f0b2bfe406ee562e17f43f36e16167af99c4c0df61db668de20002d", size = 3189614 }, + { url = "https://files.pythonhosted.org/packages/88/ee/4afb39a8ee4fc786e2d716c20ab87b5b1fb33d4ac4129a1aaa574ae8a585/sqlalchemy-2.0.44-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1e77faf6ff919aa8cd63f1c4e561cac1d9a454a191bb864d5dd5e545935e5a40", size = 3226248 }, + { url = "https://files.pythonhosted.org/packages/32/d5/0e66097fc64fa266f29a7963296b40a80d6a997b7ac13806183700676f86/sqlalchemy-2.0.44-cp313-cp313-win32.whl", hash = "sha256:ee51625c2d51f8baadf2829fae817ad0b66b140573939dd69284d2ba3553ae73", size = 2101275 }, + { url = "https://files.pythonhosted.org/packages/03/51/665617fe4f8c6450f42a6d8d69243f9420f5677395572c2fe9d21b493b7b/sqlalchemy-2.0.44-cp313-cp313-win_amd64.whl", hash = "sha256:c1c80faaee1a6c3428cecf40d16a2365bcf56c424c92c2b6f0f9ad204b899e9e", size = 2127901 }, + { url = "https://files.pythonhosted.org/packages/9c/5e/6a29fa884d9fb7ddadf6b69490a9d45fded3b38541713010dad16b77d015/sqlalchemy-2.0.44-py3-none-any.whl", hash = "sha256:19de7ca1246fbef9f9d1bff8f1ab25641569df226364a0e40457dc5457c54b05", size = 1928718 }, +] + [[package]] name = "sympy" version = "1.14.0" @@ -1215,105 +1505,97 @@ wheels = [ [[package]] name = "torch" version = "2.9.1" -source = { registry = "https://download.pytorch.org/whl/cpu" } -resolution-markers = [ - "sys_platform == 'darwin'", -] +source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "filelock", marker = "sys_platform == 'darwin'" }, - { name = "fsspec", marker = "sys_platform == 'darwin'" }, - { name = "jinja2", marker = "sys_platform == 'darwin'" }, - { name = "networkx", marker = "sys_platform == 'darwin'" }, - { name = "setuptools", marker = "sys_platform == 'darwin'" }, - { name = "sympy", marker = "sys_platform == 'darwin'" }, - { name = "typing-extensions", marker = "sys_platform == 'darwin'" }, + { name = "filelock" }, + { name = "fsspec" }, + { name = "jinja2" }, + { name = "networkx" }, + { name = "nvidia-cublas-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cuda-cupti-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cuda-nvrtc-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cuda-runtime-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cudnn-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cufft-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cufile-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-curand-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cusolver-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cusparse-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-cusparselt-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-nccl-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-nvjitlink-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-nvshmem-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "nvidia-nvtx-cu12", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "setuptools" }, + { name = "sympy" }, + { name = "triton", marker = "platform_machine == 'x86_64' and sys_platform == 'linux'" }, + { name = "typing-extensions" }, ] wheels = [ - { url = "https://download.pytorch.org/whl/cpu/torch-2.9.1-cp313-cp313t-macosx_11_0_arm64.whl" }, - { url = "https://download.pytorch.org/whl/cpu/torch-2.9.1-cp313-none-macosx_11_0_arm64.whl" }, - { url = "https://download.pytorch.org/whl/cpu/torch-2.9.1-cp314-cp314-macosx_11_0_arm64.whl" }, - { url = "https://download.pytorch.org/whl/cpu/torch-2.9.1-cp314-cp314t-macosx_11_0_arm64.whl" }, -] - -[[package]] -name = "torch" -version = "2.9.1+cpu" -source = { registry = "https://download.pytorch.org/whl/cpu" } -resolution-markers = [ - "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')", - "platform_machine == 'aarch64' and sys_platform == 'linux'", -] -dependencies = [ - { name = "filelock", marker = "sys_platform != 'darwin'" }, - { name = "fsspec", marker = "sys_platform != 'darwin'" }, - { name = "jinja2", marker = "sys_platform != 'darwin'" }, - { name = "networkx", marker = "sys_platform != 'darwin'" }, - { name = "setuptools", marker = "sys_platform != 'darwin'" }, - { name = "sympy", marker = "sys_platform != 'darwin'" }, - { name = "typing-extensions", marker = "sys_platform != 'darwin'" }, -] -wheels = [ - { url = "https://download.pytorch.org/whl/cpu/torch-2.9.1%2Bcpu-cp313-cp313-manylinux_2_28_aarch64.whl" }, - { url = "https://download.pytorch.org/whl/cpu/torch-2.9.1%2Bcpu-cp313-cp313-manylinux_2_28_x86_64.whl" }, - { url = "https://download.pytorch.org/whl/cpu/torch-2.9.1%2Bcpu-cp313-cp313-win_amd64.whl" }, - { url = "https://download.pytorch.org/whl/cpu/torch-2.9.1%2Bcpu-cp313-cp313-win_arm64.whl" }, - { url = "https://download.pytorch.org/whl/cpu/torch-2.9.1%2Bcpu-cp313-cp313t-manylinux_2_28_aarch64.whl" }, - { url = "https://download.pytorch.org/whl/cpu/torch-2.9.1%2Bcpu-cp313-cp313t-manylinux_2_28_x86_64.whl" }, - { url = "https://download.pytorch.org/whl/cpu/torch-2.9.1%2Bcpu-cp313-cp313t-win_amd64.whl" }, - { url = "https://download.pytorch.org/whl/cpu/torch-2.9.1%2Bcpu-cp314-cp314-manylinux_2_28_aarch64.whl" }, - { url = "https://download.pytorch.org/whl/cpu/torch-2.9.1%2Bcpu-cp314-cp314-manylinux_2_28_x86_64.whl" }, - { url = "https://download.pytorch.org/whl/cpu/torch-2.9.1%2Bcpu-cp314-cp314-win_amd64.whl" }, - { url = "https://download.pytorch.org/whl/cpu/torch-2.9.1%2Bcpu-cp314-cp314t-manylinux_2_28_aarch64.whl" }, - { url = "https://download.pytorch.org/whl/cpu/torch-2.9.1%2Bcpu-cp314-cp314t-manylinux_2_28_x86_64.whl" }, - { url = "https://download.pytorch.org/whl/cpu/torch-2.9.1%2Bcpu-cp314-cp314t-win_amd64.whl" }, + { url = "https://files.pythonhosted.org/packages/20/60/8fc5e828d050bddfab469b3fe78e5ab9a7e53dda9c3bdc6a43d17ce99e63/torch-2.9.1-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:c29455d2b910b98738131990394da3e50eea8291dfeb4b12de71ecf1fdeb21cb", size = 104135743 }, + { url = "https://files.pythonhosted.org/packages/f2/b7/6d3f80e6918213babddb2a37b46dbb14c15b14c5f473e347869a51f40e1f/torch-2.9.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:524de44cd13931208ba2c4bde9ec7741fd4ae6bfd06409a604fc32f6520c2bc9", size = 899749493 }, + { url = "https://files.pythonhosted.org/packages/a6/47/c7843d69d6de8938c1cbb1eba426b1d48ddf375f101473d3e31a5fc52b74/torch-2.9.1-cp313-cp313-win_amd64.whl", hash = "sha256:545844cc16b3f91e08ce3b40e9c2d77012dd33a48d505aed34b7740ed627a1b2", size = 110944162 }, + { url = "https://files.pythonhosted.org/packages/28/0e/2a37247957e72c12151b33a01e4df651d9d155dd74d8cfcbfad15a79b44a/torch-2.9.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5be4bf7496f1e3ffb1dd44b672adb1ac3f081f204c5ca81eba6442f5f634df8e", size = 74830751 }, + { url = "https://files.pythonhosted.org/packages/4b/f7/7a18745edcd7b9ca2381aa03353647bca8aace91683c4975f19ac233809d/torch-2.9.1-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:30a3e170a84894f3652434b56d59a64a2c11366b0ed5776fab33c2439396bf9a", size = 104142929 }, + { url = "https://files.pythonhosted.org/packages/f4/dd/f1c0d879f2863ef209e18823a988dc7a1bf40470750e3ebe927efdb9407f/torch-2.9.1-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:8301a7b431e51764629208d0edaa4f9e4c33e6df0f2f90b90e261d623df6a4e2", size = 899748978 }, + { url = "https://files.pythonhosted.org/packages/1f/9f/6986b83a53b4d043e36f3f898b798ab51f7f20fdf1a9b01a2720f445043d/torch-2.9.1-cp313-cp313t-win_amd64.whl", hash = "sha256:2e1c42c0ae92bf803a4b2409fdfed85e30f9027a66887f5e7dcdbc014c7531db", size = 111176995 }, + { url = "https://files.pythonhosted.org/packages/40/60/71c698b466dd01e65d0e9514b5405faae200c52a76901baf6906856f17e4/torch-2.9.1-cp313-none-macosx_11_0_arm64.whl", hash = "sha256:2c14b3da5df416cf9cb5efab83aa3056f5b8cd8620b8fde81b4987ecab730587", size = 74480347 }, + { url = "https://files.pythonhosted.org/packages/48/50/c4b5112546d0d13cc9eaa1c732b823d676a9f49ae8b6f97772f795874a03/torch-2.9.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1edee27a7c9897f4e0b7c14cfc2f3008c571921134522d5b9b5ec4ebbc69041a", size = 74433245 }, + { url = "https://files.pythonhosted.org/packages/81/c9/2628f408f0518b3bae49c95f5af3728b6ab498c8624ab1e03a43dd53d650/torch-2.9.1-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:19d144d6b3e29921f1fc70503e9f2fc572cde6a5115c0c0de2f7ca8b1483e8b6", size = 104134804 }, + { url = "https://files.pythonhosted.org/packages/28/fc/5bc91d6d831ae41bf6e9e6da6468f25330522e92347c9156eb3f1cb95956/torch-2.9.1-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:c432d04376f6d9767a9852ea0def7b47a7bbc8e7af3b16ac9cf9ce02b12851c9", size = 899747132 }, + { url = "https://files.pythonhosted.org/packages/63/5d/e8d4e009e52b6b2cf1684bde2a6be157b96fb873732542fb2a9a99e85a83/torch-2.9.1-cp314-cp314-win_amd64.whl", hash = "sha256:d187566a2cdc726fc80138c3cdb260970fab1c27e99f85452721f7759bbd554d", size = 110934845 }, + { url = "https://files.pythonhosted.org/packages/bd/b2/2d15a52516b2ea3f414643b8de68fa4cb220d3877ac8b1028c83dc8ca1c4/torch-2.9.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:cb10896a1f7fedaddbccc2017ce6ca9ecaaf990f0973bdfcf405439750118d2c", size = 74823558 }, + { url = "https://files.pythonhosted.org/packages/86/5c/5b2e5d84f5b9850cd1e71af07524d8cbb74cba19379800f1f9f7c997fc70/torch-2.9.1-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:0a2bd769944991c74acf0c4ef23603b9c777fdf7637f115605a4b2d8023110c7", size = 104145788 }, + { url = "https://files.pythonhosted.org/packages/a9/8c/3da60787bcf70add986c4ad485993026ac0ca74f2fc21410bc4eb1bb7695/torch-2.9.1-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:07c8a9660bc9414c39cac530ac83b1fb1b679d7155824144a40a54f4a47bfa73", size = 899735500 }, + { url = "https://files.pythonhosted.org/packages/db/2b/f7818f6ec88758dfd21da46b6cd46af9d1b3433e53ddbb19ad1e0da17f9b/torch-2.9.1-cp314-cp314t-win_amd64.whl", hash = "sha256:c88d3299ddeb2b35dcc31753305612db485ab6f1823e37fb29451c8b2732b87e", size = 111163659 }, ] [[package]] name = "torchvision" version = "0.24.1" -source = { registry = "https://download.pytorch.org/whl/cpu" } -resolution-markers = [ - "platform_machine == 'aarch64' and sys_platform == 'linux'", - "sys_platform == 'darwin'", -] +source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "numpy", marker = "(platform_machine == 'aarch64' and sys_platform == 'linux') or sys_platform == 'darwin'" }, - { name = "pillow", marker = "(platform_machine == 'aarch64' and sys_platform == 'linux') or sys_platform == 'darwin'" }, - { name = "torch", version = "2.9.1", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "sys_platform == 'darwin'" }, - { name = "torch", version = "2.9.1+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "platform_machine == 'aarch64' and sys_platform == 'linux'" }, + { name = "numpy" }, + { name = "pillow" }, + { name = "torch" }, ] wheels = [ - { url = "https://download.pytorch.org/whl/cpu/torchvision-0.24.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:c858f944efea2170acbda2f801613b15193be49e8419c98c204e9f5e8c65a955" }, - { url = "https://download.pytorch.org/whl/cpu/torchvision-0.24.1-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:59ddbe5779943af99a897fcd5894757ae7cffeb1c25a519b79cd9338188a8664" }, - { url = "https://download.pytorch.org/whl/cpu/torchvision-0.24.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:fff7b030a51c0b96ed0a7a163e9ccd23d4d1b6bb406decaba7ac25933f73ef91" }, - { url = "https://download.pytorch.org/whl/cpu/torchvision-0.24.1-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:0227e8cb5a418ab47e0ed0f70e0ea2fea2febb54b31ced8cd753d2efb49551df" }, - { url = "https://download.pytorch.org/whl/cpu/torchvision-0.24.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:9839848aff47d98e7724abd1a3076121db96066c32ddb319b685dfe077360f40" }, - { url = "https://download.pytorch.org/whl/cpu/torchvision-0.24.1-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:32a5ce99ec2081fd5ab304da0aa9691b6ec047d12a329c0d991c69d0a1beee45" }, - { url = "https://download.pytorch.org/whl/cpu/torchvision-0.24.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7df2c98665e3e5532da320b7d94ca228799b6c7a41700e772536bd4de2d324c7" }, - { url = "https://download.pytorch.org/whl/cpu/torchvision-0.24.1-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:e789fc690ff1307eb46540b4b8b76a8a3e06281078cf29c51b636e747373498a" }, + { url = "https://files.pythonhosted.org/packages/e4/97/ab40550f482577f2788304c27220e8ba02c63313bd74cf2f8920526aac20/torchvision-0.24.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:8a6696db7fb71eadb2c6a48602106e136c785642e598eb1533e0b27744f2cce6", size = 1891435 }, + { url = "https://files.pythonhosted.org/packages/30/65/ac0a3f9be6abdbe4e1d82c915d7e20de97e7fd0e9a277970508b015309f3/torchvision-0.24.1-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:db2125c46f9cb25dc740be831ce3ce99303cfe60439249a41b04fd9f373be671", size = 2338718 }, + { url = "https://files.pythonhosted.org/packages/10/b5/5bba24ff9d325181508501ed7f0c3de8ed3dd2edca0784d48b144b6c5252/torchvision-0.24.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:f035f0cacd1f44a8ff6cb7ca3627d84c54d685055961d73a1a9fb9827a5414c8", size = 8049661 }, + { url = "https://files.pythonhosted.org/packages/5c/ec/54a96ae9ab6a0dd66d4bba27771f892e36478a9c3489fa56e51c70abcc4d/torchvision-0.24.1-cp313-cp313-win_amd64.whl", hash = "sha256:16274823b93048e0a29d83415166a2e9e0bf4e1b432668357b657612a4802864", size = 4319808 }, + { url = "https://files.pythonhosted.org/packages/d5/f3/a90a389a7e547f3eb8821b13f96ea7c0563cdefbbbb60a10e08dda9720ff/torchvision-0.24.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e3f96208b4bef54cd60e415545f5200346a65024e04f29a26cd0006dbf9e8e66", size = 2005342 }, + { url = "https://files.pythonhosted.org/packages/a9/fe/ff27d2ed1b524078164bea1062f23d2618a5fc3208e247d6153c18c91a76/torchvision-0.24.1-cp313-cp313t-manylinux_2_28_aarch64.whl", hash = "sha256:f231f6a4f2aa6522713326d0d2563538fa72d613741ae364f9913027fa52ea35", size = 2341708 }, + { url = "https://files.pythonhosted.org/packages/b1/b9/d6c903495cbdfd2533b3ef6f7b5643ff589ea062f8feb5c206ee79b9d9e5/torchvision-0.24.1-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:1540a9e7f8cf55fe17554482f5a125a7e426347b71de07327d5de6bfd8d17caa", size = 8177239 }, + { url = "https://files.pythonhosted.org/packages/4f/2b/ba02e4261369c3798310483028495cf507e6cb3f394f42e4796981ecf3a7/torchvision-0.24.1-cp313-cp313t-win_amd64.whl", hash = "sha256:d83e16d70ea85d2f196d678bfb702c36be7a655b003abed84e465988b6128938", size = 4251604 }, + { url = "https://files.pythonhosted.org/packages/42/84/577b2cef8f32094add5f52887867da4c2a3e6b4261538447e9b48eb25812/torchvision-0.24.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:cccf4b4fec7fdfcd3431b9ea75d1588c0a8596d0333245dafebee0462abe3388", size = 2005319 }, + { url = "https://files.pythonhosted.org/packages/5f/34/ecb786bffe0159a3b49941a61caaae089853132f3cd1e8f555e3621f7e6f/torchvision-0.24.1-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:1b495edd3a8f9911292424117544f0b4ab780452e998649425d1f4b2bed6695f", size = 2338844 }, + { url = "https://files.pythonhosted.org/packages/51/99/a84623786a6969504c87f2dc3892200f586ee13503f519d282faab0bb4f0/torchvision-0.24.1-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:ab211e1807dc3e53acf8f6638df9a7444c80c0ad050466e8d652b3e83776987b", size = 8175144 }, + { url = "https://files.pythonhosted.org/packages/6d/ba/8fae3525b233e109317ce6a9c1de922ab2881737b029a7e88021f81e068f/torchvision-0.24.1-cp314-cp314-win_amd64.whl", hash = "sha256:18f9cb60e64b37b551cd605a3d62c15730c086362b40682d23e24b616a697d41", size = 4234459 }, + { url = "https://files.pythonhosted.org/packages/50/33/481602c1c72d0485d4b3a6b48c9534b71c2957c9d83bf860eb837bf5a620/torchvision-0.24.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ec9d7379c519428395e4ffda4dbb99ec56be64b0a75b95989e00f9ec7ae0b2d7", size = 2005336 }, + { url = "https://files.pythonhosted.org/packages/d0/7f/372de60bf3dd8f5593bd0d03f4aecf0d1fd58f5bc6943618d9d913f5e6d5/torchvision-0.24.1-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:af9201184c2712d808bd4eb656899011afdfce1e83721c7cb08000034df353fe", size = 2341704 }, + { url = "https://files.pythonhosted.org/packages/36/9b/0f3b9ff3d0225ee2324ec663de0e7fb3eb855615ca958ac1875f22f1f8e5/torchvision-0.24.1-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:9ef95d819fd6df81bc7cc97b8f21a15d2c0d3ac5dbfaab5cbc2d2ce57114b19e", size = 8177422 }, + { url = "https://files.pythonhosted.org/packages/d6/ab/e2bcc7c2f13d882a58f8b30ff86f794210b075736587ea50f8c545834f8a/torchvision-0.24.1-cp314-cp314t-win_amd64.whl", hash = "sha256:480b271d6edff83ac2e8d69bbb4cf2073f93366516a50d48f140ccfceedb002e", size = 4335190 }, ] [[package]] -name = "torchvision" -version = "0.24.1+cpu" -source = { registry = "https://download.pytorch.org/whl/cpu" } -resolution-markers = [ - "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')", -] -dependencies = [ - { name = "numpy", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, - { name = "pillow", marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, - { name = "torch", version = "2.9.1+cpu", source = { registry = "https://download.pytorch.org/whl/cpu" }, marker = "(platform_machine != 'aarch64' and sys_platform == 'linux') or (sys_platform != 'darwin' and sys_platform != 'linux')" }, -] +name = "triton" +version = "3.5.1" +source = { registry = "https://pypi.org/simple" } wheels = [ - { url = "https://download.pytorch.org/whl/cpu/torchvision-0.24.1%2Bcpu-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:19eb1744686a992522bf9ab8bf4b3245c2202e93a39b1fe1fcb2b8d2ca982048" }, - { url = "https://download.pytorch.org/whl/cpu/torchvision-0.24.1%2Bcpu-cp313-cp313-win_amd64.whl", hash = "sha256:4e2a64198ea3a3efdd4d1283e54418a3816a6943f619e5a33fc8236b6e259539" }, - { url = "https://download.pytorch.org/whl/cpu/torchvision-0.24.1%2Bcpu-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:0a3fecbadc155e7bf378178029215bfcd86f2cf453fbb1d9a474f375b3d475ae" }, - { url = "https://download.pytorch.org/whl/cpu/torchvision-0.24.1%2Bcpu-cp313-cp313t-win_amd64.whl", hash = "sha256:434347899fed98fb6906d86c00789963d3c22f69e18888aac15ffa012751b256" }, - { url = "https://download.pytorch.org/whl/cpu/torchvision-0.24.1%2Bcpu-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:e2c56fdda9e7a0f927d0d2748d756eb11e350e576efc719e9ab8a1b610213835" }, - { url = "https://download.pytorch.org/whl/cpu/torchvision-0.24.1%2Bcpu-cp314-cp314-win_amd64.whl", hash = "sha256:16e8565e5a8f3de450605a494605f89a4995c99c29734e0fa0d3c5577c717e69" }, - { url = "https://download.pytorch.org/whl/cpu/torchvision-0.24.1%2Bcpu-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:ad95138606b528c0c8976e6e0b184665433505c1aa87472bd31675f71d9d81c5" }, - { url = "https://download.pytorch.org/whl/cpu/torchvision-0.24.1%2Bcpu-cp314-cp314t-win_amd64.whl", hash = "sha256:75699e64987870f419e6f4fdb6a8508c2952b0faf9482a3a105d5b2c6c76c37a" }, + { url = "https://files.pythonhosted.org/packages/27/46/8c3bbb5b0a19313f50edcaa363b599e5a1a5ac9683ead82b9b80fe497c8d/triton-3.5.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f3f4346b6ebbd4fad18773f5ba839114f4826037c9f2f34e0148894cd5dd3dba", size = 170470410 }, + { url = "https://files.pythonhosted.org/packages/37/92/e97fcc6b2c27cdb87ce5ee063d77f8f26f19f06916aa680464c8104ef0f6/triton-3.5.1-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0b4d2c70127fca6a23e247f9348b8adde979d2e7a20391bfbabaac6aebc7e6a8", size = 170579924 }, + { url = "https://files.pythonhosted.org/packages/a4/e6/c595c35e5c50c4bc56a7bac96493dad321e9e29b953b526bbbe20f9911d0/triton-3.5.1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d0637b1efb1db599a8e9dc960d53ab6e4637db7d4ab6630a0974705d77b14b60", size = 170480488 }, + { url = "https://files.pythonhosted.org/packages/16/b5/b0d3d8b901b6a04ca38df5e24c27e53afb15b93624d7fd7d658c7cd9352a/triton-3.5.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bac7f7d959ad0f48c0e97d6643a1cc0fd5786fe61cb1f83b537c6b2d54776478", size = 170582192 }, +] + +[[package]] +name = "types-aiofiles" +version = "25.1.0.20251011" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/84/6c/6d23908a8217e36704aa9c79d99a620f2fdd388b66a4b7f72fbc6b6ff6c6/types_aiofiles-25.1.0.20251011.tar.gz", hash = "sha256:1c2b8ab260cb3cd40c15f9d10efdc05a6e1e6b02899304d80dfa0410e028d3ff", size = 14535 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/71/0f/76917bab27e270bb6c32addd5968d69e558e5b6f7fb4ac4cbfa282996a96/types_aiofiles-25.1.0.20251011-py3-none-any.whl", hash = "sha256:8ff8de7f9d42739d8f0dadcceeb781ce27cd8d8c4152d4a7c52f6b20edb8149c", size = 14338 }, ] [[package]] @@ -1337,6 +1619,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/2a/20/9a227ea57c1285986c4cf78400d0a91615d25b24e257fd9e2969606bdfae/types_requests-2.32.4.20250913-py3-none-any.whl", hash = "sha256:78c9c1fffebbe0fa487a418e0fa5252017e9c60d1a2da394077f1780f655d7e1", size = 20658 }, ] +[[package]] +name = "types-ujson" +version = "5.10.0.20250822" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5c/bd/d372d44534f84864a96c19a7059d9b4d29db8541828b8b9dc3040f7a46d0/types_ujson-5.10.0.20250822.tar.gz", hash = "sha256:0a795558e1f78532373cf3f03f35b1f08bc60d52d924187b97995ee3597ba006", size = 8437 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d7/f2/d812543c350674d8b3f6e17c8922248ee3bb752c2a76f64beb8c538b40cf/types_ujson-5.10.0.20250822-py3-none-any.whl", hash = "sha256:3e9e73a6dc62ccc03449d9ac2c580cd1b7a8e4873220db498f7dd056754be080", size = 7657 }, +] + [[package]] name = "typing-extensions" version = "4.15.0"