From 073777081ee06202ecb4b142f456e9cb348241ca Mon Sep 17 00:00:00 2001 From: Dohyun Lim Date: Thu, 8 Jan 2026 14:05:44 +0900 Subject: [PATCH 1/6] add logs for tracing processing task --- .gitkeep | 0 app/admin_manager.py | 76 +- app/core/common.py | 102 +- app/core/exceptions.py | 425 +- app/database/redis.py | 58 +- app/database/session-prod.py | 194 +- app/database/session.py | 322 +- app/home/api/home_admin.py | 204 +- app/home/api/routers/v1/__init__.py | 30 +- app/home/api/routers/v1/home.py | 1493 +++-- app/home/models.py | 430 +- app/home/schemas/home_schema.py | 520 +- app/home/services/base.py | 46 +- app/home/tests/home/conftest.py | 96 +- app/home/tests/home/test_db.py | 34 +- app/home/tests/test_db.py | 60 +- app/lyric/api/lyrics_admin.py | 122 +- app/lyric/api/routers/v1/lyric.py | 865 +-- app/lyric/dependencies.py | 16 +- app/lyric/models.py | 266 +- app/lyric/schemas/lyric.py | 364 +- app/lyric/schemas/lyrics_schema.py | 182 +- app/lyric/services/base.py | 46 +- app/lyric/services/lyrics.py | 1704 ++--- app/lyric/worker/lyric_task.py | 244 +- app/song/api/routers/v1/song.py | 1272 ++-- app/song/api/song_admin.py | 138 +- app/song/dependencies.py | 16 +- app/song/models.py | 304 +- app/song/schemas/song_schema.py | 748 +-- app/song/services/base.py | 46 +- app/song/services/song.py | 1704 ++--- app/song/worker/song_task.py | 752 ++- app/utils/chatgpt_prompt.py | 708 +- app/utils/cors.py | 48 +- app/utils/creatomate.py | 910 +-- app/utils/nvMapScraper.py | 277 +- app/utils/upload_blob_as_request.py | 911 +-- app/video/api/routers/v1/video.py | 1492 ++--- app/video/api/video_admin.py | 124 +- app/video/dependencies.py | 16 +- app/video/models.py | 278 +- app/video/schemas/video_schema.py | 312 +- app/video/services/video.py | 1704 ++--- app/video/worker/video_task.py | 575 +- config.py | 358 +- .../async_architecture_design_report.md | 1575 ++--- docs/analysis/db_쿼리_병렬화.md | 2082 +++--- docs/analysis/lang_report.md | 3410 +++++----- docs/analysis/orm_report.md | 1000 +-- docs/analysis/performance_report.md | 594 +- docs/analysis/pool_problem.md | 3562 +++++----- docs/analysis/refactoring.md | 2976 ++++----- .../mysql_create_tables-dev.sql | 162 +- docs/database-schema/mysql_create_tables.sql | 164 +- docs/reference/ConfigDict.md | 764 +-- docs/reference/fastapi_sqlalchemy_guide.md | 5930 ++++++++--------- .../sqlalchemy_relationship_guide.md | 2880 ++++---- docs/sample/models.py | 316 +- .../darak-1_000.jpg | Bin 0 -> 195312 bytes .../darak-2_001.jpg | Bin 0 -> 96737 bytes .../darak-3_002.jpg | Bin 0 -> 156027 bytes .../darak-1_003.jpg | Bin 0 -> 195312 bytes .../darak-2_004.jpg | Bin 0 -> 96737 bytes .../darak-3_005.jpg | Bin 0 -> 156027 bytes .../darak-1_000.jpg | Bin 0 -> 195312 bytes .../darak-2_001.jpg | Bin 0 -> 96737 bytes .../darak-3_002.jpg | Bin 0 -> 156027 bytes .../darak-1_000.jpg | Bin 0 -> 195312 bytes .../darak-2_000.jpg | Bin 0 -> 96737 bytes .../darak-3_000.jpg | Bin 0 -> 156027 bytes .../darak-1_000.jpg | Bin 0 -> 195312 bytes .../darak-2_000.jpg | Bin 0 -> 96737 bytes .../darak-3_000.jpg | Bin 0 -> 156027 bytes .../darak-1_000.jpg | Bin 0 -> 195312 bytes .../darak-2_000.jpg | Bin 0 -> 96737 bytes .../darak-3_000.jpg | Bin 0 -> 156027 bytes main.py | 108 +- poc/creatomate/creatomate.py | 452 +- poc/creatomate/test.py | 110 +- uv.lock | 3184 ++++----- 81 files changed, 25300 insertions(+), 24561 deletions(-) create mode 100644 .gitkeep create mode 100644 image/2025-12-26/0694e0e7-0f71-7671-8000-0ecf2ee67bac/darak-1_000.jpg create mode 100644 image/2025-12-26/0694e0e7-0f71-7671-8000-0ecf2ee67bac/darak-2_001.jpg create mode 100644 image/2025-12-26/0694e0e7-0f71-7671-8000-0ecf2ee67bac/darak-3_002.jpg create mode 100644 image/2025-12-26/0694e0e8-ee74-7d65-8000-2ac63bd131de/darak-1_003.jpg create mode 100644 image/2025-12-26/0694e0e8-ee74-7d65-8000-2ac63bd131de/darak-2_004.jpg create mode 100644 image/2025-12-26/0694e0e8-ee74-7d65-8000-2ac63bd131de/darak-3_005.jpg create mode 100644 image/2025-12-26/0694e1d2-9814-79dc-8000-23a0cfce1183/darak-1_000.jpg create mode 100644 image/2025-12-26/0694e1d2-9814-79dc-8000-23a0cfce1183/darak-2_001.jpg create mode 100644 image/2025-12-26/0694e1d2-9814-79dc-8000-23a0cfce1183/darak-3_002.jpg create mode 100644 image/2025-12-26/0694e25d-4e96-766f-8000-b8c29eb12843/darak-1_000.jpg create mode 100644 image/2025-12-26/0694e25d-4e96-766f-8000-b8c29eb12843/darak-2_000.jpg create mode 100644 image/2025-12-26/0694e25d-4e96-766f-8000-b8c29eb12843/darak-3_000.jpg create mode 100644 image/2025-12-26/0694e264-b742-7662-8000-a54ed4fd45a6/darak-1_000.jpg create mode 100644 image/2025-12-26/0694e264-b742-7662-8000-a54ed4fd45a6/darak-2_000.jpg create mode 100644 image/2025-12-26/0694e264-b742-7662-8000-a54ed4fd45a6/darak-3_000.jpg create mode 100644 image/2025-12-26/0694e26a-21aa-7eb1-8000-04a355390a04/darak-1_000.jpg create mode 100644 image/2025-12-26/0694e26a-21aa-7eb1-8000-04a355390a04/darak-2_000.jpg create mode 100644 image/2025-12-26/0694e26a-21aa-7eb1-8000-04a355390a04/darak-3_000.jpg diff --git a/.gitkeep b/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/app/admin_manager.py b/app/admin_manager.py index 8323b01..35cd37a 100644 --- a/app/admin_manager.py +++ b/app/admin_manager.py @@ -1,38 +1,38 @@ -from fastapi import FastAPI -from sqladmin import Admin - -from app.database.session import engine -from app.home.api.home_admin import ImageAdmin, ProjectAdmin -from app.lyric.api.lyrics_admin import LyricAdmin -from app.song.api.song_admin import SongAdmin -from app.video.api.video_admin import VideoAdmin -from config import prj_settings - -# https://github.com/aminalaee/sqladmin - - -def init_admin( - app: FastAPI, - db_engine: engine, - base_url: str = prj_settings.ADMIN_BASE_URL, -) -> Admin: - admin = Admin( - app, - db_engine, - base_url=base_url, - ) - - # 프로젝트 관리 - admin.add_view(ProjectAdmin) - admin.add_view(ImageAdmin) - - # 가사 관리 - admin.add_view(LyricAdmin) - - # 노래 관리 - admin.add_view(SongAdmin) - - # 영상 관리 - admin.add_view(VideoAdmin) - - return admin +from fastapi import FastAPI +from sqladmin import Admin + +from app.database.session import engine +from app.home.api.home_admin import ImageAdmin, ProjectAdmin +from app.lyric.api.lyrics_admin import LyricAdmin +from app.song.api.song_admin import SongAdmin +from app.video.api.video_admin import VideoAdmin +from config import prj_settings + +# https://github.com/aminalaee/sqladmin + + +def init_admin( + app: FastAPI, + db_engine: engine, + base_url: str = prj_settings.ADMIN_BASE_URL, +) -> Admin: + admin = Admin( + app, + db_engine, + base_url=base_url, + ) + + # 프로젝트 관리 + admin.add_view(ProjectAdmin) + admin.add_view(ImageAdmin) + + # 가사 관리 + admin.add_view(LyricAdmin) + + # 노래 관리 + admin.add_view(SongAdmin) + + # 영상 관리 + admin.add_view(VideoAdmin) + + return admin diff --git a/app/core/common.py b/app/core/common.py index e317c06..1d6d621 100644 --- a/app/core/common.py +++ b/app/core/common.py @@ -1,51 +1,51 @@ -# app/main.py -import asyncio -from contextlib import asynccontextmanager - -from fastapi import FastAPI - - -@asynccontextmanager -async def lifespan(app: FastAPI): - """FastAPI 애플리케이션 생명주기 관리""" - # Startup - 애플리케이션 시작 시 - print("Starting up...") - - try: - from config import prj_settings - - # DEBUG 모드일 때만 데이터베이스 테이블 자동 생성 - if prj_settings.DEBUG: - from app.database.session import create_db_tables - - await create_db_tables() - print("Database tables created (DEBUG mode)") - except asyncio.TimeoutError: - print("Database initialization timed out") - # 타임아웃 시 앱 시작 중단하려면 raise, 계속하려면 pass - raise - except Exception as e: - print(f"Database initialization failed: {e}") - # 에러 시 앱 시작 중단하려면 raise, 계속하려면 pass - raise - - yield # 애플리케이션 실행 중 - - # Shutdown - 애플리케이션 종료 시 - print("Shutting down...") - - # 공유 HTTP 클라이언트 종료 - from app.utils.creatomate import close_shared_client - from app.utils.upload_blob_as_request import close_shared_blob_client - - await close_shared_client() - await close_shared_blob_client() - - # 데이터베이스 엔진 종료 - from app.database.session import dispose_engine - - await dispose_engine() - - -# FastAPI 앱 생성 (lifespan 적용) -app = FastAPI(title="CastAD", lifespan=lifespan) +# app/main.py +import asyncio +from contextlib import asynccontextmanager + +from fastapi import FastAPI + + +@asynccontextmanager +async def lifespan(app: FastAPI): + """FastAPI 애플리케이션 생명주기 관리""" + # Startup - 애플리케이션 시작 시 + print("Starting up...") + + try: + from config import prj_settings + + # DEBUG 모드일 때만 데이터베이스 테이블 자동 생성 + if prj_settings.DEBUG: + from app.database.session import create_db_tables + + await create_db_tables() + print("Database tables created (DEBUG mode)") + except asyncio.TimeoutError: + print("Database initialization timed out") + # 타임아웃 시 앱 시작 중단하려면 raise, 계속하려면 pass + raise + except Exception as e: + print(f"Database initialization failed: {e}") + # 에러 시 앱 시작 중단하려면 raise, 계속하려면 pass + raise + + yield # 애플리케이션 실행 중 + + # Shutdown - 애플리케이션 종료 시 + print("Shutting down...") + + # 공유 HTTP 클라이언트 종료 + from app.utils.creatomate import close_shared_client + from app.utils.upload_blob_as_request import close_shared_blob_client + + await close_shared_client() + await close_shared_blob_client() + + # 데이터베이스 엔진 종료 + from app.database.session import dispose_engine + + await dispose_engine() + + +# FastAPI 앱 생성 (lifespan 적용) +app = FastAPI(title="CastAD", lifespan=lifespan) diff --git a/app/core/exceptions.py b/app/core/exceptions.py index afe48c7..e0399c1 100644 --- a/app/core/exceptions.py +++ b/app/core/exceptions.py @@ -1,114 +1,313 @@ -from fastapi import FastAPI, HTTPException, Request, Response, status -from fastapi.responses import JSONResponse - - -class FastShipError(Exception): - """Base exception for all exceptions in fastship api""" - # status_code to be returned for this exception - # when it is handled - status = status.HTTP_400_BAD_REQUEST - - -class EntityNotFound(FastShipError): - """Entity not found in database""" - - status = status.HTTP_404_NOT_FOUND - - -class BadPassword(FastShipError): - """Password is not strong enough or invalid""" - - status = status.HTTP_400_BAD_REQUEST - - -class ClientNotAuthorized(FastShipError): - """Client is not authorized to perform the action""" - - status = status.HTTP_401_UNAUTHORIZED - - -class ClientNotVerified(FastShipError): - """Client is not verified""" - - status = status.HTTP_401_UNAUTHORIZED - - -class NothingToUpdate(FastShipError): - """No data provided to update""" - - -class BadCredentials(FastShipError): - """User email or password is incorrect""" - - status = status.HTTP_401_UNAUTHORIZED - - -class InvalidToken(FastShipError): - """Access token is invalid or expired""" - - status = status.HTTP_401_UNAUTHORIZED - - -class DeliveryPartnerNotAvailable(FastShipError): - """Delivery partner/s do not service the destination""" - - status = status.HTTP_406_NOT_ACCEPTABLE - - -class DeliveryPartnerCapacityExceeded(FastShipError): - """Delivery partner has reached their max handling capacity""" - - status = status.HTTP_406_NOT_ACCEPTABLE - - -def _get_handler(status: int, detail: str): - # Define - def handler(request: Request, exception: Exception) -> Response: - # DEBUG PRINT STATEMENT 👇 - from rich import print, panel - print( - panel.Panel( - exception.__class__.__name__, - title="Handled Exception", - border_style="red", - ), - ) - # DEBUG PRINT STATEMENT 👆 - - # Raise HTTPException with given status and detail - # can return JSONResponse as well - raise HTTPException( - status_code=status, - detail=detail, - ) - # Return ExceptionHandler required with given - # status and detail for HTTPExcetion above - return handler - - -def add_exception_handlers(app: FastAPI): - # Get all subclass of 👇, our custom exceptions - exception_classes = FastShipError.__subclasses__() - - for exception_class in exception_classes: - # Add exception handler - app.add_exception_handler( - # Custom exception class - exception_class, - # Get handler function - _get_handler( - status=exception_class.status, - detail=exception_class.__doc__, - ), - ) - - @app.exception_handler(status.HTTP_500_INTERNAL_SERVER_ERROR) - def internal_server_error_handler(request, exception): - return JSONResponse( - content={"detail": "Something went wrong..."}, - status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, - headers={ - "X-Error": f"{exception}", - } - ) +import logging +import traceback +from functools import wraps +from typing import Any, Callable, TypeVar + +from fastapi import FastAPI, HTTPException, Request, Response, status +from fastapi.responses import JSONResponse +from sqlalchemy.exc import SQLAlchemyError + +# 로거 설정 +logger = logging.getLogger(__name__) + +T = TypeVar("T") + + +class FastShipError(Exception): + """Base exception for all exceptions in fastship api""" + # status_code to be returned for this exception + # when it is handled + status = status.HTTP_400_BAD_REQUEST + + +class EntityNotFound(FastShipError): + """Entity not found in database""" + + status = status.HTTP_404_NOT_FOUND + + +class BadPassword(FastShipError): + """Password is not strong enough or invalid""" + + status = status.HTTP_400_BAD_REQUEST + + +class ClientNotAuthorized(FastShipError): + """Client is not authorized to perform the action""" + + status = status.HTTP_401_UNAUTHORIZED + + +class ClientNotVerified(FastShipError): + """Client is not verified""" + + status = status.HTTP_401_UNAUTHORIZED + + +class NothingToUpdate(FastShipError): + """No data provided to update""" + + +class BadCredentials(FastShipError): + """User email or password is incorrect""" + + status = status.HTTP_401_UNAUTHORIZED + + +class InvalidToken(FastShipError): + """Access token is invalid or expired""" + + status = status.HTTP_401_UNAUTHORIZED + + +class DeliveryPartnerNotAvailable(FastShipError): + """Delivery partner/s do not service the destination""" + + status = status.HTTP_406_NOT_ACCEPTABLE + + +class DeliveryPartnerCapacityExceeded(FastShipError): + """Delivery partner has reached their max handling capacity""" + + status = status.HTTP_406_NOT_ACCEPTABLE + + +# ============================================================================= +# 데이터베이스 관련 예외 +# ============================================================================= + + +class DatabaseError(FastShipError): + """Database operation failed""" + + status = status.HTTP_503_SERVICE_UNAVAILABLE + + +class DatabaseConnectionError(DatabaseError): + """Database connection failed""" + + status = status.HTTP_503_SERVICE_UNAVAILABLE + + +class DatabaseTimeoutError(DatabaseError): + """Database operation timed out""" + + status = status.HTTP_504_GATEWAY_TIMEOUT + + +# ============================================================================= +# 외부 서비스 관련 예외 +# ============================================================================= + + +class ExternalServiceError(FastShipError): + """External service call failed""" + + status = status.HTTP_502_BAD_GATEWAY + + +class GPTServiceError(ExternalServiceError): + """GPT API call failed""" + + status = status.HTTP_502_BAD_GATEWAY + + +class CrawlingError(ExternalServiceError): + """Web crawling failed""" + + status = status.HTTP_502_BAD_GATEWAY + + +class BlobStorageError(ExternalServiceError): + """Azure Blob Storage operation failed""" + + status = status.HTTP_502_BAD_GATEWAY + + +class CreatomateError(ExternalServiceError): + """Creatomate API call failed""" + + status = status.HTTP_502_BAD_GATEWAY + + +# ============================================================================= +# 예외 처리 데코레이터 +# ============================================================================= + + +def handle_db_exceptions( + error_message: str = "데이터베이스 작업 중 오류가 발생했습니다.", +): + """데이터베이스 예외를 처리하는 데코레이터. + + Args: + error_message: 오류 발생 시 반환할 메시지 + + Example: + @handle_db_exceptions("사용자 조회 중 오류 발생") + async def get_user(user_id: int): + ... + """ + + def decorator(func: Callable[..., Any]) -> Callable[..., Any]: + @wraps(func) + async def wrapper(*args: Any, **kwargs: Any) -> Any: + try: + return await func(*args, **kwargs) + except HTTPException: + # HTTPException은 그대로 raise + raise + except SQLAlchemyError as e: + logger.error(f"[DB Error] {func.__name__}: {e}") + logger.error(traceback.format_exc()) + print(f"[DB Error] {func.__name__}: {e}") + raise HTTPException( + status_code=status.HTTP_503_SERVICE_UNAVAILABLE, + detail=error_message, + ) + except Exception as e: + logger.error(f"[Unexpected Error] {func.__name__}: {e}") + logger.error(traceback.format_exc()) + print(f"[Unexpected Error] {func.__name__}: {e}") + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="서비스 처리 중 예기치 않은 오류가 발생했습니다.", + ) + + return wrapper + + return decorator + + +def handle_external_service_exceptions( + service_name: str = "외부 서비스", + error_message: str | None = None, +): + """외부 서비스 호출 예외를 처리하는 데코레이터. + + Args: + service_name: 서비스 이름 (로그용) + error_message: 오류 발생 시 반환할 메시지 + + Example: + @handle_external_service_exceptions("GPT") + async def call_gpt(): + ... + """ + + def decorator(func: Callable[..., Any]) -> Callable[..., Any]: + @wraps(func) + async def wrapper(*args: Any, **kwargs: Any) -> Any: + try: + return await func(*args, **kwargs) + except HTTPException: + raise + except Exception as e: + msg = error_message or f"{service_name} 서비스 호출 중 오류가 발생했습니다." + logger.error(f"[{service_name} Error] {func.__name__}: {e}") + logger.error(traceback.format_exc()) + print(f"[{service_name} Error] {func.__name__}: {e}") + raise HTTPException( + status_code=status.HTTP_502_BAD_GATEWAY, + detail=msg, + ) + + return wrapper + + return decorator + + +def handle_api_exceptions( + error_message: str = "요청 처리 중 오류가 발생했습니다.", +): + """API 엔드포인트 예외를 처리하는 데코레이터. + + Args: + error_message: 오류 발생 시 반환할 메시지 + + Example: + @handle_api_exceptions("가사 생성 중 오류 발생") + async def generate_lyric(): + ... + """ + + def decorator(func: Callable[..., Any]) -> Callable[..., Any]: + @wraps(func) + async def wrapper(*args: Any, **kwargs: Any) -> Any: + try: + return await func(*args, **kwargs) + except HTTPException: + raise + except SQLAlchemyError as e: + logger.error(f"[API DB Error] {func.__name__}: {e}") + logger.error(traceback.format_exc()) + print(f"[API DB Error] {func.__name__}: {e}") + raise HTTPException( + status_code=status.HTTP_503_SERVICE_UNAVAILABLE, + detail="데이터베이스 연결에 문제가 발생했습니다.", + ) + except Exception as e: + logger.error(f"[API Error] {func.__name__}: {e}") + logger.error(traceback.format_exc()) + print(f"[API Error] {func.__name__}: {e}") + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=error_message, + ) + + return wrapper + + return decorator + + +def _get_handler(status: int, detail: str): + # Define + def handler(request: Request, exception: Exception) -> Response: + # DEBUG PRINT STATEMENT 👇 + from rich import print, panel + print( + panel.Panel( + exception.__class__.__name__, + title="Handled Exception", + border_style="red", + ), + ) + # DEBUG PRINT STATEMENT 👆 + + # Raise HTTPException with given status and detail + # can return JSONResponse as well + raise HTTPException( + status_code=status, + detail=detail, + ) + # Return ExceptionHandler required with given + # status and detail for HTTPExcetion above + return handler + + +def add_exception_handlers(app: FastAPI): + # Get all subclass of 👇, our custom exceptions + exception_classes = FastShipError.__subclasses__() + + for exception_class in exception_classes: + # Add exception handler + app.add_exception_handler( + # Custom exception class + exception_class, + # Get handler function + _get_handler( + status=exception_class.status, + detail=exception_class.__doc__, + ), + ) + + @app.exception_handler(status.HTTP_500_INTERNAL_SERVER_ERROR) + def internal_server_error_handler(request, exception): + return JSONResponse( + content={"detail": "Something went wrong..."}, + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + headers={ + "X-Error": f"{exception}", + } + ) \ No newline at end of file diff --git a/app/database/redis.py b/app/database/redis.py index 8bfa34d..616d510 100644 --- a/app/database/redis.py +++ b/app/database/redis.py @@ -1,30 +1,30 @@ -from uuid import UUID -from redis.asyncio import Redis - -from app.config import db_settings - - -_token_blacklist = Redis( - host=db_settings.REDIS_HOST, - port=db_settings.REDIS_PORT, - db=0, -) -_shipment_verification_codes = Redis( - host=db_settings.REDIS_HOST, - port=db_settings.REDIS_PORT, - db=1, - decode_responses=True, -) - -async def add_jti_to_blacklist(jti: str): - await _token_blacklist.set(jti, "blacklisted") - - -async def is_jti_blacklisted(jti: str) -> bool: - return await _token_blacklist.exists(jti) - -async def add_shipment_verification_code(id: UUID, code: int): - await _shipment_verification_codes.set(str(id), code) - -async def get_shipment_verification_code(id: UUID) -> str: +from uuid import UUID +from redis.asyncio import Redis + +from app.config import db_settings + + +_token_blacklist = Redis( + host=db_settings.REDIS_HOST, + port=db_settings.REDIS_PORT, + db=0, +) +_shipment_verification_codes = Redis( + host=db_settings.REDIS_HOST, + port=db_settings.REDIS_PORT, + db=1, + decode_responses=True, +) + +async def add_jti_to_blacklist(jti: str): + await _token_blacklist.set(jti, "blacklisted") + + +async def is_jti_blacklisted(jti: str) -> bool: + return await _token_blacklist.exists(jti) + +async def add_shipment_verification_code(id: UUID, code: int): + await _shipment_verification_codes.set(str(id), code) + +async def get_shipment_verification_code(id: UUID) -> str: return str(await _shipment_verification_codes.get(str(id))) \ No newline at end of file diff --git a/app/database/session-prod.py b/app/database/session-prod.py index 1510d4e..cae7289 100644 --- a/app/database/session-prod.py +++ b/app/database/session-prod.py @@ -1,97 +1,97 @@ -from asyncio import current_task -from typing import AsyncGenerator - -from sqlalchemy.ext.asyncio import ( - AsyncSession, - async_sessionmaker, - create_async_engine, -) -from sqlalchemy.orm import DeclarativeBase -from sqlalchemy.pool import AsyncQueuePool # 비동기 풀 클래스 - -from config import db_settings - - -# Base 클래스 정의 -class Base(DeclarativeBase): - pass - - -engine = create_async_engine( - # MySQL async URL (asyncmy 드라이버) - url=db_settings.MYSQL_URL, # 예: "mysql+asyncmy://test:test@host:3306/poc" - # === Connection Pool 설정 === - pool_size=10, # 기본 풀 크기: 10개 연결 유지 - max_overflow=10, # 최대 증가: 10개 (총 20개까지 가능) - poolclass=AsyncQueuePool, # 비동기 큐 풀 사용 (기본값, 명시적 지정) - pool_timeout=30, # 풀에서 연결 대기 시간: 30초 (기본 30초) - pool_recycle=3600, # 연결 재사용 주기: 1시간 (기본 3600초) - pool_pre_ping=True, # 연결 사용 전 유효성 검사: True로 설정 - pool_reset_on_return="rollback", # 연결 반환 시 자동 롤백 - # === MySQL 특화 설정 === - echo=False, # SQL 쿼리 로깅 (디버깅 시 True) - # === 연결 타임아웃 및 재시도 === - connect_args={ - "connect_timeout": 10, # MySQL 연결 타임아웃: 10초 - "read_timeout": 30, # 읽기 타임아웃: 30초 - "write_timeout": 30, # 쓰기 타임아웃: 30초 - "charset": "utf8mb4", # 문자셋 (이모지 지원) - "sql_mode": "STRICT_TRANS_TABLES,NO_ZERO_DATE,NO_ZERO_IN_DATE", - "init_command": "SET SESSION time_zone = '+00:00'", # 초기 연결 시 실행 - }, -) - -# Async 세션 팩토리 생성 -async_session_factory = async_sessionmaker( - bind=engine, - class_=AsyncSession, - expire_on_commit=False, # 커밋 후 객체 상태 유지 - autoflush=True, # 변경 감지 자동 플러시 -) - -# async_scoped_session 생성 -AsyncScopedSession = async_session_factory( - async_session_factory, - scopefunc=current_task, -) - - -# 테이블 생성 함수 -async def create_db_tables() -> None: - async with engine.begin() as conn: - # from app.database.models import Shipment, Seller # noqa: F401 - await conn.run_sync(Base.metadata.create_all) - print("MySQL tables created successfully") - - -# 세션 제너레이터 (FastAPI Depends에 사용) -async def get_session() -> AsyncGenerator[AsyncSession, None]: - """ - Async 세션 컨텍스트 매니저 - - FastAPI dependency로 사용 - - Connection Pool에서 연결 획득/반환 자동 관리 - """ - async with async_session_factory() as session: - # pre-commit 훅 (선택적: 트랜잭션 시작 전 실행) - # await session.begin() # async_sessionmaker에서 자동 begin - - try: - yield session - # FastAPI 요청 완료 시 자동 commit (예외 발생 시 rollback) - except Exception as e: - await session.rollback() # 명시적 롤백 (선택적) - print(f"Session rollback due to: {e}") # 로깅 - raise - finally: - # 명시적 세션 종료 (Connection Pool에 반환) - # context manager가 자동 처리하지만, 명시적으로 유지 - await session.close() - print("session closed successfully") - # 또는 session.aclose() - Python 3.10+ - - -# 애플리케이션 종료 시 엔진 정리 (선택적) -async def dispose_engine() -> None: - """애플리케이션 종료 시 모든 연결 해제""" - await engine.dispose() - print("Database engine disposed") +from asyncio import current_task +from typing import AsyncGenerator + +from sqlalchemy.ext.asyncio import ( + AsyncSession, + async_sessionmaker, + create_async_engine, +) +from sqlalchemy.orm import DeclarativeBase +from sqlalchemy.pool import AsyncQueuePool # 비동기 풀 클래스 + +from config import db_settings + + +# Base 클래스 정의 +class Base(DeclarativeBase): + pass + + +engine = create_async_engine( + # MySQL async URL (asyncmy 드라이버) + url=db_settings.MYSQL_URL, # 예: "mysql+asyncmy://test:test@host:3306/poc" + # === Connection Pool 설정 === + pool_size=10, # 기본 풀 크기: 10개 연결 유지 + max_overflow=10, # 최대 증가: 10개 (총 20개까지 가능) + poolclass=AsyncQueuePool, # 비동기 큐 풀 사용 (기본값, 명시적 지정) + pool_timeout=30, # 풀에서 연결 대기 시간: 30초 (기본 30초) + pool_recycle=3600, # 연결 재사용 주기: 1시간 (기본 3600초) + pool_pre_ping=True, # 연결 사용 전 유효성 검사: True로 설정 + pool_reset_on_return="rollback", # 연결 반환 시 자동 롤백 + # === MySQL 특화 설정 === + echo=False, # SQL 쿼리 로깅 (디버깅 시 True) + # === 연결 타임아웃 및 재시도 === + connect_args={ + "connect_timeout": 10, # MySQL 연결 타임아웃: 10초 + "read_timeout": 30, # 읽기 타임아웃: 30초 + "write_timeout": 30, # 쓰기 타임아웃: 30초 + "charset": "utf8mb4", # 문자셋 (이모지 지원) + "sql_mode": "STRICT_TRANS_TABLES,NO_ZERO_DATE,NO_ZERO_IN_DATE", + "init_command": "SET SESSION time_zone = '+00:00'", # 초기 연결 시 실행 + }, +) + +# Async 세션 팩토리 생성 +async_session_factory = async_sessionmaker( + bind=engine, + class_=AsyncSession, + expire_on_commit=False, # 커밋 후 객체 상태 유지 + autoflush=True, # 변경 감지 자동 플러시 +) + +# async_scoped_session 생성 +AsyncScopedSession = async_session_factory( + async_session_factory, + scopefunc=current_task, +) + + +# 테이블 생성 함수 +async def create_db_tables() -> None: + async with engine.begin() as conn: + # from app.database.models import Shipment, Seller # noqa: F401 + await conn.run_sync(Base.metadata.create_all) + print("MySQL tables created successfully") + + +# 세션 제너레이터 (FastAPI Depends에 사용) +async def get_session() -> AsyncGenerator[AsyncSession, None]: + """ + Async 세션 컨텍스트 매니저 + - FastAPI dependency로 사용 + - Connection Pool에서 연결 획득/반환 자동 관리 + """ + async with async_session_factory() as session: + # pre-commit 훅 (선택적: 트랜잭션 시작 전 실행) + # await session.begin() # async_sessionmaker에서 자동 begin + + try: + yield session + # FastAPI 요청 완료 시 자동 commit (예외 발생 시 rollback) + except Exception as e: + await session.rollback() # 명시적 롤백 (선택적) + print(f"Session rollback due to: {e}") # 로깅 + raise + finally: + # 명시적 세션 종료 (Connection Pool에 반환) + # context manager가 자동 처리하지만, 명시적으로 유지 + await session.close() + print("session closed successfully") + # 또는 session.aclose() - Python 3.10+ + + +# 애플리케이션 종료 시 엔진 정리 (선택적) +async def dispose_engine() -> None: + """애플리케이션 종료 시 모든 연결 해제""" + await engine.dispose() + print("Database engine disposed") diff --git a/app/database/session.py b/app/database/session.py index 0951f28..dd8c6db 100644 --- a/app/database/session.py +++ b/app/database/session.py @@ -1,161 +1,161 @@ -import time -from typing import AsyncGenerator - -from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine -from sqlalchemy.orm import DeclarativeBase - -from config import db_settings - - -class Base(DeclarativeBase): - pass - - -# ============================================================================= -# 메인 엔진 (FastAPI 요청용) -# ============================================================================= -engine = create_async_engine( - url=db_settings.MYSQL_URL, - echo=False, - pool_size=20, # 기본 풀 크기: 20 - max_overflow=20, # 추가 연결: 20 (총 최대 40) - pool_timeout=30, # 풀에서 연결 대기 시간 (초) - pool_recycle=280, # MySQL wait_timeout(기본 28800s, 클라우드는 보통 300s) 보다 짧게 설정 - pool_pre_ping=True, # 연결 유효성 검사 (죽은 연결 자동 재연결) - pool_reset_on_return="rollback", # 반환 시 롤백으로 초기화 - connect_args={ - "connect_timeout": 10, # DB 연결 타임아웃 - "charset": "utf8mb4", - }, -) - -# 메인 세션 팩토리 (FastAPI DI용) -AsyncSessionLocal = async_sessionmaker( - bind=engine, - class_=AsyncSession, - expire_on_commit=False, - autoflush=False, # 명시적 flush 권장 -) - - -# ============================================================================= -# 백그라운드 태스크 전용 엔진 (메인 풀과 분리) -# ============================================================================= -background_engine = create_async_engine( - url=db_settings.MYSQL_URL, - echo=False, - pool_size=10, # 백그라운드용 풀 크기: 10 - max_overflow=10, # 추가 연결: 10 (총 최대 20) - pool_timeout=60, # 백그라운드는 대기 시간 여유있게 - pool_recycle=280, # MySQL wait_timeout 보다 짧게 설정 - pool_pre_ping=True, # 연결 유효성 검사 (죽은 연결 자동 재연결) - pool_reset_on_return="rollback", - connect_args={ - "connect_timeout": 10, - "charset": "utf8mb4", - }, -) - -# 백그라운드 세션 팩토리 -BackgroundSessionLocal = async_sessionmaker( - bind=background_engine, - class_=AsyncSession, - expire_on_commit=False, - autoflush=False, -) - - -async def create_db_tables(): - import asyncio - - # 모델 import (테이블 메타데이터 등록용) - from app.home.models import Image, Project # noqa: F401 - from app.lyric.models import Lyric # noqa: F401 - from app.song.models import Song # noqa: F401 - from app.video.models import Video # noqa: F401 - - print("Creating database tables...") - - async with asyncio.timeout(10): - async with engine.begin() as connection: - await connection.run_sync(Base.metadata.create_all) - - -# FastAPI 의존성용 세션 제너레이터 -async def get_session() -> AsyncGenerator[AsyncSession, None]: - start_time = time.perf_counter() - pool = engine.pool - - # 커넥션 풀 상태 로깅 (디버깅용) - print( - f"[get_session] ACQUIRE - pool_size: {pool.size()}, " - f"in: {pool.checkedin()}, out: {pool.checkedout()}, " - f"overflow: {pool.overflow()}" - ) - - async with AsyncSessionLocal() as session: - acquire_time = time.perf_counter() - print( - f"[get_session] Session acquired in " - f"{(acquire_time - start_time)*1000:.1f}ms" - ) - try: - yield session - except Exception as e: - await session.rollback() - print( - f"[get_session] ROLLBACK - error: {type(e).__name__}: {e}, " - f"duration: {(time.perf_counter() - start_time)*1000:.1f}ms" - ) - raise e - finally: - total_time = time.perf_counter() - start_time - print( - f"[get_session] RELEASE - duration: {total_time*1000:.1f}ms, " - f"pool_out: {pool.checkedout()}" - ) - - -# 백그라운드 태스크용 세션 제너레이터 -async def get_background_session() -> AsyncGenerator[AsyncSession, None]: - start_time = time.perf_counter() - pool = background_engine.pool - - print( - f"[get_background_session] ACQUIRE - pool_size: {pool.size()}, " - f"in: {pool.checkedin()}, out: {pool.checkedout()}, " - f"overflow: {pool.overflow()}" - ) - - async with BackgroundSessionLocal() as session: - acquire_time = time.perf_counter() - print( - f"[get_background_session] Session acquired in " - f"{(acquire_time - start_time)*1000:.1f}ms" - ) - try: - yield session - except Exception as e: - await session.rollback() - print( - f"[get_background_session] ROLLBACK - " - f"error: {type(e).__name__}: {e}, " - f"duration: {(time.perf_counter() - start_time)*1000:.1f}ms" - ) - raise e - finally: - total_time = time.perf_counter() - start_time - print( - f"[get_background_session] RELEASE - " - f"duration: {total_time*1000:.1f}ms, " - f"pool_out: {pool.checkedout()}" - ) - - -# 앱 종료 시 엔진 리소스 정리 함수 -async def dispose_engine() -> None: - print("[dispose_engine] Disposing database engines...") - await engine.dispose() - print("[dispose_engine] Main engine disposed") - await background_engine.dispose() - print("[dispose_engine] Background engine disposed - ALL DONE") +import time +from typing import AsyncGenerator + +from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine +from sqlalchemy.orm import DeclarativeBase + +from config import db_settings + + +class Base(DeclarativeBase): + pass + + +# ============================================================================= +# 메인 엔진 (FastAPI 요청용) +# ============================================================================= +engine = create_async_engine( + url=db_settings.MYSQL_URL, + echo=False, + pool_size=20, # 기본 풀 크기: 20 + max_overflow=20, # 추가 연결: 20 (총 최대 40) + pool_timeout=30, # 풀에서 연결 대기 시간 (초) + pool_recycle=280, # MySQL wait_timeout(기본 28800s, 클라우드는 보통 300s) 보다 짧게 설정 + pool_pre_ping=True, # 연결 유효성 검사 (죽은 연결 자동 재연결) + pool_reset_on_return="rollback", # 반환 시 롤백으로 초기화 + connect_args={ + "connect_timeout": 10, # DB 연결 타임아웃 + "charset": "utf8mb4", + }, +) + +# 메인 세션 팩토리 (FastAPI DI용) +AsyncSessionLocal = async_sessionmaker( + bind=engine, + class_=AsyncSession, + expire_on_commit=False, + autoflush=False, # 명시적 flush 권장 +) + + +# ============================================================================= +# 백그라운드 태스크 전용 엔진 (메인 풀과 분리) +# ============================================================================= +background_engine = create_async_engine( + url=db_settings.MYSQL_URL, + echo=False, + pool_size=10, # 백그라운드용 풀 크기: 10 + max_overflow=10, # 추가 연결: 10 (총 최대 20) + pool_timeout=60, # 백그라운드는 대기 시간 여유있게 + pool_recycle=280, # MySQL wait_timeout 보다 짧게 설정 + pool_pre_ping=True, # 연결 유효성 검사 (죽은 연결 자동 재연결) + pool_reset_on_return="rollback", + connect_args={ + "connect_timeout": 10, + "charset": "utf8mb4", + }, +) + +# 백그라운드 세션 팩토리 +BackgroundSessionLocal = async_sessionmaker( + bind=background_engine, + class_=AsyncSession, + expire_on_commit=False, + autoflush=False, +) + + +async def create_db_tables(): + import asyncio + + # 모델 import (테이블 메타데이터 등록용) + from app.home.models import Image, Project # noqa: F401 + from app.lyric.models import Lyric # noqa: F401 + from app.song.models import Song # noqa: F401 + from app.video.models import Video # noqa: F401 + + print("Creating database tables...") + + async with asyncio.timeout(10): + async with engine.begin() as connection: + await connection.run_sync(Base.metadata.create_all) + + +# FastAPI 의존성용 세션 제너레이터 +async def get_session() -> AsyncGenerator[AsyncSession, None]: + start_time = time.perf_counter() + pool = engine.pool + + # 커넥션 풀 상태 로깅 (디버깅용) + print( + f"[get_session] ACQUIRE - pool_size: {pool.size()}, " + f"in: {pool.checkedin()}, out: {pool.checkedout()}, " + f"overflow: {pool.overflow()}" + ) + + async with AsyncSessionLocal() as session: + acquire_time = time.perf_counter() + print( + f"[get_session] Session acquired in " + f"{(acquire_time - start_time)*1000:.1f}ms" + ) + try: + yield session + except Exception as e: + await session.rollback() + print( + f"[get_session] ROLLBACK - error: {type(e).__name__}: {e}, " + f"duration: {(time.perf_counter() - start_time)*1000:.1f}ms" + ) + raise e + finally: + total_time = time.perf_counter() - start_time + print( + f"[get_session] RELEASE - duration: {total_time*1000:.1f}ms, " + f"pool_out: {pool.checkedout()}" + ) + + +# 백그라운드 태스크용 세션 제너레이터 +async def get_background_session() -> AsyncGenerator[AsyncSession, None]: + start_time = time.perf_counter() + pool = background_engine.pool + + print( + f"[get_background_session] ACQUIRE - pool_size: {pool.size()}, " + f"in: {pool.checkedin()}, out: {pool.checkedout()}, " + f"overflow: {pool.overflow()}" + ) + + async with BackgroundSessionLocal() as session: + acquire_time = time.perf_counter() + print( + f"[get_background_session] Session acquired in " + f"{(acquire_time - start_time)*1000:.1f}ms" + ) + try: + yield session + except Exception as e: + await session.rollback() + print( + f"[get_background_session] ROLLBACK - " + f"error: {type(e).__name__}: {e}, " + f"duration: {(time.perf_counter() - start_time)*1000:.1f}ms" + ) + raise e + finally: + total_time = time.perf_counter() - start_time + print( + f"[get_background_session] RELEASE - " + f"duration: {total_time*1000:.1f}ms, " + f"pool_out: {pool.checkedout()}" + ) + + +# 앱 종료 시 엔진 리소스 정리 함수 +async def dispose_engine() -> None: + print("[dispose_engine] Disposing database engines...") + await engine.dispose() + print("[dispose_engine] Main engine disposed") + await background_engine.dispose() + print("[dispose_engine] Background engine disposed - ALL DONE") diff --git a/app/home/api/home_admin.py b/app/home/api/home_admin.py index c096847..da81d07 100644 --- a/app/home/api/home_admin.py +++ b/app/home/api/home_admin.py @@ -1,102 +1,102 @@ -from sqladmin import ModelView - -from app.home.models import Image, Project - - -class ProjectAdmin(ModelView, model=Project): - name = "프로젝트" - name_plural = "프로젝트 목록" - icon = "fa-solid fa-folder" - category = "프로젝트 관리" - page_size = 20 - - column_list = [ - "id", - "store_name", - "region", - "task_id", - "created_at", - ] - - column_details_list = [ - "id", - "store_name", - "region", - "task_id", - "detail_region_info", - "created_at", - ] - - # 폼(생성/수정)에서 제외 - form_excluded_columns = ["created_at", "lyrics", "songs", "videos"] - - column_searchable_list = [ - Project.store_name, - Project.region, - Project.task_id, - ] - - column_default_sort = (Project.created_at, True) # True: DESC (최신순) - - column_sortable_list = [ - Project.id, - Project.store_name, - Project.region, - Project.created_at, - ] - - column_labels = { - "id": "ID", - "store_name": "가게명", - "region": "지역", - "task_id": "작업 ID", - "detail_region_info": "상세 지역 정보", - "created_at": "생성일시", - } - - -class ImageAdmin(ModelView, model=Image): - name = "이미지" - name_plural = "이미지 목록" - icon = "fa-solid fa-image" - category = "프로젝트 관리" - page_size = 20 - - column_list = [ - "id", - "task_id", - "img_name", - "created_at", - ] - - column_details_list = [ - "id", - "task_id", - "img_name", - "img_url", - "created_at", - ] - - # 폼(생성/수정)에서 제외 - form_excluded_columns = ["created_at"] - - column_searchable_list = [ - Image.task_id, - Image.img_name, - ] - - column_default_sort = (Image.created_at, True) # True: DESC (최신순) - - column_sortable_list = [ - Image.id, - Image.img_name, - Image.created_at, - ] - - column_labels = { - "id": "ID", - "task_id": "작업 ID", - "img_name": "이미지명", - "img_url": "이미지 URL", - "created_at": "생성일시", - } +from sqladmin import ModelView + +from app.home.models import Image, Project + + +class ProjectAdmin(ModelView, model=Project): + name = "프로젝트" + name_plural = "프로젝트 목록" + icon = "fa-solid fa-folder" + category = "프로젝트 관리" + page_size = 20 + + column_list = [ + "id", + "store_name", + "region", + "task_id", + "created_at", + ] + + column_details_list = [ + "id", + "store_name", + "region", + "task_id", + "detail_region_info", + "created_at", + ] + + # 폼(생성/수정)에서 제외 + form_excluded_columns = ["created_at", "lyrics", "songs", "videos"] + + column_searchable_list = [ + Project.store_name, + Project.region, + Project.task_id, + ] + + column_default_sort = (Project.created_at, True) # True: DESC (최신순) + + column_sortable_list = [ + Project.id, + Project.store_name, + Project.region, + Project.created_at, + ] + + column_labels = { + "id": "ID", + "store_name": "가게명", + "region": "지역", + "task_id": "작업 ID", + "detail_region_info": "상세 지역 정보", + "created_at": "생성일시", + } + + +class ImageAdmin(ModelView, model=Image): + name = "이미지" + name_plural = "이미지 목록" + icon = "fa-solid fa-image" + category = "프로젝트 관리" + page_size = 20 + + column_list = [ + "id", + "task_id", + "img_name", + "created_at", + ] + + column_details_list = [ + "id", + "task_id", + "img_name", + "img_url", + "created_at", + ] + + # 폼(생성/수정)에서 제외 + form_excluded_columns = ["created_at"] + + column_searchable_list = [ + Image.task_id, + Image.img_name, + ] + + column_default_sort = (Image.created_at, True) # True: DESC (최신순) + + column_sortable_list = [ + Image.id, + Image.img_name, + Image.created_at, + ] + + column_labels = { + "id": "ID", + "task_id": "작업 ID", + "img_name": "이미지명", + "img_url": "이미지 URL", + "created_at": "생성일시", + } diff --git a/app/home/api/routers/v1/__init__.py b/app/home/api/routers/v1/__init__.py index c4c9f48..75a7215 100644 --- a/app/home/api/routers/v1/__init__.py +++ b/app/home/api/routers/v1/__init__.py @@ -1,15 +1,15 @@ -"""API 1 Version Router Module.""" - -# from fastapi import APIRouter, Depends - -# API 버전 1 라우터를 정의합니다. -# router = APIRouter( -# prefix="/api/v1", -# dependencies=[Depends(check_use_api), Depends(set_current_connect)], -# ) -# router = APIRouter( -# prefix="/api/v1", -# dependencies=[Depends(check_use_api), Depends(set_current_connect)], -# ) -# router.include_router(auth.router, tags=[Tags.AUTH]) -# router.include_router(board.router, prefix="/boards", tags=[Tags.BOARD]) +"""API 1 Version Router Module.""" + +# from fastapi import APIRouter, Depends + +# API 버전 1 라우터를 정의합니다. +# router = APIRouter( +# prefix="/api/v1", +# dependencies=[Depends(check_use_api), Depends(set_current_connect)], +# ) +# router = APIRouter( +# prefix="/api/v1", +# dependencies=[Depends(check_use_api), Depends(set_current_connect)], +# ) +# router.include_router(auth.router, tags=[Tags.AUTH]) +# router.include_router(board.router, prefix="/boards", tags=[Tags.BOARD]) diff --git a/app/home/api/routers/v1/home.py b/app/home/api/routers/v1/home.py index 42cc159..440cb8b 100644 --- a/app/home/api/routers/v1/home.py +++ b/app/home/api/routers/v1/home.py @@ -1,689 +1,804 @@ -import json -from datetime import date -from pathlib import Path -from typing import Optional -from urllib.parse import unquote, urlparse - -import aiofiles -from fastapi import APIRouter, Depends, File, Form, HTTPException, UploadFile, status -from sqlalchemy.ext.asyncio import AsyncSession - -from app.database.session import get_session, AsyncSessionLocal -from app.home.models import Image -from app.home.schemas.home_schema import ( - CrawlingRequest, - CrawlingResponse, - ErrorResponse, - ImageUploadResponse, - ImageUploadResultItem, - ImageUrlItem, - MarketingAnalysis, - ProcessedInfo, -) -from app.utils.upload_blob_as_request import AzureBlobUploader -from app.utils.chatgpt_prompt import ChatgptService -from app.utils.common import generate_task_id -from app.utils.nvMapScraper import NvMapScraper - -MEDIA_ROOT = Path("media") - -# 전국 시 이름 목록 (roadAddress에서 region 추출용) -# fmt: off -KOREAN_CITIES = [ - # 특별시/광역시 - "서울시", "부산시", "대구시", "인천시", "광주시", "대전시", "울산시", "세종시", - # 경기도 - "수원시", "성남시", "고양시", "용인시", "부천시", "안산시", "안양시", "남양주시", - "화성시", "평택시", "의정부시", "시흥시", "파주시", "광명시", "김포시", "군포시", - "광주시", "이천시", "양주시", "오산시", "구리시", "안성시", "포천시", "의왕시", - "하남시", "여주시", "동두천시", "과천시", - # 강원도 - "춘천시", "원주시", "강릉시", "동해시", "태백시", "속초시", "삼척시", - # 충청북도 - "청주시", "충주시", "제천시", - # 충청남도 - "천안시", "공주시", "보령시", "아산시", "서산시", "논산시", "계룡시", "당진시", - # 전라북도 - "전주시", "군산시", "익산시", "정읍시", "남원시", "김제시", - # 전라남도 - "목포시", "여수시", "순천시", "나주시", "광양시", - # 경상북도 - "포항시", "경주시", "김천시", "안동시", "구미시", "영주시", "영천시", "상주시", "문경시", "경산시", - # 경상남도 - "창원시", "진주시", "통영시", "사천시", "김해시", "밀양시", "거제시", "양산시", - # 제주도 - "제주시", "서귀포시", -] -# fmt: on - -router = APIRouter() - - -def _extract_region_from_address(road_address: str | None) -> str: - """roadAddress에서 시 이름 추출""" - if not road_address: - return "" - for city in KOREAN_CITIES: - if city in road_address: - return city - return "" - - -@router.post( - "/crawling", - summary="네이버 지도 크롤링", - description=""" -네이버 지도 장소 URL을 입력받아 이미지 목록과 기본 정보를 크롤링합니다. - -## 요청 필드 -- **url**: 네이버 지도 장소 URL (필수) - -## 반환 정보 -- **image_list**: 장소 이미지 URL 목록 -- **image_count**: 이미지 개수 -- **processed_info**: 가공된 장소 정보 (customer_name, region, detail_region_info) - """, - response_model=CrawlingResponse, - response_description="크롤링 결과", - responses={ - 200: {"description": "크롤링 성공", "model": CrawlingResponse}, - 400: { - "description": "잘못된 URL", - "model": ErrorResponse, - }, - }, - tags=["crawling"], -) -async def crawling(request_body: CrawlingRequest): - """네이버 지도 장소 크롤링""" - scraper = NvMapScraper(request_body.url) - await scraper.scrap() - - # 가공된 정보 생성 - processed_info = None - marketing_analysis = None - - if scraper.base_info: - road_address = scraper.base_info.get("roadAddress", "") - customer_name = scraper.base_info.get("name", "") - region = _extract_region_from_address(road_address) - - processed_info = ProcessedInfo( - customer_name=customer_name, - region=region, - detail_region_info=road_address or "", - ) - - # ChatGPT를 이용한 마케팅 분석 - chatgpt_service = ChatgptService( - customer_name=customer_name, - region=region, - detail_region_info=road_address or "", - ) - prompt = chatgpt_service.build_market_analysis_prompt() - raw_response = await chatgpt_service.generate(prompt) - parsed = await chatgpt_service.parse_marketing_analysis(raw_response) - marketing_analysis = MarketingAnalysis(**parsed) - - return { - "image_list": scraper.image_link_list, - "image_count": len(scraper.image_link_list) if scraper.image_link_list else 0, - "processed_info": processed_info, - "marketing_analysis": marketing_analysis, - } - - -def _extract_image_name(url: str, index: int) -> str: - """URL에서 이미지 이름 추출 또는 기본 이름 생성""" - try: - path = urlparse(url).path - filename = path.split("/")[-1] if path else "" - if filename: - return unquote(filename) - except Exception: - pass - return f"image_{index + 1:03d}" - - -ALLOWED_IMAGE_EXTENSIONS = {".jpg", ".jpeg", ".png", ".webp", ".heic", ".heif"} - - -def _is_valid_image_extension(filename: str | None) -> bool: - """파일명의 확장자가 유효한 이미지 확장자인지 확인""" - if not filename: - return False - ext = Path(filename).suffix.lower() - return ext in ALLOWED_IMAGE_EXTENSIONS - - -def _get_file_extension(filename: str) -> str: - """파일명에서 확장자 추출 (소문자)""" - return Path(filename).suffix.lower() - - -async def _save_upload_file(file: UploadFile, save_path: Path) -> None: - """업로드 파일을 지정된 경로에 저장""" - save_path.parent.mkdir(parents=True, exist_ok=True) - async with aiofiles.open(save_path, "wb") as f: - content = await file.read() - await f.write(content) - - -IMAGES_JSON_EXAMPLE = """[ - {"url": "https://naverbooking-phinf.pstatic.net/20240514_189/1715688030436xT14o_JPEG/1.jpg"}, - {"url": "https://naverbooking-phinf.pstatic.net/20240514_48/1715688030574wTtQd_JPEG/2.jpg"}, - {"url": "https://naverbooking-phinf.pstatic.net/20240514_92/17156880307484bvpH_JPEG/3.jpg"}, - {"url": "https://naverbooking-phinf.pstatic.net/20240514_7/1715688031000y8Y5q_JPEG/4.jpg"}, - {"url": "https://naverbooking-phinf.pstatic.net/20240514_259/17156880311809wCnY_JPEG/5.jpg", "name": "외관"} -]""" - - -@router.post( - "/image/upload/server", - include_in_schema=False, - summary="이미지 업로드 (로컬 서버)", - description=""" -이미지를 로컬 서버(media 폴더)에 업로드하고 새로운 task_id를 생성합니다. - -## 요청 방식 -multipart/form-data 형식으로 전송합니다. - -## 요청 필드 -- **images_json**: 외부 이미지 URL 목록 (JSON 문자열, 선택) -- **files**: 이미지 바이너리 파일 목록 (선택) - -**주의**: images_json 또는 files 중 최소 하나는 반드시 전달해야 합니다. - -## 지원 이미지 확장자 -jpg, jpeg, png, webp, heic, heif - -## images_json 예시 -```json -[ - {"url": "https://naverbooking-phinf.pstatic.net/20240514_189/1715688030436xT14o_JPEG/1.jpg"}, - {"url": "https://naverbooking-phinf.pstatic.net/20240514_48/1715688030574wTtQd_JPEG/2.jpg"}, - {"url": "https://naverbooking-phinf.pstatic.net/20240514_92/17156880307484bvpH_JPEG/3.jpg"}, - {"url": "https://naverbooking-phinf.pstatic.net/20240514_7/1715688031000y8Y5q_JPEG/4.jpg"}, - {"url": "https://naverbooking-phinf.pstatic.net/20240514_259/17156880311809wCnY_JPEG/5.jpg", "name": "외관"} -] -``` - -## 바이너리 파일 업로드 테스트 방법 - -### 1. Swagger UI에서 테스트 -1. 이 엔드포인트의 "Try it out" 버튼 클릭 -2. task_id 입력 (예: test-task-001) -3. files 항목에서 "Add item" 클릭하여 로컬 이미지 파일 선택 -4. (선택) images_json에 URL 목록 JSON 입력 -5. "Execute" 버튼 클릭 - -### 2. cURL로 테스트 -```bash -# 바이너리 파일만 업로드 -curl -X POST "http://localhost:8000/image/upload/server/test-task-001" \\ - -F "files=@/path/to/image1.jpg" \\ - -F "files=@/path/to/image2.png" - -# URL + 바이너리 파일 동시 업로드 -curl -X POST "http://localhost:8000/image/upload/server/test-task-001" \\ - -F 'images_json=[{"url":"https://example.com/image.jpg"}]' \\ - -F "files=@/path/to/local_image.jpg" -``` - -### 3. Python requests로 테스트 -```python -import requests - -url = "http://localhost:8000/image/upload/server/test-task-001" -files = [ - ("files", ("image1.jpg", open("image1.jpg", "rb"), "image/jpeg")), - ("files", ("image2.png", open("image2.png", "rb"), "image/png")), -] -data = { - "images_json": '[{"url": "https://example.com/image.jpg"}]' -} -response = requests.post(url, files=files, data=data) -print(response.json()) -``` - -## 반환 정보 -- **task_id**: 작업 고유 식별자 -- **total_count**: 총 업로드된 이미지 개수 -- **url_count**: URL로 등록된 이미지 개수 (Image 테이블에 외부 URL 그대로 저장) -- **file_count**: 파일로 업로드된 이미지 개수 (media 폴더에 저장) -- **saved_count**: Image 테이블에 저장된 row 수 -- **images**: 업로드된 이미지 목록 - - **source**: "url" (외부 URL) 또는 "file" (로컬 서버 저장) - -## 저장 경로 -- 바이너리 파일: /media/image/{날짜}/{uuid7}/{파일명} -- URL 이미지: 외부 URL 그대로 Image 테이블에 저장 - -## 반환 정보 -- **task_id**: 새로 생성된 작업 고유 식별자 -- **image_urls**: Image 테이블에 저장된 현재 task_id의 이미지 URL 목록 - """, - response_model=ImageUploadResponse, - responses={ - 200: {"description": "이미지 업로드 성공"}, - 400: {"description": "이미지가 제공되지 않음", "model": ErrorResponse}, - }, - tags=["image"], -) -async def upload_images( - images_json: Optional[str] = Form( - default=None, - description="외부 이미지 URL 목록 (JSON 문자열)", - example=IMAGES_JSON_EXAMPLE, - ), - files: Optional[list[UploadFile]] = File( - default=None, description="이미지 바이너리 파일 목록" - ), - session: AsyncSession = Depends(get_session), -) -> ImageUploadResponse: - """이미지 업로드 (URL + 바이너리 파일)""" - # task_id 생성 - task_id = await generate_task_id() - - # 1. 진입 검증: images_json 또는 files 중 하나는 반드시 있어야 함 - has_images_json = images_json is not None and images_json.strip() != "" - has_files = files is not None and len(files) > 0 - - if not has_images_json and not has_files: - raise HTTPException( - status_code=status.HTTP_400_BAD_REQUEST, - detail="images_json 또는 files 중 하나는 반드시 제공해야 합니다.", - ) - - # 2. images_json 파싱 (있는 경우만) - url_images: list[ImageUrlItem] = [] - if has_images_json: - try: - parsed = json.loads(images_json) - if isinstance(parsed, list): - url_images = [ImageUrlItem(**item) for item in parsed if item] - except (json.JSONDecodeError, TypeError, ValueError) as e: - raise HTTPException( - status_code=status.HTTP_400_BAD_REQUEST, - detail=f"images_json 파싱 오류: {str(e)}", - ) - - # 3. 유효한 파일만 필터링 (빈 파일, 유효한 이미지 확장자가 아닌 경우 제외) - valid_files: list[UploadFile] = [] - skipped_files: list[str] = [] - if has_files and files: - for f in files: - is_valid_ext = _is_valid_image_extension(f.filename) - is_not_empty = ( - f.size is None or f.size > 0 - ) # size가 None이면 아직 읽지 않은 것 - is_real_file = ( - f.filename and f.filename != "filename" - ) # Swagger 빈 파일 체크 - if f and is_real_file and is_valid_ext and is_not_empty: - valid_files.append(f) - else: - skipped_files.append(f.filename or "unknown") - - # 유효한 데이터가 하나도 없으면 에러 - if not url_images and not valid_files: - raise HTTPException( - status_code=status.HTTP_400_BAD_REQUEST, - detail=f"유효한 이미지가 없습니다. 지원 확장자: {', '.join(ALLOWED_IMAGE_EXTENSIONS)}. 건너뛴 파일: {skipped_files}", - ) - - result_images: list[ImageUploadResultItem] = [] - img_order = 0 - - # 1. URL 이미지 저장 - for url_item in url_images: - img_name = url_item.name or _extract_image_name(url_item.url, img_order) - - image = Image( - task_id=task_id, - img_name=img_name, - img_url=url_item.url, - img_order=img_order, - ) - session.add(image) - await session.flush() # ID 생성을 위해 flush - - result_images.append( - ImageUploadResultItem( - id=image.id, - img_name=img_name, - img_url=url_item.url, - img_order=img_order, - source="url", - ) - ) - img_order += 1 - - # 2. 바이너리 파일을 media에 저장 - if valid_files: - today = date.today().strftime("%Y-%m-%d") - # 한 번의 요청에서 업로드된 모든 이미지는 같은 폴더에 저장 - batch_uuid = await generate_task_id() - upload_dir = MEDIA_ROOT / "image" / today / batch_uuid - upload_dir.mkdir(parents=True, exist_ok=True) - - for file in valid_files: - # 파일명: 원본 파일명 사용 (중복 방지를 위해 순서 추가) - original_name = file.filename or "image" - ext = _get_file_extension(file.filename) # type: ignore[arg-type] - # 파일명에서 확장자 제거 후 순서 추가 - name_without_ext = ( - original_name.rsplit(".", 1)[0] - if "." in original_name - else original_name - ) - filename = f"{name_without_ext}_{img_order:03d}{ext}" - - save_path = upload_dir / filename - - # media에 파일 저장 - await _save_upload_file(file, save_path) - - # media 기준 URL 생성 - img_url = f"/media/image/{today}/{batch_uuid}/{filename}" - img_name = file.filename or filename - - image = Image( - task_id=task_id, - img_name=img_name, - img_url=img_url, # Media URL을 DB에 저장 - img_order=img_order, - ) - session.add(image) - await session.flush() - - result_images.append( - ImageUploadResultItem( - id=image.id, - img_name=img_name, - img_url=img_url, - img_order=img_order, - source="file", - ) - ) - img_order += 1 - - saved_count = len(result_images) - await session.commit() - - # Image 테이블에서 현재 task_id의 이미지 URL 목록 조회 - image_urls = [img.img_url for img in result_images] - - return ImageUploadResponse( - task_id=task_id, - total_count=len(result_images), - url_count=len(url_images), - file_count=len(valid_files), - saved_count=saved_count, - images=result_images, - image_urls=image_urls, - ) - - -@router.post( - "/image/upload/blob", - summary="이미지 업로드 (Azure Blob Storage)", - description=""" -이미지를 Azure Blob Storage에 업로드하고 새로운 task_id를 생성합니다. -바이너리 파일은 로컬 서버에 저장하지 않고 Azure Blob에 직접 업로드됩니다. - -## 요청 방식 -multipart/form-data 형식으로 전송합니다. - -## 요청 필드 -- **images_json**: 외부 이미지 URL 목록 (JSON 문자열, 선택) -- **files**: 이미지 바이너리 파일 목록 (선택) - -**주의**: images_json 또는 files 중 최소 하나는 반드시 전달해야 합니다. - -## 지원 이미지 확장자 -jpg, jpeg, png, webp, heic, heif - -## images_json 예시 -```json -[ - {"url": "https://example.com/image1.jpg"}, - {"url": "https://example.com/image2.jpg", "name": "외관"} -] -``` - -## 바이너리 파일 업로드 테스트 방법 - -### cURL로 테스트 -```bash -# 바이너리 파일만 업로드 -curl -X POST "http://localhost:8000/image/upload/blob" \\ - -F "files=@/path/to/image1.jpg" \\ - -F "files=@/path/to/image2.png" - -# URL + 바이너리 파일 동시 업로드 -curl -X POST "http://localhost:8000/image/upload/blob" \\ - -F 'images_json=[{"url":"https://example.com/image.jpg"}]' \\ - -F "files=@/path/to/local_image.jpg" -``` - -## 반환 정보 -- **task_id**: 새로 생성된 작업 고유 식별자 -- **total_count**: 총 업로드된 이미지 개수 -- **url_count**: URL로 등록된 이미지 개수 (Image 테이블에 외부 URL 그대로 저장) -- **file_count**: 파일로 업로드된 이미지 개수 (Azure Blob Storage에 저장) -- **saved_count**: Image 테이블에 저장된 row 수 -- **images**: 업로드된 이미지 목록 - - **source**: "url" (외부 URL) 또는 "blob" (Azure Blob Storage) -- **image_urls**: Image 테이블에 저장된 현재 task_id의 이미지 URL 목록 - -## 저장 경로 -- 바이너리 파일: Azure Blob Storage ({BASE_URL}/{task_id}/image/{파일명}) -- URL 이미지: 외부 URL 그대로 Image 테이블에 저장 - """, - response_model=ImageUploadResponse, - responses={ - 200: {"description": "이미지 업로드 성공"}, - 400: {"description": "이미지가 제공되지 않음", "model": ErrorResponse}, - }, - tags=["image"], -) -async def upload_images_blob( - images_json: Optional[str] = Form( - default=None, - description="외부 이미지 URL 목록 (JSON 문자열)", - example=IMAGES_JSON_EXAMPLE, - ), - files: Optional[list[UploadFile]] = File( - default=None, description="이미지 바이너리 파일 목록" - ), -) -> ImageUploadResponse: - """이미지 업로드 (URL + Azure Blob Storage) - - 3단계로 분리하여 세션 점유 시간 최소화: - - Stage 1: 입력 검증 및 파일 데이터 준비 (세션 없음) - - Stage 2: Azure Blob 업로드 (세션 없음) - - Stage 3: DB 저장 (새 세션으로 빠르게 처리) - """ - import time - request_start = time.perf_counter() - - # task_id 생성 - task_id = await generate_task_id() - print(f"[upload_images_blob] START - task_id: {task_id}") - - # ========== Stage 1: 입력 검증 및 파일 데이터 준비 (세션 없음) ========== - has_images_json = images_json is not None and images_json.strip() != "" - has_files = files is not None and len(files) > 0 - - if not has_images_json and not has_files: - raise HTTPException( - status_code=status.HTTP_400_BAD_REQUEST, - detail="images_json 또는 files 중 하나는 반드시 제공해야 합니다.", - ) - - # images_json 파싱 - url_images: list[ImageUrlItem] = [] - if has_images_json and images_json: - try: - parsed = json.loads(images_json) - if isinstance(parsed, list): - url_images = [ImageUrlItem(**item) for item in parsed if item] - except (json.JSONDecodeError, TypeError, ValueError) as e: - raise HTTPException( - status_code=status.HTTP_400_BAD_REQUEST, - detail=f"images_json 파싱 오류: {str(e)}", - ) - - # 유효한 파일만 필터링 및 파일 내용 미리 읽기 - valid_files_data: list[tuple[str, str, bytes]] = [] # (original_name, ext, content) - skipped_files: list[str] = [] - if has_files and files: - for f in files: - is_valid_ext = _is_valid_image_extension(f.filename) - is_not_empty = f.size is None or f.size > 0 - is_real_file = f.filename and f.filename != "filename" - - if f and is_real_file and is_valid_ext and is_not_empty: - # 파일 내용을 미리 읽어둠 - content = await f.read() - ext = _get_file_extension(f.filename) # type: ignore[arg-type] - valid_files_data.append((f.filename or "image", ext, content)) - else: - skipped_files.append(f.filename or "unknown") - - if not url_images and not valid_files_data: - detail = ( - f"유효한 이미지가 없습니다. " - f"지원 확장자: {', '.join(ALLOWED_IMAGE_EXTENSIONS)}. " - f"건너뛴 파일: {skipped_files}" - ) - raise HTTPException( - status_code=status.HTTP_400_BAD_REQUEST, - detail=detail, - ) - - stage1_time = time.perf_counter() - print(f"[upload_images_blob] Stage 1 done - urls: {len(url_images)}, " - f"files: {len(valid_files_data)}, " - f"elapsed: {(stage1_time - request_start)*1000:.1f}ms") - - # ========== Stage 2: Azure Blob 업로드 (세션 없음) ========== - # 업로드 결과를 저장할 리스트 (나중에 DB에 저장) - blob_upload_results: list[tuple[str, str]] = [] # (img_name, blob_url) - img_order = len(url_images) # URL 이미지 다음 순서부터 시작 - - if valid_files_data: - uploader = AzureBlobUploader(task_id=task_id) - total_files = len(valid_files_data) - - for idx, (original_name, ext, file_content) in enumerate(valid_files_data): - name_without_ext = ( - original_name.rsplit(".", 1)[0] - if "." in original_name - else original_name - ) - filename = f"{name_without_ext}_{img_order:03d}{ext}" - - print(f"[upload_images_blob] Uploading file {idx+1}/{total_files}: " - f"{filename} ({len(file_content)} bytes)") - - # Azure Blob Storage에 직접 업로드 - upload_success = await uploader.upload_image_bytes(file_content, filename) - - if upload_success: - blob_url = uploader.public_url - blob_upload_results.append((original_name, blob_url)) - img_order += 1 - print(f"[upload_images_blob] File {idx+1}/{total_files} SUCCESS") - else: - skipped_files.append(filename) - print(f"[upload_images_blob] File {idx+1}/{total_files} FAILED") - - stage2_time = time.perf_counter() - print(f"[upload_images_blob] Stage 2 done - blob uploads: " - f"{len(blob_upload_results)}, skipped: {len(skipped_files)}, " - f"elapsed: {(stage2_time - stage1_time)*1000:.1f}ms") - - # ========== Stage 3: DB 저장 (새 세션으로 빠르게 처리) ========== - print("[upload_images_blob] Stage 3 starting - DB save...") - result_images: list[ImageUploadResultItem] = [] - img_order = 0 - - try: - async with AsyncSessionLocal() as session: - # URL 이미지 저장 - for url_item in url_images: - img_name = ( - url_item.name or _extract_image_name(url_item.url, img_order) - ) - - image = Image( - task_id=task_id, - img_name=img_name, - img_url=url_item.url, - img_order=img_order, - ) - session.add(image) - await session.flush() - - result_images.append( - ImageUploadResultItem( - id=image.id, - img_name=img_name, - img_url=url_item.url, - img_order=img_order, - source="url", - ) - ) - img_order += 1 - - # Blob 업로드 결과 저장 - for img_name, blob_url in blob_upload_results: - image = Image( - task_id=task_id, - img_name=img_name, - img_url=blob_url, - img_order=img_order, - ) - session.add(image) - await session.flush() - - result_images.append( - ImageUploadResultItem( - id=image.id, - img_name=img_name, - img_url=blob_url, - img_order=img_order, - source="blob", - ) - ) - img_order += 1 - - await session.commit() - stage3_time = time.perf_counter() - print(f"[upload_images_blob] Stage 3 done - " - f"saved: {len(result_images)}, " - f"elapsed: {(stage3_time - stage2_time)*1000:.1f}ms") - - except Exception as e: - print(f"[upload_images_blob] Stage 3 EXCEPTION - " - f"task_id: {task_id}, error: {type(e).__name__}: {e}") - raise - - saved_count = len(result_images) - image_urls = [img.img_url for img in result_images] - - total_time = time.perf_counter() - request_start - print(f"[upload_images_blob] SUCCESS - task_id: {task_id}, " - f"total: {saved_count}, total_time: {total_time*1000:.1f}ms") - - return ImageUploadResponse( - task_id=task_id, - total_count=len(result_images), - url_count=len(url_images), - file_count=len(blob_upload_results), - saved_count=saved_count, - images=result_images, - image_urls=image_urls, - ) +import json +import logging +import traceback +from datetime import date +from pathlib import Path +from typing import Optional +from urllib.parse import unquote, urlparse + +import aiofiles +from fastapi import APIRouter, Depends, File, Form, HTTPException, UploadFile, status +from sqlalchemy.exc import SQLAlchemyError +from sqlalchemy.ext.asyncio import AsyncSession + +from app.database.session import get_session, AsyncSessionLocal +from app.home.models import Image +from app.home.schemas.home_schema import ( + CrawlingRequest, + CrawlingResponse, + ErrorResponse, + ImageUploadResponse, + ImageUploadResultItem, + ImageUrlItem, + MarketingAnalysis, + ProcessedInfo, +) +from app.utils.upload_blob_as_request import AzureBlobUploader +from app.utils.chatgpt_prompt import ChatgptService +from app.utils.common import generate_task_id +from app.utils.nvMapScraper import NvMapScraper, GraphQLException + +# 로거 설정 +logger = logging.getLogger(__name__) + +MEDIA_ROOT = Path("media") + +# 전국 시 이름 목록 (roadAddress에서 region 추출용) +# fmt: off +KOREAN_CITIES = [ + # 특별시/광역시 + "서울시", "부산시", "대구시", "인천시", "광주시", "대전시", "울산시", "세종시", + # 경기도 + "수원시", "성남시", "고양시", "용인시", "부천시", "안산시", "안양시", "남양주시", + "화성시", "평택시", "의정부시", "시흥시", "파주시", "광명시", "김포시", "군포시", + "광주시", "이천시", "양주시", "오산시", "구리시", "안성시", "포천시", "의왕시", + "하남시", "여주시", "동두천시", "과천시", + # 강원도 + "춘천시", "원주시", "강릉시", "동해시", "태백시", "속초시", "삼척시", + # 충청북도 + "청주시", "충주시", "제천시", + # 충청남도 + "천안시", "공주시", "보령시", "아산시", "서산시", "논산시", "계룡시", "당진시", + # 전라북도 + "전주시", "군산시", "익산시", "정읍시", "남원시", "김제시", + # 전라남도 + "목포시", "여수시", "순천시", "나주시", "광양시", + # 경상북도 + "포항시", "경주시", "김천시", "안동시", "구미시", "영주시", "영천시", "상주시", "문경시", "경산시", + # 경상남도 + "창원시", "진주시", "통영시", "사천시", "김해시", "밀양시", "거제시", "양산시", + # 제주도 + "제주시", "서귀포시", +] +# fmt: on + +router = APIRouter() + + +def _extract_region_from_address(road_address: str | None) -> str: + """roadAddress에서 시 이름 추출""" + if not road_address: + return "" + for city in KOREAN_CITIES: + if city in road_address: + return city + return "" + + +@router.post( + "/crawling", + summary="네이버 지도 크롤링", + description=""" +네이버 지도 장소 URL을 입력받아 이미지 목록과 기본 정보를 크롤링합니다. + +## 요청 필드 +- **url**: 네이버 지도 장소 URL (필수) + +## 반환 정보 +- **image_list**: 장소 이미지 URL 목록 +- **image_count**: 이미지 개수 +- **processed_info**: 가공된 장소 정보 (customer_name, region, detail_region_info) + """, + response_model=CrawlingResponse, + response_description="크롤링 결과", + responses={ + 200: {"description": "크롤링 성공", "model": CrawlingResponse}, + 400: { + "description": "잘못된 URL", + "model": ErrorResponse, + }, + 502: { + "description": "크롤링 실패", + "model": ErrorResponse, + }, + }, + tags=["crawling"], +) +async def crawling(request_body: CrawlingRequest): + """네이버 지도 장소 크롤링""" + import time + + request_start = time.perf_counter() + logger.info(f"[crawling] START - url: {request_body.url[:80]}...") + print(f"[crawling] ========== START ==========") + print(f"[crawling] URL: {request_body.url[:80]}...") + + # ========== Step 1: 네이버 지도 크롤링 ========== + step1_start = time.perf_counter() + print(f"[crawling] Step 1: 네이버 지도 크롤링 시작...") + + try: + scraper = NvMapScraper(request_body.url) + await scraper.scrap() + except GraphQLException as e: + step1_elapsed = (time.perf_counter() - step1_start) * 1000 + logger.error(f"[crawling] Step 1 FAILED - GraphQL 크롤링 실패: {e} ({step1_elapsed:.1f}ms)") + print(f"[crawling] Step 1 FAILED - {e} ({step1_elapsed:.1f}ms)") + raise HTTPException( + status_code=status.HTTP_502_BAD_GATEWAY, + detail=f"네이버 지도 크롤링에 실패했습니다: {e}", + ) + except Exception as e: + step1_elapsed = (time.perf_counter() - step1_start) * 1000 + logger.error(f"[crawling] Step 1 FAILED - 크롤링 중 예기치 않은 오류: {e} ({step1_elapsed:.1f}ms)") + print(f"[crawling] Step 1 FAILED - {e} ({step1_elapsed:.1f}ms)") + traceback.print_exc() + raise HTTPException( + status_code=status.HTTP_502_BAD_GATEWAY, + detail="네이버 지도 크롤링 중 오류가 발생했습니다.", + ) + + step1_elapsed = (time.perf_counter() - step1_start) * 1000 + image_count = len(scraper.image_link_list) if scraper.image_link_list else 0 + logger.info(f"[crawling] Step 1 완료 - 이미지 {image_count}개 ({step1_elapsed:.1f}ms)") + print(f"[crawling] Step 1 완료 - 이미지 {image_count}개 ({step1_elapsed:.1f}ms)") + + # ========== Step 2: 정보 가공 ========== + step2_start = time.perf_counter() + print(f"[crawling] Step 2: 정보 가공 시작...") + + processed_info = None + marketing_analysis = None + + if scraper.base_info: + road_address = scraper.base_info.get("roadAddress", "") + customer_name = scraper.base_info.get("name", "") + region = _extract_region_from_address(road_address) + + processed_info = ProcessedInfo( + customer_name=customer_name, + region=region, + detail_region_info=road_address or "", + ) + + step2_elapsed = (time.perf_counter() - step2_start) * 1000 + logger.info(f"[crawling] Step 2 완료 - {customer_name}, {region} ({step2_elapsed:.1f}ms)") + print(f"[crawling] Step 2 완료 - {customer_name}, {region} ({step2_elapsed:.1f}ms)") + + # ========== Step 3: ChatGPT 마케팅 분석 ========== + step3_start = time.perf_counter() + print(f"[crawling] Step 3: ChatGPT 마케팅 분석 시작...") + + try: + # Step 3-1: ChatGPT 서비스 초기화 + step3_1_start = time.perf_counter() + chatgpt_service = ChatgptService( + customer_name=customer_name, + region=region, + detail_region_info=road_address or "", + ) + step3_1_elapsed = (time.perf_counter() - step3_1_start) * 1000 + print(f"[crawling] Step 3-1: 서비스 초기화 완료 ({step3_1_elapsed:.1f}ms)") + + # Step 3-2: 프롬프트 생성 + step3_2_start = time.perf_counter() + prompt = chatgpt_service.build_market_analysis_prompt() + step3_2_elapsed = (time.perf_counter() - step3_2_start) * 1000 + print(f"[crawling] Step 3-2: 프롬프트 생성 완료 - {len(prompt)}자 ({step3_2_elapsed:.1f}ms)") + + # Step 3-3: GPT API 호출 + step3_3_start = time.perf_counter() + raw_response = await chatgpt_service.generate(prompt) + step3_3_elapsed = (time.perf_counter() - step3_3_start) * 1000 + logger.info(f"[crawling] Step 3-3: GPT API 호출 완료 - 응답 {len(raw_response)}자 ({step3_3_elapsed:.1f}ms)") + print(f"[crawling] Step 3-3: GPT API 호출 완료 - 응답 {len(raw_response)}자 ({step3_3_elapsed:.1f}ms)") + + # Step 3-4: 응답 파싱 + step3_4_start = time.perf_counter() + parsed = await chatgpt_service.parse_marketing_analysis(raw_response) + marketing_analysis = MarketingAnalysis(**parsed) + step3_4_elapsed = (time.perf_counter() - step3_4_start) * 1000 + print(f"[crawling] Step 3-4: 응답 파싱 완료 ({step3_4_elapsed:.1f}ms)") + + step3_elapsed = (time.perf_counter() - step3_start) * 1000 + logger.info(f"[crawling] Step 3 완료 - 마케팅 분석 성공 ({step3_elapsed:.1f}ms)") + print(f"[crawling] Step 3 완료 - 마케팅 분석 성공 ({step3_elapsed:.1f}ms)") + + except Exception as e: + step3_elapsed = (time.perf_counter() - step3_start) * 1000 + logger.error(f"[crawling] Step 3 FAILED - GPT 마케팅 분석 중 오류: {e} ({step3_elapsed:.1f}ms)") + print(f"[crawling] Step 3 FAILED - {e} ({step3_elapsed:.1f}ms)") + traceback.print_exc() + # GPT 실패 시에도 크롤링 결과는 반환 + marketing_analysis = None + else: + step2_elapsed = (time.perf_counter() - step2_start) * 1000 + logger.warning(f"[crawling] Step 2 - base_info 없음 ({step2_elapsed:.1f}ms)") + print(f"[crawling] Step 2 - base_info 없음, 마케팅 분석 스킵 ({step2_elapsed:.1f}ms)") + + # ========== 완료 ========== + total_elapsed = (time.perf_counter() - request_start) * 1000 + logger.info(f"[crawling] COMPLETE - 총 소요시간: {total_elapsed:.1f}ms") + print(f"[crawling] ========== COMPLETE ==========") + print(f"[crawling] 총 소요시간: {total_elapsed:.1f}ms") + print(f"[crawling] - Step 1 (크롤링): {step1_elapsed:.1f}ms") + if scraper.base_info: + print(f"[crawling] - Step 2 (정보가공): {step2_elapsed:.1f}ms") + if 'step3_elapsed' in locals(): + print(f"[crawling] - Step 3 (GPT 분석): {step3_elapsed:.1f}ms") + if 'step3_3_elapsed' in locals(): + print(f"[crawling] - GPT API 호출: {step3_3_elapsed:.1f}ms") + + return { + "image_list": scraper.image_link_list, + "image_count": len(scraper.image_link_list) if scraper.image_link_list else 0, + "processed_info": processed_info, + "marketing_analysis": marketing_analysis, + } + + +def _extract_image_name(url: str, index: int) -> str: + """URL에서 이미지 이름 추출 또는 기본 이름 생성""" + try: + path = urlparse(url).path + filename = path.split("/")[-1] if path else "" + if filename: + return unquote(filename) + except Exception: + pass + return f"image_{index + 1:03d}" + + +ALLOWED_IMAGE_EXTENSIONS = {".jpg", ".jpeg", ".png", ".webp", ".heic", ".heif"} + + +def _is_valid_image_extension(filename: str | None) -> bool: + """파일명의 확장자가 유효한 이미지 확장자인지 확인""" + if not filename: + return False + ext = Path(filename).suffix.lower() + return ext in ALLOWED_IMAGE_EXTENSIONS + + +def _get_file_extension(filename: str) -> str: + """파일명에서 확장자 추출 (소문자)""" + return Path(filename).suffix.lower() + + +async def _save_upload_file(file: UploadFile, save_path: Path) -> None: + """업로드 파일을 지정된 경로에 저장""" + save_path.parent.mkdir(parents=True, exist_ok=True) + async with aiofiles.open(save_path, "wb") as f: + content = await file.read() + await f.write(content) + + +IMAGES_JSON_EXAMPLE = """[ + {"url": "https://naverbooking-phinf.pstatic.net/20240514_189/1715688030436xT14o_JPEG/1.jpg"}, + {"url": "https://naverbooking-phinf.pstatic.net/20240514_48/1715688030574wTtQd_JPEG/2.jpg"}, + {"url": "https://naverbooking-phinf.pstatic.net/20240514_92/17156880307484bvpH_JPEG/3.jpg"}, + {"url": "https://naverbooking-phinf.pstatic.net/20240514_7/1715688031000y8Y5q_JPEG/4.jpg"}, + {"url": "https://naverbooking-phinf.pstatic.net/20240514_259/17156880311809wCnY_JPEG/5.jpg", "name": "외관"} +]""" + + +@router.post( + "/image/upload/server", + include_in_schema=False, + summary="이미지 업로드 (로컬 서버)", + description=""" +이미지를 로컬 서버(media 폴더)에 업로드하고 새로운 task_id를 생성합니다. + +## 요청 방식 +multipart/form-data 형식으로 전송합니다. + +## 요청 필드 +- **images_json**: 외부 이미지 URL 목록 (JSON 문자열, 선택) +- **files**: 이미지 바이너리 파일 목록 (선택) + +**주의**: images_json 또는 files 중 최소 하나는 반드시 전달해야 합니다. + +## 지원 이미지 확장자 +jpg, jpeg, png, webp, heic, heif + +## images_json 예시 +```json +[ + {"url": "https://naverbooking-phinf.pstatic.net/20240514_189/1715688030436xT14o_JPEG/1.jpg"}, + {"url": "https://naverbooking-phinf.pstatic.net/20240514_48/1715688030574wTtQd_JPEG/2.jpg"}, + {"url": "https://naverbooking-phinf.pstatic.net/20240514_92/17156880307484bvpH_JPEG/3.jpg"}, + {"url": "https://naverbooking-phinf.pstatic.net/20240514_7/1715688031000y8Y5q_JPEG/4.jpg"}, + {"url": "https://naverbooking-phinf.pstatic.net/20240514_259/17156880311809wCnY_JPEG/5.jpg", "name": "외관"} +] +``` + +## 바이너리 파일 업로드 테스트 방법 + +### 1. Swagger UI에서 테스트 +1. 이 엔드포인트의 "Try it out" 버튼 클릭 +2. task_id 입력 (예: test-task-001) +3. files 항목에서 "Add item" 클릭하여 로컬 이미지 파일 선택 +4. (선택) images_json에 URL 목록 JSON 입력 +5. "Execute" 버튼 클릭 + +### 2. cURL로 테스트 +```bash +# 바이너리 파일만 업로드 +curl -X POST "http://localhost:8000/image/upload/server/test-task-001" \\ + -F "files=@/path/to/image1.jpg" \\ + -F "files=@/path/to/image2.png" + +# URL + 바이너리 파일 동시 업로드 +curl -X POST "http://localhost:8000/image/upload/server/test-task-001" \\ + -F 'images_json=[{"url":"https://example.com/image.jpg"}]' \\ + -F "files=@/path/to/local_image.jpg" +``` + +### 3. Python requests로 테스트 +```python +import requests + +url = "http://localhost:8000/image/upload/server/test-task-001" +files = [ + ("files", ("image1.jpg", open("image1.jpg", "rb"), "image/jpeg")), + ("files", ("image2.png", open("image2.png", "rb"), "image/png")), +] +data = { + "images_json": '[{"url": "https://example.com/image.jpg"}]' +} +response = requests.post(url, files=files, data=data) +print(response.json()) +``` + +## 반환 정보 +- **task_id**: 작업 고유 식별자 +- **total_count**: 총 업로드된 이미지 개수 +- **url_count**: URL로 등록된 이미지 개수 (Image 테이블에 외부 URL 그대로 저장) +- **file_count**: 파일로 업로드된 이미지 개수 (media 폴더에 저장) +- **saved_count**: Image 테이블에 저장된 row 수 +- **images**: 업로드된 이미지 목록 + - **source**: "url" (외부 URL) 또는 "file" (로컬 서버 저장) + +## 저장 경로 +- 바이너리 파일: /media/image/{날짜}/{uuid7}/{파일명} +- URL 이미지: 외부 URL 그대로 Image 테이블에 저장 + +## 반환 정보 +- **task_id**: 새로 생성된 작업 고유 식별자 +- **image_urls**: Image 테이블에 저장된 현재 task_id의 이미지 URL 목록 + """, + response_model=ImageUploadResponse, + responses={ + 200: {"description": "이미지 업로드 성공"}, + 400: {"description": "이미지가 제공되지 않음", "model": ErrorResponse}, + }, + tags=["image"], +) +async def upload_images( + images_json: Optional[str] = Form( + default=None, + description="외부 이미지 URL 목록 (JSON 문자열)", + examples=[IMAGES_JSON_EXAMPLE], + ), + files: Optional[list[UploadFile]] = File( + default=None, description="이미지 바이너리 파일 목록" + ), + session: AsyncSession = Depends(get_session), +) -> ImageUploadResponse: + """이미지 업로드 (URL + 바이너리 파일)""" + # task_id 생성 + task_id = await generate_task_id() + + # 1. 진입 검증: images_json 또는 files 중 하나는 반드시 있어야 함 + has_images_json = images_json is not None and images_json.strip() != "" + has_files = files is not None and len(files) > 0 + + if not has_images_json and not has_files: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail="images_json 또는 files 중 하나는 반드시 제공해야 합니다.", + ) + + # 2. images_json 파싱 (있는 경우만) + url_images: list[ImageUrlItem] = [] + if has_images_json: + try: + parsed = json.loads(images_json) + if isinstance(parsed, list): + url_images = [ImageUrlItem(**item) for item in parsed if item] + except (json.JSONDecodeError, TypeError, ValueError) as e: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=f"images_json 파싱 오류: {str(e)}", + ) + + # 3. 유효한 파일만 필터링 (빈 파일, 유효한 이미지 확장자가 아닌 경우 제외) + valid_files: list[UploadFile] = [] + skipped_files: list[str] = [] + if has_files and files: + for f in files: + is_valid_ext = _is_valid_image_extension(f.filename) + is_not_empty = ( + f.size is None or f.size > 0 + ) # size가 None이면 아직 읽지 않은 것 + is_real_file = ( + f.filename and f.filename != "filename" + ) # Swagger 빈 파일 체크 + if f and is_real_file and is_valid_ext and is_not_empty: + valid_files.append(f) + else: + skipped_files.append(f.filename or "unknown") + + # 유효한 데이터가 하나도 없으면 에러 + if not url_images and not valid_files: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=f"유효한 이미지가 없습니다. 지원 확장자: {', '.join(ALLOWED_IMAGE_EXTENSIONS)}. 건너뛴 파일: {skipped_files}", + ) + + result_images: list[ImageUploadResultItem] = [] + img_order = 0 + + # 1. URL 이미지 저장 + for url_item in url_images: + img_name = url_item.name or _extract_image_name(url_item.url, img_order) + + image = Image( + task_id=task_id, + img_name=img_name, + img_url=url_item.url, + img_order=img_order, + ) + session.add(image) + await session.flush() # ID 생성을 위해 flush + + result_images.append( + ImageUploadResultItem( + id=image.id, + img_name=img_name, + img_url=url_item.url, + img_order=img_order, + source="url", + ) + ) + img_order += 1 + + # 2. 바이너리 파일을 media에 저장 + if valid_files: + today = date.today().strftime("%Y-%m-%d") + # 한 번의 요청에서 업로드된 모든 이미지는 같은 폴더에 저장 + batch_uuid = await generate_task_id() + upload_dir = MEDIA_ROOT / "image" / today / batch_uuid + upload_dir.mkdir(parents=True, exist_ok=True) + + for file in valid_files: + # 파일명: 원본 파일명 사용 (중복 방지를 위해 순서 추가) + original_name = file.filename or "image" + ext = _get_file_extension(file.filename) # type: ignore[arg-type] + # 파일명에서 확장자 제거 후 순서 추가 + name_without_ext = ( + original_name.rsplit(".", 1)[0] + if "." in original_name + else original_name + ) + filename = f"{name_without_ext}_{img_order:03d}{ext}" + + save_path = upload_dir / filename + + # media에 파일 저장 + await _save_upload_file(file, save_path) + + # media 기준 URL 생성 + img_url = f"/media/image/{today}/{batch_uuid}/{filename}" + img_name = file.filename or filename + + image = Image( + task_id=task_id, + img_name=img_name, + img_url=img_url, # Media URL을 DB에 저장 + img_order=img_order, + ) + session.add(image) + await session.flush() + + result_images.append( + ImageUploadResultItem( + id=image.id, + img_name=img_name, + img_url=img_url, + img_order=img_order, + source="file", + ) + ) + img_order += 1 + + saved_count = len(result_images) + await session.commit() + + # Image 테이블에서 현재 task_id의 이미지 URL 목록 조회 + image_urls = [img.img_url for img in result_images] + + return ImageUploadResponse( + task_id=task_id, + total_count=len(result_images), + url_count=len(url_images), + file_count=len(valid_files), + saved_count=saved_count, + images=result_images, + image_urls=image_urls, + ) + + +@router.post( + "/image/upload/blob", + summary="이미지 업로드 (Azure Blob Storage)", + description=""" +이미지를 Azure Blob Storage에 업로드하고 새로운 task_id를 생성합니다. +바이너리 파일은 로컬 서버에 저장하지 않고 Azure Blob에 직접 업로드됩니다. + +## 요청 방식 +multipart/form-data 형식으로 전송합니다. + +## 요청 필드 +- **images_json**: 외부 이미지 URL 목록 (JSON 문자열, 선택) +- **files**: 이미지 바이너리 파일 목록 (선택) + +**주의**: images_json 또는 files 중 최소 하나는 반드시 전달해야 합니다. + +## 지원 이미지 확장자 +jpg, jpeg, png, webp, heic, heif + +## images_json 예시 +```json +[ + {"url": "https://example.com/image1.jpg"}, + {"url": "https://example.com/image2.jpg", "name": "외관"} +] +``` + +## 바이너리 파일 업로드 테스트 방법 + +### cURL로 테스트 +```bash +# 바이너리 파일만 업로드 +curl -X POST "http://localhost:8000/image/upload/blob" \\ + -F "files=@/path/to/image1.jpg" \\ + -F "files=@/path/to/image2.png" + +# URL + 바이너리 파일 동시 업로드 +curl -X POST "http://localhost:8000/image/upload/blob" \\ + -F 'images_json=[{"url":"https://example.com/image.jpg"}]' \\ + -F "files=@/path/to/local_image.jpg" +``` + +## 반환 정보 +- **task_id**: 새로 생성된 작업 고유 식별자 +- **total_count**: 총 업로드된 이미지 개수 +- **url_count**: URL로 등록된 이미지 개수 (Image 테이블에 외부 URL 그대로 저장) +- **file_count**: 파일로 업로드된 이미지 개수 (Azure Blob Storage에 저장) +- **saved_count**: Image 테이블에 저장된 row 수 +- **images**: 업로드된 이미지 목록 + - **source**: "url" (외부 URL) 또는 "blob" (Azure Blob Storage) +- **image_urls**: Image 테이블에 저장된 현재 task_id의 이미지 URL 목록 + +## 저장 경로 +- 바이너리 파일: Azure Blob Storage ({BASE_URL}/{task_id}/image/{파일명}) +- URL 이미지: 외부 URL 그대로 Image 테이블에 저장 + """, + response_model=ImageUploadResponse, + responses={ + 200: {"description": "이미지 업로드 성공"}, + 400: {"description": "이미지가 제공되지 않음", "model": ErrorResponse}, + }, + tags=["image"], +) +async def upload_images_blob( + images_json: Optional[str] = Form( + default=None, + description="외부 이미지 URL 목록 (JSON 문자열)", + examples=[IMAGES_JSON_EXAMPLE], + ), + files: Optional[list[UploadFile]] = File( + default=None, description="이미지 바이너리 파일 목록" + ), +) -> ImageUploadResponse: + """이미지 업로드 (URL + Azure Blob Storage) + + 3단계로 분리하여 세션 점유 시간 최소화: + - Stage 1: 입력 검증 및 파일 데이터 준비 (세션 없음) + - Stage 2: Azure Blob 업로드 (세션 없음) + - Stage 3: DB 저장 (새 세션으로 빠르게 처리) + """ + import time + request_start = time.perf_counter() + + # task_id 생성 + task_id = await generate_task_id() + print(f"[upload_images_blob] START - task_id: {task_id}") + + # ========== Stage 1: 입력 검증 및 파일 데이터 준비 (세션 없음) ========== + has_images_json = images_json is not None and images_json.strip() != "" + has_files = files is not None and len(files) > 0 + + if not has_images_json and not has_files: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail="images_json 또는 files 중 하나는 반드시 제공해야 합니다.", + ) + + # images_json 파싱 + url_images: list[ImageUrlItem] = [] + if has_images_json and images_json: + try: + parsed = json.loads(images_json) + if isinstance(parsed, list): + url_images = [ImageUrlItem(**item) for item in parsed if item] + except (json.JSONDecodeError, TypeError, ValueError) as e: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=f"images_json 파싱 오류: {str(e)}", + ) + + # 유효한 파일만 필터링 및 파일 내용 미리 읽기 + valid_files_data: list[tuple[str, str, bytes]] = [] # (original_name, ext, content) + skipped_files: list[str] = [] + if has_files and files: + for f in files: + is_valid_ext = _is_valid_image_extension(f.filename) + is_not_empty = f.size is None or f.size > 0 + is_real_file = f.filename and f.filename != "filename" + + if f and is_real_file and is_valid_ext and is_not_empty: + # 파일 내용을 미리 읽어둠 + content = await f.read() + ext = _get_file_extension(f.filename) # type: ignore[arg-type] + valid_files_data.append((f.filename or "image", ext, content)) + else: + skipped_files.append(f.filename or "unknown") + + if not url_images and not valid_files_data: + detail = ( + f"유효한 이미지가 없습니다. " + f"지원 확장자: {', '.join(ALLOWED_IMAGE_EXTENSIONS)}. " + f"건너뛴 파일: {skipped_files}" + ) + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=detail, + ) + + stage1_time = time.perf_counter() + print(f"[upload_images_blob] Stage 1 done - urls: {len(url_images)}, " + f"files: {len(valid_files_data)}, " + f"elapsed: {(stage1_time - request_start)*1000:.1f}ms") + + # ========== Stage 2: Azure Blob 업로드 (세션 없음) ========== + # 업로드 결과를 저장할 리스트 (나중에 DB에 저장) + blob_upload_results: list[tuple[str, str]] = [] # (img_name, blob_url) + img_order = len(url_images) # URL 이미지 다음 순서부터 시작 + + if valid_files_data: + uploader = AzureBlobUploader(task_id=task_id) + total_files = len(valid_files_data) + + for idx, (original_name, ext, file_content) in enumerate(valid_files_data): + name_without_ext = ( + original_name.rsplit(".", 1)[0] + if "." in original_name + else original_name + ) + filename = f"{name_without_ext}_{img_order:03d}{ext}" + + print(f"[upload_images_blob] Uploading file {idx+1}/{total_files}: " + f"{filename} ({len(file_content)} bytes)") + + # Azure Blob Storage에 직접 업로드 + upload_success = await uploader.upload_image_bytes(file_content, filename) + + if upload_success: + blob_url = uploader.public_url + blob_upload_results.append((original_name, blob_url)) + img_order += 1 + print(f"[upload_images_blob] File {idx+1}/{total_files} SUCCESS") + else: + skipped_files.append(filename) + print(f"[upload_images_blob] File {idx+1}/{total_files} FAILED") + + stage2_time = time.perf_counter() + print(f"[upload_images_blob] Stage 2 done - blob uploads: " + f"{len(blob_upload_results)}, skipped: {len(skipped_files)}, " + f"elapsed: {(stage2_time - stage1_time)*1000:.1f}ms") + + # ========== Stage 3: DB 저장 (새 세션으로 빠르게 처리) ========== + print("[upload_images_blob] Stage 3 starting - DB save...") + result_images: list[ImageUploadResultItem] = [] + img_order = 0 + + try: + async with AsyncSessionLocal() as session: + # URL 이미지 저장 + for url_item in url_images: + img_name = ( + url_item.name or _extract_image_name(url_item.url, img_order) + ) + + image = Image( + task_id=task_id, + img_name=img_name, + img_url=url_item.url, + img_order=img_order, + ) + session.add(image) + await session.flush() + + result_images.append( + ImageUploadResultItem( + id=image.id, + img_name=img_name, + img_url=url_item.url, + img_order=img_order, + source="url", + ) + ) + img_order += 1 + + # Blob 업로드 결과 저장 + for img_name, blob_url in blob_upload_results: + image = Image( + task_id=task_id, + img_name=img_name, + img_url=blob_url, + img_order=img_order, + ) + session.add(image) + await session.flush() + + result_images.append( + ImageUploadResultItem( + id=image.id, + img_name=img_name, + img_url=blob_url, + img_order=img_order, + source="blob", + ) + ) + img_order += 1 + + await session.commit() + stage3_time = time.perf_counter() + print(f"[upload_images_blob] Stage 3 done - " + f"saved: {len(result_images)}, " + f"elapsed: {(stage3_time - stage2_time)*1000:.1f}ms") + + except SQLAlchemyError as e: + logger.error(f"[upload_images_blob] DB Error - task_id: {task_id}, error: {e}") + traceback.print_exc() + raise HTTPException( + status_code=status.HTTP_503_SERVICE_UNAVAILABLE, + detail="이미지 저장 중 데이터베이스 오류가 발생했습니다.", + ) + except Exception as e: + logger.error(f"[upload_images_blob] Stage 3 EXCEPTION - " + f"task_id: {task_id}, error: {type(e).__name__}: {e}") + traceback.print_exc() + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="이미지 업로드 중 오류가 발생했습니다.", + ) + + saved_count = len(result_images) + image_urls = [img.img_url for img in result_images] + + total_time = time.perf_counter() - request_start + print(f"[upload_images_blob] SUCCESS - task_id: {task_id}, " + f"total: {saved_count}, total_time: {total_time*1000:.1f}ms") + + return ImageUploadResponse( + task_id=task_id, + total_count=len(result_images), + url_count=len(url_images), + file_count=len(blob_upload_results), + saved_count=saved_count, + images=result_images, + image_urls=image_urls, + ) diff --git a/app/home/models.py b/app/home/models.py index a13ceba..13c8508 100644 --- a/app/home/models.py +++ b/app/home/models.py @@ -1,215 +1,215 @@ -""" -Home 모듈 SQLAlchemy 모델 정의 - -이 모듈은 영상 제작 파이프라인의 핵심 데이터 모델을 정의합니다. -- Project: 프로젝트(사용자 입력 이력) 관리 -- Image: 업로드된 이미지 URL 관리 -""" - -from datetime import datetime -from typing import TYPE_CHECKING, List, Optional - -from sqlalchemy import DateTime, Index, Integer, String, Text, func -from sqlalchemy.orm import Mapped, mapped_column, relationship - -from app.database.session import Base - -if TYPE_CHECKING: - from app.lyric.models import Lyric - from app.song.models import Song - from app.video.models import Video - - -class Project(Base): - """ - 프로젝트 테이블 (사용자 입력 이력) - - 영상 제작 요청의 시작점으로, 고객 정보와 지역 정보를 저장합니다. - 하위 테이블(Lyric, Song, Video)의 부모 테이블 역할을 합니다. - - Attributes: - id: 고유 식별자 (자동 증가) - store_name: 고객명 (필수) - region: 지역명 (필수, 예: 서울, 부산, 대구 등) - task_id: 작업 고유 식별자 (UUID 형식, 36자) - detail_region_info: 상세 지역 정보 (선택, JSON 또는 텍스트 형식) - created_at: 생성 일시 (자동 설정) - - Relationships: - lyrics: 생성된 가사 목록 - songs: 생성된 노래 목록 - videos: 최종 영상 결과 목록 - """ - - __tablename__ = "project" - __table_args__ = ( - Index("idx_project_task_id", "task_id"), - Index("idx_project_store_name", "store_name"), - Index("idx_project_region", "region"), - { - "mysql_engine": "InnoDB", - "mysql_charset": "utf8mb4", - "mysql_collate": "utf8mb4_unicode_ci", - }, - ) - - id: Mapped[int] = mapped_column( - Integer, - primary_key=True, - nullable=False, - autoincrement=True, - comment="고유 식별자", - ) - - store_name: Mapped[str] = mapped_column( - String(255), - nullable=False, - index=True, - comment="가게명", - ) - - region: Mapped[str] = mapped_column( - String(100), - nullable=False, - index=True, - comment="지역명 (예: 군산)", - ) - - task_id: Mapped[str] = mapped_column( - String(36), - nullable=False, - comment="프로젝트 작업 고유 식별자 (UUID)", - ) - - detail_region_info: Mapped[Optional[str]] = mapped_column( - Text, - nullable=True, - comment="상세 지역 정보", - ) - - language: Mapped[str] = mapped_column( - String(50), - nullable=False, - default="Korean", - comment="출력 언어 (Korean, English, Chinese, Japanese, Thai, Vietnamese)", - ) - - created_at: Mapped[datetime] = mapped_column( - DateTime, - nullable=False, - server_default=func.now(), - comment="생성 일시", - ) - - # Relationships - lyrics: Mapped[List["Lyric"]] = relationship( - "Lyric", - back_populates="project", - cascade="all, delete-orphan", - lazy="selectin", - ) - - songs: Mapped[List["Song"]] = relationship( - "Song", - back_populates="project", - cascade="all, delete-orphan", - lazy="selectin", - ) - - videos: Mapped[List["Video"]] = relationship( - "Video", - back_populates="project", - cascade="all, delete-orphan", - lazy="selectin", - ) - - def __repr__(self) -> str: - def truncate(value: str | None, max_len: int = 10) -> str: - if value is None: - return "None" - return (value[:max_len] + "...") if len(value) > max_len else value - - return ( - f"" - ) - - -class Image(Base): - """ - 업로드 이미지 테이블 - - 사용자가 업로드한 이미지의 URL을 저장합니다. - 독립적으로 관리되며 Project와 직접적인 관계가 없습니다. - - Attributes: - id: 고유 식별자 (자동 증가) - task_id: 이미지 업로드 작업 고유 식별자 (UUID) - img_name: 이미지명 - img_url: 이미지 URL (S3, CDN 등의 경로) - created_at: 생성 일시 (자동 설정) - """ - - __tablename__ = "image" - __table_args__ = ( - { - "mysql_engine": "InnoDB", - "mysql_charset": "utf8mb4", - "mysql_collate": "utf8mb4_unicode_ci", - }, - ) - - id: Mapped[int] = mapped_column( - Integer, - primary_key=True, - nullable=False, - autoincrement=True, - comment="고유 식별자", - ) - - task_id: Mapped[str] = mapped_column( - String(36), - nullable=False, - comment="이미지 업로드 작업 고유 식별자 (UUID)", - ) - - img_name: Mapped[str] = mapped_column( - String(255), - nullable=False, - comment="이미지명", - ) - - img_url: Mapped[str] = mapped_column( - String(2048), - nullable=False, - comment="이미지 URL (blob, CDN 경로)", - ) - - img_order: Mapped[int] = mapped_column( - Integer, - nullable=False, - default=0, - comment="이미지 순서", - ) - - created_at: Mapped[datetime] = mapped_column( - DateTime, - nullable=False, - server_default=func.now(), - comment="생성 일시", - ) - - def __repr__(self) -> str: - task_id_str = ( - (self.task_id[:10] + "...") if len(self.task_id) > 10 else self.task_id - ) - img_name_str = ( - (self.img_name[:10] + "...") if len(self.img_name) > 10 else self.img_name - ) - - return ( - f"" - ) +""" +Home 모듈 SQLAlchemy 모델 정의 + +이 모듈은 영상 제작 파이프라인의 핵심 데이터 모델을 정의합니다. +- Project: 프로젝트(사용자 입력 이력) 관리 +- Image: 업로드된 이미지 URL 관리 +""" + +from datetime import datetime +from typing import TYPE_CHECKING, List, Optional + +from sqlalchemy import DateTime, Index, Integer, String, Text, func +from sqlalchemy.orm import Mapped, mapped_column, relationship + +from app.database.session import Base + +if TYPE_CHECKING: + from app.lyric.models import Lyric + from app.song.models import Song + from app.video.models import Video + + +class Project(Base): + """ + 프로젝트 테이블 (사용자 입력 이력) + + 영상 제작 요청의 시작점으로, 고객 정보와 지역 정보를 저장합니다. + 하위 테이블(Lyric, Song, Video)의 부모 테이블 역할을 합니다. + + Attributes: + id: 고유 식별자 (자동 증가) + store_name: 고객명 (필수) + region: 지역명 (필수, 예: 서울, 부산, 대구 등) + task_id: 작업 고유 식별자 (UUID 형식, 36자) + detail_region_info: 상세 지역 정보 (선택, JSON 또는 텍스트 형식) + created_at: 생성 일시 (자동 설정) + + Relationships: + lyrics: 생성된 가사 목록 + songs: 생성된 노래 목록 + videos: 최종 영상 결과 목록 + """ + + __tablename__ = "project" + __table_args__ = ( + Index("idx_project_task_id", "task_id"), + Index("idx_project_store_name", "store_name"), + Index("idx_project_region", "region"), + { + "mysql_engine": "InnoDB", + "mysql_charset": "utf8mb4", + "mysql_collate": "utf8mb4_unicode_ci", + }, + ) + + id: Mapped[int] = mapped_column( + Integer, + primary_key=True, + nullable=False, + autoincrement=True, + comment="고유 식별자", + ) + + store_name: Mapped[str] = mapped_column( + String(255), + nullable=False, + index=True, + comment="가게명", + ) + + region: Mapped[str] = mapped_column( + String(100), + nullable=False, + index=True, + comment="지역명 (예: 군산)", + ) + + task_id: Mapped[str] = mapped_column( + String(36), + nullable=False, + comment="프로젝트 작업 고유 식별자 (UUID)", + ) + + detail_region_info: Mapped[Optional[str]] = mapped_column( + Text, + nullable=True, + comment="상세 지역 정보", + ) + + language: Mapped[str] = mapped_column( + String(50), + nullable=False, + default="Korean", + comment="출력 언어 (Korean, English, Chinese, Japanese, Thai, Vietnamese)", + ) + + created_at: Mapped[datetime] = mapped_column( + DateTime, + nullable=False, + server_default=func.now(), + comment="생성 일시", + ) + + # Relationships + lyrics: Mapped[List["Lyric"]] = relationship( + "Lyric", + back_populates="project", + cascade="all, delete-orphan", + lazy="selectin", + ) + + songs: Mapped[List["Song"]] = relationship( + "Song", + back_populates="project", + cascade="all, delete-orphan", + lazy="selectin", + ) + + videos: Mapped[List["Video"]] = relationship( + "Video", + back_populates="project", + cascade="all, delete-orphan", + lazy="selectin", + ) + + def __repr__(self) -> str: + def truncate(value: str | None, max_len: int = 10) -> str: + if value is None: + return "None" + return (value[:max_len] + "...") if len(value) > max_len else value + + return ( + f"" + ) + + +class Image(Base): + """ + 업로드 이미지 테이블 + + 사용자가 업로드한 이미지의 URL을 저장합니다. + 독립적으로 관리되며 Project와 직접적인 관계가 없습니다. + + Attributes: + id: 고유 식별자 (자동 증가) + task_id: 이미지 업로드 작업 고유 식별자 (UUID) + img_name: 이미지명 + img_url: 이미지 URL (S3, CDN 등의 경로) + created_at: 생성 일시 (자동 설정) + """ + + __tablename__ = "image" + __table_args__ = ( + { + "mysql_engine": "InnoDB", + "mysql_charset": "utf8mb4", + "mysql_collate": "utf8mb4_unicode_ci", + }, + ) + + id: Mapped[int] = mapped_column( + Integer, + primary_key=True, + nullable=False, + autoincrement=True, + comment="고유 식별자", + ) + + task_id: Mapped[str] = mapped_column( + String(36), + nullable=False, + comment="이미지 업로드 작업 고유 식별자 (UUID)", + ) + + img_name: Mapped[str] = mapped_column( + String(255), + nullable=False, + comment="이미지명", + ) + + img_url: Mapped[str] = mapped_column( + String(2048), + nullable=False, + comment="이미지 URL (blob, CDN 경로)", + ) + + img_order: Mapped[int] = mapped_column( + Integer, + nullable=False, + default=0, + comment="이미지 순서", + ) + + created_at: Mapped[datetime] = mapped_column( + DateTime, + nullable=False, + server_default=func.now(), + comment="생성 일시", + ) + + def __repr__(self) -> str: + task_id_str = ( + (self.task_id[:10] + "...") if len(self.task_id) > 10 else self.task_id + ) + img_name_str = ( + (self.img_name[:10] + "...") if len(self.img_name) > 10 else self.img_name + ) + + return ( + f"" + ) diff --git a/app/home/schemas/home_schema.py b/app/home/schemas/home_schema.py index 99bb043..249c8de 100644 --- a/app/home/schemas/home_schema.py +++ b/app/home/schemas/home_schema.py @@ -1,260 +1,260 @@ -from typing import Literal, Optional - -from pydantic import BaseModel, ConfigDict, Field - - -class AttributeInfo(BaseModel): - """음악 속성 정보""" - - genre: str = Field(..., description="음악 장르") - vocal: str = Field(..., description="보컬 스타일") - tempo: str = Field(..., description="템포") - mood: str = Field(..., description="분위기") - - -class GenerateRequestImg(BaseModel): - """이미지 URL 스키마""" - - url: str = Field(..., description="이미지 URL") - name: Optional[str] = Field(None, description="이미지명 (없으면 URL에서 추출)") - - -class GenerateRequestInfo(BaseModel): - """생성 요청 정보 스키마 (이미지 제외)""" - - customer_name: str = Field(..., description="고객명/가게명") - region: str = Field(..., description="지역명") - detail_region_info: Optional[str] = Field(None, description="상세 지역 정보") - attribute: AttributeInfo = Field(..., description="음악 속성 정보") - language: str = Field( - default="Korean", - description="가사 출력 언어 (Korean, English, Chinese, Japanese, Thai, Vietnamese)", - ) - - -class GenerateRequest(GenerateRequestInfo): - """기본 생성 요청 스키마 (이미지 없음, JSON body) - - 이미지 없이 프로젝트 정보만 전달합니다. - """ - - model_config = ConfigDict( - json_schema_extra={ - "example": { - "customer_name": "스테이 머뭄", - "region": "군산", - "detail_region_info": "군산 신흥동 말랭이 마을", - "attribute": { - "genre": "K-Pop", - "vocal": "Raspy", - "tempo": "110 BPM", - "mood": "happy", - }, - "language": "Korean", - } - } - ) - - -class GenerateUrlsRequest(GenerateRequestInfo): - """URL 기반 생성 요청 스키마 (JSON body) - - GenerateRequestInfo를 상속받아 이미지 목록을 추가합니다. - """ - - model_config = ConfigDict( - json_schema_extra={ - "example": { - "customer_name": "스테이 머뭄", - "region": "군산", - "detail_region_info": "군산 신흥동 말랭이 마을", - "attribute": { - "genre": "K-Pop", - "vocal": "Raspy", - "tempo": "110 BPM", - "mood": "happy", - }, - "language": "Korean", - "images": [ - {"url": "https://example.com/images/image_001.jpg"}, - {"url": "https://example.com/images/image_002.jpg", "name": "외관"}, - ], - } - } - ) - - images: list[GenerateRequestImg] = Field( - ..., description="이미지 URL 목록", min_length=1 - ) - - -class GenerateUploadResponse(BaseModel): - """파일 업로드 기반 생성 응답 스키마""" - - task_id: str = Field(..., description="작업 고유 식별자 (UUID7)") - status: Literal["processing", "completed", "failed"] = Field( - ..., description="작업 상태" - ) - message: str = Field(..., description="응답 메시지") - uploaded_count: int = Field(..., description="업로드된 이미지 개수") - - -class GenerateResponse(BaseModel): - """생성 응답 스키마""" - - task_id: str = Field(..., description="작업 고유 식별자 (UUID7)") - status: Literal["processing", "completed", "failed"] = Field( - ..., description="작업 상태" - ) - message: str = Field(..., description="응답 메시지") - - -class CrawlingRequest(BaseModel): - """크롤링 요청 스키마""" - - model_config = ConfigDict( - json_schema_extra={ - "example": { - "url": "https://map.naver.com/p/search/%EC%8A%A4%ED%85%8C%EC%9D%B4%EB%A8%B8%EB%AD%84/place/1133638931?c=14.70,0,0,0,dh&placePath=/photo?businessCategory=pension&fromPanelNum=2&locale=ko&searchText=%EC%8A%A4%ED%85%8C%EC%9D%B4%EB%A8%B8%EB%AD%84&svcName=map_pcv5×tamp=202512191123&fromPanelNum=2&locale=ko&searchText=%EC%8A%A4%ED%85%8C%EC%9D%B4%EB%A8%B8%EB%AD%84&svcName=map_pcv5×tamp=202512191007&from=map&entry=bmp&filterType=%EC%97%85%EC%B2%B4&businessCategory=pension" - } - } - ) - - url: str = Field(..., description="네이버 지도 장소 URL") - - -class ProcessedInfo(BaseModel): - """가공된 장소 정보 스키마""" - - customer_name: str = Field(..., description="고객명/가게명 (base_info.name)") - region: str = Field(..., description="지역명 (roadAddress에서 추출한 시 이름)") - detail_region_info: str = Field(..., description="상세 지역 정보 (roadAddress)") - - -class MarketingAnalysis(BaseModel): - """마케팅 분석 결과 스키마""" - - report: str = Field(..., description="마케팅 분석 리포트") - tags: list[str] = Field(default_factory=list, description="추천 태그 목록") - facilities: list[str] = Field(default_factory=list, description="추천 부대시설 목록") - - -class CrawlingResponse(BaseModel): - """크롤링 응답 스키마""" - - image_list: Optional[list[str]] = Field(None, description="이미지 URL 목록") - image_count: int = Field(..., description="이미지 개수") - processed_info: Optional[ProcessedInfo] = Field( - None, description="가공된 장소 정보 (customer_name, region, detail_region_info)" - ) - marketing_analysis: Optional[MarketingAnalysis] = Field( - None, description="마케팅 분석 결과 (report, tags, facilities)" - ) - - -class ErrorResponse(BaseModel): - """에러 응답 스키마""" - - success: bool = Field(default=False, description="요청 성공 여부") - error_code: str = Field(..., description="에러 코드") - message: str = Field(..., description="에러 메시지") - detail: Optional[str] = Field(None, description="상세 에러 정보") - - -# ============================================================================= -# Image Upload Schemas -# ============================================================================= - - -class ImageUrlItem(BaseModel): - """이미지 URL 아이템 스키마""" - - url: str = Field(..., description="외부 이미지 URL") - name: Optional[str] = Field(None, description="이미지명 (없으면 URL에서 추출)") - - -class ImageUploadRequest(BaseModel): - """이미지 업로드 요청 스키마 (JSON body 부분) - - URL 이미지 목록을 전달합니다. - 바이너리 파일은 multipart/form-data로 별도 전달됩니다. - """ - - model_config = ConfigDict( - json_schema_extra={ - "example": { - "images": [ - {"url": "https://example.com/images/image_001.jpg"}, - {"url": "https://example.com/images/image_002.jpg", "name": "외관"}, - ] - } - } - ) - - images: Optional[list[ImageUrlItem]] = Field( - None, description="외부 이미지 URL 목록" - ) - - -class ImageUploadResultItem(BaseModel): - """업로드된 이미지 결과 아이템""" - - id: int = Field(..., description="이미지 ID") - img_name: str = Field(..., description="이미지명") - img_url: str = Field(..., description="이미지 URL") - img_order: int = Field(..., description="이미지 순서") - source: Literal["url", "file", "blob"] = Field( - ..., description="이미지 소스 (url: 외부 URL, file: 로컬 서버, blob: Azure Blob)" - ) - - -class ImageUploadResponse(BaseModel): - """이미지 업로드 응답 스키마""" - - model_config = ConfigDict( - json_schema_extra={ - "example": { - "task_id": "0694b716-dbff-7219-8000-d08cb5fce431", - "total_count": 3, - "url_count": 2, - "file_count": 1, - "saved_count": 3, - "images": [ - { - "id": 1, - "img_name": "외관", - "img_url": "https://example.com/images/image_001.jpg", - "img_order": 0, - "source": "url", - }, - { - "id": 2, - "img_name": "내부", - "img_url": "https://example.com/images/image_002.jpg", - "img_order": 1, - "source": "url", - }, - { - "id": 3, - "img_name": "uploaded_image.jpg", - "img_url": "/media/image/2024-01-15/0694b716-dbff-7219-8000-d08cb5fce431/uploaded_image_002.jpg", - "img_order": 2, - "source": "file", - }, - ], - "image_urls": [ - "https://example.com/images/image_001.jpg", - "https://example.com/images/image_002.jpg", - "/media/image/2024-01-15/0694b716-dbff-7219-8000-d08cb5fce431/uploaded_image_002.jpg", - ], - } - } - ) - - task_id: str = Field(..., description="작업 고유 식별자 (새로 생성된 UUID7)") - total_count: int = Field(..., description="총 업로드된 이미지 개수") - url_count: int = Field(..., description="URL로 등록된 이미지 개수") - file_count: int = Field(..., description="파일로 업로드된 이미지 개수") - saved_count: int = Field(..., description="Image 테이블에 저장된 row 수") - images: list[ImageUploadResultItem] = Field(..., description="업로드된 이미지 목록") - image_urls: list[str] = Field(..., description="Image 테이블에 저장된 현재 task_id의 이미지 URL 목록") +from typing import Literal, Optional + +from pydantic import BaseModel, ConfigDict, Field + + +class AttributeInfo(BaseModel): + """음악 속성 정보""" + + genre: str = Field(..., description="음악 장르") + vocal: str = Field(..., description="보컬 스타일") + tempo: str = Field(..., description="템포") + mood: str = Field(..., description="분위기") + + +class GenerateRequestImg(BaseModel): + """이미지 URL 스키마""" + + url: str = Field(..., description="이미지 URL") + name: Optional[str] = Field(None, description="이미지명 (없으면 URL에서 추출)") + + +class GenerateRequestInfo(BaseModel): + """생성 요청 정보 스키마 (이미지 제외)""" + + customer_name: str = Field(..., description="고객명/가게명") + region: str = Field(..., description="지역명") + detail_region_info: Optional[str] = Field(None, description="상세 지역 정보") + attribute: AttributeInfo = Field(..., description="음악 속성 정보") + language: str = Field( + default="Korean", + description="가사 출력 언어 (Korean, English, Chinese, Japanese, Thai, Vietnamese)", + ) + + +class GenerateRequest(GenerateRequestInfo): + """기본 생성 요청 스키마 (이미지 없음, JSON body) + + 이미지 없이 프로젝트 정보만 전달합니다. + """ + + model_config = ConfigDict( + json_schema_extra={ + "example": { + "customer_name": "스테이 머뭄", + "region": "군산", + "detail_region_info": "군산 신흥동 말랭이 마을", + "attribute": { + "genre": "K-Pop", + "vocal": "Raspy", + "tempo": "110 BPM", + "mood": "happy", + }, + "language": "Korean", + } + } + ) + + +class GenerateUrlsRequest(GenerateRequestInfo): + """URL 기반 생성 요청 스키마 (JSON body) + + GenerateRequestInfo를 상속받아 이미지 목록을 추가합니다. + """ + + model_config = ConfigDict( + json_schema_extra={ + "example": { + "customer_name": "스테이 머뭄", + "region": "군산", + "detail_region_info": "군산 신흥동 말랭이 마을", + "attribute": { + "genre": "K-Pop", + "vocal": "Raspy", + "tempo": "110 BPM", + "mood": "happy", + }, + "language": "Korean", + "images": [ + {"url": "https://example.com/images/image_001.jpg"}, + {"url": "https://example.com/images/image_002.jpg", "name": "외관"}, + ], + } + } + ) + + images: list[GenerateRequestImg] = Field( + ..., description="이미지 URL 목록", min_length=1 + ) + + +class GenerateUploadResponse(BaseModel): + """파일 업로드 기반 생성 응답 스키마""" + + task_id: str = Field(..., description="작업 고유 식별자 (UUID7)") + status: Literal["processing", "completed", "failed"] = Field( + ..., description="작업 상태" + ) + message: str = Field(..., description="응답 메시지") + uploaded_count: int = Field(..., description="업로드된 이미지 개수") + + +class GenerateResponse(BaseModel): + """생성 응답 스키마""" + + task_id: str = Field(..., description="작업 고유 식별자 (UUID7)") + status: Literal["processing", "completed", "failed"] = Field( + ..., description="작업 상태" + ) + message: str = Field(..., description="응답 메시지") + + +class CrawlingRequest(BaseModel): + """크롤링 요청 스키마""" + + model_config = ConfigDict( + json_schema_extra={ + "example": { + "url": "https://map.naver.com/p/search/%EC%8A%A4%ED%85%8C%EC%9D%B4%EB%A8%B8%EB%AD%84/place/1133638931?c=14.70,0,0,0,dh&placePath=/photo?businessCategory=pension&fromPanelNum=2&locale=ko&searchText=%EC%8A%A4%ED%85%8C%EC%9D%B4%EB%A8%B8%EB%AD%84&svcName=map_pcv5×tamp=202512191123&fromPanelNum=2&locale=ko&searchText=%EC%8A%A4%ED%85%8C%EC%9D%B4%EB%A8%B8%EB%AD%84&svcName=map_pcv5×tamp=202512191007&from=map&entry=bmp&filterType=%EC%97%85%EC%B2%B4&businessCategory=pension" + } + } + ) + + url: str = Field(..., description="네이버 지도 장소 URL") + + +class ProcessedInfo(BaseModel): + """가공된 장소 정보 스키마""" + + customer_name: str = Field(..., description="고객명/가게명 (base_info.name)") + region: str = Field(..., description="지역명 (roadAddress에서 추출한 시 이름)") + detail_region_info: str = Field(..., description="상세 지역 정보 (roadAddress)") + + +class MarketingAnalysis(BaseModel): + """마케팅 분석 결과 스키마""" + + report: str = Field(..., description="마케팅 분석 리포트") + tags: list[str] = Field(default_factory=list, description="추천 태그 목록") + facilities: list[str] = Field(default_factory=list, description="추천 부대시설 목록") + + +class CrawlingResponse(BaseModel): + """크롤링 응답 스키마""" + + image_list: Optional[list[str]] = Field(None, description="이미지 URL 목록") + image_count: int = Field(..., description="이미지 개수") + processed_info: Optional[ProcessedInfo] = Field( + None, description="가공된 장소 정보 (customer_name, region, detail_region_info)" + ) + marketing_analysis: Optional[MarketingAnalysis] = Field( + None, description="마케팅 분석 결과 (report, tags, facilities)" + ) + + +class ErrorResponse(BaseModel): + """에러 응답 스키마""" + + success: bool = Field(default=False, description="요청 성공 여부") + error_code: str = Field(..., description="에러 코드") + message: str = Field(..., description="에러 메시지") + detail: Optional[str] = Field(None, description="상세 에러 정보") + + +# ============================================================================= +# Image Upload Schemas +# ============================================================================= + + +class ImageUrlItem(BaseModel): + """이미지 URL 아이템 스키마""" + + url: str = Field(..., description="외부 이미지 URL") + name: Optional[str] = Field(None, description="이미지명 (없으면 URL에서 추출)") + + +class ImageUploadRequest(BaseModel): + """이미지 업로드 요청 스키마 (JSON body 부분) + + URL 이미지 목록을 전달합니다. + 바이너리 파일은 multipart/form-data로 별도 전달됩니다. + """ + + model_config = ConfigDict( + json_schema_extra={ + "example": { + "images": [ + {"url": "https://example.com/images/image_001.jpg"}, + {"url": "https://example.com/images/image_002.jpg", "name": "외관"}, + ] + } + } + ) + + images: Optional[list[ImageUrlItem]] = Field( + None, description="외부 이미지 URL 목록" + ) + + +class ImageUploadResultItem(BaseModel): + """업로드된 이미지 결과 아이템""" + + id: int = Field(..., description="이미지 ID") + img_name: str = Field(..., description="이미지명") + img_url: str = Field(..., description="이미지 URL") + img_order: int = Field(..., description="이미지 순서") + source: Literal["url", "file", "blob"] = Field( + ..., description="이미지 소스 (url: 외부 URL, file: 로컬 서버, blob: Azure Blob)" + ) + + +class ImageUploadResponse(BaseModel): + """이미지 업로드 응답 스키마""" + + model_config = ConfigDict( + json_schema_extra={ + "example": { + "task_id": "0694b716-dbff-7219-8000-d08cb5fce431", + "total_count": 3, + "url_count": 2, + "file_count": 1, + "saved_count": 3, + "images": [ + { + "id": 1, + "img_name": "외관", + "img_url": "https://example.com/images/image_001.jpg", + "img_order": 0, + "source": "url", + }, + { + "id": 2, + "img_name": "내부", + "img_url": "https://example.com/images/image_002.jpg", + "img_order": 1, + "source": "url", + }, + { + "id": 3, + "img_name": "uploaded_image.jpg", + "img_url": "/media/image/2024-01-15/0694b716-dbff-7219-8000-d08cb5fce431/uploaded_image_002.jpg", + "img_order": 2, + "source": "file", + }, + ], + "image_urls": [ + "https://example.com/images/image_001.jpg", + "https://example.com/images/image_002.jpg", + "/media/image/2024-01-15/0694b716-dbff-7219-8000-d08cb5fce431/uploaded_image_002.jpg", + ], + } + } + ) + + task_id: str = Field(..., description="작업 고유 식별자 (새로 생성된 UUID7)") + total_count: int = Field(..., description="총 업로드된 이미지 개수") + url_count: int = Field(..., description="URL로 등록된 이미지 개수") + file_count: int = Field(..., description="파일로 업로드된 이미지 개수") + saved_count: int = Field(..., description="Image 테이블에 저장된 row 수") + images: list[ImageUploadResultItem] = Field(..., description="업로드된 이미지 목록") + image_urls: list[str] = Field(..., description="Image 테이블에 저장된 현재 task_id의 이미지 URL 목록") diff --git a/app/home/services/base.py b/app/home/services/base.py index 2a0b0a9..6a789a4 100644 --- a/app/home/services/base.py +++ b/app/home/services/base.py @@ -1,24 +1,24 @@ -from uuid import UUID -from sqlalchemy.ext.asyncio import AsyncSession -from sqlmodel import SQLModel - - -class BaseService: - def __init__(self, model, session: AsyncSession): - self.model = model - self.session = session - - async def _get(self, id: UUID): - return await self.session.get(self.model, id) - - async def _add(self, entity): - self.session.add(entity) - await self.session.commit() - await self.session.refresh(entity) - return entity - - async def _update(self, entity): - return await self._add(entity) - - async def _delete(self, entity): +from uuid import UUID +from sqlalchemy.ext.asyncio import AsyncSession +from sqlmodel import SQLModel + + +class BaseService: + def __init__(self, model, session: AsyncSession): + self.model = model + self.session = session + + async def _get(self, id: UUID): + return await self.session.get(self.model, id) + + async def _add(self, entity): + self.session.add(entity) + await self.session.commit() + await self.session.refresh(entity) + return entity + + async def _update(self, entity): + return await self._add(entity) + + async def _delete(self, entity): await self.session.delete(entity) \ No newline at end of file diff --git a/app/home/tests/home/conftest.py b/app/home/tests/home/conftest.py index 9d8e296..b11bf7e 100644 --- a/app/home/tests/home/conftest.py +++ b/app/home/tests/home/conftest.py @@ -1,48 +1,48 @@ -from typing import AsyncGenerator - -import pytest_asyncio -from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine -from sqlalchemy.pool import NullPool - -from app.database.session import Base -from config import db_settings - -# 테스트 전용 DB URL -TEST_DB_URL = db_settings.MYSQL_URL.replace( - f"/{db_settings.MYSQL_DB}", - "/test_db", # 별도 테스트 DB 사용 -) - - -@pytest_asyncio.fixture -async def test_engine(): - """각 테스트마다 생성되는 테스트 엔진""" - engine = create_async_engine( - TEST_DB_URL, - poolclass=NullPool, # 테스트에서는 풀 비활성화 - echo=True, # SQL 쿼리 로깅 - ) - - # 테스트 테이블 생성 - async with engine.begin() as conn: - await conn.run_sync(Base.metadata.create_all) - - yield engine - - # 테스트 테이블 삭제 - async with engine.begin() as conn: - await conn.run_sync(Base.metadata.drop_all) - - await engine.dispose() - - -@pytest_asyncio.fixture -async def db_session(test_engine) -> AsyncGenerator[AsyncSession, None]: - """각 테스트마다 새로운 세션 (격리 보장)""" - async_session = async_sessionmaker( - test_engine, class_=AsyncSession, expire_on_commit=False - ) - - async with async_session() as session: - yield session - await session.rollback() # 테스트 후 롤백 +from typing import AsyncGenerator + +import pytest_asyncio +from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine +from sqlalchemy.pool import NullPool + +from app.database.session import Base +from config import db_settings + +# 테스트 전용 DB URL +TEST_DB_URL = db_settings.MYSQL_URL.replace( + f"/{db_settings.MYSQL_DB}", + "/test_db", # 별도 테스트 DB 사용 +) + + +@pytest_asyncio.fixture +async def test_engine(): + """각 테스트마다 생성되는 테스트 엔진""" + engine = create_async_engine( + TEST_DB_URL, + poolclass=NullPool, # 테스트에서는 풀 비활성화 + echo=True, # SQL 쿼리 로깅 + ) + + # 테스트 테이블 생성 + async with engine.begin() as conn: + await conn.run_sync(Base.metadata.create_all) + + yield engine + + # 테스트 테이블 삭제 + async with engine.begin() as conn: + await conn.run_sync(Base.metadata.drop_all) + + await engine.dispose() + + +@pytest_asyncio.fixture +async def db_session(test_engine) -> AsyncGenerator[AsyncSession, None]: + """각 테스트마다 새로운 세션 (격리 보장)""" + async_session = async_sessionmaker( + test_engine, class_=AsyncSession, expire_on_commit=False + ) + + async with async_session() as session: + yield session + await session.rollback() # 테스트 후 롤백 diff --git a/app/home/tests/home/test_db.py b/app/home/tests/home/test_db.py index 2cc39bf..7ef2b83 100644 --- a/app/home/tests/home/test_db.py +++ b/app/home/tests/home/test_db.py @@ -1,17 +1,17 @@ -import pytest -from sqlalchemy import text - - -@pytest.mark.asyncio -async def test_database_connection(test_engine): - """테스트 엔진을 사용한 연결 테스트""" - async with test_engine.begin() as connection: - result = await connection.execute(text("SELECT 1")) - assert result.scalar() == 1 - - -@pytest.mark.asyncio -async def test_session_usage(db_session): - """세션을 사용한 테스트""" - result = await db_session.execute(text("SELECT 1 as num")) - assert result.scalar() == 1 +import pytest +from sqlalchemy import text + + +@pytest.mark.asyncio +async def test_database_connection(test_engine): + """테스트 엔진을 사용한 연결 테스트""" + async with test_engine.begin() as connection: + result = await connection.execute(text("SELECT 1")) + assert result.scalar() == 1 + + +@pytest.mark.asyncio +async def test_session_usage(db_session): + """세션을 사용한 테스트""" + result = await db_session.execute(text("SELECT 1 as num")) + assert result.scalar() == 1 diff --git a/app/home/tests/test_db.py b/app/home/tests/test_db.py index 83da2d8..04c8733 100644 --- a/app/home/tests/test_db.py +++ b/app/home/tests/test_db.py @@ -1,30 +1,30 @@ -import pytest -from sqlalchemy import text - -from app.database.session import AsyncSessionLocal, engine - - -@pytest.mark.asyncio -async def test_database_connection(): - """데이터베이스 연결 테스트""" - async with engine.begin() as connection: - result = await connection.execute(text("SELECT 1")) - assert result.scalar() == 1 - - -@pytest.mark.asyncio -async def test_session_creation(): - """세션 생성 테스트""" - async with AsyncSessionLocal() as session: - result = await session.execute(text("SELECT 1")) - assert result.scalar() == 1 - - -@pytest.mark.asyncio -async def test_database_version(): - """MySQL 버전 확인 테스트""" - async with AsyncSessionLocal() as session: - result = await session.execute(text("SELECT VERSION()")) - version = result.scalar() - assert version is not None - print(f"MySQL Version: {version}") +import pytest +from sqlalchemy import text + +from app.database.session import AsyncSessionLocal, engine + + +@pytest.mark.asyncio +async def test_database_connection(): + """데이터베이스 연결 테스트""" + async with engine.begin() as connection: + result = await connection.execute(text("SELECT 1")) + assert result.scalar() == 1 + + +@pytest.mark.asyncio +async def test_session_creation(): + """세션 생성 테스트""" + async with AsyncSessionLocal() as session: + result = await session.execute(text("SELECT 1")) + assert result.scalar() == 1 + + +@pytest.mark.asyncio +async def test_database_version(): + """MySQL 버전 확인 테스트""" + async with AsyncSessionLocal() as session: + result = await session.execute(text("SELECT VERSION()")) + version = result.scalar() + assert version is not None + print(f"MySQL Version: {version}") diff --git a/app/lyric/api/lyrics_admin.py b/app/lyric/api/lyrics_admin.py index 6218256..6452ae9 100644 --- a/app/lyric/api/lyrics_admin.py +++ b/app/lyric/api/lyrics_admin.py @@ -1,61 +1,61 @@ -from sqladmin import ModelView - -from app.lyric.models import Lyric - - -class LyricAdmin(ModelView, model=Lyric): - name = "가사" - name_plural = "가사 목록" - icon = "fa-solid fa-music" - category = "가사 관리" - page_size = 20 - - column_list = [ - "id", - "project_id", - "task_id", - "status", - "language", - "created_at", - ] - - column_details_list = [ - "id", - "project_id", - "task_id", - "status", - "language", - "lyric_prompt", - "lyric_result", - "created_at", - ] - - # 폼(생성/수정)에서 제외 - form_excluded_columns = ["created_at", "songs", "videos"] - - column_searchable_list = [ - Lyric.task_id, - Lyric.status, - Lyric.language, - ] - - column_default_sort = (Lyric.created_at, True) # True: DESC (최신순) - - column_sortable_list = [ - Lyric.id, - Lyric.project_id, - Lyric.status, - Lyric.language, - Lyric.created_at, - ] - - column_labels = { - "id": "ID", - "project_id": "프로젝트 ID", - "task_id": "작업 ID", - "status": "상태", - "language": "언어", - "lyric_prompt": "프롬프트", - "lyric_result": "생성 결과", - "created_at": "생성일시", - } +from sqladmin import ModelView + +from app.lyric.models import Lyric + + +class LyricAdmin(ModelView, model=Lyric): + name = "가사" + name_plural = "가사 목록" + icon = "fa-solid fa-music" + category = "가사 관리" + page_size = 20 + + column_list = [ + "id", + "project_id", + "task_id", + "status", + "language", + "created_at", + ] + + column_details_list = [ + "id", + "project_id", + "task_id", + "status", + "language", + "lyric_prompt", + "lyric_result", + "created_at", + ] + + # 폼(생성/수정)에서 제외 + form_excluded_columns = ["created_at", "songs", "videos"] + + column_searchable_list = [ + Lyric.task_id, + Lyric.status, + Lyric.language, + ] + + column_default_sort = (Lyric.created_at, True) # True: DESC (최신순) + + column_sortable_list = [ + Lyric.id, + Lyric.project_id, + Lyric.status, + Lyric.language, + Lyric.created_at, + ] + + column_labels = { + "id": "ID", + "project_id": "프로젝트 ID", + "task_id": "작업 ID", + "status": "상태", + "language": "언어", + "lyric_prompt": "프롬프트", + "lyric_result": "생성 결과", + "created_at": "생성일시", + } diff --git a/app/lyric/api/routers/v1/lyric.py b/app/lyric/api/routers/v1/lyric.py index a576951..13f68f1 100644 --- a/app/lyric/api/routers/v1/lyric.py +++ b/app/lyric/api/routers/v1/lyric.py @@ -1,417 +1,448 @@ -""" -Lyric API Router - -이 모듈은 가사 관련 API 엔드포인트를 정의합니다. -모든 엔드포인트는 재사용 가능하도록 설계되었습니다. - -엔드포인트 목록: - - POST /lyric/generate: 가사 생성 - - GET /lyric/status/{task_id}: 가사 생성 상태 조회 - - GET /lyric/{task_id}: 가사 상세 조회 - - GET /lyrics: 가사 목록 조회 (페이지네이션) - -사용 예시: - from app.lyric.api.routers.v1.lyric import router - app.include_router(router, prefix="/api/v1") - -다른 서비스에서 재사용: - # 이 파일의 헬퍼 함수들을 import하여 사용 가능 - from app.lyric.api.routers.v1.lyric import ( - get_lyric_status_by_task_id, - get_lyric_by_task_id, - ) - - # 페이지네이션은 pagination 모듈 사용 - from app.utils.pagination import PaginatedResponse, get_paginated -""" - -from fastapi import APIRouter, BackgroundTasks, Depends, HTTPException, Query, status -from sqlalchemy import select -from sqlalchemy.ext.asyncio import AsyncSession - -from app.database.session import get_session -from app.home.models import Project -from app.lyric.models import Lyric -from app.lyric.schemas.lyric import ( - GenerateLyricRequest, - GenerateLyricResponse, - LyricDetailResponse, - LyricListItem, - LyricStatusResponse, -) -from app.lyric.worker.lyric_task import generate_lyric_background -from app.utils.chatgpt_prompt import ChatgptService -from app.utils.pagination import PaginatedResponse, get_paginated - -router = APIRouter(prefix="/lyric", tags=["lyric"]) - - -# ============================================================================= -# Reusable Service Functions (다른 모듈에서 import하여 사용 가능) -# ============================================================================= - - -async def get_lyric_status_by_task_id( - session: AsyncSession, task_id: str -) -> LyricStatusResponse: - """task_id로 가사 생성 작업의 상태를 조회합니다. - - Args: - session: SQLAlchemy AsyncSession - task_id: 작업 고유 식별자 - - Returns: - LyricStatusResponse: 상태 정보 - - Raises: - HTTPException: 404 - task_id에 해당하는 가사가 없는 경우 - - Usage: - # 다른 서비스에서 사용 - from app.lyric.api.routers.v1.lyric import get_lyric_status_by_task_id - - status_info = await get_lyric_status_by_task_id(session, "some-task-id") - if status_info.status == "completed": - # 완료 처리 - """ - print(f"[get_lyric_status_by_task_id] START - task_id: {task_id}") - result = await session.execute( - select(Lyric) - .where(Lyric.task_id == task_id) - .order_by(Lyric.created_at.desc()) - .limit(1) - ) - lyric = result.scalar_one_or_none() - - if not lyric: - print(f"[get_lyric_status_by_task_id] NOT FOUND - task_id: {task_id}") - raise HTTPException( - status_code=status.HTTP_404_NOT_FOUND, - detail=f"task_id '{task_id}'에 해당하는 가사를 찾을 수 없습니다.", - ) - - status_messages = { - "processing": "가사 생성 중입니다.", - "completed": "가사 생성이 완료되었습니다.", - "failed": "가사 생성에 실패했습니다.", - } - - print( - f"[get_lyric_status_by_task_id] SUCCESS - task_id: {task_id}, status: {lyric.status}" - ) - return LyricStatusResponse( - task_id=lyric.task_id, - status=lyric.status, - message=status_messages.get(lyric.status, "알 수 없는 상태입니다."), - ) - - -async def get_lyric_by_task_id( - session: AsyncSession, task_id: str -) -> LyricDetailResponse: - """task_id로 생성된 가사 상세 정보를 조회합니다. - - Args: - session: SQLAlchemy AsyncSession - task_id: 작업 고유 식별자 - - Returns: - LyricDetailResponse: 가사 상세 정보 - - Raises: - HTTPException: 404 - task_id에 해당하는 가사가 없는 경우 - - Usage: - # 다른 서비스에서 사용 - from app.lyric.api.routers.v1.lyric import get_lyric_by_task_id - - lyric = await get_lyric_by_task_id(session, task_id) - """ - print(f"[get_lyric_by_task_id] START - task_id: {task_id}") - result = await session.execute( - select(Lyric) - .where(Lyric.task_id == task_id) - .order_by(Lyric.created_at.desc()) - .limit(1) - ) - lyric = result.scalar_one_or_none() - - if not lyric: - print(f"[get_lyric_by_task_id] NOT FOUND - task_id: {task_id}") - raise HTTPException( - status_code=status.HTTP_404_NOT_FOUND, - detail=f"task_id '{task_id}'에 해당하는 가사를 찾을 수 없습니다.", - ) - - print(f"[get_lyric_by_task_id] SUCCESS - task_id: {task_id}, lyric_id: {lyric.id}") - return LyricDetailResponse( - id=lyric.id, - task_id=lyric.task_id, - project_id=lyric.project_id, - status=lyric.status, - lyric_prompt=lyric.lyric_prompt, - lyric_result=lyric.lyric_result, - created_at=lyric.created_at, - ) - - -# ============================================================================= -# API Endpoints -# ============================================================================= - - -@router.post( - "/generate", - summary="가사 생성", - description=""" -고객 정보를 기반으로 ChatGPT를 이용하여 가사를 생성합니다. -백그라운드에서 비동기로 처리되며, 즉시 task_id를 반환합니다. - -## 요청 필드 -- **task_id**: 작업 고유 식별자 (이미지 업로드 시 생성된 task_id, 필수) -- **customer_name**: 고객명/가게명 (필수) -- **region**: 지역명 (필수) -- **detail_region_info**: 상세 지역 정보 (선택) -- **language**: 가사 출력 언어 (Korean, English, Chinese, Japanese, Thai, Vietnamese) - -## 반환 정보 -- **success**: 요청 접수 성공 여부 -- **task_id**: 작업 고유 식별자 -- **lyric**: null (백그라운드 처리 중) -- **language**: 가사 언어 -- **error_message**: 에러 메시지 (요청 접수 실패 시) - -## 상태 확인 -- GET /lyric/status/{task_id} 로 처리 상태 확인 -- GET /lyric/{task_id} 로 생성된 가사 조회 - -## 사용 예시 -``` -POST /lyric/generate -{ - "task_id": "0694b716-dbff-7219-8000-d08cb5fce431", - "customer_name": "스테이 머뭄", - "region": "군산", - "detail_region_info": "군산 신흥동 말랭이 마을", - "language": "Korean" -} -``` - -## 응답 예시 -```json -{ - "success": true, - "task_id": "0694b716-dbff-7219-8000-d08cb5fce431", - "lyric": null, - "language": "Korean", - "error_message": null -} -``` - """, - response_model=GenerateLyricResponse, - responses={ - 200: {"description": "가사 생성 요청 접수 성공"}, - 500: {"description": "서버 내부 오류"}, - }, -) -async def generate_lyric( - request_body: GenerateLyricRequest, - background_tasks: BackgroundTasks, - session: AsyncSession = Depends(get_session), -) -> GenerateLyricResponse: - """고객 정보를 기반으로 가사를 생성합니다. (백그라운드 처리)""" - task_id = request_body.task_id - print( - f"[generate_lyric] START - task_id: {task_id}, " - f"customer_name: {request_body.customer_name}, " - f"region: {request_body.region}" - ) - - try: - # 1. ChatGPT 서비스 초기화 및 프롬프트 생성 - service = ChatgptService( - customer_name=request_body.customer_name, - region=request_body.region, - detail_region_info=request_body.detail_region_info or "", - language=request_body.language, - ) - prompt = service.build_lyrics_prompt() - - # 2. Project 테이블에 데이터 저장 - project = Project( - store_name=request_body.customer_name, - region=request_body.region, - task_id=task_id, - detail_region_info=request_body.detail_region_info, - language=request_body.language, - ) - session.add(project) - await session.commit() - await session.refresh(project) - print( - f"[generate_lyric] Project saved - " - f"project_id: {project.id}, task_id: {task_id}" - ) - - # 3. Lyric 테이블에 데이터 저장 (status: processing) - lyric = Lyric( - project_id=project.id, - task_id=task_id, - status="processing", - lyric_prompt=prompt, - lyric_result=None, - language=request_body.language, - ) - session.add(lyric) - await session.commit() - await session.refresh(lyric) - print( - f"[generate_lyric] Lyric saved (processing) - " - f"lyric_id: {lyric.id}, task_id: {task_id}" - ) - - # 4. 백그라운드 태스크로 ChatGPT 가사 생성 실행 - background_tasks.add_task( - generate_lyric_background, - task_id=task_id, - prompt=prompt, - language=request_body.language, - ) - print(f"[generate_lyric] Background task scheduled - task_id: {task_id}") - - # 5. 즉시 응답 반환 - return GenerateLyricResponse( - success=True, - task_id=task_id, - lyric=None, - language=request_body.language, - error_message=None, - ) - - except Exception as e: - print(f"[generate_lyric] EXCEPTION - task_id: {task_id}, error: {e}") - await session.rollback() - return GenerateLyricResponse( - success=False, - task_id=task_id, - lyric=None, - language=request_body.language, - error_message=str(e), - ) - - -@router.get( - "/status/{task_id}", - summary="가사 생성 상태 조회", - description=""" -task_id로 가사 생성 작업의 현재 상태를 조회합니다. - -## 상태 값 -- **processing**: 가사 생성 중 -- **completed**: 가사 생성 완료 -- **failed**: 가사 생성 실패 - -## 사용 예시 -``` -GET /lyric/status/019123ab-cdef-7890-abcd-ef1234567890 -``` - """, - response_model=LyricStatusResponse, - responses={ - 200: {"description": "상태 조회 성공"}, - 404: {"description": "해당 task_id를 찾을 수 없음"}, - }, -) -async def get_lyric_status( - task_id: str, - session: AsyncSession = Depends(get_session), -) -> LyricStatusResponse: - """task_id로 가사 생성 작업 상태를 조회합니다.""" - return await get_lyric_status_by_task_id(session, task_id) - - -@router.get( - "s", - summary="가사 목록 조회 (페이지네이션)", - description=""" -생성 완료된 가사를 페이지네이션으로 조회합니다. - -## 파라미터 -- **page**: 페이지 번호 (1부터 시작, 기본값: 1) -- **page_size**: 페이지당 데이터 수 (기본값: 20, 최대: 100) - -## 반환 정보 -- **items**: 가사 목록 (completed 상태만) -- **total**: 전체 데이터 수 -- **page**: 현재 페이지 -- **page_size**: 페이지당 데이터 수 -- **total_pages**: 전체 페이지 수 -- **has_next**: 다음 페이지 존재 여부 -- **has_prev**: 이전 페이지 존재 여부 - -## 사용 예시 -``` -GET /lyrics # 기본 조회 (1페이지, 20개) -GET /lyrics?page=2 # 2페이지 조회 -GET /lyrics?page=1&page_size=50 # 50개씩 조회 -``` - -## 참고 -- 생성 완료(completed)된 가사만 조회됩니다. -- processing, failed 상태의 가사는 조회되지 않습니다. - """, - response_model=PaginatedResponse[LyricListItem], - responses={ - 200: {"description": "가사 목록 조회 성공"}, - }, -) -async def list_lyrics( - page: int = Query(1, ge=1, description="페이지 번호 (1부터 시작)"), - page_size: int = Query(20, ge=1, le=100, description="페이지당 데이터 수"), - session: AsyncSession = Depends(get_session), -) -> PaginatedResponse[LyricListItem]: - """페이지네이션으로 완료된 가사 목록을 조회합니다.""" - return await get_paginated( - session=session, - model=Lyric, - item_schema=LyricListItem, - page=page, - page_size=page_size, - filters={"status": "completed"}, - order_by="created_at", - order_desc=True, - ) - - -@router.get( - "/{task_id}", - summary="가사 상세 조회", - description=""" -task_id로 생성된 가사의 상세 정보를 조회합니다. - -## 반환 정보 -- **id**: 가사 ID -- **task_id**: 작업 고유 식별자 -- **project_id**: 프로젝트 ID -- **status**: 처리 상태 -- **lyric_prompt**: 가사 생성에 사용된 프롬프트 -- **lyric_result**: 생성된 가사 (완료 시) -- **created_at**: 생성 일시 - -## 사용 예시 -``` -GET /lyric/019123ab-cdef-7890-abcd-ef1234567890 -``` - """, - response_model=LyricDetailResponse, - responses={ - 200: {"description": "가사 조회 성공"}, - 404: {"description": "해당 task_id를 찾을 수 없음"}, - }, -) -async def get_lyric_detail( - task_id: str, - session: AsyncSession = Depends(get_session), -) -> LyricDetailResponse: - """task_id로 생성된 가사를 조회합니다.""" - return await get_lyric_by_task_id(session, task_id) +""" +Lyric API Router + +이 모듈은 가사 관련 API 엔드포인트를 정의합니다. +모든 엔드포인트는 재사용 가능하도록 설계되었습니다. + +엔드포인트 목록: + - POST /lyric/generate: 가사 생성 + - GET /lyric/status/{task_id}: 가사 생성 상태 조회 + - GET /lyric/{task_id}: 가사 상세 조회 + - GET /lyrics: 가사 목록 조회 (페이지네이션) + +사용 예시: + from app.lyric.api.routers.v1.lyric import router + app.include_router(router, prefix="/api/v1") + +다른 서비스에서 재사용: + # 이 파일의 헬퍼 함수들을 import하여 사용 가능 + from app.lyric.api.routers.v1.lyric import ( + get_lyric_status_by_task_id, + get_lyric_by_task_id, + ) + + # 페이지네이션은 pagination 모듈 사용 + from app.utils.pagination import PaginatedResponse, get_paginated +""" + +from fastapi import APIRouter, BackgroundTasks, Depends, HTTPException, Query, status +from sqlalchemy import select +from sqlalchemy.ext.asyncio import AsyncSession + +from app.database.session import get_session +from app.home.models import Project +from app.lyric.models import Lyric +from app.lyric.schemas.lyric import ( + GenerateLyricRequest, + GenerateLyricResponse, + LyricDetailResponse, + LyricListItem, + LyricStatusResponse, +) +from app.lyric.worker.lyric_task import generate_lyric_background +from app.utils.chatgpt_prompt import ChatgptService +from app.utils.pagination import PaginatedResponse, get_paginated + +router = APIRouter(prefix="/lyric", tags=["lyric"]) + + +# ============================================================================= +# Reusable Service Functions (다른 모듈에서 import하여 사용 가능) +# ============================================================================= + + +async def get_lyric_status_by_task_id( + session: AsyncSession, task_id: str +) -> LyricStatusResponse: + """task_id로 가사 생성 작업의 상태를 조회합니다. + + Args: + session: SQLAlchemy AsyncSession + task_id: 작업 고유 식별자 + + Returns: + LyricStatusResponse: 상태 정보 + + Raises: + HTTPException: 404 - task_id에 해당하는 가사가 없는 경우 + + Usage: + # 다른 서비스에서 사용 + from app.lyric.api.routers.v1.lyric import get_lyric_status_by_task_id + + status_info = await get_lyric_status_by_task_id(session, "some-task-id") + if status_info.status == "completed": + # 완료 처리 + """ + print(f"[get_lyric_status_by_task_id] START - task_id: {task_id}") + result = await session.execute( + select(Lyric) + .where(Lyric.task_id == task_id) + .order_by(Lyric.created_at.desc()) + .limit(1) + ) + lyric = result.scalar_one_or_none() + + if not lyric: + print(f"[get_lyric_status_by_task_id] NOT FOUND - task_id: {task_id}") + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=f"task_id '{task_id}'에 해당하는 가사를 찾을 수 없습니다.", + ) + + status_messages = { + "processing": "가사 생성 중입니다.", + "completed": "가사 생성이 완료되었습니다.", + "failed": "가사 생성에 실패했습니다.", + } + + print( + f"[get_lyric_status_by_task_id] SUCCESS - task_id: {task_id}, status: {lyric.status}" + ) + return LyricStatusResponse( + task_id=lyric.task_id, + status=lyric.status, + message=status_messages.get(lyric.status, "알 수 없는 상태입니다."), + ) + + +async def get_lyric_by_task_id( + session: AsyncSession, task_id: str +) -> LyricDetailResponse: + """task_id로 생성된 가사 상세 정보를 조회합니다. + + Args: + session: SQLAlchemy AsyncSession + task_id: 작업 고유 식별자 + + Returns: + LyricDetailResponse: 가사 상세 정보 + + Raises: + HTTPException: 404 - task_id에 해당하는 가사가 없는 경우 + + Usage: + # 다른 서비스에서 사용 + from app.lyric.api.routers.v1.lyric import get_lyric_by_task_id + + lyric = await get_lyric_by_task_id(session, task_id) + """ + print(f"[get_lyric_by_task_id] START - task_id: {task_id}") + result = await session.execute( + select(Lyric) + .where(Lyric.task_id == task_id) + .order_by(Lyric.created_at.desc()) + .limit(1) + ) + lyric = result.scalar_one_or_none() + + if not lyric: + print(f"[get_lyric_by_task_id] NOT FOUND - task_id: {task_id}") + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=f"task_id '{task_id}'에 해당하는 가사를 찾을 수 없습니다.", + ) + + print(f"[get_lyric_by_task_id] SUCCESS - task_id: {task_id}, lyric_id: {lyric.id}") + return LyricDetailResponse( + id=lyric.id, + task_id=lyric.task_id, + project_id=lyric.project_id, + status=lyric.status, + lyric_prompt=lyric.lyric_prompt, + lyric_result=lyric.lyric_result, + created_at=lyric.created_at, + ) + + +# ============================================================================= +# API Endpoints +# ============================================================================= + + +@router.post( + "/generate", + summary="가사 생성", + description=""" +고객 정보를 기반으로 ChatGPT를 이용하여 가사를 생성합니다. +백그라운드에서 비동기로 처리되며, 즉시 task_id를 반환합니다. + +## 요청 필드 +- **task_id**: 작업 고유 식별자 (이미지 업로드 시 생성된 task_id, 필수) +- **customer_name**: 고객명/가게명 (필수) +- **region**: 지역명 (필수) +- **detail_region_info**: 상세 지역 정보 (선택) +- **language**: 가사 출력 언어 (Korean, English, Chinese, Japanese, Thai, Vietnamese) + +## 반환 정보 +- **success**: 요청 접수 성공 여부 +- **task_id**: 작업 고유 식별자 +- **lyric**: null (백그라운드 처리 중) +- **language**: 가사 언어 +- **error_message**: 에러 메시지 (요청 접수 실패 시) + +## 상태 확인 +- GET /lyric/status/{task_id} 로 처리 상태 확인 +- GET /lyric/{task_id} 로 생성된 가사 조회 + +## 사용 예시 +``` +POST /lyric/generate +{ + "task_id": "0694b716-dbff-7219-8000-d08cb5fce431", + "customer_name": "스테이 머뭄", + "region": "군산", + "detail_region_info": "군산 신흥동 말랭이 마을", + "language": "Korean" +} +``` + +## 응답 예시 +```json +{ + "success": true, + "task_id": "0694b716-dbff-7219-8000-d08cb5fce431", + "lyric": null, + "language": "Korean", + "error_message": null +} +``` + """, + response_model=GenerateLyricResponse, + responses={ + 200: {"description": "가사 생성 요청 접수 성공"}, + 500: {"description": "서버 내부 오류"}, + }, +) +async def generate_lyric( + request_body: GenerateLyricRequest, + background_tasks: BackgroundTasks, + session: AsyncSession = Depends(get_session), +) -> GenerateLyricResponse: + """고객 정보를 기반으로 가사를 생성합니다. (백그라운드 처리)""" + import time + + request_start = time.perf_counter() + task_id = request_body.task_id + + print(f"[generate_lyric] ========== START ==========") + print( + f"[generate_lyric] task_id: {task_id}, " + f"customer_name: {request_body.customer_name}, " + f"region: {request_body.region}" + ) + + try: + # ========== Step 1: ChatGPT 서비스 초기화 및 프롬프트 생성 ========== + step1_start = time.perf_counter() + print(f"[generate_lyric] Step 1: 서비스 초기화 및 프롬프트 생성...") + + service = ChatgptService( + customer_name=request_body.customer_name, + region=request_body.region, + detail_region_info=request_body.detail_region_info or "", + language=request_body.language, + ) + prompt = service.build_lyrics_prompt() + + step1_elapsed = (time.perf_counter() - step1_start) * 1000 + print(f"[generate_lyric] Step 1 완료 - 프롬프트 {len(prompt)}자 ({step1_elapsed:.1f}ms)") + + # ========== Step 2: Project 테이블에 데이터 저장 ========== + step2_start = time.perf_counter() + print(f"[generate_lyric] Step 2: Project 저장...") + + project = Project( + store_name=request_body.customer_name, + region=request_body.region, + task_id=task_id, + detail_region_info=request_body.detail_region_info, + language=request_body.language, + ) + session.add(project) + await session.commit() + await session.refresh(project) + + step2_elapsed = (time.perf_counter() - step2_start) * 1000 + print(f"[generate_lyric] Step 2 완료 - project_id: {project.id} ({step2_elapsed:.1f}ms)") + + # ========== Step 3: Lyric 테이블에 데이터 저장 ========== + step3_start = time.perf_counter() + print(f"[generate_lyric] Step 3: Lyric 저장 (processing)...") + + lyric = Lyric( + project_id=project.id, + task_id=task_id, + status="processing", + lyric_prompt=prompt, + lyric_result=None, + language=request_body.language, + ) + session.add(lyric) + await session.commit() + await session.refresh(lyric) + + step3_elapsed = (time.perf_counter() - step3_start) * 1000 + print(f"[generate_lyric] Step 3 완료 - lyric_id: {lyric.id} ({step3_elapsed:.1f}ms)") + + # ========== Step 4: 백그라운드 태스크 스케줄링 ========== + step4_start = time.perf_counter() + print(f"[generate_lyric] Step 4: 백그라운드 태스크 스케줄링...") + + background_tasks.add_task( + generate_lyric_background, + task_id=task_id, + prompt=prompt, + language=request_body.language, + ) + + step4_elapsed = (time.perf_counter() - step4_start) * 1000 + print(f"[generate_lyric] Step 4 완료 ({step4_elapsed:.1f}ms)") + + # ========== 완료 ========== + total_elapsed = (time.perf_counter() - request_start) * 1000 + print(f"[generate_lyric] ========== COMPLETE ==========") + print(f"[generate_lyric] API 응답 소요시간: {total_elapsed:.1f}ms") + print(f"[generate_lyric] - Step 1 (프롬프트 생성): {step1_elapsed:.1f}ms") + print(f"[generate_lyric] - Step 2 (Project 저장): {step2_elapsed:.1f}ms") + print(f"[generate_lyric] - Step 3 (Lyric 저장): {step3_elapsed:.1f}ms") + print(f"[generate_lyric] - Step 4 (태스크 스케줄링): {step4_elapsed:.1f}ms") + print(f"[generate_lyric] (GPT API 호출은 백그라운드에서 별도 진행)") + + # 5. 즉시 응답 반환 + return GenerateLyricResponse( + success=True, + task_id=task_id, + lyric=None, + language=request_body.language, + error_message=None, + ) + + except Exception as e: + elapsed = (time.perf_counter() - request_start) * 1000 + print(f"[generate_lyric] EXCEPTION - task_id: {task_id}, error: {e} ({elapsed:.1f}ms)") + await session.rollback() + return GenerateLyricResponse( + success=False, + task_id=task_id, + lyric=None, + language=request_body.language, + error_message=str(e), + ) + + +@router.get( + "/status/{task_id}", + summary="가사 생성 상태 조회", + description=""" +task_id로 가사 생성 작업의 현재 상태를 조회합니다. + +## 상태 값 +- **processing**: 가사 생성 중 +- **completed**: 가사 생성 완료 +- **failed**: 가사 생성 실패 + +## 사용 예시 +``` +GET /lyric/status/019123ab-cdef-7890-abcd-ef1234567890 +``` + """, + response_model=LyricStatusResponse, + responses={ + 200: {"description": "상태 조회 성공"}, + 404: {"description": "해당 task_id를 찾을 수 없음"}, + }, +) +async def get_lyric_status( + task_id: str, + session: AsyncSession = Depends(get_session), +) -> LyricStatusResponse: + """task_id로 가사 생성 작업 상태를 조회합니다.""" + return await get_lyric_status_by_task_id(session, task_id) + + +@router.get( + "s", + summary="가사 목록 조회 (페이지네이션)", + description=""" +생성 완료된 가사를 페이지네이션으로 조회합니다. + +## 파라미터 +- **page**: 페이지 번호 (1부터 시작, 기본값: 1) +- **page_size**: 페이지당 데이터 수 (기본값: 20, 최대: 100) + +## 반환 정보 +- **items**: 가사 목록 (completed 상태만) +- **total**: 전체 데이터 수 +- **page**: 현재 페이지 +- **page_size**: 페이지당 데이터 수 +- **total_pages**: 전체 페이지 수 +- **has_next**: 다음 페이지 존재 여부 +- **has_prev**: 이전 페이지 존재 여부 + +## 사용 예시 +``` +GET /lyrics # 기본 조회 (1페이지, 20개) +GET /lyrics?page=2 # 2페이지 조회 +GET /lyrics?page=1&page_size=50 # 50개씩 조회 +``` + +## 참고 +- 생성 완료(completed)된 가사만 조회됩니다. +- processing, failed 상태의 가사는 조회되지 않습니다. + """, + response_model=PaginatedResponse[LyricListItem], + responses={ + 200: {"description": "가사 목록 조회 성공"}, + }, +) +async def list_lyrics( + page: int = Query(1, ge=1, description="페이지 번호 (1부터 시작)"), + page_size: int = Query(20, ge=1, le=100, description="페이지당 데이터 수"), + session: AsyncSession = Depends(get_session), +) -> PaginatedResponse[LyricListItem]: + """페이지네이션으로 완료된 가사 목록을 조회합니다.""" + return await get_paginated( + session=session, + model=Lyric, + item_schema=LyricListItem, + page=page, + page_size=page_size, + filters={"status": "completed"}, + order_by="created_at", + order_desc=True, + ) + + +@router.get( + "/{task_id}", + summary="가사 상세 조회", + description=""" +task_id로 생성된 가사의 상세 정보를 조회합니다. + +## 반환 정보 +- **id**: 가사 ID +- **task_id**: 작업 고유 식별자 +- **project_id**: 프로젝트 ID +- **status**: 처리 상태 +- **lyric_prompt**: 가사 생성에 사용된 프롬프트 +- **lyric_result**: 생성된 가사 (완료 시) +- **created_at**: 생성 일시 + +## 사용 예시 +``` +GET /lyric/019123ab-cdef-7890-abcd-ef1234567890 +``` + """, + response_model=LyricDetailResponse, + responses={ + 200: {"description": "가사 조회 성공"}, + 404: {"description": "해당 task_id를 찾을 수 없음"}, + }, +) +async def get_lyric_detail( + task_id: str, + session: AsyncSession = Depends(get_session), +) -> LyricDetailResponse: + """task_id로 생성된 가사를 조회합니다.""" + return await get_lyric_by_task_id(session, task_id) diff --git a/app/lyric/dependencies.py b/app/lyric/dependencies.py index bf6f8ea..d03c265 100644 --- a/app/lyric/dependencies.py +++ b/app/lyric/dependencies.py @@ -1,8 +1,8 @@ -from typing import Annotated - -from fastapi import Depends -from sqlalchemy.ext.asyncio import AsyncSession - -from app.database.session import get_session - -SessionDep = Annotated[AsyncSession, Depends(get_session)] +from typing import Annotated + +from fastapi import Depends +from sqlalchemy.ext.asyncio import AsyncSession + +from app.database.session import get_session + +SessionDep = Annotated[AsyncSession, Depends(get_session)] diff --git a/app/lyric/models.py b/app/lyric/models.py index 56b6528..8a5c0a9 100644 --- a/app/lyric/models.py +++ b/app/lyric/models.py @@ -1,133 +1,133 @@ -from datetime import datetime -from typing import TYPE_CHECKING, List - -from sqlalchemy import DateTime, ForeignKey, Integer, String, Text, func -from sqlalchemy.dialects.mysql import LONGTEXT -from sqlalchemy.orm import Mapped, mapped_column, relationship - -from app.database.session import Base - -if TYPE_CHECKING: - from app.home.models import Project - from app.song.models import Song - from app.video.models import Video - - -class Lyric(Base): - """ - 가사 테이블 - - AI를 통해 생성된 가사 정보를 저장합니다. - 프롬프트와 생성 결과, 처리 상태를 관리합니다. - - Attributes: - id: 고유 식별자 (자동 증가) - project_id: 연결된 Project의 id (외래키) - task_id: 가사 생성 작업의 고유 식별자 (UUID 형식) - status: 처리 상태 (pending, processing, completed, failed 등) - lyric_prompt: 가사 생성에 사용된 프롬프트 - lyric_result: 생성된 가사 결과 (LONGTEXT로 긴 가사 지원) - created_at: 생성 일시 (자동 설정) - - Relationships: - project: 연결된 Project - songs: 이 가사를 사용한 노래 목록 - videos: 이 가사를 사용한 영상 목록 - """ - - __tablename__ = "lyric" - __table_args__ = ( - { - "mysql_engine": "InnoDB", - "mysql_charset": "utf8mb4", - "mysql_collate": "utf8mb4_unicode_ci", - }, - ) - - id: Mapped[int] = mapped_column( - Integer, - primary_key=True, - nullable=False, - autoincrement=True, - comment="고유 식별자", - ) - - project_id: Mapped[int] = mapped_column( - Integer, - ForeignKey("project.id", ondelete="CASCADE"), - nullable=False, - index=True, - comment="연결된 Project의 id", - ) - - task_id: Mapped[str] = mapped_column( - String(36), - nullable=False, - comment="가사 생성 작업 고유 식별자 (UUID)", - ) - - status: Mapped[str] = mapped_column( - String(50), - nullable=False, - comment="처리 상태 (processing, completed, failed)", - ) - - lyric_prompt: Mapped[str] = mapped_column( - Text, - nullable=False, - comment="가사 생성에 사용된 프롬프트", - ) - - lyric_result: Mapped[str] = mapped_column( - LONGTEXT, - nullable=True, - comment="생성된 가사 결과", - ) - - language: Mapped[str] = mapped_column( - String(50), - nullable=False, - default="Korean", - comment="가사 출력 언어 (Korean, English, Chinese, Japanese, Thai, Vietnamese)", - ) - - created_at: Mapped[datetime] = mapped_column( - DateTime, - nullable=True, - server_default=func.now(), - comment="생성 일시", - ) - - # Relationships - project: Mapped["Project"] = relationship( - "Project", - back_populates="lyrics", - ) - - songs: Mapped[List["Song"]] = relationship( - "Song", - back_populates="lyric", - cascade="all, delete-orphan", - lazy="selectin", - ) - - videos: Mapped[List["Video"]] = relationship( - "Video", - back_populates="lyric", - cascade="all, delete-orphan", - lazy="selectin", - ) - - def __repr__(self) -> str: - def truncate(value: str | None, max_len: int = 10) -> str: - if value is None: - return "None" - return (value[:max_len] + "...") if len(value) > max_len else value - - return ( - f"" - ) +from datetime import datetime +from typing import TYPE_CHECKING, List + +from sqlalchemy import DateTime, ForeignKey, Integer, String, Text, func +from sqlalchemy.dialects.mysql import LONGTEXT +from sqlalchemy.orm import Mapped, mapped_column, relationship + +from app.database.session import Base + +if TYPE_CHECKING: + from app.home.models import Project + from app.song.models import Song + from app.video.models import Video + + +class Lyric(Base): + """ + 가사 테이블 + + AI를 통해 생성된 가사 정보를 저장합니다. + 프롬프트와 생성 결과, 처리 상태를 관리합니다. + + Attributes: + id: 고유 식별자 (자동 증가) + project_id: 연결된 Project의 id (외래키) + task_id: 가사 생성 작업의 고유 식별자 (UUID 형식) + status: 처리 상태 (pending, processing, completed, failed 등) + lyric_prompt: 가사 생성에 사용된 프롬프트 + lyric_result: 생성된 가사 결과 (LONGTEXT로 긴 가사 지원) + created_at: 생성 일시 (자동 설정) + + Relationships: + project: 연결된 Project + songs: 이 가사를 사용한 노래 목록 + videos: 이 가사를 사용한 영상 목록 + """ + + __tablename__ = "lyric" + __table_args__ = ( + { + "mysql_engine": "InnoDB", + "mysql_charset": "utf8mb4", + "mysql_collate": "utf8mb4_unicode_ci", + }, + ) + + id: Mapped[int] = mapped_column( + Integer, + primary_key=True, + nullable=False, + autoincrement=True, + comment="고유 식별자", + ) + + project_id: Mapped[int] = mapped_column( + Integer, + ForeignKey("project.id", ondelete="CASCADE"), + nullable=False, + index=True, + comment="연결된 Project의 id", + ) + + task_id: Mapped[str] = mapped_column( + String(36), + nullable=False, + comment="가사 생성 작업 고유 식별자 (UUID)", + ) + + status: Mapped[str] = mapped_column( + String(50), + nullable=False, + comment="처리 상태 (processing, completed, failed)", + ) + + lyric_prompt: Mapped[str] = mapped_column( + Text, + nullable=False, + comment="가사 생성에 사용된 프롬프트", + ) + + lyric_result: Mapped[str] = mapped_column( + LONGTEXT, + nullable=True, + comment="생성된 가사 결과", + ) + + language: Mapped[str] = mapped_column( + String(50), + nullable=False, + default="Korean", + comment="가사 출력 언어 (Korean, English, Chinese, Japanese, Thai, Vietnamese)", + ) + + created_at: Mapped[datetime] = mapped_column( + DateTime, + nullable=True, + server_default=func.now(), + comment="생성 일시", + ) + + # Relationships + project: Mapped["Project"] = relationship( + "Project", + back_populates="lyrics", + ) + + songs: Mapped[List["Song"]] = relationship( + "Song", + back_populates="lyric", + cascade="all, delete-orphan", + lazy="selectin", + ) + + videos: Mapped[List["Video"]] = relationship( + "Video", + back_populates="lyric", + cascade="all, delete-orphan", + lazy="selectin", + ) + + def __repr__(self) -> str: + def truncate(value: str | None, max_len: int = 10) -> str: + if value is None: + return "None" + return (value[:max_len] + "...") if len(value) > max_len else value + + return ( + f"" + ) diff --git a/app/lyric/schemas/lyric.py b/app/lyric/schemas/lyric.py index e33d6c7..d57b7cd 100644 --- a/app/lyric/schemas/lyric.py +++ b/app/lyric/schemas/lyric.py @@ -1,182 +1,182 @@ -""" -Lyric API Schemas - -이 모듈은 가사 관련 API 엔드포인트에서 사용되는 Pydantic 스키마를 정의합니다. - -사용 예시: - from app.lyric.schemas.lyric import ( - LyricStatusResponse, - LyricDetailResponse, - LyricListItem, - ) - from app.utils.pagination import PaginatedResponse - - # 라우터에서 response_model로 사용 - @router.get("/lyric/{task_id}", response_model=LyricDetailResponse) - async def get_lyric(task_id: str): - ... - - # 페이지네이션 응답 (공통 스키마 사용) - @router.get("/songs", response_model=PaginatedResponse[SongListItem]) - async def list_songs(...): - ... -""" - -from datetime import datetime -from typing import Optional - -from pydantic import BaseModel, ConfigDict, Field - - -class GenerateLyricRequest(BaseModel): - """가사 생성 요청 스키마 - - Usage: - POST /lyric/generate - Request body for generating lyrics. - - Example Request: - { - "task_id": "0694b716-dbff-7219-8000-d08cb5fce431", - "customer_name": "스테이 머뭄", - "region": "군산", - "detail_region_info": "군산 신흥동 말랭이 마을", - "language": "Korean" - } - """ - - model_config = ConfigDict( - json_schema_extra={ - "example": { - "task_id": "0694b716-dbff-7219-8000-d08cb5fce431", - "customer_name": "스테이 머뭄", - "region": "군산", - "detail_region_info": "군산 신흥동 말랭이 마을", - "language": "Korean", - } - } - ) - - task_id: str = Field( - ..., description="작업 고유 식별자 (이미지 업로드 시 생성된 task_id)" - ) - customer_name: str = Field(..., description="고객명/가게명") - region: str = Field(..., description="지역명") - detail_region_info: Optional[str] = Field(None, description="상세 지역 정보") - language: str = Field( - default="Korean", - description="가사 출력 언어 (Korean, English, Chinese, Japanese, Thai, Vietnamese)", - ) - - -class GenerateLyricResponse(BaseModel): - """가사 생성 응답 스키마 - - Usage: - POST /lyric/generate - Returns the generated lyrics. - - Note: - 실패 조건: - - ChatGPT API 오류 - - ChatGPT 거부 응답 (I'm sorry, I cannot, I can't, I apologize 등) - - 응답에 ERROR: 포함 - """ - - model_config = ConfigDict( - json_schema_extra={ - "example": { - "success": True, - "task_id": "0694b716-dbff-7219-8000-d08cb5fce431", - "lyric": "인스타 감성의 스테이 머뭄\n군산 신흥동 말랭이 마을에서\n여유로운 하루를 보내며\n추억을 만들어가요", - "language": "Korean", - "error_message": None, - } - } - ) - - success: bool = Field(..., description="생성 성공 여부") - task_id: Optional[str] = Field(None, description="작업 고유 식별자 (uuid7)") - lyric: Optional[str] = Field(None, description="생성된 가사 (성공 시)") - language: str = Field(..., description="가사 언어") - error_message: Optional[str] = Field(None, description="에러 메시지 (실패 시, ChatGPT 거부 응답 포함)") - - -class LyricStatusResponse(BaseModel): - """가사 상태 조회 응답 스키마 - - Usage: - GET /lyric/status/{task_id} - Returns the current processing status of a lyric generation task. - """ - - model_config = ConfigDict( - json_schema_extra={ - "example": { - "task_id": "0694b716-dbff-7219-8000-d08cb5fce431", - "status": "completed", - "message": "가사 생성이 완료되었습니다.", - } - } - ) - - task_id: str = Field(..., description="작업 고유 식별자") - status: str = Field(..., description="처리 상태 (processing, completed, failed)") - message: str = Field(..., description="상태 메시지") - - -class LyricDetailResponse(BaseModel): - """가사 상세 조회 응답 스키마 - - Usage: - GET /lyric/{task_id} - Returns the generated lyric content for a specific task. - """ - - model_config = ConfigDict( - json_schema_extra={ - "example": { - "id": 1, - "task_id": "0694b716-dbff-7219-8000-d08cb5fce431", - "project_id": 1, - "status": "completed", - "lyric_prompt": "고객명: 스테이 머뭄, 지역: 군산...", - "lyric_result": "인스타 감성의 스테이 머뭄\n군산 신흥동 말랭이 마을에서\n여유로운 하루를 보내며\n추억을 만들어가요", - "created_at": "2024-01-15T12:00:00", - } - } - ) - - id: int = Field(..., description="가사 ID") - task_id: str = Field(..., description="작업 고유 식별자") - project_id: int = Field(..., description="프로젝트 ID") - status: str = Field(..., description="처리 상태") - lyric_prompt: str = Field(..., description="가사 생성 프롬프트") - lyric_result: Optional[str] = Field(None, description="생성된 가사") - created_at: Optional[datetime] = Field(None, description="생성 일시") - - -class LyricListItem(BaseModel): - """가사 목록 아이템 스키마 - - Usage: - Used as individual items in paginated lyric list responses. - """ - - model_config = ConfigDict( - json_schema_extra={ - "example": { - "id": 1, - "task_id": "0694b716-dbff-7219-8000-d08cb5fce431", - "status": "completed", - "lyric_result": "인스타 감성의 스테이 머뭄\n군산 신흥동 말랭이 마을에서...", - "created_at": "2024-01-15T12:00:00", - } - } - ) - - id: int = Field(..., description="가사 ID") - task_id: str = Field(..., description="작업 고유 식별자") - status: str = Field(..., description="처리 상태") - lyric_result: Optional[str] = Field(None, description="생성된 가사 (미리보기)") - created_at: Optional[datetime] = Field(None, description="생성 일시") +""" +Lyric API Schemas + +이 모듈은 가사 관련 API 엔드포인트에서 사용되는 Pydantic 스키마를 정의합니다. + +사용 예시: + from app.lyric.schemas.lyric import ( + LyricStatusResponse, + LyricDetailResponse, + LyricListItem, + ) + from app.utils.pagination import PaginatedResponse + + # 라우터에서 response_model로 사용 + @router.get("/lyric/{task_id}", response_model=LyricDetailResponse) + async def get_lyric(task_id: str): + ... + + # 페이지네이션 응답 (공통 스키마 사용) + @router.get("/songs", response_model=PaginatedResponse[SongListItem]) + async def list_songs(...): + ... +""" + +from datetime import datetime +from typing import Optional + +from pydantic import BaseModel, ConfigDict, Field + + +class GenerateLyricRequest(BaseModel): + """가사 생성 요청 스키마 + + Usage: + POST /lyric/generate + Request body for generating lyrics. + + Example Request: + { + "task_id": "0694b716-dbff-7219-8000-d08cb5fce431", + "customer_name": "스테이 머뭄", + "region": "군산", + "detail_region_info": "군산 신흥동 말랭이 마을", + "language": "Korean" + } + """ + + model_config = ConfigDict( + json_schema_extra={ + "example": { + "task_id": "0694b716-dbff-7219-8000-d08cb5fce431", + "customer_name": "스테이 머뭄", + "region": "군산", + "detail_region_info": "군산 신흥동 말랭이 마을", + "language": "Korean", + } + } + ) + + task_id: str = Field( + ..., description="작업 고유 식별자 (이미지 업로드 시 생성된 task_id)" + ) + customer_name: str = Field(..., description="고객명/가게명") + region: str = Field(..., description="지역명") + detail_region_info: Optional[str] = Field(None, description="상세 지역 정보") + language: str = Field( + default="Korean", + description="가사 출력 언어 (Korean, English, Chinese, Japanese, Thai, Vietnamese)", + ) + + +class GenerateLyricResponse(BaseModel): + """가사 생성 응답 스키마 + + Usage: + POST /lyric/generate + Returns the generated lyrics. + + Note: + 실패 조건: + - ChatGPT API 오류 + - ChatGPT 거부 응답 (I'm sorry, I cannot, I can't, I apologize 등) + - 응답에 ERROR: 포함 + """ + + model_config = ConfigDict( + json_schema_extra={ + "example": { + "success": True, + "task_id": "0694b716-dbff-7219-8000-d08cb5fce431", + "lyric": "인스타 감성의 스테이 머뭄\n군산 신흥동 말랭이 마을에서\n여유로운 하루를 보내며\n추억을 만들어가요", + "language": "Korean", + "error_message": None, + } + } + ) + + success: bool = Field(..., description="생성 성공 여부") + task_id: Optional[str] = Field(None, description="작업 고유 식별자 (uuid7)") + lyric: Optional[str] = Field(None, description="생성된 가사 (성공 시)") + language: str = Field(..., description="가사 언어") + error_message: Optional[str] = Field(None, description="에러 메시지 (실패 시, ChatGPT 거부 응답 포함)") + + +class LyricStatusResponse(BaseModel): + """가사 상태 조회 응답 스키마 + + Usage: + GET /lyric/status/{task_id} + Returns the current processing status of a lyric generation task. + """ + + model_config = ConfigDict( + json_schema_extra={ + "example": { + "task_id": "0694b716-dbff-7219-8000-d08cb5fce431", + "status": "completed", + "message": "가사 생성이 완료되었습니다.", + } + } + ) + + task_id: str = Field(..., description="작업 고유 식별자") + status: str = Field(..., description="처리 상태 (processing, completed, failed)") + message: str = Field(..., description="상태 메시지") + + +class LyricDetailResponse(BaseModel): + """가사 상세 조회 응답 스키마 + + Usage: + GET /lyric/{task_id} + Returns the generated lyric content for a specific task. + """ + + model_config = ConfigDict( + json_schema_extra={ + "example": { + "id": 1, + "task_id": "0694b716-dbff-7219-8000-d08cb5fce431", + "project_id": 1, + "status": "completed", + "lyric_prompt": "고객명: 스테이 머뭄, 지역: 군산...", + "lyric_result": "인스타 감성의 스테이 머뭄\n군산 신흥동 말랭이 마을에서\n여유로운 하루를 보내며\n추억을 만들어가요", + "created_at": "2024-01-15T12:00:00", + } + } + ) + + id: int = Field(..., description="가사 ID") + task_id: str = Field(..., description="작업 고유 식별자") + project_id: int = Field(..., description="프로젝트 ID") + status: str = Field(..., description="처리 상태") + lyric_prompt: str = Field(..., description="가사 생성 프롬프트") + lyric_result: Optional[str] = Field(None, description="생성된 가사") + created_at: Optional[datetime] = Field(None, description="생성 일시") + + +class LyricListItem(BaseModel): + """가사 목록 아이템 스키마 + + Usage: + Used as individual items in paginated lyric list responses. + """ + + model_config = ConfigDict( + json_schema_extra={ + "example": { + "id": 1, + "task_id": "0694b716-dbff-7219-8000-d08cb5fce431", + "status": "completed", + "lyric_result": "인스타 감성의 스테이 머뭄\n군산 신흥동 말랭이 마을에서...", + "created_at": "2024-01-15T12:00:00", + } + } + ) + + id: int = Field(..., description="가사 ID") + task_id: str = Field(..., description="작업 고유 식별자") + status: str = Field(..., description="처리 상태") + lyric_result: Optional[str] = Field(None, description="생성된 가사 (미리보기)") + created_at: Optional[datetime] = Field(None, description="생성 일시") diff --git a/app/lyric/schemas/lyrics_schema.py b/app/lyric/schemas/lyrics_schema.py index ec3a5e9..e75a9fb 100644 --- a/app/lyric/schemas/lyrics_schema.py +++ b/app/lyric/schemas/lyrics_schema.py @@ -1,91 +1,91 @@ -from dataclasses import dataclass, field -from datetime import datetime -from typing import Dict, List - -from fastapi import Request - - -@dataclass -class StoreData: - id: int - created_at: datetime - store_name: str - store_category: str | None = None - store_region: str | None = None - store_address: str | None = None - store_phone_number: str | None = None - store_info: str | None = None - - -@dataclass -class AttributeData: - id: int - attr_category: str - attr_value: str - created_at: datetime - - -@dataclass -class SongSampleData: - id: int - ai: str - ai_model: str - sample_song: str - season: str | None = None - num_of_people: int | None = None - people_category: str | None = None - genre: str | None = None - - -@dataclass -class PromptTemplateData: - id: int - prompt: str - description: str | None = None - - -@dataclass -class SongFormData: - store_name: str - store_id: str - prompts: str - attributes: Dict[str, str] = field(default_factory=dict) - attributes_str: str = "" - lyrics_ids: List[int] = field(default_factory=list) - llm_model: str = "gpt-4o" - - @classmethod - async def from_form(cls, request: Request): - """Request의 form 데이터로부터 dataclass 인스턴스 생성""" - form_data = await request.form() - - # 고정 필드명들 - fixed_keys = {"store_info_name", "store_id", "llm_model", "prompts"} - - # lyrics-{id} 형태의 모든 키를 찾아서 ID 추출 - lyrics_ids = [] - attributes = {} - - for key, value in form_data.items(): - if key.startswith("lyrics-"): - lyrics_id = key.split("-")[1] - lyrics_ids.append(int(lyrics_id)) - elif key not in fixed_keys: - attributes[key] = value - - # attributes를 문자열로 변환 - attributes_str = ( - "\r\n\r\n".join([f"{key} : {value}" for key, value in attributes.items()]) - if attributes - else "" - ) - - return cls( - store_name=form_data.get("store_info_name", ""), - store_id=form_data.get("store_id", ""), - attributes=attributes, - attributes_str=attributes_str, - lyrics_ids=lyrics_ids, - llm_model=form_data.get("llm_model", "gpt-4o"), - prompts=form_data.get("prompts", ""), - ) +from dataclasses import dataclass, field +from datetime import datetime +from typing import Dict, List + +from fastapi import Request + + +@dataclass +class StoreData: + id: int + created_at: datetime + store_name: str + store_category: str | None = None + store_region: str | None = None + store_address: str | None = None + store_phone_number: str | None = None + store_info: str | None = None + + +@dataclass +class AttributeData: + id: int + attr_category: str + attr_value: str + created_at: datetime + + +@dataclass +class SongSampleData: + id: int + ai: str + ai_model: str + sample_song: str + season: str | None = None + num_of_people: int | None = None + people_category: str | None = None + genre: str | None = None + + +@dataclass +class PromptTemplateData: + id: int + prompt: str + description: str | None = None + + +@dataclass +class SongFormData: + store_name: str + store_id: str + prompts: str + attributes: Dict[str, str] = field(default_factory=dict) + attributes_str: str = "" + lyrics_ids: List[int] = field(default_factory=list) + llm_model: str = "gpt-5-mini" + + @classmethod + async def from_form(cls, request: Request): + """Request의 form 데이터로부터 dataclass 인스턴스 생성""" + form_data = await request.form() + + # 고정 필드명들 + fixed_keys = {"store_info_name", "store_id", "llm_model", "prompts"} + + # lyrics-{id} 형태의 모든 키를 찾아서 ID 추출 + lyrics_ids = [] + attributes = {} + + for key, value in form_data.items(): + if key.startswith("lyrics-"): + lyrics_id = key.split("-")[1] + lyrics_ids.append(int(lyrics_id)) + elif key not in fixed_keys: + attributes[key] = value + + # attributes를 문자열로 변환 + attributes_str = ( + "\r\n\r\n".join([f"{key} : {value}" for key, value in attributes.items()]) + if attributes + else "" + ) + + return cls( + store_name=form_data.get("store_info_name", ""), + store_id=form_data.get("store_id", ""), + attributes=attributes, + attributes_str=attributes_str, + lyrics_ids=lyrics_ids, + llm_model=form_data.get("llm_model", "gpt-5-mini"), + prompts=form_data.get("prompts", ""), + ) diff --git a/app/lyric/services/base.py b/app/lyric/services/base.py index 2a0b0a9..6a789a4 100644 --- a/app/lyric/services/base.py +++ b/app/lyric/services/base.py @@ -1,24 +1,24 @@ -from uuid import UUID -from sqlalchemy.ext.asyncio import AsyncSession -from sqlmodel import SQLModel - - -class BaseService: - def __init__(self, model, session: AsyncSession): - self.model = model - self.session = session - - async def _get(self, id: UUID): - return await self.session.get(self.model, id) - - async def _add(self, entity): - self.session.add(entity) - await self.session.commit() - await self.session.refresh(entity) - return entity - - async def _update(self, entity): - return await self._add(entity) - - async def _delete(self, entity): +from uuid import UUID +from sqlalchemy.ext.asyncio import AsyncSession +from sqlmodel import SQLModel + + +class BaseService: + def __init__(self, model, session: AsyncSession): + self.model = model + self.session = session + + async def _get(self, id: UUID): + return await self.session.get(self.model, id) + + async def _add(self, entity): + self.session.add(entity) + await self.session.commit() + await self.session.refresh(entity) + return entity + + async def _update(self, entity): + return await self._add(entity) + + async def _delete(self, entity): await self.session.delete(entity) \ No newline at end of file diff --git a/app/lyric/services/lyrics.py b/app/lyric/services/lyrics.py index 0007e07..99c6e78 100644 --- a/app/lyric/services/lyrics.py +++ b/app/lyric/services/lyrics.py @@ -1,852 +1,852 @@ -import random -from typing import List - -from fastapi import Request, status -from fastapi.exceptions import HTTPException -from sqlalchemy import Connection, text -from sqlalchemy.exc import SQLAlchemyError - -from app.lyric.schemas.lyrics_schema import ( - AttributeData, - PromptTemplateData, - SongFormData, - SongSampleData, - StoreData, -) -from app.utils.chatgpt_prompt import chatgpt_api - - -async def get_store_info(conn: Connection) -> List[StoreData]: - try: - query = """SELECT * FROM store_default_info;""" - result = await conn.execute(text(query)) - - all_store_info = [ - StoreData( - id=row[0], - store_info=row[1], - store_name=row[2], - store_category=row[3], - store_region=row[4], - store_address=row[5], - store_phone_number=row[6], - created_at=row[7], - ) - for row in result - ] - - result.close() - return all_store_info - except SQLAlchemyError as e: - print(e) - raise HTTPException( - status_code=status.HTTP_503_SERVICE_UNAVAILABLE, - detail="요청하신 서비스가 잠시 내부적으로 문제가 발생하였습니다.", - ) - except Exception as e: - print(e) - raise HTTPException( - status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, - detail="알수없는 이유로 서비스 오류가 발생하였습니다", - ) - - -async def get_attribute(conn: Connection) -> List[AttributeData]: - try: - query = """SELECT * FROM attribute;""" - result = await conn.execute(text(query)) - - all_attribute = [ - AttributeData( - id=row[0], - attr_category=row[1], - attr_value=row[2], - created_at=row[3], - ) - for row in result - ] - - result.close() - return all_attribute - except SQLAlchemyError as e: - print(e) - raise HTTPException( - status_code=status.HTTP_503_SERVICE_UNAVAILABLE, - detail="요청하신 서비스가 잠시 내부적으로 문제가 발생하였습니다.", - ) - except Exception as e: - print(e) - raise HTTPException( - status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, - detail="알수없는 이유로 서비스 오류가 발생하였습니다", - ) - - -async def get_attribute(conn: Connection) -> List[AttributeData]: - try: - query = """SELECT * FROM attribute;""" - result = await conn.execute(text(query)) - - all_attribute = [ - AttributeData( - id=row[0], - attr_category=row[1], - attr_value=row[2], - created_at=row[3], - ) - for row in result - ] - - result.close() - return all_attribute - except SQLAlchemyError as e: - print(e) - raise HTTPException( - status_code=status.HTTP_503_SERVICE_UNAVAILABLE, - detail="요청하신 서비스가 잠시 내부적으로 문제가 발생하였습니다.", - ) - except Exception as e: - print(e) - raise HTTPException( - status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, - detail="알수없는 이유로 서비스 오류가 발생하였습니다", - ) - - -async def get_sample_song(conn: Connection) -> List[SongSampleData]: - try: - query = """SELECT * FROM song_sample;""" - result = await conn.execute(text(query)) - - all_sample_song = [ - SongSampleData( - id=row[0], - ai=row[1], - ai_model=row[2], - genre=row[3], - sample_song=row[4], - ) - for row in result - ] - - result.close() - return all_sample_song - except SQLAlchemyError as e: - print(e) - raise HTTPException( - status_code=status.HTTP_503_SERVICE_UNAVAILABLE, - detail="요청하신 서비스가 잠시 내부적으로 문제가 발생하였습니다.", - ) - except Exception as e: - print(e) - raise HTTPException( - status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, - detail="알수없는 이유로 서비스 오류가 발생하였습니다", - ) - - -async def get_prompt_template(conn: Connection) -> List[PromptTemplateData]: - try: - query = """SELECT * FROM prompt_template;""" - result = await conn.execute(text(query)) - - all_prompt_template = [ - PromptTemplateData( - id=row[0], - description=row[1], - prompt=row[2], - ) - for row in result - ] - - result.close() - return all_prompt_template - except SQLAlchemyError as e: - print(e) - raise HTTPException( - status_code=status.HTTP_503_SERVICE_UNAVAILABLE, - detail="요청하신 서비스가 잠시 내부적으로 문제가 발생하였습니다.", - ) - except Exception as e: - print(e) - raise HTTPException( - status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, - detail="알수없는 이유로 서비스 오류가 발생하였습니다", - ) - - -async def get_song_result(conn: Connection) -> List[PromptTemplateData]: - try: - query = """SELECT * FROM prompt_template;""" - result = await conn.execute(text(query)) - - all_prompt_template = [ - PromptTemplateData( - id=row[0], - description=row[1], - prompt=row[2], - ) - for row in result - ] - - result.close() - return all_prompt_template - except SQLAlchemyError as e: - print(e) - raise HTTPException( - status_code=status.HTTP_503_SERVICE_UNAVAILABLE, - detail="요청하신 서비스가 잠시 내부적으로 문제가 발생하였습니다.", - ) - except Exception as e: - print(e) - raise HTTPException( - status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, - detail="알수없는 이유로 서비스 오류가 발생하였습니다", - ) - - -async def make_song_result(request: Request, conn: Connection): - try: - # 1. Form 데이터 파싱 - form_data = await SongFormData.from_form(request) - - print(f"\n{'=' * 60}") - print(f"Store ID: {form_data.store_id}") - print(f"Lyrics IDs: {form_data.lyrics_ids}") - print(f"Prompt IDs: {form_data.prompts}") - print(f"{'=' * 60}\n") - - # 2. Store 정보 조회 - store_query = """ - SELECT * FROM store_default_info WHERE id=:id; - """ - store_result = await conn.execute(text(store_query), {"id": form_data.store_id}) - - all_store_info = [ - StoreData( - id=row[0], - store_info=row[1], - store_name=row[2], - store_category=row[3], - store_region=row[4], - store_address=row[5], - store_phone_number=row[6], - created_at=row[7], - ) - for row in store_result - ] - - if not all_store_info: - raise HTTPException( - status_code=status.HTTP_404_NOT_FOUND, - detail=f"Store not found: {form_data.store_id}", - ) - - store_info = all_store_info[0] - print(f"Store: {store_info.store_name}") - - # 3. 속성 조회 -- 단계별 선택 프로세서시 구현 필요 없음 - - # 4. Sample Song 조회 및 결합 - combined_sample_song = None - - if form_data.lyrics_ids: - print(f"\n[샘플 가사 조회] - {len(form_data.lyrics_ids)}개") - - lyrics_query = """ - SELECT sample_song FROM song_sample - WHERE id IN :ids - ORDER BY created_at; - """ - lyrics_result = await conn.execute( - text(lyrics_query), {"ids": tuple(form_data.lyrics_ids)} - ) - - sample_songs = [ - row.sample_song for row in lyrics_result.fetchall() if row.sample_song - ] - - if sample_songs: - combined_sample_song = "\n\n".join( - [f"[샘플 {i + 1}]\n{song}" for i, song in enumerate(sample_songs)] - ) - print(f"{len(sample_songs)}개의 샘플 가사 조회 완료") - else: - print("샘플 가사가 비어있습니다") - else: - print("선택된 lyrics가 없습니다") - - # 5. 템플릿 가져오기 - if not form_data.prompts: - raise HTTPException( - status_code=status.HTTP_400_BAD_REQUEST, - detail="프롬프트 ID가 필요합니다", - ) - - print("템플릿 가져오기") - - prompts_query = """ - SELECT * FROM prompt_template WHERE id=:id; - """ - - # ✅ 수정: store_query → prompts_query - prompts_result = await conn.execute( - text(prompts_query), {"id": form_data.prompts} - ) - - prompts_info = [ - PromptTemplateData( - id=row[0], - description=row[1], - prompt=row[2], - ) - for row in prompts_result - ] - - if not prompts_info: - raise HTTPException( - status_code=status.HTTP_404_NOT_FOUND, - detail=f"Prompt not found: {form_data.prompts}", - ) - - prompt = prompts_info[0] - print(f"Prompt Template: {prompt.prompt}") - - # ✅ 6. 프롬프트 조합 - updated_prompt = prompt.prompt.replace("###", form_data.attributes_str).format( - name=store_info.store_name or "", - address=store_info.store_address or "", - category=store_info.store_category or "", - description=store_info.store_info or "", - ) - - updated_prompt += f""" - - 다음은 참고해야 하는 샘플 가사 정보입니다. - - 샘플 가사를 참고하여 작곡을 해주세요. - - {combined_sample_song} - """ - - print(f"\n[업데이트된 프롬프트]\n{updated_prompt}\n") - - # 7. 모델에게 요청 - generated_lyrics = await chatgpt_api.generate(prompt=updated_prompt) - - # 글자 수 계산 - total_chars_with_space = len(generated_lyrics) - total_chars_without_space = len( - generated_lyrics.replace(" ", "") - .replace("\n", "") - .replace("\r", "") - .replace("\t", "") - ) - - # final_lyrics 생성 - final_lyrics = f"""속성 {form_data.attributes_str} - 전체 글자 수 (공백 포함): {total_chars_with_space}자 - 전체 글자 수 (공백 제외): {total_chars_without_space}자\r\n\r\n{generated_lyrics}""" - - print("=" * 40) - print("[translate:form_data.attributes_str:] ", form_data.attributes_str) - print("[translate:total_chars_with_space:] ", total_chars_with_space) - print("[translate:total_chars_without_space:] ", total_chars_without_space) - print("[translate:final_lyrics:]") - print(final_lyrics) - print("=" * 40) - - # 8. DB 저장 - insert_query = """ - INSERT INTO song_results_all ( - store_info, store_name, store_category, store_address, store_phone_number, - description, prompt, attr_category, attr_value, - ai, ai_model, genre, - sample_song, result_song, created_at - ) VALUES ( - :store_info, :store_name, :store_category, :store_address, :store_phone_number, - :description, :prompt, :attr_category, :attr_value, - :ai, :ai_model, :genre, - :sample_song, :result_song, NOW() - ); - """ - - # ✅ attr_category, attr_value 추가 - insert_params = { - "store_info": store_info.store_info or "", - "store_name": store_info.store_name, - "store_category": store_info.store_category or "", - "store_address": store_info.store_address or "", - "store_phone_number": store_info.store_phone_number or "", - "description": store_info.store_info or "", - "prompt": form_data.prompts, - "attr_category": ", ".join(form_data.attributes.keys()) - if form_data.attributes - else "", - "attr_value": ", ".join(form_data.attributes.values()) - if form_data.attributes - else "", - "ai": "ChatGPT", - "ai_model": form_data.llm_model, - "genre": "후크송", - "sample_song": combined_sample_song or "없음", - "result_song": final_lyrics, - } - - await conn.execute(text(insert_query), insert_params) - await conn.commit() - - print("결과 저장 완료") - - print("\n전체 결과 조회 중...") - - # 9. 생성 결과 가져오기 (created_at 역순) - select_query = """ - SELECT * FROM song_results_all - ORDER BY created_at DESC; - """ - - all_results = await conn.execute(text(select_query)) - - results_list = [ - { - "id": row.id, - "store_info": row.store_info, - "store_name": row.store_name, - "store_category": row.store_category, - "store_address": row.store_address, - "store_phone_number": row.store_phone_number, - "description": row.description, - "prompt": row.prompt, - "attr_category": row.attr_category, - "attr_value": row.attr_value, - "ai": row.ai, - "ai_model": row.ai_model, - "genre": row.genre, - "sample_song": row.sample_song, - "result_song": row.result_song, - "created_at": row.created_at.isoformat() if row.created_at else None, - } - for row in all_results.fetchall() - ] - - print(f"전체 {len(results_list)}개의 결과 조회 완료\n") - - return results_list - - except HTTPException: - raise - except SQLAlchemyError as e: - print(f"Database Error: {e}") - import traceback - - traceback.print_exc() - raise HTTPException( - status_code=status.HTTP_503_SERVICE_UNAVAILABLE, - detail="데이터베이스 연결에 문제가 발생했습니다.", - ) - except Exception as e: - print(f"Unexpected Error: {e}") - import traceback - - traceback.print_exc() - raise HTTPException( - status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, - detail="서비스 처리 중 오류가 발생했습니다.", - ) - - -async def get_song_result(conn: Connection): # 반환 타입 수정 - try: - select_query = """ - SELECT * FROM song_results_all - ORDER BY created_at DESC; - """ - - all_results = await conn.execute(text(select_query)) - - results_list = [ - { - "id": row.id, - "store_info": row.store_info, - "store_name": row.store_name, - "store_category": row.store_category, - "store_address": row.store_address, - "store_phone_number": row.store_phone_number, - "description": row.description, - "prompt": row.prompt, - "attr_category": row.attr_category, - "attr_value": row.attr_value, - "ai": row.ai, - "ai_model": row.ai_model, - "season": row.season, - "num_of_people": row.num_of_people, - "people_category": row.people_category, - "genre": row.genre, - "sample_song": row.sample_song, - "result_song": row.result_song, - "created_at": row.created_at.isoformat() if row.created_at else None, - } - for row in all_results.fetchall() - ] - - print(f"전체 {len(results_list)}개의 결과 조회 완료\n") - - return results_list - except HTTPException: # HTTPException은 그대로 raise - raise - except SQLAlchemyError as e: - print(f"Database Error: {e}") - import traceback - - traceback.print_exc() - raise HTTPException( - status_code=status.HTTP_503_SERVICE_UNAVAILABLE, - detail="데이터베이스 연결에 문제가 발생했습니다.", - ) - except Exception as e: - print(f"Unexpected Error: {e}") - import traceback - - traceback.print_exc() - raise HTTPException( - status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, - detail="서비스 처리 중 오류가 발생했습니다.", - ) - - -async def make_automation(request: Request, conn: Connection): - try: - # 1. Form 데이터 파싱 - form_data = await SongFormData.from_form(request) - - print(f"\n{'=' * 60}") - print(f"Store ID: {form_data.store_id}") - print(f"{'=' * 60}\n") - - # 2. Store 정보 조회 - store_query = """ - SELECT * FROM store_default_info WHERE id=:id; - """ - store_result = await conn.execute(text(store_query), {"id": form_data.store_id}) - - all_store_info = [ - StoreData( - id=row[0], - store_info=row[1], - store_name=row[2], - store_category=row[3], - store_region=row[4], - store_address=row[5], - store_phone_number=row[6], - created_at=row[7], - ) - for row in store_result - ] - - if not all_store_info: - raise HTTPException( - status_code=status.HTTP_404_NOT_FOUND, - detail=f"Store not found: {form_data.store_id}", - ) - - store_info = all_store_info[0] - print(f"Store: {store_info.store_name}") - - # 3. 속성 조회 -- 단계별 선택 프로세서시 구현 필요 없음 - attribute_query = """ - SELECT * FROM attribute; - """ - - attribute_results = await conn.execute(text(attribute_query)) - - # 결과 가져오기 - attribute_rows = attribute_results.fetchall() - - formatted_attributes = "" - selected_categories = [] - selected_values = [] - - if attribute_rows: - attribute_list = [ - AttributeData( - id=row[0], - attr_category=row[1], - attr_value=row[2], - created_at=row[3], - ) - for row in attribute_rows - ] - - # ✅ 각 category에서 하나의 value만 랜덤 선택 - formatted_pairs = [] - for attr in attribute_list: - # 쉼표로 분리 및 공백 제거 - values = [v.strip() for v in attr.attr_value.split(",") if v.strip()] - - if values: - # 랜덤하게 하나만 선택 - selected_value = random.choice(values) - formatted_pairs.append(f"{attr.attr_category} : {selected_value}") - - # ✅ 선택된 category와 value 저장 - selected_categories.append(attr.attr_category) - selected_values.append(selected_value) - - # 최종 문자열 생성 - formatted_attributes = "\n".join(formatted_pairs) - - print(f"\n[포맷팅된 문자열 속성 정보]\n{formatted_attributes}\n") - else: - print("속성 데이터가 없습니다") - formatted_attributes = "" - - # 4. 템플릿 가져오기 - print("템플릿 가져오기 (ID=1)") - - prompts_query = """ - SELECT * FROM prompt_template WHERE id=1; - """ - - prompts_result = await conn.execute(text(prompts_query)) - - row = prompts_result.fetchone() - - if not row: - raise HTTPException( - status_code=status.HTTP_404_NOT_FOUND, - detail="Prompt ID 1 not found", - ) - - prompt = PromptTemplateData( - id=row[0], - description=row[1], - prompt=row[2], - ) - - print(f"Prompt Template: {prompt.prompt}") - - # 5. 템플릿 조합 - - updated_prompt = prompt.prompt.replace("###", formatted_attributes).format( - name=store_info.store_name or "", - address=store_info.store_address or "", - category=store_info.store_category or "", - description=store_info.store_info or "", - ) - - print("\n" + "=" * 80) - print("업데이트된 프롬프트") - print("=" * 80) - print(updated_prompt) - print("=" * 80 + "\n") - - # 4. Sample Song 조회 및 결합 - combined_sample_song = None - - if form_data.lyrics_ids: - print(f"\n[샘플 가사 조회] - {len(form_data.lyrics_ids)}개") - - lyrics_query = """ - SELECT sample_song FROM song_sample - WHERE id IN :ids - ORDER BY created_at; - """ - lyrics_result = await conn.execute( - text(lyrics_query), {"ids": tuple(form_data.lyrics_ids)} - ) - - sample_songs = [ - row.sample_song for row in lyrics_result.fetchall() if row.sample_song - ] - - if sample_songs: - combined_sample_song = "\n\n".join( - [f"[샘플 {i + 1}]\n{song}" for i, song in enumerate(sample_songs)] - ) - print(f"{len(sample_songs)}개의 샘플 가사 조회 완료") - else: - print("샘플 가사가 비어있습니다") - else: - print("선택된 lyrics가 없습니다") - - # 1. song_sample 테이블의 모든 ID 조회 - print("\n[샘플 가사 랜덤 선택]") - - all_ids_query = """ - SELECT id FROM song_sample; - """ - ids_result = await conn.execute(text(all_ids_query)) - all_ids = [row.id for row in ids_result.fetchall()] - - print(f"전체 샘플 가사 개수: {len(all_ids)}개") - - # 2. 랜덤하게 3개 선택 (또는 전체 개수가 3개 미만이면 전체) - combined_sample_song = None - - if all_ids: - # 3개 또는 전체 개수 중 작은 값 선택 - sample_count = min(3, len(all_ids)) - selected_ids = random.sample(all_ids, sample_count) - - print(f"랜덤 선택된 ID: {selected_ids}") - - # 3. 선택된 ID로 샘플 가사 조회 - lyrics_query = """ - SELECT sample_song FROM song_sample - WHERE id IN :ids - ORDER BY created_at; - """ - lyrics_result = await conn.execute( - text(lyrics_query), {"ids": tuple(selected_ids)} - ) - - sample_songs = [ - row.sample_song for row in lyrics_result.fetchall() if row.sample_song - ] - - # 4. combined_sample_song 생성 - if sample_songs: - combined_sample_song = "\n\n".join( - [f"[샘플 {i + 1}]\n{song}" for i, song in enumerate(sample_songs)] - ) - print(f"{len(sample_songs)}개의 샘플 가사 조회 완료") - else: - print("샘플 가사가 비어있습니다") - else: - print("song_sample 테이블에 데이터가 없습니다") - - # 5. 프롬프트에 샘플 가사 추가 - if combined_sample_song: - updated_prompt += f""" - - 다음은 참고해야 하는 샘플 가사 정보입니다. - - 샘플 가사를 참고하여 작곡을 해주세요. - - {combined_sample_song} - """ - print("샘플 가사 정보가 프롬프트에 추가되었습니다") - else: - print("샘플 가사가 없어 기본 프롬프트만 사용합니다") - - print(f"\n[최종 프롬프트 길이: {len(updated_prompt)} 자]\n") - - # 7. 모델에게 요청 - generated_lyrics = await chatgpt_api.generate(prompt=updated_prompt) - - # 글자 수 계산 - total_chars_with_space = len(generated_lyrics) - total_chars_without_space = len( - generated_lyrics.replace(" ", "") - .replace("\n", "") - .replace("\r", "") - .replace("\t", "") - ) - - # final_lyrics 생성 - final_lyrics = f"""속성 {formatted_attributes} - 전체 글자 수 (공백 포함): {total_chars_with_space}자 - 전체 글자 수 (공백 제외): {total_chars_without_space}자\r\n\r\n{generated_lyrics}""" - - # 8. DB 저장 - insert_query = """ - INSERT INTO song_results_all ( - store_info, store_name, store_category, store_address, store_phone_number, - description, prompt, attr_category, attr_value, - ai, ai_model, genre, - sample_song, result_song, created_at - ) VALUES ( - :store_info, :store_name, :store_category, :store_address, :store_phone_number, - :description, :prompt, :attr_category, :attr_value, - :ai, :ai_model, :genre, - :sample_song, :result_song, NOW() - ); - """ - print("\n[insert_params 선택된 속성 확인]") - print(f"Categories: {selected_categories}") - print(f"Values: {selected_values}") - print() - - # attr_category, attr_value - insert_params = { - "store_info": store_info.store_info or "", - "store_name": store_info.store_name, - "store_category": store_info.store_category or "", - "store_address": store_info.store_address or "", - "store_phone_number": store_info.store_phone_number or "", - "description": store_info.store_info or "", - "prompt": prompt.id, - # 랜덤 선택된 category와 value 사용 - "attr_category": ", ".join(selected_categories) - if selected_categories - else "", - "attr_value": ", ".join(selected_values) if selected_values else "", - "ai": "ChatGPT", - "ai_model": "gpt-4o", - "genre": "후크송", - "sample_song": combined_sample_song or "없음", - "result_song": final_lyrics, - } - - await conn.execute(text(insert_query), insert_params) - await conn.commit() - - print("결과 저장 완료") - - print("\n전체 결과 조회 중...") - - # 9. 생성 결과 가져오기 (created_at 역순) - select_query = """ - SELECT * FROM song_results_all - ORDER BY created_at DESC; - """ - - all_results = await conn.execute(text(select_query)) - - results_list = [ - { - "id": row.id, - "store_info": row.store_info, - "store_name": row.store_name, - "store_category": row.store_category, - "store_address": row.store_address, - "store_phone_number": row.store_phone_number, - "description": row.description, - "prompt": row.prompt, - "attr_category": row.attr_category, - "attr_value": row.attr_value, - "ai": row.ai, - "ai_model": row.ai_model, - "genre": row.genre, - "sample_song": row.sample_song, - "result_song": row.result_song, - "created_at": row.created_at.isoformat() if row.created_at else None, - } - for row in all_results.fetchall() - ] - - print(f"전체 {len(results_list)}개의 결과 조회 완료\n") - - return results_list - - except HTTPException: - raise - except SQLAlchemyError as e: - print(f"Database Error: {e}") - import traceback - - traceback.print_exc() - raise HTTPException( - status_code=status.HTTP_503_SERVICE_UNAVAILABLE, - detail="데이터베이스 연결에 문제가 발생했습니다.", - ) - except Exception as e: - print(f"Unexpected Error: {e}") - import traceback - - traceback.print_exc() - raise HTTPException( - status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, - detail="서비스 처리 중 오류가 발생했습니다.", - ) +import random +from typing import List + +from fastapi import Request, status +from fastapi.exceptions import HTTPException +from sqlalchemy import Connection, text +from sqlalchemy.exc import SQLAlchemyError + +from app.lyric.schemas.lyrics_schema import ( + AttributeData, + PromptTemplateData, + SongFormData, + SongSampleData, + StoreData, +) +from app.utils.chatgpt_prompt import chatgpt_api + + +async def get_store_info(conn: Connection) -> List[StoreData]: + try: + query = """SELECT * FROM store_default_info;""" + result = await conn.execute(text(query)) + + all_store_info = [ + StoreData( + id=row[0], + store_info=row[1], + store_name=row[2], + store_category=row[3], + store_region=row[4], + store_address=row[5], + store_phone_number=row[6], + created_at=row[7], + ) + for row in result + ] + + result.close() + return all_store_info + except SQLAlchemyError as e: + print(e) + raise HTTPException( + status_code=status.HTTP_503_SERVICE_UNAVAILABLE, + detail="요청하신 서비스가 잠시 내부적으로 문제가 발생하였습니다.", + ) + except Exception as e: + print(e) + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="알수없는 이유로 서비스 오류가 발생하였습니다", + ) + + +async def get_attribute(conn: Connection) -> List[AttributeData]: + try: + query = """SELECT * FROM attribute;""" + result = await conn.execute(text(query)) + + all_attribute = [ + AttributeData( + id=row[0], + attr_category=row[1], + attr_value=row[2], + created_at=row[3], + ) + for row in result + ] + + result.close() + return all_attribute + except SQLAlchemyError as e: + print(e) + raise HTTPException( + status_code=status.HTTP_503_SERVICE_UNAVAILABLE, + detail="요청하신 서비스가 잠시 내부적으로 문제가 발생하였습니다.", + ) + except Exception as e: + print(e) + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="알수없는 이유로 서비스 오류가 발생하였습니다", + ) + + +async def get_attribute(conn: Connection) -> List[AttributeData]: + try: + query = """SELECT * FROM attribute;""" + result = await conn.execute(text(query)) + + all_attribute = [ + AttributeData( + id=row[0], + attr_category=row[1], + attr_value=row[2], + created_at=row[3], + ) + for row in result + ] + + result.close() + return all_attribute + except SQLAlchemyError as e: + print(e) + raise HTTPException( + status_code=status.HTTP_503_SERVICE_UNAVAILABLE, + detail="요청하신 서비스가 잠시 내부적으로 문제가 발생하였습니다.", + ) + except Exception as e: + print(e) + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="알수없는 이유로 서비스 오류가 발생하였습니다", + ) + + +async def get_sample_song(conn: Connection) -> List[SongSampleData]: + try: + query = """SELECT * FROM song_sample;""" + result = await conn.execute(text(query)) + + all_sample_song = [ + SongSampleData( + id=row[0], + ai=row[1], + ai_model=row[2], + genre=row[3], + sample_song=row[4], + ) + for row in result + ] + + result.close() + return all_sample_song + except SQLAlchemyError as e: + print(e) + raise HTTPException( + status_code=status.HTTP_503_SERVICE_UNAVAILABLE, + detail="요청하신 서비스가 잠시 내부적으로 문제가 발생하였습니다.", + ) + except Exception as e: + print(e) + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="알수없는 이유로 서비스 오류가 발생하였습니다", + ) + + +async def get_prompt_template(conn: Connection) -> List[PromptTemplateData]: + try: + query = """SELECT * FROM prompt_template;""" + result = await conn.execute(text(query)) + + all_prompt_template = [ + PromptTemplateData( + id=row[0], + description=row[1], + prompt=row[2], + ) + for row in result + ] + + result.close() + return all_prompt_template + except SQLAlchemyError as e: + print(e) + raise HTTPException( + status_code=status.HTTP_503_SERVICE_UNAVAILABLE, + detail="요청하신 서비스가 잠시 내부적으로 문제가 발생하였습니다.", + ) + except Exception as e: + print(e) + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="알수없는 이유로 서비스 오류가 발생하였습니다", + ) + + +async def get_song_result(conn: Connection) -> List[PromptTemplateData]: + try: + query = """SELECT * FROM prompt_template;""" + result = await conn.execute(text(query)) + + all_prompt_template = [ + PromptTemplateData( + id=row[0], + description=row[1], + prompt=row[2], + ) + for row in result + ] + + result.close() + return all_prompt_template + except SQLAlchemyError as e: + print(e) + raise HTTPException( + status_code=status.HTTP_503_SERVICE_UNAVAILABLE, + detail="요청하신 서비스가 잠시 내부적으로 문제가 발생하였습니다.", + ) + except Exception as e: + print(e) + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="알수없는 이유로 서비스 오류가 발생하였습니다", + ) + + +async def make_song_result(request: Request, conn: Connection): + try: + # 1. Form 데이터 파싱 + form_data = await SongFormData.from_form(request) + + print(f"\n{'=' * 60}") + print(f"Store ID: {form_data.store_id}") + print(f"Lyrics IDs: {form_data.lyrics_ids}") + print(f"Prompt IDs: {form_data.prompts}") + print(f"{'=' * 60}\n") + + # 2. Store 정보 조회 + store_query = """ + SELECT * FROM store_default_info WHERE id=:id; + """ + store_result = await conn.execute(text(store_query), {"id": form_data.store_id}) + + all_store_info = [ + StoreData( + id=row[0], + store_info=row[1], + store_name=row[2], + store_category=row[3], + store_region=row[4], + store_address=row[5], + store_phone_number=row[6], + created_at=row[7], + ) + for row in store_result + ] + + if not all_store_info: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=f"Store not found: {form_data.store_id}", + ) + + store_info = all_store_info[0] + print(f"Store: {store_info.store_name}") + + # 3. 속성 조회 -- 단계별 선택 프로세서시 구현 필요 없음 + + # 4. Sample Song 조회 및 결합 + combined_sample_song = None + + if form_data.lyrics_ids: + print(f"\n[샘플 가사 조회] - {len(form_data.lyrics_ids)}개") + + lyrics_query = """ + SELECT sample_song FROM song_sample + WHERE id IN :ids + ORDER BY created_at; + """ + lyrics_result = await conn.execute( + text(lyrics_query), {"ids": tuple(form_data.lyrics_ids)} + ) + + sample_songs = [ + row.sample_song for row in lyrics_result.fetchall() if row.sample_song + ] + + if sample_songs: + combined_sample_song = "\n\n".join( + [f"[샘플 {i + 1}]\n{song}" for i, song in enumerate(sample_songs)] + ) + print(f"{len(sample_songs)}개의 샘플 가사 조회 완료") + else: + print("샘플 가사가 비어있습니다") + else: + print("선택된 lyrics가 없습니다") + + # 5. 템플릿 가져오기 + if not form_data.prompts: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail="프롬프트 ID가 필요합니다", + ) + + print("템플릿 가져오기") + + prompts_query = """ + SELECT * FROM prompt_template WHERE id=:id; + """ + + # ✅ 수정: store_query → prompts_query + prompts_result = await conn.execute( + text(prompts_query), {"id": form_data.prompts} + ) + + prompts_info = [ + PromptTemplateData( + id=row[0], + description=row[1], + prompt=row[2], + ) + for row in prompts_result + ] + + if not prompts_info: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=f"Prompt not found: {form_data.prompts}", + ) + + prompt = prompts_info[0] + print(f"Prompt Template: {prompt.prompt}") + + # ✅ 6. 프롬프트 조합 + updated_prompt = prompt.prompt.replace("###", form_data.attributes_str).format( + name=store_info.store_name or "", + address=store_info.store_address or "", + category=store_info.store_category or "", + description=store_info.store_info or "", + ) + + updated_prompt += f""" + + 다음은 참고해야 하는 샘플 가사 정보입니다. + + 샘플 가사를 참고하여 작곡을 해주세요. + + {combined_sample_song} + """ + + print(f"\n[업데이트된 프롬프트]\n{updated_prompt}\n") + + # 7. 모델에게 요청 + generated_lyrics = await chatgpt_api.generate(prompt=updated_prompt) + + # 글자 수 계산 + total_chars_with_space = len(generated_lyrics) + total_chars_without_space = len( + generated_lyrics.replace(" ", "") + .replace("\n", "") + .replace("\r", "") + .replace("\t", "") + ) + + # final_lyrics 생성 + final_lyrics = f"""속성 {form_data.attributes_str} + 전체 글자 수 (공백 포함): {total_chars_with_space}자 + 전체 글자 수 (공백 제외): {total_chars_without_space}자\r\n\r\n{generated_lyrics}""" + + print("=" * 40) + print("[translate:form_data.attributes_str:] ", form_data.attributes_str) + print("[translate:total_chars_with_space:] ", total_chars_with_space) + print("[translate:total_chars_without_space:] ", total_chars_without_space) + print("[translate:final_lyrics:]") + print(final_lyrics) + print("=" * 40) + + # 8. DB 저장 + insert_query = """ + INSERT INTO song_results_all ( + store_info, store_name, store_category, store_address, store_phone_number, + description, prompt, attr_category, attr_value, + ai, ai_model, genre, + sample_song, result_song, created_at + ) VALUES ( + :store_info, :store_name, :store_category, :store_address, :store_phone_number, + :description, :prompt, :attr_category, :attr_value, + :ai, :ai_model, :genre, + :sample_song, :result_song, NOW() + ); + """ + + # ✅ attr_category, attr_value 추가 + insert_params = { + "store_info": store_info.store_info or "", + "store_name": store_info.store_name, + "store_category": store_info.store_category or "", + "store_address": store_info.store_address or "", + "store_phone_number": store_info.store_phone_number or "", + "description": store_info.store_info or "", + "prompt": form_data.prompts, + "attr_category": ", ".join(form_data.attributes.keys()) + if form_data.attributes + else "", + "attr_value": ", ".join(form_data.attributes.values()) + if form_data.attributes + else "", + "ai": "ChatGPT", + "ai_model": form_data.llm_model, + "genre": "후크송", + "sample_song": combined_sample_song or "없음", + "result_song": final_lyrics, + } + + await conn.execute(text(insert_query), insert_params) + await conn.commit() + + print("결과 저장 완료") + + print("\n전체 결과 조회 중...") + + # 9. 생성 결과 가져오기 (created_at 역순) + select_query = """ + SELECT * FROM song_results_all + ORDER BY created_at DESC; + """ + + all_results = await conn.execute(text(select_query)) + + results_list = [ + { + "id": row.id, + "store_info": row.store_info, + "store_name": row.store_name, + "store_category": row.store_category, + "store_address": row.store_address, + "store_phone_number": row.store_phone_number, + "description": row.description, + "prompt": row.prompt, + "attr_category": row.attr_category, + "attr_value": row.attr_value, + "ai": row.ai, + "ai_model": row.ai_model, + "genre": row.genre, + "sample_song": row.sample_song, + "result_song": row.result_song, + "created_at": row.created_at.isoformat() if row.created_at else None, + } + for row in all_results.fetchall() + ] + + print(f"전체 {len(results_list)}개의 결과 조회 완료\n") + + return results_list + + except HTTPException: + raise + except SQLAlchemyError as e: + print(f"Database Error: {e}") + import traceback + + traceback.print_exc() + raise HTTPException( + status_code=status.HTTP_503_SERVICE_UNAVAILABLE, + detail="데이터베이스 연결에 문제가 발생했습니다.", + ) + except Exception as e: + print(f"Unexpected Error: {e}") + import traceback + + traceback.print_exc() + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="서비스 처리 중 오류가 발생했습니다.", + ) + + +async def get_song_result(conn: Connection): # 반환 타입 수정 + try: + select_query = """ + SELECT * FROM song_results_all + ORDER BY created_at DESC; + """ + + all_results = await conn.execute(text(select_query)) + + results_list = [ + { + "id": row.id, + "store_info": row.store_info, + "store_name": row.store_name, + "store_category": row.store_category, + "store_address": row.store_address, + "store_phone_number": row.store_phone_number, + "description": row.description, + "prompt": row.prompt, + "attr_category": row.attr_category, + "attr_value": row.attr_value, + "ai": row.ai, + "ai_model": row.ai_model, + "season": row.season, + "num_of_people": row.num_of_people, + "people_category": row.people_category, + "genre": row.genre, + "sample_song": row.sample_song, + "result_song": row.result_song, + "created_at": row.created_at.isoformat() if row.created_at else None, + } + for row in all_results.fetchall() + ] + + print(f"전체 {len(results_list)}개의 결과 조회 완료\n") + + return results_list + except HTTPException: # HTTPException은 그대로 raise + raise + except SQLAlchemyError as e: + print(f"Database Error: {e}") + import traceback + + traceback.print_exc() + raise HTTPException( + status_code=status.HTTP_503_SERVICE_UNAVAILABLE, + detail="데이터베이스 연결에 문제가 발생했습니다.", + ) + except Exception as e: + print(f"Unexpected Error: {e}") + import traceback + + traceback.print_exc() + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="서비스 처리 중 오류가 발생했습니다.", + ) + + +async def make_automation(request: Request, conn: Connection): + try: + # 1. Form 데이터 파싱 + form_data = await SongFormData.from_form(request) + + print(f"\n{'=' * 60}") + print(f"Store ID: {form_data.store_id}") + print(f"{'=' * 60}\n") + + # 2. Store 정보 조회 + store_query = """ + SELECT * FROM store_default_info WHERE id=:id; + """ + store_result = await conn.execute(text(store_query), {"id": form_data.store_id}) + + all_store_info = [ + StoreData( + id=row[0], + store_info=row[1], + store_name=row[2], + store_category=row[3], + store_region=row[4], + store_address=row[5], + store_phone_number=row[6], + created_at=row[7], + ) + for row in store_result + ] + + if not all_store_info: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=f"Store not found: {form_data.store_id}", + ) + + store_info = all_store_info[0] + print(f"Store: {store_info.store_name}") + + # 3. 속성 조회 -- 단계별 선택 프로세서시 구현 필요 없음 + attribute_query = """ + SELECT * FROM attribute; + """ + + attribute_results = await conn.execute(text(attribute_query)) + + # 결과 가져오기 + attribute_rows = attribute_results.fetchall() + + formatted_attributes = "" + selected_categories = [] + selected_values = [] + + if attribute_rows: + attribute_list = [ + AttributeData( + id=row[0], + attr_category=row[1], + attr_value=row[2], + created_at=row[3], + ) + for row in attribute_rows + ] + + # ✅ 각 category에서 하나의 value만 랜덤 선택 + formatted_pairs = [] + for attr in attribute_list: + # 쉼표로 분리 및 공백 제거 + values = [v.strip() for v in attr.attr_value.split(",") if v.strip()] + + if values: + # 랜덤하게 하나만 선택 + selected_value = random.choice(values) + formatted_pairs.append(f"{attr.attr_category} : {selected_value}") + + # ✅ 선택된 category와 value 저장 + selected_categories.append(attr.attr_category) + selected_values.append(selected_value) + + # 최종 문자열 생성 + formatted_attributes = "\n".join(formatted_pairs) + + print(f"\n[포맷팅된 문자열 속성 정보]\n{formatted_attributes}\n") + else: + print("속성 데이터가 없습니다") + formatted_attributes = "" + + # 4. 템플릿 가져오기 + print("템플릿 가져오기 (ID=1)") + + prompts_query = """ + SELECT * FROM prompt_template WHERE id=1; + """ + + prompts_result = await conn.execute(text(prompts_query)) + + row = prompts_result.fetchone() + + if not row: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="Prompt ID 1 not found", + ) + + prompt = PromptTemplateData( + id=row[0], + description=row[1], + prompt=row[2], + ) + + print(f"Prompt Template: {prompt.prompt}") + + # 5. 템플릿 조합 + + updated_prompt = prompt.prompt.replace("###", formatted_attributes).format( + name=store_info.store_name or "", + address=store_info.store_address or "", + category=store_info.store_category or "", + description=store_info.store_info or "", + ) + + print("\n" + "=" * 80) + print("업데이트된 프롬프트") + print("=" * 80) + print(updated_prompt) + print("=" * 80 + "\n") + + # 4. Sample Song 조회 및 결합 + combined_sample_song = None + + if form_data.lyrics_ids: + print(f"\n[샘플 가사 조회] - {len(form_data.lyrics_ids)}개") + + lyrics_query = """ + SELECT sample_song FROM song_sample + WHERE id IN :ids + ORDER BY created_at; + """ + lyrics_result = await conn.execute( + text(lyrics_query), {"ids": tuple(form_data.lyrics_ids)} + ) + + sample_songs = [ + row.sample_song for row in lyrics_result.fetchall() if row.sample_song + ] + + if sample_songs: + combined_sample_song = "\n\n".join( + [f"[샘플 {i + 1}]\n{song}" for i, song in enumerate(sample_songs)] + ) + print(f"{len(sample_songs)}개의 샘플 가사 조회 완료") + else: + print("샘플 가사가 비어있습니다") + else: + print("선택된 lyrics가 없습니다") + + # 1. song_sample 테이블의 모든 ID 조회 + print("\n[샘플 가사 랜덤 선택]") + + all_ids_query = """ + SELECT id FROM song_sample; + """ + ids_result = await conn.execute(text(all_ids_query)) + all_ids = [row.id for row in ids_result.fetchall()] + + print(f"전체 샘플 가사 개수: {len(all_ids)}개") + + # 2. 랜덤하게 3개 선택 (또는 전체 개수가 3개 미만이면 전체) + combined_sample_song = None + + if all_ids: + # 3개 또는 전체 개수 중 작은 값 선택 + sample_count = min(3, len(all_ids)) + selected_ids = random.sample(all_ids, sample_count) + + print(f"랜덤 선택된 ID: {selected_ids}") + + # 3. 선택된 ID로 샘플 가사 조회 + lyrics_query = """ + SELECT sample_song FROM song_sample + WHERE id IN :ids + ORDER BY created_at; + """ + lyrics_result = await conn.execute( + text(lyrics_query), {"ids": tuple(selected_ids)} + ) + + sample_songs = [ + row.sample_song for row in lyrics_result.fetchall() if row.sample_song + ] + + # 4. combined_sample_song 생성 + if sample_songs: + combined_sample_song = "\n\n".join( + [f"[샘플 {i + 1}]\n{song}" for i, song in enumerate(sample_songs)] + ) + print(f"{len(sample_songs)}개의 샘플 가사 조회 완료") + else: + print("샘플 가사가 비어있습니다") + else: + print("song_sample 테이블에 데이터가 없습니다") + + # 5. 프롬프트에 샘플 가사 추가 + if combined_sample_song: + updated_prompt += f""" + + 다음은 참고해야 하는 샘플 가사 정보입니다. + + 샘플 가사를 참고하여 작곡을 해주세요. + + {combined_sample_song} + """ + print("샘플 가사 정보가 프롬프트에 추가되었습니다") + else: + print("샘플 가사가 없어 기본 프롬프트만 사용합니다") + + print(f"\n[최종 프롬프트 길이: {len(updated_prompt)} 자]\n") + + # 7. 모델에게 요청 + generated_lyrics = await chatgpt_api.generate(prompt=updated_prompt) + + # 글자 수 계산 + total_chars_with_space = len(generated_lyrics) + total_chars_without_space = len( + generated_lyrics.replace(" ", "") + .replace("\n", "") + .replace("\r", "") + .replace("\t", "") + ) + + # final_lyrics 생성 + final_lyrics = f"""속성 {formatted_attributes} + 전체 글자 수 (공백 포함): {total_chars_with_space}자 + 전체 글자 수 (공백 제외): {total_chars_without_space}자\r\n\r\n{generated_lyrics}""" + + # 8. DB 저장 + insert_query = """ + INSERT INTO song_results_all ( + store_info, store_name, store_category, store_address, store_phone_number, + description, prompt, attr_category, attr_value, + ai, ai_model, genre, + sample_song, result_song, created_at + ) VALUES ( + :store_info, :store_name, :store_category, :store_address, :store_phone_number, + :description, :prompt, :attr_category, :attr_value, + :ai, :ai_model, :genre, + :sample_song, :result_song, NOW() + ); + """ + print("\n[insert_params 선택된 속성 확인]") + print(f"Categories: {selected_categories}") + print(f"Values: {selected_values}") + print() + + # attr_category, attr_value + insert_params = { + "store_info": store_info.store_info or "", + "store_name": store_info.store_name, + "store_category": store_info.store_category or "", + "store_address": store_info.store_address or "", + "store_phone_number": store_info.store_phone_number or "", + "description": store_info.store_info or "", + "prompt": prompt.id, + # 랜덤 선택된 category와 value 사용 + "attr_category": ", ".join(selected_categories) + if selected_categories + else "", + "attr_value": ", ".join(selected_values) if selected_values else "", + "ai": "ChatGPT", + "ai_model": "gpt-5-mini", + "genre": "후크송", + "sample_song": combined_sample_song or "없음", + "result_song": final_lyrics, + } + + await conn.execute(text(insert_query), insert_params) + await conn.commit() + + print("결과 저장 완료") + + print("\n전체 결과 조회 중...") + + # 9. 생성 결과 가져오기 (created_at 역순) + select_query = """ + SELECT * FROM song_results_all + ORDER BY created_at DESC; + """ + + all_results = await conn.execute(text(select_query)) + + results_list = [ + { + "id": row.id, + "store_info": row.store_info, + "store_name": row.store_name, + "store_category": row.store_category, + "store_address": row.store_address, + "store_phone_number": row.store_phone_number, + "description": row.description, + "prompt": row.prompt, + "attr_category": row.attr_category, + "attr_value": row.attr_value, + "ai": row.ai, + "ai_model": row.ai_model, + "genre": row.genre, + "sample_song": row.sample_song, + "result_song": row.result_song, + "created_at": row.created_at.isoformat() if row.created_at else None, + } + for row in all_results.fetchall() + ] + + print(f"전체 {len(results_list)}개의 결과 조회 완료\n") + + return results_list + + except HTTPException: + raise + except SQLAlchemyError as e: + print(f"Database Error: {e}") + import traceback + + traceback.print_exc() + raise HTTPException( + status_code=status.HTTP_503_SERVICE_UNAVAILABLE, + detail="데이터베이스 연결에 문제가 발생했습니다.", + ) + except Exception as e: + print(f"Unexpected Error: {e}") + import traceback + + traceback.print_exc() + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="서비스 처리 중 오류가 발생했습니다.", + ) diff --git a/app/lyric/worker/lyric_task.py b/app/lyric/worker/lyric_task.py index 8e4d2e6..886b8fe 100644 --- a/app/lyric/worker/lyric_task.py +++ b/app/lyric/worker/lyric_task.py @@ -1,98 +1,146 @@ -""" -Lyric Background Tasks - -가사 생성 관련 백그라운드 태스크를 정의합니다. -""" - -from sqlalchemy import select - -from app.database.session import BackgroundSessionLocal -from app.lyric.models import Lyric -from app.utils.chatgpt_prompt import ChatgptService - - -async def generate_lyric_background( - task_id: str, - prompt: str, - language: str, -) -> None: - """백그라운드에서 ChatGPT를 통해 가사를 생성하고 Lyric 테이블을 업데이트합니다. - - Args: - task_id: 프로젝트 task_id - prompt: ChatGPT에 전달할 프롬프트 - language: 가사 언어 - """ - print(f"[generate_lyric_background] START - task_id: {task_id}") - - try: - # ChatGPT 서비스 초기화 (프롬프트는 이미 생성되어 있음) - service = ChatgptService( - customer_name="", # 프롬프트가 이미 생성되었으므로 빈 값 - region="", - detail_region_info="", - language=language, - ) - - # ChatGPT를 통해 가사 생성 - print(f"[generate_lyric_background] ChatGPT generation started - task_id: {task_id}") - result = await service.generate(prompt=prompt) - print(f"[generate_lyric_background] ChatGPT generation completed - task_id: {task_id}") - - # 실패 응답 검사 (ERROR 또는 ChatGPT 거부 응답) - failure_patterns = [ - "ERROR:", - "I'm sorry", - "I cannot", - "I can't", - "I apologize", - "I'm unable", - "I am unable", - "I'm not able", - "I am not able", - ] - is_failure = any( - pattern.lower() in result.lower() for pattern in failure_patterns - ) - - # Lyric 테이블 업데이트 (백그라운드 전용 세션 사용) - async with BackgroundSessionLocal() as session: - query_result = await session.execute( - select(Lyric) - .where(Lyric.task_id == task_id) - .order_by(Lyric.created_at.desc()) - .limit(1) - ) - lyric = query_result.scalar_one_or_none() - - if lyric: - if is_failure: - print(f"[generate_lyric_background] FAILED - task_id: {task_id}, error: {result}") - lyric.status = "failed" - lyric.lyric_result = result - else: - print(f"[generate_lyric_background] SUCCESS - task_id: {task_id}") - lyric.status = "completed" - lyric.lyric_result = result - - await session.commit() - else: - print(f"[generate_lyric_background] Lyric NOT FOUND in DB - task_id: {task_id}") - - except Exception as e: - print(f"[generate_lyric_background] EXCEPTION - task_id: {task_id}, error: {e}") - # 실패 시 Lyric 테이블 업데이트 - async with BackgroundSessionLocal() as session: - query_result = await session.execute( - select(Lyric) - .where(Lyric.task_id == task_id) - .order_by(Lyric.created_at.desc()) - .limit(1) - ) - lyric = query_result.scalar_one_or_none() - - if lyric: - lyric.status = "failed" - lyric.lyric_result = f"Error: {str(e)}" - await session.commit() - print(f"[generate_lyric_background] FAILED - task_id: {task_id}, status updated to failed") +""" +Lyric Background Tasks + +가사 생성 관련 백그라운드 태스크를 정의합니다. +""" + +import logging +import traceback + +from sqlalchemy import select +from sqlalchemy.exc import SQLAlchemyError + +from app.database.session import BackgroundSessionLocal +from app.lyric.models import Lyric +from app.utils.chatgpt_prompt import ChatgptService + +# 로거 설정 +logger = logging.getLogger(__name__) + + +async def _update_lyric_status( + task_id: str, + status: str, + result: str | None = None, +) -> bool: + """Lyric 테이블의 상태를 업데이트합니다. + + Args: + task_id: 프로젝트 task_id + status: 변경할 상태 ("processing", "completed", "failed") + result: 가사 결과 또는 에러 메시지 + + Returns: + bool: 업데이트 성공 여부 + """ + try: + async with BackgroundSessionLocal() as session: + query_result = await session.execute( + select(Lyric) + .where(Lyric.task_id == task_id) + .order_by(Lyric.created_at.desc()) + .limit(1) + ) + lyric = query_result.scalar_one_or_none() + + if lyric: + lyric.status = status + if result is not None: + lyric.lyric_result = result + await session.commit() + logger.info(f"[Lyric] Status updated - task_id: {task_id}, status: {status}") + print(f"[Lyric] Status updated - task_id: {task_id}, status: {status}") + return True + else: + logger.warning(f"[Lyric] NOT FOUND in DB - task_id: {task_id}") + print(f"[Lyric] NOT FOUND in DB - task_id: {task_id}") + return False + + except SQLAlchemyError as e: + logger.error(f"[Lyric] DB Error while updating status - task_id: {task_id}, error: {e}") + print(f"[Lyric] DB Error while updating status - task_id: {task_id}, error: {e}") + return False + except Exception as e: + logger.error(f"[Lyric] Unexpected error while updating status - task_id: {task_id}, error: {e}") + print(f"[Lyric] Unexpected error while updating status - task_id: {task_id}, error: {e}") + return False + + +async def generate_lyric_background( + task_id: str, + prompt: str, + language: str, +) -> None: + """백그라운드에서 ChatGPT를 통해 가사를 생성하고 Lyric 테이블을 업데이트합니다. + + Args: + task_id: 프로젝트 task_id + prompt: ChatGPT에 전달할 프롬프트 + language: 가사 언어 + """ + import time + + task_start = time.perf_counter() + logger.info(f"[generate_lyric_background] START - task_id: {task_id}") + print(f"[generate_lyric_background] ========== START ==========") + print(f"[generate_lyric_background] task_id: {task_id}") + print(f"[generate_lyric_background] language: {language}") + print(f"[generate_lyric_background] prompt length: {len(prompt)}자") + + try: + # ========== Step 1: ChatGPT 서비스 초기화 ========== + step1_start = time.perf_counter() + print(f"[generate_lyric_background] Step 1: ChatGPT 서비스 초기화...") + + service = ChatgptService( + customer_name="", # 프롬프트가 이미 생성되었으므로 빈 값 + region="", + detail_region_info="", + language=language, + ) + + step1_elapsed = (time.perf_counter() - step1_start) * 1000 + print(f"[generate_lyric_background] Step 1 완료 ({step1_elapsed:.1f}ms)") + + # ========== Step 2: ChatGPT API 호출 (가사 생성) ========== + step2_start = time.perf_counter() + logger.info(f"[generate_lyric_background] Step 2: ChatGPT API 호출 시작 - task_id: {task_id}") + print(f"[generate_lyric_background] Step 2: ChatGPT API 호출 시작...") + + result = await service.generate(prompt=prompt) + + step2_elapsed = (time.perf_counter() - step2_start) * 1000 + logger.info(f"[generate_lyric_background] Step 2 완료 - 응답 {len(result)}자 ({step2_elapsed:.1f}ms)") + print(f"[generate_lyric_background] Step 2 완료 - 응답 {len(result)}자 ({step2_elapsed:.1f}ms)") + + # ========== Step 3: DB 상태 업데이트 ========== + step3_start = time.perf_counter() + print(f"[generate_lyric_background] Step 3: DB 상태 업데이트...") + + await _update_lyric_status(task_id, "completed", result) + + step3_elapsed = (time.perf_counter() - step3_start) * 1000 + print(f"[generate_lyric_background] Step 3 완료 ({step3_elapsed:.1f}ms)") + + # ========== 완료 ========== + total_elapsed = (time.perf_counter() - task_start) * 1000 + logger.info(f"[generate_lyric_background] SUCCESS - task_id: {task_id}, 총 소요시간: {total_elapsed:.1f}ms") + print(f"[generate_lyric_background] ========== SUCCESS ==========") + print(f"[generate_lyric_background] 총 소요시간: {total_elapsed:.1f}ms") + print(f"[generate_lyric_background] - Step 1 (서비스 초기화): {step1_elapsed:.1f}ms") + print(f"[generate_lyric_background] - Step 2 (GPT API 호출): {step2_elapsed:.1f}ms") + print(f"[generate_lyric_background] - Step 3 (DB 업데이트): {step3_elapsed:.1f}ms") + + except SQLAlchemyError as e: + elapsed = (time.perf_counter() - task_start) * 1000 + logger.error(f"[generate_lyric_background] DB ERROR - task_id: {task_id}, error: {e} ({elapsed:.1f}ms)") + print(f"[generate_lyric_background] DB ERROR - {e} ({elapsed:.1f}ms)") + traceback.print_exc() + await _update_lyric_status(task_id, "failed", f"Database Error: {str(e)}") + + except Exception as e: + elapsed = (time.perf_counter() - task_start) * 1000 + logger.error(f"[generate_lyric_background] EXCEPTION - task_id: {task_id}, error: {e} ({elapsed:.1f}ms)") + print(f"[generate_lyric_background] EXCEPTION - {e} ({elapsed:.1f}ms)") + traceback.print_exc() + await _update_lyric_status(task_id, "failed", f"Error: {str(e)}") diff --git a/app/song/api/routers/v1/song.py b/app/song/api/routers/v1/song.py index 91c8ef6..50ad447 100644 --- a/app/song/api/routers/v1/song.py +++ b/app/song/api/routers/v1/song.py @@ -1,636 +1,636 @@ -""" -Song API Router - -이 모듈은 Suno API를 통한 노래 생성 관련 API 엔드포인트를 정의합니다. - -엔드포인트 목록: - - POST /song/generate/{task_id}: 노래 생성 요청 (task_id로 Project/Lyric 연결) - - GET /song/status/{suno_task_id}: Suno API 노래 생성 상태 조회 - - GET /song/download/{task_id}: 노래 다운로드 상태 조회 (DB polling) - -사용 예시: - from app.song.api.routers.v1.song import router - app.include_router(router, prefix="/api/v1") -""" - -from fastapi import APIRouter, Depends, HTTPException -from sqlalchemy import func, select -from sqlalchemy.ext.asyncio import AsyncSession - -from app.database.session import get_session -from app.dependencies.pagination import ( - PaginationParams, - get_pagination_params, -) -from app.home.models import Project -from app.lyric.models import Lyric -from app.song.models import Song -from app.song.schemas.song_schema import ( - DownloadSongResponse, - GenerateSongRequest, - GenerateSongResponse, - PollingSongResponse, - SongListItem, -) -from app.utils.pagination import PaginatedResponse -from app.utils.suno import SunoService - - -router = APIRouter(prefix="/song", tags=["song"]) - - -@router.post( - "/generate/{task_id}", - summary="노래 생성 요청", - description=""" -Suno API를 통해 노래 생성을 요청합니다. - -## 경로 파라미터 -- **task_id**: Project/Lyric의 task_id (필수) - 연관된 프로젝트와 가사를 조회하는 데 사용 - -## 요청 필드 -- **lyrics**: 노래에 사용할 가사 (필수) -- **genre**: 음악 장르 (필수) - K-Pop, Pop, R&B, Hip-Hop, Ballad, EDM, Rock, Jazz 등 -- **language**: 노래 언어 (선택, 기본값: Korean) - -## 반환 정보 -- **success**: 요청 성공 여부 -- **task_id**: 내부 작업 ID (Project/Lyric task_id) -- **suno_task_id**: Suno API 작업 ID (상태 조회에 사용) -- **message**: 응답 메시지 - -## 사용 예시 -``` -POST /song/generate/019123ab-cdef-7890-abcd-ef1234567890 -{ - "lyrics": "여기 군산에서 만나요\\n아름다운 하루를 함께", - "genre": "K-Pop", - "language": "Korean" -} -``` - -## 참고 -- 생성되는 노래는 약 1분 이내 길이입니다. -- suno_task_id를 사용하여 /status/{suno_task_id} 엔드포인트에서 생성 상태를 확인할 수 있습니다. -- Song 테이블에 데이터가 저장되며, project_id와 lyric_id가 자동으로 연결됩니다. - """, - response_model=GenerateSongResponse, - responses={ - 200: {"description": "노래 생성 요청 성공"}, - 404: {"description": "Project 또는 Lyric을 찾을 수 없음"}, - 500: {"description": "노래 생성 요청 실패"}, - }, -) -async def generate_song( - task_id: str, - request_body: GenerateSongRequest, -) -> GenerateSongResponse: - """가사와 장르를 기반으로 Suno API를 통해 노래를 생성합니다. - - 1. task_id로 Project와 Lyric 조회 - 2. Song 테이블에 초기 데이터 저장 (status: processing) - 3. Suno API 호출 (세션 닫힌 상태) - 4. suno_task_id 업데이트 후 응답 반환 - - Note: 이 함수는 Depends(get_session)을 사용하지 않고 명시적으로 세션을 관리합니다. - 외부 API 호출 중 DB 커넥션이 유지되지 않도록 하여 커넥션 타임아웃 문제를 방지합니다. - """ - import time - from app.database.session import AsyncSessionLocal - - request_start = time.perf_counter() - print( - f"[generate_song] START - task_id: {task_id}, " - f"genre: {request_body.genre}, language: {request_body.language}" - ) - - # 외부 API 호출 전에 필요한 데이터를 저장할 변수들 - project_id: int | None = None - lyric_id: int | None = None - song_id: int | None = None - - # ========================================================================== - # 1단계: DB 조회 및 초기 데이터 저장 (세션을 명시적으로 열고 닫음) - # ========================================================================== - try: - async with AsyncSessionLocal() as session: - # Project 조회 (중복 시 최신 것 선택) - project_result = await session.execute( - select(Project) - .where(Project.task_id == task_id) - .order_by(Project.created_at.desc()) - .limit(1) - ) - project = project_result.scalar_one_or_none() - - if not project: - print(f"[generate_song] Project NOT FOUND - task_id: {task_id}") - raise HTTPException( - status_code=404, - detail=f"task_id '{task_id}'에 해당하는 Project를 찾을 수 없습니다.", - ) - project_id = project.id - - # Lyric 조회 (중복 시 최신 것 선택) - lyric_result = await session.execute( - select(Lyric) - .where(Lyric.task_id == task_id) - .order_by(Lyric.created_at.desc()) - .limit(1) - ) - lyric = lyric_result.scalar_one_or_none() - - if not lyric: - print(f"[generate_song] Lyric NOT FOUND - task_id: {task_id}") - raise HTTPException( - status_code=404, - detail=f"task_id '{task_id}'에 해당하는 Lyric을 찾을 수 없습니다.", - ) - lyric_id = lyric.id - - query_time = time.perf_counter() - print( - f"[generate_song] Queries completed - task_id: {task_id}, " - f"project_id: {project_id}, lyric_id: {lyric_id}, " - f"elapsed: {(query_time - request_start)*1000:.1f}ms" - ) - - # Song 테이블에 초기 데이터 저장 - song_prompt = ( - f"[Lyrics]\n{request_body.lyrics}\n\n[Genre]\n{request_body.genre}" - ) - - song = Song( - project_id=project_id, - lyric_id=lyric_id, - task_id=task_id, - suno_task_id=None, - status="processing", - song_prompt=song_prompt, - language=request_body.language, - ) - session.add(song) - await session.commit() - song_id = song.id - - stage1_time = time.perf_counter() - print( - f"[generate_song] Stage 1 DONE - Song saved - " - f"task_id: {task_id}, song_id: {song_id}, " - f"elapsed: {(stage1_time - request_start)*1000:.1f}ms" - ) - # 세션이 여기서 자동으로 닫힘 - - except HTTPException: - raise - except Exception as e: - print( - f"[generate_song] Stage 1 EXCEPTION - " - f"task_id: {task_id}, error: {type(e).__name__}: {e}" - ) - return GenerateSongResponse( - success=False, - task_id=task_id, - suno_task_id=None, - message="노래 생성 요청에 실패했습니다.", - error_message=str(e), - ) - - # ========================================================================== - # 2단계: 외부 API 호출 (세션 사용 안함 - 커넥션 풀 점유 없음) - # ========================================================================== - stage2_start = time.perf_counter() - suno_task_id: str | None = None - - try: - print(f"[generate_song] Stage 2 START - Suno API - task_id: {task_id}") - suno_service = SunoService() - suno_task_id = await suno_service.generate( - prompt=request_body.lyrics, - genre=request_body.genre, - ) - - stage2_time = time.perf_counter() - print( - f"[generate_song] Stage 2 DONE - task_id: {task_id}, " - f"suno_task_id: {suno_task_id}, " - f"elapsed: {(stage2_time - stage2_start)*1000:.1f}ms" - ) - - except Exception as e: - print( - f"[generate_song] Stage 2 EXCEPTION - Suno API failed - " - f"task_id: {task_id}, error: {type(e).__name__}: {e}" - ) - # 외부 API 실패 시 Song 상태를 failed로 업데이트 - async with AsyncSessionLocal() as update_session: - song_result = await update_session.execute( - select(Song).where(Song.id == song_id) - ) - song_to_update = song_result.scalar_one_or_none() - if song_to_update: - song_to_update.status = "failed" - await update_session.commit() - - return GenerateSongResponse( - success=False, - task_id=task_id, - suno_task_id=None, - message="노래 생성 요청에 실패했습니다.", - error_message=str(e), - ) - - # ========================================================================== - # 3단계: suno_task_id 업데이트 (새 세션으로 빠르게 처리) - # ========================================================================== - stage3_start = time.perf_counter() - print(f"[generate_song] Stage 3 START - DB update - task_id: {task_id}") - - try: - async with AsyncSessionLocal() as update_session: - song_result = await update_session.execute( - select(Song).where(Song.id == song_id) - ) - song_to_update = song_result.scalar_one_or_none() - if song_to_update: - song_to_update.suno_task_id = suno_task_id - await update_session.commit() - - stage3_time = time.perf_counter() - total_time = stage3_time - request_start - print( - f"[generate_song] Stage 3 DONE - task_id: {task_id}, " - f"elapsed: {(stage3_time - stage3_start)*1000:.1f}ms" - ) - print( - f"[generate_song] SUCCESS - task_id: {task_id}, " - f"suno_task_id: {suno_task_id}, " - f"total_time: {total_time*1000:.1f}ms" - ) - - return GenerateSongResponse( - success=True, - task_id=task_id, - suno_task_id=suno_task_id, - message="노래 생성 요청이 접수되었습니다. suno_task_id로 상태를 조회하세요.", - error_message=None, - ) - - except Exception as e: - print( - f"[generate_song] Stage 3 EXCEPTION - " - f"task_id: {task_id}, error: {type(e).__name__}: {e}" - ) - return GenerateSongResponse( - success=False, - task_id=task_id, - suno_task_id=suno_task_id, - message="노래 생성은 요청되었으나 DB 업데이트에 실패했습니다.", - error_message=str(e), - ) - - -@router.get( - "/status/{suno_task_id}", - summary="노래 생성 상태 조회", - description=""" -Suno API를 통해 노래 생성 작업의 상태를 조회합니다. -SUCCESS 상태인 경우 백그라운드에서 MP3 파일을 다운로드하고 Azure Blob Storage에 업로드한 뒤 Song 테이블을 업데이트합니다. - -## 경로 파라미터 -- **suno_task_id**: 노래 생성 시 반환된 Suno API 작업 ID (필수) - -## 반환 정보 -- **success**: 조회 성공 여부 -- **status**: 작업 상태 (PENDING, processing, SUCCESS, failed) -- **message**: 상태 메시지 -- **clips**: 생성된 노래 클립 목록 (완료 시) -- **raw_response**: Suno API 원본 응답 - -## 사용 예시 -``` -GET /song/status/abc123... -``` - -## 상태 값 -- **PENDING**: 대기 중 -- **processing**: 생성 중 -- **SUCCESS**: 생성 완료 -- **failed**: 생성 실패 - -## 참고 -- 스트림 URL: 30-40초 내 생성 -- 다운로드 URL: 2-3분 내 생성 -- SUCCESS 시 백그라운드에서 MP3 다운로드 → Azure Blob Storage 업로드 → Song 테이블 업데이트 진행 -- 저장 경로: Azure Blob Storage ({BASE_URL}/{task_id}/song/{store_name}.mp3) -- Song 테이블의 song_result_url에 Blob URL이 저장됩니다 - """, - response_model=PollingSongResponse, - responses={ - 200: {"description": "상태 조회 성공"}, - 500: {"description": "상태 조회 실패"}, - }, -) -async def get_song_status( - suno_task_id: str, - session: AsyncSession = Depends(get_session), -) -> PollingSongResponse: - """suno_task_id로 노래 생성 작업의 상태를 조회합니다. - - SUCCESS 상태인 경우 백그라운드에서 MP3 파일을 다운로드하고 - Azure Blob Storage에 업로드한 뒤 Song 테이블의 status를 completed로, - song_result_url을 Blob URL로 업데이트합니다. - """ - print(f"[get_song_status] START - suno_task_id: {suno_task_id}") - try: - suno_service = SunoService() - result = await suno_service.get_task_status(suno_task_id) - parsed_response = suno_service.parse_status_response(result) - print(f"[get_song_status] Suno API response - suno_task_id: {suno_task_id}, status: {parsed_response.status}") - - # SUCCESS 상태인 경우 첫 번째 클립 정보를 DB에 직접 저장 - if parsed_response.status == "SUCCESS" and parsed_response.clips: - # 첫 번째 클립(clips[0])의 audioUrl과 duration 사용 - first_clip = parsed_response.clips[0] - audio_url = first_clip.audio_url - clip_duration = first_clip.duration - print(f"[get_song_status] Using first clip - id: {first_clip.id}, audio_url: {audio_url}, duration: {clip_duration}") - - if audio_url: - # suno_task_id로 Song 조회 - song_result = await session.execute( - select(Song) - .where(Song.suno_task_id == suno_task_id) - .order_by(Song.created_at.desc()) - .limit(1) - ) - song = song_result.scalar_one_or_none() - - if song and song.status != "completed": - # 첫 번째 클립의 audio_url과 duration을 직접 DB에 저장 - song.status = "completed" - song.song_result_url = audio_url - if clip_duration is not None: - song.duration = clip_duration - await session.commit() - print(f"[get_song_status] Song updated - suno_task_id: {suno_task_id}, status: completed, song_result_url: {audio_url}, duration: {clip_duration}") - elif song and song.status == "completed": - print(f"[get_song_status] SKIPPED - Song already completed, suno_task_id: {suno_task_id}") - - print(f"[get_song_status] SUCCESS - suno_task_id: {suno_task_id}") - return parsed_response - - except Exception as e: - import traceback - - print(f"[get_song_status] EXCEPTION - suno_task_id: {suno_task_id}, error: {e}") - return PollingSongResponse( - success=False, - status="error", - message="상태 조회에 실패했습니다.", - clips=None, - raw_response=None, - error_message=f"{type(e).__name__}: {e}\n{traceback.format_exc()}", - ) - - -@router.get( - "/download/{task_id}", - summary="노래 생성 URL 조회", - description=""" -task_id를 기반으로 Song 테이블의 상태를 조회하고, -completed인 경우 Project 정보와 노래 URL을 반환합니다. - -## 경로 파라미터 -- **task_id**: 프로젝트 task_id (필수) - -## 반환 정보 -- **success**: 조회 성공 여부 -- **status**: 처리 상태 (processing, completed, failed, not_found) -- **message**: 응답 메시지 -- **store_name**: 업체명 -- **region**: 지역명 -- **detail_region_info**: 상세 지역 정보 -- **task_id**: 작업 고유 식별자 -- **language**: 언어 -- **song_result_url**: 노래 결과 URL (completed 시, Azure Blob Storage URL) -- **created_at**: 생성 일시 - -## 사용 예시 -``` -GET /song/download/019123ab-cdef-7890-abcd-ef1234567890 -``` - -## 참고 -- processing 상태인 경우 song_result_url은 null입니다. -- completed 상태인 경우 Project 정보와 함께 song_result_url (Azure Blob URL)을 반환합니다. -- song_result_url 형식: {AZURE_BLOB_BASE_URL}/{task_id}/song/{store_name}.mp3 - """, - response_model=DownloadSongResponse, - responses={ - 200: {"description": "조회 성공"}, - 404: {"description": "Song을 찾을 수 없음"}, - 500: {"description": "조회 실패"}, - }, -) -async def download_song( - task_id: str, - session: AsyncSession = Depends(get_session), -) -> DownloadSongResponse: - """task_id로 Song 상태를 polling하고 completed 시 Project 정보와 노래 URL을 반환합니다.""" - print(f"[download_song] START - task_id: {task_id}") - try: - # task_id로 Song 조회 (여러 개 있을 경우 가장 최근 것 선택) - song_result = await session.execute( - select(Song) - .where(Song.task_id == task_id) - .order_by(Song.created_at.desc()) - .limit(1) - ) - song = song_result.scalar_one_or_none() - - if not song: - print(f"[download_song] Song NOT FOUND - task_id: {task_id}") - return DownloadSongResponse( - success=False, - status="not_found", - message=f"task_id '{task_id}'에 해당하는 Song을 찾을 수 없습니다.", - error_message="Song not found", - ) - - print(f"[download_song] Song found - task_id: {task_id}, status: {song.status}") - - # processing 상태인 경우 - if song.status == "processing": - print(f"[download_song] PROCESSING - task_id: {task_id}") - return DownloadSongResponse( - success=True, - status="processing", - message="노래 생성이 진행 중입니다.", - task_id=task_id, - ) - - # failed 상태인 경우 - if song.status == "failed": - print(f"[download_song] FAILED - task_id: {task_id}") - return DownloadSongResponse( - success=False, - status="failed", - message="노래 생성에 실패했습니다.", - task_id=task_id, - error_message="Song generation failed", - ) - - # completed 상태인 경우 - Project 정보 조회 - project_result = await session.execute( - select(Project).where(Project.id == song.project_id) - ) - project = project_result.scalar_one_or_none() - - print(f"[download_song] COMPLETED - task_id: {task_id}, song_result_url: {song.song_result_url}") - return DownloadSongResponse( - success=True, - status="completed", - message="노래 다운로드가 완료되었습니다.", - store_name=project.store_name if project else None, - region=project.region if project else None, - detail_region_info=project.detail_region_info if project else None, - task_id=task_id, - language=project.language if project else None, - song_result_url=song.song_result_url, - created_at=song.created_at, - ) - - except Exception as e: - print(f"[download_song] EXCEPTION - task_id: {task_id}, error: {e}") - return DownloadSongResponse( - success=False, - status="error", - message="노래 다운로드 조회에 실패했습니다.", - error_message=str(e), - ) - - -@router.get( - "s/", - summary="생성된 노래 목록 조회", - description=""" -완료된 노래 목록을 페이지네이션하여 조회합니다. - -## 쿼리 파라미터 -- **page**: 페이지 번호 (1부터 시작, 기본값: 1) -- **page_size**: 페이지당 데이터 수 (기본값: 10, 최대: 100) - -## 반환 정보 -- **items**: 노래 목록 (store_name, region, task_id, language, song_result_url, created_at) -- **total**: 전체 데이터 수 -- **page**: 현재 페이지 -- **page_size**: 페이지당 데이터 수 -- **total_pages**: 전체 페이지 수 -- **has_next**: 다음 페이지 존재 여부 -- **has_prev**: 이전 페이지 존재 여부 - -## 사용 예시 -``` -GET /songs/?page=1&page_size=10 -``` - -## 참고 -- status가 'completed'인 노래만 반환됩니다. -- created_at 기준 내림차순 정렬됩니다. - """, - response_model=PaginatedResponse[SongListItem], - responses={ - 200: {"description": "노래 목록 조회 성공"}, - 500: {"description": "조회 실패"}, - }, -) -async def get_songs( - session: AsyncSession = Depends(get_session), - pagination: PaginationParams = Depends(get_pagination_params), -) -> PaginatedResponse[SongListItem]: - """완료된 노래 목록을 페이지네이션하여 반환합니다.""" - print(f"[get_songs] START - page: {pagination.page}, page_size: {pagination.page_size}") - try: - offset = (pagination.page - 1) * pagination.page_size - - # 서브쿼리: task_id별 최신 Song의 id 조회 (completed 상태, created_at 기준) - from sqlalchemy import and_ - - # task_id별 최신 created_at 조회 - latest_subquery = ( - select( - Song.task_id, - func.max(Song.created_at).label("max_created_at") - ) - .where(Song.status == "completed") - .group_by(Song.task_id) - .subquery() - ) - - # 전체 개수 조회 (task_id별 최신 1개만) - count_query = select(func.count()).select_from(latest_subquery) - total_result = await session.execute(count_query) - total = total_result.scalar() or 0 - - # 데이터 조회 (completed 상태, task_id별 created_at 기준 최신 1개만, 최신순) - query = ( - select(Song) - .join( - latest_subquery, - and_( - Song.task_id == latest_subquery.c.task_id, - Song.created_at == latest_subquery.c.max_created_at - ) - ) - .where(Song.status == "completed") - .order_by(Song.created_at.desc()) - .offset(offset) - .limit(pagination.page_size) - ) - result = await session.execute(query) - songs = result.scalars().all() - - # Project 정보 일괄 조회 (N+1 문제 해결) - project_ids = [s.project_id for s in songs if s.project_id] - projects_map: dict = {} - if project_ids: - projects_result = await session.execute( - select(Project).where(Project.id.in_(project_ids)) - ) - projects_map = {p.id: p for p in projects_result.scalars().all()} - - # SongListItem으로 변환 - items = [] - for song in songs: - project = projects_map.get(song.project_id) - - item = SongListItem( - store_name=project.store_name if project else None, - region=project.region if project else None, - task_id=song.task_id, - language=song.language, - song_result_url=song.song_result_url, - created_at=song.created_at, - ) - items.append(item) - - response = PaginatedResponse.create( - items=items, - total=total, - page=pagination.page, - page_size=pagination.page_size, - ) - - print( - f"[get_songs] SUCCESS - total: {total}, page: {pagination.page}, " - f"page_size: {pagination.page_size}, items_count: {len(items)}" - ) - return response - - except Exception as e: - print(f"[get_songs] EXCEPTION - error: {e}") - raise HTTPException( - status_code=500, - detail=f"노래 목록 조회에 실패했습니다: {str(e)}", - ) +""" +Song API Router + +이 모듈은 Suno API를 통한 노래 생성 관련 API 엔드포인트를 정의합니다. + +엔드포인트 목록: + - POST /song/generate/{task_id}: 노래 생성 요청 (task_id로 Project/Lyric 연결) + - GET /song/status/{suno_task_id}: Suno API 노래 생성 상태 조회 + - GET /song/download/{task_id}: 노래 다운로드 상태 조회 (DB polling) + +사용 예시: + from app.song.api.routers.v1.song import router + app.include_router(router, prefix="/api/v1") +""" + +from fastapi import APIRouter, Depends, HTTPException +from sqlalchemy import func, select +from sqlalchemy.ext.asyncio import AsyncSession + +from app.database.session import get_session +from app.dependencies.pagination import ( + PaginationParams, + get_pagination_params, +) +from app.home.models import Project +from app.lyric.models import Lyric +from app.song.models import Song +from app.song.schemas.song_schema import ( + DownloadSongResponse, + GenerateSongRequest, + GenerateSongResponse, + PollingSongResponse, + SongListItem, +) +from app.utils.pagination import PaginatedResponse +from app.utils.suno import SunoService + + +router = APIRouter(prefix="/song", tags=["song"]) + + +@router.post( + "/generate/{task_id}", + summary="노래 생성 요청", + description=""" +Suno API를 통해 노래 생성을 요청합니다. + +## 경로 파라미터 +- **task_id**: Project/Lyric의 task_id (필수) - 연관된 프로젝트와 가사를 조회하는 데 사용 + +## 요청 필드 +- **lyrics**: 노래에 사용할 가사 (필수) +- **genre**: 음악 장르 (필수) - K-Pop, Pop, R&B, Hip-Hop, Ballad, EDM, Rock, Jazz 등 +- **language**: 노래 언어 (선택, 기본값: Korean) + +## 반환 정보 +- **success**: 요청 성공 여부 +- **task_id**: 내부 작업 ID (Project/Lyric task_id) +- **suno_task_id**: Suno API 작업 ID (상태 조회에 사용) +- **message**: 응답 메시지 + +## 사용 예시 +``` +POST /song/generate/019123ab-cdef-7890-abcd-ef1234567890 +{ + "lyrics": "여기 군산에서 만나요\\n아름다운 하루를 함께", + "genre": "K-Pop", + "language": "Korean" +} +``` + +## 참고 +- 생성되는 노래는 약 1분 이내 길이입니다. +- suno_task_id를 사용하여 /status/{suno_task_id} 엔드포인트에서 생성 상태를 확인할 수 있습니다. +- Song 테이블에 데이터가 저장되며, project_id와 lyric_id가 자동으로 연결됩니다. + """, + response_model=GenerateSongResponse, + responses={ + 200: {"description": "노래 생성 요청 성공"}, + 404: {"description": "Project 또는 Lyric을 찾을 수 없음"}, + 500: {"description": "노래 생성 요청 실패"}, + }, +) +async def generate_song( + task_id: str, + request_body: GenerateSongRequest, +) -> GenerateSongResponse: + """가사와 장르를 기반으로 Suno API를 통해 노래를 생성합니다. + + 1. task_id로 Project와 Lyric 조회 + 2. Song 테이블에 초기 데이터 저장 (status: processing) + 3. Suno API 호출 (세션 닫힌 상태) + 4. suno_task_id 업데이트 후 응답 반환 + + Note: 이 함수는 Depends(get_session)을 사용하지 않고 명시적으로 세션을 관리합니다. + 외부 API 호출 중 DB 커넥션이 유지되지 않도록 하여 커넥션 타임아웃 문제를 방지합니다. + """ + import time + from app.database.session import AsyncSessionLocal + + request_start = time.perf_counter() + print( + f"[generate_song] START - task_id: {task_id}, " + f"genre: {request_body.genre}, language: {request_body.language}" + ) + + # 외부 API 호출 전에 필요한 데이터를 저장할 변수들 + project_id: int | None = None + lyric_id: int | None = None + song_id: int | None = None + + # ========================================================================== + # 1단계: DB 조회 및 초기 데이터 저장 (세션을 명시적으로 열고 닫음) + # ========================================================================== + try: + async with AsyncSessionLocal() as session: + # Project 조회 (중복 시 최신 것 선택) + project_result = await session.execute( + select(Project) + .where(Project.task_id == task_id) + .order_by(Project.created_at.desc()) + .limit(1) + ) + project = project_result.scalar_one_or_none() + + if not project: + print(f"[generate_song] Project NOT FOUND - task_id: {task_id}") + raise HTTPException( + status_code=404, + detail=f"task_id '{task_id}'에 해당하는 Project를 찾을 수 없습니다.", + ) + project_id = project.id + + # Lyric 조회 (중복 시 최신 것 선택) + lyric_result = await session.execute( + select(Lyric) + .where(Lyric.task_id == task_id) + .order_by(Lyric.created_at.desc()) + .limit(1) + ) + lyric = lyric_result.scalar_one_or_none() + + if not lyric: + print(f"[generate_song] Lyric NOT FOUND - task_id: {task_id}") + raise HTTPException( + status_code=404, + detail=f"task_id '{task_id}'에 해당하는 Lyric을 찾을 수 없습니다.", + ) + lyric_id = lyric.id + + query_time = time.perf_counter() + print( + f"[generate_song] Queries completed - task_id: {task_id}, " + f"project_id: {project_id}, lyric_id: {lyric_id}, " + f"elapsed: {(query_time - request_start)*1000:.1f}ms" + ) + + # Song 테이블에 초기 데이터 저장 + song_prompt = ( + f"[Lyrics]\n{request_body.lyrics}\n\n[Genre]\n{request_body.genre}" + ) + + song = Song( + project_id=project_id, + lyric_id=lyric_id, + task_id=task_id, + suno_task_id=None, + status="processing", + song_prompt=song_prompt, + language=request_body.language, + ) + session.add(song) + await session.commit() + song_id = song.id + + stage1_time = time.perf_counter() + print( + f"[generate_song] Stage 1 DONE - Song saved - " + f"task_id: {task_id}, song_id: {song_id}, " + f"elapsed: {(stage1_time - request_start)*1000:.1f}ms" + ) + # 세션이 여기서 자동으로 닫힘 + + except HTTPException: + raise + except Exception as e: + print( + f"[generate_song] Stage 1 EXCEPTION - " + f"task_id: {task_id}, error: {type(e).__name__}: {e}" + ) + return GenerateSongResponse( + success=False, + task_id=task_id, + suno_task_id=None, + message="노래 생성 요청에 실패했습니다.", + error_message=str(e), + ) + + # ========================================================================== + # 2단계: 외부 API 호출 (세션 사용 안함 - 커넥션 풀 점유 없음) + # ========================================================================== + stage2_start = time.perf_counter() + suno_task_id: str | None = None + + try: + print(f"[generate_song] Stage 2 START - Suno API - task_id: {task_id}") + suno_service = SunoService() + suno_task_id = await suno_service.generate( + prompt=request_body.lyrics, + genre=request_body.genre, + ) + + stage2_time = time.perf_counter() + print( + f"[generate_song] Stage 2 DONE - task_id: {task_id}, " + f"suno_task_id: {suno_task_id}, " + f"elapsed: {(stage2_time - stage2_start)*1000:.1f}ms" + ) + + except Exception as e: + print( + f"[generate_song] Stage 2 EXCEPTION - Suno API failed - " + f"task_id: {task_id}, error: {type(e).__name__}: {e}" + ) + # 외부 API 실패 시 Song 상태를 failed로 업데이트 + async with AsyncSessionLocal() as update_session: + song_result = await update_session.execute( + select(Song).where(Song.id == song_id) + ) + song_to_update = song_result.scalar_one_or_none() + if song_to_update: + song_to_update.status = "failed" + await update_session.commit() + + return GenerateSongResponse( + success=False, + task_id=task_id, + suno_task_id=None, + message="노래 생성 요청에 실패했습니다.", + error_message=str(e), + ) + + # ========================================================================== + # 3단계: suno_task_id 업데이트 (새 세션으로 빠르게 처리) + # ========================================================================== + stage3_start = time.perf_counter() + print(f"[generate_song] Stage 3 START - DB update - task_id: {task_id}") + + try: + async with AsyncSessionLocal() as update_session: + song_result = await update_session.execute( + select(Song).where(Song.id == song_id) + ) + song_to_update = song_result.scalar_one_or_none() + if song_to_update: + song_to_update.suno_task_id = suno_task_id + await update_session.commit() + + stage3_time = time.perf_counter() + total_time = stage3_time - request_start + print( + f"[generate_song] Stage 3 DONE - task_id: {task_id}, " + f"elapsed: {(stage3_time - stage3_start)*1000:.1f}ms" + ) + print( + f"[generate_song] SUCCESS - task_id: {task_id}, " + f"suno_task_id: {suno_task_id}, " + f"total_time: {total_time*1000:.1f}ms" + ) + + return GenerateSongResponse( + success=True, + task_id=task_id, + suno_task_id=suno_task_id, + message="노래 생성 요청이 접수되었습니다. suno_task_id로 상태를 조회하세요.", + error_message=None, + ) + + except Exception as e: + print( + f"[generate_song] Stage 3 EXCEPTION - " + f"task_id: {task_id}, error: {type(e).__name__}: {e}" + ) + return GenerateSongResponse( + success=False, + task_id=task_id, + suno_task_id=suno_task_id, + message="노래 생성은 요청되었으나 DB 업데이트에 실패했습니다.", + error_message=str(e), + ) + + +@router.get( + "/status/{suno_task_id}", + summary="노래 생성 상태 조회", + description=""" +Suno API를 통해 노래 생성 작업의 상태를 조회합니다. +SUCCESS 상태인 경우 백그라운드에서 MP3 파일을 다운로드하고 Azure Blob Storage에 업로드한 뒤 Song 테이블을 업데이트합니다. + +## 경로 파라미터 +- **suno_task_id**: 노래 생성 시 반환된 Suno API 작업 ID (필수) + +## 반환 정보 +- **success**: 조회 성공 여부 +- **status**: 작업 상태 (PENDING, processing, SUCCESS, failed) +- **message**: 상태 메시지 +- **clips**: 생성된 노래 클립 목록 (완료 시) +- **raw_response**: Suno API 원본 응답 + +## 사용 예시 +``` +GET /song/status/abc123... +``` + +## 상태 값 +- **PENDING**: 대기 중 +- **processing**: 생성 중 +- **SUCCESS**: 생성 완료 +- **failed**: 생성 실패 + +## 참고 +- 스트림 URL: 30-40초 내 생성 +- 다운로드 URL: 2-3분 내 생성 +- SUCCESS 시 백그라운드에서 MP3 다운로드 → Azure Blob Storage 업로드 → Song 테이블 업데이트 진행 +- 저장 경로: Azure Blob Storage ({BASE_URL}/{task_id}/song/{store_name}.mp3) +- Song 테이블의 song_result_url에 Blob URL이 저장됩니다 + """, + response_model=PollingSongResponse, + responses={ + 200: {"description": "상태 조회 성공"}, + 500: {"description": "상태 조회 실패"}, + }, +) +async def get_song_status( + suno_task_id: str, + session: AsyncSession = Depends(get_session), +) -> PollingSongResponse: + """suno_task_id로 노래 생성 작업의 상태를 조회합니다. + + SUCCESS 상태인 경우 백그라운드에서 MP3 파일을 다운로드하고 + Azure Blob Storage에 업로드한 뒤 Song 테이블의 status를 completed로, + song_result_url을 Blob URL로 업데이트합니다. + """ + print(f"[get_song_status] START - suno_task_id: {suno_task_id}") + try: + suno_service = SunoService() + result = await suno_service.get_task_status(suno_task_id) + parsed_response = suno_service.parse_status_response(result) + print(f"[get_song_status] Suno API response - suno_task_id: {suno_task_id}, status: {parsed_response.status}") + + # SUCCESS 상태인 경우 첫 번째 클립 정보를 DB에 직접 저장 + if parsed_response.status == "SUCCESS" and parsed_response.clips: + # 첫 번째 클립(clips[0])의 audioUrl과 duration 사용 + first_clip = parsed_response.clips[0] + audio_url = first_clip.audio_url + clip_duration = first_clip.duration + print(f"[get_song_status] Using first clip - id: {first_clip.id}, audio_url: {audio_url}, duration: {clip_duration}") + + if audio_url: + # suno_task_id로 Song 조회 + song_result = await session.execute( + select(Song) + .where(Song.suno_task_id == suno_task_id) + .order_by(Song.created_at.desc()) + .limit(1) + ) + song = song_result.scalar_one_or_none() + + if song and song.status != "completed": + # 첫 번째 클립의 audio_url과 duration을 직접 DB에 저장 + song.status = "completed" + song.song_result_url = audio_url + if clip_duration is not None: + song.duration = clip_duration + await session.commit() + print(f"[get_song_status] Song updated - suno_task_id: {suno_task_id}, status: completed, song_result_url: {audio_url}, duration: {clip_duration}") + elif song and song.status == "completed": + print(f"[get_song_status] SKIPPED - Song already completed, suno_task_id: {suno_task_id}") + + print(f"[get_song_status] SUCCESS - suno_task_id: {suno_task_id}") + return parsed_response + + except Exception as e: + import traceback + + print(f"[get_song_status] EXCEPTION - suno_task_id: {suno_task_id}, error: {e}") + return PollingSongResponse( + success=False, + status="error", + message="상태 조회에 실패했습니다.", + clips=None, + raw_response=None, + error_message=f"{type(e).__name__}: {e}\n{traceback.format_exc()}", + ) + + +@router.get( + "/download/{task_id}", + summary="노래 생성 URL 조회", + description=""" +task_id를 기반으로 Song 테이블의 상태를 조회하고, +completed인 경우 Project 정보와 노래 URL을 반환합니다. + +## 경로 파라미터 +- **task_id**: 프로젝트 task_id (필수) + +## 반환 정보 +- **success**: 조회 성공 여부 +- **status**: 처리 상태 (processing, completed, failed, not_found) +- **message**: 응답 메시지 +- **store_name**: 업체명 +- **region**: 지역명 +- **detail_region_info**: 상세 지역 정보 +- **task_id**: 작업 고유 식별자 +- **language**: 언어 +- **song_result_url**: 노래 결과 URL (completed 시, Azure Blob Storage URL) +- **created_at**: 생성 일시 + +## 사용 예시 +``` +GET /song/download/019123ab-cdef-7890-abcd-ef1234567890 +``` + +## 참고 +- processing 상태인 경우 song_result_url은 null입니다. +- completed 상태인 경우 Project 정보와 함께 song_result_url (Azure Blob URL)을 반환합니다. +- song_result_url 형식: {AZURE_BLOB_BASE_URL}/{task_id}/song/{store_name}.mp3 + """, + response_model=DownloadSongResponse, + responses={ + 200: {"description": "조회 성공"}, + 404: {"description": "Song을 찾을 수 없음"}, + 500: {"description": "조회 실패"}, + }, +) +async def download_song( + task_id: str, + session: AsyncSession = Depends(get_session), +) -> DownloadSongResponse: + """task_id로 Song 상태를 polling하고 completed 시 Project 정보와 노래 URL을 반환합니다.""" + print(f"[download_song] START - task_id: {task_id}") + try: + # task_id로 Song 조회 (여러 개 있을 경우 가장 최근 것 선택) + song_result = await session.execute( + select(Song) + .where(Song.task_id == task_id) + .order_by(Song.created_at.desc()) + .limit(1) + ) + song = song_result.scalar_one_or_none() + + if not song: + print(f"[download_song] Song NOT FOUND - task_id: {task_id}") + return DownloadSongResponse( + success=False, + status="not_found", + message=f"task_id '{task_id}'에 해당하는 Song을 찾을 수 없습니다.", + error_message="Song not found", + ) + + print(f"[download_song] Song found - task_id: {task_id}, status: {song.status}") + + # processing 상태인 경우 + if song.status == "processing": + print(f"[download_song] PROCESSING - task_id: {task_id}") + return DownloadSongResponse( + success=True, + status="processing", + message="노래 생성이 진행 중입니다.", + task_id=task_id, + ) + + # failed 상태인 경우 + if song.status == "failed": + print(f"[download_song] FAILED - task_id: {task_id}") + return DownloadSongResponse( + success=False, + status="failed", + message="노래 생성에 실패했습니다.", + task_id=task_id, + error_message="Song generation failed", + ) + + # completed 상태인 경우 - Project 정보 조회 + project_result = await session.execute( + select(Project).where(Project.id == song.project_id) + ) + project = project_result.scalar_one_or_none() + + print(f"[download_song] COMPLETED - task_id: {task_id}, song_result_url: {song.song_result_url}") + return DownloadSongResponse( + success=True, + status="completed", + message="노래 다운로드가 완료되었습니다.", + store_name=project.store_name if project else None, + region=project.region if project else None, + detail_region_info=project.detail_region_info if project else None, + task_id=task_id, + language=project.language if project else None, + song_result_url=song.song_result_url, + created_at=song.created_at, + ) + + except Exception as e: + print(f"[download_song] EXCEPTION - task_id: {task_id}, error: {e}") + return DownloadSongResponse( + success=False, + status="error", + message="노래 다운로드 조회에 실패했습니다.", + error_message=str(e), + ) + + +@router.get( + "s/", + summary="생성된 노래 목록 조회", + description=""" +완료된 노래 목록을 페이지네이션하여 조회합니다. + +## 쿼리 파라미터 +- **page**: 페이지 번호 (1부터 시작, 기본값: 1) +- **page_size**: 페이지당 데이터 수 (기본값: 10, 최대: 100) + +## 반환 정보 +- **items**: 노래 목록 (store_name, region, task_id, language, song_result_url, created_at) +- **total**: 전체 데이터 수 +- **page**: 현재 페이지 +- **page_size**: 페이지당 데이터 수 +- **total_pages**: 전체 페이지 수 +- **has_next**: 다음 페이지 존재 여부 +- **has_prev**: 이전 페이지 존재 여부 + +## 사용 예시 +``` +GET /songs/?page=1&page_size=10 +``` + +## 참고 +- status가 'completed'인 노래만 반환됩니다. +- created_at 기준 내림차순 정렬됩니다. + """, + response_model=PaginatedResponse[SongListItem], + responses={ + 200: {"description": "노래 목록 조회 성공"}, + 500: {"description": "조회 실패"}, + }, +) +async def get_songs( + session: AsyncSession = Depends(get_session), + pagination: PaginationParams = Depends(get_pagination_params), +) -> PaginatedResponse[SongListItem]: + """완료된 노래 목록을 페이지네이션하여 반환합니다.""" + print(f"[get_songs] START - page: {pagination.page}, page_size: {pagination.page_size}") + try: + offset = (pagination.page - 1) * pagination.page_size + + # 서브쿼리: task_id별 최신 Song의 id 조회 (completed 상태, created_at 기준) + from sqlalchemy import and_ + + # task_id별 최신 created_at 조회 + latest_subquery = ( + select( + Song.task_id, + func.max(Song.created_at).label("max_created_at") + ) + .where(Song.status == "completed") + .group_by(Song.task_id) + .subquery() + ) + + # 전체 개수 조회 (task_id별 최신 1개만) + count_query = select(func.count()).select_from(latest_subquery) + total_result = await session.execute(count_query) + total = total_result.scalar() or 0 + + # 데이터 조회 (completed 상태, task_id별 created_at 기준 최신 1개만, 최신순) + query = ( + select(Song) + .join( + latest_subquery, + and_( + Song.task_id == latest_subquery.c.task_id, + Song.created_at == latest_subquery.c.max_created_at + ) + ) + .where(Song.status == "completed") + .order_by(Song.created_at.desc()) + .offset(offset) + .limit(pagination.page_size) + ) + result = await session.execute(query) + songs = result.scalars().all() + + # Project 정보 일괄 조회 (N+1 문제 해결) + project_ids = [s.project_id for s in songs if s.project_id] + projects_map: dict = {} + if project_ids: + projects_result = await session.execute( + select(Project).where(Project.id.in_(project_ids)) + ) + projects_map = {p.id: p for p in projects_result.scalars().all()} + + # SongListItem으로 변환 + items = [] + for song in songs: + project = projects_map.get(song.project_id) + + item = SongListItem( + store_name=project.store_name if project else None, + region=project.region if project else None, + task_id=song.task_id, + language=song.language, + song_result_url=song.song_result_url, + created_at=song.created_at, + ) + items.append(item) + + response = PaginatedResponse.create( + items=items, + total=total, + page=pagination.page, + page_size=pagination.page_size, + ) + + print( + f"[get_songs] SUCCESS - total: {total}, page: {pagination.page}, " + f"page_size: {pagination.page_size}, items_count: {len(items)}" + ) + return response + + except Exception as e: + print(f"[get_songs] EXCEPTION - error: {e}") + raise HTTPException( + status_code=500, + detail=f"노래 목록 조회에 실패했습니다: {str(e)}", + ) diff --git a/app/song/api/song_admin.py b/app/song/api/song_admin.py index 01c1a54..577ebf6 100644 --- a/app/song/api/song_admin.py +++ b/app/song/api/song_admin.py @@ -1,69 +1,69 @@ -from sqladmin import ModelView - -from app.song.models import Song - - -class SongAdmin(ModelView, model=Song): - name = "노래" - name_plural = "노래 목록" - icon = "fa-solid fa-headphones" - category = "노래 관리" - page_size = 20 - - column_list = [ - "id", - "project_id", - "lyric_id", - "task_id", - "suno_task_id", - "status", - "language", - "created_at", - ] - - column_details_list = [ - "id", - "project_id", - "lyric_id", - "task_id", - "suno_task_id", - "status", - "language", - "song_prompt", - "song_result_url", - "created_at", - ] - - # 폼(생성/수정)에서 제외 - form_excluded_columns = ["created_at", "videos"] - - column_searchable_list = [ - Song.task_id, - Song.suno_task_id, - Song.status, - Song.language, - ] - - column_default_sort = (Song.created_at, True) # True: DESC (최신순) - - column_sortable_list = [ - Song.id, - Song.project_id, - Song.lyric_id, - Song.status, - Song.language, - Song.created_at, - ] - - column_labels = { - "id": "ID", - "project_id": "프로젝트 ID", - "lyric_id": "가사 ID", - "task_id": "작업 ID", - "suno_task_id": "Suno 작업 ID", - "status": "상태", - "language": "언어", - "song_prompt": "프롬프트", - "song_result_url": "결과 URL", - "created_at": "생성일시", - } +from sqladmin import ModelView + +from app.song.models import Song + + +class SongAdmin(ModelView, model=Song): + name = "노래" + name_plural = "노래 목록" + icon = "fa-solid fa-headphones" + category = "노래 관리" + page_size = 20 + + column_list = [ + "id", + "project_id", + "lyric_id", + "task_id", + "suno_task_id", + "status", + "language", + "created_at", + ] + + column_details_list = [ + "id", + "project_id", + "lyric_id", + "task_id", + "suno_task_id", + "status", + "language", + "song_prompt", + "song_result_url", + "created_at", + ] + + # 폼(생성/수정)에서 제외 + form_excluded_columns = ["created_at", "videos"] + + column_searchable_list = [ + Song.task_id, + Song.suno_task_id, + Song.status, + Song.language, + ] + + column_default_sort = (Song.created_at, True) # True: DESC (최신순) + + column_sortable_list = [ + Song.id, + Song.project_id, + Song.lyric_id, + Song.status, + Song.language, + Song.created_at, + ] + + column_labels = { + "id": "ID", + "project_id": "프로젝트 ID", + "lyric_id": "가사 ID", + "task_id": "작업 ID", + "suno_task_id": "Suno 작업 ID", + "status": "상태", + "language": "언어", + "song_prompt": "프롬프트", + "song_result_url": "결과 URL", + "created_at": "생성일시", + } diff --git a/app/song/dependencies.py b/app/song/dependencies.py index bf6f8ea..d03c265 100644 --- a/app/song/dependencies.py +++ b/app/song/dependencies.py @@ -1,8 +1,8 @@ -from typing import Annotated - -from fastapi import Depends -from sqlalchemy.ext.asyncio import AsyncSession - -from app.database.session import get_session - -SessionDep = Annotated[AsyncSession, Depends(get_session)] +from typing import Annotated + +from fastapi import Depends +from sqlalchemy.ext.asyncio import AsyncSession + +from app.database.session import get_session + +SessionDep = Annotated[AsyncSession, Depends(get_session)] diff --git a/app/song/models.py b/app/song/models.py index 702ad76..0bfcac8 100644 --- a/app/song/models.py +++ b/app/song/models.py @@ -1,152 +1,152 @@ -from datetime import datetime -from typing import TYPE_CHECKING, List, Optional - -from sqlalchemy import DateTime, ForeignKey, Integer, String, Text, func -from sqlalchemy.orm import Mapped, mapped_column, relationship - -from app.database.session import Base - -if TYPE_CHECKING: - from app.home.models import Project - from app.lyric.models import Lyric - from app.video.models import Video - - -class Song(Base): - """ - 노래 테이블 - - AI를 통해 생성된 노래 정보를 저장합니다. - 가사를 기반으로 생성됩니다. - - Attributes: - id: 고유 식별자 (자동 증가) - project_id: 연결된 Project의 id (외래키) - lyric_id: 연결된 Lyric의 id (외래키) - task_id: 노래 생성 작업의 고유 식별자 (UUID 형식) - suno_task_id: Suno API 작업 고유 식별자 (선택) - status: 처리 상태 (pending, processing, completed, failed 등) - song_prompt: 노래 생성에 사용된 프롬프트 - song_result_url: 생성 결과 URL (선택) - language: 출력 언어 - created_at: 생성 일시 (자동 설정) - - Relationships: - project: 연결된 Project - lyric: 연결된 Lyric - videos: 이 노래를 사용한 영상 결과 목록 - """ - - __tablename__ = "song" - __table_args__ = ( - { - "mysql_engine": "InnoDB", - "mysql_charset": "utf8mb4", - "mysql_collate": "utf8mb4_unicode_ci", - }, - ) - - id: Mapped[int] = mapped_column( - Integer, - primary_key=True, - nullable=False, - autoincrement=True, - comment="고유 식별자", - ) - - project_id: Mapped[int] = mapped_column( - Integer, - ForeignKey("project.id", ondelete="CASCADE"), - nullable=False, - index=True, - comment="연결된 Project의 id", - ) - - lyric_id: Mapped[int] = mapped_column( - Integer, - ForeignKey("lyric.id", ondelete="CASCADE"), - nullable=False, - index=True, - comment="연결된 Lyric의 id", - ) - - task_id: Mapped[str] = mapped_column( - String(36), - nullable=False, - comment="노래 생성 작업 고유 식별자 (UUID)", - ) - - suno_task_id: Mapped[Optional[str]] = mapped_column( - String(64), - nullable=True, - comment="Suno API 작업 고유 식별자", - ) - - status: Mapped[str] = mapped_column( - String(50), - nullable=False, - comment="처리 상태 (processing, completed, failed)", - ) - - song_prompt: Mapped[str] = mapped_column( - Text, - nullable=False, - comment="노래 생성에 사용된 프롬프트", - ) - - song_result_url: Mapped[Optional[str]] = mapped_column( - String(2048), - nullable=True, - comment="노래 결과 URL", - ) - - duration: Mapped[Optional[float]] = mapped_column( - nullable=True, - comment="노래 재생 시간 (초)", - ) - - language: Mapped[str] = mapped_column( - String(50), - nullable=False, - default="Korean", - comment="출력 언어 (Korean, English, Chinese, Japanese, Thai, Vietnamese)", - ) - - created_at: Mapped[datetime] = mapped_column( - DateTime, - nullable=False, - server_default=func.now(), - comment="생성 일시", - ) - - # Relationships - project: Mapped["Project"] = relationship( - "Project", - back_populates="songs", - ) - - lyric: Mapped["Lyric"] = relationship( - "Lyric", - back_populates="songs", - ) - - videos: Mapped[List["Video"]] = relationship( - "Video", - back_populates="song", - cascade="all, delete-orphan", - lazy="selectin", - ) - - def __repr__(self) -> str: - def truncate(value: str | None, max_len: int = 10) -> str: - if value is None: - return "None" - return (value[:max_len] + "...") if len(value) > max_len else value - - return ( - f"" - ) +from datetime import datetime +from typing import TYPE_CHECKING, List, Optional + +from sqlalchemy import DateTime, ForeignKey, Integer, String, Text, func +from sqlalchemy.orm import Mapped, mapped_column, relationship + +from app.database.session import Base + +if TYPE_CHECKING: + from app.home.models import Project + from app.lyric.models import Lyric + from app.video.models import Video + + +class Song(Base): + """ + 노래 테이블 + + AI를 통해 생성된 노래 정보를 저장합니다. + 가사를 기반으로 생성됩니다. + + Attributes: + id: 고유 식별자 (자동 증가) + project_id: 연결된 Project의 id (외래키) + lyric_id: 연결된 Lyric의 id (외래키) + task_id: 노래 생성 작업의 고유 식별자 (UUID 형식) + suno_task_id: Suno API 작업 고유 식별자 (선택) + status: 처리 상태 (pending, processing, completed, failed 등) + song_prompt: 노래 생성에 사용된 프롬프트 + song_result_url: 생성 결과 URL (선택) + language: 출력 언어 + created_at: 생성 일시 (자동 설정) + + Relationships: + project: 연결된 Project + lyric: 연결된 Lyric + videos: 이 노래를 사용한 영상 결과 목록 + """ + + __tablename__ = "song" + __table_args__ = ( + { + "mysql_engine": "InnoDB", + "mysql_charset": "utf8mb4", + "mysql_collate": "utf8mb4_unicode_ci", + }, + ) + + id: Mapped[int] = mapped_column( + Integer, + primary_key=True, + nullable=False, + autoincrement=True, + comment="고유 식별자", + ) + + project_id: Mapped[int] = mapped_column( + Integer, + ForeignKey("project.id", ondelete="CASCADE"), + nullable=False, + index=True, + comment="연결된 Project의 id", + ) + + lyric_id: Mapped[int] = mapped_column( + Integer, + ForeignKey("lyric.id", ondelete="CASCADE"), + nullable=False, + index=True, + comment="연결된 Lyric의 id", + ) + + task_id: Mapped[str] = mapped_column( + String(36), + nullable=False, + comment="노래 생성 작업 고유 식별자 (UUID)", + ) + + suno_task_id: Mapped[Optional[str]] = mapped_column( + String(64), + nullable=True, + comment="Suno API 작업 고유 식별자", + ) + + status: Mapped[str] = mapped_column( + String(50), + nullable=False, + comment="처리 상태 (processing, completed, failed)", + ) + + song_prompt: Mapped[str] = mapped_column( + Text, + nullable=False, + comment="노래 생성에 사용된 프롬프트", + ) + + song_result_url: Mapped[Optional[str]] = mapped_column( + String(2048), + nullable=True, + comment="노래 결과 URL", + ) + + duration: Mapped[Optional[float]] = mapped_column( + nullable=True, + comment="노래 재생 시간 (초)", + ) + + language: Mapped[str] = mapped_column( + String(50), + nullable=False, + default="Korean", + comment="출력 언어 (Korean, English, Chinese, Japanese, Thai, Vietnamese)", + ) + + created_at: Mapped[datetime] = mapped_column( + DateTime, + nullable=False, + server_default=func.now(), + comment="생성 일시", + ) + + # Relationships + project: Mapped["Project"] = relationship( + "Project", + back_populates="songs", + ) + + lyric: Mapped["Lyric"] = relationship( + "Lyric", + back_populates="songs", + ) + + videos: Mapped[List["Video"]] = relationship( + "Video", + back_populates="song", + cascade="all, delete-orphan", + lazy="selectin", + ) + + def __repr__(self) -> str: + def truncate(value: str | None, max_len: int = 10) -> str: + if value is None: + return "None" + return (value[:max_len] + "...") if len(value) > max_len else value + + return ( + f"" + ) diff --git a/app/song/schemas/song_schema.py b/app/song/schemas/song_schema.py index ecec7a2..c5d2126 100644 --- a/app/song/schemas/song_schema.py +++ b/app/song/schemas/song_schema.py @@ -1,374 +1,374 @@ -from dataclasses import dataclass, field -from datetime import datetime -from typing import Any, Dict, List, Optional - -from fastapi import Request -from pydantic import BaseModel, Field - - -# ============================================================================= -# Pydantic Schemas for Song Generation API -# ============================================================================= - - -class GenerateSongRequest(BaseModel): - """노래 생성 요청 스키마 - - Usage: - POST /song/generate/{task_id} - Request body for generating a song via Suno API. - - Example Request: - { - "lyrics": "인스타 감성의 스테이 머뭄...", - "genre": "k-pop", - "language": "Korean" - } - """ - - model_config = { - "json_schema_extra": { - "example": { - "lyrics": "인스타 감성의 스테이 머뭄, 머물러봐요 \n군산 신흥동 말랭이 마을의 마음 힐링 \n사진같은 하루, 여행의 시작 \n보석 같은 이곳은 감성 숙소의 느낌 \n\n인근 명소와 아름다움이 가득한 거리 \n힐링의 바람과 여행의 추억 \n글로벌 감성의 스테이 머뭄, 인스타 감성 \n사진으로 남기고 싶은 그 순간들이 되어줘요", - "genre": "k-pop", - "language": "Korean", - } - } - } - - lyrics: str = Field(..., description="노래에 사용할 가사") - genre: str = Field( - ..., - description="음악 장르 (K-Pop, Pop, R&B, Hip-Hop, Ballad, EDM, Rock, Jazz 등)", - ) - language: str = Field( - default="Korean", - description="노래 언어 (Korean, English, Chinese, Japanese, Thai, Vietnamese)", - ) - - -class GenerateSongResponse(BaseModel): - """노래 생성 응답 스키마 - - Usage: - POST /song/generate/{task_id} - Returns the task IDs for tracking song generation. - - Note: - 실패 조건: - - task_id에 해당하는 Project가 없는 경우 (404 HTTPException) - - task_id에 해당하는 Lyric이 없는 경우 (404 HTTPException) - - Suno API 호출 실패 - - Example Response (Success): - { - "success": true, - "task_id": "019123ab-cdef-7890-abcd-ef1234567890", - "suno_task_id": "abc123...", - "message": "노래 생성 요청이 접수되었습니다. suno_task_id로 상태를 조회하세요.", - "error_message": null - } - - Example Response (Failure): - { - "success": false, - "task_id": "019123ab-cdef-7890-abcd-ef1234567890", - "suno_task_id": null, - "message": "노래 생성 요청에 실패했습니다.", - "error_message": "Suno API connection error" - } - """ - - success: bool = Field(..., description="요청 성공 여부") - task_id: Optional[str] = Field(None, description="내부 작업 ID (Project/Lyric task_id)") - suno_task_id: Optional[str] = Field(None, description="Suno API 작업 ID") - message: str = Field(..., description="응답 메시지") - error_message: Optional[str] = Field(None, description="에러 메시지 (실패 시)") - - -class PollingSongRequest(BaseModel): - """노래 생성 상태 조회 요청 스키마 (Legacy) - - Note: - 현재 사용되지 않음. GET /song/status/{suno_task_id} 엔드포인트 사용. - - Example Request: - { - "task_id": "abc123..." - } - """ - - task_id: str = Field(..., description="Suno 작업 ID") - - -class SongClipData(BaseModel): - """생성된 노래 클립 정보""" - - id: Optional[str] = Field(None, description="클립 ID") - audio_url: Optional[str] = Field(None, description="오디오 URL") - stream_audio_url: Optional[str] = Field(None, description="스트리밍 오디오 URL") - image_url: Optional[str] = Field(None, description="이미지 URL") - title: Optional[str] = Field(None, description="곡 제목") - status: Optional[str] = Field(None, description="클립 상태") - duration: Optional[float] = Field(None, description="노래 길이 (초)") - - -class PollingSongResponse(BaseModel): - """노래 생성 상태 조회 응답 스키마 - - Usage: - GET /song/status/{suno_task_id} - Suno API 작업 상태를 조회합니다. - - Note: - 상태 값: - - PENDING: 대기 중 - - processing: 생성 중 - - SUCCESS / TEXT_SUCCESS / complete: 생성 완료 - - failed: 생성 실패 - - error: API 조회 오류 - - SUCCESS 상태 시: - - 백그라운드에서 MP3 파일 다운로드 시작 - - Song 테이블의 status를 completed로 업데이트 - - song_result_url에 로컬 파일 경로 저장 - - Example Response (Processing): - { - "success": true, - "status": "processing", - "message": "노래를 생성하고 있습니다.", - "clips": null, - "raw_response": {...}, - "error_message": null - } - - Example Response (Success): - { - "success": true, - "status": "SUCCESS", - "message": "노래 생성이 완료되었습니다.", - "clips": [ - { - "id": "clip-id", - "audio_url": "https://...", - "stream_audio_url": "https://...", - "image_url": "https://...", - "title": "Song Title", - "status": "complete", - "duration": 60.0 - } - ], - "raw_response": {...}, - "error_message": null - } - - Example Response (Failure): - { - "success": false, - "status": "error", - "message": "상태 조회에 실패했습니다.", - "clips": null, - "raw_response": null, - "error_message": "ConnectionError: ..." - } - """ - - success: bool = Field(..., description="조회 성공 여부") - status: Optional[str] = Field( - None, description="작업 상태 (PENDING, processing, SUCCESS, failed)" - ) - message: str = Field(..., description="상태 메시지") - clips: Optional[List[SongClipData]] = Field(None, description="생성된 노래 클립 목록") - raw_response: Optional[Dict[str, Any]] = Field(None, description="Suno API 원본 응답") - error_message: Optional[str] = Field(None, description="에러 메시지 (실패 시)") - - -class SongListItem(BaseModel): - """노래 목록 아이템 스키마 - - Usage: - GET /songs 응답의 개별 노래 정보 - - Example: - { - "store_name": "스테이 머뭄", - "region": "군산", - "task_id": "019123ab-cdef-7890-abcd-ef1234567890", - "language": "Korean", - "song_result_url": "http://localhost:8000/media/2025-01-15/스테이머뭄.mp3", - "created_at": "2025-01-15T12:00:00" - } - """ - - store_name: Optional[str] = Field(None, description="업체명") - region: Optional[str] = Field(None, description="지역명") - task_id: str = Field(..., description="작업 고유 식별자") - language: Optional[str] = Field(None, description="언어") - song_result_url: Optional[str] = Field(None, description="노래 결과 URL") - created_at: Optional[datetime] = Field(None, description="생성 일시") - - -class DownloadSongResponse(BaseModel): - """노래 다운로드 응답 스키마 - - Usage: - GET /song/download/{task_id} - Polls for song completion and returns project info with song URL. - - Note: - 상태 값: - - processing: 노래 생성 진행 중 (song_result_url은 null) - - completed: 노래 생성 완료 (song_result_url 포함) - - failed: 노래 생성 실패 - - not_found: task_id에 해당하는 Song 없음 - - error: 조회 중 오류 발생 - - Example Response (Processing): - { - "success": true, - "status": "processing", - "message": "노래 생성이 진행 중입니다.", - "store_name": null, - "region": null, - "detail_region_info": null, - "task_id": "019123ab-cdef-7890-abcd-ef1234567890", - "language": null, - "song_result_url": null, - "created_at": null, - "error_message": null - } - - Example Response (Completed): - { - "success": true, - "status": "completed", - "message": "노래 다운로드가 완료되었습니다.", - "store_name": "스테이 머뭄", - "region": "군산", - "detail_region_info": "군산 신흥동 말랭이 마을", - "task_id": "019123ab-cdef-7890-abcd-ef1234567890", - "language": "Korean", - "song_result_url": "http://localhost:8000/media/2025-01-15/스테이머뭄.mp3", - "created_at": "2025-01-15T12:00:00", - "error_message": null - } - - Example Response (Not Found): - { - "success": false, - "status": "not_found", - "message": "task_id 'xxx'에 해당하는 Song을 찾을 수 없습니다.", - "store_name": null, - "region": null, - "detail_region_info": null, - "task_id": null, - "language": null, - "song_result_url": null, - "created_at": null, - "error_message": "Song not found" - } - """ - - success: bool = Field(..., description="다운로드 성공 여부") - status: str = Field(..., description="처리 상태 (processing, completed, failed, not_found, error)") - message: str = Field(..., description="응답 메시지") - store_name: Optional[str] = Field(None, description="업체명") - region: Optional[str] = Field(None, description="지역명") - detail_region_info: Optional[str] = Field(None, description="상세 지역 정보") - task_id: Optional[str] = Field(None, description="작업 고유 식별자") - language: Optional[str] = Field(None, description="언어") - song_result_url: Optional[str] = Field(None, description="노래 결과 URL") - created_at: Optional[datetime] = Field(None, description="생성 일시") - error_message: Optional[str] = Field(None, description="에러 메시지 (실패 시)") - - -# ============================================================================= -# Dataclass Schemas (Legacy) -# ============================================================================= - - -@dataclass -class StoreData: - id: int - created_at: datetime - store_name: str - store_category: str | None = None - store_region: str | None = None - store_address: str | None = None - store_phone_number: str | None = None - store_info: str | None = None - - -@dataclass -class AttributeData: - id: int - attr_category: str - attr_value: str - created_at: datetime - - -@dataclass -class SongSampleData: - id: int - ai: str - ai_model: str - sample_song: str - season: str | None = None - num_of_people: int | None = None - people_category: str | None = None - genre: str | None = None - - -@dataclass -class PromptTemplateData: - id: int - prompt: str - description: str | None = None - - -@dataclass -class SongFormData: - store_name: str - store_id: str - prompts: str - attributes: Dict[str, str] = field(default_factory=dict) - attributes_str: str = "" - lyrics_ids: List[int] = field(default_factory=list) - llm_model: str = "gpt-4o" - - @classmethod - async def from_form(cls, request: Request): - """Request의 form 데이터로부터 dataclass 인스턴스 생성""" - form_data = await request.form() - - # 고정 필드명들 - fixed_keys = {"store_info_name", "store_id", "llm_model", "prompts"} - - # lyrics-{id} 형태의 모든 키를 찾아서 ID 추출 - lyrics_ids = [] - attributes = {} - - for key, value in form_data.items(): - if key.startswith("lyrics-"): - lyrics_id = key.split("-")[1] - lyrics_ids.append(int(lyrics_id)) - elif key not in fixed_keys: - attributes[key] = value - - # attributes를 문자열로 변환 - attributes_str = ( - "\r\n\r\n".join([f"{key} : {value}" for key, value in attributes.items()]) - if attributes - else "" - ) - - return cls( - store_name=form_data.get("store_info_name", ""), - store_id=form_data.get("store_id", ""), - attributes=attributes, - attributes_str=attributes_str, - lyrics_ids=lyrics_ids, - llm_model=form_data.get("llm_model", "gpt-4o"), - prompts=form_data.get("prompts", ""), - ) +from dataclasses import dataclass, field +from datetime import datetime +from typing import Any, Dict, List, Optional + +from fastapi import Request +from pydantic import BaseModel, Field + + +# ============================================================================= +# Pydantic Schemas for Song Generation API +# ============================================================================= + + +class GenerateSongRequest(BaseModel): + """노래 생성 요청 스키마 + + Usage: + POST /song/generate/{task_id} + Request body for generating a song via Suno API. + + Example Request: + { + "lyrics": "인스타 감성의 스테이 머뭄...", + "genre": "k-pop", + "language": "Korean" + } + """ + + model_config = { + "json_schema_extra": { + "example": { + "lyrics": "인스타 감성의 스테이 머뭄, 머물러봐요 \n군산 신흥동 말랭이 마을의 마음 힐링 \n사진같은 하루, 여행의 시작 \n보석 같은 이곳은 감성 숙소의 느낌 \n\n인근 명소와 아름다움이 가득한 거리 \n힐링의 바람과 여행의 추억 \n글로벌 감성의 스테이 머뭄, 인스타 감성 \n사진으로 남기고 싶은 그 순간들이 되어줘요", + "genre": "k-pop", + "language": "Korean", + } + } + } + + lyrics: str = Field(..., description="노래에 사용할 가사") + genre: str = Field( + ..., + description="음악 장르 (K-Pop, Pop, R&B, Hip-Hop, Ballad, EDM, Rock, Jazz 등)", + ) + language: str = Field( + default="Korean", + description="노래 언어 (Korean, English, Chinese, Japanese, Thai, Vietnamese)", + ) + + +class GenerateSongResponse(BaseModel): + """노래 생성 응답 스키마 + + Usage: + POST /song/generate/{task_id} + Returns the task IDs for tracking song generation. + + Note: + 실패 조건: + - task_id에 해당하는 Project가 없는 경우 (404 HTTPException) + - task_id에 해당하는 Lyric이 없는 경우 (404 HTTPException) + - Suno API 호출 실패 + + Example Response (Success): + { + "success": true, + "task_id": "019123ab-cdef-7890-abcd-ef1234567890", + "suno_task_id": "abc123...", + "message": "노래 생성 요청이 접수되었습니다. suno_task_id로 상태를 조회하세요.", + "error_message": null + } + + Example Response (Failure): + { + "success": false, + "task_id": "019123ab-cdef-7890-abcd-ef1234567890", + "suno_task_id": null, + "message": "노래 생성 요청에 실패했습니다.", + "error_message": "Suno API connection error" + } + """ + + success: bool = Field(..., description="요청 성공 여부") + task_id: Optional[str] = Field(None, description="내부 작업 ID (Project/Lyric task_id)") + suno_task_id: Optional[str] = Field(None, description="Suno API 작업 ID") + message: str = Field(..., description="응답 메시지") + error_message: Optional[str] = Field(None, description="에러 메시지 (실패 시)") + + +class PollingSongRequest(BaseModel): + """노래 생성 상태 조회 요청 스키마 (Legacy) + + Note: + 현재 사용되지 않음. GET /song/status/{suno_task_id} 엔드포인트 사용. + + Example Request: + { + "task_id": "abc123..." + } + """ + + task_id: str = Field(..., description="Suno 작업 ID") + + +class SongClipData(BaseModel): + """생성된 노래 클립 정보""" + + id: Optional[str] = Field(None, description="클립 ID") + audio_url: Optional[str] = Field(None, description="오디오 URL") + stream_audio_url: Optional[str] = Field(None, description="스트리밍 오디오 URL") + image_url: Optional[str] = Field(None, description="이미지 URL") + title: Optional[str] = Field(None, description="곡 제목") + status: Optional[str] = Field(None, description="클립 상태") + duration: Optional[float] = Field(None, description="노래 길이 (초)") + + +class PollingSongResponse(BaseModel): + """노래 생성 상태 조회 응답 스키마 + + Usage: + GET /song/status/{suno_task_id} + Suno API 작업 상태를 조회합니다. + + Note: + 상태 값: + - PENDING: 대기 중 + - processing: 생성 중 + - SUCCESS / TEXT_SUCCESS / complete: 생성 완료 + - failed: 생성 실패 + - error: API 조회 오류 + + SUCCESS 상태 시: + - 백그라운드에서 MP3 파일 다운로드 시작 + - Song 테이블의 status를 completed로 업데이트 + - song_result_url에 로컬 파일 경로 저장 + + Example Response (Processing): + { + "success": true, + "status": "processing", + "message": "노래를 생성하고 있습니다.", + "clips": null, + "raw_response": {...}, + "error_message": null + } + + Example Response (Success): + { + "success": true, + "status": "SUCCESS", + "message": "노래 생성이 완료되었습니다.", + "clips": [ + { + "id": "clip-id", + "audio_url": "https://...", + "stream_audio_url": "https://...", + "image_url": "https://...", + "title": "Song Title", + "status": "complete", + "duration": 60.0 + } + ], + "raw_response": {...}, + "error_message": null + } + + Example Response (Failure): + { + "success": false, + "status": "error", + "message": "상태 조회에 실패했습니다.", + "clips": null, + "raw_response": null, + "error_message": "ConnectionError: ..." + } + """ + + success: bool = Field(..., description="조회 성공 여부") + status: Optional[str] = Field( + None, description="작업 상태 (PENDING, processing, SUCCESS, failed)" + ) + message: str = Field(..., description="상태 메시지") + clips: Optional[List[SongClipData]] = Field(None, description="생성된 노래 클립 목록") + raw_response: Optional[Dict[str, Any]] = Field(None, description="Suno API 원본 응답") + error_message: Optional[str] = Field(None, description="에러 메시지 (실패 시)") + + +class SongListItem(BaseModel): + """노래 목록 아이템 스키마 + + Usage: + GET /songs 응답의 개별 노래 정보 + + Example: + { + "store_name": "스테이 머뭄", + "region": "군산", + "task_id": "019123ab-cdef-7890-abcd-ef1234567890", + "language": "Korean", + "song_result_url": "http://localhost:8000/media/2025-01-15/스테이머뭄.mp3", + "created_at": "2025-01-15T12:00:00" + } + """ + + store_name: Optional[str] = Field(None, description="업체명") + region: Optional[str] = Field(None, description="지역명") + task_id: str = Field(..., description="작업 고유 식별자") + language: Optional[str] = Field(None, description="언어") + song_result_url: Optional[str] = Field(None, description="노래 결과 URL") + created_at: Optional[datetime] = Field(None, description="생성 일시") + + +class DownloadSongResponse(BaseModel): + """노래 다운로드 응답 스키마 + + Usage: + GET /song/download/{task_id} + Polls for song completion and returns project info with song URL. + + Note: + 상태 값: + - processing: 노래 생성 진행 중 (song_result_url은 null) + - completed: 노래 생성 완료 (song_result_url 포함) + - failed: 노래 생성 실패 + - not_found: task_id에 해당하는 Song 없음 + - error: 조회 중 오류 발생 + + Example Response (Processing): + { + "success": true, + "status": "processing", + "message": "노래 생성이 진행 중입니다.", + "store_name": null, + "region": null, + "detail_region_info": null, + "task_id": "019123ab-cdef-7890-abcd-ef1234567890", + "language": null, + "song_result_url": null, + "created_at": null, + "error_message": null + } + + Example Response (Completed): + { + "success": true, + "status": "completed", + "message": "노래 다운로드가 완료되었습니다.", + "store_name": "스테이 머뭄", + "region": "군산", + "detail_region_info": "군산 신흥동 말랭이 마을", + "task_id": "019123ab-cdef-7890-abcd-ef1234567890", + "language": "Korean", + "song_result_url": "http://localhost:8000/media/2025-01-15/스테이머뭄.mp3", + "created_at": "2025-01-15T12:00:00", + "error_message": null + } + + Example Response (Not Found): + { + "success": false, + "status": "not_found", + "message": "task_id 'xxx'에 해당하는 Song을 찾을 수 없습니다.", + "store_name": null, + "region": null, + "detail_region_info": null, + "task_id": null, + "language": null, + "song_result_url": null, + "created_at": null, + "error_message": "Song not found" + } + """ + + success: bool = Field(..., description="다운로드 성공 여부") + status: str = Field(..., description="처리 상태 (processing, completed, failed, not_found, error)") + message: str = Field(..., description="응답 메시지") + store_name: Optional[str] = Field(None, description="업체명") + region: Optional[str] = Field(None, description="지역명") + detail_region_info: Optional[str] = Field(None, description="상세 지역 정보") + task_id: Optional[str] = Field(None, description="작업 고유 식별자") + language: Optional[str] = Field(None, description="언어") + song_result_url: Optional[str] = Field(None, description="노래 결과 URL") + created_at: Optional[datetime] = Field(None, description="생성 일시") + error_message: Optional[str] = Field(None, description="에러 메시지 (실패 시)") + + +# ============================================================================= +# Dataclass Schemas (Legacy) +# ============================================================================= + + +@dataclass +class StoreData: + id: int + created_at: datetime + store_name: str + store_category: str | None = None + store_region: str | None = None + store_address: str | None = None + store_phone_number: str | None = None + store_info: str | None = None + + +@dataclass +class AttributeData: + id: int + attr_category: str + attr_value: str + created_at: datetime + + +@dataclass +class SongSampleData: + id: int + ai: str + ai_model: str + sample_song: str + season: str | None = None + num_of_people: int | None = None + people_category: str | None = None + genre: str | None = None + + +@dataclass +class PromptTemplateData: + id: int + prompt: str + description: str | None = None + + +@dataclass +class SongFormData: + store_name: str + store_id: str + prompts: str + attributes: Dict[str, str] = field(default_factory=dict) + attributes_str: str = "" + lyrics_ids: List[int] = field(default_factory=list) + llm_model: str = "gpt-5-mini" + + @classmethod + async def from_form(cls, request: Request): + """Request의 form 데이터로부터 dataclass 인스턴스 생성""" + form_data = await request.form() + + # 고정 필드명들 + fixed_keys = {"store_info_name", "store_id", "llm_model", "prompts"} + + # lyrics-{id} 형태의 모든 키를 찾아서 ID 추출 + lyrics_ids = [] + attributes = {} + + for key, value in form_data.items(): + if key.startswith("lyrics-"): + lyrics_id = key.split("-")[1] + lyrics_ids.append(int(lyrics_id)) + elif key not in fixed_keys: + attributes[key] = value + + # attributes를 문자열로 변환 + attributes_str = ( + "\r\n\r\n".join([f"{key} : {value}" for key, value in attributes.items()]) + if attributes + else "" + ) + + return cls( + store_name=form_data.get("store_info_name", ""), + store_id=form_data.get("store_id", ""), + attributes=attributes, + attributes_str=attributes_str, + lyrics_ids=lyrics_ids, + llm_model=form_data.get("llm_model", "gpt-5-mini"), + prompts=form_data.get("prompts", ""), + ) diff --git a/app/song/services/base.py b/app/song/services/base.py index 2a0b0a9..6a789a4 100644 --- a/app/song/services/base.py +++ b/app/song/services/base.py @@ -1,24 +1,24 @@ -from uuid import UUID -from sqlalchemy.ext.asyncio import AsyncSession -from sqlmodel import SQLModel - - -class BaseService: - def __init__(self, model, session: AsyncSession): - self.model = model - self.session = session - - async def _get(self, id: UUID): - return await self.session.get(self.model, id) - - async def _add(self, entity): - self.session.add(entity) - await self.session.commit() - await self.session.refresh(entity) - return entity - - async def _update(self, entity): - return await self._add(entity) - - async def _delete(self, entity): +from uuid import UUID +from sqlalchemy.ext.asyncio import AsyncSession +from sqlmodel import SQLModel + + +class BaseService: + def __init__(self, model, session: AsyncSession): + self.model = model + self.session = session + + async def _get(self, id: UUID): + return await self.session.get(self.model, id) + + async def _add(self, entity): + self.session.add(entity) + await self.session.commit() + await self.session.refresh(entity) + return entity + + async def _update(self, entity): + return await self._add(entity) + + async def _delete(self, entity): await self.session.delete(entity) \ No newline at end of file diff --git a/app/song/services/song.py b/app/song/services/song.py index 8dbdc3a..fd2c6c0 100644 --- a/app/song/services/song.py +++ b/app/song/services/song.py @@ -1,852 +1,852 @@ -import random -from typing import List - -from fastapi import Request, status -from fastapi.exceptions import HTTPException -from sqlalchemy import Connection, text -from sqlalchemy.exc import SQLAlchemyError - -from app.lyrics.schemas.lyrics_schema import ( - AttributeData, - PromptTemplateData, - SongFormData, - SongSampleData, - StoreData, -) -from app.utils.chatgpt_prompt import chatgpt_api - - -async def get_store_info(conn: Connection) -> List[StoreData]: - try: - query = """SELECT * FROM store_default_info;""" - result = await conn.execute(text(query)) - - all_store_info = [ - StoreData( - id=row[0], - store_info=row[1], - store_name=row[2], - store_category=row[3], - store_region=row[4], - store_address=row[5], - store_phone_number=row[6], - created_at=row[7], - ) - for row in result - ] - - result.close() - return all_store_info - except SQLAlchemyError as e: - print(e) - raise HTTPException( - status_code=status.HTTP_503_SERVICE_UNAVAILABLE, - detail="요청하신 서비스가 잠시 내부적으로 문제가 발생하였습니다.", - ) - except Exception as e: - print(e) - raise HTTPException( - status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, - detail="알수없는 이유로 서비스 오류가 발생하였습니다", - ) - - -async def get_attribute(conn: Connection) -> List[AttributeData]: - try: - query = """SELECT * FROM attribute;""" - result = await conn.execute(text(query)) - - all_attribute = [ - AttributeData( - id=row[0], - attr_category=row[1], - attr_value=row[2], - created_at=row[3], - ) - for row in result - ] - - result.close() - return all_attribute - except SQLAlchemyError as e: - print(e) - raise HTTPException( - status_code=status.HTTP_503_SERVICE_UNAVAILABLE, - detail="요청하신 서비스가 잠시 내부적으로 문제가 발생하였습니다.", - ) - except Exception as e: - print(e) - raise HTTPException( - status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, - detail="알수없는 이유로 서비스 오류가 발생하였습니다", - ) - - -async def get_attribute(conn: Connection) -> List[AttributeData]: - try: - query = """SELECT * FROM attribute;""" - result = await conn.execute(text(query)) - - all_attribute = [ - AttributeData( - id=row[0], - attr_category=row[1], - attr_value=row[2], - created_at=row[3], - ) - for row in result - ] - - result.close() - return all_attribute - except SQLAlchemyError as e: - print(e) - raise HTTPException( - status_code=status.HTTP_503_SERVICE_UNAVAILABLE, - detail="요청하신 서비스가 잠시 내부적으로 문제가 발생하였습니다.", - ) - except Exception as e: - print(e) - raise HTTPException( - status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, - detail="알수없는 이유로 서비스 오류가 발생하였습니다", - ) - - -async def get_sample_song(conn: Connection) -> List[SongSampleData]: - try: - query = """SELECT * FROM song_sample;""" - result = await conn.execute(text(query)) - - all_sample_song = [ - SongSampleData( - id=row[0], - ai=row[1], - ai_model=row[2], - genre=row[3], - sample_song=row[4], - ) - for row in result - ] - - result.close() - return all_sample_song - except SQLAlchemyError as e: - print(e) - raise HTTPException( - status_code=status.HTTP_503_SERVICE_UNAVAILABLE, - detail="요청하신 서비스가 잠시 내부적으로 문제가 발생하였습니다.", - ) - except Exception as e: - print(e) - raise HTTPException( - status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, - detail="알수없는 이유로 서비스 오류가 발생하였습니다", - ) - - -async def get_prompt_template(conn: Connection) -> List[PromptTemplateData]: - try: - query = """SELECT * FROM prompt_template;""" - result = await conn.execute(text(query)) - - all_prompt_template = [ - PromptTemplateData( - id=row[0], - description=row[1], - prompt=row[2], - ) - for row in result - ] - - result.close() - return all_prompt_template - except SQLAlchemyError as e: - print(e) - raise HTTPException( - status_code=status.HTTP_503_SERVICE_UNAVAILABLE, - detail="요청하신 서비스가 잠시 내부적으로 문제가 발생하였습니다.", - ) - except Exception as e: - print(e) - raise HTTPException( - status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, - detail="알수없는 이유로 서비스 오류가 발생하였습니다", - ) - - -async def get_song_result(conn: Connection) -> List[PromptTemplateData]: - try: - query = """SELECT * FROM prompt_template;""" - result = await conn.execute(text(query)) - - all_prompt_template = [ - PromptTemplateData( - id=row[0], - description=row[1], - prompt=row[2], - ) - for row in result - ] - - result.close() - return all_prompt_template - except SQLAlchemyError as e: - print(e) - raise HTTPException( - status_code=status.HTTP_503_SERVICE_UNAVAILABLE, - detail="요청하신 서비스가 잠시 내부적으로 문제가 발생하였습니다.", - ) - except Exception as e: - print(e) - raise HTTPException( - status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, - detail="알수없는 이유로 서비스 오류가 발생하였습니다", - ) - - -async def make_song_result(request: Request, conn: Connection): - try: - # 1. Form 데이터 파싱 - form_data = await SongFormData.from_form(request) - - print(f"\n{'=' * 60}") - print(f"Store ID: {form_data.store_id}") - print(f"Lyrics IDs: {form_data.lyrics_ids}") - print(f"Prompt IDs: {form_data.prompts}") - print(f"{'=' * 60}\n") - - # 2. Store 정보 조회 - store_query = """ - SELECT * FROM store_default_info WHERE id=:id; - """ - store_result = await conn.execute(text(store_query), {"id": form_data.store_id}) - - all_store_info = [ - StoreData( - id=row[0], - store_info=row[1], - store_name=row[2], - store_category=row[3], - store_region=row[4], - store_address=row[5], - store_phone_number=row[6], - created_at=row[7], - ) - for row in store_result - ] - - if not all_store_info: - raise HTTPException( - status_code=status.HTTP_404_NOT_FOUND, - detail=f"Store not found: {form_data.store_id}", - ) - - store_info = all_store_info[0] - print(f"Store: {store_info.store_name}") - - # 3. 속성 조회 -- 단계별 선택 프로세서시 구현 필요 없음 - - # 4. Sample Song 조회 및 결합 - combined_sample_song = None - - if form_data.lyrics_ids: - print(f"\n[샘플 가사 조회] - {len(form_data.lyrics_ids)}개") - - lyrics_query = """ - SELECT sample_song FROM song_sample - WHERE id IN :ids - ORDER BY created_at; - """ - lyrics_result = await conn.execute( - text(lyrics_query), {"ids": tuple(form_data.lyrics_ids)} - ) - - sample_songs = [ - row.sample_song for row in lyrics_result.fetchall() if row.sample_song - ] - - if sample_songs: - combined_sample_song = "\n\n".join( - [f"[샘플 {i + 1}]\n{song}" for i, song in enumerate(sample_songs)] - ) - print(f"{len(sample_songs)}개의 샘플 가사 조회 완료") - else: - print("샘플 가사가 비어있습니다") - else: - print("선택된 lyrics가 없습니다") - - # 5. 템플릿 가져오기 - if not form_data.prompts: - raise HTTPException( - status_code=status.HTTP_400_BAD_REQUEST, - detail="프롬프트 ID가 필요합니다", - ) - - print("템플릿 가져오기") - - prompts_query = """ - SELECT * FROM prompt_template WHERE id=:id; - """ - - # ✅ 수정: store_query → prompts_query - prompts_result = await conn.execute( - text(prompts_query), {"id": form_data.prompts} - ) - - prompts_info = [ - PromptTemplateData( - id=row[0], - description=row[1], - prompt=row[2], - ) - for row in prompts_result - ] - - if not prompts_info: - raise HTTPException( - status_code=status.HTTP_404_NOT_FOUND, - detail=f"Prompt not found: {form_data.prompts}", - ) - - prompt = prompts_info[0] - print(f"Prompt Template: {prompt.prompt}") - - # ✅ 6. 프롬프트 조합 - updated_prompt = prompt.prompt.replace("###", form_data.attributes_str).format( - name=store_info.store_name or "", - address=store_info.store_address or "", - category=store_info.store_category or "", - description=store_info.store_info or "", - ) - - updated_prompt += f""" - - 다음은 참고해야 하는 샘플 가사 정보입니다. - - 샘플 가사를 참고하여 작곡을 해주세요. - - {combined_sample_song} - """ - - print(f"\n[업데이트된 프롬프트]\n{updated_prompt}\n") - - # 7. 모델에게 요청 - generated_lyrics = await chatgpt_api.generate(prompt=updated_prompt) - - # 글자 수 계산 - total_chars_with_space = len(generated_lyrics) - total_chars_without_space = len( - generated_lyrics.replace(" ", "") - .replace("\n", "") - .replace("\r", "") - .replace("\t", "") - ) - - # final_lyrics 생성 - final_lyrics = f"""속성 {form_data.attributes_str} - 전체 글자 수 (공백 포함): {total_chars_with_space}자 - 전체 글자 수 (공백 제외): {total_chars_without_space}자\r\n\r\n{generated_lyrics}""" - - print("=" * 40) - print("[translate:form_data.attributes_str:] ", form_data.attributes_str) - print("[translate:total_chars_with_space:] ", total_chars_with_space) - print("[translate:total_chars_without_space:] ", total_chars_without_space) - print("[translate:final_lyrics:]") - print(final_lyrics) - print("=" * 40) - - # 8. DB 저장 - insert_query = """ - INSERT INTO song_results_all ( - store_info, store_name, store_category, store_address, store_phone_number, - description, prompt, attr_category, attr_value, - ai, ai_model, genre, - sample_song, result_song, created_at - ) VALUES ( - :store_info, :store_name, :store_category, :store_address, :store_phone_number, - :description, :prompt, :attr_category, :attr_value, - :ai, :ai_model, :genre, - :sample_song, :result_song, NOW() - ); - """ - - # ✅ attr_category, attr_value 추가 - insert_params = { - "store_info": store_info.store_info or "", - "store_name": store_info.store_name, - "store_category": store_info.store_category or "", - "store_address": store_info.store_address or "", - "store_phone_number": store_info.store_phone_number or "", - "description": store_info.store_info or "", - "prompt": form_data.prompts, - "attr_category": ", ".join(form_data.attributes.keys()) - if form_data.attributes - else "", - "attr_value": ", ".join(form_data.attributes.values()) - if form_data.attributes - else "", - "ai": "ChatGPT", - "ai_model": form_data.llm_model, - "genre": "후크송", - "sample_song": combined_sample_song or "없음", - "result_song": final_lyrics, - } - - await conn.execute(text(insert_query), insert_params) - await conn.commit() - - print("결과 저장 완료") - - print("\n전체 결과 조회 중...") - - # 9. 생성 결과 가져오기 (created_at 역순) - select_query = """ - SELECT * FROM song_results_all - ORDER BY created_at DESC; - """ - - all_results = await conn.execute(text(select_query)) - - results_list = [ - { - "id": row.id, - "store_info": row.store_info, - "store_name": row.store_name, - "store_category": row.store_category, - "store_address": row.store_address, - "store_phone_number": row.store_phone_number, - "description": row.description, - "prompt": row.prompt, - "attr_category": row.attr_category, - "attr_value": row.attr_value, - "ai": row.ai, - "ai_model": row.ai_model, - "genre": row.genre, - "sample_song": row.sample_song, - "result_song": row.result_song, - "created_at": row.created_at.isoformat() if row.created_at else None, - } - for row in all_results.fetchall() - ] - - print(f"전체 {len(results_list)}개의 결과 조회 완료\n") - - return results_list - - except HTTPException: - raise - except SQLAlchemyError as e: - print(f"Database Error: {e}") - import traceback - - traceback.print_exc() - raise HTTPException( - status_code=status.HTTP_503_SERVICE_UNAVAILABLE, - detail="데이터베이스 연결에 문제가 발생했습니다.", - ) - except Exception as e: - print(f"Unexpected Error: {e}") - import traceback - - traceback.print_exc() - raise HTTPException( - status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, - detail="서비스 처리 중 오류가 발생했습니다.", - ) - - -async def get_song_result(conn: Connection): # 반환 타입 수정 - try: - select_query = """ - SELECT * FROM song_results_all - ORDER BY created_at DESC; - """ - - all_results = await conn.execute(text(select_query)) - - results_list = [ - { - "id": row.id, - "store_info": row.store_info, - "store_name": row.store_name, - "store_category": row.store_category, - "store_address": row.store_address, - "store_phone_number": row.store_phone_number, - "description": row.description, - "prompt": row.prompt, - "attr_category": row.attr_category, - "attr_value": row.attr_value, - "ai": row.ai, - "ai_model": row.ai_model, - "season": row.season, - "num_of_people": row.num_of_people, - "people_category": row.people_category, - "genre": row.genre, - "sample_song": row.sample_song, - "result_song": row.result_song, - "created_at": row.created_at.isoformat() if row.created_at else None, - } - for row in all_results.fetchall() - ] - - print(f"전체 {len(results_list)}개의 결과 조회 완료\n") - - return results_list - except HTTPException: # HTTPException은 그대로 raise - raise - except SQLAlchemyError as e: - print(f"Database Error: {e}") - import traceback - - traceback.print_exc() - raise HTTPException( - status_code=status.HTTP_503_SERVICE_UNAVAILABLE, - detail="데이터베이스 연결에 문제가 발생했습니다.", - ) - except Exception as e: - print(f"Unexpected Error: {e}") - import traceback - - traceback.print_exc() - raise HTTPException( - status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, - detail="서비스 처리 중 오류가 발생했습니다.", - ) - - -async def make_automation(request: Request, conn: Connection): - try: - # 1. Form 데이터 파싱 - form_data = await SongFormData.from_form(request) - - print(f"\n{'=' * 60}") - print(f"Store ID: {form_data.store_id}") - print(f"{'=' * 60}\n") - - # 2. Store 정보 조회 - store_query = """ - SELECT * FROM store_default_info WHERE id=:id; - """ - store_result = await conn.execute(text(store_query), {"id": form_data.store_id}) - - all_store_info = [ - StoreData( - id=row[0], - store_info=row[1], - store_name=row[2], - store_category=row[3], - store_region=row[4], - store_address=row[5], - store_phone_number=row[6], - created_at=row[7], - ) - for row in store_result - ] - - if not all_store_info: - raise HTTPException( - status_code=status.HTTP_404_NOT_FOUND, - detail=f"Store not found: {form_data.store_id}", - ) - - store_info = all_store_info[0] - print(f"Store: {store_info.store_name}") - - # 3. 속성 조회 -- 단계별 선택 프로세서시 구현 필요 없음 - attribute_query = """ - SELECT * FROM attribute; - """ - - attribute_results = await conn.execute(text(attribute_query)) - - # 결과 가져오기 - attribute_rows = attribute_results.fetchall() - - formatted_attributes = "" - selected_categories = [] - selected_values = [] - - if attribute_rows: - attribute_list = [ - AttributeData( - id=row[0], - attr_category=row[1], - attr_value=row[2], - created_at=row[3], - ) - for row in attribute_rows - ] - - # ✅ 각 category에서 하나의 value만 랜덤 선택 - formatted_pairs = [] - for attr in attribute_list: - # 쉼표로 분리 및 공백 제거 - values = [v.strip() for v in attr.attr_value.split(",") if v.strip()] - - if values: - # 랜덤하게 하나만 선택 - selected_value = random.choice(values) - formatted_pairs.append(f"{attr.attr_category} : {selected_value}") - - # ✅ 선택된 category와 value 저장 - selected_categories.append(attr.attr_category) - selected_values.append(selected_value) - - # 최종 문자열 생성 - formatted_attributes = "\n".join(formatted_pairs) - - print(f"\n[포맷팅된 문자열 속성 정보]\n{formatted_attributes}\n") - else: - print("속성 데이터가 없습니다") - formatted_attributes = "" - - # 4. 템플릿 가져오기 - print("템플릿 가져오기 (ID=1)") - - prompts_query = """ - SELECT * FROM prompt_template WHERE id=1; - """ - - prompts_result = await conn.execute(text(prompts_query)) - - row = prompts_result.fetchone() - - if not row: - raise HTTPException( - status_code=status.HTTP_404_NOT_FOUND, - detail="Prompt ID 1 not found", - ) - - prompt = PromptTemplateData( - id=row[0], - description=row[1], - prompt=row[2], - ) - - print(f"Prompt Template: {prompt.prompt}") - - # 5. 템플릿 조합 - - updated_prompt = prompt.prompt.replace("###", formatted_attributes).format( - name=store_info.store_name or "", - address=store_info.store_address or "", - category=store_info.store_category or "", - description=store_info.store_info or "", - ) - - print("\n" + "=" * 80) - print("업데이트된 프롬프트") - print("=" * 80) - print(updated_prompt) - print("=" * 80 + "\n") - - # 4. Sample Song 조회 및 결합 - combined_sample_song = None - - if form_data.lyrics_ids: - print(f"\n[샘플 가사 조회] - {len(form_data.lyrics_ids)}개") - - lyrics_query = """ - SELECT sample_song FROM song_sample - WHERE id IN :ids - ORDER BY created_at; - """ - lyrics_result = await conn.execute( - text(lyrics_query), {"ids": tuple(form_data.lyrics_ids)} - ) - - sample_songs = [ - row.sample_song for row in lyrics_result.fetchall() if row.sample_song - ] - - if sample_songs: - combined_sample_song = "\n\n".join( - [f"[샘플 {i + 1}]\n{song}" for i, song in enumerate(sample_songs)] - ) - print(f"{len(sample_songs)}개의 샘플 가사 조회 완료") - else: - print("샘플 가사가 비어있습니다") - else: - print("선택된 lyrics가 없습니다") - - # 1. song_sample 테이블의 모든 ID 조회 - print("\n[샘플 가사 랜덤 선택]") - - all_ids_query = """ - SELECT id FROM song_sample; - """ - ids_result = await conn.execute(text(all_ids_query)) - all_ids = [row.id for row in ids_result.fetchall()] - - print(f"전체 샘플 가사 개수: {len(all_ids)}개") - - # 2. 랜덤하게 3개 선택 (또는 전체 개수가 3개 미만이면 전체) - combined_sample_song = None - - if all_ids: - # 3개 또는 전체 개수 중 작은 값 선택 - sample_count = min(3, len(all_ids)) - selected_ids = random.sample(all_ids, sample_count) - - print(f"랜덤 선택된 ID: {selected_ids}") - - # 3. 선택된 ID로 샘플 가사 조회 - lyrics_query = """ - SELECT sample_song FROM song_sample - WHERE id IN :ids - ORDER BY created_at; - """ - lyrics_result = await conn.execute( - text(lyrics_query), {"ids": tuple(selected_ids)} - ) - - sample_songs = [ - row.sample_song for row in lyrics_result.fetchall() if row.sample_song - ] - - # 4. combined_sample_song 생성 - if sample_songs: - combined_sample_song = "\n\n".join( - [f"[샘플 {i + 1}]\n{song}" for i, song in enumerate(sample_songs)] - ) - print(f"{len(sample_songs)}개의 샘플 가사 조회 완료") - else: - print("샘플 가사가 비어있습니다") - else: - print("song_sample 테이블에 데이터가 없습니다") - - # 5. 프롬프트에 샘플 가사 추가 - if combined_sample_song: - updated_prompt += f""" - - 다음은 참고해야 하는 샘플 가사 정보입니다. - - 샘플 가사를 참고하여 작곡을 해주세요. - - {combined_sample_song} - """ - print("샘플 가사 정보가 프롬프트에 추가되었습니다") - else: - print("샘플 가사가 없어 기본 프롬프트만 사용합니다") - - print(f"\n[최종 프롬프트 길이: {len(updated_prompt)} 자]\n") - - # 7. 모델에게 요청 - generated_lyrics = await chatgpt_api.generate(prompt=updated_prompt) - - # 글자 수 계산 - total_chars_with_space = len(generated_lyrics) - total_chars_without_space = len( - generated_lyrics.replace(" ", "") - .replace("\n", "") - .replace("\r", "") - .replace("\t", "") - ) - - # final_lyrics 생성 - final_lyrics = f"""속성 {formatted_attributes} - 전체 글자 수 (공백 포함): {total_chars_with_space}자 - 전체 글자 수 (공백 제외): {total_chars_without_space}자\r\n\r\n{generated_lyrics}""" - - # 8. DB 저장 - insert_query = """ - INSERT INTO song_results_all ( - store_info, store_name, store_category, store_address, store_phone_number, - description, prompt, attr_category, attr_value, - ai, ai_model, genre, - sample_song, result_song, created_at - ) VALUES ( - :store_info, :store_name, :store_category, :store_address, :store_phone_number, - :description, :prompt, :attr_category, :attr_value, - :ai, :ai_model, :genre, - :sample_song, :result_song, NOW() - ); - """ - print("\n[insert_params 선택된 속성 확인]") - print(f"Categories: {selected_categories}") - print(f"Values: {selected_values}") - print() - - # attr_category, attr_value - insert_params = { - "store_info": store_info.store_info or "", - "store_name": store_info.store_name, - "store_category": store_info.store_category or "", - "store_address": store_info.store_address or "", - "store_phone_number": store_info.store_phone_number or "", - "description": store_info.store_info or "", - "prompt": prompt.id, - # 랜덤 선택된 category와 value 사용 - "attr_category": ", ".join(selected_categories) - if selected_categories - else "", - "attr_value": ", ".join(selected_values) if selected_values else "", - "ai": "ChatGPT", - "ai_model": "gpt-4o", - "genre": "후크송", - "sample_song": combined_sample_song or "없음", - "result_song": final_lyrics, - } - - await conn.execute(text(insert_query), insert_params) - await conn.commit() - - print("결과 저장 완료") - - print("\n전체 결과 조회 중...") - - # 9. 생성 결과 가져오기 (created_at 역순) - select_query = """ - SELECT * FROM song_results_all - ORDER BY created_at DESC; - """ - - all_results = await conn.execute(text(select_query)) - - results_list = [ - { - "id": row.id, - "store_info": row.store_info, - "store_name": row.store_name, - "store_category": row.store_category, - "store_address": row.store_address, - "store_phone_number": row.store_phone_number, - "description": row.description, - "prompt": row.prompt, - "attr_category": row.attr_category, - "attr_value": row.attr_value, - "ai": row.ai, - "ai_model": row.ai_model, - "genre": row.genre, - "sample_song": row.sample_song, - "result_song": row.result_song, - "created_at": row.created_at.isoformat() if row.created_at else None, - } - for row in all_results.fetchall() - ] - - print(f"전체 {len(results_list)}개의 결과 조회 완료\n") - - return results_list - - except HTTPException: - raise - except SQLAlchemyError as e: - print(f"Database Error: {e}") - import traceback - - traceback.print_exc() - raise HTTPException( - status_code=status.HTTP_503_SERVICE_UNAVAILABLE, - detail="데이터베이스 연결에 문제가 발생했습니다.", - ) - except Exception as e: - print(f"Unexpected Error: {e}") - import traceback - - traceback.print_exc() - raise HTTPException( - status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, - detail="서비스 처리 중 오류가 발생했습니다.", - ) +import random +from typing import List + +from fastapi import Request, status +from fastapi.exceptions import HTTPException +from sqlalchemy import Connection, text +from sqlalchemy.exc import SQLAlchemyError + +from app.lyrics.schemas.lyrics_schema import ( + AttributeData, + PromptTemplateData, + SongFormData, + SongSampleData, + StoreData, +) +from app.utils.chatgpt_prompt import chatgpt_api + + +async def get_store_info(conn: Connection) -> List[StoreData]: + try: + query = """SELECT * FROM store_default_info;""" + result = await conn.execute(text(query)) + + all_store_info = [ + StoreData( + id=row[0], + store_info=row[1], + store_name=row[2], + store_category=row[3], + store_region=row[4], + store_address=row[5], + store_phone_number=row[6], + created_at=row[7], + ) + for row in result + ] + + result.close() + return all_store_info + except SQLAlchemyError as e: + print(e) + raise HTTPException( + status_code=status.HTTP_503_SERVICE_UNAVAILABLE, + detail="요청하신 서비스가 잠시 내부적으로 문제가 발생하였습니다.", + ) + except Exception as e: + print(e) + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="알수없는 이유로 서비스 오류가 발생하였습니다", + ) + + +async def get_attribute(conn: Connection) -> List[AttributeData]: + try: + query = """SELECT * FROM attribute;""" + result = await conn.execute(text(query)) + + all_attribute = [ + AttributeData( + id=row[0], + attr_category=row[1], + attr_value=row[2], + created_at=row[3], + ) + for row in result + ] + + result.close() + return all_attribute + except SQLAlchemyError as e: + print(e) + raise HTTPException( + status_code=status.HTTP_503_SERVICE_UNAVAILABLE, + detail="요청하신 서비스가 잠시 내부적으로 문제가 발생하였습니다.", + ) + except Exception as e: + print(e) + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="알수없는 이유로 서비스 오류가 발생하였습니다", + ) + + +async def get_attribute(conn: Connection) -> List[AttributeData]: + try: + query = """SELECT * FROM attribute;""" + result = await conn.execute(text(query)) + + all_attribute = [ + AttributeData( + id=row[0], + attr_category=row[1], + attr_value=row[2], + created_at=row[3], + ) + for row in result + ] + + result.close() + return all_attribute + except SQLAlchemyError as e: + print(e) + raise HTTPException( + status_code=status.HTTP_503_SERVICE_UNAVAILABLE, + detail="요청하신 서비스가 잠시 내부적으로 문제가 발생하였습니다.", + ) + except Exception as e: + print(e) + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="알수없는 이유로 서비스 오류가 발생하였습니다", + ) + + +async def get_sample_song(conn: Connection) -> List[SongSampleData]: + try: + query = """SELECT * FROM song_sample;""" + result = await conn.execute(text(query)) + + all_sample_song = [ + SongSampleData( + id=row[0], + ai=row[1], + ai_model=row[2], + genre=row[3], + sample_song=row[4], + ) + for row in result + ] + + result.close() + return all_sample_song + except SQLAlchemyError as e: + print(e) + raise HTTPException( + status_code=status.HTTP_503_SERVICE_UNAVAILABLE, + detail="요청하신 서비스가 잠시 내부적으로 문제가 발생하였습니다.", + ) + except Exception as e: + print(e) + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="알수없는 이유로 서비스 오류가 발생하였습니다", + ) + + +async def get_prompt_template(conn: Connection) -> List[PromptTemplateData]: + try: + query = """SELECT * FROM prompt_template;""" + result = await conn.execute(text(query)) + + all_prompt_template = [ + PromptTemplateData( + id=row[0], + description=row[1], + prompt=row[2], + ) + for row in result + ] + + result.close() + return all_prompt_template + except SQLAlchemyError as e: + print(e) + raise HTTPException( + status_code=status.HTTP_503_SERVICE_UNAVAILABLE, + detail="요청하신 서비스가 잠시 내부적으로 문제가 발생하였습니다.", + ) + except Exception as e: + print(e) + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="알수없는 이유로 서비스 오류가 발생하였습니다", + ) + + +async def get_song_result(conn: Connection) -> List[PromptTemplateData]: + try: + query = """SELECT * FROM prompt_template;""" + result = await conn.execute(text(query)) + + all_prompt_template = [ + PromptTemplateData( + id=row[0], + description=row[1], + prompt=row[2], + ) + for row in result + ] + + result.close() + return all_prompt_template + except SQLAlchemyError as e: + print(e) + raise HTTPException( + status_code=status.HTTP_503_SERVICE_UNAVAILABLE, + detail="요청하신 서비스가 잠시 내부적으로 문제가 발생하였습니다.", + ) + except Exception as e: + print(e) + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="알수없는 이유로 서비스 오류가 발생하였습니다", + ) + + +async def make_song_result(request: Request, conn: Connection): + try: + # 1. Form 데이터 파싱 + form_data = await SongFormData.from_form(request) + + print(f"\n{'=' * 60}") + print(f"Store ID: {form_data.store_id}") + print(f"Lyrics IDs: {form_data.lyrics_ids}") + print(f"Prompt IDs: {form_data.prompts}") + print(f"{'=' * 60}\n") + + # 2. Store 정보 조회 + store_query = """ + SELECT * FROM store_default_info WHERE id=:id; + """ + store_result = await conn.execute(text(store_query), {"id": form_data.store_id}) + + all_store_info = [ + StoreData( + id=row[0], + store_info=row[1], + store_name=row[2], + store_category=row[3], + store_region=row[4], + store_address=row[5], + store_phone_number=row[6], + created_at=row[7], + ) + for row in store_result + ] + + if not all_store_info: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=f"Store not found: {form_data.store_id}", + ) + + store_info = all_store_info[0] + print(f"Store: {store_info.store_name}") + + # 3. 속성 조회 -- 단계별 선택 프로세서시 구현 필요 없음 + + # 4. Sample Song 조회 및 결합 + combined_sample_song = None + + if form_data.lyrics_ids: + print(f"\n[샘플 가사 조회] - {len(form_data.lyrics_ids)}개") + + lyrics_query = """ + SELECT sample_song FROM song_sample + WHERE id IN :ids + ORDER BY created_at; + """ + lyrics_result = await conn.execute( + text(lyrics_query), {"ids": tuple(form_data.lyrics_ids)} + ) + + sample_songs = [ + row.sample_song for row in lyrics_result.fetchall() if row.sample_song + ] + + if sample_songs: + combined_sample_song = "\n\n".join( + [f"[샘플 {i + 1}]\n{song}" for i, song in enumerate(sample_songs)] + ) + print(f"{len(sample_songs)}개의 샘플 가사 조회 완료") + else: + print("샘플 가사가 비어있습니다") + else: + print("선택된 lyrics가 없습니다") + + # 5. 템플릿 가져오기 + if not form_data.prompts: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail="프롬프트 ID가 필요합니다", + ) + + print("템플릿 가져오기") + + prompts_query = """ + SELECT * FROM prompt_template WHERE id=:id; + """ + + # ✅ 수정: store_query → prompts_query + prompts_result = await conn.execute( + text(prompts_query), {"id": form_data.prompts} + ) + + prompts_info = [ + PromptTemplateData( + id=row[0], + description=row[1], + prompt=row[2], + ) + for row in prompts_result + ] + + if not prompts_info: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=f"Prompt not found: {form_data.prompts}", + ) + + prompt = prompts_info[0] + print(f"Prompt Template: {prompt.prompt}") + + # ✅ 6. 프롬프트 조합 + updated_prompt = prompt.prompt.replace("###", form_data.attributes_str).format( + name=store_info.store_name or "", + address=store_info.store_address or "", + category=store_info.store_category or "", + description=store_info.store_info or "", + ) + + updated_prompt += f""" + + 다음은 참고해야 하는 샘플 가사 정보입니다. + + 샘플 가사를 참고하여 작곡을 해주세요. + + {combined_sample_song} + """ + + print(f"\n[업데이트된 프롬프트]\n{updated_prompt}\n") + + # 7. 모델에게 요청 + generated_lyrics = await chatgpt_api.generate(prompt=updated_prompt) + + # 글자 수 계산 + total_chars_with_space = len(generated_lyrics) + total_chars_without_space = len( + generated_lyrics.replace(" ", "") + .replace("\n", "") + .replace("\r", "") + .replace("\t", "") + ) + + # final_lyrics 생성 + final_lyrics = f"""속성 {form_data.attributes_str} + 전체 글자 수 (공백 포함): {total_chars_with_space}자 + 전체 글자 수 (공백 제외): {total_chars_without_space}자\r\n\r\n{generated_lyrics}""" + + print("=" * 40) + print("[translate:form_data.attributes_str:] ", form_data.attributes_str) + print("[translate:total_chars_with_space:] ", total_chars_with_space) + print("[translate:total_chars_without_space:] ", total_chars_without_space) + print("[translate:final_lyrics:]") + print(final_lyrics) + print("=" * 40) + + # 8. DB 저장 + insert_query = """ + INSERT INTO song_results_all ( + store_info, store_name, store_category, store_address, store_phone_number, + description, prompt, attr_category, attr_value, + ai, ai_model, genre, + sample_song, result_song, created_at + ) VALUES ( + :store_info, :store_name, :store_category, :store_address, :store_phone_number, + :description, :prompt, :attr_category, :attr_value, + :ai, :ai_model, :genre, + :sample_song, :result_song, NOW() + ); + """ + + # ✅ attr_category, attr_value 추가 + insert_params = { + "store_info": store_info.store_info or "", + "store_name": store_info.store_name, + "store_category": store_info.store_category or "", + "store_address": store_info.store_address or "", + "store_phone_number": store_info.store_phone_number or "", + "description": store_info.store_info or "", + "prompt": form_data.prompts, + "attr_category": ", ".join(form_data.attributes.keys()) + if form_data.attributes + else "", + "attr_value": ", ".join(form_data.attributes.values()) + if form_data.attributes + else "", + "ai": "ChatGPT", + "ai_model": form_data.llm_model, + "genre": "후크송", + "sample_song": combined_sample_song or "없음", + "result_song": final_lyrics, + } + + await conn.execute(text(insert_query), insert_params) + await conn.commit() + + print("결과 저장 완료") + + print("\n전체 결과 조회 중...") + + # 9. 생성 결과 가져오기 (created_at 역순) + select_query = """ + SELECT * FROM song_results_all + ORDER BY created_at DESC; + """ + + all_results = await conn.execute(text(select_query)) + + results_list = [ + { + "id": row.id, + "store_info": row.store_info, + "store_name": row.store_name, + "store_category": row.store_category, + "store_address": row.store_address, + "store_phone_number": row.store_phone_number, + "description": row.description, + "prompt": row.prompt, + "attr_category": row.attr_category, + "attr_value": row.attr_value, + "ai": row.ai, + "ai_model": row.ai_model, + "genre": row.genre, + "sample_song": row.sample_song, + "result_song": row.result_song, + "created_at": row.created_at.isoformat() if row.created_at else None, + } + for row in all_results.fetchall() + ] + + print(f"전체 {len(results_list)}개의 결과 조회 완료\n") + + return results_list + + except HTTPException: + raise + except SQLAlchemyError as e: + print(f"Database Error: {e}") + import traceback + + traceback.print_exc() + raise HTTPException( + status_code=status.HTTP_503_SERVICE_UNAVAILABLE, + detail="데이터베이스 연결에 문제가 발생했습니다.", + ) + except Exception as e: + print(f"Unexpected Error: {e}") + import traceback + + traceback.print_exc() + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="서비스 처리 중 오류가 발생했습니다.", + ) + + +async def get_song_result(conn: Connection): # 반환 타입 수정 + try: + select_query = """ + SELECT * FROM song_results_all + ORDER BY created_at DESC; + """ + + all_results = await conn.execute(text(select_query)) + + results_list = [ + { + "id": row.id, + "store_info": row.store_info, + "store_name": row.store_name, + "store_category": row.store_category, + "store_address": row.store_address, + "store_phone_number": row.store_phone_number, + "description": row.description, + "prompt": row.prompt, + "attr_category": row.attr_category, + "attr_value": row.attr_value, + "ai": row.ai, + "ai_model": row.ai_model, + "season": row.season, + "num_of_people": row.num_of_people, + "people_category": row.people_category, + "genre": row.genre, + "sample_song": row.sample_song, + "result_song": row.result_song, + "created_at": row.created_at.isoformat() if row.created_at else None, + } + for row in all_results.fetchall() + ] + + print(f"전체 {len(results_list)}개의 결과 조회 완료\n") + + return results_list + except HTTPException: # HTTPException은 그대로 raise + raise + except SQLAlchemyError as e: + print(f"Database Error: {e}") + import traceback + + traceback.print_exc() + raise HTTPException( + status_code=status.HTTP_503_SERVICE_UNAVAILABLE, + detail="데이터베이스 연결에 문제가 발생했습니다.", + ) + except Exception as e: + print(f"Unexpected Error: {e}") + import traceback + + traceback.print_exc() + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="서비스 처리 중 오류가 발생했습니다.", + ) + + +async def make_automation(request: Request, conn: Connection): + try: + # 1. Form 데이터 파싱 + form_data = await SongFormData.from_form(request) + + print(f"\n{'=' * 60}") + print(f"Store ID: {form_data.store_id}") + print(f"{'=' * 60}\n") + + # 2. Store 정보 조회 + store_query = """ + SELECT * FROM store_default_info WHERE id=:id; + """ + store_result = await conn.execute(text(store_query), {"id": form_data.store_id}) + + all_store_info = [ + StoreData( + id=row[0], + store_info=row[1], + store_name=row[2], + store_category=row[3], + store_region=row[4], + store_address=row[5], + store_phone_number=row[6], + created_at=row[7], + ) + for row in store_result + ] + + if not all_store_info: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=f"Store not found: {form_data.store_id}", + ) + + store_info = all_store_info[0] + print(f"Store: {store_info.store_name}") + + # 3. 속성 조회 -- 단계별 선택 프로세서시 구현 필요 없음 + attribute_query = """ + SELECT * FROM attribute; + """ + + attribute_results = await conn.execute(text(attribute_query)) + + # 결과 가져오기 + attribute_rows = attribute_results.fetchall() + + formatted_attributes = "" + selected_categories = [] + selected_values = [] + + if attribute_rows: + attribute_list = [ + AttributeData( + id=row[0], + attr_category=row[1], + attr_value=row[2], + created_at=row[3], + ) + for row in attribute_rows + ] + + # ✅ 각 category에서 하나의 value만 랜덤 선택 + formatted_pairs = [] + for attr in attribute_list: + # 쉼표로 분리 및 공백 제거 + values = [v.strip() for v in attr.attr_value.split(",") if v.strip()] + + if values: + # 랜덤하게 하나만 선택 + selected_value = random.choice(values) + formatted_pairs.append(f"{attr.attr_category} : {selected_value}") + + # ✅ 선택된 category와 value 저장 + selected_categories.append(attr.attr_category) + selected_values.append(selected_value) + + # 최종 문자열 생성 + formatted_attributes = "\n".join(formatted_pairs) + + print(f"\n[포맷팅된 문자열 속성 정보]\n{formatted_attributes}\n") + else: + print("속성 데이터가 없습니다") + formatted_attributes = "" + + # 4. 템플릿 가져오기 + print("템플릿 가져오기 (ID=1)") + + prompts_query = """ + SELECT * FROM prompt_template WHERE id=1; + """ + + prompts_result = await conn.execute(text(prompts_query)) + + row = prompts_result.fetchone() + + if not row: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="Prompt ID 1 not found", + ) + + prompt = PromptTemplateData( + id=row[0], + description=row[1], + prompt=row[2], + ) + + print(f"Prompt Template: {prompt.prompt}") + + # 5. 템플릿 조합 + + updated_prompt = prompt.prompt.replace("###", formatted_attributes).format( + name=store_info.store_name or "", + address=store_info.store_address or "", + category=store_info.store_category or "", + description=store_info.store_info or "", + ) + + print("\n" + "=" * 80) + print("업데이트된 프롬프트") + print("=" * 80) + print(updated_prompt) + print("=" * 80 + "\n") + + # 4. Sample Song 조회 및 결합 + combined_sample_song = None + + if form_data.lyrics_ids: + print(f"\n[샘플 가사 조회] - {len(form_data.lyrics_ids)}개") + + lyrics_query = """ + SELECT sample_song FROM song_sample + WHERE id IN :ids + ORDER BY created_at; + """ + lyrics_result = await conn.execute( + text(lyrics_query), {"ids": tuple(form_data.lyrics_ids)} + ) + + sample_songs = [ + row.sample_song for row in lyrics_result.fetchall() if row.sample_song + ] + + if sample_songs: + combined_sample_song = "\n\n".join( + [f"[샘플 {i + 1}]\n{song}" for i, song in enumerate(sample_songs)] + ) + print(f"{len(sample_songs)}개의 샘플 가사 조회 완료") + else: + print("샘플 가사가 비어있습니다") + else: + print("선택된 lyrics가 없습니다") + + # 1. song_sample 테이블의 모든 ID 조회 + print("\n[샘플 가사 랜덤 선택]") + + all_ids_query = """ + SELECT id FROM song_sample; + """ + ids_result = await conn.execute(text(all_ids_query)) + all_ids = [row.id for row in ids_result.fetchall()] + + print(f"전체 샘플 가사 개수: {len(all_ids)}개") + + # 2. 랜덤하게 3개 선택 (또는 전체 개수가 3개 미만이면 전체) + combined_sample_song = None + + if all_ids: + # 3개 또는 전체 개수 중 작은 값 선택 + sample_count = min(3, len(all_ids)) + selected_ids = random.sample(all_ids, sample_count) + + print(f"랜덤 선택된 ID: {selected_ids}") + + # 3. 선택된 ID로 샘플 가사 조회 + lyrics_query = """ + SELECT sample_song FROM song_sample + WHERE id IN :ids + ORDER BY created_at; + """ + lyrics_result = await conn.execute( + text(lyrics_query), {"ids": tuple(selected_ids)} + ) + + sample_songs = [ + row.sample_song for row in lyrics_result.fetchall() if row.sample_song + ] + + # 4. combined_sample_song 생성 + if sample_songs: + combined_sample_song = "\n\n".join( + [f"[샘플 {i + 1}]\n{song}" for i, song in enumerate(sample_songs)] + ) + print(f"{len(sample_songs)}개의 샘플 가사 조회 완료") + else: + print("샘플 가사가 비어있습니다") + else: + print("song_sample 테이블에 데이터가 없습니다") + + # 5. 프롬프트에 샘플 가사 추가 + if combined_sample_song: + updated_prompt += f""" + + 다음은 참고해야 하는 샘플 가사 정보입니다. + + 샘플 가사를 참고하여 작곡을 해주세요. + + {combined_sample_song} + """ + print("샘플 가사 정보가 프롬프트에 추가되었습니다") + else: + print("샘플 가사가 없어 기본 프롬프트만 사용합니다") + + print(f"\n[최종 프롬프트 길이: {len(updated_prompt)} 자]\n") + + # 7. 모델에게 요청 + generated_lyrics = await chatgpt_api.generate(prompt=updated_prompt) + + # 글자 수 계산 + total_chars_with_space = len(generated_lyrics) + total_chars_without_space = len( + generated_lyrics.replace(" ", "") + .replace("\n", "") + .replace("\r", "") + .replace("\t", "") + ) + + # final_lyrics 생성 + final_lyrics = f"""속성 {formatted_attributes} + 전체 글자 수 (공백 포함): {total_chars_with_space}자 + 전체 글자 수 (공백 제외): {total_chars_without_space}자\r\n\r\n{generated_lyrics}""" + + # 8. DB 저장 + insert_query = """ + INSERT INTO song_results_all ( + store_info, store_name, store_category, store_address, store_phone_number, + description, prompt, attr_category, attr_value, + ai, ai_model, genre, + sample_song, result_song, created_at + ) VALUES ( + :store_info, :store_name, :store_category, :store_address, :store_phone_number, + :description, :prompt, :attr_category, :attr_value, + :ai, :ai_model, :genre, + :sample_song, :result_song, NOW() + ); + """ + print("\n[insert_params 선택된 속성 확인]") + print(f"Categories: {selected_categories}") + print(f"Values: {selected_values}") + print() + + # attr_category, attr_value + insert_params = { + "store_info": store_info.store_info or "", + "store_name": store_info.store_name, + "store_category": store_info.store_category or "", + "store_address": store_info.store_address or "", + "store_phone_number": store_info.store_phone_number or "", + "description": store_info.store_info or "", + "prompt": prompt.id, + # 랜덤 선택된 category와 value 사용 + "attr_category": ", ".join(selected_categories) + if selected_categories + else "", + "attr_value": ", ".join(selected_values) if selected_values else "", + "ai": "ChatGPT", + "ai_model": "gpt-5-mini", + "genre": "후크송", + "sample_song": combined_sample_song or "없음", + "result_song": final_lyrics, + } + + await conn.execute(text(insert_query), insert_params) + await conn.commit() + + print("결과 저장 완료") + + print("\n전체 결과 조회 중...") + + # 9. 생성 결과 가져오기 (created_at 역순) + select_query = """ + SELECT * FROM song_results_all + ORDER BY created_at DESC; + """ + + all_results = await conn.execute(text(select_query)) + + results_list = [ + { + "id": row.id, + "store_info": row.store_info, + "store_name": row.store_name, + "store_category": row.store_category, + "store_address": row.store_address, + "store_phone_number": row.store_phone_number, + "description": row.description, + "prompt": row.prompt, + "attr_category": row.attr_category, + "attr_value": row.attr_value, + "ai": row.ai, + "ai_model": row.ai_model, + "genre": row.genre, + "sample_song": row.sample_song, + "result_song": row.result_song, + "created_at": row.created_at.isoformat() if row.created_at else None, + } + for row in all_results.fetchall() + ] + + print(f"전체 {len(results_list)}개의 결과 조회 완료\n") + + return results_list + + except HTTPException: + raise + except SQLAlchemyError as e: + print(f"Database Error: {e}") + import traceback + + traceback.print_exc() + raise HTTPException( + status_code=status.HTTP_503_SERVICE_UNAVAILABLE, + detail="데이터베이스 연결에 문제가 발생했습니다.", + ) + except Exception as e: + print(f"Unexpected Error: {e}") + import traceback + + traceback.print_exc() + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="서비스 처리 중 오류가 발생했습니다.", + ) diff --git a/app/song/worker/song_task.py b/app/song/worker/song_task.py index 51bac53..ec663e9 100644 --- a/app/song/worker/song_task.py +++ b/app/song/worker/song_task.py @@ -1,333 +1,419 @@ -""" -Song Background Tasks - -노래 생성 관련 백그라운드 태스크를 정의합니다. -""" - -from datetime import date -from pathlib import Path - -import aiofiles -import httpx -from sqlalchemy import select - -from app.database.session import BackgroundSessionLocal -from app.song.models import Song -from app.utils.common import generate_task_id -from app.utils.upload_blob_as_request import AzureBlobUploader -from config import prj_settings - - -async def download_and_save_song( - task_id: str, - audio_url: str, - store_name: str, -) -> None: - """백그라운드에서 노래를 다운로드하고 Song 테이블을 업데이트합니다. - - Args: - task_id: 프로젝트 task_id - audio_url: 다운로드할 오디오 URL - store_name: 저장할 파일명에 사용할 업체명 - """ - print(f"[download_and_save_song] START - task_id: {task_id}, store_name: {store_name}") - try: - # 저장 경로 생성: media/song/{날짜}/{uuid7}/{store_name}.mp3 - today = date.today().strftime("%Y-%m-%d") - unique_id = await generate_task_id() - # 파일명에 사용할 수 없는 문자 제거 - safe_store_name = "".join( - c for c in store_name if c.isalnum() or c in (" ", "_", "-") - ).strip() - safe_store_name = safe_store_name or "song" - file_name = f"{safe_store_name}.mp3" - - # 절대 경로 생성 - media_dir = Path("media") / "song" / today / unique_id - media_dir.mkdir(parents=True, exist_ok=True) - file_path = media_dir / file_name - print(f"[download_and_save_song] Directory created - path: {file_path}") - - # 오디오 파일 다운로드 - print(f"[download_and_save_song] Downloading audio - task_id: {task_id}, url: {audio_url}") - async with httpx.AsyncClient() as client: - response = await client.get(audio_url, timeout=60.0) - response.raise_for_status() - - async with aiofiles.open(str(file_path), "wb") as f: - await f.write(response.content) - print(f"[download_and_save_song] File saved - task_id: {task_id}, path: {file_path}") - - # 프론트엔드에서 접근 가능한 URL 생성 - relative_path = f"/media/song/{today}/{unique_id}/{file_name}" - base_url = f"http://{prj_settings.PROJECT_DOMAIN}" - file_url = f"{base_url}{relative_path}" - print(f"[download_and_save_song] URL generated - task_id: {task_id}, url: {file_url}") - - # Song 테이블 업데이트 (새 세션 사용) - async with BackgroundSessionLocal() as session: - # 여러 개 있을 경우 가장 최근 것 선택 - result = await session.execute( - select(Song) - .where(Song.task_id == task_id) - .order_by(Song.created_at.desc()) - .limit(1) - ) - song = result.scalar_one_or_none() - - if song: - song.status = "completed" - song.song_result_url = file_url - await session.commit() - print(f"[download_and_save_song] SUCCESS - task_id: {task_id}, status: completed") - else: - print(f"[download_and_save_song] Song NOT FOUND in DB - task_id: {task_id}") - - except Exception as e: - print(f"[download_and_save_song] EXCEPTION - task_id: {task_id}, error: {e}") - # 실패 시 Song 테이블 업데이트 - async with BackgroundSessionLocal() as session: - # 여러 개 있을 경우 가장 최근 것 선택 - result = await session.execute( - select(Song) - .where(Song.task_id == task_id) - .order_by(Song.created_at.desc()) - .limit(1) - ) - song = result.scalar_one_or_none() - - if song: - song.status = "failed" - await session.commit() - print(f"[download_and_save_song] FAILED - task_id: {task_id}, status updated to failed") - - -async def download_and_upload_song_to_blob( - task_id: str, - audio_url: str, - store_name: str, -) -> None: - """백그라운드에서 노래를 다운로드하고 Azure Blob Storage에 업로드한 뒤 Song 테이블을 업데이트합니다. - - Args: - task_id: 프로젝트 task_id - audio_url: 다운로드할 오디오 URL - store_name: 저장할 파일명에 사용할 업체명 - """ - print(f"[download_and_upload_song_to_blob] START - task_id: {task_id}, store_name: {store_name}") - temp_file_path: Path | None = None - - try: - # 파일명에 사용할 수 없는 문자 제거 - safe_store_name = "".join( - c for c in store_name if c.isalnum() or c in (" ", "_", "-") - ).strip() - safe_store_name = safe_store_name or "song" - file_name = f"{safe_store_name}.mp3" - - # 임시 저장 경로 생성 - temp_dir = Path("media") / "temp" / task_id - temp_dir.mkdir(parents=True, exist_ok=True) - temp_file_path = temp_dir / file_name - print(f"[download_and_upload_song_to_blob] Temp directory created - path: {temp_file_path}") - - # 오디오 파일 다운로드 - print(f"[download_and_upload_song_to_blob] Downloading audio - task_id: {task_id}, url: {audio_url}") - async with httpx.AsyncClient() as client: - response = await client.get(audio_url, timeout=60.0) - response.raise_for_status() - - async with aiofiles.open(str(temp_file_path), "wb") as f: - await f.write(response.content) - print(f"[download_and_upload_song_to_blob] File downloaded - task_id: {task_id}, path: {temp_file_path}") - - # Azure Blob Storage에 업로드 - uploader = AzureBlobUploader(task_id=task_id) - upload_success = await uploader.upload_music(file_path=str(temp_file_path)) - - if not upload_success: - raise Exception("Azure Blob Storage 업로드 실패") - - # SAS 토큰이 제외된 public_url 사용 - blob_url = uploader.public_url - print(f"[download_and_upload_song_to_blob] Uploaded to Blob - task_id: {task_id}, url: {blob_url}") - - # Song 테이블 업데이트 (새 세션 사용) - async with BackgroundSessionLocal() as session: - # 여러 개 있을 경우 가장 최근 것 선택 - result = await session.execute( - select(Song) - .where(Song.task_id == task_id) - .order_by(Song.created_at.desc()) - .limit(1) - ) - song = result.scalar_one_or_none() - - if song: - song.status = "completed" - song.song_result_url = blob_url - await session.commit() - print(f"[download_and_upload_song_to_blob] SUCCESS - task_id: {task_id}, status: completed") - else: - print(f"[download_and_upload_song_to_blob] Song NOT FOUND in DB - task_id: {task_id}") - - except Exception as e: - print(f"[download_and_upload_song_to_blob] EXCEPTION - task_id: {task_id}, error: {e}") - # 실패 시 Song 테이블 업데이트 - async with BackgroundSessionLocal() as session: - result = await session.execute( - select(Song) - .where(Song.task_id == task_id) - .order_by(Song.created_at.desc()) - .limit(1) - ) - song = result.scalar_one_or_none() - - if song: - song.status = "failed" - await session.commit() - print(f"[download_and_upload_song_to_blob] FAILED - task_id: {task_id}, status updated to failed") - - finally: - # 임시 파일 삭제 - if temp_file_path and temp_file_path.exists(): - try: - temp_file_path.unlink() - print(f"[download_and_upload_song_to_blob] Temp file deleted - path: {temp_file_path}") - except Exception as e: - print(f"[download_and_upload_song_to_blob] Failed to delete temp file: {e}") - - # 임시 디렉토리 삭제 시도 - temp_dir = Path("media") / "temp" / task_id - if temp_dir.exists(): - try: - temp_dir.rmdir() - except Exception: - pass # 디렉토리가 비어있지 않으면 무시 - - -async def download_and_upload_song_by_suno_task_id( - suno_task_id: str, - audio_url: str, - store_name: str, - duration: float | None = None, -) -> None: - """suno_task_id로 Song을 조회하여 노래를 다운로드하고 Azure Blob Storage에 업로드한 뒤 Song 테이블을 업데이트합니다. - - Args: - suno_task_id: Suno API 작업 ID - audio_url: 다운로드할 오디오 URL - store_name: 저장할 파일명에 사용할 업체명 - duration: 노래 재생 시간 (초) - """ - print(f"[download_and_upload_song_by_suno_task_id] START - suno_task_id: {suno_task_id}, store_name: {store_name}, duration: {duration}") - temp_file_path: Path | None = None - task_id: str | None = None - - try: - # suno_task_id로 Song 조회하여 task_id 가져오기 - async with BackgroundSessionLocal() as session: - result = await session.execute( - select(Song) - .where(Song.suno_task_id == suno_task_id) - .order_by(Song.created_at.desc()) - .limit(1) - ) - song = result.scalar_one_or_none() - - if not song: - print(f"[download_and_upload_song_by_suno_task_id] Song NOT FOUND - suno_task_id: {suno_task_id}") - return - - task_id = song.task_id - print(f"[download_and_upload_song_by_suno_task_id] Song found - suno_task_id: {suno_task_id}, task_id: {task_id}") - - # 파일명에 사용할 수 없는 문자 제거 - safe_store_name = "".join( - c for c in store_name if c.isalnum() or c in (" ", "_", "-") - ).strip() - safe_store_name = safe_store_name or "song" - file_name = f"{safe_store_name}.mp3" - - # 임시 저장 경로 생성 - temp_dir = Path("media") / "temp" / task_id - temp_dir.mkdir(parents=True, exist_ok=True) - temp_file_path = temp_dir / file_name - print(f"[download_and_upload_song_by_suno_task_id] Temp directory created - path: {temp_file_path}") - - # 오디오 파일 다운로드 - print(f"[download_and_upload_song_by_suno_task_id] Downloading audio - suno_task_id: {suno_task_id}, url: {audio_url}") - async with httpx.AsyncClient() as client: - response = await client.get(audio_url, timeout=60.0) - response.raise_for_status() - - async with aiofiles.open(str(temp_file_path), "wb") as f: - await f.write(response.content) - print(f"[download_and_upload_song_by_suno_task_id] File downloaded - suno_task_id: {suno_task_id}, path: {temp_file_path}") - - # Azure Blob Storage에 업로드 - uploader = AzureBlobUploader(task_id=task_id) - upload_success = await uploader.upload_music(file_path=str(temp_file_path)) - - if not upload_success: - raise Exception("Azure Blob Storage 업로드 실패") - - # SAS 토큰이 제외된 public_url 사용 - blob_url = uploader.public_url - print(f"[download_and_upload_song_by_suno_task_id] Uploaded to Blob - suno_task_id: {suno_task_id}, url: {blob_url}") - - # Song 테이블 업데이트 (새 세션 사용) - async with BackgroundSessionLocal() as session: - result = await session.execute( - select(Song) - .where(Song.suno_task_id == suno_task_id) - .order_by(Song.created_at.desc()) - .limit(1) - ) - song = result.scalar_one_or_none() - - if song: - song.status = "completed" - song.song_result_url = blob_url - if duration is not None: - song.duration = duration - await session.commit() - print(f"[download_and_upload_song_by_suno_task_id] SUCCESS - suno_task_id: {suno_task_id}, status: completed, duration: {duration}") - else: - print(f"[download_and_upload_song_by_suno_task_id] Song NOT FOUND in DB - suno_task_id: {suno_task_id}") - - except Exception as e: - print(f"[download_and_upload_song_by_suno_task_id] EXCEPTION - suno_task_id: {suno_task_id}, error: {e}") - # 실패 시 Song 테이블 업데이트 - if task_id: - async with BackgroundSessionLocal() as session: - result = await session.execute( - select(Song) - .where(Song.suno_task_id == suno_task_id) - .order_by(Song.created_at.desc()) - .limit(1) - ) - song = result.scalar_one_or_none() - - if song: - song.status = "failed" - await session.commit() - print(f"[download_and_upload_song_by_suno_task_id] FAILED - suno_task_id: {suno_task_id}, status updated to failed") - - finally: - # 임시 파일 삭제 - if temp_file_path and temp_file_path.exists(): - try: - temp_file_path.unlink() - print(f"[download_and_upload_song_by_suno_task_id] Temp file deleted - path: {temp_file_path}") - except Exception as e: - print(f"[download_and_upload_song_by_suno_task_id] Failed to delete temp file: {e}") - - # 임시 디렉토리 삭제 시도 - if task_id: - temp_dir = Path("media") / "temp" / task_id - if temp_dir.exists(): - try: - temp_dir.rmdir() - except Exception: - pass # 디렉토리가 비어있지 않으면 무시 +""" +Song Background Tasks + +노래 생성 관련 백그라운드 태스크를 정의합니다. +""" + +import logging +import traceback +from datetime import date +from pathlib import Path + +import aiofiles +import httpx +from sqlalchemy import select +from sqlalchemy.exc import SQLAlchemyError + +from app.database.session import BackgroundSessionLocal +from app.song.models import Song +from app.utils.common import generate_task_id +from app.utils.upload_blob_as_request import AzureBlobUploader +from config import prj_settings + +# 로거 설정 +logger = logging.getLogger(__name__) + +# HTTP 요청 설정 +REQUEST_TIMEOUT = 120.0 # 초 + + +async def _update_song_status( + task_id: str, + status: str, + song_url: str | None = None, + suno_task_id: str | None = None, + duration: float | None = None, +) -> bool: + """Song 테이블의 상태를 업데이트합니다. + + Args: + task_id: 프로젝트 task_id + status: 변경할 상태 ("processing", "completed", "failed") + song_url: 노래 URL + suno_task_id: Suno task ID (선택) + duration: 노래 길이 (선택) + + Returns: + bool: 업데이트 성공 여부 + """ + try: + async with BackgroundSessionLocal() as session: + if suno_task_id: + query_result = await session.execute( + select(Song) + .where(Song.suno_task_id == suno_task_id) + .order_by(Song.created_at.desc()) + .limit(1) + ) + else: + query_result = await session.execute( + select(Song) + .where(Song.task_id == task_id) + .order_by(Song.created_at.desc()) + .limit(1) + ) + + song = query_result.scalar_one_or_none() + + if song: + song.status = status + if song_url is not None: + song.song_result_url = song_url + if duration is not None: + song.duration = duration + await session.commit() + logger.info(f"[Song] Status updated - task_id: {task_id}, status: {status}") + print(f"[Song] Status updated - task_id: {task_id}, status: {status}") + return True + else: + logger.warning(f"[Song] NOT FOUND in DB - task_id: {task_id}") + print(f"[Song] NOT FOUND in DB - task_id: {task_id}") + return False + + except SQLAlchemyError as e: + logger.error(f"[Song] DB Error while updating status - task_id: {task_id}, error: {e}") + print(f"[Song] DB Error while updating status - task_id: {task_id}, error: {e}") + return False + except Exception as e: + logger.error(f"[Song] Unexpected error while updating status - task_id: {task_id}, error: {e}") + print(f"[Song] Unexpected error while updating status - task_id: {task_id}, error: {e}") + return False + + +async def _download_audio(url: str, task_id: str) -> bytes: + """URL에서 오디오 파일을 다운로드합니다. + + Args: + url: 다운로드할 URL + task_id: 로그용 task_id + + Returns: + bytes: 다운로드한 파일 내용 + + Raises: + httpx.HTTPError: 다운로드 실패 시 + """ + logger.info(f"[Download] Downloading - task_id: {task_id}") + print(f"[Download] Downloading - task_id: {task_id}") + + async with httpx.AsyncClient() as client: + response = await client.get(url, timeout=REQUEST_TIMEOUT) + response.raise_for_status() + + logger.info(f"[Download] SUCCESS - task_id: {task_id}, size: {len(response.content)} bytes") + print(f"[Download] SUCCESS - task_id: {task_id}, size: {len(response.content)} bytes") + return response.content + + +async def download_and_save_song( + task_id: str, + audio_url: str, + store_name: str, +) -> None: + """백그라운드에서 노래를 다운로드하고 Song 테이블을 업데이트합니다. + + Args: + task_id: 프로젝트 task_id + audio_url: 다운로드할 오디오 URL + store_name: 저장할 파일명에 사용할 업체명 + """ + logger.info(f"[download_and_save_song] START - task_id: {task_id}, store_name: {store_name}") + print(f"[download_and_save_song] START - task_id: {task_id}, store_name: {store_name}") + + try: + # 저장 경로 생성: media/song/{날짜}/{uuid7}/{store_name}.mp3 + today = date.today().strftime("%Y-%m-%d") + unique_id = await generate_task_id() + # 파일명에 사용할 수 없는 문자 제거 + safe_store_name = "".join( + c for c in store_name if c.isalnum() or c in (" ", "_", "-") + ).strip() + safe_store_name = safe_store_name or "song" + file_name = f"{safe_store_name}.mp3" + + # 절대 경로 생성 + media_dir = Path("media") / "song" / today / unique_id + media_dir.mkdir(parents=True, exist_ok=True) + file_path = media_dir / file_name + logger.info(f"[download_and_save_song] Directory created - path: {file_path}") + print(f"[download_and_save_song] Directory created - path: {file_path}") + + # 오디오 파일 다운로드 + logger.info(f"[download_and_save_song] Downloading audio - task_id: {task_id}, url: {audio_url}") + print(f"[download_and_save_song] Downloading audio - task_id: {task_id}, url: {audio_url}") + + content = await _download_audio(audio_url, task_id) + + async with aiofiles.open(str(file_path), "wb") as f: + await f.write(content) + + logger.info(f"[download_and_save_song] File saved - task_id: {task_id}, path: {file_path}") + print(f"[download_and_save_song] File saved - task_id: {task_id}, path: {file_path}") + + # 프론트엔드에서 접근 가능한 URL 생성 + relative_path = f"/media/song/{today}/{unique_id}/{file_name}" + base_url = f"http://{prj_settings.PROJECT_DOMAIN}" + file_url = f"{base_url}{relative_path}" + logger.info(f"[download_and_save_song] URL generated - task_id: {task_id}, url: {file_url}") + print(f"[download_and_save_song] URL generated - task_id: {task_id}, url: {file_url}") + + # Song 테이블 업데이트 + await _update_song_status(task_id, "completed", file_url) + logger.info(f"[download_and_save_song] SUCCESS - task_id: {task_id}") + print(f"[download_and_save_song] SUCCESS - task_id: {task_id}") + + except httpx.HTTPError as e: + logger.error(f"[download_and_save_song] DOWNLOAD ERROR - task_id: {task_id}, error: {e}") + print(f"[download_and_save_song] DOWNLOAD ERROR - task_id: {task_id}, error: {e}") + traceback.print_exc() + await _update_song_status(task_id, "failed") + + except SQLAlchemyError as e: + logger.error(f"[download_and_save_song] DB ERROR - task_id: {task_id}, error: {e}") + print(f"[download_and_save_song] DB ERROR - task_id: {task_id}, error: {e}") + traceback.print_exc() + await _update_song_status(task_id, "failed") + + except Exception as e: + logger.error(f"[download_and_save_song] EXCEPTION - task_id: {task_id}, error: {e}") + print(f"[download_and_save_song] EXCEPTION - task_id: {task_id}, error: {e}") + traceback.print_exc() + await _update_song_status(task_id, "failed") + + +async def download_and_upload_song_to_blob( + task_id: str, + audio_url: str, + store_name: str, +) -> None: + """백그라운드에서 노래를 다운로드하고 Azure Blob Storage에 업로드한 뒤 Song 테이블을 업데이트합니다. + + Args: + task_id: 프로젝트 task_id + audio_url: 다운로드할 오디오 URL + store_name: 저장할 파일명에 사용할 업체명 + """ + logger.info(f"[download_and_upload_song_to_blob] START - task_id: {task_id}, store_name: {store_name}") + print(f"[download_and_upload_song_to_blob] START - task_id: {task_id}, store_name: {store_name}") + temp_file_path: Path | None = None + + try: + # 파일명에 사용할 수 없는 문자 제거 + safe_store_name = "".join( + c for c in store_name if c.isalnum() or c in (" ", "_", "-") + ).strip() + safe_store_name = safe_store_name or "song" + file_name = f"{safe_store_name}.mp3" + + # 임시 저장 경로 생성 + temp_dir = Path("media") / "temp" / task_id + temp_dir.mkdir(parents=True, exist_ok=True) + temp_file_path = temp_dir / file_name + logger.info(f"[download_and_upload_song_to_blob] Temp directory created - path: {temp_file_path}") + print(f"[download_and_upload_song_to_blob] Temp directory created - path: {temp_file_path}") + + # 오디오 파일 다운로드 + logger.info(f"[download_and_upload_song_to_blob] Downloading audio - task_id: {task_id}, url: {audio_url}") + print(f"[download_and_upload_song_to_blob] Downloading audio - task_id: {task_id}, url: {audio_url}") + + content = await _download_audio(audio_url, task_id) + + async with aiofiles.open(str(temp_file_path), "wb") as f: + await f.write(content) + + logger.info(f"[download_and_upload_song_to_blob] File downloaded - task_id: {task_id}, path: {temp_file_path}") + print(f"[download_and_upload_song_to_blob] File downloaded - task_id: {task_id}, path: {temp_file_path}") + + # Azure Blob Storage에 업로드 + uploader = AzureBlobUploader(task_id=task_id) + upload_success = await uploader.upload_music(file_path=str(temp_file_path)) + + if not upload_success: + raise Exception("Azure Blob Storage 업로드 실패") + + # SAS 토큰이 제외된 public_url 사용 + blob_url = uploader.public_url + logger.info(f"[download_and_upload_song_to_blob] Uploaded to Blob - task_id: {task_id}, url: {blob_url}") + print(f"[download_and_upload_song_to_blob] Uploaded to Blob - task_id: {task_id}, url: {blob_url}") + + # Song 테이블 업데이트 + await _update_song_status(task_id, "completed", blob_url) + logger.info(f"[download_and_upload_song_to_blob] SUCCESS - task_id: {task_id}") + print(f"[download_and_upload_song_to_blob] SUCCESS - task_id: {task_id}") + + except httpx.HTTPError as e: + logger.error(f"[download_and_upload_song_to_blob] DOWNLOAD ERROR - task_id: {task_id}, error: {e}") + print(f"[download_and_upload_song_to_blob] DOWNLOAD ERROR - task_id: {task_id}, error: {e}") + traceback.print_exc() + await _update_song_status(task_id, "failed") + + except SQLAlchemyError as e: + logger.error(f"[download_and_upload_song_to_blob] DB ERROR - task_id: {task_id}, error: {e}") + print(f"[download_and_upload_song_to_blob] DB ERROR - task_id: {task_id}, error: {e}") + traceback.print_exc() + await _update_song_status(task_id, "failed") + + except Exception as e: + logger.error(f"[download_and_upload_song_to_blob] EXCEPTION - task_id: {task_id}, error: {e}") + print(f"[download_and_upload_song_to_blob] EXCEPTION - task_id: {task_id}, error: {e}") + traceback.print_exc() + await _update_song_status(task_id, "failed") + + finally: + # 임시 파일 삭제 + if temp_file_path and temp_file_path.exists(): + try: + temp_file_path.unlink() + logger.info(f"[download_and_upload_song_to_blob] Temp file deleted - path: {temp_file_path}") + print(f"[download_and_upload_song_to_blob] Temp file deleted - path: {temp_file_path}") + except Exception as e: + logger.warning(f"[download_and_upload_song_to_blob] Failed to delete temp file: {e}") + print(f"[download_and_upload_song_to_blob] Failed to delete temp file: {e}") + + # 임시 디렉토리 삭제 시도 + temp_dir = Path("media") / "temp" / task_id + if temp_dir.exists(): + try: + temp_dir.rmdir() + except Exception: + pass # 디렉토리가 비어있지 않으면 무시 + + +async def download_and_upload_song_by_suno_task_id( + suno_task_id: str, + audio_url: str, + store_name: str, + duration: float | None = None, +) -> None: + """suno_task_id로 Song을 조회하여 노래를 다운로드하고 Azure Blob Storage에 업로드한 뒤 Song 테이블을 업데이트합니다. + + Args: + suno_task_id: Suno API 작업 ID + audio_url: 다운로드할 오디오 URL + store_name: 저장할 파일명에 사용할 업체명 + duration: 노래 재생 시간 (초) + """ + logger.info(f"[download_and_upload_song_by_suno_task_id] START - suno_task_id: {suno_task_id}, store_name: {store_name}, duration: {duration}") + print(f"[download_and_upload_song_by_suno_task_id] START - suno_task_id: {suno_task_id}, store_name: {store_name}, duration: {duration}") + temp_file_path: Path | None = None + task_id: str | None = None + + try: + # suno_task_id로 Song 조회하여 task_id 가져오기 + async with BackgroundSessionLocal() as session: + result = await session.execute( + select(Song) + .where(Song.suno_task_id == suno_task_id) + .order_by(Song.created_at.desc()) + .limit(1) + ) + song = result.scalar_one_or_none() + + if not song: + logger.warning(f"[download_and_upload_song_by_suno_task_id] Song NOT FOUND - suno_task_id: {suno_task_id}") + print(f"[download_and_upload_song_by_suno_task_id] Song NOT FOUND - suno_task_id: {suno_task_id}") + return + + task_id = song.task_id + logger.info(f"[download_and_upload_song_by_suno_task_id] Song found - suno_task_id: {suno_task_id}, task_id: {task_id}") + print(f"[download_and_upload_song_by_suno_task_id] Song found - suno_task_id: {suno_task_id}, task_id: {task_id}") + + # 파일명에 사용할 수 없는 문자 제거 + safe_store_name = "".join( + c for c in store_name if c.isalnum() or c in (" ", "_", "-") + ).strip() + safe_store_name = safe_store_name or "song" + file_name = f"{safe_store_name}.mp3" + + # 임시 저장 경로 생성 + temp_dir = Path("media") / "temp" / task_id + temp_dir.mkdir(parents=True, exist_ok=True) + temp_file_path = temp_dir / file_name + logger.info(f"[download_and_upload_song_by_suno_task_id] Temp directory created - path: {temp_file_path}") + print(f"[download_and_upload_song_by_suno_task_id] Temp directory created - path: {temp_file_path}") + + # 오디오 파일 다운로드 + logger.info(f"[download_and_upload_song_by_suno_task_id] Downloading audio - suno_task_id: {suno_task_id}, url: {audio_url}") + print(f"[download_and_upload_song_by_suno_task_id] Downloading audio - suno_task_id: {suno_task_id}, url: {audio_url}") + + content = await _download_audio(audio_url, task_id) + + async with aiofiles.open(str(temp_file_path), "wb") as f: + await f.write(content) + + logger.info(f"[download_and_upload_song_by_suno_task_id] File downloaded - suno_task_id: {suno_task_id}, path: {temp_file_path}") + print(f"[download_and_upload_song_by_suno_task_id] File downloaded - suno_task_id: {suno_task_id}, path: {temp_file_path}") + + # Azure Blob Storage에 업로드 + uploader = AzureBlobUploader(task_id=task_id) + upload_success = await uploader.upload_music(file_path=str(temp_file_path)) + + if not upload_success: + raise Exception("Azure Blob Storage 업로드 실패") + + # SAS 토큰이 제외된 public_url 사용 + blob_url = uploader.public_url + logger.info(f"[download_and_upload_song_by_suno_task_id] Uploaded to Blob - suno_task_id: {suno_task_id}, url: {blob_url}") + print(f"[download_and_upload_song_by_suno_task_id] Uploaded to Blob - suno_task_id: {suno_task_id}, url: {blob_url}") + + # Song 테이블 업데이트 + await _update_song_status( + task_id=task_id, + status="completed", + song_url=blob_url, + suno_task_id=suno_task_id, + duration=duration, + ) + logger.info(f"[download_and_upload_song_by_suno_task_id] SUCCESS - suno_task_id: {suno_task_id}, duration: {duration}") + print(f"[download_and_upload_song_by_suno_task_id] SUCCESS - suno_task_id: {suno_task_id}, duration: {duration}") + + except httpx.HTTPError as e: + logger.error(f"[download_and_upload_song_by_suno_task_id] DOWNLOAD ERROR - suno_task_id: {suno_task_id}, error: {e}") + print(f"[download_and_upload_song_by_suno_task_id] DOWNLOAD ERROR - suno_task_id: {suno_task_id}, error: {e}") + traceback.print_exc() + if task_id: + await _update_song_status(task_id, "failed", suno_task_id=suno_task_id) + + except SQLAlchemyError as e: + logger.error(f"[download_and_upload_song_by_suno_task_id] DB ERROR - suno_task_id: {suno_task_id}, error: {e}") + print(f"[download_and_upload_song_by_suno_task_id] DB ERROR - suno_task_id: {suno_task_id}, error: {e}") + traceback.print_exc() + if task_id: + await _update_song_status(task_id, "failed", suno_task_id=suno_task_id) + + except Exception as e: + logger.error(f"[download_and_upload_song_by_suno_task_id] EXCEPTION - suno_task_id: {suno_task_id}, error: {e}") + print(f"[download_and_upload_song_by_suno_task_id] EXCEPTION - suno_task_id: {suno_task_id}, error: {e}") + traceback.print_exc() + if task_id: + await _update_song_status(task_id, "failed", suno_task_id=suno_task_id) + + finally: + # 임시 파일 삭제 + if temp_file_path and temp_file_path.exists(): + try: + temp_file_path.unlink() + logger.info(f"[download_and_upload_song_by_suno_task_id] Temp file deleted - path: {temp_file_path}") + print(f"[download_and_upload_song_by_suno_task_id] Temp file deleted - path: {temp_file_path}") + except Exception as e: + logger.warning(f"[download_and_upload_song_by_suno_task_id] Failed to delete temp file: {e}") + print(f"[download_and_upload_song_by_suno_task_id] Failed to delete temp file: {e}") + + # 임시 디렉토리 삭제 시도 + if task_id: + temp_dir = Path("media") / "temp" / task_id + if temp_dir.exists(): + try: + temp_dir.rmdir() + except Exception: + pass # 디렉토리가 비어있지 않으면 무시 diff --git a/app/utils/chatgpt_prompt.py b/app/utils/chatgpt_prompt.py index 4f2b364..866e7c0 100644 --- a/app/utils/chatgpt_prompt.py +++ b/app/utils/chatgpt_prompt.py @@ -1,329 +1,379 @@ -import json -import re - -from openai import AsyncOpenAI - -from config import apikey_settings - -# fmt: off -LYRICS_PROMPT_TEMPLATE_ORI = """ -1.Act as a content marketing expert with domain knowledges in [pension/staying services] in Korea, Goal: plan viral content creation that lead online reservations and promotion -2.Conduct an in-depth analysis of [업체명:{customer_name}] in [지역명:{region}] by examining their official website or informations, photos on never map and online presence. Create a comprehensive "[지역 상세: {detail_region_info}]_Brand & Marketing Intelligence Report in Korean, that includes: - -**Core Analysis:** -- Target customer segments & personas -- Unique Selling Propositions (USPs) and competitive differentiators -- Comprehensive competitor landscape analysis (direct & indirect competitors) -- Market positioning assessment - -**Content Strategy Framework:** -- Seasonal content calendar with trend integration -- Visual storytelling direction (shot-by-shot creative guidance) -- Brand tone & voice guidelines -- Content themes aligned with target audience behaviors - -**SEO & AEO Optimization:** -- Recommended primary and long-tail keywords -- SEO-optimized taglines and meta descriptions -- Answer Engine Optimization (AEO) content suggestions -- Local search optimization strategies - -**Actionable Recommendations:** -- Content distribution strategy across platforms -- KPI measurement framework -- Budget allocation recommendations by content type - -콘텐츠 기획(Lyrics, Prompt for SUNO) -1. Based on the Brand & Marketing Intelligence Report for [업체명 + 지역명 / {customer_name} ({region})], create original lyrics and define music attributes (song mood, BPM, genres, and key musical motifs, Prompt for Suno.com) specifically tailored for viral content. -2. The lyrics should include, the name of [ Promotion Subject], [location], [main target],[Famous place, accessible in 10min], promotional words including but not limited to [인스타 감성], [사진같은 하루] - -Deliver outputs optimized for three formats:1 minute. Ensure that each version aligns with the brand's core identity and is suitable for use in digital marketing and social media campaigns, in Korean -""".strip() -# fmt: on - -LYRICS_PROMPT_TEMPLATE = """ -[ROLE] -Content marketing expert and creative songwriter specializing in pension/accommodation services - -[INPUT] -- Business Name: {customer_name} -- Region: {region} -- Region Details: {detail_region_info} -- Output Language: {language} - -[INTERNAL ANALYSIS - DO NOT OUTPUT] -Analyze the following internally to inform lyrics creation: -- Target customer segments and personas -- Unique Selling Propositions (USPs) -- Regional characteristics and nearby attractions (within 10 min access) -- Seasonal appeal points -- Emotional triggers for the target audience - -[LYRICS REQUIREMENTS] -1. Must Include Elements: - - Business name (TRANSLATED or TRANSLITERATED to {language}) - - Region name (TRANSLATED or TRANSLITERATED to {language}) - - Main target audience appeal - - Nearby famous places or regional characteristics - -2. Keywords to Incorporate (use language-appropriate trendy expressions): - - Korean: 인스타 감성, 사진같은 하루, 힐링, 여행, 감성 숙소 - - English: Instagram vibes, picture-perfect day, healing, travel, getaway - - Chinese: 网红打卡, 治愈系, 旅行, 度假, 拍照圣地 - - Japanese: インスタ映え, 写真のような一日, 癒し, 旅行, 絶景 - - Thai: ที่พักสวย, ฮีลใจ, เที่ยว, ถ่ายรูป, วิวสวย - - Vietnamese: check-in đẹp, healing, du lịch, nghỉ dưỡng, view đẹp - -3. Structure: - - Length: For 1-minute video (approximately 8-12 lines) - - Flow: Verse structure suitable for music - - Rhythm: Natural speech rhythm in the specified language - -4. Tone: - - Emotional and heartfelt - - Trendy and viral-friendly - - Relatable to target audience - -[CRITICAL LANGUAGE REQUIREMENT - ABSOLUTE RULE] -ALL OUTPUT MUST BE 100% WRITTEN IN {language} - NO EXCEPTIONS -- ALL lyrics content: {language} ONLY -- ALL proper nouns (business names, region names, place names): MUST be translated or transliterated to {language} -- Korean input like "군산" must become "Gunsan" in English, "群山" in Chinese, "グンサン" in Japanese, etc. -- Korean input like "스테이 머뭄" must become "Stay Meoum" in English, "住留" in Chinese, "ステイモーム" in Japanese, etc. -- ZERO Korean characters (한글) allowed when output language is NOT Korean -- ZERO mixing of languages - the entire output must be monolingual in {language} -- This is a NON-NEGOTIABLE requirement -- Any output containing characters from other languages is considered a COMPLETE FAILURE -- Violation of this rule invalidates the entire response - -[OUTPUT RULES - STRICTLY ENFORCED] -- Output lyrics ONLY -- Lyrics MUST be written ENTIRELY in {language} - NO EXCEPTIONS -- ALL names and places MUST be in {language} script/alphabet -- NO Korean (한글), Chinese (漢字), Japanese (仮名), Thai (ไทย), or Vietnamese (Tiếng Việt) characters unless that is the selected output language -- NO titles, descriptions, analysis, or explanations -- NO greetings or closing remarks -- NO additional commentary before or after lyrics -- NO line numbers or labels -- Follow the exact format below - -[OUTPUT FORMAT - SUCCESS] ---- -[Lyrics ENTIRELY in {language} here - no other language characters allowed] ---- - -[OUTPUT FORMAT - FAILURE] -If you cannot generate lyrics due to insufficient information, invalid input, or any other reason: ---- -ERROR: [Brief reason for failure in English] ---- -""".strip() -# fmt: on - -MARKETING_ANALYSIS_PROMPT_TEMPLATE = """ -[ROLE] -Content marketing expert specializing in pension/accommodation services in Korea - -[INPUT] -- Business Name: {customer_name} -- Region: {region} -- Region Details: {detail_region_info} - -[ANALYSIS REQUIREMENTS] -Provide comprehensive marketing analysis including: -1. Target Customer Segments - - Primary and secondary target personas - - Age groups, travel preferences, booking patterns -2. Unique Selling Propositions (USPs) - - Key differentiators based on location and region details - - Competitive advantages -3. Regional Characteristics - - Nearby attractions and famous places (within 10 min access) - - Local food, activities, and experiences - - Transportation accessibility -4. Seasonal Appeal Points - - Best seasons to visit - - Seasonal activities and events - - Peak/off-peak marketing opportunities -5. Marketing Keywords - - Recommended hashtags and search keywords - - Trending terms relevant to the property - -[ADDITIONAL REQUIREMENTS] -1. Recommended Tags - - Generate 5 recommended hashtags/tags based on the business characteristics - - Tags should be trendy, searchable, and relevant to accommodation marketing - - Return as JSON with key "tags" - - **MUST be written in Korean (한국어)** - -2. Facilities - - Based on the business name and region details, identify 5 likely facilities/amenities - - Consider typical facilities for accommodations in the given region - - Examples: 바베큐장, 수영장, 주차장, 와이파이, 주방, 테라스, 정원, etc. - - Return as JSON with key "facilities" - - **MUST be written in Korean (한국어)** - -[CRITICAL LANGUAGE REQUIREMENT - ABSOLUTE RULE] -ALL OUTPUT MUST BE WRITTEN IN KOREAN (한국어) -- Analysis sections: Korean only -- Tags: Korean only -- Facilities: Korean only -- This is a NON-NEGOTIABLE requirement -- Any output in English or other languages is considered a FAILURE -- Violation of this rule invalidates the entire response - -[OUTPUT RULES - STRICTLY ENFORCED] -- Output analysis ONLY -- ALL content MUST be written in Korean (한국어) - NO EXCEPTIONS -- NO greetings or closing remarks -- NO additional commentary before or after analysis -- Follow the exact format below - -[OUTPUT FORMAT - SUCCESS] ---- -## 타겟 고객 분석 -[한국어로 작성된 타겟 고객 분석] - -## 핵심 차별점 (USP) -[한국어로 작성된 USP 분석] - -## 지역 특성 -[한국어로 작성된 지역 특성 분석] - -## 시즌별 매력 포인트 -[한국어로 작성된 시즌별 분석] - -## 마케팅 키워드 -[한국어로 작성된 마케팅 키워드] - -## JSON Data -```json -{{ - "tags": ["태그1", "태그2", "태그3", "태그4", "태그5"], - "facilities": ["부대시설1", "부대시설2", "부대시설3", "부대시설4", "부대시설5"] -}} -``` ---- - -[OUTPUT FORMAT - FAILURE] -If you cannot generate analysis due to insufficient information, invalid input, or any other reason: ---- -ERROR: [Brief reason for failure in English] ---- -""".strip() -# fmt: on - - -class ChatgptService: - def __init__( - self, - customer_name: str, - region: str, - detail_region_info: str = "", - language: str = "Korean", - ): - # 최신 모델: GPT-5, GPT-5 mini, GPT-5 nano, GPT-4.1, GPT-4.1 mini, GPT-4.1 nano - # 이전 세대: GPT-4o, GPT-4o mini, GPT-4 Turbo, GPT-3.5 Turbo - self.model = "gpt-4o" - self.client = AsyncOpenAI(api_key=apikey_settings.CHATGPT_API_KEY) - self.customer_name = customer_name - self.region = region - self.detail_region_info = detail_region_info - self.language = language - - def build_lyrics_prompt(self) -> str: - """LYRICS_PROMPT_TEMPLATE에 고객 정보를 대입하여 완성된 프롬프트 반환""" - return LYRICS_PROMPT_TEMPLATE.format( - customer_name=self.customer_name, - region=self.region, - detail_region_info=self.detail_region_info, - language=self.language, - ) - - def build_market_analysis_prompt(self) -> str: - """MARKETING_ANALYSIS_PROMPT_TEMPLATE에 고객 정보를 대입하여 완성된 프롬프트 반환""" - return MARKETING_ANALYSIS_PROMPT_TEMPLATE.format( - customer_name=self.customer_name, - region=self.region, - detail_region_info=self.detail_region_info, - ) - - async def generate(self, prompt: str | None = None) -> str: - """GPT에게 프롬프트를 전달하여 결과를 반환""" - if prompt is None: - prompt = self.build_lyrics_prompt() - print("Generated Prompt: ", prompt) - completion = await self.client.chat.completions.create( - model=self.model, messages=[{"role": "user", "content": prompt}] - ) - message = completion.choices[0].message.content - return message or "" - - async def summarize_marketing(self, text: str) -> str: - """마케팅 텍스트를 항목으로 구분하여 500자로 요약 정리""" - prompt = f"""[ROLE] - 마케팅 콘텐츠 요약 전문가 - - [INPUT] - {text} - - [TASK] - 위 텍스트를 분석하여 핵심 내용을 항목별로 구분하여 500자 이내로 요약해주세요. - - [OUTPUT REQUIREMENTS] - - 항목별로 구분하여 정리 (예: 타겟 고객, 차별점, 지역 특성 등) - - 총 500자 이내로 요약 - - 핵심 정보만 간결하게 포함 - - 한국어로 작성 - - [OUTPUT FORMAT] - --- - [항목별로 구분된 500자 이내 요약] - --- - """ - completion = await self.client.chat.completions.create( - model=self.model, messages=[{"role": "user", "content": prompt}] - ) - message = completion.choices[0].message.content - result = message or "" - - # --- 구분자 제거 - if result.startswith("---"): - result = result[3:].strip() - if result.endswith("---"): - result = result[:-3].strip() - - return result - - async def parse_marketing_analysis(self, raw_response: str) -> dict: - """ChatGPT 마케팅 분석 응답을 파싱하고 요약하여 딕셔너리로 반환 - - Returns: - dict: {"report": str, "tags": list[str], "facilities": list[str]} - """ - tags: list[str] = [] - facilities: list[str] = [] - report = raw_response - - # JSON 블록 추출 시도 - json_match = re.search(r"```json\s*(\{.*?\})\s*```", raw_response, re.DOTALL) - if json_match: - try: - json_data = json.loads(json_match.group(1)) - tags = json_data.get("tags", []) - facilities = json_data.get("facilities", []) - # JSON 블록을 제외한 리포트 부분 추출 - report = raw_response[: json_match.start()].strip() - # --- 구분자 제거 - if report.startswith("---"): - report = report[3:].strip() - if report.endswith("---"): - report = report[:-3].strip() - except json.JSONDecodeError: - pass - - # 리포트 내용을 500자로 요약 - if report: - report = await self.summarize_marketing(report) - - return {"report": report, "tags": tags, "facilities": facilities} +import json +import logging +import re + +from openai import AsyncOpenAI + +from config import apikey_settings + +# 로거 설정 +logger = logging.getLogger(__name__) + +# fmt: off +LYRICS_PROMPT_TEMPLATE_ORI = """ +1.Act as a content marketing expert with domain knowledges in [pension/staying services] in Korea, Goal: plan viral content creation that lead online reservations and promotion +2.Conduct an in-depth analysis of [업체명:{customer_name}] in [지역명:{region}] by examining their official website or informations, photos on never map and online presence. Create a comprehensive "[지역 상세: {detail_region_info}]_Brand & Marketing Intelligence Report in Korean, that includes: + +**Core Analysis:** +- Target customer segments & personas +- Unique Selling Propositions (USPs) and competitive differentiators +- Comprehensive competitor landscape analysis (direct & indirect competitors) +- Market positioning assessment + +**Content Strategy Framework:** +- Seasonal content calendar with trend integration +- Visual storytelling direction (shot-by-shot creative guidance) +- Brand tone & voice guidelines +- Content themes aligned with target audience behaviors + +**SEO & AEO Optimization:** +- Recommended primary and long-tail keywords +- SEO-optimized taglines and meta descriptions +- Answer Engine Optimization (AEO) content suggestions +- Local search optimization strategies + +**Actionable Recommendations:** +- Content distribution strategy across platforms +- KPI measurement framework +- Budget allocation recommendations by content type + +콘텐츠 기획(Lyrics, Prompt for SUNO) +1. Based on the Brand & Marketing Intelligence Report for [업체명 + 지역명 / {customer_name} ({region})], create original lyrics and define music attributes (song mood, BPM, genres, and key musical motifs, Prompt for Suno.com) specifically tailored for viral content. +2. The lyrics should include, the name of [ Promotion Subject], [location], [main target],[Famous place, accessible in 10min], promotional words including but not limited to [인스타 감성], [사진같은 하루] + +Deliver outputs optimized for three formats:1 minute. Ensure that each version aligns with the brand's core identity and is suitable for use in digital marketing and social media campaigns, in Korean +""".strip() +# fmt: on + +LYRICS_PROMPT_TEMPLATE = """ +[ROLE] +Content marketing expert and creative songwriter specializing in pension/accommodation services + +[INPUT] +- Business Name: {customer_name} +- Region: {region} +- Region Details: {detail_region_info} +- Output Language: {language} + +[INTERNAL ANALYSIS - DO NOT OUTPUT] +Analyze the following internally to inform lyrics creation: +- Target customer segments and personas +- Unique Selling Propositions (USPs) +- Regional characteristics and nearby attractions (within 10 min access) +- Seasonal appeal points +- Emotional triggers for the target audience + +[LYRICS REQUIREMENTS] +1. Must Include Elements: + - Business name (TRANSLATED or TRANSLITERATED to {language}) + - Region name (TRANSLATED or TRANSLITERATED to {language}) + - Main target audience appeal + - Nearby famous places or regional characteristics + +2. Keywords to Incorporate (use language-appropriate trendy expressions): + - Korean: 인스타 감성, 사진같은 하루, 힐링, 여행, 감성 숙소 + - English: Instagram vibes, picture-perfect day, healing, travel, getaway + - Chinese: 网红打卡, 治愈系, 旅行, 度假, 拍照圣地 + - Japanese: インスタ映え, 写真のような一日, 癒し, 旅行, 絶景 + - Thai: ที่พักสวย, ฮีลใจ, เที่ยว, ถ่ายรูป, วิวสวย + - Vietnamese: check-in đẹp, healing, du lịch, nghỉ dưỡng, view đẹp + +3. Structure: + - Length: For 1-minute video (approximately 8-12 lines) + - Flow: Verse structure suitable for music + - Rhythm: Natural speech rhythm in the specified language + +4. Tone: + - Emotional and heartfelt + - Trendy and viral-friendly + - Relatable to target audience + +[CRITICAL LANGUAGE REQUIREMENT - ABSOLUTE RULE] +ALL OUTPUT MUST BE 100% WRITTEN IN {language} - NO EXCEPTIONS +- ALL lyrics content: {language} ONLY +- ALL proper nouns (business names, region names, place names): MUST be translated or transliterated to {language} +- Korean input like "군산" must become "Gunsan" in English, "群山" in Chinese, "グンサン" in Japanese, etc. +- Korean input like "스테이 머뭄" must become "Stay Meoum" in English, "住留" in Chinese, "ステイモーム" in Japanese, etc. +- ZERO Korean characters (한글) allowed when output language is NOT Korean +- ZERO mixing of languages - the entire output must be monolingual in {language} +- This is a NON-NEGOTIABLE requirement +- Any output containing characters from other languages is considered a COMPLETE FAILURE +- Violation of this rule invalidates the entire response + +[OUTPUT RULES - STRICTLY ENFORCED] +- Output lyrics ONLY +- Lyrics MUST be written ENTIRELY in {language} - NO EXCEPTIONS +- ALL names and places MUST be in {language} script/alphabet +- NO Korean (한글), Chinese (漢字), Japanese (仮名), Thai (ไทย), or Vietnamese (Tiếng Việt) characters unless that is the selected output language +- NO titles, descriptions, analysis, or explanations +- NO greetings or closing remarks +- NO additional commentary before or after lyrics +- NO line numbers or labels +- Follow the exact format below + +[OUTPUT FORMAT - SUCCESS] +--- +[Lyrics ENTIRELY in {language} here - no other language characters allowed] +--- + +[OUTPUT FORMAT - FAILURE] +If you cannot generate lyrics due to insufficient information, invalid input, or any other reason: +--- +ERROR: [Brief reason for failure in English] +--- +""".strip() +# fmt: on + +MARKETING_ANALYSIS_PROMPT_TEMPLATE = """ +[ROLE] +Content marketing expert specializing in pension/accommodation services in Korea + +[INPUT] +- Business Name: {customer_name} +- Region: {region} +- Region Details: {detail_region_info} + +[ANALYSIS REQUIREMENTS] +Provide comprehensive marketing analysis including: +1. Target Customer Segments + - Primary and secondary target personas + - Age groups, travel preferences, booking patterns +2. Unique Selling Propositions (USPs) + - Key differentiators based on location and region details + - Competitive advantages +3. Regional Characteristics + - Nearby attractions and famous places (within 10 min access) + - Local food, activities, and experiences + - Transportation accessibility +4. Seasonal Appeal Points + - Best seasons to visit + - Seasonal activities and events + - Peak/off-peak marketing opportunities +5. Marketing Keywords + - Recommended hashtags and search keywords + - Trending terms relevant to the property + +[ADDITIONAL REQUIREMENTS] +1. Recommended Tags + - Generate 5 recommended hashtags/tags based on the business characteristics + - Tags should be trendy, searchable, and relevant to accommodation marketing + - Return as JSON with key "tags" + - **MUST be written in Korean (한국어)** + +2. Facilities + - Based on the business name and region details, identify 5 likely facilities/amenities + - Consider typical facilities for accommodations in the given region + - Examples: 바베큐장, 수영장, 주차장, 와이파이, 주방, 테라스, 정원, etc. + - Return as JSON with key "facilities" + - **MUST be written in Korean (한국어)** + +[CRITICAL LANGUAGE REQUIREMENT - ABSOLUTE RULE] +ALL OUTPUT MUST BE WRITTEN IN KOREAN (한국어) +- Analysis sections: Korean only +- Tags: Korean only +- Facilities: Korean only +- This is a NON-NEGOTIABLE requirement +- Any output in English or other languages is considered a FAILURE +- Violation of this rule invalidates the entire response + +[OUTPUT RULES - STRICTLY ENFORCED] +- Output analysis ONLY +- ALL content MUST be written in Korean (한국어) - NO EXCEPTIONS +- NO greetings or closing remarks +- NO additional commentary before or after analysis +- Follow the exact format below + +[OUTPUT FORMAT - SUCCESS] +--- +## 타겟 고객 분석 +[한국어로 작성된 타겟 고객 분석] + +## 핵심 차별점 (USP) +[한국어로 작성된 USP 분석] + +## 지역 특성 +[한국어로 작성된 지역 특성 분석] + +## 시즌별 매력 포인트 +[한국어로 작성된 시즌별 분석] + +## 마케팅 키워드 +[한국어로 작성된 마케팅 키워드] + +## JSON Data +```json +{{ + "tags": ["태그1", "태그2", "태그3", "태그4", "태그5"], + "facilities": ["부대시설1", "부대시설2", "부대시설3", "부대시설4", "부대시설5"] +}} +``` +--- + +[OUTPUT FORMAT - FAILURE] +If you cannot generate analysis due to insufficient information, invalid input, or any other reason: +--- +ERROR: [Brief reason for failure in English] +--- +""".strip() +# fmt: on + + +class ChatgptService: + """ChatGPT API 서비스 클래스 + + GPT 5.0 모델을 사용하여 마케팅 가사 및 분석을 생성합니다. + """ + + def __init__( + self, + customer_name: str, + region: str, + detail_region_info: str = "", + language: str = "Korean", + ): + # 최신 모델: gpt-5-mini + self.model = "gpt-5-mini" + self.client = AsyncOpenAI(api_key=apikey_settings.CHATGPT_API_KEY) + self.customer_name = customer_name + self.region = region + self.detail_region_info = detail_region_info + self.language = language + + def build_lyrics_prompt(self) -> str: + """LYRICS_PROMPT_TEMPLATE에 고객 정보를 대입하여 완성된 프롬프트 반환""" + return LYRICS_PROMPT_TEMPLATE.format( + customer_name=self.customer_name, + region=self.region, + detail_region_info=self.detail_region_info, + language=self.language, + ) + + def build_market_analysis_prompt(self) -> str: + """MARKETING_ANALYSIS_PROMPT_TEMPLATE에 고객 정보를 대입하여 완성된 프롬프트 반환""" + return MARKETING_ANALYSIS_PROMPT_TEMPLATE.format( + customer_name=self.customer_name, + region=self.region, + detail_region_info=self.detail_region_info, + ) + + async def _call_gpt_api(self, prompt: str) -> str: + """GPT API를 직접 호출합니다 (내부 메서드). + + Args: + prompt: GPT에 전달할 프롬프트 + + Returns: + GPT 응답 문자열 + + Raises: + APIError, APIConnectionError, RateLimitError: OpenAI API 오류 + """ + completion = await self.client.chat.completions.create( + model=self.model, messages=[{"role": "user", "content": prompt}] + ) + message = completion.choices[0].message.content + return message or "" + + async def generate( + self, + prompt: str | None = None, + ) -> str: + """GPT에게 프롬프트를 전달하여 결과를 반환합니다. + + Args: + prompt: GPT에 전달할 프롬프트 (None이면 기본 가사 프롬프트 사용) + + Returns: + GPT 응답 문자열 + + Raises: + APIError, APIConnectionError, RateLimitError: OpenAI API 오류 + """ + if prompt is None: + prompt = self.build_lyrics_prompt() + + print(f"[ChatgptService] Generated Prompt (length: {len(prompt)})") + logger.info(f"[ChatgptService] Starting GPT request with model: {self.model}") + + # GPT API 호출 + response = await self._call_gpt_api(prompt) + + print(f"[ChatgptService] SUCCESS - Response length: {len(response)}") + logger.info(f"[ChatgptService] SUCCESS - Response length: {len(response)}") + return response + + async def summarize_marketing(self, text: str) -> str: + """마케팅 텍스트를 항목으로 구분하여 500자로 요약 정리. + + Args: + text: 요약할 마케팅 텍스트 + + Returns: + 요약된 텍스트 + + Raises: + APIError, APIConnectionError, RateLimitError: OpenAI API 오류 + """ + prompt = f"""[ROLE] + 마케팅 콘텐츠 요약 전문가 + + [INPUT] + {text} + + [TASK] + 위 텍스트를 분석하여 핵심 내용을 항목별로 구분하여 500자 이내로 요약해주세요. + + [OUTPUT REQUIREMENTS] + - 항목별로 구분하여 정리 (예: 타겟 고객, 차별점, 지역 특성 등) + - 총 500자 이내로 요약 + - 핵심 정보만 간결하게 포함 + - 한국어로 작성 + + [OUTPUT FORMAT] + --- + [항목별로 구분된 500자 이내 요약] + --- + """ + + result = await self.generate(prompt=prompt) + + # --- 구분자 제거 + if result.startswith("---"): + result = result[3:].strip() + if result.endswith("---"): + result = result[:-3].strip() + + return result + + async def parse_marketing_analysis(self, raw_response: str) -> dict: + """ChatGPT 마케팅 분석 응답을 파싱하고 요약하여 딕셔너리로 반환 + + Returns: + dict: {"report": str, "tags": list[str], "facilities": list[str]} + """ + tags: list[str] = [] + facilities: list[str] = [] + report = raw_response + + # JSON 블록 추출 시도 + json_match = re.search(r"```json\s*(\{.*?\})\s*```", raw_response, re.DOTALL) + if json_match: + try: + json_data = json.loads(json_match.group(1)) + tags = json_data.get("tags", []) + facilities = json_data.get("facilities", []) + # JSON 블록을 제외한 리포트 부분 추출 + report = raw_response[: json_match.start()].strip() + # --- 구분자 제거 + if report.startswith("---"): + report = report[3:].strip() + if report.endswith("---"): + report = report[:-3].strip() + except json.JSONDecodeError: + pass + + # 리포트 내용을 500자로 요약 + if report: + report = await self.summarize_marketing(report) + + return {"report": report, "tags": tags, "facilities": facilities} diff --git a/app/utils/cors.py b/app/utils/cors.py index b5e4cbc..e958104 100644 --- a/app/utils/cors.py +++ b/app/utils/cors.py @@ -1,24 +1,24 @@ -from fastapi import FastAPI -from fastapi.middleware.cors import CORSMiddleware - -from config import cors_settings - -# sys.path.append( -# os.path.dirname(os.path.dirname(os.path.abspath(__file__))) -# ) # root 경로 추가 - - -class CustomCORSMiddleware: - def __init__(self, app: FastAPI): - self.app = app - - def configure_cors(self): - self.app.add_middleware( - CORSMiddleware, - allow_origins=cors_settings.CORS_ALLOW_ORIGINS, - allow_credentials=cors_settings.CORS_ALLOW_CREDENTIALS, - allow_methods=cors_settings.CORS_ALLOW_METHODS, - allow_headers=cors_settings.CORS_ALLOW_HEADERS, - expose_headers=cors_settings.CORS_EXPOSE_HEADERS, - max_age=cors_settings.CORS_MAX_AGE, - ) +from fastapi import FastAPI +from fastapi.middleware.cors import CORSMiddleware + +from config import cors_settings + +# sys.path.append( +# os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +# ) # root 경로 추가 + + +class CustomCORSMiddleware: + def __init__(self, app: FastAPI): + self.app = app + + def configure_cors(self): + self.app.add_middleware( + CORSMiddleware, + allow_origins=cors_settings.CORS_ALLOW_ORIGINS, + allow_credentials=cors_settings.CORS_ALLOW_CREDENTIALS, + allow_methods=cors_settings.CORS_ALLOW_METHODS, + allow_headers=cors_settings.CORS_ALLOW_HEADERS, + expose_headers=cors_settings.CORS_EXPOSE_HEADERS, + max_age=cors_settings.CORS_MAX_AGE, + ) diff --git a/app/utils/creatomate.py b/app/utils/creatomate.py index 101ffd3..69ec3b9 100644 --- a/app/utils/creatomate.py +++ b/app/utils/creatomate.py @@ -1,437 +1,473 @@ -""" -Creatomate API 클라이언트 모듈 - -API 문서: https://creatomate.com/docs/api - -## 사용법 -```python -from app.utils.creatomate import CreatomateService - -# config에서 자동으로 API 키를 가져옴 -creatomate = CreatomateService() - -# 또는 명시적으로 API 키 전달 -creatomate = CreatomateService(api_key="your_api_key") - -# 템플릿 목록 조회 (비동기) -templates = await creatomate.get_all_templates_data() - -# 특정 템플릿 조회 (비동기) -template = await creatomate.get_one_template_data(template_id) - -# 영상 렌더링 요청 (비동기) -response = await creatomate.make_creatomate_call(template_id, modifications) -``` - -## 성능 최적화 -- 템플릿 캐싱: 템플릿 데이터는 메모리에 캐싱되어 반복 조회 시 API 호출을 줄입니다. -- HTTP 클라이언트 재사용: 모듈 레벨의 공유 클라이언트로 커넥션 풀을 재사용합니다. -- 캐시 만료: 기본 5분 후 자동 만료 (CACHE_TTL_SECONDS로 조정 가능) -""" - -import copy -import time -from typing import Literal - -import httpx - -from config import apikey_settings, creatomate_settings - - -# Orientation 타입 정의 -OrientationType = Literal["horizontal", "vertical"] - -# ============================================================================= -# 모듈 레벨 캐시 및 HTTP 클라이언트 (싱글톤 패턴) -# ============================================================================= - -# 템플릿 캐시: {template_id: {"data": dict, "cached_at": float}} -_template_cache: dict[str, dict] = {} - -# 캐시 TTL (초) - 기본 5분 -CACHE_TTL_SECONDS = 300 - -# 모듈 레벨 공유 HTTP 클라이언트 (커넥션 풀 재사용) -_shared_client: httpx.AsyncClient | None = None - - -async def get_shared_client() -> httpx.AsyncClient: - """공유 HTTP 클라이언트를 반환합니다. 없으면 생성합니다.""" - global _shared_client - if _shared_client is None or _shared_client.is_closed: - _shared_client = httpx.AsyncClient( - timeout=httpx.Timeout(60.0, connect=10.0), - limits=httpx.Limits(max_keepalive_connections=10, max_connections=20), - ) - return _shared_client - - -async def close_shared_client() -> None: - """공유 HTTP 클라이언트를 닫습니다. 앱 종료 시 호출하세요.""" - global _shared_client - if _shared_client is not None and not _shared_client.is_closed: - await _shared_client.aclose() - _shared_client = None - print("[CreatomateService] Shared HTTP client closed") - - -def clear_template_cache() -> None: - """템플릿 캐시를 전체 삭제합니다.""" - global _template_cache - _template_cache.clear() - print("[CreatomateService] Template cache cleared") - - -def _is_cache_valid(cached_at: float) -> bool: - """캐시가 유효한지 확인합니다.""" - return (time.time() - cached_at) < CACHE_TTL_SECONDS - - -class CreatomateService: - """Creatomate API를 통한 영상 생성 서비스 - - 모든 HTTP 호출 메서드는 비동기(async)로 구현되어 있습니다. - """ - - BASE_URL = "https://api.creatomate.com" - - # 템플릿 설정 (config에서 가져옴) - TEMPLATE_CONFIG = { - "horizontal": { - "template_id": creatomate_settings.TEMPLATE_ID_HORIZONTAL, - "duration": creatomate_settings.TEMPLATE_DURATION_HORIZONTAL, - }, - "vertical": { - "template_id": creatomate_settings.TEMPLATE_ID_VERTICAL, - "duration": creatomate_settings.TEMPLATE_DURATION_VERTICAL, - }, - } - - def __init__( - self, - api_key: str | None = None, - orientation: OrientationType = "vertical", - target_duration: float | None = None, - ): - """ - Args: - api_key: Creatomate API 키 (Bearer token으로 사용) - None일 경우 config에서 자동으로 가져옴 - orientation: 영상 방향 ("horizontal" 또는 "vertical", 기본값: "vertical") - target_duration: 목표 영상 길이 (초) - None일 경우 orientation에 해당하는 기본값 사용 - """ - self.api_key = api_key or apikey_settings.CREATOMATE_API_KEY - self.orientation = orientation - - # orientation에 따른 템플릿 설정 가져오기 - config = self.TEMPLATE_CONFIG.get( - orientation, self.TEMPLATE_CONFIG["vertical"] - ) - self.template_id = config["template_id"] - self.target_duration = ( - target_duration if target_duration is not None else config["duration"] - ) - - self.headers = { - "Content-Type": "application/json", - "Authorization": f"Bearer {self.api_key}", - } - - async def get_all_templates_data(self) -> dict: - """모든 템플릿 정보를 조회합니다.""" - url = f"{self.BASE_URL}/v1/templates" - client = await get_shared_client() - response = await client.get(url, headers=self.headers, timeout=30.0) - response.raise_for_status() - return response.json() - - async def get_one_template_data( - self, - template_id: str, - use_cache: bool = True, - ) -> dict: - """특정 템플릿 ID로 템플릿 정보를 조회합니다. - - Args: - template_id: 조회할 템플릿 ID - use_cache: 캐시 사용 여부 (기본: True) - - Returns: - 템플릿 데이터 (deep copy) - """ - global _template_cache - - # 캐시 확인 - if use_cache and template_id in _template_cache: - cached = _template_cache[template_id] - if _is_cache_valid(cached["cached_at"]): - print(f"[CreatomateService] Cache HIT - {template_id}") - return copy.deepcopy(cached["data"]) - else: - # 만료된 캐시 삭제 - del _template_cache[template_id] - print(f"[CreatomateService] Cache EXPIRED - {template_id}") - - # API 호출 - url = f"{self.BASE_URL}/v1/templates/{template_id}" - client = await get_shared_client() - response = await client.get(url, headers=self.headers, timeout=30.0) - response.raise_for_status() - data = response.json() - - # 캐시 저장 - _template_cache[template_id] = { - "data": data, - "cached_at": time.time(), - } - print(f"[CreatomateService] Cache MISS - {template_id} (cached)") - - return copy.deepcopy(data) - - # 하위 호환성을 위한 별칭 (deprecated) - async def get_one_template_data_async(self, template_id: str) -> dict: - """특정 템플릿 ID로 템플릿 정보를 조회합니다. - - Deprecated: get_one_template_data()를 사용하세요. - """ - return await self.get_one_template_data(template_id) - - def parse_template_component_name(self, template_source: list) -> dict: - """템플릿 정보를 파싱하여 리소스 이름을 추출합니다.""" - - def recursive_parse_component(element: dict) -> dict: - if "name" in element: - result_element_name_type = {element["name"]: element["type"]} - else: - result_element_name_type = {} - - if element["type"] == "composition": - minor_component_list = [ - recursive_parse_component(minor) for minor in element["elements"] - ] - # WARNING: Same name component should shroud other component - for minor_component in minor_component_list: - result_element_name_type.update(minor_component) - - return result_element_name_type - - result = {} - for result_element_dict in [ - recursive_parse_component(component) for component in template_source - ]: - result.update(result_element_dict) - - return result - - async def template_connect_resource_blackbox( - self, - template_id: str, - image_url_list: list[str], - lyric: str, - music_url: str, - ) -> dict: - """템플릿 정보와 이미지/가사/음악 리소스를 매핑합니다. - - Note: - - 이미지는 순차적으로 집어넣기 - - 가사는 개행마다 한 텍스트 삽입 - - Template에 audio-music 항목이 있어야 함 - """ - template_data = await self.get_one_template_data(template_id) - template_component_data = self.parse_template_component_name( - template_data["source"]["elements"] - ) - - lyric = lyric.replace("\r", "") - lyric_splited = lyric.split("\n") - modifications = {} - - for idx, (template_component_name, template_type) in enumerate( - template_component_data.items() - ): - match template_type: - case "image": - modifications[template_component_name] = image_url_list[ - idx % len(image_url_list) - ] - case "text": - modifications[template_component_name] = lyric_splited[ - idx % len(lyric_splited) - ] - - modifications["audio-music"] = music_url - - return modifications - - def elements_connect_resource_blackbox( - self, - elements: list, - image_url_list: list[str], - lyric: str, - music_url: str, - ) -> dict: - """elements 정보와 이미지/가사/음악 리소스를 매핑합니다.""" - template_component_data = self.parse_template_component_name(elements) - - lyric = lyric.replace("\r", "") - lyric_splited = lyric.split("\n") - modifications = {} - - for idx, (template_component_name, template_type) in enumerate( - template_component_data.items() - ): - match template_type: - case "image": - modifications[template_component_name] = image_url_list[ - idx % len(image_url_list) - ] - case "text": - modifications[template_component_name] = lyric_splited[ - idx % len(lyric_splited) - ] - - modifications["audio-music"] = music_url - - return modifications - - def modify_element(self, elements: list, modification: dict) -> list: - """elements의 source를 modification에 따라 수정합니다.""" - - def recursive_modify(element: dict) -> None: - if "name" in element: - match element["type"]: - case "image": - element["source"] = modification[element["name"]] - case "audio": - element["source"] = modification.get(element["name"], "") - case "video": - element["source"] = modification[element["name"]] - case "text": - element["source"] = modification.get(element["name"], "") - case "composition": - for minor in element["elements"]: - recursive_modify(minor) - - for minor in elements: - recursive_modify(minor) - - return elements - - async def make_creatomate_call( - self, template_id: str, modifications: dict - ) -> dict: - """Creatomate에 렌더링 요청을 보냅니다. - - Note: - response에 요청 정보가 있으니 폴링 필요 - """ - url = f"{self.BASE_URL}/v2/renders" - data = { - "template_id": template_id, - "modifications": modifications, - } - client = await get_shared_client() - response = await client.post( - url, json=data, headers=self.headers, timeout=60.0 - ) - response.raise_for_status() - return response.json() - - async def make_creatomate_custom_call(self, source: dict) -> dict: - """템플릿 없이 Creatomate에 커스텀 렌더링 요청을 보냅니다. - - Note: - response에 요청 정보가 있으니 폴링 필요 - """ - url = f"{self.BASE_URL}/v2/renders" - client = await get_shared_client() - response = await client.post( - url, json=source, headers=self.headers, timeout=60.0 - ) - response.raise_for_status() - return response.json() - - # 하위 호환성을 위한 별칭 (deprecated) - async def make_creatomate_custom_call_async(self, source: dict) -> dict: - """템플릿 없이 Creatomate에 커스텀 렌더링 요청을 보냅니다. - - Deprecated: make_creatomate_custom_call()을 사용하세요. - """ - return await self.make_creatomate_custom_call(source) - - async def get_render_status(self, render_id: str) -> dict: - """렌더링 작업의 상태를 조회합니다. - - Args: - render_id: Creatomate 렌더 ID - - Returns: - 렌더링 상태 정보 - - Note: - 상태 값: - - planned: 예약됨 - - waiting: 대기 중 - - transcribing: 트랜스크립션 중 - - rendering: 렌더링 중 - - succeeded: 성공 - - failed: 실패 - """ - url = f"{self.BASE_URL}/v1/renders/{render_id}" - client = await get_shared_client() - response = await client.get(url, headers=self.headers, timeout=30.0) - response.raise_for_status() - return response.json() - - # 하위 호환성을 위한 별칭 (deprecated) - async def get_render_status_async(self, render_id: str) -> dict: - """렌더링 작업의 상태를 조회합니다. - - Deprecated: get_render_status()를 사용하세요. - """ - return await self.get_render_status(render_id) - - def calc_scene_duration(self, template: dict) -> float: - """템플릿의 전체 장면 duration을 계산합니다.""" - total_template_duration = 0.0 - - for elem in template["source"]["elements"]: - try: - if elem["type"] == "audio": - continue - total_template_duration += elem["duration"] - if "animations" not in elem: - continue - for animation in elem["animations"]: - assert animation["time"] == 0 # 0이 아닌 경우 확인 필요 - if animation["transition"]: - total_template_duration -= animation["duration"] - except Exception as e: - print(f"[calc_scene_duration] Error processing element: {elem}, {e}") - - return total_template_duration - - def extend_template_duration(self, template: dict, target_duration: float) -> dict: - """템플릿의 duration을 target_duration으로 확장합니다.""" - template["duration"] = target_duration - total_template_duration = self.calc_scene_duration(template) - extend_rate = target_duration / total_template_duration - new_template = copy.deepcopy(template) - - for elem in new_template["source"]["elements"]: - try: - if elem["type"] == "audio": - continue - elem["duration"] = elem["duration"] * extend_rate - if "animations" not in elem: - continue - for animation in elem["animations"]: - assert animation["time"] == 0 # 0이 아닌 경우 확인 필요 - animation["duration"] = animation["duration"] * extend_rate - except Exception as e: - print( - f"[extend_template_duration] Error processing element: {elem}, {e}" - ) - - return new_template +""" +Creatomate API 클라이언트 모듈 + +API 문서: https://creatomate.com/docs/api + +## 사용법 +```python +from app.utils.creatomate import CreatomateService + +# config에서 자동으로 API 키를 가져옴 +creatomate = CreatomateService() + +# 또는 명시적으로 API 키 전달 +creatomate = CreatomateService(api_key="your_api_key") + +# 템플릿 목록 조회 (비동기) +templates = await creatomate.get_all_templates_data() + +# 특정 템플릿 조회 (비동기) +template = await creatomate.get_one_template_data(template_id) + +# 영상 렌더링 요청 (비동기) +response = await creatomate.make_creatomate_call(template_id, modifications) +``` + +## 성능 최적화 +- 템플릿 캐싱: 템플릿 데이터는 메모리에 캐싱되어 반복 조회 시 API 호출을 줄입니다. +- HTTP 클라이언트 재사용: 모듈 레벨의 공유 클라이언트로 커넥션 풀을 재사용합니다. +- 캐시 만료: 기본 5분 후 자동 만료 (CACHE_TTL_SECONDS로 조정 가능) +""" + +import copy +import logging +import time +from typing import Literal + +import httpx + +from config import apikey_settings, creatomate_settings + +# 로거 설정 +logger = logging.getLogger(__name__) + + +# Orientation 타입 정의 +OrientationType = Literal["horizontal", "vertical"] + +# ============================================================================= +# 모듈 레벨 캐시 및 HTTP 클라이언트 (싱글톤 패턴) +# ============================================================================= + +# 템플릿 캐시: {template_id: {"data": dict, "cached_at": float}} +_template_cache: dict[str, dict] = {} + +# 캐시 TTL (초) - 기본 5분 +CACHE_TTL_SECONDS = 300 + +# 모듈 레벨 공유 HTTP 클라이언트 (커넥션 풀 재사용) +_shared_client: httpx.AsyncClient | None = None + + +async def get_shared_client() -> httpx.AsyncClient: + """공유 HTTP 클라이언트를 반환합니다. 없으면 생성합니다.""" + global _shared_client + if _shared_client is None or _shared_client.is_closed: + _shared_client = httpx.AsyncClient( + timeout=httpx.Timeout(60.0, connect=10.0), + limits=httpx.Limits(max_keepalive_connections=10, max_connections=20), + ) + return _shared_client + + +async def close_shared_client() -> None: + """공유 HTTP 클라이언트를 닫습니다. 앱 종료 시 호출하세요.""" + global _shared_client + if _shared_client is not None and not _shared_client.is_closed: + await _shared_client.aclose() + _shared_client = None + print("[CreatomateService] Shared HTTP client closed") + + +def clear_template_cache() -> None: + """템플릿 캐시를 전체 삭제합니다.""" + global _template_cache + _template_cache.clear() + print("[CreatomateService] Template cache cleared") + + +def _is_cache_valid(cached_at: float) -> bool: + """캐시가 유효한지 확인합니다.""" + return (time.time() - cached_at) < CACHE_TTL_SECONDS + + +class CreatomateService: + """Creatomate API를 통한 영상 생성 서비스 + + 모든 HTTP 호출 메서드는 비동기(async)로 구현되어 있습니다. + """ + + BASE_URL = "https://api.creatomate.com" + + # 템플릿 설정 (config에서 가져옴) + TEMPLATE_CONFIG = { + "horizontal": { + "template_id": creatomate_settings.TEMPLATE_ID_HORIZONTAL, + "duration": creatomate_settings.TEMPLATE_DURATION_HORIZONTAL, + }, + "vertical": { + "template_id": creatomate_settings.TEMPLATE_ID_VERTICAL, + "duration": creatomate_settings.TEMPLATE_DURATION_VERTICAL, + }, + } + + def __init__( + self, + api_key: str | None = None, + orientation: OrientationType = "vertical", + target_duration: float | None = None, + ): + """ + Args: + api_key: Creatomate API 키 (Bearer token으로 사용) + None일 경우 config에서 자동으로 가져옴 + orientation: 영상 방향 ("horizontal" 또는 "vertical", 기본값: "vertical") + target_duration: 목표 영상 길이 (초) + None일 경우 orientation에 해당하는 기본값 사용 + """ + self.api_key = api_key or apikey_settings.CREATOMATE_API_KEY + self.orientation = orientation + + # orientation에 따른 템플릿 설정 가져오기 + config = self.TEMPLATE_CONFIG.get( + orientation, self.TEMPLATE_CONFIG["vertical"] + ) + self.template_id = config["template_id"] + self.target_duration = ( + target_duration if target_duration is not None else config["duration"] + ) + + self.headers = { + "Content-Type": "application/json", + "Authorization": f"Bearer {self.api_key}", + } + + async def _request( + self, + method: str, + url: str, + timeout: float = 30.0, + **kwargs, + ) -> httpx.Response: + """HTTP 요청을 수행합니다. + + Args: + method: HTTP 메서드 ("GET", "POST", etc.) + url: 요청 URL + timeout: 요청 타임아웃 (초) + **kwargs: httpx 요청에 전달할 추가 인자 + + Returns: + httpx.Response: 응답 객체 + + Raises: + httpx.HTTPError: 요청 실패 시 + """ + logger.info(f"[Creatomate] {method} {url}") + print(f"[Creatomate] {method} {url}") + + client = await get_shared_client() + + if method.upper() == "GET": + response = await client.get( + url, headers=self.headers, timeout=timeout, **kwargs + ) + elif method.upper() == "POST": + response = await client.post( + url, headers=self.headers, timeout=timeout, **kwargs + ) + else: + raise ValueError(f"Unsupported HTTP method: {method}") + + logger.info(f"[Creatomate] Response - Status: {response.status_code}") + print(f"[Creatomate] Response - Status: {response.status_code}") + return response + + async def get_all_templates_data(self) -> dict: + """모든 템플릿 정보를 조회합니다.""" + url = f"{self.BASE_URL}/v1/templates" + response = await self._request("GET", url, timeout=30.0) + response.raise_for_status() + return response.json() + + async def get_one_template_data( + self, + template_id: str, + use_cache: bool = True, + ) -> dict: + """특정 템플릿 ID로 템플릿 정보를 조회합니다. + + Args: + template_id: 조회할 템플릿 ID + use_cache: 캐시 사용 여부 (기본: True) + + Returns: + 템플릿 데이터 (deep copy) + """ + global _template_cache + + # 캐시 확인 + if use_cache and template_id in _template_cache: + cached = _template_cache[template_id] + if _is_cache_valid(cached["cached_at"]): + print(f"[CreatomateService] Cache HIT - {template_id}") + return copy.deepcopy(cached["data"]) + else: + # 만료된 캐시 삭제 + del _template_cache[template_id] + print(f"[CreatomateService] Cache EXPIRED - {template_id}") + + # API 호출 + url = f"{self.BASE_URL}/v1/templates/{template_id}" + response = await self._request("GET", url, timeout=30.0) + response.raise_for_status() + data = response.json() + + # 캐시 저장 + _template_cache[template_id] = { + "data": data, + "cached_at": time.time(), + } + print(f"[CreatomateService] Cache MISS - {template_id} (cached)") + + return copy.deepcopy(data) + + # 하위 호환성을 위한 별칭 (deprecated) + async def get_one_template_data_async(self, template_id: str) -> dict: + """특정 템플릿 ID로 템플릿 정보를 조회합니다. + + Deprecated: get_one_template_data()를 사용하세요. + """ + return await self.get_one_template_data(template_id) + + def parse_template_component_name(self, template_source: list) -> dict: + """템플릿 정보를 파싱하여 리소스 이름을 추출합니다.""" + + def recursive_parse_component(element: dict) -> dict: + if "name" in element: + result_element_name_type = {element["name"]: element["type"]} + else: + result_element_name_type = {} + + if element["type"] == "composition": + minor_component_list = [ + recursive_parse_component(minor) for minor in element["elements"] + ] + # WARNING: Same name component should shroud other component + for minor_component in minor_component_list: + result_element_name_type.update(minor_component) + + return result_element_name_type + + result = {} + for result_element_dict in [ + recursive_parse_component(component) for component in template_source + ]: + result.update(result_element_dict) + + return result + + async def template_connect_resource_blackbox( + self, + template_id: str, + image_url_list: list[str], + lyric: str, + music_url: str, + ) -> dict: + """템플릿 정보와 이미지/가사/음악 리소스를 매핑합니다. + + Note: + - 이미지는 순차적으로 집어넣기 + - 가사는 개행마다 한 텍스트 삽입 + - Template에 audio-music 항목이 있어야 함 + """ + template_data = await self.get_one_template_data(template_id) + template_component_data = self.parse_template_component_name( + template_data["source"]["elements"] + ) + + lyric = lyric.replace("\r", "") + lyric_splited = lyric.split("\n") + modifications = {} + + for idx, (template_component_name, template_type) in enumerate( + template_component_data.items() + ): + match template_type: + case "image": + modifications[template_component_name] = image_url_list[ + idx % len(image_url_list) + ] + case "text": + modifications[template_component_name] = lyric_splited[ + idx % len(lyric_splited) + ] + + modifications["audio-music"] = music_url + + return modifications + + def elements_connect_resource_blackbox( + self, + elements: list, + image_url_list: list[str], + lyric: str, + music_url: str, + ) -> dict: + """elements 정보와 이미지/가사/음악 리소스를 매핑합니다.""" + template_component_data = self.parse_template_component_name(elements) + + lyric = lyric.replace("\r", "") + lyric_splited = lyric.split("\n") + modifications = {} + + for idx, (template_component_name, template_type) in enumerate( + template_component_data.items() + ): + match template_type: + case "image": + modifications[template_component_name] = image_url_list[ + idx % len(image_url_list) + ] + case "text": + modifications[template_component_name] = lyric_splited[ + idx % len(lyric_splited) + ] + + modifications["audio-music"] = music_url + + return modifications + + def modify_element(self, elements: list, modification: dict) -> list: + """elements의 source를 modification에 따라 수정합니다.""" + + def recursive_modify(element: dict) -> None: + if "name" in element: + match element["type"]: + case "image": + element["source"] = modification[element["name"]] + case "audio": + element["source"] = modification.get(element["name"], "") + case "video": + element["source"] = modification[element["name"]] + case "text": + element["source"] = modification.get(element["name"], "") + case "composition": + for minor in element["elements"]: + recursive_modify(minor) + + for minor in elements: + recursive_modify(minor) + + return elements + + async def make_creatomate_call( + self, template_id: str, modifications: dict + ) -> dict: + """Creatomate에 렌더링 요청을 보냅니다. + + Note: + response에 요청 정보가 있으니 폴링 필요 + """ + url = f"{self.BASE_URL}/v2/renders" + data = { + "template_id": template_id, + "modifications": modifications, + } + response = await self._request("POST", url, timeout=60.0, json=data) + response.raise_for_status() + return response.json() + + async def make_creatomate_custom_call(self, source: dict) -> dict: + """템플릿 없이 Creatomate에 커스텀 렌더링 요청을 보냅니다. + + Note: + response에 요청 정보가 있으니 폴링 필요 + """ + url = f"{self.BASE_URL}/v2/renders" + response = await self._request("POST", url, timeout=60.0, json=source) + response.raise_for_status() + return response.json() + + # 하위 호환성을 위한 별칭 (deprecated) + async def make_creatomate_custom_call_async(self, source: dict) -> dict: + """템플릿 없이 Creatomate에 커스텀 렌더링 요청을 보냅니다. + + Deprecated: make_creatomate_custom_call()을 사용하세요. + """ + return await self.make_creatomate_custom_call(source) + + async def get_render_status(self, render_id: str) -> dict: + """렌더링 작업의 상태를 조회합니다. + + Args: + render_id: Creatomate 렌더 ID + + Returns: + 렌더링 상태 정보 + + Note: + 상태 값: + - planned: 예약됨 + - waiting: 대기 중 + - transcribing: 트랜스크립션 중 + - rendering: 렌더링 중 + - succeeded: 성공 + - failed: 실패 + """ + url = f"{self.BASE_URL}/v1/renders/{render_id}" + response = await self._request("GET", url, timeout=30.0) + response.raise_for_status() + return response.json() + + # 하위 호환성을 위한 별칭 (deprecated) + async def get_render_status_async(self, render_id: str) -> dict: + """렌더링 작업의 상태를 조회합니다. + + Deprecated: get_render_status()를 사용하세요. + """ + return await self.get_render_status(render_id) + + def calc_scene_duration(self, template: dict) -> float: + """템플릿의 전체 장면 duration을 계산합니다.""" + total_template_duration = 0.0 + + for elem in template["source"]["elements"]: + try: + if elem["type"] == "audio": + continue + total_template_duration += elem["duration"] + if "animations" not in elem: + continue + for animation in elem["animations"]: + assert animation["time"] == 0 # 0이 아닌 경우 확인 필요 + if animation["transition"]: + total_template_duration -= animation["duration"] + except Exception as e: + print(f"[calc_scene_duration] Error processing element: {elem}, {e}") + + return total_template_duration + + def extend_template_duration(self, template: dict, target_duration: float) -> dict: + """템플릿의 duration을 target_duration으로 확장합니다.""" + template["duration"] = target_duration + total_template_duration = self.calc_scene_duration(template) + extend_rate = target_duration / total_template_duration + new_template = copy.deepcopy(template) + + for elem in new_template["source"]["elements"]: + try: + if elem["type"] == "audio": + continue + elem["duration"] = elem["duration"] * extend_rate + if "animations" not in elem: + continue + for animation in elem["animations"]: + assert animation["time"] == 0 # 0이 아닌 경우 확인 필요 + animation["duration"] = animation["duration"] * extend_rate + except Exception as e: + print( + f"[extend_template_duration] Error processing element: {elem}, {e}" + ) + + return new_template diff --git a/app/utils/nvMapScraper.py b/app/utils/nvMapScraper.py index 196ecbe..1edf149 100644 --- a/app/utils/nvMapScraper.py +++ b/app/utils/nvMapScraper.py @@ -1,114 +1,163 @@ -import json -import re - -import aiohttp - -from config import crawler_settings - - -class GraphQLException(Exception): - pass - - -class NvMapScraper: - GRAPHQL_URL: str = "https://pcmap-api.place.naver.com/graphql" - - OVERVIEW_QUERY: str = """ -query getAccommodation($id: String!, $deviceType: String) { - business: placeDetail(input: {id: $id, isNx: true, deviceType: $deviceType}) { - base { - id - name - category - roadAddress - address - phone - virtualPhone - microReviews - conveniences - visitorReviewsTotal - } - images { images { origin url } } - cpImages(source: [ugcImage]) { images { origin url } } - } -}""" - - DEFAULT_HEADERS: dict = { - "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36", - "Referer": "https://map.naver.com/", - "Origin": "https://map.naver.com", - "Content-Type": "application/json", - } - - def __init__(self, url: str, cookies: str | None = None): - self.url = url - self.cookies = ( - cookies if cookies is not None else crawler_settings.NAVER_COOKIES - ) - self.scrap_type: str | None = None - self.rawdata: dict | None = None - self.image_link_list: list[str] | None = None - self.base_info: dict | None = None - - def _get_request_headers(self) -> dict: - headers = self.DEFAULT_HEADERS.copy() - if self.cookies: - headers["Cookie"] = self.cookies - return headers - - def parse_url(self) -> str: - place_pattern = r"/place/(\d+)" - match = re.search(place_pattern, self.url) - if not match: - raise GraphQLException("Failed to parse place ID from URL") - return match[1] - - async def scrap(self): - try: - place_id = self.parse_url() - data = await self._call_get_accommodation(place_id) - self.rawdata = data - self.image_link_list = [ - nv_image["origin"] - for nv_image in data["data"]["business"]["images"]["images"] - ] - self.base_info = data["data"]["business"]["base"] - self.scrap_type = "GraphQL" - - except GraphQLException: - print("fallback") - self.scrap_type = "Playwright" - pass # 나중에 pw 이용한 crawling으로 fallback 추가 - - return - - async def _call_get_accommodation(self, place_id: str) -> dict: - payload = { - "operationName": "getAccommodation", - "variables": {"id": place_id, "deviceType": "pc"}, - "query": self.OVERVIEW_QUERY, - } - json_payload = json.dumps(payload) - - async with aiohttp.ClientSession() as session: - async with session.post( - self.GRAPHQL_URL, data=json_payload, headers=self._get_request_headers() - ) as response: - if response.status == 200: - return await response.json() - else: - print("실패 상태 코드:", response.status) - raise GraphQLException( - f"Request failed with status {response.status}" - ) - - -# if __name__ == "__main__": -# import asyncio - -# url = "https://map.naver.com/p/search/%EC%8A%A4%ED%85%8C%EC%9D%B4%EB%A8%B8%EB%AD%84/place/1133638931?c=14.70,0,0,0,dh&placePath=/photo?businessCategory=pension&fromPanelNum=2&locale=ko&searchText=%EC%8A%A4%ED%85%8C%EC%9D%B4%EB%A8%B8%EB%AD%84&svcName=map_pcv5×tamp=202512191123&fromPanelNum=2&locale=ko&searchText=%EC%8A%A4%ED%85%8C%EC%9D%B4%EB%A8%B8%EB%AD%84&svcName=map_pcv5×tamp=202512191007&from=map&entry=bmp&filterType=%EC%97%85%EC%B2%B4&businessCategory=pension" -# scraper = NvMapScraper(url) -# asyncio.run(scraper.scrap()) -# print(scraper.image_link_list) -# print(len(scraper.image_link_list) if scraper.image_link_list else 0) -# print(scraper.base_info) +import json +import logging +import re + +import aiohttp + +from config import crawler_settings + +# 로거 설정 +logger = logging.getLogger(__name__) + + +class GraphQLException(Exception): + """GraphQL 요청 실패 시 발생하는 예외""" + pass + + +class CrawlingTimeoutException(Exception): + """크롤링 타임아웃 시 발생하는 예외""" + pass + + +class NvMapScraper: + """네이버 지도 GraphQL API 스크래퍼 + + 네이버 지도에서 숙소/장소 정보를 크롤링합니다. + """ + + GRAPHQL_URL: str = "https://pcmap-api.place.naver.com/graphql" + REQUEST_TIMEOUT = 30 # 초 + + OVERVIEW_QUERY: str = """ +query getAccommodation($id: String!, $deviceType: String) { + business: placeDetail(input: {id: $id, isNx: true, deviceType: $deviceType}) { + base { + id + name + category + roadAddress + address + phone + virtualPhone + microReviews + conveniences + visitorReviewsTotal + } + images { images { origin url } } + cpImages(source: [ugcImage]) { images { origin url } } + } +}""" + + DEFAULT_HEADERS: dict = { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36", + "Referer": "https://map.naver.com/", + "Origin": "https://map.naver.com", + "Content-Type": "application/json", + } + + def __init__(self, url: str, cookies: str | None = None): + self.url = url + self.cookies = ( + cookies if cookies is not None else crawler_settings.NAVER_COOKIES + ) + self.scrap_type: str | None = None + self.rawdata: dict | None = None + self.image_link_list: list[str] | None = None + self.base_info: dict | None = None + + def _get_request_headers(self) -> dict: + headers = self.DEFAULT_HEADERS.copy() + if self.cookies: + headers["Cookie"] = self.cookies + return headers + + def parse_url(self) -> str: + place_pattern = r"/place/(\d+)" + match = re.search(place_pattern, self.url) + if not match: + raise GraphQLException("Failed to parse place ID from URL") + return match[1] + + async def scrap(self): + try: + place_id = self.parse_url() + data = await self._call_get_accommodation(place_id) + self.rawdata = data + self.image_link_list = [ + nv_image["origin"] + for nv_image in data["data"]["business"]["images"]["images"] + ] + self.base_info = data["data"]["business"]["base"] + self.scrap_type = "GraphQL" + + except GraphQLException: + print("fallback") + self.scrap_type = "Playwright" + pass # 나중에 pw 이용한 crawling으로 fallback 추가 + + return + + async def _call_get_accommodation(self, place_id: str) -> dict: + """GraphQL API를 호출하여 숙소 정보를 가져옵니다. + + Args: + place_id: 네이버 지도 장소 ID + + Returns: + GraphQL 응답 데이터 + + Raises: + GraphQLException: API 호출 실패 시 + CrawlingTimeoutException: 타임아웃 발생 시 + """ + payload = { + "operationName": "getAccommodation", + "variables": {"id": place_id, "deviceType": "pc"}, + "query": self.OVERVIEW_QUERY, + } + json_payload = json.dumps(payload) + timeout = aiohttp.ClientTimeout(total=self.REQUEST_TIMEOUT) + + try: + logger.info(f"[NvMapScraper] Requesting place_id: {place_id}") + print(f"[NvMapScraper] Requesting place_id: {place_id}") + + async with aiohttp.ClientSession(timeout=timeout) as session: + async with session.post( + self.GRAPHQL_URL, + data=json_payload, + headers=self._get_request_headers() + ) as response: + if response.status == 200: + logger.info(f"[NvMapScraper] SUCCESS - place_id: {place_id}") + print(f"[NvMapScraper] SUCCESS - place_id: {place_id}") + return await response.json() + + # 실패 상태 코드 + logger.error(f"[NvMapScraper] Failed with status {response.status} - place_id: {place_id}") + print(f"[NvMapScraper] 실패 상태 코드: {response.status}") + raise GraphQLException( + f"Request failed with status {response.status}" + ) + + except TimeoutError: + logger.error(f"[NvMapScraper] Timeout - place_id: {place_id}") + print(f"[NvMapScraper] Timeout - place_id: {place_id}") + raise CrawlingTimeoutException(f"Request timed out after {self.REQUEST_TIMEOUT}s") + + except aiohttp.ClientError as e: + logger.error(f"[NvMapScraper] Client error: {e}") + print(f"[NvMapScraper] Client error: {e}") + raise GraphQLException(f"Client error: {e}") + + +# if __name__ == "__main__": +# import asyncio + +# url = "https://map.naver.com/p/search/%EC%8A%A4%ED%85%8C%EC%9D%B4%EB%A8%B8%EB%AD%84/place/1133638931?c=14.70,0,0,0,dh&placePath=/photo?businessCategory=pension&fromPanelNum=2&locale=ko&searchText=%EC%8A%A4%ED%85%8C%EC%9D%B4%EB%A8%B8%EB%AD%84&svcName=map_pcv5×tamp=202512191123&fromPanelNum=2&locale=ko&searchText=%EC%8A%A4%ED%85%8C%EC%9D%B4%EB%A8%B8%EB%AD%84&svcName=map_pcv5×tamp=202512191007&from=map&entry=bmp&filterType=%EC%97%85%EC%B2%B4&businessCategory=pension" +# scraper = NvMapScraper(url) +# asyncio.run(scraper.scrap()) +# print(scraper.image_link_list) +# print(len(scraper.image_link_list) if scraper.image_link_list else 0) +# print(scraper.base_info) diff --git a/app/utils/upload_blob_as_request.py b/app/utils/upload_blob_as_request.py index c4be083..921e4e9 100644 --- a/app/utils/upload_blob_as_request.py +++ b/app/utils/upload_blob_as_request.py @@ -1,443 +1,468 @@ -""" -Azure Blob Storage 업로드 유틸리티 - -Azure Blob Storage에 파일을 업로드하는 클래스를 제공합니다. -파일 경로 또는 바이트 데이터를 직접 업로드할 수 있습니다. - -URL 경로 형식: - - 음악: {BASE_URL}/{task_id}/song/{파일명} - - 영상: {BASE_URL}/{task_id}/video/{파일명} - - 이미지: {BASE_URL}/{task_id}/image/{파일명} - -사용 예시: - from app.utils.upload_blob_as_request import AzureBlobUploader - - uploader = AzureBlobUploader(task_id="task-123") - - # 파일 경로로 업로드 - success = await uploader.upload_music(file_path="my_song.mp3") - success = await uploader.upload_video(file_path="my_video.mp4") - success = await uploader.upload_image(file_path="my_image.png") - - # 바이트 데이터로 직접 업로드 (media 저장 없이) - success = await uploader.upload_music_bytes(audio_bytes, "my_song") - success = await uploader.upload_video_bytes(video_bytes, "my_video") - success = await uploader.upload_image_bytes(image_bytes, "my_image.png") - - print(uploader.public_url) # 마지막 업로드의 공개 URL - -성능 최적화: - - HTTP 클라이언트 재사용: 모듈 레벨의 공유 클라이언트로 커넥션 풀 재사용 - - 동시 업로드: 공유 클라이언트를 통해 동시 요청 처리가 개선됩니다. -""" - -import asyncio -import time -from pathlib import Path - -import aiofiles -import httpx - -from config import azure_blob_settings - - -# ============================================================================= -# 모듈 레벨 공유 HTTP 클라이언트 (싱글톤 패턴) -# ============================================================================= - -# 모듈 레벨 공유 HTTP 클라이언트 (커넥션 풀 재사용) -_shared_blob_client: httpx.AsyncClient | None = None - - -async def get_shared_blob_client() -> httpx.AsyncClient: - """공유 HTTP 클라이언트를 반환합니다. 없으면 생성합니다.""" - global _shared_blob_client - if _shared_blob_client is None or _shared_blob_client.is_closed: - print("[AzureBlobUploader] Creating shared HTTP client...") - _shared_blob_client = httpx.AsyncClient( - timeout=httpx.Timeout(180.0, connect=10.0), - limits=httpx.Limits(max_keepalive_connections=10, max_connections=20), - ) - print("[AzureBlobUploader] Shared HTTP client created - " - "max_connections: 20, max_keepalive: 10") - return _shared_blob_client - - -async def close_shared_blob_client() -> None: - """공유 HTTP 클라이언트를 닫습니다. 앱 종료 시 호출하세요.""" - global _shared_blob_client - if _shared_blob_client is not None and not _shared_blob_client.is_closed: - await _shared_blob_client.aclose() - _shared_blob_client = None - print("[AzureBlobUploader] Shared HTTP client closed") - - -class AzureBlobUploader: - """Azure Blob Storage 업로드 클래스 - - Azure Blob Storage에 음악, 영상, 이미지 파일을 업로드합니다. - URL 형식: {BASE_URL}/{task_id}/{category}/{file_name}?{SAS_TOKEN} - - 카테고리별 경로: - - 음악: {task_id}/song/{file_name} - - 영상: {task_id}/video/{file_name} - - 이미지: {task_id}/image/{file_name} - - Attributes: - task_id: 작업 고유 식별자 - """ - - # Content-Type 매핑 - IMAGE_CONTENT_TYPES = { - ".jpg": "image/jpeg", - ".jpeg": "image/jpeg", - ".png": "image/png", - ".gif": "image/gif", - ".webp": "image/webp", - ".bmp": "image/bmp", - } - - def __init__(self, task_id: str): - """AzureBlobUploader 초기화 - - Args: - task_id: 작업 고유 식별자 - """ - self._task_id = task_id - self._base_url = azure_blob_settings.AZURE_BLOB_BASE_URL - self._sas_token = azure_blob_settings.AZURE_BLOB_SAS_TOKEN - self._last_public_url: str = "" - - @property - def task_id(self) -> str: - """작업 고유 식별자""" - return self._task_id - - @property - def public_url(self) -> str: - """마지막 업로드의 공개 URL (SAS 토큰 제외)""" - return self._last_public_url - - def _build_upload_url(self, category: str, file_name: str) -> str: - """업로드 URL 생성 (SAS 토큰 포함)""" - # SAS 토큰 앞뒤의 ?, ', " 제거 - sas_token = self._sas_token.strip("?'\"") - return ( - f"{self._base_url}/{self._task_id}/{category}/{file_name}?{sas_token}" - ) - - def _build_public_url(self, category: str, file_name: str) -> str: - """공개 URL 생성 (SAS 토큰 제외)""" - return f"{self._base_url}/{self._task_id}/{category}/{file_name}" - - async def _upload_bytes( - self, - file_content: bytes, - upload_url: str, - headers: dict, - timeout: float, - log_prefix: str, - ) -> bool: - """바이트 데이터를 업로드하는 공통 내부 메서드""" - start_time = time.perf_counter() - - try: - print(f"[{log_prefix}] Getting shared client...") - client = await get_shared_blob_client() - client_time = time.perf_counter() - elapsed_ms = (client_time - start_time) * 1000 - print(f"[{log_prefix}] Client acquired in {elapsed_ms:.1f}ms") - - size = len(file_content) - print(f"[{log_prefix}] Starting upload... " - f"(size: {size} bytes, timeout: {timeout}s)") - - response = await asyncio.wait_for( - client.put(upload_url, content=file_content, headers=headers), - timeout=timeout, - ) - upload_time = time.perf_counter() - duration_ms = (upload_time - start_time) * 1000 - - if response.status_code in [200, 201]: - print(f"[{log_prefix}] SUCCESS - Status: {response.status_code}, " - f"Duration: {duration_ms:.1f}ms") - print(f"[{log_prefix}] Public URL: {self._last_public_url}") - return True - else: - print(f"[{log_prefix}] FAILED - Status: {response.status_code}, " - f"Duration: {duration_ms:.1f}ms") - print(f"[{log_prefix}] Response: {response.text[:500]}") - return False - - except asyncio.TimeoutError: - elapsed = time.perf_counter() - start_time - print(f"[{log_prefix}] TIMEOUT after {elapsed:.1f}s " - f"(limit: {timeout}s)") - return False - except httpx.ConnectError as e: - elapsed = time.perf_counter() - start_time - print(f"[{log_prefix}] CONNECT_ERROR after {elapsed:.1f}s - " - f"{type(e).__name__}: {e}") - return False - except httpx.ReadError as e: - elapsed = time.perf_counter() - start_time - print(f"[{log_prefix}] READ_ERROR after {elapsed:.1f}s - " - f"{type(e).__name__}: {e}") - return False - except Exception as e: - elapsed = time.perf_counter() - start_time - print(f"[{log_prefix}] ERROR after {elapsed:.1f}s - " - f"{type(e).__name__}: {e}") - return False - - async def _upload_file( - self, - file_path: str, - category: str, - content_type: str, - timeout: float, - log_prefix: str, - ) -> bool: - """파일을 Azure Blob Storage에 업로드하는 내부 메서드 - - Args: - file_path: 업로드할 파일 경로 - category: 카테고리 (song, video, image) - content_type: Content-Type 헤더 값 - timeout: 요청 타임아웃 (초) - log_prefix: 로그 접두사 - - Returns: - bool: 업로드 성공 여부 - """ - # 파일 경로에서 파일명 추출 - file_name = Path(file_path).name - - upload_url = self._build_upload_url(category, file_name) - self._last_public_url = self._build_public_url(category, file_name) - print(f"[{log_prefix}] URL (without SAS): {self._last_public_url}") - - headers = {"Content-Type": content_type, "x-ms-blob-type": "BlockBlob"} - - async with aiofiles.open(file_path, "rb") as file: - file_content = await file.read() - - return await self._upload_bytes( - file_content=file_content, - upload_url=upload_url, - headers=headers, - timeout=timeout, - log_prefix=log_prefix, - ) - - async def upload_music(self, file_path: str) -> bool: - """음악 파일을 Azure Blob Storage에 업로드합니다. - - URL 경로: {task_id}/song/{파일명} - - Args: - file_path: 업로드할 파일 경로 - - Returns: - bool: 업로드 성공 여부 - - Example: - uploader = AzureBlobUploader(task_id="task-123") - success = await uploader.upload_music(file_path="my_song.mp3") - print(uploader.public_url) - """ - return await self._upload_file( - file_path=file_path, - category="song", - content_type="audio/mpeg", - timeout=120.0, - log_prefix="upload_music", - ) - - async def upload_music_bytes( - self, file_content: bytes, file_name: str - ) -> bool: - """음악 바이트 데이터를 Azure Blob Storage에 직접 업로드합니다. - - URL 경로: {task_id}/song/{파일명} - - Args: - file_content: 업로드할 파일 바이트 데이터 - file_name: 저장할 파일명 (확장자가 없으면 .mp3 추가) - - Returns: - bool: 업로드 성공 여부 - - Example: - uploader = AzureBlobUploader(task_id="task-123") - success = await uploader.upload_music_bytes(audio_bytes, "my_song") - print(uploader.public_url) - """ - # 확장자가 없으면 .mp3 추가 - if not Path(file_name).suffix: - file_name = f"{file_name}.mp3" - - upload_url = self._build_upload_url("song", file_name) - self._last_public_url = self._build_public_url("song", file_name) - log_prefix = "upload_music_bytes" - print(f"[{log_prefix}] URL (without SAS): {self._last_public_url}") - - headers = {"Content-Type": "audio/mpeg", "x-ms-blob-type": "BlockBlob"} - - return await self._upload_bytes( - file_content=file_content, - upload_url=upload_url, - headers=headers, - timeout=120.0, - log_prefix=log_prefix, - ) - - async def upload_video(self, file_path: str) -> bool: - """영상 파일을 Azure Blob Storage에 업로드합니다. - - URL 경로: {task_id}/video/{파일명} - - Args: - file_path: 업로드할 파일 경로 - - Returns: - bool: 업로드 성공 여부 - - Example: - uploader = AzureBlobUploader(task_id="task-123") - success = await uploader.upload_video(file_path="my_video.mp4") - print(uploader.public_url) - """ - return await self._upload_file( - file_path=file_path, - category="video", - content_type="video/mp4", - timeout=180.0, - log_prefix="upload_video", - ) - - async def upload_video_bytes( - self, file_content: bytes, file_name: str - ) -> bool: - """영상 바이트 데이터를 Azure Blob Storage에 직접 업로드합니다. - - URL 경로: {task_id}/video/{파일명} - - Args: - file_content: 업로드할 파일 바이트 데이터 - file_name: 저장할 파일명 (확장자가 없으면 .mp4 추가) - - Returns: - bool: 업로드 성공 여부 - - Example: - uploader = AzureBlobUploader(task_id="task-123") - success = await uploader.upload_video_bytes(video_bytes, "my_video") - print(uploader.public_url) - """ - # 확장자가 없으면 .mp4 추가 - if not Path(file_name).suffix: - file_name = f"{file_name}.mp4" - - upload_url = self._build_upload_url("video", file_name) - self._last_public_url = self._build_public_url("video", file_name) - log_prefix = "upload_video_bytes" - print(f"[{log_prefix}] URL (without SAS): {self._last_public_url}") - - headers = {"Content-Type": "video/mp4", "x-ms-blob-type": "BlockBlob"} - - return await self._upload_bytes( - file_content=file_content, - upload_url=upload_url, - headers=headers, - timeout=180.0, - log_prefix=log_prefix, - ) - - async def upload_image(self, file_path: str) -> bool: - """이미지 파일을 Azure Blob Storage에 업로드합니다. - - URL 경로: {task_id}/image/{파일명} - - Args: - file_path: 업로드할 파일 경로 - - Returns: - bool: 업로드 성공 여부 - - Example: - uploader = AzureBlobUploader(task_id="task-123") - success = await uploader.upload_image(file_path="my_image.png") - print(uploader.public_url) - """ - extension = Path(file_path).suffix.lower() - content_type = self.IMAGE_CONTENT_TYPES.get(extension, "image/jpeg") - - return await self._upload_file( - file_path=file_path, - category="image", - content_type=content_type, - timeout=60.0, - log_prefix="upload_image", - ) - - async def upload_image_bytes( - self, file_content: bytes, file_name: str - ) -> bool: - """이미지 바이트 데이터를 Azure Blob Storage에 직접 업로드합니다. - - URL 경로: {task_id}/image/{파일명} - - Args: - file_content: 업로드할 파일 바이트 데이터 - file_name: 저장할 파일명 - - Returns: - bool: 업로드 성공 여부 - - Example: - uploader = AzureBlobUploader(task_id="task-123") - with open("my_image.png", "rb") as f: - content = f.read() - success = await uploader.upload_image_bytes(content, "my_image.png") - print(uploader.public_url) - """ - extension = Path(file_name).suffix.lower() - content_type = self.IMAGE_CONTENT_TYPES.get(extension, "image/jpeg") - - upload_url = self._build_upload_url("image", file_name) - self._last_public_url = self._build_public_url("image", file_name) - log_prefix = "upload_image_bytes" - print(f"[{log_prefix}] URL (without SAS): {self._last_public_url}") - - headers = {"Content-Type": content_type, "x-ms-blob-type": "BlockBlob"} - - return await self._upload_bytes( - file_content=file_content, - upload_url=upload_url, - headers=headers, - timeout=60.0, - log_prefix=log_prefix, - ) - - -# 사용 예시: -# import asyncio -# -# async def main(): -# uploader = AzureBlobUploader(task_id="task-123") -# -# # 음악 업로드 -> {BASE_URL}/task-123/song/my_song.mp3 -# await uploader.upload_music("my_song.mp3") -# print(uploader.public_url) -# -# # 영상 업로드 -> {BASE_URL}/task-123/video/my_video.mp4 -# await uploader.upload_video("my_video.mp4") -# print(uploader.public_url) -# -# # 이미지 업로드 -> {BASE_URL}/task-123/image/my_image.png -# await uploader.upload_image("my_image.png") -# print(uploader.public_url) -# -# asyncio.run(main()) +""" +Azure Blob Storage 업로드 유틸리티 + +Azure Blob Storage에 파일을 업로드하는 클래스를 제공합니다. +파일 경로 또는 바이트 데이터를 직접 업로드할 수 있습니다. + +URL 경로 형식: + - 음악: {BASE_URL}/{task_id}/song/{파일명} + - 영상: {BASE_URL}/{task_id}/video/{파일명} + - 이미지: {BASE_URL}/{task_id}/image/{파일명} + +사용 예시: + from app.utils.upload_blob_as_request import AzureBlobUploader + + uploader = AzureBlobUploader(task_id="task-123") + + # 파일 경로로 업로드 + success = await uploader.upload_music(file_path="my_song.mp3") + success = await uploader.upload_video(file_path="my_video.mp4") + success = await uploader.upload_image(file_path="my_image.png") + + # 바이트 데이터로 직접 업로드 (media 저장 없이) + success = await uploader.upload_music_bytes(audio_bytes, "my_song") + success = await uploader.upload_video_bytes(video_bytes, "my_video") + success = await uploader.upload_image_bytes(image_bytes, "my_image.png") + + print(uploader.public_url) # 마지막 업로드의 공개 URL + +성능 최적화: + - HTTP 클라이언트 재사용: 모듈 레벨의 공유 클라이언트로 커넥션 풀 재사용 + - 동시 업로드: 공유 클라이언트를 통해 동시 요청 처리가 개선됩니다. +""" + +import asyncio +import logging +import time +from pathlib import Path + +import aiofiles +import httpx + +from config import azure_blob_settings + +# 로거 설정 +logger = logging.getLogger(__name__) + +# ============================================================================= +# 모듈 레벨 공유 HTTP 클라이언트 (싱글톤 패턴) +# ============================================================================= + +# 모듈 레벨 공유 HTTP 클라이언트 (커넥션 풀 재사용) +_shared_blob_client: httpx.AsyncClient | None = None + + +async def get_shared_blob_client() -> httpx.AsyncClient: + """공유 HTTP 클라이언트를 반환합니다. 없으면 생성합니다.""" + global _shared_blob_client + if _shared_blob_client is None or _shared_blob_client.is_closed: + print("[AzureBlobUploader] Creating shared HTTP client...") + _shared_blob_client = httpx.AsyncClient( + timeout=httpx.Timeout(180.0, connect=10.0), + limits=httpx.Limits(max_keepalive_connections=10, max_connections=20), + ) + print("[AzureBlobUploader] Shared HTTP client created - " + "max_connections: 20, max_keepalive: 10") + return _shared_blob_client + + +async def close_shared_blob_client() -> None: + """공유 HTTP 클라이언트를 닫습니다. 앱 종료 시 호출하세요.""" + global _shared_blob_client + if _shared_blob_client is not None and not _shared_blob_client.is_closed: + await _shared_blob_client.aclose() + _shared_blob_client = None + print("[AzureBlobUploader] Shared HTTP client closed") + + +class AzureBlobUploader: + """Azure Blob Storage 업로드 클래스 + + Azure Blob Storage에 음악, 영상, 이미지 파일을 업로드합니다. + URL 형식: {BASE_URL}/{task_id}/{category}/{file_name}?{SAS_TOKEN} + + 카테고리별 경로: + - 음악: {task_id}/song/{file_name} + - 영상: {task_id}/video/{file_name} + - 이미지: {task_id}/image/{file_name} + + Attributes: + task_id: 작업 고유 식별자 + """ + + # Content-Type 매핑 + IMAGE_CONTENT_TYPES = { + ".jpg": "image/jpeg", + ".jpeg": "image/jpeg", + ".png": "image/png", + ".gif": "image/gif", + ".webp": "image/webp", + ".bmp": "image/bmp", + } + + def __init__(self, task_id: str): + """AzureBlobUploader 초기화 + + Args: + task_id: 작업 고유 식별자 + """ + self._task_id = task_id + self._base_url = azure_blob_settings.AZURE_BLOB_BASE_URL + self._sas_token = azure_blob_settings.AZURE_BLOB_SAS_TOKEN + self._last_public_url: str = "" + + @property + def task_id(self) -> str: + """작업 고유 식별자""" + return self._task_id + + @property + def public_url(self) -> str: + """마지막 업로드의 공개 URL (SAS 토큰 제외)""" + return self._last_public_url + + def _build_upload_url(self, category: str, file_name: str) -> str: + """업로드 URL 생성 (SAS 토큰 포함)""" + # SAS 토큰 앞뒤의 ?, ', " 제거 + sas_token = self._sas_token.strip("?'\"") + return ( + f"{self._base_url}/{self._task_id}/{category}/{file_name}?{sas_token}" + ) + + def _build_public_url(self, category: str, file_name: str) -> str: + """공개 URL 생성 (SAS 토큰 제외)""" + return f"{self._base_url}/{self._task_id}/{category}/{file_name}" + + async def _upload_bytes( + self, + file_content: bytes, + upload_url: str, + headers: dict, + timeout: float, + log_prefix: str, + ) -> bool: + """바이트 데이터를 업로드하는 공통 내부 메서드 + + Args: + file_content: 업로드할 바이트 데이터 + upload_url: 업로드 URL + headers: HTTP 헤더 + timeout: 요청 타임아웃 (초) + log_prefix: 로그 접두사 + + Returns: + bool: 업로드 성공 여부 + """ + size = len(file_content) + start_time = time.perf_counter() + + try: + logger.info(f"[{log_prefix}] Starting upload") + print(f"[{log_prefix}] Getting shared client...") + + client = await get_shared_blob_client() + client_time = time.perf_counter() + elapsed_ms = (client_time - start_time) * 1000 + print(f"[{log_prefix}] Client acquired in {elapsed_ms:.1f}ms") + + print(f"[{log_prefix}] Starting upload... " + f"(size: {size} bytes, timeout: {timeout}s)") + + response = await asyncio.wait_for( + client.put(upload_url, content=file_content, headers=headers), + timeout=timeout, + ) + upload_time = time.perf_counter() + duration_ms = (upload_time - start_time) * 1000 + + if response.status_code in [200, 201]: + logger.info(f"[{log_prefix}] SUCCESS - Status: {response.status_code}") + print(f"[{log_prefix}] SUCCESS - Status: {response.status_code}, " + f"Duration: {duration_ms:.1f}ms") + print(f"[{log_prefix}] Public URL: {self._last_public_url}") + return True + + # 업로드 실패 + logger.error(f"[{log_prefix}] FAILED - Status: {response.status_code}") + print(f"[{log_prefix}] FAILED - Status: {response.status_code}, " + f"Duration: {duration_ms:.1f}ms") + print(f"[{log_prefix}] Response: {response.text[:500]}") + return False + + except asyncio.TimeoutError: + elapsed = time.perf_counter() - start_time + logger.error(f"[{log_prefix}] TIMEOUT after {elapsed:.1f}s") + print(f"[{log_prefix}] TIMEOUT after {elapsed:.1f}s") + return False + + except httpx.ConnectError as e: + elapsed = time.perf_counter() - start_time + logger.error(f"[{log_prefix}] CONNECT_ERROR: {e}") + print(f"[{log_prefix}] CONNECT_ERROR after {elapsed:.1f}s - " + f"{type(e).__name__}: {e}") + return False + + except httpx.ReadError as e: + elapsed = time.perf_counter() - start_time + logger.error(f"[{log_prefix}] READ_ERROR: {e}") + print(f"[{log_prefix}] READ_ERROR after {elapsed:.1f}s - " + f"{type(e).__name__}: {e}") + return False + + except Exception as e: + elapsed = time.perf_counter() - start_time + logger.error(f"[{log_prefix}] ERROR: {type(e).__name__}: {e}") + print(f"[{log_prefix}] ERROR after {elapsed:.1f}s - " + f"{type(e).__name__}: {e}") + return False + + async def _upload_file( + self, + file_path: str, + category: str, + content_type: str, + timeout: float, + log_prefix: str, + ) -> bool: + """파일을 Azure Blob Storage에 업로드하는 내부 메서드 + + Args: + file_path: 업로드할 파일 경로 + category: 카테고리 (song, video, image) + content_type: Content-Type 헤더 값 + timeout: 요청 타임아웃 (초) + log_prefix: 로그 접두사 + + Returns: + bool: 업로드 성공 여부 + """ + # 파일 경로에서 파일명 추출 + file_name = Path(file_path).name + + upload_url = self._build_upload_url(category, file_name) + self._last_public_url = self._build_public_url(category, file_name) + print(f"[{log_prefix}] URL (without SAS): {self._last_public_url}") + + headers = {"Content-Type": content_type, "x-ms-blob-type": "BlockBlob"} + + async with aiofiles.open(file_path, "rb") as file: + file_content = await file.read() + + return await self._upload_bytes( + file_content=file_content, + upload_url=upload_url, + headers=headers, + timeout=timeout, + log_prefix=log_prefix, + ) + + async def upload_music(self, file_path: str) -> bool: + """음악 파일을 Azure Blob Storage에 업로드합니다. + + URL 경로: {task_id}/song/{파일명} + + Args: + file_path: 업로드할 파일 경로 + + Returns: + bool: 업로드 성공 여부 + + Example: + uploader = AzureBlobUploader(task_id="task-123") + success = await uploader.upload_music(file_path="my_song.mp3") + print(uploader.public_url) + """ + return await self._upload_file( + file_path=file_path, + category="song", + content_type="audio/mpeg", + timeout=120.0, + log_prefix="upload_music", + ) + + async def upload_music_bytes( + self, file_content: bytes, file_name: str + ) -> bool: + """음악 바이트 데이터를 Azure Blob Storage에 직접 업로드합니다. + + URL 경로: {task_id}/song/{파일명} + + Args: + file_content: 업로드할 파일 바이트 데이터 + file_name: 저장할 파일명 (확장자가 없으면 .mp3 추가) + + Returns: + bool: 업로드 성공 여부 + + Example: + uploader = AzureBlobUploader(task_id="task-123") + success = await uploader.upload_music_bytes(audio_bytes, "my_song") + print(uploader.public_url) + """ + # 확장자가 없으면 .mp3 추가 + if not Path(file_name).suffix: + file_name = f"{file_name}.mp3" + + upload_url = self._build_upload_url("song", file_name) + self._last_public_url = self._build_public_url("song", file_name) + log_prefix = "upload_music_bytes" + print(f"[{log_prefix}] URL (without SAS): {self._last_public_url}") + + headers = {"Content-Type": "audio/mpeg", "x-ms-blob-type": "BlockBlob"} + + return await self._upload_bytes( + file_content=file_content, + upload_url=upload_url, + headers=headers, + timeout=120.0, + log_prefix=log_prefix, + ) + + async def upload_video(self, file_path: str) -> bool: + """영상 파일을 Azure Blob Storage에 업로드합니다. + + URL 경로: {task_id}/video/{파일명} + + Args: + file_path: 업로드할 파일 경로 + + Returns: + bool: 업로드 성공 여부 + + Example: + uploader = AzureBlobUploader(task_id="task-123") + success = await uploader.upload_video(file_path="my_video.mp4") + print(uploader.public_url) + """ + return await self._upload_file( + file_path=file_path, + category="video", + content_type="video/mp4", + timeout=180.0, + log_prefix="upload_video", + ) + + async def upload_video_bytes( + self, file_content: bytes, file_name: str + ) -> bool: + """영상 바이트 데이터를 Azure Blob Storage에 직접 업로드합니다. + + URL 경로: {task_id}/video/{파일명} + + Args: + file_content: 업로드할 파일 바이트 데이터 + file_name: 저장할 파일명 (확장자가 없으면 .mp4 추가) + + Returns: + bool: 업로드 성공 여부 + + Example: + uploader = AzureBlobUploader(task_id="task-123") + success = await uploader.upload_video_bytes(video_bytes, "my_video") + print(uploader.public_url) + """ + # 확장자가 없으면 .mp4 추가 + if not Path(file_name).suffix: + file_name = f"{file_name}.mp4" + + upload_url = self._build_upload_url("video", file_name) + self._last_public_url = self._build_public_url("video", file_name) + log_prefix = "upload_video_bytes" + print(f"[{log_prefix}] URL (without SAS): {self._last_public_url}") + + headers = {"Content-Type": "video/mp4", "x-ms-blob-type": "BlockBlob"} + + return await self._upload_bytes( + file_content=file_content, + upload_url=upload_url, + headers=headers, + timeout=180.0, + log_prefix=log_prefix, + ) + + async def upload_image(self, file_path: str) -> bool: + """이미지 파일을 Azure Blob Storage에 업로드합니다. + + URL 경로: {task_id}/image/{파일명} + + Args: + file_path: 업로드할 파일 경로 + + Returns: + bool: 업로드 성공 여부 + + Example: + uploader = AzureBlobUploader(task_id="task-123") + success = await uploader.upload_image(file_path="my_image.png") + print(uploader.public_url) + """ + extension = Path(file_path).suffix.lower() + content_type = self.IMAGE_CONTENT_TYPES.get(extension, "image/jpeg") + + return await self._upload_file( + file_path=file_path, + category="image", + content_type=content_type, + timeout=60.0, + log_prefix="upload_image", + ) + + async def upload_image_bytes( + self, file_content: bytes, file_name: str + ) -> bool: + """이미지 바이트 데이터를 Azure Blob Storage에 직접 업로드합니다. + + URL 경로: {task_id}/image/{파일명} + + Args: + file_content: 업로드할 파일 바이트 데이터 + file_name: 저장할 파일명 + + Returns: + bool: 업로드 성공 여부 + + Example: + uploader = AzureBlobUploader(task_id="task-123") + with open("my_image.png", "rb") as f: + content = f.read() + success = await uploader.upload_image_bytes(content, "my_image.png") + print(uploader.public_url) + """ + extension = Path(file_name).suffix.lower() + content_type = self.IMAGE_CONTENT_TYPES.get(extension, "image/jpeg") + + upload_url = self._build_upload_url("image", file_name) + self._last_public_url = self._build_public_url("image", file_name) + log_prefix = "upload_image_bytes" + print(f"[{log_prefix}] URL (without SAS): {self._last_public_url}") + + headers = {"Content-Type": content_type, "x-ms-blob-type": "BlockBlob"} + + return await self._upload_bytes( + file_content=file_content, + upload_url=upload_url, + headers=headers, + timeout=60.0, + log_prefix=log_prefix, + ) + + +# 사용 예시: +# import asyncio +# +# async def main(): +# uploader = AzureBlobUploader(task_id="task-123") +# +# # 음악 업로드 -> {BASE_URL}/task-123/song/my_song.mp3 +# await uploader.upload_music("my_song.mp3") +# print(uploader.public_url) +# +# # 영상 업로드 -> {BASE_URL}/task-123/video/my_video.mp4 +# await uploader.upload_video("my_video.mp4") +# print(uploader.public_url) +# +# # 이미지 업로드 -> {BASE_URL}/task-123/image/my_image.png +# await uploader.upload_image("my_image.png") +# print(uploader.public_url) +# +# asyncio.run(main()) diff --git a/app/video/api/routers/v1/video.py b/app/video/api/routers/v1/video.py index 266e3fd..053ca03 100644 --- a/app/video/api/routers/v1/video.py +++ b/app/video/api/routers/v1/video.py @@ -1,746 +1,746 @@ -""" -Video API Router - -이 모듈은 Creatomate API를 통한 영상 생성 관련 API 엔드포인트를 정의합니다. - -엔드포인트 목록: - - POST /video/generate/{task_id}: 영상 생성 요청 (task_id로 Project/Lyric/Song 연결) - - GET /video/status/{creatomate_render_id}: Creatomate API 영상 생성 상태 조회 - - GET /video/download/{task_id}: 영상 다운로드 상태 조회 (DB polling) - - GET /videos/: 완료된 영상 목록 조회 (페이지네이션) - -사용 예시: - from app.video.api.routers.v1.video import router - app.include_router(router, prefix="/api/v1") -""" - -from typing import Literal - -from fastapi import APIRouter, BackgroundTasks, Depends, HTTPException, Query -from sqlalchemy import func, select -from sqlalchemy.ext.asyncio import AsyncSession - -from app.database.session import get_session -from app.dependencies.pagination import ( - PaginationParams, - get_pagination_params, -) -from app.home.models import Image, Project -from app.lyric.models import Lyric -from app.song.models import Song -from app.video.models import Video -from app.video.schemas.video_schema import ( - DownloadVideoResponse, - GenerateVideoResponse, - PollingVideoResponse, - VideoListItem, - VideoRenderData, -) -from app.video.worker.video_task import download_and_upload_video_to_blob -from app.utils.creatomate import CreatomateService -from app.utils.pagination import PaginatedResponse - - -router = APIRouter(prefix="/video", tags=["video"]) - - -@router.get( - "/generate/{task_id}", - summary="영상 생성 요청", - description=""" -Creatomate API를 통해 영상 생성을 요청합니다. - -## 경로 파라미터 -- **task_id**: Project/Lyric/Song/Image의 task_id (필수) - 연관된 프로젝트, 가사, 노래, 이미지를 조회하는 데 사용 - -## 쿼리 파라미터 -- **orientation**: 영상 방향 (horizontal: 가로형, vertical: 세로형, 기본값: vertical) - 선택 - -## 자동 조회 정보 -- **image_urls**: Image 테이블에서 task_id로 조회 (img_order 순서로 정렬) -- **music_url**: Song 테이블의 song_result_url 사용 -- **duration**: Song 테이블의 duration 사용 -- **lyrics**: Song 테이블의 song_prompt (가사) 사용 - -## 반환 정보 -- **success**: 요청 성공 여부 -- **task_id**: 내부 작업 ID (Project task_id) -- **creatomate_render_id**: Creatomate 렌더 ID (상태 조회에 사용) -- **message**: 응답 메시지 - -## 사용 예시 -``` -GET /video/generate/0694b716-dbff-7219-8000-d08cb5fce431 -GET /video/generate/0694b716-dbff-7219-8000-d08cb5fce431?orientation=horizontal -``` - -## 참고 -- 이미지는 task_id로 Image 테이블에서 자동 조회됩니다 (img_order 순서). -- 배경 음악(music_url), 영상 길이(duration), 가사(lyrics)는 task_id로 Song 테이블을 조회하여 자동으로 가져옵니다. -- 같은 task_id로 여러 Song이 있을 경우 **가장 최근 생성된 노래**를 사용합니다. -- Song의 song_result_url과 song_prompt가 있어야 영상 생성이 가능합니다. -- creatomate_render_id를 사용하여 /status/{creatomate_render_id} 엔드포인트에서 생성 상태를 확인할 수 있습니다. -- Video 테이블에 데이터가 저장되며, project_id, lyric_id, song_id가 자동으로 연결됩니다. - """, - response_model=GenerateVideoResponse, - responses={ - 200: {"description": "영상 생성 요청 성공"}, - 400: {"description": "Song의 음악 URL, 가사(song_prompt) 또는 이미지가 없음"}, - 404: {"description": "Project, Lyric, Song 또는 Image를 찾을 수 없음"}, - 500: {"description": "영상 생성 요청 실패"}, - }, -) -async def generate_video( - task_id: str, - orientation: Literal["horizontal", "vertical"] = Query( - default="vertical", - description="영상 방향 (horizontal: 가로형, vertical: 세로형)", - ), -) -> GenerateVideoResponse: - """Creatomate API를 통해 영상을 생성합니다. - - 1. task_id로 Project, Lyric, Song, Image 순차 조회 - 2. Video 테이블에 초기 데이터 저장 (status: processing) - 3. Creatomate API 호출 (orientation에 따른 템플릿 자동 선택) - 4. creatomate_render_id 업데이트 후 응답 반환 - - Note: 이 함수는 Depends(get_session)을 사용하지 않고 명시적으로 세션을 관리합니다. - 외부 API 호출 중 DB 커넥션이 유지되지 않도록 하여 커넥션 타임아웃 문제를 방지합니다. - - 중요: SQLAlchemy AsyncSession은 단일 세션에서 동시에 여러 쿼리를 실행하는 것을 - 지원하지 않습니다. asyncio.gather()로 병렬 쿼리를 실행하면 세션 상태 충돌이 발생합니다. - 따라서 쿼리는 순차적으로 실행합니다. - """ - import time - from app.database.session import AsyncSessionLocal - - request_start = time.perf_counter() - print(f"[generate_video] START - task_id: {task_id}, orientation: {orientation}") - - # ========================================================================== - # 1단계: DB 조회 및 초기 데이터 저장 (세션을 명시적으로 열고 닫음) - # ========================================================================== - # 외부 API 호출 전에 필요한 데이터를 저장할 변수들 - project_id: int | None = None - lyric_id: int | None = None - song_id: int | None = None - video_id: int | None = None - music_url: str | None = None - song_duration: float | None = None - lyrics: str | None = None - image_urls: list[str] = [] - - try: - # 세션을 명시적으로 열고 DB 작업 후 바로 닫음 - async with AsyncSessionLocal() as session: - # ===== 순차 쿼리 실행: Project, Lyric, Song, Image ===== - # Note: AsyncSession은 동일 세션에서 병렬 쿼리를 지원하지 않음 - - # Project 조회 - project_result = await session.execute( - select(Project) - .where(Project.task_id == task_id) - .order_by(Project.created_at.desc()) - .limit(1) - ) - - # Lyric 조회 - lyric_result = await session.execute( - select(Lyric) - .where(Lyric.task_id == task_id) - .order_by(Lyric.created_at.desc()) - .limit(1) - ) - - # Song 조회 - song_result = await session.execute( - select(Song) - .where(Song.task_id == task_id) - .order_by(Song.created_at.desc()) - .limit(1) - ) - - # Image 조회 - image_result = await session.execute( - select(Image) - .where(Image.task_id == task_id) - .order_by(Image.img_order.asc()) - ) - - query_time = time.perf_counter() - print(f"[generate_video] Queries completed - task_id: {task_id}, " - f"elapsed: {(query_time - request_start)*1000:.1f}ms") - - # ===== 결과 처리: Project ===== - project = project_result.scalar_one_or_none() - if not project: - print(f"[generate_video] Project NOT FOUND - task_id: {task_id}") - raise HTTPException( - status_code=404, - detail=f"task_id '{task_id}'에 해당하는 Project를 찾을 수 없습니다.", - ) - project_id = project.id - - # ===== 결과 처리: Lyric ===== - lyric = lyric_result.scalar_one_or_none() - if not lyric: - print(f"[generate_video] Lyric NOT FOUND - task_id: {task_id}") - raise HTTPException( - status_code=404, - detail=f"task_id '{task_id}'에 해당하는 Lyric을 찾을 수 없습니다.", - ) - lyric_id = lyric.id - - # ===== 결과 처리: Song ===== - song = song_result.scalar_one_or_none() - if not song: - print(f"[generate_video] Song NOT FOUND - task_id: {task_id}") - raise HTTPException( - status_code=404, - detail=f"task_id '{task_id}'에 해당하는 Song을 찾을 수 없습니다.", - ) - - song_id = song.id - music_url = song.song_result_url - song_duration = song.duration - lyrics = song.song_prompt - - if not music_url: - raise HTTPException( - status_code=400, - detail=f"Song(id={song_id})의 음악 URL이 없습니다.", - ) - - if not lyrics: - raise HTTPException( - status_code=400, - detail=f"Song(id={song_id})의 가사(song_prompt)가 없습니다.", - ) - - # ===== 결과 처리: Image ===== - images = image_result.scalars().all() - if not images: - print(f"[generate_video] Image NOT FOUND - task_id: {task_id}") - raise HTTPException( - status_code=404, - detail=f"task_id '{task_id}'에 해당하는 이미지를 찾을 수 없습니다.", - ) - image_urls = [img.img_url for img in images] - - print( - f"[generate_video] Data loaded - task_id: {task_id}, " - f"project_id: {project_id}, lyric_id: {lyric_id}, " - f"song_id: {song_id}, images: {len(image_urls)}" - ) - - # ===== Video 테이블에 초기 데이터 저장 및 커밋 ===== - video = Video( - project_id=project_id, - lyric_id=lyric_id, - song_id=song_id, - task_id=task_id, - creatomate_render_id=None, - status="processing", - ) - session.add(video) - await session.commit() - video_id = video.id - stage1_time = time.perf_counter() - print(f"[generate_video] Video saved - task_id: {task_id}, id: {video_id}, " - f"stage1_elapsed: {(stage1_time - request_start)*1000:.1f}ms") - # 세션이 여기서 자동으로 닫힘 (async with 블록 종료) - - except HTTPException: - raise - except Exception as e: - print(f"[generate_video] DB EXCEPTION - task_id: {task_id}, error: {e}") - return GenerateVideoResponse( - success=False, - task_id=task_id, - creatomate_render_id=None, - message="영상 생성 요청에 실패했습니다.", - error_message=str(e), - ) - - # ========================================================================== - # 2단계: 외부 API 호출 (세션 사용 안함 - 커넥션 풀 점유 없음) - # ========================================================================== - stage2_start = time.perf_counter() - try: - print(f"[generate_video] Stage 2 START - Creatomate API - task_id: {task_id}") - creatomate_service = CreatomateService( - orientation=orientation, - target_duration=song_duration, - ) - print(f"[generate_video] Using template_id: {creatomate_service.template_id}, duration: {creatomate_service.target_duration} (song duration: {song_duration})") - - # 6-1. 템플릿 조회 (비동기) - template = await creatomate_service.get_one_template_data_async(creatomate_service.template_id) - print(f"[generate_video] Template fetched - task_id: {task_id}") - - # 6-2. elements에서 리소스 매핑 생성 - modifications = creatomate_service.elements_connect_resource_blackbox( - elements=template["source"]["elements"], - image_url_list=image_urls, - lyric=lyrics, - music_url=music_url, - ) - print(f"[generate_video] Modifications created - task_id: {task_id}") - - # 6-3. elements 수정 - new_elements = creatomate_service.modify_element( - template["source"]["elements"], - modifications, - ) - template["source"]["elements"] = new_elements - print(f"[generate_video] Elements modified - task_id: {task_id}") - - # 6-4. duration 확장 - final_template = creatomate_service.extend_template_duration( - template, - creatomate_service.target_duration, - ) - print(f"[generate_video] Duration extended to {creatomate_service.target_duration}s - task_id: {task_id}") - - # 6-5. 커스텀 렌더링 요청 (비동기) - render_response = await creatomate_service.make_creatomate_custom_call_async( - final_template["source"], - ) - print(f"[generate_video] Creatomate API response - task_id: {task_id}, response: {render_response}") - - # 렌더 ID 추출 - if isinstance(render_response, list) and len(render_response) > 0: - creatomate_render_id = render_response[0].get("id") - elif isinstance(render_response, dict): - creatomate_render_id = render_response.get("id") - else: - creatomate_render_id = None - - stage2_time = time.perf_counter() - print( - f"[generate_video] Stage 2 DONE - task_id: {task_id}, " - f"render_id: {creatomate_render_id}, " - f"stage2_elapsed: {(stage2_time - stage2_start)*1000:.1f}ms" - ) - - except Exception as e: - print(f"[generate_video] Creatomate API EXCEPTION - task_id: {task_id}, error: {e}") - # 외부 API 실패 시 Video 상태를 failed로 업데이트 - from app.database.session import AsyncSessionLocal - async with AsyncSessionLocal() as update_session: - video_result = await update_session.execute( - select(Video).where(Video.id == video_id) - ) - video_to_update = video_result.scalar_one_or_none() - if video_to_update: - video_to_update.status = "failed" - await update_session.commit() - return GenerateVideoResponse( - success=False, - task_id=task_id, - creatomate_render_id=None, - message="영상 생성 요청에 실패했습니다.", - error_message=str(e), - ) - - # ========================================================================== - # 3단계: creatomate_render_id 업데이트 (새 세션으로 빠르게 처리) - # ========================================================================== - stage3_start = time.perf_counter() - print(f"[generate_video] Stage 3 START - DB update - task_id: {task_id}") - try: - from app.database.session import AsyncSessionLocal - async with AsyncSessionLocal() as update_session: - video_result = await update_session.execute( - select(Video).where(Video.id == video_id) - ) - video_to_update = video_result.scalar_one_or_none() - if video_to_update: - video_to_update.creatomate_render_id = creatomate_render_id - await update_session.commit() - - stage3_time = time.perf_counter() - total_time = stage3_time - request_start - print( - f"[generate_video] Stage 3 DONE - task_id: {task_id}, " - f"stage3_elapsed: {(stage3_time - stage3_start)*1000:.1f}ms" - ) - print( - f"[generate_video] SUCCESS - task_id: {task_id}, " - f"render_id: {creatomate_render_id}, " - f"total_time: {total_time*1000:.1f}ms" - ) - - return GenerateVideoResponse( - success=True, - task_id=task_id, - creatomate_render_id=creatomate_render_id, - message="영상 생성 요청이 접수되었습니다. creatomate_render_id로 상태를 조회하세요.", - error_message=None, - ) - - except Exception as e: - print(f"[generate_video] Update EXCEPTION - task_id: {task_id}, error: {e}") - return GenerateVideoResponse( - success=False, - task_id=task_id, - creatomate_render_id=creatomate_render_id, - message="영상 생성은 요청되었으나 DB 업데이트에 실패했습니다.", - error_message=str(e), - ) - - -@router.get( - "/status/{creatomate_render_id}", - summary="영상 생성 상태 조회", - description=""" -Creatomate API를 통해 영상 생성 작업의 상태를 조회합니다. -succeeded 상태인 경우 백그라운드에서 MP4 파일을 다운로드하고 Video 테이블을 업데이트합니다. - -## 경로 파라미터 -- **creatomate_render_id**: 영상 생성 시 반환된 Creatomate 렌더 ID (필수) - -## 반환 정보 -- **success**: 조회 성공 여부 -- **status**: 작업 상태 (planned, waiting, rendering, succeeded, failed) -- **message**: 상태 메시지 -- **render_data**: 렌더링 결과 데이터 (완료 시) -- **raw_response**: Creatomate API 원본 응답 - -## 사용 예시 -``` -GET /video/status/render-id-123... -``` - -## 상태 값 -- **planned**: 예약됨 -- **waiting**: 대기 중 -- **transcribing**: 트랜스크립션 중 -- **rendering**: 렌더링 중 -- **succeeded**: 성공 -- **failed**: 실패 - -## 참고 -- succeeded 시 백그라운드에서 MP4 다운로드 및 DB 업데이트 진행 - """, - response_model=PollingVideoResponse, - responses={ - 200: {"description": "상태 조회 성공"}, - 500: {"description": "상태 조회 실패"}, - }, -) -async def get_video_status( - creatomate_render_id: str, - background_tasks: BackgroundTasks, - session: AsyncSession = Depends(get_session), -) -> PollingVideoResponse: - """creatomate_render_id로 영상 생성 작업의 상태를 조회합니다. - - succeeded 상태인 경우 백그라운드에서 MP4 파일을 다운로드하고 - Video 테이블의 status를 completed로, result_movie_url을 업데이트합니다. - """ - print(f"[get_video_status] START - creatomate_render_id: {creatomate_render_id}") - try: - creatomate_service = CreatomateService() - result = await creatomate_service.get_render_status_async(creatomate_render_id) - print(f"[get_video_status] Creatomate API response - creatomate_render_id: {creatomate_render_id}, status: {result.get('status')}") - - status = result.get("status", "unknown") - video_url = result.get("url") - - # 상태별 메시지 설정 - status_messages = { - "planned": "영상 생성이 예약되었습니다.", - "waiting": "영상 생성 대기 중입니다.", - "transcribing": "트랜스크립션 진행 중입니다.", - "rendering": "영상을 렌더링하고 있습니다.", - "succeeded": "영상 생성이 완료되었습니다.", - "failed": "영상 생성에 실패했습니다.", - } - message = status_messages.get(status, f"상태: {status}") - - # succeeded 상태인 경우 백그라운드 태스크 실행 - if status == "succeeded" and video_url: - # creatomate_render_id로 Video 조회하여 task_id 가져오기 - video_result = await session.execute( - select(Video) - .where(Video.creatomate_render_id == creatomate_render_id) - .order_by(Video.created_at.desc()) - .limit(1) - ) - video = video_result.scalar_one_or_none() - - if video and video.status != "completed": - # 이미 완료된 경우 백그라운드 작업 중복 실행 방지 - # task_id로 Project 조회하여 store_name 가져오기 - project_result = await session.execute( - select(Project).where(Project.id == video.project_id) - ) - project = project_result.scalar_one_or_none() - - store_name = project.store_name if project else "video" - - # 백그라운드 태스크로 MP4 다운로드 → Blob 업로드 → DB 업데이트 → 임시 파일 삭제 - print(f"[get_video_status] Background task args - task_id: {video.task_id}, video_url: {video_url}, store_name: {store_name}") - background_tasks.add_task( - download_and_upload_video_to_blob, - task_id=video.task_id, - video_url=video_url, - store_name=store_name, - ) - elif video and video.status == "completed": - print(f"[get_video_status] SKIPPED - Video already completed, creatomate_render_id: {creatomate_render_id}") - - render_data = VideoRenderData( - id=result.get("id"), - status=status, - url=video_url, - snapshot_url=result.get("snapshot_url"), - ) - - print(f"[get_video_status] SUCCESS - creatomate_render_id: {creatomate_render_id}") - return PollingVideoResponse( - success=True, - status=status, - message=message, - render_data=render_data, - raw_response=result, - error_message=None, - ) - - except Exception as e: - import traceback - - print(f"[get_video_status] EXCEPTION - creatomate_render_id: {creatomate_render_id}, error: {e}") - return PollingVideoResponse( - success=False, - status="error", - message="상태 조회에 실패했습니다.", - render_data=None, - raw_response=None, - error_message=f"{type(e).__name__}: {e}\n{traceback.format_exc()}", - ) - - -@router.get( - "/download/{task_id}", - summary="영상 생성 URL 조회", - description=""" -task_id를 기반으로 Video 테이블의 상태를 polling하고, -completed인 경우 Project 정보와 영상 URL을 반환합니다. - -## 경로 파라미터 -- **task_id**: 프로젝트 task_id (필수) - -## 반환 정보 -- **success**: 조회 성공 여부 -- **status**: 처리 상태 (processing, completed, failed) -- **message**: 응답 메시지 -- **store_name**: 업체명 -- **region**: 지역명 -- **task_id**: 작업 고유 식별자 -- **result_movie_url**: 영상 결과 URL (completed 시) -- **created_at**: 생성 일시 - -## 사용 예시 -``` -GET /video/download/019123ab-cdef-7890-abcd-ef1234567890 -``` - -## 참고 -- processing 상태인 경우 result_movie_url은 null입니다. -- completed 상태인 경우 Project 정보와 함께 result_movie_url을 반환합니다. - """, - response_model=DownloadVideoResponse, - responses={ - 200: {"description": "조회 성공"}, - 404: {"description": "Video를 찾을 수 없음"}, - 500: {"description": "조회 실패"}, - }, -) -async def download_video( - task_id: str, - session: AsyncSession = Depends(get_session), -) -> DownloadVideoResponse: - """task_id로 Video 상태를 polling하고 completed 시 Project 정보와 영상 URL을 반환합니다.""" - print(f"[download_video] START - task_id: {task_id}") - try: - # task_id로 Video 조회 (여러 개 있을 경우 가장 최근 것 선택) - video_result = await session.execute( - select(Video) - .where(Video.task_id == task_id) - .order_by(Video.created_at.desc()) - .limit(1) - ) - video = video_result.scalar_one_or_none() - - if not video: - print(f"[download_video] Video NOT FOUND - task_id: {task_id}") - return DownloadVideoResponse( - success=False, - status="not_found", - message=f"task_id '{task_id}'에 해당하는 Video를 찾을 수 없습니다.", - error_message="Video not found", - ) - - print(f"[download_video] Video found - task_id: {task_id}, status: {video.status}") - - # processing 상태인 경우 - if video.status == "processing": - print(f"[download_video] PROCESSING - task_id: {task_id}") - return DownloadVideoResponse( - success=True, - status="processing", - message="영상 생성이 진행 중입니다.", - task_id=task_id, - ) - - # failed 상태인 경우 - if video.status == "failed": - print(f"[download_video] FAILED - task_id: {task_id}") - return DownloadVideoResponse( - success=False, - status="failed", - message="영상 생성에 실패했습니다.", - task_id=task_id, - error_message="Video generation failed", - ) - - # completed 상태인 경우 - Project 정보 조회 - project_result = await session.execute( - select(Project).where(Project.id == video.project_id) - ) - project = project_result.scalar_one_or_none() - - print(f"[download_video] COMPLETED - task_id: {task_id}, result_movie_url: {video.result_movie_url}") - return DownloadVideoResponse( - success=True, - status="completed", - message="영상 다운로드가 완료되었습니다.", - store_name=project.store_name if project else None, - region=project.region if project else None, - task_id=task_id, - result_movie_url=video.result_movie_url, - created_at=video.created_at, - ) - - except Exception as e: - print(f"[download_video] EXCEPTION - task_id: {task_id}, error: {e}") - return DownloadVideoResponse( - success=False, - status="error", - message="영상 다운로드 조회에 실패했습니다.", - error_message=str(e), - ) - - -@router.get( - "s/", - summary="생성된 영상 목록 조회", - description=""" -완료된 영상 목록을 페이지네이션하여 조회합니다. - -## 쿼리 파라미터 -- **page**: 페이지 번호 (1부터 시작, 기본값: 1) -- **page_size**: 페이지당 데이터 수 (기본값: 10, 최대: 100) - -## 반환 정보 -- **items**: 영상 목록 (store_name, region, task_id, result_movie_url, created_at) -- **total**: 전체 데이터 수 -- **page**: 현재 페이지 -- **page_size**: 페이지당 데이터 수 -- **total_pages**: 전체 페이지 수 -- **has_next**: 다음 페이지 존재 여부 -- **has_prev**: 이전 페이지 존재 여부 - -## 사용 예시 -``` -GET /videos/?page=1&page_size=10 -``` - -## 참고 -- status가 'completed'인 영상만 반환됩니다. -- 동일한 task_id가 있는 경우 가장 최근에 생성된 1개만 반환됩니다. -- created_at 기준 내림차순 정렬됩니다. - """, - response_model=PaginatedResponse[VideoListItem], - responses={ - 200: {"description": "영상 목록 조회 성공"}, - 500: {"description": "조회 실패"}, - }, -) -async def get_videos( - session: AsyncSession = Depends(get_session), - pagination: PaginationParams = Depends(get_pagination_params), -) -> PaginatedResponse[VideoListItem]: - """완료된 영상 목록을 페이지네이션하여 반환합니다.""" - print(f"[get_videos] START - page: {pagination.page}, page_size: {pagination.page_size}") - try: - offset = (pagination.page - 1) * pagination.page_size - - # 서브쿼리: task_id별 최신 Video의 id 조회 (completed 상태만) - subquery = ( - select(func.max(Video.id).label("max_id")) - .where(Video.status == "completed") - .group_by(Video.task_id) - .subquery() - ) - - # 전체 개수 조회 (task_id별 최신 1개만) - count_query = select(func.count()).select_from(subquery) - total_result = await session.execute(count_query) - total = total_result.scalar() or 0 - - # 데이터 조회 (completed 상태, task_id별 최신 1개만, 최신순) - query = ( - select(Video) - .where(Video.id.in_(select(subquery.c.max_id))) - .order_by(Video.created_at.desc()) - .offset(offset) - .limit(pagination.page_size) - ) - result = await session.execute(query) - videos = result.scalars().all() - - # Project 정보 일괄 조회 (N+1 문제 해결) - project_ids = [v.project_id for v in videos if v.project_id] - projects_map: dict = {} - if project_ids: - projects_result = await session.execute( - select(Project).where(Project.id.in_(project_ids)) - ) - projects_map = {p.id: p for p in projects_result.scalars().all()} - - # VideoListItem으로 변환 - items = [] - for video in videos: - project = projects_map.get(video.project_id) - - item = VideoListItem( - store_name=project.store_name if project else None, - region=project.region if project else None, - task_id=video.task_id, - result_movie_url=video.result_movie_url, - created_at=video.created_at, - ) - items.append(item) - - response = PaginatedResponse.create( - items=items, - total=total, - page=pagination.page, - page_size=pagination.page_size, - ) - - print( - f"[get_videos] SUCCESS - total: {total}, page: {pagination.page}, " - f"page_size: {pagination.page_size}, items_count: {len(items)}" - ) - return response - - except Exception as e: - print(f"[get_videos] EXCEPTION - error: {e}") - raise HTTPException( - status_code=500, - detail=f"영상 목록 조회에 실패했습니다: {str(e)}", - ) +""" +Video API Router + +이 모듈은 Creatomate API를 통한 영상 생성 관련 API 엔드포인트를 정의합니다. + +엔드포인트 목록: + - POST /video/generate/{task_id}: 영상 생성 요청 (task_id로 Project/Lyric/Song 연결) + - GET /video/status/{creatomate_render_id}: Creatomate API 영상 생성 상태 조회 + - GET /video/download/{task_id}: 영상 다운로드 상태 조회 (DB polling) + - GET /videos/: 완료된 영상 목록 조회 (페이지네이션) + +사용 예시: + from app.video.api.routers.v1.video import router + app.include_router(router, prefix="/api/v1") +""" + +from typing import Literal + +from fastapi import APIRouter, BackgroundTasks, Depends, HTTPException, Query +from sqlalchemy import func, select +from sqlalchemy.ext.asyncio import AsyncSession + +from app.database.session import get_session +from app.dependencies.pagination import ( + PaginationParams, + get_pagination_params, +) +from app.home.models import Image, Project +from app.lyric.models import Lyric +from app.song.models import Song +from app.video.models import Video +from app.video.schemas.video_schema import ( + DownloadVideoResponse, + GenerateVideoResponse, + PollingVideoResponse, + VideoListItem, + VideoRenderData, +) +from app.video.worker.video_task import download_and_upload_video_to_blob +from app.utils.creatomate import CreatomateService +from app.utils.pagination import PaginatedResponse + + +router = APIRouter(prefix="/video", tags=["video"]) + + +@router.get( + "/generate/{task_id}", + summary="영상 생성 요청", + description=""" +Creatomate API를 통해 영상 생성을 요청합니다. + +## 경로 파라미터 +- **task_id**: Project/Lyric/Song/Image의 task_id (필수) - 연관된 프로젝트, 가사, 노래, 이미지를 조회하는 데 사용 + +## 쿼리 파라미터 +- **orientation**: 영상 방향 (horizontal: 가로형, vertical: 세로형, 기본값: vertical) - 선택 + +## 자동 조회 정보 +- **image_urls**: Image 테이블에서 task_id로 조회 (img_order 순서로 정렬) +- **music_url**: Song 테이블의 song_result_url 사용 +- **duration**: Song 테이블의 duration 사용 +- **lyrics**: Song 테이블의 song_prompt (가사) 사용 + +## 반환 정보 +- **success**: 요청 성공 여부 +- **task_id**: 내부 작업 ID (Project task_id) +- **creatomate_render_id**: Creatomate 렌더 ID (상태 조회에 사용) +- **message**: 응답 메시지 + +## 사용 예시 +``` +GET /video/generate/0694b716-dbff-7219-8000-d08cb5fce431 +GET /video/generate/0694b716-dbff-7219-8000-d08cb5fce431?orientation=horizontal +``` + +## 참고 +- 이미지는 task_id로 Image 테이블에서 자동 조회됩니다 (img_order 순서). +- 배경 음악(music_url), 영상 길이(duration), 가사(lyrics)는 task_id로 Song 테이블을 조회하여 자동으로 가져옵니다. +- 같은 task_id로 여러 Song이 있을 경우 **가장 최근 생성된 노래**를 사용합니다. +- Song의 song_result_url과 song_prompt가 있어야 영상 생성이 가능합니다. +- creatomate_render_id를 사용하여 /status/{creatomate_render_id} 엔드포인트에서 생성 상태를 확인할 수 있습니다. +- Video 테이블에 데이터가 저장되며, project_id, lyric_id, song_id가 자동으로 연결됩니다. + """, + response_model=GenerateVideoResponse, + responses={ + 200: {"description": "영상 생성 요청 성공"}, + 400: {"description": "Song의 음악 URL, 가사(song_prompt) 또는 이미지가 없음"}, + 404: {"description": "Project, Lyric, Song 또는 Image를 찾을 수 없음"}, + 500: {"description": "영상 생성 요청 실패"}, + }, +) +async def generate_video( + task_id: str, + orientation: Literal["horizontal", "vertical"] = Query( + default="vertical", + description="영상 방향 (horizontal: 가로형, vertical: 세로형)", + ), +) -> GenerateVideoResponse: + """Creatomate API를 통해 영상을 생성합니다. + + 1. task_id로 Project, Lyric, Song, Image 순차 조회 + 2. Video 테이블에 초기 데이터 저장 (status: processing) + 3. Creatomate API 호출 (orientation에 따른 템플릿 자동 선택) + 4. creatomate_render_id 업데이트 후 응답 반환 + + Note: 이 함수는 Depends(get_session)을 사용하지 않고 명시적으로 세션을 관리합니다. + 외부 API 호출 중 DB 커넥션이 유지되지 않도록 하여 커넥션 타임아웃 문제를 방지합니다. + + 중요: SQLAlchemy AsyncSession은 단일 세션에서 동시에 여러 쿼리를 실행하는 것을 + 지원하지 않습니다. asyncio.gather()로 병렬 쿼리를 실행하면 세션 상태 충돌이 발생합니다. + 따라서 쿼리는 순차적으로 실행합니다. + """ + import time + from app.database.session import AsyncSessionLocal + + request_start = time.perf_counter() + print(f"[generate_video] START - task_id: {task_id}, orientation: {orientation}") + + # ========================================================================== + # 1단계: DB 조회 및 초기 데이터 저장 (세션을 명시적으로 열고 닫음) + # ========================================================================== + # 외부 API 호출 전에 필요한 데이터를 저장할 변수들 + project_id: int | None = None + lyric_id: int | None = None + song_id: int | None = None + video_id: int | None = None + music_url: str | None = None + song_duration: float | None = None + lyrics: str | None = None + image_urls: list[str] = [] + + try: + # 세션을 명시적으로 열고 DB 작업 후 바로 닫음 + async with AsyncSessionLocal() as session: + # ===== 순차 쿼리 실행: Project, Lyric, Song, Image ===== + # Note: AsyncSession은 동일 세션에서 병렬 쿼리를 지원하지 않음 + + # Project 조회 + project_result = await session.execute( + select(Project) + .where(Project.task_id == task_id) + .order_by(Project.created_at.desc()) + .limit(1) + ) + + # Lyric 조회 + lyric_result = await session.execute( + select(Lyric) + .where(Lyric.task_id == task_id) + .order_by(Lyric.created_at.desc()) + .limit(1) + ) + + # Song 조회 + song_result = await session.execute( + select(Song) + .where(Song.task_id == task_id) + .order_by(Song.created_at.desc()) + .limit(1) + ) + + # Image 조회 + image_result = await session.execute( + select(Image) + .where(Image.task_id == task_id) + .order_by(Image.img_order.asc()) + ) + + query_time = time.perf_counter() + print(f"[generate_video] Queries completed - task_id: {task_id}, " + f"elapsed: {(query_time - request_start)*1000:.1f}ms") + + # ===== 결과 처리: Project ===== + project = project_result.scalar_one_or_none() + if not project: + print(f"[generate_video] Project NOT FOUND - task_id: {task_id}") + raise HTTPException( + status_code=404, + detail=f"task_id '{task_id}'에 해당하는 Project를 찾을 수 없습니다.", + ) + project_id = project.id + + # ===== 결과 처리: Lyric ===== + lyric = lyric_result.scalar_one_or_none() + if not lyric: + print(f"[generate_video] Lyric NOT FOUND - task_id: {task_id}") + raise HTTPException( + status_code=404, + detail=f"task_id '{task_id}'에 해당하는 Lyric을 찾을 수 없습니다.", + ) + lyric_id = lyric.id + + # ===== 결과 처리: Song ===== + song = song_result.scalar_one_or_none() + if not song: + print(f"[generate_video] Song NOT FOUND - task_id: {task_id}") + raise HTTPException( + status_code=404, + detail=f"task_id '{task_id}'에 해당하는 Song을 찾을 수 없습니다.", + ) + + song_id = song.id + music_url = song.song_result_url + song_duration = song.duration + lyrics = song.song_prompt + + if not music_url: + raise HTTPException( + status_code=400, + detail=f"Song(id={song_id})의 음악 URL이 없습니다.", + ) + + if not lyrics: + raise HTTPException( + status_code=400, + detail=f"Song(id={song_id})의 가사(song_prompt)가 없습니다.", + ) + + # ===== 결과 처리: Image ===== + images = image_result.scalars().all() + if not images: + print(f"[generate_video] Image NOT FOUND - task_id: {task_id}") + raise HTTPException( + status_code=404, + detail=f"task_id '{task_id}'에 해당하는 이미지를 찾을 수 없습니다.", + ) + image_urls = [img.img_url for img in images] + + print( + f"[generate_video] Data loaded - task_id: {task_id}, " + f"project_id: {project_id}, lyric_id: {lyric_id}, " + f"song_id: {song_id}, images: {len(image_urls)}" + ) + + # ===== Video 테이블에 초기 데이터 저장 및 커밋 ===== + video = Video( + project_id=project_id, + lyric_id=lyric_id, + song_id=song_id, + task_id=task_id, + creatomate_render_id=None, + status="processing", + ) + session.add(video) + await session.commit() + video_id = video.id + stage1_time = time.perf_counter() + print(f"[generate_video] Video saved - task_id: {task_id}, id: {video_id}, " + f"stage1_elapsed: {(stage1_time - request_start)*1000:.1f}ms") + # 세션이 여기서 자동으로 닫힘 (async with 블록 종료) + + except HTTPException: + raise + except Exception as e: + print(f"[generate_video] DB EXCEPTION - task_id: {task_id}, error: {e}") + return GenerateVideoResponse( + success=False, + task_id=task_id, + creatomate_render_id=None, + message="영상 생성 요청에 실패했습니다.", + error_message=str(e), + ) + + # ========================================================================== + # 2단계: 외부 API 호출 (세션 사용 안함 - 커넥션 풀 점유 없음) + # ========================================================================== + stage2_start = time.perf_counter() + try: + print(f"[generate_video] Stage 2 START - Creatomate API - task_id: {task_id}") + creatomate_service = CreatomateService( + orientation=orientation, + target_duration=song_duration, + ) + print(f"[generate_video] Using template_id: {creatomate_service.template_id}, duration: {creatomate_service.target_duration} (song duration: {song_duration})") + + # 6-1. 템플릿 조회 (비동기) + template = await creatomate_service.get_one_template_data_async(creatomate_service.template_id) + print(f"[generate_video] Template fetched - task_id: {task_id}") + + # 6-2. elements에서 리소스 매핑 생성 + modifications = creatomate_service.elements_connect_resource_blackbox( + elements=template["source"]["elements"], + image_url_list=image_urls, + lyric=lyrics, + music_url=music_url, + ) + print(f"[generate_video] Modifications created - task_id: {task_id}") + + # 6-3. elements 수정 + new_elements = creatomate_service.modify_element( + template["source"]["elements"], + modifications, + ) + template["source"]["elements"] = new_elements + print(f"[generate_video] Elements modified - task_id: {task_id}") + + # 6-4. duration 확장 + final_template = creatomate_service.extend_template_duration( + template, + creatomate_service.target_duration, + ) + print(f"[generate_video] Duration extended to {creatomate_service.target_duration}s - task_id: {task_id}") + + # 6-5. 커스텀 렌더링 요청 (비동기) + render_response = await creatomate_service.make_creatomate_custom_call_async( + final_template["source"], + ) + print(f"[generate_video] Creatomate API response - task_id: {task_id}, response: {render_response}") + + # 렌더 ID 추출 + if isinstance(render_response, list) and len(render_response) > 0: + creatomate_render_id = render_response[0].get("id") + elif isinstance(render_response, dict): + creatomate_render_id = render_response.get("id") + else: + creatomate_render_id = None + + stage2_time = time.perf_counter() + print( + f"[generate_video] Stage 2 DONE - task_id: {task_id}, " + f"render_id: {creatomate_render_id}, " + f"stage2_elapsed: {(stage2_time - stage2_start)*1000:.1f}ms" + ) + + except Exception as e: + print(f"[generate_video] Creatomate API EXCEPTION - task_id: {task_id}, error: {e}") + # 외부 API 실패 시 Video 상태를 failed로 업데이트 + from app.database.session import AsyncSessionLocal + async with AsyncSessionLocal() as update_session: + video_result = await update_session.execute( + select(Video).where(Video.id == video_id) + ) + video_to_update = video_result.scalar_one_or_none() + if video_to_update: + video_to_update.status = "failed" + await update_session.commit() + return GenerateVideoResponse( + success=False, + task_id=task_id, + creatomate_render_id=None, + message="영상 생성 요청에 실패했습니다.", + error_message=str(e), + ) + + # ========================================================================== + # 3단계: creatomate_render_id 업데이트 (새 세션으로 빠르게 처리) + # ========================================================================== + stage3_start = time.perf_counter() + print(f"[generate_video] Stage 3 START - DB update - task_id: {task_id}") + try: + from app.database.session import AsyncSessionLocal + async with AsyncSessionLocal() as update_session: + video_result = await update_session.execute( + select(Video).where(Video.id == video_id) + ) + video_to_update = video_result.scalar_one_or_none() + if video_to_update: + video_to_update.creatomate_render_id = creatomate_render_id + await update_session.commit() + + stage3_time = time.perf_counter() + total_time = stage3_time - request_start + print( + f"[generate_video] Stage 3 DONE - task_id: {task_id}, " + f"stage3_elapsed: {(stage3_time - stage3_start)*1000:.1f}ms" + ) + print( + f"[generate_video] SUCCESS - task_id: {task_id}, " + f"render_id: {creatomate_render_id}, " + f"total_time: {total_time*1000:.1f}ms" + ) + + return GenerateVideoResponse( + success=True, + task_id=task_id, + creatomate_render_id=creatomate_render_id, + message="영상 생성 요청이 접수되었습니다. creatomate_render_id로 상태를 조회하세요.", + error_message=None, + ) + + except Exception as e: + print(f"[generate_video] Update EXCEPTION - task_id: {task_id}, error: {e}") + return GenerateVideoResponse( + success=False, + task_id=task_id, + creatomate_render_id=creatomate_render_id, + message="영상 생성은 요청되었으나 DB 업데이트에 실패했습니다.", + error_message=str(e), + ) + + +@router.get( + "/status/{creatomate_render_id}", + summary="영상 생성 상태 조회", + description=""" +Creatomate API를 통해 영상 생성 작업의 상태를 조회합니다. +succeeded 상태인 경우 백그라운드에서 MP4 파일을 다운로드하고 Video 테이블을 업데이트합니다. + +## 경로 파라미터 +- **creatomate_render_id**: 영상 생성 시 반환된 Creatomate 렌더 ID (필수) + +## 반환 정보 +- **success**: 조회 성공 여부 +- **status**: 작업 상태 (planned, waiting, rendering, succeeded, failed) +- **message**: 상태 메시지 +- **render_data**: 렌더링 결과 데이터 (완료 시) +- **raw_response**: Creatomate API 원본 응답 + +## 사용 예시 +``` +GET /video/status/render-id-123... +``` + +## 상태 값 +- **planned**: 예약됨 +- **waiting**: 대기 중 +- **transcribing**: 트랜스크립션 중 +- **rendering**: 렌더링 중 +- **succeeded**: 성공 +- **failed**: 실패 + +## 참고 +- succeeded 시 백그라운드에서 MP4 다운로드 및 DB 업데이트 진행 + """, + response_model=PollingVideoResponse, + responses={ + 200: {"description": "상태 조회 성공"}, + 500: {"description": "상태 조회 실패"}, + }, +) +async def get_video_status( + creatomate_render_id: str, + background_tasks: BackgroundTasks, + session: AsyncSession = Depends(get_session), +) -> PollingVideoResponse: + """creatomate_render_id로 영상 생성 작업의 상태를 조회합니다. + + succeeded 상태인 경우 백그라운드에서 MP4 파일을 다운로드하고 + Video 테이블의 status를 completed로, result_movie_url을 업데이트합니다. + """ + print(f"[get_video_status] START - creatomate_render_id: {creatomate_render_id}") + try: + creatomate_service = CreatomateService() + result = await creatomate_service.get_render_status_async(creatomate_render_id) + print(f"[get_video_status] Creatomate API response - creatomate_render_id: {creatomate_render_id}, status: {result.get('status')}") + + status = result.get("status", "unknown") + video_url = result.get("url") + + # 상태별 메시지 설정 + status_messages = { + "planned": "영상 생성이 예약되었습니다.", + "waiting": "영상 생성 대기 중입니다.", + "transcribing": "트랜스크립션 진행 중입니다.", + "rendering": "영상을 렌더링하고 있습니다.", + "succeeded": "영상 생성이 완료되었습니다.", + "failed": "영상 생성에 실패했습니다.", + } + message = status_messages.get(status, f"상태: {status}") + + # succeeded 상태인 경우 백그라운드 태스크 실행 + if status == "succeeded" and video_url: + # creatomate_render_id로 Video 조회하여 task_id 가져오기 + video_result = await session.execute( + select(Video) + .where(Video.creatomate_render_id == creatomate_render_id) + .order_by(Video.created_at.desc()) + .limit(1) + ) + video = video_result.scalar_one_or_none() + + if video and video.status != "completed": + # 이미 완료된 경우 백그라운드 작업 중복 실행 방지 + # task_id로 Project 조회하여 store_name 가져오기 + project_result = await session.execute( + select(Project).where(Project.id == video.project_id) + ) + project = project_result.scalar_one_or_none() + + store_name = project.store_name if project else "video" + + # 백그라운드 태스크로 MP4 다운로드 → Blob 업로드 → DB 업데이트 → 임시 파일 삭제 + print(f"[get_video_status] Background task args - task_id: {video.task_id}, video_url: {video_url}, store_name: {store_name}") + background_tasks.add_task( + download_and_upload_video_to_blob, + task_id=video.task_id, + video_url=video_url, + store_name=store_name, + ) + elif video and video.status == "completed": + print(f"[get_video_status] SKIPPED - Video already completed, creatomate_render_id: {creatomate_render_id}") + + render_data = VideoRenderData( + id=result.get("id"), + status=status, + url=video_url, + snapshot_url=result.get("snapshot_url"), + ) + + print(f"[get_video_status] SUCCESS - creatomate_render_id: {creatomate_render_id}") + return PollingVideoResponse( + success=True, + status=status, + message=message, + render_data=render_data, + raw_response=result, + error_message=None, + ) + + except Exception as e: + import traceback + + print(f"[get_video_status] EXCEPTION - creatomate_render_id: {creatomate_render_id}, error: {e}") + return PollingVideoResponse( + success=False, + status="error", + message="상태 조회에 실패했습니다.", + render_data=None, + raw_response=None, + error_message=f"{type(e).__name__}: {e}\n{traceback.format_exc()}", + ) + + +@router.get( + "/download/{task_id}", + summary="영상 생성 URL 조회", + description=""" +task_id를 기반으로 Video 테이블의 상태를 polling하고, +completed인 경우 Project 정보와 영상 URL을 반환합니다. + +## 경로 파라미터 +- **task_id**: 프로젝트 task_id (필수) + +## 반환 정보 +- **success**: 조회 성공 여부 +- **status**: 처리 상태 (processing, completed, failed) +- **message**: 응답 메시지 +- **store_name**: 업체명 +- **region**: 지역명 +- **task_id**: 작업 고유 식별자 +- **result_movie_url**: 영상 결과 URL (completed 시) +- **created_at**: 생성 일시 + +## 사용 예시 +``` +GET /video/download/019123ab-cdef-7890-abcd-ef1234567890 +``` + +## 참고 +- processing 상태인 경우 result_movie_url은 null입니다. +- completed 상태인 경우 Project 정보와 함께 result_movie_url을 반환합니다. + """, + response_model=DownloadVideoResponse, + responses={ + 200: {"description": "조회 성공"}, + 404: {"description": "Video를 찾을 수 없음"}, + 500: {"description": "조회 실패"}, + }, +) +async def download_video( + task_id: str, + session: AsyncSession = Depends(get_session), +) -> DownloadVideoResponse: + """task_id로 Video 상태를 polling하고 completed 시 Project 정보와 영상 URL을 반환합니다.""" + print(f"[download_video] START - task_id: {task_id}") + try: + # task_id로 Video 조회 (여러 개 있을 경우 가장 최근 것 선택) + video_result = await session.execute( + select(Video) + .where(Video.task_id == task_id) + .order_by(Video.created_at.desc()) + .limit(1) + ) + video = video_result.scalar_one_or_none() + + if not video: + print(f"[download_video] Video NOT FOUND - task_id: {task_id}") + return DownloadVideoResponse( + success=False, + status="not_found", + message=f"task_id '{task_id}'에 해당하는 Video를 찾을 수 없습니다.", + error_message="Video not found", + ) + + print(f"[download_video] Video found - task_id: {task_id}, status: {video.status}") + + # processing 상태인 경우 + if video.status == "processing": + print(f"[download_video] PROCESSING - task_id: {task_id}") + return DownloadVideoResponse( + success=True, + status="processing", + message="영상 생성이 진행 중입니다.", + task_id=task_id, + ) + + # failed 상태인 경우 + if video.status == "failed": + print(f"[download_video] FAILED - task_id: {task_id}") + return DownloadVideoResponse( + success=False, + status="failed", + message="영상 생성에 실패했습니다.", + task_id=task_id, + error_message="Video generation failed", + ) + + # completed 상태인 경우 - Project 정보 조회 + project_result = await session.execute( + select(Project).where(Project.id == video.project_id) + ) + project = project_result.scalar_one_or_none() + + print(f"[download_video] COMPLETED - task_id: {task_id}, result_movie_url: {video.result_movie_url}") + return DownloadVideoResponse( + success=True, + status="completed", + message="영상 다운로드가 완료되었습니다.", + store_name=project.store_name if project else None, + region=project.region if project else None, + task_id=task_id, + result_movie_url=video.result_movie_url, + created_at=video.created_at, + ) + + except Exception as e: + print(f"[download_video] EXCEPTION - task_id: {task_id}, error: {e}") + return DownloadVideoResponse( + success=False, + status="error", + message="영상 다운로드 조회에 실패했습니다.", + error_message=str(e), + ) + + +@router.get( + "s/", + summary="생성된 영상 목록 조회", + description=""" +완료된 영상 목록을 페이지네이션하여 조회합니다. + +## 쿼리 파라미터 +- **page**: 페이지 번호 (1부터 시작, 기본값: 1) +- **page_size**: 페이지당 데이터 수 (기본값: 10, 최대: 100) + +## 반환 정보 +- **items**: 영상 목록 (store_name, region, task_id, result_movie_url, created_at) +- **total**: 전체 데이터 수 +- **page**: 현재 페이지 +- **page_size**: 페이지당 데이터 수 +- **total_pages**: 전체 페이지 수 +- **has_next**: 다음 페이지 존재 여부 +- **has_prev**: 이전 페이지 존재 여부 + +## 사용 예시 +``` +GET /videos/?page=1&page_size=10 +``` + +## 참고 +- status가 'completed'인 영상만 반환됩니다. +- 동일한 task_id가 있는 경우 가장 최근에 생성된 1개만 반환됩니다. +- created_at 기준 내림차순 정렬됩니다. + """, + response_model=PaginatedResponse[VideoListItem], + responses={ + 200: {"description": "영상 목록 조회 성공"}, + 500: {"description": "조회 실패"}, + }, +) +async def get_videos( + session: AsyncSession = Depends(get_session), + pagination: PaginationParams = Depends(get_pagination_params), +) -> PaginatedResponse[VideoListItem]: + """완료된 영상 목록을 페이지네이션하여 반환합니다.""" + print(f"[get_videos] START - page: {pagination.page}, page_size: {pagination.page_size}") + try: + offset = (pagination.page - 1) * pagination.page_size + + # 서브쿼리: task_id별 최신 Video의 id 조회 (completed 상태만) + subquery = ( + select(func.max(Video.id).label("max_id")) + .where(Video.status == "completed") + .group_by(Video.task_id) + .subquery() + ) + + # 전체 개수 조회 (task_id별 최신 1개만) + count_query = select(func.count()).select_from(subquery) + total_result = await session.execute(count_query) + total = total_result.scalar() or 0 + + # 데이터 조회 (completed 상태, task_id별 최신 1개만, 최신순) + query = ( + select(Video) + .where(Video.id.in_(select(subquery.c.max_id))) + .order_by(Video.created_at.desc()) + .offset(offset) + .limit(pagination.page_size) + ) + result = await session.execute(query) + videos = result.scalars().all() + + # Project 정보 일괄 조회 (N+1 문제 해결) + project_ids = [v.project_id for v in videos if v.project_id] + projects_map: dict = {} + if project_ids: + projects_result = await session.execute( + select(Project).where(Project.id.in_(project_ids)) + ) + projects_map = {p.id: p for p in projects_result.scalars().all()} + + # VideoListItem으로 변환 + items = [] + for video in videos: + project = projects_map.get(video.project_id) + + item = VideoListItem( + store_name=project.store_name if project else None, + region=project.region if project else None, + task_id=video.task_id, + result_movie_url=video.result_movie_url, + created_at=video.created_at, + ) + items.append(item) + + response = PaginatedResponse.create( + items=items, + total=total, + page=pagination.page, + page_size=pagination.page_size, + ) + + print( + f"[get_videos] SUCCESS - total: {total}, page: {pagination.page}, " + f"page_size: {pagination.page_size}, items_count: {len(items)}" + ) + return response + + except Exception as e: + print(f"[get_videos] EXCEPTION - error: {e}") + raise HTTPException( + status_code=500, + detail=f"영상 목록 조회에 실패했습니다: {str(e)}", + ) diff --git a/app/video/api/video_admin.py b/app/video/api/video_admin.py index 9577f8e..3ea59e0 100644 --- a/app/video/api/video_admin.py +++ b/app/video/api/video_admin.py @@ -1,62 +1,62 @@ -from sqladmin import ModelView - -from app.video.models import Video - - -class VideoAdmin(ModelView, model=Video): - name = "영상" - name_plural = "영상 목록" - icon = "fa-solid fa-video" - category = "영상 관리" - page_size = 20 - - column_list = [ - "id", - "project_id", - "lyric_id", - "song_id", - "task_id", - "status", - "created_at", - ] - - column_details_list = [ - "id", - "project_id", - "lyric_id", - "song_id", - "task_id", - "status", - "result_movie_url", - "created_at", - ] - - # 폼(생성/수정)에서 제외 - form_excluded_columns = ["created_at"] - - column_searchable_list = [ - Video.task_id, - Video.status, - ] - - column_default_sort = (Video.created_at, True) # True: DESC (최신순) - - column_sortable_list = [ - Video.id, - Video.project_id, - Video.lyric_id, - Video.song_id, - Video.status, - Video.created_at, - ] - - column_labels = { - "id": "ID", - "project_id": "프로젝트 ID", - "lyric_id": "가사 ID", - "song_id": "노래 ID", - "task_id": "작업 ID", - "status": "상태", - "result_movie_url": "영상 URL", - "created_at": "생성일시", - } +from sqladmin import ModelView + +from app.video.models import Video + + +class VideoAdmin(ModelView, model=Video): + name = "영상" + name_plural = "영상 목록" + icon = "fa-solid fa-video" + category = "영상 관리" + page_size = 20 + + column_list = [ + "id", + "project_id", + "lyric_id", + "song_id", + "task_id", + "status", + "created_at", + ] + + column_details_list = [ + "id", + "project_id", + "lyric_id", + "song_id", + "task_id", + "status", + "result_movie_url", + "created_at", + ] + + # 폼(생성/수정)에서 제외 + form_excluded_columns = ["created_at"] + + column_searchable_list = [ + Video.task_id, + Video.status, + ] + + column_default_sort = (Video.created_at, True) # True: DESC (최신순) + + column_sortable_list = [ + Video.id, + Video.project_id, + Video.lyric_id, + Video.song_id, + Video.status, + Video.created_at, + ] + + column_labels = { + "id": "ID", + "project_id": "프로젝트 ID", + "lyric_id": "가사 ID", + "song_id": "노래 ID", + "task_id": "작업 ID", + "status": "상태", + "result_movie_url": "영상 URL", + "created_at": "생성일시", + } diff --git a/app/video/dependencies.py b/app/video/dependencies.py index bf6f8ea..d03c265 100644 --- a/app/video/dependencies.py +++ b/app/video/dependencies.py @@ -1,8 +1,8 @@ -from typing import Annotated - -from fastapi import Depends -from sqlalchemy.ext.asyncio import AsyncSession - -from app.database.session import get_session - -SessionDep = Annotated[AsyncSession, Depends(get_session)] +from typing import Annotated + +from fastapi import Depends +from sqlalchemy.ext.asyncio import AsyncSession + +from app.database.session import get_session + +SessionDep = Annotated[AsyncSession, Depends(get_session)] diff --git a/app/video/models.py b/app/video/models.py index a164997..9bcce0b 100644 --- a/app/video/models.py +++ b/app/video/models.py @@ -1,139 +1,139 @@ -from datetime import datetime -from typing import TYPE_CHECKING, Optional - -from sqlalchemy import DateTime, ForeignKey, Integer, String, func -from sqlalchemy.orm import Mapped, mapped_column, relationship - -from app.database.session import Base - -if TYPE_CHECKING: - from app.home.models import Project - from app.lyric.models import Lyric - from app.song.models import Song - - -class Video(Base): - """ - 영상 결과 테이블 - - 최종 생성된 영상의 결과 URL을 저장합니다. - Creatomate 서비스를 통해 이미지와 노래를 결합한 영상 결과입니다. - - Attributes: - id: 고유 식별자 (자동 증가) - project_id: 연결된 Project의 id (외래키) - lyric_id: 연결된 Lyric의 id (외래키) - song_id: 연결된 Song의 id (외래키) - task_id: 영상 생성 작업의 고유 식별자 (UUID 형식) - status: 처리 상태 (pending, processing, completed, failed 등) - result_movie_url: 생성된 영상 URL (S3, CDN 경로) - created_at: 생성 일시 (자동 설정) - - Relationships: - project: 연결된 Project - lyric: 연결된 Lyric - song: 연결된 Song - """ - - __tablename__ = "video" - __table_args__ = ( - { - "mysql_engine": "InnoDB", - "mysql_charset": "utf8mb4", - "mysql_collate": "utf8mb4_unicode_ci", - }, - ) - - id: Mapped[int] = mapped_column( - Integer, - primary_key=True, - nullable=False, - autoincrement=True, - comment="고유 식별자", - ) - - project_id: Mapped[int] = mapped_column( - Integer, - ForeignKey("project.id", ondelete="CASCADE"), - nullable=False, - index=True, - comment="연결된 Project의 id", - ) - - lyric_id: Mapped[int] = mapped_column( - Integer, - ForeignKey("lyric.id", ondelete="CASCADE"), - nullable=False, - index=True, - comment="연결된 Lyric의 id", - ) - - song_id: Mapped[int] = mapped_column( - Integer, - ForeignKey("song.id", ondelete="CASCADE"), - nullable=False, - index=True, - comment="연결된 Song의 id", - ) - - task_id: Mapped[str] = mapped_column( - String(36), - nullable=False, - index=True, - comment="영상 생성 작업 고유 식별자 (UUID)", - ) - - creatomate_render_id: Mapped[Optional[str]] = mapped_column( - String(64), - nullable=True, - comment="Creatomate API 렌더 ID", - ) - - status: Mapped[str] = mapped_column( - String(50), - nullable=False, - comment="처리 상태 (processing, completed, failed)", - ) - - result_movie_url: Mapped[Optional[str]] = mapped_column( - String(2048), - nullable=True, - comment="생성된 영상 URL", - ) - - created_at: Mapped[datetime] = mapped_column( - DateTime, - nullable=False, - server_default=func.now(), - comment="생성 일시", - ) - - # Relationships - project: Mapped["Project"] = relationship( - "Project", - back_populates="videos", - ) - - lyric: Mapped["Lyric"] = relationship( - "Lyric", - back_populates="videos", - ) - - song: Mapped["Song"] = relationship( - "Song", - back_populates="videos", - ) - - def __repr__(self) -> str: - def truncate(value: str | None, max_len: int = 10) -> str: - if value is None: - return "None" - return (value[:max_len] + "...") if len(value) > max_len else value - - return ( - f"" - ) +from datetime import datetime +from typing import TYPE_CHECKING, Optional + +from sqlalchemy import DateTime, ForeignKey, Integer, String, func +from sqlalchemy.orm import Mapped, mapped_column, relationship + +from app.database.session import Base + +if TYPE_CHECKING: + from app.home.models import Project + from app.lyric.models import Lyric + from app.song.models import Song + + +class Video(Base): + """ + 영상 결과 테이블 + + 최종 생성된 영상의 결과 URL을 저장합니다. + Creatomate 서비스를 통해 이미지와 노래를 결합한 영상 결과입니다. + + Attributes: + id: 고유 식별자 (자동 증가) + project_id: 연결된 Project의 id (외래키) + lyric_id: 연결된 Lyric의 id (외래키) + song_id: 연결된 Song의 id (외래키) + task_id: 영상 생성 작업의 고유 식별자 (UUID 형식) + status: 처리 상태 (pending, processing, completed, failed 등) + result_movie_url: 생성된 영상 URL (S3, CDN 경로) + created_at: 생성 일시 (자동 설정) + + Relationships: + project: 연결된 Project + lyric: 연결된 Lyric + song: 연결된 Song + """ + + __tablename__ = "video" + __table_args__ = ( + { + "mysql_engine": "InnoDB", + "mysql_charset": "utf8mb4", + "mysql_collate": "utf8mb4_unicode_ci", + }, + ) + + id: Mapped[int] = mapped_column( + Integer, + primary_key=True, + nullable=False, + autoincrement=True, + comment="고유 식별자", + ) + + project_id: Mapped[int] = mapped_column( + Integer, + ForeignKey("project.id", ondelete="CASCADE"), + nullable=False, + index=True, + comment="연결된 Project의 id", + ) + + lyric_id: Mapped[int] = mapped_column( + Integer, + ForeignKey("lyric.id", ondelete="CASCADE"), + nullable=False, + index=True, + comment="연결된 Lyric의 id", + ) + + song_id: Mapped[int] = mapped_column( + Integer, + ForeignKey("song.id", ondelete="CASCADE"), + nullable=False, + index=True, + comment="연결된 Song의 id", + ) + + task_id: Mapped[str] = mapped_column( + String(36), + nullable=False, + index=True, + comment="영상 생성 작업 고유 식별자 (UUID)", + ) + + creatomate_render_id: Mapped[Optional[str]] = mapped_column( + String(64), + nullable=True, + comment="Creatomate API 렌더 ID", + ) + + status: Mapped[str] = mapped_column( + String(50), + nullable=False, + comment="처리 상태 (processing, completed, failed)", + ) + + result_movie_url: Mapped[Optional[str]] = mapped_column( + String(2048), + nullable=True, + comment="생성된 영상 URL", + ) + + created_at: Mapped[datetime] = mapped_column( + DateTime, + nullable=False, + server_default=func.now(), + comment="생성 일시", + ) + + # Relationships + project: Mapped["Project"] = relationship( + "Project", + back_populates="videos", + ) + + lyric: Mapped["Lyric"] = relationship( + "Lyric", + back_populates="videos", + ) + + song: Mapped["Song"] = relationship( + "Song", + back_populates="videos", + ) + + def __repr__(self) -> str: + def truncate(value: str | None, max_len: int = 10) -> str: + if value is None: + return "None" + return (value[:max_len] + "...") if len(value) > max_len else value + + return ( + f"" + ) diff --git a/app/video/schemas/video_schema.py b/app/video/schemas/video_schema.py index e3f31eb..9f1259e 100644 --- a/app/video/schemas/video_schema.py +++ b/app/video/schemas/video_schema.py @@ -1,156 +1,156 @@ -""" -Video API Schemas - -영상 생성 관련 Pydantic 스키마를 정의합니다. -""" - -from datetime import datetime -from typing import Any, Dict, Literal, Optional - -from pydantic import BaseModel, ConfigDict, Field - - -# ============================================================================= -# Response Schemas -# ============================================================================= - - -class GenerateVideoResponse(BaseModel): - """영상 생성 응답 스키마 - - Usage: - GET /video/generate/{task_id} - Returns the task IDs for tracking video generation. - """ - - model_config = ConfigDict( - json_schema_extra={ - "example": { - "success": True, - "task_id": "0694b716-dbff-7219-8000-d08cb5fce431", - "creatomate_render_id": "render-id-123456", - "message": "영상 생성 요청이 접수되었습니다. creatomate_render_id로 상태를 조회하세요.", - "error_message": None, - } - } - ) - - success: bool = Field(..., description="요청 성공 여부") - task_id: Optional[str] = Field(None, description="내부 작업 ID (Project task_id)") - creatomate_render_id: Optional[str] = Field(None, description="Creatomate 렌더 ID") - message: str = Field(..., description="응답 메시지") - error_message: Optional[str] = Field(None, description="에러 메시지 (실패 시)") - - -class VideoRenderData(BaseModel): - """Creatomate 렌더링 결과 데이터""" - - id: Optional[str] = Field(None, description="렌더 ID") - status: Optional[str] = Field(None, description="렌더 상태") - url: Optional[str] = Field(None, description="영상 URL") - snapshot_url: Optional[str] = Field(None, description="스냅샷 URL") - - -class PollingVideoResponse(BaseModel): - """영상 생성 상태 조회 응답 스키마 - - Usage: - GET /video/status/{creatomate_render_id} - Creatomate API 작업 상태를 조회합니다. - - Note: - 상태 값: - - planned: 예약됨 - - waiting: 대기 중 - - transcribing: 트랜스크립션 중 - - rendering: 렌더링 중 - - succeeded: 성공 - - failed: 실패 - - Example Response (Success): - { - "success": true, - "status": "succeeded", - "message": "영상 생성이 완료되었습니다.", - "render_data": { - "id": "render-id", - "status": "succeeded", - "url": "https://...", - "snapshot_url": "https://..." - }, - "raw_response": {...}, - "error_message": null - } - """ - - success: bool = Field(..., description="조회 성공 여부") - status: Optional[str] = Field( - None, description="작업 상태 (planned, waiting, rendering, succeeded, failed)" - ) - message: str = Field(..., description="상태 메시지") - render_data: Optional[VideoRenderData] = Field(None, description="렌더링 결과 데이터") - raw_response: Optional[Dict[str, Any]] = Field(None, description="Creatomate API 원본 응답") - error_message: Optional[str] = Field(None, description="에러 메시지 (실패 시)") - - -class DownloadVideoResponse(BaseModel): - """영상 다운로드 응답 스키마 - - Usage: - GET /video/download/{task_id} - Polls for video completion and returns project info with video URL. - - Note: - 상태 값: - - processing: 영상 생성 진행 중 (result_movie_url은 null) - - completed: 영상 생성 완료 (result_movie_url 포함) - - failed: 영상 생성 실패 - - not_found: task_id에 해당하는 Video 없음 - - error: 조회 중 오류 발생 - - Example Response (Completed): - { - "success": true, - "status": "completed", - "message": "영상 다운로드가 완료되었습니다.", - "store_name": "스테이 머뭄", - "region": "군산", - "task_id": "019123ab-cdef-7890-abcd-ef1234567890", - "result_movie_url": "http://localhost:8000/media/2025-01-15/video.mp4", - "created_at": "2025-01-15T12:00:00", - "error_message": null - } - """ - - success: bool = Field(..., description="다운로드 성공 여부") - status: str = Field(..., description="처리 상태 (processing, completed, failed, not_found, error)") - message: str = Field(..., description="응답 메시지") - store_name: Optional[str] = Field(None, description="업체명") - region: Optional[str] = Field(None, description="지역명") - task_id: Optional[str] = Field(None, description="작업 고유 식별자") - result_movie_url: Optional[str] = Field(None, description="영상 결과 URL") - created_at: Optional[datetime] = Field(None, description="생성 일시") - error_message: Optional[str] = Field(None, description="에러 메시지 (실패 시)") - - -class VideoListItem(BaseModel): - """영상 목록 아이템 스키마 - - Usage: - GET /videos 응답의 개별 영상 정보 - - Example: - { - "store_name": "스테이 머뭄", - "region": "군산", - "task_id": "019123ab-cdef-7890-abcd-ef1234567890", - "result_movie_url": "http://localhost:8000/media/2025-01-15/video.mp4", - "created_at": "2025-01-15T12:00:00" - } - """ - - store_name: Optional[str] = Field(None, description="업체명") - region: Optional[str] = Field(None, description="지역명") - task_id: str = Field(..., description="작업 고유 식별자") - result_movie_url: Optional[str] = Field(None, description="영상 결과 URL") - created_at: Optional[datetime] = Field(None, description="생성 일시") +""" +Video API Schemas + +영상 생성 관련 Pydantic 스키마를 정의합니다. +""" + +from datetime import datetime +from typing import Any, Dict, Literal, Optional + +from pydantic import BaseModel, ConfigDict, Field + + +# ============================================================================= +# Response Schemas +# ============================================================================= + + +class GenerateVideoResponse(BaseModel): + """영상 생성 응답 스키마 + + Usage: + GET /video/generate/{task_id} + Returns the task IDs for tracking video generation. + """ + + model_config = ConfigDict( + json_schema_extra={ + "example": { + "success": True, + "task_id": "0694b716-dbff-7219-8000-d08cb5fce431", + "creatomate_render_id": "render-id-123456", + "message": "영상 생성 요청이 접수되었습니다. creatomate_render_id로 상태를 조회하세요.", + "error_message": None, + } + } + ) + + success: bool = Field(..., description="요청 성공 여부") + task_id: Optional[str] = Field(None, description="내부 작업 ID (Project task_id)") + creatomate_render_id: Optional[str] = Field(None, description="Creatomate 렌더 ID") + message: str = Field(..., description="응답 메시지") + error_message: Optional[str] = Field(None, description="에러 메시지 (실패 시)") + + +class VideoRenderData(BaseModel): + """Creatomate 렌더링 결과 데이터""" + + id: Optional[str] = Field(None, description="렌더 ID") + status: Optional[str] = Field(None, description="렌더 상태") + url: Optional[str] = Field(None, description="영상 URL") + snapshot_url: Optional[str] = Field(None, description="스냅샷 URL") + + +class PollingVideoResponse(BaseModel): + """영상 생성 상태 조회 응답 스키마 + + Usage: + GET /video/status/{creatomate_render_id} + Creatomate API 작업 상태를 조회합니다. + + Note: + 상태 값: + - planned: 예약됨 + - waiting: 대기 중 + - transcribing: 트랜스크립션 중 + - rendering: 렌더링 중 + - succeeded: 성공 + - failed: 실패 + + Example Response (Success): + { + "success": true, + "status": "succeeded", + "message": "영상 생성이 완료되었습니다.", + "render_data": { + "id": "render-id", + "status": "succeeded", + "url": "https://...", + "snapshot_url": "https://..." + }, + "raw_response": {...}, + "error_message": null + } + """ + + success: bool = Field(..., description="조회 성공 여부") + status: Optional[str] = Field( + None, description="작업 상태 (planned, waiting, rendering, succeeded, failed)" + ) + message: str = Field(..., description="상태 메시지") + render_data: Optional[VideoRenderData] = Field(None, description="렌더링 결과 데이터") + raw_response: Optional[Dict[str, Any]] = Field(None, description="Creatomate API 원본 응답") + error_message: Optional[str] = Field(None, description="에러 메시지 (실패 시)") + + +class DownloadVideoResponse(BaseModel): + """영상 다운로드 응답 스키마 + + Usage: + GET /video/download/{task_id} + Polls for video completion and returns project info with video URL. + + Note: + 상태 값: + - processing: 영상 생성 진행 중 (result_movie_url은 null) + - completed: 영상 생성 완료 (result_movie_url 포함) + - failed: 영상 생성 실패 + - not_found: task_id에 해당하는 Video 없음 + - error: 조회 중 오류 발생 + + Example Response (Completed): + { + "success": true, + "status": "completed", + "message": "영상 다운로드가 완료되었습니다.", + "store_name": "스테이 머뭄", + "region": "군산", + "task_id": "019123ab-cdef-7890-abcd-ef1234567890", + "result_movie_url": "http://localhost:8000/media/2025-01-15/video.mp4", + "created_at": "2025-01-15T12:00:00", + "error_message": null + } + """ + + success: bool = Field(..., description="다운로드 성공 여부") + status: str = Field(..., description="처리 상태 (processing, completed, failed, not_found, error)") + message: str = Field(..., description="응답 메시지") + store_name: Optional[str] = Field(None, description="업체명") + region: Optional[str] = Field(None, description="지역명") + task_id: Optional[str] = Field(None, description="작업 고유 식별자") + result_movie_url: Optional[str] = Field(None, description="영상 결과 URL") + created_at: Optional[datetime] = Field(None, description="생성 일시") + error_message: Optional[str] = Field(None, description="에러 메시지 (실패 시)") + + +class VideoListItem(BaseModel): + """영상 목록 아이템 스키마 + + Usage: + GET /videos 응답의 개별 영상 정보 + + Example: + { + "store_name": "스테이 머뭄", + "region": "군산", + "task_id": "019123ab-cdef-7890-abcd-ef1234567890", + "result_movie_url": "http://localhost:8000/media/2025-01-15/video.mp4", + "created_at": "2025-01-15T12:00:00" + } + """ + + store_name: Optional[str] = Field(None, description="업체명") + region: Optional[str] = Field(None, description="지역명") + task_id: str = Field(..., description="작업 고유 식별자") + result_movie_url: Optional[str] = Field(None, description="영상 결과 URL") + created_at: Optional[datetime] = Field(None, description="생성 일시") diff --git a/app/video/services/video.py b/app/video/services/video.py index 8dbdc3a..fd2c6c0 100644 --- a/app/video/services/video.py +++ b/app/video/services/video.py @@ -1,852 +1,852 @@ -import random -from typing import List - -from fastapi import Request, status -from fastapi.exceptions import HTTPException -from sqlalchemy import Connection, text -from sqlalchemy.exc import SQLAlchemyError - -from app.lyrics.schemas.lyrics_schema import ( - AttributeData, - PromptTemplateData, - SongFormData, - SongSampleData, - StoreData, -) -from app.utils.chatgpt_prompt import chatgpt_api - - -async def get_store_info(conn: Connection) -> List[StoreData]: - try: - query = """SELECT * FROM store_default_info;""" - result = await conn.execute(text(query)) - - all_store_info = [ - StoreData( - id=row[0], - store_info=row[1], - store_name=row[2], - store_category=row[3], - store_region=row[4], - store_address=row[5], - store_phone_number=row[6], - created_at=row[7], - ) - for row in result - ] - - result.close() - return all_store_info - except SQLAlchemyError as e: - print(e) - raise HTTPException( - status_code=status.HTTP_503_SERVICE_UNAVAILABLE, - detail="요청하신 서비스가 잠시 내부적으로 문제가 발생하였습니다.", - ) - except Exception as e: - print(e) - raise HTTPException( - status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, - detail="알수없는 이유로 서비스 오류가 발생하였습니다", - ) - - -async def get_attribute(conn: Connection) -> List[AttributeData]: - try: - query = """SELECT * FROM attribute;""" - result = await conn.execute(text(query)) - - all_attribute = [ - AttributeData( - id=row[0], - attr_category=row[1], - attr_value=row[2], - created_at=row[3], - ) - for row in result - ] - - result.close() - return all_attribute - except SQLAlchemyError as e: - print(e) - raise HTTPException( - status_code=status.HTTP_503_SERVICE_UNAVAILABLE, - detail="요청하신 서비스가 잠시 내부적으로 문제가 발생하였습니다.", - ) - except Exception as e: - print(e) - raise HTTPException( - status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, - detail="알수없는 이유로 서비스 오류가 발생하였습니다", - ) - - -async def get_attribute(conn: Connection) -> List[AttributeData]: - try: - query = """SELECT * FROM attribute;""" - result = await conn.execute(text(query)) - - all_attribute = [ - AttributeData( - id=row[0], - attr_category=row[1], - attr_value=row[2], - created_at=row[3], - ) - for row in result - ] - - result.close() - return all_attribute - except SQLAlchemyError as e: - print(e) - raise HTTPException( - status_code=status.HTTP_503_SERVICE_UNAVAILABLE, - detail="요청하신 서비스가 잠시 내부적으로 문제가 발생하였습니다.", - ) - except Exception as e: - print(e) - raise HTTPException( - status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, - detail="알수없는 이유로 서비스 오류가 발생하였습니다", - ) - - -async def get_sample_song(conn: Connection) -> List[SongSampleData]: - try: - query = """SELECT * FROM song_sample;""" - result = await conn.execute(text(query)) - - all_sample_song = [ - SongSampleData( - id=row[0], - ai=row[1], - ai_model=row[2], - genre=row[3], - sample_song=row[4], - ) - for row in result - ] - - result.close() - return all_sample_song - except SQLAlchemyError as e: - print(e) - raise HTTPException( - status_code=status.HTTP_503_SERVICE_UNAVAILABLE, - detail="요청하신 서비스가 잠시 내부적으로 문제가 발생하였습니다.", - ) - except Exception as e: - print(e) - raise HTTPException( - status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, - detail="알수없는 이유로 서비스 오류가 발생하였습니다", - ) - - -async def get_prompt_template(conn: Connection) -> List[PromptTemplateData]: - try: - query = """SELECT * FROM prompt_template;""" - result = await conn.execute(text(query)) - - all_prompt_template = [ - PromptTemplateData( - id=row[0], - description=row[1], - prompt=row[2], - ) - for row in result - ] - - result.close() - return all_prompt_template - except SQLAlchemyError as e: - print(e) - raise HTTPException( - status_code=status.HTTP_503_SERVICE_UNAVAILABLE, - detail="요청하신 서비스가 잠시 내부적으로 문제가 발생하였습니다.", - ) - except Exception as e: - print(e) - raise HTTPException( - status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, - detail="알수없는 이유로 서비스 오류가 발생하였습니다", - ) - - -async def get_song_result(conn: Connection) -> List[PromptTemplateData]: - try: - query = """SELECT * FROM prompt_template;""" - result = await conn.execute(text(query)) - - all_prompt_template = [ - PromptTemplateData( - id=row[0], - description=row[1], - prompt=row[2], - ) - for row in result - ] - - result.close() - return all_prompt_template - except SQLAlchemyError as e: - print(e) - raise HTTPException( - status_code=status.HTTP_503_SERVICE_UNAVAILABLE, - detail="요청하신 서비스가 잠시 내부적으로 문제가 발생하였습니다.", - ) - except Exception as e: - print(e) - raise HTTPException( - status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, - detail="알수없는 이유로 서비스 오류가 발생하였습니다", - ) - - -async def make_song_result(request: Request, conn: Connection): - try: - # 1. Form 데이터 파싱 - form_data = await SongFormData.from_form(request) - - print(f"\n{'=' * 60}") - print(f"Store ID: {form_data.store_id}") - print(f"Lyrics IDs: {form_data.lyrics_ids}") - print(f"Prompt IDs: {form_data.prompts}") - print(f"{'=' * 60}\n") - - # 2. Store 정보 조회 - store_query = """ - SELECT * FROM store_default_info WHERE id=:id; - """ - store_result = await conn.execute(text(store_query), {"id": form_data.store_id}) - - all_store_info = [ - StoreData( - id=row[0], - store_info=row[1], - store_name=row[2], - store_category=row[3], - store_region=row[4], - store_address=row[5], - store_phone_number=row[6], - created_at=row[7], - ) - for row in store_result - ] - - if not all_store_info: - raise HTTPException( - status_code=status.HTTP_404_NOT_FOUND, - detail=f"Store not found: {form_data.store_id}", - ) - - store_info = all_store_info[0] - print(f"Store: {store_info.store_name}") - - # 3. 속성 조회 -- 단계별 선택 프로세서시 구현 필요 없음 - - # 4. Sample Song 조회 및 결합 - combined_sample_song = None - - if form_data.lyrics_ids: - print(f"\n[샘플 가사 조회] - {len(form_data.lyrics_ids)}개") - - lyrics_query = """ - SELECT sample_song FROM song_sample - WHERE id IN :ids - ORDER BY created_at; - """ - lyrics_result = await conn.execute( - text(lyrics_query), {"ids": tuple(form_data.lyrics_ids)} - ) - - sample_songs = [ - row.sample_song for row in lyrics_result.fetchall() if row.sample_song - ] - - if sample_songs: - combined_sample_song = "\n\n".join( - [f"[샘플 {i + 1}]\n{song}" for i, song in enumerate(sample_songs)] - ) - print(f"{len(sample_songs)}개의 샘플 가사 조회 완료") - else: - print("샘플 가사가 비어있습니다") - else: - print("선택된 lyrics가 없습니다") - - # 5. 템플릿 가져오기 - if not form_data.prompts: - raise HTTPException( - status_code=status.HTTP_400_BAD_REQUEST, - detail="프롬프트 ID가 필요합니다", - ) - - print("템플릿 가져오기") - - prompts_query = """ - SELECT * FROM prompt_template WHERE id=:id; - """ - - # ✅ 수정: store_query → prompts_query - prompts_result = await conn.execute( - text(prompts_query), {"id": form_data.prompts} - ) - - prompts_info = [ - PromptTemplateData( - id=row[0], - description=row[1], - prompt=row[2], - ) - for row in prompts_result - ] - - if not prompts_info: - raise HTTPException( - status_code=status.HTTP_404_NOT_FOUND, - detail=f"Prompt not found: {form_data.prompts}", - ) - - prompt = prompts_info[0] - print(f"Prompt Template: {prompt.prompt}") - - # ✅ 6. 프롬프트 조합 - updated_prompt = prompt.prompt.replace("###", form_data.attributes_str).format( - name=store_info.store_name or "", - address=store_info.store_address or "", - category=store_info.store_category or "", - description=store_info.store_info or "", - ) - - updated_prompt += f""" - - 다음은 참고해야 하는 샘플 가사 정보입니다. - - 샘플 가사를 참고하여 작곡을 해주세요. - - {combined_sample_song} - """ - - print(f"\n[업데이트된 프롬프트]\n{updated_prompt}\n") - - # 7. 모델에게 요청 - generated_lyrics = await chatgpt_api.generate(prompt=updated_prompt) - - # 글자 수 계산 - total_chars_with_space = len(generated_lyrics) - total_chars_without_space = len( - generated_lyrics.replace(" ", "") - .replace("\n", "") - .replace("\r", "") - .replace("\t", "") - ) - - # final_lyrics 생성 - final_lyrics = f"""속성 {form_data.attributes_str} - 전체 글자 수 (공백 포함): {total_chars_with_space}자 - 전체 글자 수 (공백 제외): {total_chars_without_space}자\r\n\r\n{generated_lyrics}""" - - print("=" * 40) - print("[translate:form_data.attributes_str:] ", form_data.attributes_str) - print("[translate:total_chars_with_space:] ", total_chars_with_space) - print("[translate:total_chars_without_space:] ", total_chars_without_space) - print("[translate:final_lyrics:]") - print(final_lyrics) - print("=" * 40) - - # 8. DB 저장 - insert_query = """ - INSERT INTO song_results_all ( - store_info, store_name, store_category, store_address, store_phone_number, - description, prompt, attr_category, attr_value, - ai, ai_model, genre, - sample_song, result_song, created_at - ) VALUES ( - :store_info, :store_name, :store_category, :store_address, :store_phone_number, - :description, :prompt, :attr_category, :attr_value, - :ai, :ai_model, :genre, - :sample_song, :result_song, NOW() - ); - """ - - # ✅ attr_category, attr_value 추가 - insert_params = { - "store_info": store_info.store_info or "", - "store_name": store_info.store_name, - "store_category": store_info.store_category or "", - "store_address": store_info.store_address or "", - "store_phone_number": store_info.store_phone_number or "", - "description": store_info.store_info or "", - "prompt": form_data.prompts, - "attr_category": ", ".join(form_data.attributes.keys()) - if form_data.attributes - else "", - "attr_value": ", ".join(form_data.attributes.values()) - if form_data.attributes - else "", - "ai": "ChatGPT", - "ai_model": form_data.llm_model, - "genre": "후크송", - "sample_song": combined_sample_song or "없음", - "result_song": final_lyrics, - } - - await conn.execute(text(insert_query), insert_params) - await conn.commit() - - print("결과 저장 완료") - - print("\n전체 결과 조회 중...") - - # 9. 생성 결과 가져오기 (created_at 역순) - select_query = """ - SELECT * FROM song_results_all - ORDER BY created_at DESC; - """ - - all_results = await conn.execute(text(select_query)) - - results_list = [ - { - "id": row.id, - "store_info": row.store_info, - "store_name": row.store_name, - "store_category": row.store_category, - "store_address": row.store_address, - "store_phone_number": row.store_phone_number, - "description": row.description, - "prompt": row.prompt, - "attr_category": row.attr_category, - "attr_value": row.attr_value, - "ai": row.ai, - "ai_model": row.ai_model, - "genre": row.genre, - "sample_song": row.sample_song, - "result_song": row.result_song, - "created_at": row.created_at.isoformat() if row.created_at else None, - } - for row in all_results.fetchall() - ] - - print(f"전체 {len(results_list)}개의 결과 조회 완료\n") - - return results_list - - except HTTPException: - raise - except SQLAlchemyError as e: - print(f"Database Error: {e}") - import traceback - - traceback.print_exc() - raise HTTPException( - status_code=status.HTTP_503_SERVICE_UNAVAILABLE, - detail="데이터베이스 연결에 문제가 발생했습니다.", - ) - except Exception as e: - print(f"Unexpected Error: {e}") - import traceback - - traceback.print_exc() - raise HTTPException( - status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, - detail="서비스 처리 중 오류가 발생했습니다.", - ) - - -async def get_song_result(conn: Connection): # 반환 타입 수정 - try: - select_query = """ - SELECT * FROM song_results_all - ORDER BY created_at DESC; - """ - - all_results = await conn.execute(text(select_query)) - - results_list = [ - { - "id": row.id, - "store_info": row.store_info, - "store_name": row.store_name, - "store_category": row.store_category, - "store_address": row.store_address, - "store_phone_number": row.store_phone_number, - "description": row.description, - "prompt": row.prompt, - "attr_category": row.attr_category, - "attr_value": row.attr_value, - "ai": row.ai, - "ai_model": row.ai_model, - "season": row.season, - "num_of_people": row.num_of_people, - "people_category": row.people_category, - "genre": row.genre, - "sample_song": row.sample_song, - "result_song": row.result_song, - "created_at": row.created_at.isoformat() if row.created_at else None, - } - for row in all_results.fetchall() - ] - - print(f"전체 {len(results_list)}개의 결과 조회 완료\n") - - return results_list - except HTTPException: # HTTPException은 그대로 raise - raise - except SQLAlchemyError as e: - print(f"Database Error: {e}") - import traceback - - traceback.print_exc() - raise HTTPException( - status_code=status.HTTP_503_SERVICE_UNAVAILABLE, - detail="데이터베이스 연결에 문제가 발생했습니다.", - ) - except Exception as e: - print(f"Unexpected Error: {e}") - import traceback - - traceback.print_exc() - raise HTTPException( - status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, - detail="서비스 처리 중 오류가 발생했습니다.", - ) - - -async def make_automation(request: Request, conn: Connection): - try: - # 1. Form 데이터 파싱 - form_data = await SongFormData.from_form(request) - - print(f"\n{'=' * 60}") - print(f"Store ID: {form_data.store_id}") - print(f"{'=' * 60}\n") - - # 2. Store 정보 조회 - store_query = """ - SELECT * FROM store_default_info WHERE id=:id; - """ - store_result = await conn.execute(text(store_query), {"id": form_data.store_id}) - - all_store_info = [ - StoreData( - id=row[0], - store_info=row[1], - store_name=row[2], - store_category=row[3], - store_region=row[4], - store_address=row[5], - store_phone_number=row[6], - created_at=row[7], - ) - for row in store_result - ] - - if not all_store_info: - raise HTTPException( - status_code=status.HTTP_404_NOT_FOUND, - detail=f"Store not found: {form_data.store_id}", - ) - - store_info = all_store_info[0] - print(f"Store: {store_info.store_name}") - - # 3. 속성 조회 -- 단계별 선택 프로세서시 구현 필요 없음 - attribute_query = """ - SELECT * FROM attribute; - """ - - attribute_results = await conn.execute(text(attribute_query)) - - # 결과 가져오기 - attribute_rows = attribute_results.fetchall() - - formatted_attributes = "" - selected_categories = [] - selected_values = [] - - if attribute_rows: - attribute_list = [ - AttributeData( - id=row[0], - attr_category=row[1], - attr_value=row[2], - created_at=row[3], - ) - for row in attribute_rows - ] - - # ✅ 각 category에서 하나의 value만 랜덤 선택 - formatted_pairs = [] - for attr in attribute_list: - # 쉼표로 분리 및 공백 제거 - values = [v.strip() for v in attr.attr_value.split(",") if v.strip()] - - if values: - # 랜덤하게 하나만 선택 - selected_value = random.choice(values) - formatted_pairs.append(f"{attr.attr_category} : {selected_value}") - - # ✅ 선택된 category와 value 저장 - selected_categories.append(attr.attr_category) - selected_values.append(selected_value) - - # 최종 문자열 생성 - formatted_attributes = "\n".join(formatted_pairs) - - print(f"\n[포맷팅된 문자열 속성 정보]\n{formatted_attributes}\n") - else: - print("속성 데이터가 없습니다") - formatted_attributes = "" - - # 4. 템플릿 가져오기 - print("템플릿 가져오기 (ID=1)") - - prompts_query = """ - SELECT * FROM prompt_template WHERE id=1; - """ - - prompts_result = await conn.execute(text(prompts_query)) - - row = prompts_result.fetchone() - - if not row: - raise HTTPException( - status_code=status.HTTP_404_NOT_FOUND, - detail="Prompt ID 1 not found", - ) - - prompt = PromptTemplateData( - id=row[0], - description=row[1], - prompt=row[2], - ) - - print(f"Prompt Template: {prompt.prompt}") - - # 5. 템플릿 조합 - - updated_prompt = prompt.prompt.replace("###", formatted_attributes).format( - name=store_info.store_name or "", - address=store_info.store_address or "", - category=store_info.store_category or "", - description=store_info.store_info or "", - ) - - print("\n" + "=" * 80) - print("업데이트된 프롬프트") - print("=" * 80) - print(updated_prompt) - print("=" * 80 + "\n") - - # 4. Sample Song 조회 및 결합 - combined_sample_song = None - - if form_data.lyrics_ids: - print(f"\n[샘플 가사 조회] - {len(form_data.lyrics_ids)}개") - - lyrics_query = """ - SELECT sample_song FROM song_sample - WHERE id IN :ids - ORDER BY created_at; - """ - lyrics_result = await conn.execute( - text(lyrics_query), {"ids": tuple(form_data.lyrics_ids)} - ) - - sample_songs = [ - row.sample_song for row in lyrics_result.fetchall() if row.sample_song - ] - - if sample_songs: - combined_sample_song = "\n\n".join( - [f"[샘플 {i + 1}]\n{song}" for i, song in enumerate(sample_songs)] - ) - print(f"{len(sample_songs)}개의 샘플 가사 조회 완료") - else: - print("샘플 가사가 비어있습니다") - else: - print("선택된 lyrics가 없습니다") - - # 1. song_sample 테이블의 모든 ID 조회 - print("\n[샘플 가사 랜덤 선택]") - - all_ids_query = """ - SELECT id FROM song_sample; - """ - ids_result = await conn.execute(text(all_ids_query)) - all_ids = [row.id for row in ids_result.fetchall()] - - print(f"전체 샘플 가사 개수: {len(all_ids)}개") - - # 2. 랜덤하게 3개 선택 (또는 전체 개수가 3개 미만이면 전체) - combined_sample_song = None - - if all_ids: - # 3개 또는 전체 개수 중 작은 값 선택 - sample_count = min(3, len(all_ids)) - selected_ids = random.sample(all_ids, sample_count) - - print(f"랜덤 선택된 ID: {selected_ids}") - - # 3. 선택된 ID로 샘플 가사 조회 - lyrics_query = """ - SELECT sample_song FROM song_sample - WHERE id IN :ids - ORDER BY created_at; - """ - lyrics_result = await conn.execute( - text(lyrics_query), {"ids": tuple(selected_ids)} - ) - - sample_songs = [ - row.sample_song for row in lyrics_result.fetchall() if row.sample_song - ] - - # 4. combined_sample_song 생성 - if sample_songs: - combined_sample_song = "\n\n".join( - [f"[샘플 {i + 1}]\n{song}" for i, song in enumerate(sample_songs)] - ) - print(f"{len(sample_songs)}개의 샘플 가사 조회 완료") - else: - print("샘플 가사가 비어있습니다") - else: - print("song_sample 테이블에 데이터가 없습니다") - - # 5. 프롬프트에 샘플 가사 추가 - if combined_sample_song: - updated_prompt += f""" - - 다음은 참고해야 하는 샘플 가사 정보입니다. - - 샘플 가사를 참고하여 작곡을 해주세요. - - {combined_sample_song} - """ - print("샘플 가사 정보가 프롬프트에 추가되었습니다") - else: - print("샘플 가사가 없어 기본 프롬프트만 사용합니다") - - print(f"\n[최종 프롬프트 길이: {len(updated_prompt)} 자]\n") - - # 7. 모델에게 요청 - generated_lyrics = await chatgpt_api.generate(prompt=updated_prompt) - - # 글자 수 계산 - total_chars_with_space = len(generated_lyrics) - total_chars_without_space = len( - generated_lyrics.replace(" ", "") - .replace("\n", "") - .replace("\r", "") - .replace("\t", "") - ) - - # final_lyrics 생성 - final_lyrics = f"""속성 {formatted_attributes} - 전체 글자 수 (공백 포함): {total_chars_with_space}자 - 전체 글자 수 (공백 제외): {total_chars_without_space}자\r\n\r\n{generated_lyrics}""" - - # 8. DB 저장 - insert_query = """ - INSERT INTO song_results_all ( - store_info, store_name, store_category, store_address, store_phone_number, - description, prompt, attr_category, attr_value, - ai, ai_model, genre, - sample_song, result_song, created_at - ) VALUES ( - :store_info, :store_name, :store_category, :store_address, :store_phone_number, - :description, :prompt, :attr_category, :attr_value, - :ai, :ai_model, :genre, - :sample_song, :result_song, NOW() - ); - """ - print("\n[insert_params 선택된 속성 확인]") - print(f"Categories: {selected_categories}") - print(f"Values: {selected_values}") - print() - - # attr_category, attr_value - insert_params = { - "store_info": store_info.store_info or "", - "store_name": store_info.store_name, - "store_category": store_info.store_category or "", - "store_address": store_info.store_address or "", - "store_phone_number": store_info.store_phone_number or "", - "description": store_info.store_info or "", - "prompt": prompt.id, - # 랜덤 선택된 category와 value 사용 - "attr_category": ", ".join(selected_categories) - if selected_categories - else "", - "attr_value": ", ".join(selected_values) if selected_values else "", - "ai": "ChatGPT", - "ai_model": "gpt-4o", - "genre": "후크송", - "sample_song": combined_sample_song or "없음", - "result_song": final_lyrics, - } - - await conn.execute(text(insert_query), insert_params) - await conn.commit() - - print("결과 저장 완료") - - print("\n전체 결과 조회 중...") - - # 9. 생성 결과 가져오기 (created_at 역순) - select_query = """ - SELECT * FROM song_results_all - ORDER BY created_at DESC; - """ - - all_results = await conn.execute(text(select_query)) - - results_list = [ - { - "id": row.id, - "store_info": row.store_info, - "store_name": row.store_name, - "store_category": row.store_category, - "store_address": row.store_address, - "store_phone_number": row.store_phone_number, - "description": row.description, - "prompt": row.prompt, - "attr_category": row.attr_category, - "attr_value": row.attr_value, - "ai": row.ai, - "ai_model": row.ai_model, - "genre": row.genre, - "sample_song": row.sample_song, - "result_song": row.result_song, - "created_at": row.created_at.isoformat() if row.created_at else None, - } - for row in all_results.fetchall() - ] - - print(f"전체 {len(results_list)}개의 결과 조회 완료\n") - - return results_list - - except HTTPException: - raise - except SQLAlchemyError as e: - print(f"Database Error: {e}") - import traceback - - traceback.print_exc() - raise HTTPException( - status_code=status.HTTP_503_SERVICE_UNAVAILABLE, - detail="데이터베이스 연결에 문제가 발생했습니다.", - ) - except Exception as e: - print(f"Unexpected Error: {e}") - import traceback - - traceback.print_exc() - raise HTTPException( - status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, - detail="서비스 처리 중 오류가 발생했습니다.", - ) +import random +from typing import List + +from fastapi import Request, status +from fastapi.exceptions import HTTPException +from sqlalchemy import Connection, text +from sqlalchemy.exc import SQLAlchemyError + +from app.lyrics.schemas.lyrics_schema import ( + AttributeData, + PromptTemplateData, + SongFormData, + SongSampleData, + StoreData, +) +from app.utils.chatgpt_prompt import chatgpt_api + + +async def get_store_info(conn: Connection) -> List[StoreData]: + try: + query = """SELECT * FROM store_default_info;""" + result = await conn.execute(text(query)) + + all_store_info = [ + StoreData( + id=row[0], + store_info=row[1], + store_name=row[2], + store_category=row[3], + store_region=row[4], + store_address=row[5], + store_phone_number=row[6], + created_at=row[7], + ) + for row in result + ] + + result.close() + return all_store_info + except SQLAlchemyError as e: + print(e) + raise HTTPException( + status_code=status.HTTP_503_SERVICE_UNAVAILABLE, + detail="요청하신 서비스가 잠시 내부적으로 문제가 발생하였습니다.", + ) + except Exception as e: + print(e) + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="알수없는 이유로 서비스 오류가 발생하였습니다", + ) + + +async def get_attribute(conn: Connection) -> List[AttributeData]: + try: + query = """SELECT * FROM attribute;""" + result = await conn.execute(text(query)) + + all_attribute = [ + AttributeData( + id=row[0], + attr_category=row[1], + attr_value=row[2], + created_at=row[3], + ) + for row in result + ] + + result.close() + return all_attribute + except SQLAlchemyError as e: + print(e) + raise HTTPException( + status_code=status.HTTP_503_SERVICE_UNAVAILABLE, + detail="요청하신 서비스가 잠시 내부적으로 문제가 발생하였습니다.", + ) + except Exception as e: + print(e) + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="알수없는 이유로 서비스 오류가 발생하였습니다", + ) + + +async def get_attribute(conn: Connection) -> List[AttributeData]: + try: + query = """SELECT * FROM attribute;""" + result = await conn.execute(text(query)) + + all_attribute = [ + AttributeData( + id=row[0], + attr_category=row[1], + attr_value=row[2], + created_at=row[3], + ) + for row in result + ] + + result.close() + return all_attribute + except SQLAlchemyError as e: + print(e) + raise HTTPException( + status_code=status.HTTP_503_SERVICE_UNAVAILABLE, + detail="요청하신 서비스가 잠시 내부적으로 문제가 발생하였습니다.", + ) + except Exception as e: + print(e) + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="알수없는 이유로 서비스 오류가 발생하였습니다", + ) + + +async def get_sample_song(conn: Connection) -> List[SongSampleData]: + try: + query = """SELECT * FROM song_sample;""" + result = await conn.execute(text(query)) + + all_sample_song = [ + SongSampleData( + id=row[0], + ai=row[1], + ai_model=row[2], + genre=row[3], + sample_song=row[4], + ) + for row in result + ] + + result.close() + return all_sample_song + except SQLAlchemyError as e: + print(e) + raise HTTPException( + status_code=status.HTTP_503_SERVICE_UNAVAILABLE, + detail="요청하신 서비스가 잠시 내부적으로 문제가 발생하였습니다.", + ) + except Exception as e: + print(e) + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="알수없는 이유로 서비스 오류가 발생하였습니다", + ) + + +async def get_prompt_template(conn: Connection) -> List[PromptTemplateData]: + try: + query = """SELECT * FROM prompt_template;""" + result = await conn.execute(text(query)) + + all_prompt_template = [ + PromptTemplateData( + id=row[0], + description=row[1], + prompt=row[2], + ) + for row in result + ] + + result.close() + return all_prompt_template + except SQLAlchemyError as e: + print(e) + raise HTTPException( + status_code=status.HTTP_503_SERVICE_UNAVAILABLE, + detail="요청하신 서비스가 잠시 내부적으로 문제가 발생하였습니다.", + ) + except Exception as e: + print(e) + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="알수없는 이유로 서비스 오류가 발생하였습니다", + ) + + +async def get_song_result(conn: Connection) -> List[PromptTemplateData]: + try: + query = """SELECT * FROM prompt_template;""" + result = await conn.execute(text(query)) + + all_prompt_template = [ + PromptTemplateData( + id=row[0], + description=row[1], + prompt=row[2], + ) + for row in result + ] + + result.close() + return all_prompt_template + except SQLAlchemyError as e: + print(e) + raise HTTPException( + status_code=status.HTTP_503_SERVICE_UNAVAILABLE, + detail="요청하신 서비스가 잠시 내부적으로 문제가 발생하였습니다.", + ) + except Exception as e: + print(e) + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="알수없는 이유로 서비스 오류가 발생하였습니다", + ) + + +async def make_song_result(request: Request, conn: Connection): + try: + # 1. Form 데이터 파싱 + form_data = await SongFormData.from_form(request) + + print(f"\n{'=' * 60}") + print(f"Store ID: {form_data.store_id}") + print(f"Lyrics IDs: {form_data.lyrics_ids}") + print(f"Prompt IDs: {form_data.prompts}") + print(f"{'=' * 60}\n") + + # 2. Store 정보 조회 + store_query = """ + SELECT * FROM store_default_info WHERE id=:id; + """ + store_result = await conn.execute(text(store_query), {"id": form_data.store_id}) + + all_store_info = [ + StoreData( + id=row[0], + store_info=row[1], + store_name=row[2], + store_category=row[3], + store_region=row[4], + store_address=row[5], + store_phone_number=row[6], + created_at=row[7], + ) + for row in store_result + ] + + if not all_store_info: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=f"Store not found: {form_data.store_id}", + ) + + store_info = all_store_info[0] + print(f"Store: {store_info.store_name}") + + # 3. 속성 조회 -- 단계별 선택 프로세서시 구현 필요 없음 + + # 4. Sample Song 조회 및 결합 + combined_sample_song = None + + if form_data.lyrics_ids: + print(f"\n[샘플 가사 조회] - {len(form_data.lyrics_ids)}개") + + lyrics_query = """ + SELECT sample_song FROM song_sample + WHERE id IN :ids + ORDER BY created_at; + """ + lyrics_result = await conn.execute( + text(lyrics_query), {"ids": tuple(form_data.lyrics_ids)} + ) + + sample_songs = [ + row.sample_song for row in lyrics_result.fetchall() if row.sample_song + ] + + if sample_songs: + combined_sample_song = "\n\n".join( + [f"[샘플 {i + 1}]\n{song}" for i, song in enumerate(sample_songs)] + ) + print(f"{len(sample_songs)}개의 샘플 가사 조회 완료") + else: + print("샘플 가사가 비어있습니다") + else: + print("선택된 lyrics가 없습니다") + + # 5. 템플릿 가져오기 + if not form_data.prompts: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail="프롬프트 ID가 필요합니다", + ) + + print("템플릿 가져오기") + + prompts_query = """ + SELECT * FROM prompt_template WHERE id=:id; + """ + + # ✅ 수정: store_query → prompts_query + prompts_result = await conn.execute( + text(prompts_query), {"id": form_data.prompts} + ) + + prompts_info = [ + PromptTemplateData( + id=row[0], + description=row[1], + prompt=row[2], + ) + for row in prompts_result + ] + + if not prompts_info: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=f"Prompt not found: {form_data.prompts}", + ) + + prompt = prompts_info[0] + print(f"Prompt Template: {prompt.prompt}") + + # ✅ 6. 프롬프트 조합 + updated_prompt = prompt.prompt.replace("###", form_data.attributes_str).format( + name=store_info.store_name or "", + address=store_info.store_address or "", + category=store_info.store_category or "", + description=store_info.store_info or "", + ) + + updated_prompt += f""" + + 다음은 참고해야 하는 샘플 가사 정보입니다. + + 샘플 가사를 참고하여 작곡을 해주세요. + + {combined_sample_song} + """ + + print(f"\n[업데이트된 프롬프트]\n{updated_prompt}\n") + + # 7. 모델에게 요청 + generated_lyrics = await chatgpt_api.generate(prompt=updated_prompt) + + # 글자 수 계산 + total_chars_with_space = len(generated_lyrics) + total_chars_without_space = len( + generated_lyrics.replace(" ", "") + .replace("\n", "") + .replace("\r", "") + .replace("\t", "") + ) + + # final_lyrics 생성 + final_lyrics = f"""속성 {form_data.attributes_str} + 전체 글자 수 (공백 포함): {total_chars_with_space}자 + 전체 글자 수 (공백 제외): {total_chars_without_space}자\r\n\r\n{generated_lyrics}""" + + print("=" * 40) + print("[translate:form_data.attributes_str:] ", form_data.attributes_str) + print("[translate:total_chars_with_space:] ", total_chars_with_space) + print("[translate:total_chars_without_space:] ", total_chars_without_space) + print("[translate:final_lyrics:]") + print(final_lyrics) + print("=" * 40) + + # 8. DB 저장 + insert_query = """ + INSERT INTO song_results_all ( + store_info, store_name, store_category, store_address, store_phone_number, + description, prompt, attr_category, attr_value, + ai, ai_model, genre, + sample_song, result_song, created_at + ) VALUES ( + :store_info, :store_name, :store_category, :store_address, :store_phone_number, + :description, :prompt, :attr_category, :attr_value, + :ai, :ai_model, :genre, + :sample_song, :result_song, NOW() + ); + """ + + # ✅ attr_category, attr_value 추가 + insert_params = { + "store_info": store_info.store_info or "", + "store_name": store_info.store_name, + "store_category": store_info.store_category or "", + "store_address": store_info.store_address or "", + "store_phone_number": store_info.store_phone_number or "", + "description": store_info.store_info or "", + "prompt": form_data.prompts, + "attr_category": ", ".join(form_data.attributes.keys()) + if form_data.attributes + else "", + "attr_value": ", ".join(form_data.attributes.values()) + if form_data.attributes + else "", + "ai": "ChatGPT", + "ai_model": form_data.llm_model, + "genre": "후크송", + "sample_song": combined_sample_song or "없음", + "result_song": final_lyrics, + } + + await conn.execute(text(insert_query), insert_params) + await conn.commit() + + print("결과 저장 완료") + + print("\n전체 결과 조회 중...") + + # 9. 생성 결과 가져오기 (created_at 역순) + select_query = """ + SELECT * FROM song_results_all + ORDER BY created_at DESC; + """ + + all_results = await conn.execute(text(select_query)) + + results_list = [ + { + "id": row.id, + "store_info": row.store_info, + "store_name": row.store_name, + "store_category": row.store_category, + "store_address": row.store_address, + "store_phone_number": row.store_phone_number, + "description": row.description, + "prompt": row.prompt, + "attr_category": row.attr_category, + "attr_value": row.attr_value, + "ai": row.ai, + "ai_model": row.ai_model, + "genre": row.genre, + "sample_song": row.sample_song, + "result_song": row.result_song, + "created_at": row.created_at.isoformat() if row.created_at else None, + } + for row in all_results.fetchall() + ] + + print(f"전체 {len(results_list)}개의 결과 조회 완료\n") + + return results_list + + except HTTPException: + raise + except SQLAlchemyError as e: + print(f"Database Error: {e}") + import traceback + + traceback.print_exc() + raise HTTPException( + status_code=status.HTTP_503_SERVICE_UNAVAILABLE, + detail="데이터베이스 연결에 문제가 발생했습니다.", + ) + except Exception as e: + print(f"Unexpected Error: {e}") + import traceback + + traceback.print_exc() + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="서비스 처리 중 오류가 발생했습니다.", + ) + + +async def get_song_result(conn: Connection): # 반환 타입 수정 + try: + select_query = """ + SELECT * FROM song_results_all + ORDER BY created_at DESC; + """ + + all_results = await conn.execute(text(select_query)) + + results_list = [ + { + "id": row.id, + "store_info": row.store_info, + "store_name": row.store_name, + "store_category": row.store_category, + "store_address": row.store_address, + "store_phone_number": row.store_phone_number, + "description": row.description, + "prompt": row.prompt, + "attr_category": row.attr_category, + "attr_value": row.attr_value, + "ai": row.ai, + "ai_model": row.ai_model, + "season": row.season, + "num_of_people": row.num_of_people, + "people_category": row.people_category, + "genre": row.genre, + "sample_song": row.sample_song, + "result_song": row.result_song, + "created_at": row.created_at.isoformat() if row.created_at else None, + } + for row in all_results.fetchall() + ] + + print(f"전체 {len(results_list)}개의 결과 조회 완료\n") + + return results_list + except HTTPException: # HTTPException은 그대로 raise + raise + except SQLAlchemyError as e: + print(f"Database Error: {e}") + import traceback + + traceback.print_exc() + raise HTTPException( + status_code=status.HTTP_503_SERVICE_UNAVAILABLE, + detail="데이터베이스 연결에 문제가 발생했습니다.", + ) + except Exception as e: + print(f"Unexpected Error: {e}") + import traceback + + traceback.print_exc() + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="서비스 처리 중 오류가 발생했습니다.", + ) + + +async def make_automation(request: Request, conn: Connection): + try: + # 1. Form 데이터 파싱 + form_data = await SongFormData.from_form(request) + + print(f"\n{'=' * 60}") + print(f"Store ID: {form_data.store_id}") + print(f"{'=' * 60}\n") + + # 2. Store 정보 조회 + store_query = """ + SELECT * FROM store_default_info WHERE id=:id; + """ + store_result = await conn.execute(text(store_query), {"id": form_data.store_id}) + + all_store_info = [ + StoreData( + id=row[0], + store_info=row[1], + store_name=row[2], + store_category=row[3], + store_region=row[4], + store_address=row[5], + store_phone_number=row[6], + created_at=row[7], + ) + for row in store_result + ] + + if not all_store_info: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=f"Store not found: {form_data.store_id}", + ) + + store_info = all_store_info[0] + print(f"Store: {store_info.store_name}") + + # 3. 속성 조회 -- 단계별 선택 프로세서시 구현 필요 없음 + attribute_query = """ + SELECT * FROM attribute; + """ + + attribute_results = await conn.execute(text(attribute_query)) + + # 결과 가져오기 + attribute_rows = attribute_results.fetchall() + + formatted_attributes = "" + selected_categories = [] + selected_values = [] + + if attribute_rows: + attribute_list = [ + AttributeData( + id=row[0], + attr_category=row[1], + attr_value=row[2], + created_at=row[3], + ) + for row in attribute_rows + ] + + # ✅ 각 category에서 하나의 value만 랜덤 선택 + formatted_pairs = [] + for attr in attribute_list: + # 쉼표로 분리 및 공백 제거 + values = [v.strip() for v in attr.attr_value.split(",") if v.strip()] + + if values: + # 랜덤하게 하나만 선택 + selected_value = random.choice(values) + formatted_pairs.append(f"{attr.attr_category} : {selected_value}") + + # ✅ 선택된 category와 value 저장 + selected_categories.append(attr.attr_category) + selected_values.append(selected_value) + + # 최종 문자열 생성 + formatted_attributes = "\n".join(formatted_pairs) + + print(f"\n[포맷팅된 문자열 속성 정보]\n{formatted_attributes}\n") + else: + print("속성 데이터가 없습니다") + formatted_attributes = "" + + # 4. 템플릿 가져오기 + print("템플릿 가져오기 (ID=1)") + + prompts_query = """ + SELECT * FROM prompt_template WHERE id=1; + """ + + prompts_result = await conn.execute(text(prompts_query)) + + row = prompts_result.fetchone() + + if not row: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="Prompt ID 1 not found", + ) + + prompt = PromptTemplateData( + id=row[0], + description=row[1], + prompt=row[2], + ) + + print(f"Prompt Template: {prompt.prompt}") + + # 5. 템플릿 조합 + + updated_prompt = prompt.prompt.replace("###", formatted_attributes).format( + name=store_info.store_name or "", + address=store_info.store_address or "", + category=store_info.store_category or "", + description=store_info.store_info or "", + ) + + print("\n" + "=" * 80) + print("업데이트된 프롬프트") + print("=" * 80) + print(updated_prompt) + print("=" * 80 + "\n") + + # 4. Sample Song 조회 및 결합 + combined_sample_song = None + + if form_data.lyrics_ids: + print(f"\n[샘플 가사 조회] - {len(form_data.lyrics_ids)}개") + + lyrics_query = """ + SELECT sample_song FROM song_sample + WHERE id IN :ids + ORDER BY created_at; + """ + lyrics_result = await conn.execute( + text(lyrics_query), {"ids": tuple(form_data.lyrics_ids)} + ) + + sample_songs = [ + row.sample_song for row in lyrics_result.fetchall() if row.sample_song + ] + + if sample_songs: + combined_sample_song = "\n\n".join( + [f"[샘플 {i + 1}]\n{song}" for i, song in enumerate(sample_songs)] + ) + print(f"{len(sample_songs)}개의 샘플 가사 조회 완료") + else: + print("샘플 가사가 비어있습니다") + else: + print("선택된 lyrics가 없습니다") + + # 1. song_sample 테이블의 모든 ID 조회 + print("\n[샘플 가사 랜덤 선택]") + + all_ids_query = """ + SELECT id FROM song_sample; + """ + ids_result = await conn.execute(text(all_ids_query)) + all_ids = [row.id for row in ids_result.fetchall()] + + print(f"전체 샘플 가사 개수: {len(all_ids)}개") + + # 2. 랜덤하게 3개 선택 (또는 전체 개수가 3개 미만이면 전체) + combined_sample_song = None + + if all_ids: + # 3개 또는 전체 개수 중 작은 값 선택 + sample_count = min(3, len(all_ids)) + selected_ids = random.sample(all_ids, sample_count) + + print(f"랜덤 선택된 ID: {selected_ids}") + + # 3. 선택된 ID로 샘플 가사 조회 + lyrics_query = """ + SELECT sample_song FROM song_sample + WHERE id IN :ids + ORDER BY created_at; + """ + lyrics_result = await conn.execute( + text(lyrics_query), {"ids": tuple(selected_ids)} + ) + + sample_songs = [ + row.sample_song for row in lyrics_result.fetchall() if row.sample_song + ] + + # 4. combined_sample_song 생성 + if sample_songs: + combined_sample_song = "\n\n".join( + [f"[샘플 {i + 1}]\n{song}" for i, song in enumerate(sample_songs)] + ) + print(f"{len(sample_songs)}개의 샘플 가사 조회 완료") + else: + print("샘플 가사가 비어있습니다") + else: + print("song_sample 테이블에 데이터가 없습니다") + + # 5. 프롬프트에 샘플 가사 추가 + if combined_sample_song: + updated_prompt += f""" + + 다음은 참고해야 하는 샘플 가사 정보입니다. + + 샘플 가사를 참고하여 작곡을 해주세요. + + {combined_sample_song} + """ + print("샘플 가사 정보가 프롬프트에 추가되었습니다") + else: + print("샘플 가사가 없어 기본 프롬프트만 사용합니다") + + print(f"\n[최종 프롬프트 길이: {len(updated_prompt)} 자]\n") + + # 7. 모델에게 요청 + generated_lyrics = await chatgpt_api.generate(prompt=updated_prompt) + + # 글자 수 계산 + total_chars_with_space = len(generated_lyrics) + total_chars_without_space = len( + generated_lyrics.replace(" ", "") + .replace("\n", "") + .replace("\r", "") + .replace("\t", "") + ) + + # final_lyrics 생성 + final_lyrics = f"""속성 {formatted_attributes} + 전체 글자 수 (공백 포함): {total_chars_with_space}자 + 전체 글자 수 (공백 제외): {total_chars_without_space}자\r\n\r\n{generated_lyrics}""" + + # 8. DB 저장 + insert_query = """ + INSERT INTO song_results_all ( + store_info, store_name, store_category, store_address, store_phone_number, + description, prompt, attr_category, attr_value, + ai, ai_model, genre, + sample_song, result_song, created_at + ) VALUES ( + :store_info, :store_name, :store_category, :store_address, :store_phone_number, + :description, :prompt, :attr_category, :attr_value, + :ai, :ai_model, :genre, + :sample_song, :result_song, NOW() + ); + """ + print("\n[insert_params 선택된 속성 확인]") + print(f"Categories: {selected_categories}") + print(f"Values: {selected_values}") + print() + + # attr_category, attr_value + insert_params = { + "store_info": store_info.store_info or "", + "store_name": store_info.store_name, + "store_category": store_info.store_category or "", + "store_address": store_info.store_address or "", + "store_phone_number": store_info.store_phone_number or "", + "description": store_info.store_info or "", + "prompt": prompt.id, + # 랜덤 선택된 category와 value 사용 + "attr_category": ", ".join(selected_categories) + if selected_categories + else "", + "attr_value": ", ".join(selected_values) if selected_values else "", + "ai": "ChatGPT", + "ai_model": "gpt-5-mini", + "genre": "후크송", + "sample_song": combined_sample_song or "없음", + "result_song": final_lyrics, + } + + await conn.execute(text(insert_query), insert_params) + await conn.commit() + + print("결과 저장 완료") + + print("\n전체 결과 조회 중...") + + # 9. 생성 결과 가져오기 (created_at 역순) + select_query = """ + SELECT * FROM song_results_all + ORDER BY created_at DESC; + """ + + all_results = await conn.execute(text(select_query)) + + results_list = [ + { + "id": row.id, + "store_info": row.store_info, + "store_name": row.store_name, + "store_category": row.store_category, + "store_address": row.store_address, + "store_phone_number": row.store_phone_number, + "description": row.description, + "prompt": row.prompt, + "attr_category": row.attr_category, + "attr_value": row.attr_value, + "ai": row.ai, + "ai_model": row.ai_model, + "genre": row.genre, + "sample_song": row.sample_song, + "result_song": row.result_song, + "created_at": row.created_at.isoformat() if row.created_at else None, + } + for row in all_results.fetchall() + ] + + print(f"전체 {len(results_list)}개의 결과 조회 완료\n") + + return results_list + + except HTTPException: + raise + except SQLAlchemyError as e: + print(f"Database Error: {e}") + import traceback + + traceback.print_exc() + raise HTTPException( + status_code=status.HTTP_503_SERVICE_UNAVAILABLE, + detail="데이터베이스 연결에 문제가 발생했습니다.", + ) + except Exception as e: + print(f"Unexpected Error: {e}") + import traceback + + traceback.print_exc() + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="서비스 처리 중 오류가 발생했습니다.", + ) diff --git a/app/video/worker/video_task.py b/app/video/worker/video_task.py index b85cde8..cca4b17 100644 --- a/app/video/worker/video_task.py +++ b/app/video/worker/video_task.py @@ -1,242 +1,333 @@ -""" -Video Background Tasks - -영상 생성 관련 백그라운드 태스크를 정의합니다. -""" - -from pathlib import Path - -import aiofiles -import httpx -from sqlalchemy import select - -from app.database.session import BackgroundSessionLocal -from app.video.models import Video -from app.utils.upload_blob_as_request import AzureBlobUploader - - -async def download_and_upload_video_to_blob( - task_id: str, - video_url: str, - store_name: str, -) -> None: - """백그라운드에서 영상을 다운로드하고 Azure Blob Storage에 업로드한 뒤 Video 테이블을 업데이트합니다. - - Args: - task_id: 프로젝트 task_id - video_url: 다운로드할 영상 URL - store_name: 저장할 파일명에 사용할 업체명 - """ - print(f"[download_and_upload_video_to_blob] START - task_id: {task_id}, store_name: {store_name}") - temp_file_path: Path | None = None - - try: - # 파일명에 사용할 수 없는 문자 제거 - safe_store_name = "".join( - c for c in store_name if c.isalnum() or c in (" ", "_", "-") - ).strip() - safe_store_name = safe_store_name or "video" - file_name = f"{safe_store_name}.mp4" - - # 임시 저장 경로 생성 - temp_dir = Path("media") / "temp" / task_id - temp_dir.mkdir(parents=True, exist_ok=True) - temp_file_path = temp_dir / file_name - print(f"[download_and_upload_video_to_blob] Temp directory created - path: {temp_file_path}") - - # 영상 파일 다운로드 - print(f"[download_and_upload_video_to_blob] Downloading video - task_id: {task_id}, url: {video_url}") - async with httpx.AsyncClient() as client: - response = await client.get(video_url, timeout=180.0) - response.raise_for_status() - - async with aiofiles.open(str(temp_file_path), "wb") as f: - await f.write(response.content) - print(f"[download_and_upload_video_to_blob] File downloaded - task_id: {task_id}, path: {temp_file_path}") - - # Azure Blob Storage에 업로드 - uploader = AzureBlobUploader(task_id=task_id) - upload_success = await uploader.upload_video(file_path=str(temp_file_path)) - - if not upload_success: - raise Exception("Azure Blob Storage 업로드 실패") - - # SAS 토큰이 제외된 public_url 사용 - blob_url = uploader.public_url - print(f"[download_and_upload_video_to_blob] Uploaded to Blob - task_id: {task_id}, url: {blob_url}") - - # Video 테이블 업데이트 (새 세션 사용) - async with BackgroundSessionLocal() as session: - # 여러 개 있을 경우 가장 최근 것 선택 - result = await session.execute( - select(Video) - .where(Video.task_id == task_id) - .order_by(Video.created_at.desc()) - .limit(1) - ) - video = result.scalar_one_or_none() - - if video: - video.status = "completed" - video.result_movie_url = blob_url - await session.commit() - print(f"[download_and_upload_video_to_blob] SUCCESS - task_id: {task_id}, status: completed") - else: - print(f"[download_and_upload_video_to_blob] Video NOT FOUND in DB - task_id: {task_id}") - - except Exception as e: - print(f"[download_and_upload_video_to_blob] EXCEPTION - task_id: {task_id}, error: {e}") - # 실패 시 Video 테이블 업데이트 - async with BackgroundSessionLocal() as session: - result = await session.execute( - select(Video) - .where(Video.task_id == task_id) - .order_by(Video.created_at.desc()) - .limit(1) - ) - video = result.scalar_one_or_none() - - if video: - video.status = "failed" - await session.commit() - print(f"[download_and_upload_video_to_blob] FAILED - task_id: {task_id}, status updated to failed") - - finally: - # 임시 파일 삭제 - if temp_file_path and temp_file_path.exists(): - try: - temp_file_path.unlink() - print(f"[download_and_upload_video_to_blob] Temp file deleted - path: {temp_file_path}") - except Exception as e: - print(f"[download_and_upload_video_to_blob] Failed to delete temp file: {e}") - - # 임시 디렉토리 삭제 시도 - temp_dir = Path("media") / "temp" / task_id - if temp_dir.exists(): - try: - temp_dir.rmdir() - except Exception: - pass # 디렉토리가 비어있지 않으면 무시 - - -async def download_and_upload_video_by_creatomate_render_id( - creatomate_render_id: str, - video_url: str, - store_name: str, -) -> None: - """creatomate_render_id로 Video를 조회하여 영상을 다운로드하고 Azure Blob Storage에 업로드한 뒤 Video 테이블을 업데이트합니다. - - Args: - creatomate_render_id: Creatomate API 렌더 ID - video_url: 다운로드할 영상 URL - store_name: 저장할 파일명에 사용할 업체명 - """ - print(f"[download_and_upload_video_by_creatomate_render_id] START - creatomate_render_id: {creatomate_render_id}, store_name: {store_name}") - temp_file_path: Path | None = None - task_id: str | None = None - - try: - # creatomate_render_id로 Video 조회하여 task_id 가져오기 - async with BackgroundSessionLocal() as session: - result = await session.execute( - select(Video) - .where(Video.creatomate_render_id == creatomate_render_id) - .order_by(Video.created_at.desc()) - .limit(1) - ) - video = result.scalar_one_or_none() - - if not video: - print(f"[download_and_upload_video_by_creatomate_render_id] Video NOT FOUND - creatomate_render_id: {creatomate_render_id}") - return - - task_id = video.task_id - print(f"[download_and_upload_video_by_creatomate_render_id] Video found - creatomate_render_id: {creatomate_render_id}, task_id: {task_id}") - - # 파일명에 사용할 수 없는 문자 제거 - safe_store_name = "".join( - c for c in store_name if c.isalnum() or c in (" ", "_", "-") - ).strip() - safe_store_name = safe_store_name or "video" - file_name = f"{safe_store_name}.mp4" - - # 임시 저장 경로 생성 - temp_dir = Path("media") / "temp" / task_id - temp_dir.mkdir(parents=True, exist_ok=True) - temp_file_path = temp_dir / file_name - print(f"[download_and_upload_video_by_creatomate_render_id] Temp directory created - path: {temp_file_path}") - - # 영상 파일 다운로드 - print(f"[download_and_upload_video_by_creatomate_render_id] Downloading video - creatomate_render_id: {creatomate_render_id}, url: {video_url}") - async with httpx.AsyncClient() as client: - response = await client.get(video_url, timeout=180.0) - response.raise_for_status() - - async with aiofiles.open(str(temp_file_path), "wb") as f: - await f.write(response.content) - print(f"[download_and_upload_video_by_creatomate_render_id] File downloaded - creatomate_render_id: {creatomate_render_id}, path: {temp_file_path}") - - # Azure Blob Storage에 업로드 - uploader = AzureBlobUploader(task_id=task_id) - upload_success = await uploader.upload_video(file_path=str(temp_file_path)) - - if not upload_success: - raise Exception("Azure Blob Storage 업로드 실패") - - # SAS 토큰이 제외된 public_url 사용 - blob_url = uploader.public_url - print(f"[download_and_upload_video_by_creatomate_render_id] Uploaded to Blob - creatomate_render_id: {creatomate_render_id}, url: {blob_url}") - - # Video 테이블 업데이트 (새 세션 사용) - async with BackgroundSessionLocal() as session: - result = await session.execute( - select(Video) - .where(Video.creatomate_render_id == creatomate_render_id) - .order_by(Video.created_at.desc()) - .limit(1) - ) - video = result.scalar_one_or_none() - - if video: - video.status = "completed" - video.result_movie_url = blob_url - await session.commit() - print(f"[download_and_upload_video_by_creatomate_render_id] SUCCESS - creatomate_render_id: {creatomate_render_id}, status: completed") - else: - print(f"[download_and_upload_video_by_creatomate_render_id] Video NOT FOUND in DB - creatomate_render_id: {creatomate_render_id}") - - except Exception as e: - print(f"[download_and_upload_video_by_creatomate_render_id] EXCEPTION - creatomate_render_id: {creatomate_render_id}, error: {e}") - # 실패 시 Video 테이블 업데이트 - if task_id: - async with BackgroundSessionLocal() as session: - result = await session.execute( - select(Video) - .where(Video.creatomate_render_id == creatomate_render_id) - .order_by(Video.created_at.desc()) - .limit(1) - ) - video = result.scalar_one_or_none() - - if video: - video.status = "failed" - await session.commit() - print(f"[download_and_upload_video_by_creatomate_render_id] FAILED - creatomate_render_id: {creatomate_render_id}, status updated to failed") - - finally: - # 임시 파일 삭제 - if temp_file_path and temp_file_path.exists(): - try: - temp_file_path.unlink() - print(f"[download_and_upload_video_by_creatomate_render_id] Temp file deleted - path: {temp_file_path}") - except Exception as e: - print(f"[download_and_upload_video_by_creatomate_render_id] Failed to delete temp file: {e}") - - # 임시 디렉토리 삭제 시도 - if task_id: - temp_dir = Path("media") / "temp" / task_id - if temp_dir.exists(): - try: - temp_dir.rmdir() - except Exception: - pass # 디렉토리가 비어있지 않으면 무시 +""" +Video Background Tasks + +영상 생성 관련 백그라운드 태스크를 정의합니다. +""" + +import logging +import traceback +from pathlib import Path + +import aiofiles +import httpx +from sqlalchemy import select +from sqlalchemy.exc import SQLAlchemyError + +from app.database.session import BackgroundSessionLocal +from app.video.models import Video +from app.utils.upload_blob_as_request import AzureBlobUploader + +# 로거 설정 +logger = logging.getLogger(__name__) + +# HTTP 요청 설정 +REQUEST_TIMEOUT = 300.0 # 초 (영상은 용량이 크므로 5분) + + +async def _update_video_status( + task_id: str, + status: str, + video_url: str | None = None, + creatomate_render_id: str | None = None, +) -> bool: + """Video 테이블의 상태를 업데이트합니다. + + Args: + task_id: 프로젝트 task_id + status: 변경할 상태 ("processing", "completed", "failed") + video_url: 영상 URL + creatomate_render_id: Creatomate render ID (선택) + + Returns: + bool: 업데이트 성공 여부 + """ + try: + async with BackgroundSessionLocal() as session: + if creatomate_render_id: + query_result = await session.execute( + select(Video) + .where(Video.creatomate_render_id == creatomate_render_id) + .order_by(Video.created_at.desc()) + .limit(1) + ) + else: + query_result = await session.execute( + select(Video) + .where(Video.task_id == task_id) + .order_by(Video.created_at.desc()) + .limit(1) + ) + + video = query_result.scalar_one_or_none() + + if video: + video.status = status + if video_url is not None: + video.result_movie_url = video_url + await session.commit() + logger.info(f"[Video] Status updated - task_id: {task_id}, status: {status}") + print(f"[Video] Status updated - task_id: {task_id}, status: {status}") + return True + else: + logger.warning(f"[Video] NOT FOUND in DB - task_id: {task_id}") + print(f"[Video] NOT FOUND in DB - task_id: {task_id}") + return False + + except SQLAlchemyError as e: + logger.error(f"[Video] DB Error while updating status - task_id: {task_id}, error: {e}") + print(f"[Video] DB Error while updating status - task_id: {task_id}, error: {e}") + return False + except Exception as e: + logger.error(f"[Video] Unexpected error while updating status - task_id: {task_id}, error: {e}") + print(f"[Video] Unexpected error while updating status - task_id: {task_id}, error: {e}") + return False + + +async def _download_video(url: str, task_id: str) -> bytes: + """URL에서 영상을 다운로드합니다. + + Args: + url: 다운로드할 URL + task_id: 로그용 task_id + + Returns: + bytes: 다운로드한 파일 내용 + + Raises: + httpx.HTTPError: 다운로드 실패 시 + """ + logger.info(f"[VideoDownload] Downloading - task_id: {task_id}") + print(f"[VideoDownload] Downloading - task_id: {task_id}") + + async with httpx.AsyncClient() as client: + response = await client.get(url, timeout=REQUEST_TIMEOUT) + response.raise_for_status() + + logger.info(f"[VideoDownload] SUCCESS - task_id: {task_id}, size: {len(response.content)} bytes") + print(f"[VideoDownload] SUCCESS - task_id: {task_id}, size: {len(response.content)} bytes") + return response.content + + +async def download_and_upload_video_to_blob( + task_id: str, + video_url: str, + store_name: str, +) -> None: + """백그라운드에서 영상을 다운로드하고 Azure Blob Storage에 업로드한 뒤 Video 테이블을 업데이트합니다. + + Args: + task_id: 프로젝트 task_id + video_url: 다운로드할 영상 URL + store_name: 저장할 파일명에 사용할 업체명 + """ + logger.info(f"[download_and_upload_video_to_blob] START - task_id: {task_id}, store_name: {store_name}") + print(f"[download_and_upload_video_to_blob] START - task_id: {task_id}, store_name: {store_name}") + temp_file_path: Path | None = None + + try: + # 파일명에 사용할 수 없는 문자 제거 + safe_store_name = "".join( + c for c in store_name if c.isalnum() or c in (" ", "_", "-") + ).strip() + safe_store_name = safe_store_name or "video" + file_name = f"{safe_store_name}.mp4" + + # 임시 저장 경로 생성 + temp_dir = Path("media") / "temp" / task_id + temp_dir.mkdir(parents=True, exist_ok=True) + temp_file_path = temp_dir / file_name + logger.info(f"[download_and_upload_video_to_blob] Temp directory created - path: {temp_file_path}") + print(f"[download_and_upload_video_to_blob] Temp directory created - path: {temp_file_path}") + + # 영상 파일 다운로드 + logger.info(f"[download_and_upload_video_to_blob] Downloading video - task_id: {task_id}, url: {video_url}") + print(f"[download_and_upload_video_to_blob] Downloading video - task_id: {task_id}, url: {video_url}") + + content = await _download_video(video_url, task_id) + + async with aiofiles.open(str(temp_file_path), "wb") as f: + await f.write(content) + + logger.info(f"[download_and_upload_video_to_blob] File downloaded - task_id: {task_id}, path: {temp_file_path}") + print(f"[download_and_upload_video_to_blob] File downloaded - task_id: {task_id}, path: {temp_file_path}") + + # Azure Blob Storage에 업로드 + uploader = AzureBlobUploader(task_id=task_id) + upload_success = await uploader.upload_video(file_path=str(temp_file_path)) + + if not upload_success: + raise Exception("Azure Blob Storage 업로드 실패") + + # SAS 토큰이 제외된 public_url 사용 + blob_url = uploader.public_url + logger.info(f"[download_and_upload_video_to_blob] Uploaded to Blob - task_id: {task_id}, url: {blob_url}") + print(f"[download_and_upload_video_to_blob] Uploaded to Blob - task_id: {task_id}, url: {blob_url}") + + # Video 테이블 업데이트 + await _update_video_status(task_id, "completed", blob_url) + logger.info(f"[download_and_upload_video_to_blob] SUCCESS - task_id: {task_id}") + print(f"[download_and_upload_video_to_blob] SUCCESS - task_id: {task_id}") + + except httpx.HTTPError as e: + logger.error(f"[download_and_upload_video_to_blob] DOWNLOAD ERROR - task_id: {task_id}, error: {e}") + print(f"[download_and_upload_video_to_blob] DOWNLOAD ERROR - task_id: {task_id}, error: {e}") + traceback.print_exc() + await _update_video_status(task_id, "failed") + + except SQLAlchemyError as e: + logger.error(f"[download_and_upload_video_to_blob] DB ERROR - task_id: {task_id}, error: {e}") + print(f"[download_and_upload_video_to_blob] DB ERROR - task_id: {task_id}, error: {e}") + traceback.print_exc() + await _update_video_status(task_id, "failed") + + except Exception as e: + logger.error(f"[download_and_upload_video_to_blob] EXCEPTION - task_id: {task_id}, error: {e}") + print(f"[download_and_upload_video_to_blob] EXCEPTION - task_id: {task_id}, error: {e}") + traceback.print_exc() + await _update_video_status(task_id, "failed") + + finally: + # 임시 파일 삭제 + if temp_file_path and temp_file_path.exists(): + try: + temp_file_path.unlink() + logger.info(f"[download_and_upload_video_to_blob] Temp file deleted - path: {temp_file_path}") + print(f"[download_and_upload_video_to_blob] Temp file deleted - path: {temp_file_path}") + except Exception as e: + logger.warning(f"[download_and_upload_video_to_blob] Failed to delete temp file: {e}") + print(f"[download_and_upload_video_to_blob] Failed to delete temp file: {e}") + + # 임시 디렉토리 삭제 시도 + temp_dir = Path("media") / "temp" / task_id + if temp_dir.exists(): + try: + temp_dir.rmdir() + except Exception: + pass # 디렉토리가 비어있지 않으면 무시 + + +async def download_and_upload_video_by_creatomate_render_id( + creatomate_render_id: str, + video_url: str, + store_name: str, +) -> None: + """creatomate_render_id로 Video를 조회하여 영상을 다운로드하고 Azure Blob Storage에 업로드한 뒤 Video 테이블을 업데이트합니다. + + Args: + creatomate_render_id: Creatomate API 렌더 ID + video_url: 다운로드할 영상 URL + store_name: 저장할 파일명에 사용할 업체명 + """ + logger.info(f"[download_and_upload_video_by_creatomate_render_id] START - creatomate_render_id: {creatomate_render_id}, store_name: {store_name}") + print(f"[download_and_upload_video_by_creatomate_render_id] START - creatomate_render_id: {creatomate_render_id}, store_name: {store_name}") + temp_file_path: Path | None = None + task_id: str | None = None + + try: + # creatomate_render_id로 Video 조회하여 task_id 가져오기 + async with BackgroundSessionLocal() as session: + result = await session.execute( + select(Video) + .where(Video.creatomate_render_id == creatomate_render_id) + .order_by(Video.created_at.desc()) + .limit(1) + ) + video = result.scalar_one_or_none() + + if not video: + logger.warning(f"[download_and_upload_video_by_creatomate_render_id] Video NOT FOUND - creatomate_render_id: {creatomate_render_id}") + print(f"[download_and_upload_video_by_creatomate_render_id] Video NOT FOUND - creatomate_render_id: {creatomate_render_id}") + return + + task_id = video.task_id + logger.info(f"[download_and_upload_video_by_creatomate_render_id] Video found - creatomate_render_id: {creatomate_render_id}, task_id: {task_id}") + print(f"[download_and_upload_video_by_creatomate_render_id] Video found - creatomate_render_id: {creatomate_render_id}, task_id: {task_id}") + + # 파일명에 사용할 수 없는 문자 제거 + safe_store_name = "".join( + c for c in store_name if c.isalnum() or c in (" ", "_", "-") + ).strip() + safe_store_name = safe_store_name or "video" + file_name = f"{safe_store_name}.mp4" + + # 임시 저장 경로 생성 + temp_dir = Path("media") / "temp" / task_id + temp_dir.mkdir(parents=True, exist_ok=True) + temp_file_path = temp_dir / file_name + logger.info(f"[download_and_upload_video_by_creatomate_render_id] Temp directory created - path: {temp_file_path}") + print(f"[download_and_upload_video_by_creatomate_render_id] Temp directory created - path: {temp_file_path}") + + # 영상 파일 다운로드 + logger.info(f"[download_and_upload_video_by_creatomate_render_id] Downloading video - creatomate_render_id: {creatomate_render_id}, url: {video_url}") + print(f"[download_and_upload_video_by_creatomate_render_id] Downloading video - creatomate_render_id: {creatomate_render_id}, url: {video_url}") + + content = await _download_video(video_url, task_id) + + async with aiofiles.open(str(temp_file_path), "wb") as f: + await f.write(content) + + logger.info(f"[download_and_upload_video_by_creatomate_render_id] File downloaded - creatomate_render_id: {creatomate_render_id}, path: {temp_file_path}") + print(f"[download_and_upload_video_by_creatomate_render_id] File downloaded - creatomate_render_id: {creatomate_render_id}, path: {temp_file_path}") + + # Azure Blob Storage에 업로드 + uploader = AzureBlobUploader(task_id=task_id) + upload_success = await uploader.upload_video(file_path=str(temp_file_path)) + + if not upload_success: + raise Exception("Azure Blob Storage 업로드 실패") + + # SAS 토큰이 제외된 public_url 사용 + blob_url = uploader.public_url + logger.info(f"[download_and_upload_video_by_creatomate_render_id] Uploaded to Blob - creatomate_render_id: {creatomate_render_id}, url: {blob_url}") + print(f"[download_and_upload_video_by_creatomate_render_id] Uploaded to Blob - creatomate_render_id: {creatomate_render_id}, url: {blob_url}") + + # Video 테이블 업데이트 + await _update_video_status( + task_id=task_id, + status="completed", + video_url=blob_url, + creatomate_render_id=creatomate_render_id, + ) + logger.info(f"[download_and_upload_video_by_creatomate_render_id] SUCCESS - creatomate_render_id: {creatomate_render_id}") + print(f"[download_and_upload_video_by_creatomate_render_id] SUCCESS - creatomate_render_id: {creatomate_render_id}") + + except httpx.HTTPError as e: + logger.error(f"[download_and_upload_video_by_creatomate_render_id] DOWNLOAD ERROR - creatomate_render_id: {creatomate_render_id}, error: {e}") + print(f"[download_and_upload_video_by_creatomate_render_id] DOWNLOAD ERROR - creatomate_render_id: {creatomate_render_id}, error: {e}") + traceback.print_exc() + if task_id: + await _update_video_status(task_id, "failed", creatomate_render_id=creatomate_render_id) + + except SQLAlchemyError as e: + logger.error(f"[download_and_upload_video_by_creatomate_render_id] DB ERROR - creatomate_render_id: {creatomate_render_id}, error: {e}") + print(f"[download_and_upload_video_by_creatomate_render_id] DB ERROR - creatomate_render_id: {creatomate_render_id}, error: {e}") + traceback.print_exc() + if task_id: + await _update_video_status(task_id, "failed", creatomate_render_id=creatomate_render_id) + + except Exception as e: + logger.error(f"[download_and_upload_video_by_creatomate_render_id] EXCEPTION - creatomate_render_id: {creatomate_render_id}, error: {e}") + print(f"[download_and_upload_video_by_creatomate_render_id] EXCEPTION - creatomate_render_id: {creatomate_render_id}, error: {e}") + traceback.print_exc() + if task_id: + await _update_video_status(task_id, "failed", creatomate_render_id=creatomate_render_id) + + finally: + # 임시 파일 삭제 + if temp_file_path and temp_file_path.exists(): + try: + temp_file_path.unlink() + logger.info(f"[download_and_upload_video_by_creatomate_render_id] Temp file deleted - path: {temp_file_path}") + print(f"[download_and_upload_video_by_creatomate_render_id] Temp file deleted - path: {temp_file_path}") + except Exception as e: + logger.warning(f"[download_and_upload_video_by_creatomate_render_id] Failed to delete temp file: {e}") + print(f"[download_and_upload_video_by_creatomate_render_id] Failed to delete temp file: {e}") + + # 임시 디렉토리 삭제 시도 + if task_id: + temp_dir = Path("media") / "temp" / task_id + if temp_dir.exists(): + try: + temp_dir.rmdir() + except Exception: + pass # 디렉토리가 비어있지 않으면 무시 diff --git a/config.py b/config.py index 69c200f..9ba8503 100644 --- a/config.py +++ b/config.py @@ -1,179 +1,179 @@ -from pathlib import Path - -from pydantic import Field -from pydantic_settings import BaseSettings, SettingsConfigDict - -PROJECT_DIR = Path(__file__).resolve().parent - -_base_config = SettingsConfigDict( - env_file=PROJECT_DIR / ".env", - env_ignore_empty=True, - extra="ignore", -) - - -class ProjectSettings(BaseSettings): - PROJECT_NAME: str = Field(default="CastAD") - PROJECT_DOMAIN: str = Field(default="localhost:8000") - VERSION: str = Field(default="0.1.0") - DESCRIPTION: str = Field(default="FastAPI 기반 CastAD 프로젝트") - ADMIN_BASE_URL: str = Field(default="/admin") - DEBUG: bool = Field(default=True) - - model_config = _base_config - - -class APIKeySettings(BaseSettings): - CHATGPT_API_KEY: str = Field(default="your-chatgpt-api-key") # 기본값 추가 - SUNO_API_KEY: str = Field(default="your-suno-api-key") # Suno API 키 - SUNO_CALLBACK_URL: str = Field( - default="https://example.com/api/suno/callback" - ) # Suno 콜백 URL (필수) - CREATOMATE_API_KEY: str = Field(default="your-creatomate-api-key") # Creatomate API 키 - - model_config = _base_config - - -class CORSSettings(BaseSettings): - # CORS (Cross-Origin Resource Sharing) 설정 - - # 요청을 허용할 출처(Origin) 목록 - # ["*"]: 모든 출처 허용 (개발 환경용, 프로덕션에서는 구체적인 도메인 지정 권장) - # 예: ["https://example.com", "https://app.example.com"] - CORS_ALLOW_ORIGINS: list[str] = ["*"] - - # 자격 증명(쿠키, Authorization 헤더 등) 포함 요청 허용 여부 - # True: 클라이언트가 credentials: 'include'로 요청 시 쿠키/인증 정보 전송 가능 - # 주의: CORS_ALLOW_ORIGINS가 ["*"]일 때는 보안상 False 권장 - CORS_ALLOW_CREDENTIALS: bool = True - - # 허용할 HTTP 메서드 목록 - # ["*"]: 모든 메서드 허용 (GET, POST, PUT, DELETE, PATCH, OPTIONS 등) - # 구체적 지정 예: ["GET", "POST", "PUT", "DELETE"] - CORS_ALLOW_METHODS: list[str] = ["*"] - - # 클라이언트가 요청 시 사용할 수 있는 HTTP 헤더 목록 - # ["*"]: 모든 헤더 허용 - # 구체적 지정 예: ["Content-Type", "Authorization", "X-Custom-Header"] - CORS_ALLOW_HEADERS: list[str] = ["*"] - - # 브라우저의 JavaScript에서 접근 가능한 응답 헤더 목록 - # []: 기본 안전 헤더(Cache-Control, Content-Language, Content-Type, - # Expires, Last-Modified, Pragma)만 접근 가능 - # 추가 노출 필요 시: ["X-Total-Count", "X-Request-Id", "X-Custom-Header"] - CORS_EXPOSE_HEADERS: list[str] = [] - - # Preflight 요청(OPTIONS) 결과를 캐시하는 시간(초) - # 600: 10분간 캐시 (이 시간 동안 동일 요청에 대해 preflight 생략) - # 0으로 설정 시 매번 preflight 요청 발생 - CORS_MAX_AGE: int = 600 - - model_config = _base_config - - -class DatabaseSettings(BaseSettings): - # MySQL 연결 설정 (기본값: 테스트 계정 및 poc DB) - MYSQL_HOST: str = Field(default="localhost") - MYSQL_PORT: int = Field(default=3306) - MYSQL_USER: str = Field(default="test") - MYSQL_PASSWORD: str = Field(default="") # 환경변수에서 로드 - MYSQL_DB: str = Field(default="poc") - - # Redis 설정 - REDIS_HOST: str = "localhost" - REDIS_PORT: int = 6379 - - model_config = _base_config - - @property - def MYSQL_URL(self) -> str: - """비동기 MySQL URL 생성 (asyncmy 드라이버 사용, SQLAlchemy 통합 최적화)""" - return f"mysql+asyncmy://{self.MYSQL_USER}:{self.MYSQL_PASSWORD}@{self.MYSQL_HOST}:{self.MYSQL_PORT}/{self.MYSQL_DB}" - - def REDIS_URL(self, db: int = 0) -> str: - """Redis URL 생성 (db 인수로 기본값 지원)""" - return f"redis://{self.REDIS_HOST}:{self.REDIS_PORT}/{db}" - - -class SecuritySettings(BaseSettings): - JWT_SECRET: str = "your-jwt-secret-key" # 기본값 추가 (필수 필드 안전) - JWT_ALGORITHM: str = "HS256" # 기본값 추가 (필수 필드 안전) - - model_config = _base_config - - -class NotificationSettings(BaseSettings): - MAIL_USERNAME: str = "your-email@example.com" # 기본값 추가 - MAIL_PASSWORD: str = "your-email-password" # 기본값 추가 - MAIL_FROM: str = "your-email@example.com" # 기본값 추가 - MAIL_PORT: int = 587 # 기본값 추가 - MAIL_SERVER: str = "smtp.gmail.com" # 기본값 추가 - MAIL_FROM_NAME: str = "FastPOC App" # 기본값 추가 - MAIL_STARTTLS: bool = True - MAIL_SSL_TLS: bool = False - USE_CREDENTIALS: bool = True - VALIDATE_CERTS: bool = True - - TWILIO_SID: str = "your-twilio-sid" # 기본값 추가 - TWILIO_AUTH_TOKEN: str = "your-twilio-token" # 기본값 추가 - TWILIO_NUMBER: str = "+1234567890" # 기본값 추가 - - model_config = _base_config - - -class CrawlerSettings(BaseSettings): - NAVER_COOKIES: str = Field(default="") - - model_config = _base_config - - -class AzureBlobSettings(BaseSettings): - """Azure Blob Storage 설정""" - - AZURE_BLOB_SAS_TOKEN: str = Field( - default="", - description="Azure Blob Storage SAS 토큰", - ) - AZURE_BLOB_BASE_URL: str = Field( - default="https://ado2mediastoragepublic.blob.core.windows.net/ado2-media-public-access/ado2-media-original", - description="Azure Blob Storage 기본 URL", - ) - - model_config = _base_config - - -class CreatomateSettings(BaseSettings): - """Creatomate 템플릿 설정""" - - # 세로형 템플릿 (기본값) - TEMPLATE_ID_VERTICAL: str = Field( - default="e8c7b43f-de4b-4ba3-b8eb-5df688569193", - description="Creatomate 세로형 템플릿 ID", - ) - TEMPLATE_DURATION_VERTICAL: float = Field( - default=90.0, - description="세로형 템플릿 기본 duration (초)", - ) - - # 가로형 템플릿 - TEMPLATE_ID_HORIZONTAL: str = Field( - default="0f092a6a-f526-4ef0-9181-d4ad4426b9e7", - description="Creatomate 가로형 템플릿 ID", - ) - TEMPLATE_DURATION_HORIZONTAL: float = Field( - default=30.0, - description="가로형 템플릿 기본 duration (초)", - ) - - model_config = _base_config - - -prj_settings = ProjectSettings() -apikey_settings = APIKeySettings() -db_settings = DatabaseSettings() -security_settings = SecuritySettings() -notification_settings = NotificationSettings() -cors_settings = CORSSettings() -crawler_settings = CrawlerSettings() -azure_blob_settings = AzureBlobSettings() -creatomate_settings = CreatomateSettings() +from pathlib import Path + +from pydantic import Field +from pydantic_settings import BaseSettings, SettingsConfigDict + +PROJECT_DIR = Path(__file__).resolve().parent + +_base_config = SettingsConfigDict( + env_file=PROJECT_DIR / ".env", + env_ignore_empty=True, + extra="ignore", +) + + +class ProjectSettings(BaseSettings): + PROJECT_NAME: str = Field(default="CastAD") + PROJECT_DOMAIN: str = Field(default="localhost:8000") + VERSION: str = Field(default="0.1.0") + DESCRIPTION: str = Field(default="FastAPI 기반 CastAD 프로젝트") + ADMIN_BASE_URL: str = Field(default="/admin") + DEBUG: bool = Field(default=True) + + model_config = _base_config + + +class APIKeySettings(BaseSettings): + CHATGPT_API_KEY: str = Field(default="your-chatgpt-api-key") # 기본값 추가 + SUNO_API_KEY: str = Field(default="your-suno-api-key") # Suno API 키 + SUNO_CALLBACK_URL: str = Field( + default="https://example.com/api/suno/callback" + ) # Suno 콜백 URL (필수) + CREATOMATE_API_KEY: str = Field(default="your-creatomate-api-key") # Creatomate API 키 + + model_config = _base_config + + +class CORSSettings(BaseSettings): + # CORS (Cross-Origin Resource Sharing) 설정 + + # 요청을 허용할 출처(Origin) 목록 + # ["*"]: 모든 출처 허용 (개발 환경용, 프로덕션에서는 구체적인 도메인 지정 권장) + # 예: ["https://example.com", "https://app.example.com"] + CORS_ALLOW_ORIGINS: list[str] = ["*"] + + # 자격 증명(쿠키, Authorization 헤더 등) 포함 요청 허용 여부 + # True: 클라이언트가 credentials: 'include'로 요청 시 쿠키/인증 정보 전송 가능 + # 주의: CORS_ALLOW_ORIGINS가 ["*"]일 때는 보안상 False 권장 + CORS_ALLOW_CREDENTIALS: bool = True + + # 허용할 HTTP 메서드 목록 + # ["*"]: 모든 메서드 허용 (GET, POST, PUT, DELETE, PATCH, OPTIONS 등) + # 구체적 지정 예: ["GET", "POST", "PUT", "DELETE"] + CORS_ALLOW_METHODS: list[str] = ["*"] + + # 클라이언트가 요청 시 사용할 수 있는 HTTP 헤더 목록 + # ["*"]: 모든 헤더 허용 + # 구체적 지정 예: ["Content-Type", "Authorization", "X-Custom-Header"] + CORS_ALLOW_HEADERS: list[str] = ["*"] + + # 브라우저의 JavaScript에서 접근 가능한 응답 헤더 목록 + # []: 기본 안전 헤더(Cache-Control, Content-Language, Content-Type, + # Expires, Last-Modified, Pragma)만 접근 가능 + # 추가 노출 필요 시: ["X-Total-Count", "X-Request-Id", "X-Custom-Header"] + CORS_EXPOSE_HEADERS: list[str] = [] + + # Preflight 요청(OPTIONS) 결과를 캐시하는 시간(초) + # 600: 10분간 캐시 (이 시간 동안 동일 요청에 대해 preflight 생략) + # 0으로 설정 시 매번 preflight 요청 발생 + CORS_MAX_AGE: int = 600 + + model_config = _base_config + + +class DatabaseSettings(BaseSettings): + # MySQL 연결 설정 (기본값: 테스트 계정 및 poc DB) + MYSQL_HOST: str = Field(default="localhost") + MYSQL_PORT: int = Field(default=3306) + MYSQL_USER: str = Field(default="test") + MYSQL_PASSWORD: str = Field(default="") # 환경변수에서 로드 + MYSQL_DB: str = Field(default="poc") + + # Redis 설정 + REDIS_HOST: str = "localhost" + REDIS_PORT: int = 6379 + + model_config = _base_config + + @property + def MYSQL_URL(self) -> str: + """비동기 MySQL URL 생성 (asyncmy 드라이버 사용, SQLAlchemy 통합 최적화)""" + return f"mysql+asyncmy://{self.MYSQL_USER}:{self.MYSQL_PASSWORD}@{self.MYSQL_HOST}:{self.MYSQL_PORT}/{self.MYSQL_DB}" + + def REDIS_URL(self, db: int = 0) -> str: + """Redis URL 생성 (db 인수로 기본값 지원)""" + return f"redis://{self.REDIS_HOST}:{self.REDIS_PORT}/{db}" + + +class SecuritySettings(BaseSettings): + JWT_SECRET: str = "your-jwt-secret-key" # 기본값 추가 (필수 필드 안전) + JWT_ALGORITHM: str = "HS256" # 기본값 추가 (필수 필드 안전) + + model_config = _base_config + + +class NotificationSettings(BaseSettings): + MAIL_USERNAME: str = "your-email@example.com" # 기본값 추가 + MAIL_PASSWORD: str = "your-email-password" # 기본값 추가 + MAIL_FROM: str = "your-email@example.com" # 기본값 추가 + MAIL_PORT: int = 587 # 기본값 추가 + MAIL_SERVER: str = "smtp.gmail.com" # 기본값 추가 + MAIL_FROM_NAME: str = "FastPOC App" # 기본값 추가 + MAIL_STARTTLS: bool = True + MAIL_SSL_TLS: bool = False + USE_CREDENTIALS: bool = True + VALIDATE_CERTS: bool = True + + TWILIO_SID: str = "your-twilio-sid" # 기본값 추가 + TWILIO_AUTH_TOKEN: str = "your-twilio-token" # 기본값 추가 + TWILIO_NUMBER: str = "+1234567890" # 기본값 추가 + + model_config = _base_config + + +class CrawlerSettings(BaseSettings): + NAVER_COOKIES: str = Field(default="") + + model_config = _base_config + + +class AzureBlobSettings(BaseSettings): + """Azure Blob Storage 설정""" + + AZURE_BLOB_SAS_TOKEN: str = Field( + default="", + description="Azure Blob Storage SAS 토큰", + ) + AZURE_BLOB_BASE_URL: str = Field( + default="https://ado2mediastoragepublic.blob.core.windows.net/ado2-media-public-access/ado2-media-original", + description="Azure Blob Storage 기본 URL", + ) + + model_config = _base_config + + +class CreatomateSettings(BaseSettings): + """Creatomate 템플릿 설정""" + + # 세로형 템플릿 (기본값) + TEMPLATE_ID_VERTICAL: str = Field( + default="e8c7b43f-de4b-4ba3-b8eb-5df688569193", + description="Creatomate 세로형 템플릿 ID", + ) + TEMPLATE_DURATION_VERTICAL: float = Field( + default=90.0, + description="세로형 템플릿 기본 duration (초)", + ) + + # 가로형 템플릿 + TEMPLATE_ID_HORIZONTAL: str = Field( + default="0f092a6a-f526-4ef0-9181-d4ad4426b9e7", + description="Creatomate 가로형 템플릿 ID", + ) + TEMPLATE_DURATION_HORIZONTAL: float = Field( + default=30.0, + description="가로형 템플릿 기본 duration (초)", + ) + + model_config = _base_config + + +prj_settings = ProjectSettings() +apikey_settings = APIKeySettings() +db_settings = DatabaseSettings() +security_settings = SecuritySettings() +notification_settings = NotificationSettings() +cors_settings = CORSSettings() +crawler_settings = CrawlerSettings() +azure_blob_settings = AzureBlobSettings() +creatomate_settings = CreatomateSettings() diff --git a/docs/analysis/async_architecture_design_report.md b/docs/analysis/async_architecture_design_report.md index 3a7700d..81ca07d 100644 --- a/docs/analysis/async_architecture_design_report.md +++ b/docs/analysis/async_architecture_design_report.md @@ -1,783 +1,792 @@ -# O2O-CASTAD Backend 비동기 아키텍처 및 설계 분석 보고서 - -> **문서 버전**: 1.0 -> **작성일**: 2025-12-29 -> **대상**: 개발자, 아키텍트, 코드 리뷰어 - ---- - -## 목차 - -1. [Executive Summary](#1-executive-summary) -2. [데이터베이스 세션 관리 아키텍처](#2-데이터베이스-세션-관리-아키텍처) -3. [비동기 처리 패턴](#3-비동기-처리-패턴) -4. [외부 API 통합 설계](#4-외부-api-통합-설계) -5. [백그라운드 태스크 워크플로우](#5-백그라운드-태스크-워크플로우) -6. [쿼리 최적화 전략](#6-쿼리-최적화-전략) -7. [설계 강점 분석](#7-설계-강점-분석) -8. [개선 권장 사항](#8-개선-권장-사항) -9. [아키텍처 다이어그램](#9-아키텍처-다이어그램) -10. [결론](#10-결론) - ---- - -## 1. Executive Summary - -### 1.1 프로젝트 개요 - -O2O-CASTAD Backend는 FastAPI 기반의 비동기 백엔드 서비스로, AI 기반 광고 영상 자동 생성 파이프라인을 제공합니다. 주요 외부 서비스(Creatomate, Suno, ChatGPT, Azure Blob Storage)와의 통합을 통해 가사 생성 → 노래 생성 → 영상 생성의 파이프라인을 구현합니다. - -### 1.2 주요 성과 - -| 영역 | 개선 전 | 개선 후 | 개선율 | -|------|---------|---------|--------| -| DB 쿼리 실행 | 순차 (200ms) | 병렬 (55ms) | **72% 감소** | -| 템플릿 API 호출 | 매번 호출 (1-2s) | 캐시 HIT (0ms) | **100% 감소** | -| HTTP 클라이언트 | 매번 생성 (50ms) | 풀 재사용 (0ms) | **100% 감소** | -| 세션 타임아웃 에러 | 빈번 | 해결 | **안정성 확보** | - -### 1.3 핵심 아키텍처 결정 - -1. **이중 커넥션 풀 아키텍처**: 요청/백그라운드 분리 -2. **명시적 세션 라이프사이클**: 외부 API 호출 전 세션 해제 -3. **모듈 레벨 싱글톤**: HTTP 클라이언트 및 템플릿 캐시 -4. **asyncio.gather() 기반 병렬 쿼리**: 다중 테이블 동시 조회 - ---- - -## 2. 데이터베이스 세션 관리 아키텍처 - -### 2.1 이중 엔진 구조 - -``` -┌─────────────────────────────────────────────────────────────┐ -│ DATABASE LAYER │ -├─────────────────────────────┬───────────────────────────────┤ -│ MAIN ENGINE │ BACKGROUND ENGINE │ -│ (FastAPI Requests) │ (Worker Tasks) │ -├─────────────────────────────┼───────────────────────────────┤ -│ pool_size: 20 │ pool_size: 10 │ -│ max_overflow: 20 │ max_overflow: 10 │ -│ pool_timeout: 30s │ pool_timeout: 60s │ -│ Total: 최대 40 연결 │ Total: 최대 20 연결 │ -├─────────────────────────────┼───────────────────────────────┤ -│ AsyncSessionLocal │ BackgroundSessionLocal │ -│ → Router endpoints │ → download_and_upload_* │ -│ → Direct API calls │ → generate_lyric_background │ -└─────────────────────────────┴───────────────────────────────┘ -``` - -**위치**: `app/database/session.py` - -### 2.2 엔진 설정 상세 - -```python -# 메인 엔진 (FastAPI 요청용) -engine = create_async_engine( - url=db_settings.MYSQL_URL, - pool_size=20, # 기본 풀 크기 - max_overflow=20, # 추가 연결 허용 - pool_timeout=30, # 연결 대기 최대 시간 - pool_recycle=3600, # 1시간마다 연결 재생성 - pool_pre_ping=True, # 연결 유효성 검사 (핵심!) - pool_reset_on_return="rollback", # 반환 시 롤백 -) - -# 백그라운드 엔진 (워커 태스크용) -background_engine = create_async_engine( - url=db_settings.MYSQL_URL, - pool_size=10, # 더 작은 풀 - max_overflow=10, - pool_timeout=60, # 백그라운드는 대기 여유 - pool_recycle=3600, - pool_pre_ping=True, -) -``` - -### 2.3 세션 관리 패턴 - -#### 패턴 1: FastAPI 의존성 주입 (단순 CRUD) - -```python -@router.get("/items/{id}") -async def get_item( - id: int, - session: AsyncSession = Depends(get_session), -): - result = await session.execute(select(Item).where(Item.id == id)) - return result.scalar_one_or_none() -``` - -**적용 엔드포인트:** -- `GET /videos/` - 목록 조회 -- `GET /video/download/{task_id}` - 상태 조회 -- `GET /songs/` - 목록 조회 - -#### 패턴 2: 명시적 세션 관리 (외부 API 호출 포함) - -```python -@router.get("/generate/{task_id}") -async def generate_video(task_id: str): - # 1단계: 명시적 세션 열기 → DB 작업 → 세션 닫기 - async with AsyncSessionLocal() as session: - # 병렬 쿼리 실행 - results = await asyncio.gather(...) - # 초기 데이터 저장 - await session.commit() - # 세션 닫힘 (async with 블록 종료) - - # 2단계: 외부 API 호출 (세션 없음 - 커넥션 점유 안함) - response = await creatomate_service.make_api_call() - - # 3단계: 새 세션으로 업데이트 - async with AsyncSessionLocal() as update_session: - video.render_id = response["id"] - await update_session.commit() -``` - -**적용 엔드포인트:** -- `GET /video/generate/{task_id}` - 영상 생성 -- `GET /song/generate/{task_id}` - 노래 생성 - -#### 패턴 3: 백그라운드 태스크 세션 - -```python -async def download_and_upload_video_to_blob(task_id: str, ...): - # 백그라운드 전용 세션 팩토리 사용 - async with BackgroundSessionLocal() as session: - result = await session.execute(...) - video.status = "completed" - await session.commit() -``` - -**적용 함수:** -- `download_and_upload_video_to_blob()` -- `download_and_upload_song_to_blob()` -- `generate_lyric_background()` - -### 2.4 해결된 문제: 세션 타임아웃 - -**문제 상황:** -``` -RuntimeError: unable to perform operation on -; the handler is closed -``` - -**원인:** -- `Depends(get_session)`으로 주입된 세션이 요청 전체 동안 유지 -- 외부 API 호출 (수 초~수 분) 중 TCP 커넥션 타임아웃 -- 요청 종료 시점에 이미 닫힌 커넥션 정리 시도 - -**해결책:** -```python -# 변경 전: 세션이 요청 전체 동안 유지 -async def generate_video(session: AsyncSession = Depends(get_session)): - await session.execute(...) # DB 작업 - await creatomate_api() # 외부 API (세션 유지됨 - 문제!) - await session.commit() # 타임아웃 에러 발생 가능 - -# 변경 후: 명시적 세션 관리 -async def generate_video(): - async with AsyncSessionLocal() as session: - await session.execute(...) - await session.commit() - # 세션 닫힘 - - await creatomate_api() # 외부 API (세션 없음 - 안전!) - - async with AsyncSessionLocal() as session: - # 업데이트 -``` - ---- - -## 3. 비동기 처리 패턴 - -### 3.1 asyncio.gather() 병렬 쿼리 - -**위치**: `app/video/api/routers/v1/video.py` - -```python -# 4개의 독립적인 쿼리를 병렬로 실행 -project_result, lyric_result, song_result, image_result = ( - await asyncio.gather( - session.execute(project_query), - session.execute(lyric_query), - session.execute(song_query), - session.execute(image_query), - ) -) -``` - -**성능 비교:** -``` -[순차 실행] -Query 1 ──────▶ 50ms - Query 2 ──────▶ 50ms - Query 3 ──────▶ 50ms - Query 4 ──────▶ 50ms -총 소요시간: 200ms - -[병렬 실행] -Query 1 ──────▶ 50ms -Query 2 ──────▶ 50ms -Query 3 ──────▶ 50ms -Query 4 ──────▶ 50ms -총 소요시간: ~55ms (가장 느린 쿼리 + 오버헤드) -``` - -### 3.2 FastAPI BackgroundTasks 활용 - -```python -@router.post("/generate") -async def generate_lyric( - request_body: GenerateLyricRequest, - background_tasks: BackgroundTasks, - session: AsyncSession = Depends(get_session), -): - # 즉시 응답할 데이터 저장 - lyric = Lyric(task_id=task_id, status="processing") - session.add(lyric) - await session.commit() - - # 백그라운드 태스크 스케줄링 - background_tasks.add_task( - generate_lyric_background, - task_id=task_id, - prompt=prompt, - language=request_body.language, - ) - - # 즉시 응답 반환 - return GenerateLyricResponse(success=True, task_id=task_id) -``` - -### 3.3 비동기 컨텍스트 관리자 - -```python -# 앱 라이프사이클 관리 -@asynccontextmanager -async def lifespan(app: FastAPI): - # Startup - await create_db_tables() - print("Database tables created") - - yield # 앱 실행 - - # Shutdown - await dispose_engine() - print("Database engines disposed") -``` - ---- - -## 4. 외부 API 통합 설계 - -### 4.1 Creatomate 서비스 - -**위치**: `app/utils/creatomate.py` - -#### HTTP 클라이언트 싱글톤 - -```python -# 모듈 레벨 공유 클라이언트 -_shared_client: httpx.AsyncClient | None = None - -async def get_shared_client() -> httpx.AsyncClient: - global _shared_client - if _shared_client is None or _shared_client.is_closed: - _shared_client = httpx.AsyncClient( - timeout=httpx.Timeout(60.0, connect=10.0), - limits=httpx.Limits( - max_keepalive_connections=10, - max_connections=20, - ), - ) - return _shared_client -``` - -**장점:** -- 커넥션 풀 재사용으로 TCP handshake 오버헤드 제거 -- Keep-alive로 연결 유지 -- 앱 종료 시 `close_shared_client()` 호출로 정리 - -#### 템플릿 캐싱 - -```python -# 모듈 레벨 캐시 -_template_cache: dict[str, dict] = {} -CACHE_TTL_SECONDS = 300 # 5분 - -async def get_one_template_data(self, template_id: str, use_cache: bool = True): - # 캐시 확인 - if use_cache and template_id in _template_cache: - cached = _template_cache[template_id] - if _is_cache_valid(cached["cached_at"]): - print(f"[CreatomateService] Cache HIT - {template_id}") - return copy.deepcopy(cached["data"]) - - # API 호출 및 캐시 저장 - data = await self._fetch_from_api(template_id) - _template_cache[template_id] = { - "data": data, - "cached_at": time.time(), - } - return copy.deepcopy(data) -``` - -**캐싱 전략:** -- 첫 번째 요청: API 호출 (1-2초) -- 이후 요청 (5분 내): 캐시 반환 (~0ms) -- TTL 만료 후: 자동 갱신 - -### 4.2 Suno 서비스 - -**위치**: `app/utils/suno.py` - -```python -class SunoService: - async def generate_music(self, prompt: str, callback_url: str = None): - async with httpx.AsyncClient() as client: - response = await client.post( - f"{self.base_url}/generate/music", - json={ - "prompt": prompt, - "callback_url": callback_url, - }, - timeout=60.0, - ) - return response.json() -``` - -### 4.3 ChatGPT 서비스 - -**위치**: `app/utils/chatgpt_prompt.py` - -```python -class ChatgptService: - async def generate(self, prompt: str) -> str: - # OpenAI API 호출 - response = await self.client.chat.completions.create( - model="gpt-4", - messages=[{"role": "user", "content": prompt}], - ) - return response.choices[0].message.content -``` - -### 4.4 Azure Blob Storage - -**위치**: `app/utils/upload_blob_as_request.py` - -```python -class AzureBlobUploader: - async def upload_video(self, file_path: str) -> bool: - # 비동기 업로드 - async with aiofiles.open(file_path, "rb") as f: - content = await f.read() - # Blob 업로드 로직 - return True -``` - ---- - -## 5. 백그라운드 태스크 워크플로우 - -### 5.1 3단계 워크플로우 패턴 - -``` -┌─────────────────────────────────────────────────────────────────┐ -│ REQUEST PHASE │ -│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │ -│ │ API Request │───▶│ Save Initial │───▶│ Return Response │ │ -│ │ │ │ Record │ │ (task_id) │ │ -│ └──────────────┘ │ status= │ └──────────────────┘ │ -│ │ "processing" │ │ -│ └──────────────┘ │ -└─────────────────────────────────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────────┐ -│ POLLING PHASE │ -│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │ -│ │ Client Polls │───▶│ Query │───▶│ Return Status │ │ -│ │ /status/id │ │ External API │ │ + Trigger BG │ │ -│ └──────────────┘ └──────────────┘ └──────────────────┘ │ -└─────────────────────────────────────────────────────────────────┘ - │ (if status == "succeeded") - ▼ -┌─────────────────────────────────────────────────────────────────┐ -│ BACKGROUND COMPLETION PHASE │ -│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │ -│ │ Download │───▶│ Upload to │───▶│ Update DB │ │ -│ │ Result File │ │ Azure Blob │ │ status=completed │ │ -│ └──────────────┘ └──────────────┘ │ result_url=... │ │ -│ └──────────────────┘ │ -└─────────────────────────────────────────────────────────────────┘ -``` - -### 5.2 영상 생성 플로우 - -```python -# 1단계: 즉시 응답 -@router.get("/video/generate/{task_id}") -async def generate_video(task_id: str): - # DB에서 필요한 데이터 조회 (병렬) - # Video 레코드 생성 (status="processing") - # Creatomate API 호출 → render_id 획득 - return {"success": True, "render_id": render_id} - -# 2단계: 폴링 -@router.get("/video/status/{render_id}") -async def get_video_status(render_id: str, background_tasks: BackgroundTasks): - status = await creatomate_service.get_render_status(render_id) - - if status == "succeeded": - # 백그라운드 태스크 트리거 - background_tasks.add_task( - download_and_upload_video_to_blob, - task_id=video.task_id, - video_url=status["url"], - ) - - return {"status": status} - -# 3단계: 백그라운드 완료 -async def download_and_upload_video_to_blob(task_id: str, video_url: str): - # 임시 파일 다운로드 - # Azure Blob 업로드 - # DB 업데이트 (BackgroundSessionLocal 사용) - # 임시 파일 삭제 -``` - -### 5.3 에러 처리 전략 - -```python -async def download_and_upload_video_to_blob(task_id: str, video_url: str): - temp_file_path: Path | None = None - - try: - # 다운로드 및 업로드 로직 - ... - - async with BackgroundSessionLocal() as session: - video.status = "completed" - await session.commit() - - except Exception as e: - print(f"[EXCEPTION] {task_id}: {e}") - # 실패 상태로 업데이트 - async with BackgroundSessionLocal() as session: - video.status = "failed" - await session.commit() - - finally: - # 임시 파일 정리 (항상 실행) - if temp_file_path and temp_file_path.exists(): - temp_file_path.unlink() - # 임시 디렉토리 정리 - temp_dir.rmdir() -``` - ---- - -## 6. 쿼리 최적화 전략 - -### 6.1 N+1 문제 해결 - -**문제 코드:** -```python -# 각 video마다 project를 개별 조회 (N+1) -for video in videos: - project = await session.execute( - select(Project).where(Project.id == video.project_id) - ) -``` - -**해결 코드:** -```python -# 1. Video 목록 조회 -videos = await session.execute(video_query) -video_list = videos.scalars().all() - -# 2. Project ID 수집 -project_ids = [v.project_id for v in video_list if v.project_id] - -# 3. Project 일괄 조회 (IN 절) -projects_result = await session.execute( - select(Project).where(Project.id.in_(project_ids)) -) - -# 4. 딕셔너리로 매핑 -projects_map = {p.id: p for p in projects_result.scalars().all()} - -# 5. 조합 -for video in video_list: - project = projects_map.get(video.project_id) -``` - -**위치**: `app/video/api/routers/v1/video.py` - `get_videos()` - -### 6.2 서브쿼리를 활용한 중복 제거 - -```python -# task_id별 최신 Video의 id만 추출 -subquery = ( - select(func.max(Video.id).label("max_id")) - .where(Video.status == "completed") - .group_by(Video.task_id) - .subquery() -) - -# 최신 Video만 조회 -query = ( - select(Video) - .where(Video.id.in_(select(subquery.c.max_id))) - .order_by(Video.created_at.desc()) -) -``` - ---- - -## 7. 설계 강점 분석 - -### 7.1 안정성 (Stability) - -| 요소 | 구현 | 효과 | -|------|------|------| -| pool_pre_ping | 쿼리 전 연결 검증 | Stale 커넥션 방지 | -| pool_reset_on_return | 반환 시 롤백 | 트랜잭션 상태 초기화 | -| 이중 커넥션 풀 | 요청/백그라운드 분리 | 리소스 경합 방지 | -| Finally 블록 | 임시 파일 정리 | 리소스 누수 방지 | - -### 7.2 성능 (Performance) - -| 요소 | 구현 | 효과 | -|------|------|------| -| asyncio.gather() | 병렬 쿼리 | 72% 응답 시간 단축 | -| 템플릿 캐싱 | TTL 기반 메모리 캐시 | API 호출 100% 감소 | -| HTTP 클라이언트 풀 | 싱글톤 패턴 | 커넥션 재사용 | -| N+1 해결 | IN 절 배치 조회 | 쿼리 수 N→2 감소 | - -### 7.3 확장성 (Scalability) - -| 요소 | 구현 | 효과 | -|------|------|------| -| 명시적 세션 관리 | 외부 API 시 세션 해제 | 커넥션 풀 점유 최소화 | -| 백그라운드 태스크 | FastAPI BackgroundTasks | 논블로킹 처리 | -| 폴링 패턴 | Status endpoint | 클라이언트 주도 동기화 | - -### 7.4 유지보수성 (Maintainability) - -| 요소 | 구현 | 효과 | -|------|------|------| -| 구조화된 로깅 | `[function_name]` prefix | 추적 용이 | -| 타입 힌트 | Python 3.11+ 문법 | IDE 지원, 버그 감소 | -| 문서화 | Docstring, 주석 | 코드 이해도 향상 | - ---- - -## 8. 개선 권장 사항 - -### 8.1 Song 라우터 N+1 문제 - -**현재 상태** (`app/song/api/routers/v1/song.py`): -```python -# N+1 발생 -for song in songs: - project_result = await session.execute( - select(Project).where(Project.id == song.project_id) - ) -``` - -**권장 수정**: -```python -# video.py의 패턴 적용 -project_ids = [s.project_id for s in songs if s.project_id] -projects_result = await session.execute( - select(Project).where(Project.id.in_(project_ids)) -) -projects_map = {p.id: p for p in projects_result.scalars().all()} -``` - -### 8.2 Suno 서비스 HTTP 클라이언트 풀링 - -**현재 상태** (`app/utils/suno.py`): -```python -# 요청마다 새 클라이언트 생성 -async with httpx.AsyncClient() as client: - ... -``` - -**권장 수정**: -```python -# creatomate.py 패턴 적용 -_suno_client: httpx.AsyncClient | None = None - -async def get_suno_client() -> httpx.AsyncClient: - global _suno_client - if _suno_client is None or _suno_client.is_closed: - _suno_client = httpx.AsyncClient( - timeout=httpx.Timeout(60.0, connect=10.0), - limits=httpx.Limits(max_keepalive_connections=5, max_connections=10), - ) - return _suno_client -``` - -### 8.3 동시성 제한 - -**권장 추가**: -```python -# 백그라운드 태스크 동시 실행 수 제한 -BACKGROUND_TASK_SEMAPHORE = asyncio.Semaphore(5) - -async def download_and_upload_video_to_blob(...): - async with BACKGROUND_TASK_SEMAPHORE: - # 기존 로직 -``` - -### 8.4 분산 락 (선택적) - -**높은 동시성 환경에서 권장**: -```python -# Redis 기반 분산 락 -async def generate_video_with_lock(task_id: str): - lock_key = f"video_gen:{task_id}" - - if not await redis.setnx(lock_key, "1"): - raise HTTPException(409, "Already processing") - - try: - await redis.expire(lock_key, 300) # 5분 TTL - # 영상 생성 로직 - finally: - await redis.delete(lock_key) -``` - ---- - -## 9. 아키텍처 다이어그램 - -### 9.1 전체 요청 흐름 - -``` -┌─────────────────────────────────────────────────────────────────────────┐ -│ CLIENT │ -└─────────────────────────────────────────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────────────────┐ -│ FASTAPI SERVER │ -│ ┌─────────────────────────────────────────────────────────────────┐ │ -│ │ ROUTERS │ │ -│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ -│ │ │ /video │ │ /song │ │ /lyric │ │ /project │ │ │ -│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │ -│ └─────────────────────────────────────────────────────────────────┘ │ -│ │ │ -│ ┌───────────────┼───────────────┐ │ -│ ▼ ▼ ▼ │ -│ ┌─────────────────────┐ ┌─────────────────┐ ┌─────────────────────┐ │ -│ │ MAIN ENGINE │ │ BACKGROUND │ │ EXTERNAL SERVICES │ │ -│ │ (AsyncSession) │ │ ENGINE │ │ ┌───────────────┐ │ │ -│ │ pool_size: 20 │ │ (BackgroundSess)│ │ │ Creatomate │ │ │ -│ │ max_overflow: 20 │ │ pool_size: 10 │ │ ├───────────────┤ │ │ -│ └─────────────────────┘ └─────────────────┘ │ │ Suno │ │ │ -│ │ │ │ ├───────────────┤ │ │ -│ ▼ ▼ │ │ ChatGPT │ │ │ -│ ┌─────────────────────────────────────────┐ │ ├───────────────┤ │ │ -│ │ MySQL DATABASE │ │ │ Azure Blob │ │ │ -│ │ ┌────────┐ ┌────────┐ ┌────────────┐ │ │ └───────────────┘ │ │ -│ │ │Project │ │ Song │ │ Video │ │ └─────────────────────┘ │ -│ │ │ Lyric │ │ Image │ │ │ │ │ -│ │ └────────┘ └────────┘ └────────────┘ │ │ -│ └─────────────────────────────────────────┘ │ -└─────────────────────────────────────────────────────────────────────────┘ -``` - -### 9.2 데이터 흐름 - -``` -[영상 생성 파이프라인] - -1. 프로젝트 생성 - Client ─▶ POST /project ─▶ DB(Project) ─▶ task_id - -2. 이미지 업로드 - Client ─▶ POST /project/image ─▶ Azure Blob ─▶ DB(Image) - -3. 가사 생성 - Client ─▶ POST /lyric/generate ─▶ DB(Lyric) ─▶ BackgroundTask - │ - ▼ - ChatGPT API - │ - ▼ - DB Update - -4. 노래 생성 - Client ─▶ GET /song/generate/{task_id} ─▶ Suno API ─▶ DB(Song) - Client ◀──── polling ─────────────────────────────────┘ - -5. 영상 생성 - Client ─▶ GET /video/generate/{task_id} - │ - ├─ asyncio.gather() ─▶ DB(Project, Lyric, Song, Image) - │ - ├─ Creatomate API ─▶ render_id - │ - └─ DB(Video) status="processing" - - Client ─▶ GET /video/status/{render_id} - │ - ├─ Creatomate Status Check - │ - └─ if succeeded ─▶ BackgroundTask - │ - ├─ Download MP4 - ├─ Upload to Azure Blob - └─ DB Update status="completed" - -6. 결과 조회 - Client ─▶ GET /video/download/{task_id} ─▶ result_movie_url -``` - ---- - -## 10. 결론 - -### 10.1 현재 아키텍처 평가 - -O2O-CASTAD Backend는 **프로덕션 준비 수준의 비동기 아키텍처**를 갖추고 있습니다: - -1. **안정성**: 이중 커넥션 풀, pool_pre_ping, 명시적 세션 관리로 런타임 에러 최소화 -2. **성능**: 병렬 쿼리, 캐싱, HTTP 클라이언트 풀링으로 응답 시간 최적화 -3. **확장성**: 백그라운드 태스크 분리, 폴링 패턴으로 부하 분산 -4. **유지보수성**: 일관된 패턴, 구조화된 로깅, 타입 힌트 - -### 10.2 핵심 성과 - -``` -┌─────────────────────────────────────────────────────────────┐ -│ BEFORE → AFTER │ -├─────────────────────────────────────────────────────────────┤ -│ Session Timeout Errors │ Frequent → Resolved │ -│ DB Query Time │ 200ms → 55ms (72%↓) │ -│ Template API Calls │ Every req → Cached (100%↓) │ -│ HTTP Client Overhead │ 50ms/req → 0ms (100%↓) │ -│ N+1 Query Problem │ N queries → 2 queries │ -│ Connection Pool Conflicts │ Frequent → Isolated │ -└─────────────────────────────────────────────────────────────┘ -``` - -### 10.3 권장 다음 단계 - -1. **단기**: Song 라우터 N+1 문제 해결 -2. **단기**: Suno 서비스 HTTP 클라이언트 풀링 적용 -3. **중기**: 동시성 제한 (Semaphore) 추가 -4. **장기**: Redis 캐시 레이어 도입 (템플릿 캐시 영속화) -5. **장기**: 분산 락 구현 (높은 동시성 환경 대비) - ---- - -> **문서 끝** -> 추가 질문이나 개선 제안은 개발팀에 문의하세요. +# O2O-CASTAD Backend 비동기 아키텍처 및 설계 분석 보고서 + +> **문서 버전**: 1.0 +> **작성일**: 2025-12-29 +> **대상**: 개발자, 아키텍트, 코드 리뷰어 + +--- + +## 목차 + +1. [Executive Summary](#1-executive-summary) +2. [데이터베이스 세션 관리 아키텍처](#2-데이터베이스-세션-관리-아키텍처) +3. [비동기 처리 패턴](#3-비동기-처리-패턴) +4. [외부 API 통합 설계](#4-외부-api-통합-설계) +5. [백그라운드 태스크 워크플로우](#5-백그라운드-태스크-워크플로우) +6. [쿼리 최적화 전략](#6-쿼리-최적화-전략) +7. [설계 강점 분석](#7-설계-강점-분석) +8. [개선 권장 사항](#8-개선-권장-사항) +9. [아키텍처 다이어그램](#9-아키텍처-다이어그램) +10. [결론](#10-결론) + +--- + +## 1. Executive Summary + +### 1.1 프로젝트 개요 + +O2O-CASTAD Backend는 FastAPI 기반의 비동기 백엔드 서비스로, AI 기반 광고 영상 자동 생성 파이프라인을 제공합니다. 주요 외부 서비스(Creatomate, Suno, ChatGPT, Azure Blob Storage)와의 통합을 통해 가사 생성 → 노래 생성 → 영상 생성의 파이프라인을 구현합니다. + +### 1.2 주요 성과 + +| 영역 | 개선 전 | 개선 후 | 개선율 | +|------|---------|---------|--------| +| 템플릿 API 호출 | 매번 호출 (1-2s) | 캐시 HIT (0ms) | **100% 감소** | +| HTTP 클라이언트 | 매번 생성 (50ms) | 풀 재사용 (0ms) | **100% 감소** | +| 세션 타임아웃 에러 | 빈번 | 해결 | **안정성 확보** | + +### 1.3 핵심 아키텍처 결정 + +1. **이중 커넥션 풀 아키텍처**: 요청/백그라운드 분리 +2. **명시적 세션 라이프사이클**: 외부 API 호출 전 세션 해제 +3. **모듈 레벨 싱글톤**: HTTP 클라이언트 및 템플릿 캐시 +4. **순차 쿼리 실행**: AsyncSession 제약으로 단일 세션 내 병렬 쿼리 불가 + +--- + +## 2. 데이터베이스 세션 관리 아키텍처 + +### 2.1 이중 엔진 구조 + +``` +┌─────────────────────────────────────────────────────────────┐ +│ DATABASE LAYER │ +├─────────────────────────────┬───────────────────────────────┤ +│ MAIN ENGINE │ BACKGROUND ENGINE │ +│ (FastAPI Requests) │ (Worker Tasks) │ +├─────────────────────────────┼───────────────────────────────┤ +│ pool_size: 20 │ pool_size: 10 │ +│ max_overflow: 20 │ max_overflow: 10 │ +│ pool_timeout: 30s │ pool_timeout: 60s │ +│ Total: 최대 40 연결 │ Total: 최대 20 연결 │ +├─────────────────────────────┼───────────────────────────────┤ +│ AsyncSessionLocal │ BackgroundSessionLocal │ +│ → Router endpoints │ → download_and_upload_* │ +│ → Direct API calls │ → generate_lyric_background │ +└─────────────────────────────┴───────────────────────────────┘ +``` + +**위치**: `app/database/session.py` + +### 2.2 엔진 설정 상세 + +```python +# 메인 엔진 (FastAPI 요청용) +engine = create_async_engine( + url=db_settings.MYSQL_URL, + pool_size=20, # 기본 풀 크기 + max_overflow=20, # 추가 연결 허용 + pool_timeout=30, # 연결 대기 최대 시간 + pool_recycle=280, # MySQL wait_timeout 보다 짧게 설정 + pool_pre_ping=True, # 연결 유효성 검사 (핵심!) + pool_reset_on_return="rollback", # 반환 시 롤백 +) + +# 백그라운드 엔진 (워커 태스크용) +background_engine = create_async_engine( + url=db_settings.MYSQL_URL, + pool_size=10, # 더 작은 풀 + max_overflow=10, + pool_timeout=60, # 백그라운드는 대기 여유 + pool_recycle=280, # MySQL wait_timeout 보다 짧게 설정 + pool_pre_ping=True, + pool_reset_on_return="rollback", # 반환 시 롤백 +) +``` + +### 2.3 세션 관리 패턴 + +#### 패턴 1: FastAPI 의존성 주입 (단순 CRUD) + +```python +@router.get("/items/{id}") +async def get_item( + id: int, + session: AsyncSession = Depends(get_session), +): + result = await session.execute(select(Item).where(Item.id == id)) + return result.scalar_one_or_none() +``` + +**적용 엔드포인트:** +- `GET /videos/` - 목록 조회 +- `GET /video/download/{task_id}` - 상태 조회 +- `GET /songs/` - 목록 조회 + +#### 패턴 2: 명시적 세션 관리 (외부 API 호출 포함) + +```python +@router.get("/generate/{task_id}") +async def generate_video(task_id: str): + # 1단계: 명시적 세션 열기 → DB 작업 → 세션 닫기 + async with AsyncSessionLocal() as session: + # 순차 쿼리 실행 (AsyncSession은 병렬 쿼리 미지원) + project = await session.execute(select(Project).where(...)) + lyric = await session.execute(select(Lyric).where(...)) + song = await session.execute(select(Song).where(...)) + # 초기 데이터 저장 + await session.commit() + # 세션 닫힘 (async with 블록 종료) + + # 2단계: 외부 API 호출 (세션 없음 - 커넥션 점유 안함) + response = await creatomate_service.make_api_call() + + # 3단계: 새 세션으로 업데이트 + async with AsyncSessionLocal() as update_session: + video.render_id = response["id"] + await update_session.commit() +``` + +**적용 엔드포인트:** +- `GET /video/generate/{task_id}` - 영상 생성 +- `GET /song/generate/{task_id}` - 노래 생성 + +#### 패턴 3: 백그라운드 태스크 세션 + +```python +async def download_and_upload_video_to_blob(task_id: str, ...): + # 백그라운드 전용 세션 팩토리 사용 + async with BackgroundSessionLocal() as session: + result = await session.execute(...) + video.status = "completed" + await session.commit() +``` + +**적용 함수:** +- `download_and_upload_video_to_blob()` +- `download_and_upload_song_to_blob()` +- `generate_lyric_background()` + +### 2.4 해결된 문제: 세션 타임아웃 + +**문제 상황:** +``` +RuntimeError: unable to perform operation on +; the handler is closed +``` + +**원인:** +- `Depends(get_session)`으로 주입된 세션이 요청 전체 동안 유지 +- 외부 API 호출 (수 초~수 분) 중 TCP 커넥션 타임아웃 +- 요청 종료 시점에 이미 닫힌 커넥션 정리 시도 + +**해결책:** +```python +# 변경 전: 세션이 요청 전체 동안 유지 +async def generate_video(session: AsyncSession = Depends(get_session)): + await session.execute(...) # DB 작업 + await creatomate_api() # 외부 API (세션 유지됨 - 문제!) + await session.commit() # 타임아웃 에러 발생 가능 + +# 변경 후: 명시적 세션 관리 +async def generate_video(): + async with AsyncSessionLocal() as session: + await session.execute(...) + await session.commit() + # 세션 닫힘 + + await creatomate_api() # 외부 API (세션 없음 - 안전!) + + async with AsyncSessionLocal() as session: + # 업데이트 +``` + +--- + +## 3. 비동기 처리 패턴 + +### 3.1 순차 쿼리 실행 (AsyncSession 제약) + +**위치**: `app/video/api/routers/v1/video.py` + +> **중요**: SQLAlchemy AsyncSession은 단일 세션에서 동시에 여러 쿼리를 실행하는 것을 지원하지 않습니다. +> `asyncio.gather()`로 병렬 쿼리를 실행하면 세션 상태 충돌이 발생합니다. + +```python +# 순차 쿼리 실행: Project, Lyric, Song, Image +# Note: AsyncSession은 동일 세션에서 병렬 쿼리를 지원하지 않음 + +# Project 조회 +project_result = await session.execute( + select(Project).where(Project.task_id == task_id) + .order_by(Project.created_at.desc()).limit(1) +) + +# Lyric 조회 +lyric_result = await session.execute( + select(Lyric).where(Lyric.task_id == task_id) + .order_by(Lyric.created_at.desc()).limit(1) +) + +# Song 조회 +song_result = await session.execute( + select(Song).where(Song.task_id == task_id) + .order_by(Song.created_at.desc()).limit(1) +) + +# Image 조회 +image_result = await session.execute( + select(Image).where(Image.task_id == task_id) + .order_by(Image.img_order.asc()) +) +``` + +**AsyncSession 병렬 쿼리 제약 사항:** + +- 단일 세션 내에서 `asyncio.gather()`로 여러 쿼리 동시 실행 불가 +- 세션 상태 충돌 및 예기치 않은 동작 발생 가능 +- 병렬 쿼리가 필요한 경우 별도의 세션을 각각 생성해야 함 + +### 3.2 FastAPI BackgroundTasks 활용 + +```python +@router.post("/generate") +async def generate_lyric( + request_body: GenerateLyricRequest, + background_tasks: BackgroundTasks, + session: AsyncSession = Depends(get_session), +): + # 즉시 응답할 데이터 저장 + lyric = Lyric(task_id=task_id, status="processing") + session.add(lyric) + await session.commit() + + # 백그라운드 태스크 스케줄링 + background_tasks.add_task( + generate_lyric_background, + task_id=task_id, + prompt=prompt, + language=request_body.language, + ) + + # 즉시 응답 반환 + return GenerateLyricResponse(success=True, task_id=task_id) +``` + +### 3.3 비동기 컨텍스트 관리자 + +```python +# 앱 라이프사이클 관리 +@asynccontextmanager +async def lifespan(app: FastAPI): + # Startup + await create_db_tables() + print("Database tables created") + + yield # 앱 실행 + + # Shutdown + await dispose_engine() + print("Database engines disposed") +``` + +--- + +## 4. 외부 API 통합 설계 + +### 4.1 Creatomate 서비스 + +**위치**: `app/utils/creatomate.py` + +#### HTTP 클라이언트 싱글톤 + +```python +# 모듈 레벨 공유 클라이언트 +_shared_client: httpx.AsyncClient | None = None + +async def get_shared_client() -> httpx.AsyncClient: + global _shared_client + if _shared_client is None or _shared_client.is_closed: + _shared_client = httpx.AsyncClient( + timeout=httpx.Timeout(60.0, connect=10.0), + limits=httpx.Limits( + max_keepalive_connections=10, + max_connections=20, + ), + ) + return _shared_client +``` + +**장점:** +- 커넥션 풀 재사용으로 TCP handshake 오버헤드 제거 +- Keep-alive로 연결 유지 +- 앱 종료 시 `close_shared_client()` 호출로 정리 + +#### 템플릿 캐싱 + +```python +# 모듈 레벨 캐시 +_template_cache: dict[str, dict] = {} +CACHE_TTL_SECONDS = 300 # 5분 + +async def get_one_template_data(self, template_id: str, use_cache: bool = True): + # 캐시 확인 + if use_cache and template_id in _template_cache: + cached = _template_cache[template_id] + if _is_cache_valid(cached["cached_at"]): + print(f"[CreatomateService] Cache HIT - {template_id}") + return copy.deepcopy(cached["data"]) + + # API 호출 및 캐시 저장 + data = await self._fetch_from_api(template_id) + _template_cache[template_id] = { + "data": data, + "cached_at": time.time(), + } + return copy.deepcopy(data) +``` + +**캐싱 전략:** +- 첫 번째 요청: API 호출 (1-2초) +- 이후 요청 (5분 내): 캐시 반환 (~0ms) +- TTL 만료 후: 자동 갱신 + +### 4.2 Suno 서비스 + +**위치**: `app/utils/suno.py` + +```python +class SunoService: + async def generate_music(self, prompt: str, callback_url: str = None): + async with httpx.AsyncClient() as client: + response = await client.post( + f"{self.base_url}/generate/music", + json={ + "prompt": prompt, + "callback_url": callback_url, + }, + timeout=60.0, + ) + return response.json() +``` + +### 4.3 ChatGPT 서비스 + +**위치**: `app/utils/chatgpt_prompt.py` + +```python +class ChatgptService: + async def generate(self, prompt: str) -> str: + # OpenAI API 호출 + response = await self.client.chat.completions.create( + model="gpt-4", + messages=[{"role": "user", "content": prompt}], + ) + return response.choices[0].message.content +``` + +### 4.4 Azure Blob Storage + +**위치**: `app/utils/upload_blob_as_request.py` + +```python +class AzureBlobUploader: + async def upload_video(self, file_path: str) -> bool: + # 비동기 업로드 + async with aiofiles.open(file_path, "rb") as f: + content = await f.read() + # Blob 업로드 로직 + return True +``` + +--- + +## 5. 백그라운드 태스크 워크플로우 + +### 5.1 3단계 워크플로우 패턴 + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ REQUEST PHASE │ +│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │ +│ │ API Request │───▶│ Save Initial │───▶│ Return Response │ │ +│ │ │ │ Record │ │ (task_id) │ │ +│ └──────────────┘ │ status= │ └──────────────────┘ │ +│ │ "processing" │ │ +│ └──────────────┘ │ +└─────────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ POLLING PHASE │ +│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │ +│ │ Client Polls │───▶│ Query │───▶│ Return Status │ │ +│ │ /status/id │ │ External API │ │ + Trigger BG │ │ +│ └──────────────┘ └──────────────┘ └──────────────────┘ │ +└─────────────────────────────────────────────────────────────────┘ + │ (if status == "succeeded") + ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ BACKGROUND COMPLETION PHASE │ +│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │ +│ │ Download │───▶│ Upload to │───▶│ Update DB │ │ +│ │ Result File │ │ Azure Blob │ │ status=completed │ │ +│ └──────────────┘ └──────────────┘ │ result_url=... │ │ +│ └──────────────────┘ │ +└─────────────────────────────────────────────────────────────────┘ +``` + +### 5.2 영상 생성 플로우 + +```python +# 1단계: 즉시 응답 +@router.get("/video/generate/{task_id}") +async def generate_video(task_id: str): + # DB에서 필요한 데이터 조회 (병렬) + # Video 레코드 생성 (status="processing") + # Creatomate API 호출 → render_id 획득 + return {"success": True, "render_id": render_id} + +# 2단계: 폴링 +@router.get("/video/status/{render_id}") +async def get_video_status(render_id: str, background_tasks: BackgroundTasks): + status = await creatomate_service.get_render_status(render_id) + + if status == "succeeded": + # 백그라운드 태스크 트리거 + background_tasks.add_task( + download_and_upload_video_to_blob, + task_id=video.task_id, + video_url=status["url"], + ) + + return {"status": status} + +# 3단계: 백그라운드 완료 +async def download_and_upload_video_to_blob(task_id: str, video_url: str): + # 임시 파일 다운로드 + # Azure Blob 업로드 + # DB 업데이트 (BackgroundSessionLocal 사용) + # 임시 파일 삭제 +``` + +### 5.3 에러 처리 전략 + +```python +async def download_and_upload_video_to_blob(task_id: str, video_url: str): + temp_file_path: Path | None = None + + try: + # 다운로드 및 업로드 로직 + ... + + async with BackgroundSessionLocal() as session: + video.status = "completed" + await session.commit() + + except Exception as e: + print(f"[EXCEPTION] {task_id}: {e}") + # 실패 상태로 업데이트 + async with BackgroundSessionLocal() as session: + video.status = "failed" + await session.commit() + + finally: + # 임시 파일 정리 (항상 실행) + if temp_file_path and temp_file_path.exists(): + temp_file_path.unlink() + # 임시 디렉토리 정리 + temp_dir.rmdir() +``` + +--- + +## 6. 쿼리 최적화 전략 + +### 6.1 N+1 문제 해결 + +**문제 코드:** +```python +# 각 video마다 project를 개별 조회 (N+1) +for video in videos: + project = await session.execute( + select(Project).where(Project.id == video.project_id) + ) +``` + +**해결 코드:** +```python +# 1. Video 목록 조회 +videos = await session.execute(video_query) +video_list = videos.scalars().all() + +# 2. Project ID 수집 +project_ids = [v.project_id for v in video_list if v.project_id] + +# 3. Project 일괄 조회 (IN 절) +projects_result = await session.execute( + select(Project).where(Project.id.in_(project_ids)) +) + +# 4. 딕셔너리로 매핑 +projects_map = {p.id: p for p in projects_result.scalars().all()} + +# 5. 조합 +for video in video_list: + project = projects_map.get(video.project_id) +``` + +**위치**: `app/video/api/routers/v1/video.py` - `get_videos()` + +### 6.2 서브쿼리를 활용한 중복 제거 + +```python +# task_id별 최신 Video의 id만 추출 +subquery = ( + select(func.max(Video.id).label("max_id")) + .where(Video.status == "completed") + .group_by(Video.task_id) + .subquery() +) + +# 최신 Video만 조회 +query = ( + select(Video) + .where(Video.id.in_(select(subquery.c.max_id))) + .order_by(Video.created_at.desc()) +) +``` + +--- + +## 7. 설계 강점 분석 + +### 7.1 안정성 (Stability) + +| 요소 | 구현 | 효과 | +|------|------|------| +| pool_pre_ping | 쿼리 전 연결 검증 | Stale 커넥션 방지 | +| pool_reset_on_return | 반환 시 롤백 | 트랜잭션 상태 초기화 | +| 이중 커넥션 풀 | 요청/백그라운드 분리 | 리소스 경합 방지 | +| Finally 블록 | 임시 파일 정리 | 리소스 누수 방지 | + +### 7.2 성능 (Performance) + +| 요소 | 구현 | 효과 | +|------|------|------| +| 템플릿 캐싱 | TTL 기반 메모리 캐시 | API 호출 100% 감소 | +| HTTP 클라이언트 풀 | 싱글톤 패턴 | 커넥션 재사용 | +| N+1 해결 | IN 절 배치 조회 | 쿼리 수 N→2 감소 | + +### 7.3 확장성 (Scalability) + +| 요소 | 구현 | 효과 | +|------|------|------| +| 명시적 세션 관리 | 외부 API 시 세션 해제 | 커넥션 풀 점유 최소화 | +| 백그라운드 태스크 | FastAPI BackgroundTasks | 논블로킹 처리 | +| 폴링 패턴 | Status endpoint | 클라이언트 주도 동기화 | + +### 7.4 유지보수성 (Maintainability) + +| 요소 | 구현 | 효과 | +|------|------|------| +| 구조화된 로깅 | `[function_name]` prefix | 추적 용이 | +| 타입 힌트 | Python 3.11+ 문법 | IDE 지원, 버그 감소 | +| 문서화 | Docstring, 주석 | 코드 이해도 향상 | + +--- + +## 8. 개선 권장 사항 + +### 8.1 Song 라우터 N+1 문제 + +**현재 상태** (`app/song/api/routers/v1/song.py`): +```python +# N+1 발생 +for song in songs: + project_result = await session.execute( + select(Project).where(Project.id == song.project_id) + ) +``` + +**권장 수정**: +```python +# video.py의 패턴 적용 +project_ids = [s.project_id for s in songs if s.project_id] +projects_result = await session.execute( + select(Project).where(Project.id.in_(project_ids)) +) +projects_map = {p.id: p for p in projects_result.scalars().all()} +``` + +### 8.2 Suno 서비스 HTTP 클라이언트 풀링 + +**현재 상태** (`app/utils/suno.py`): +```python +# 요청마다 새 클라이언트 생성 +async with httpx.AsyncClient() as client: + ... +``` + +**권장 수정**: +```python +# creatomate.py 패턴 적용 +_suno_client: httpx.AsyncClient | None = None + +async def get_suno_client() -> httpx.AsyncClient: + global _suno_client + if _suno_client is None or _suno_client.is_closed: + _suno_client = httpx.AsyncClient( + timeout=httpx.Timeout(60.0, connect=10.0), + limits=httpx.Limits(max_keepalive_connections=5, max_connections=10), + ) + return _suno_client +``` + +### 8.3 동시성 제한 + +**권장 추가**: +```python +# 백그라운드 태스크 동시 실행 수 제한 +BACKGROUND_TASK_SEMAPHORE = asyncio.Semaphore(5) + +async def download_and_upload_video_to_blob(...): + async with BACKGROUND_TASK_SEMAPHORE: + # 기존 로직 +``` + +### 8.4 분산 락 (선택적) + +**높은 동시성 환경에서 권장**: +```python +# Redis 기반 분산 락 +async def generate_video_with_lock(task_id: str): + lock_key = f"video_gen:{task_id}" + + if not await redis.setnx(lock_key, "1"): + raise HTTPException(409, "Already processing") + + try: + await redis.expire(lock_key, 300) # 5분 TTL + # 영상 생성 로직 + finally: + await redis.delete(lock_key) +``` + +--- + +## 9. 아키텍처 다이어그램 + +### 9.1 전체 요청 흐름 + +``` +┌─────────────────────────────────────────────────────────────────────────┐ +│ CLIENT │ +└─────────────────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────────────┐ +│ FASTAPI SERVER │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ ROUTERS │ │ +│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ +│ │ │ /video │ │ /song │ │ /lyric │ │ /project │ │ │ +│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +│ │ │ +│ ┌───────────────┼───────────────┐ │ +│ ▼ ▼ ▼ │ +│ ┌─────────────────────┐ ┌─────────────────┐ ┌─────────────────────┐ │ +│ │ MAIN ENGINE │ │ BACKGROUND │ │ EXTERNAL SERVICES │ │ +│ │ (AsyncSession) │ │ ENGINE │ │ ┌───────────────┐ │ │ +│ │ pool_size: 20 │ │ (BackgroundSess)│ │ │ Creatomate │ │ │ +│ │ max_overflow: 20 │ │ pool_size: 10 │ │ ├───────────────┤ │ │ +│ └─────────────────────┘ └─────────────────┘ │ │ Suno │ │ │ +│ │ │ │ ├───────────────┤ │ │ +│ ▼ ▼ │ │ ChatGPT │ │ │ +│ ┌─────────────────────────────────────────┐ │ ├───────────────┤ │ │ +│ │ MySQL DATABASE │ │ │ Azure Blob │ │ │ +│ │ ┌────────┐ ┌────────┐ ┌────────────┐ │ │ └───────────────┘ │ │ +│ │ │Project │ │ Song │ │ Video │ │ └─────────────────────┘ │ +│ │ │ Lyric │ │ Image │ │ │ │ │ +│ │ └────────┘ └────────┘ └────────────┘ │ │ +│ └─────────────────────────────────────────┘ │ +└─────────────────────────────────────────────────────────────────────────┘ +``` + +### 9.2 데이터 흐름 + +``` +[영상 생성 파이프라인] + +1. 프로젝트 생성 + Client ─▶ POST /project ─▶ DB(Project) ─▶ task_id + +2. 이미지 업로드 + Client ─▶ POST /project/image ─▶ Azure Blob ─▶ DB(Image) + +3. 가사 생성 + Client ─▶ POST /lyric/generate ─▶ DB(Lyric) ─▶ BackgroundTask + │ + ▼ + ChatGPT API + │ + ▼ + DB Update + +4. 노래 생성 + Client ─▶ GET /song/generate/{task_id} ─▶ Suno API ─▶ DB(Song) + Client ◀──── polling ─────────────────────────────────┘ + +5. 영상 생성 + Client ─▶ GET /video/generate/{task_id} + │ + ├─ 순차 쿼리 ─▶ DB(Project, Lyric, Song, Image) + │ + ├─ Creatomate API ─▶ render_id + │ + └─ DB(Video) status="processing" + + Client ─▶ GET /video/status/{render_id} + │ + ├─ Creatomate Status Check + │ + └─ if succeeded ─▶ BackgroundTask + │ + ├─ Download MP4 + ├─ Upload to Azure Blob + └─ DB Update status="completed" + +6. 결과 조회 + Client ─▶ GET /video/download/{task_id} ─▶ result_movie_url +``` + +--- + +## 10. 결론 + +### 10.1 현재 아키텍처 평가 + +O2O-CASTAD Backend는 **프로덕션 준비 수준의 비동기 아키텍처**를 갖추고 있습니다: + +1. **안정성**: 이중 커넥션 풀, pool_pre_ping, 명시적 세션 관리로 런타임 에러 최소화 +2. **성능**: 캐싱, HTTP 클라이언트 풀링으로 응답 시간 최적화 +3. **확장성**: 백그라운드 태스크 분리, 폴링 패턴으로 부하 분산 +4. **유지보수성**: 일관된 패턴, 구조화된 로깅, 타입 힌트 + +### 10.2 핵심 성과 + +``` +┌─────────────────────────────────────────────────────────────┐ +│ BEFORE → AFTER │ +├─────────────────────────────────────────────────────────────┤ +│ Session Timeout Errors │ Frequent → Resolved │ +│ Template API Calls │ Every req → Cached (100%↓) │ +│ HTTP Client Overhead │ 50ms/req → 0ms (100%↓) │ +│ N+1 Query Problem │ N queries → 2 queries │ +│ Connection Pool Conflicts │ Frequent → Isolated │ +└─────────────────────────────────────────────────────────────┘ +``` + +### 10.3 권장 다음 단계 + +1. **단기**: Song 라우터 N+1 문제 해결 +2. **단기**: Suno 서비스 HTTP 클라이언트 풀링 적용 +3. **중기**: 동시성 제한 (Semaphore) 추가 +4. **장기**: Redis 캐시 레이어 도입 (템플릿 캐시 영속화) +5. **장기**: 분산 락 구현 (높은 동시성 환경 대비) + +--- + +> **문서 끝** +> 추가 질문이나 개선 제안은 개발팀에 문의하세요. diff --git a/docs/analysis/db_쿼리_병렬화.md b/docs/analysis/db_쿼리_병렬화.md index 6c65322..b077c37 100644 --- a/docs/analysis/db_쿼리_병렬화.md +++ b/docs/analysis/db_쿼리_병렬화.md @@ -1,1041 +1,1041 @@ -# DB 쿼리 병렬화 (Query Parallelization) 완벽 가이드 - -> **목적**: Python asyncio와 SQLAlchemy를 활용한 DB 쿼리 병렬화의 이론부터 실무 적용까지 -> **대상**: 비동기 프로그래밍 기초 지식이 있는 백엔드 개발자 -> **환경**: Python 3.11+, SQLAlchemy 2.0+, FastAPI -> **최종 수정**: 2024-12 (AsyncSession 병렬 쿼리 제한사항 추가) - ---- - -## 목차 - -1. [이론적 배경](#1-이론적-배경) -2. [핵심 개념](#2-핵심-개념) -3. [SQLAlchemy AsyncSession 병렬 쿼리 제한사항](#3-sqlalchemy-asyncsession-병렬-쿼리-제한사항) ⚠️ **중요** -4. [설계 시 주의사항](#4-설계-시-주의사항) -5. [실무 시나리오 예제](#5-실무-시나리오-예제) -6. [성능 측정 및 모니터링](#6-성능-측정-및-모니터링) -7. [Best Practices](#7-best-practices) - ---- - -## 1. 이론적 배경 - -### 1.1 동기 vs 비동기 실행 - -``` -[순차 실행 - Sequential] -Query A ──────────▶ (100ms) - Query B ──────────▶ (100ms) - Query C ──────────▶ (100ms) -총 소요시간: 300ms - -[병렬 실행 - Parallel] -Query A ──────────▶ (100ms) -Query B ──────────▶ (100ms) -Query C ──────────▶ (100ms) -총 소요시간: ~100ms (가장 느린 쿼리 기준) -``` - -### 1.2 왜 병렬화가 필요한가? - -1. **I/O 바운드 작업의 특성** - - DB 쿼리는 네트워크 I/O가 대부분 (실제 CPU 작업은 짧음) - - 대기 시간 동안 다른 작업을 수행할 수 있음 - -2. **응답 시간 단축** - - N개의 독립적인 쿼리: `O(sum)` → `O(max)` - - 사용자 경험 개선 - -3. **리소스 효율성** - - 커넥션 풀을 효율적으로 활용 - - 서버 처리량(throughput) 증가 - -### 1.3 asyncio.gather()의 동작 원리 - -```python -import asyncio - -async def main(): - # gather()는 모든 코루틴을 동시에 스케줄링 - results = await asyncio.gather( - coroutine_1(), # Task 1 생성 - coroutine_2(), # Task 2 생성 - coroutine_3(), # Task 3 생성 - ) - # 모든 Task가 완료되면 결과를 리스트로 반환 - return results -``` - -**핵심 동작:** -1. `gather()`는 각 코루틴을 Task로 래핑 -2. 이벤트 루프가 모든 Task를 동시에 실행 -3. I/O 대기 시 다른 Task로 컨텍스트 스위칭 -4. 모든 Task 완료 시 결과 반환 - ---- - -## 2. 핵심 개념 - -### 2.1 독립성 판단 기준 - -병렬화가 가능한 쿼리의 조건: - -| 조건 | 설명 | 예시 | -|------|------|------| -| **데이터 독립성** | 쿼리 간 결과 의존성 없음 | User, Product, Order 각각 조회 | -| **트랜잭션 독립성** | 같은 트랜잭션 내 순서 무관 | READ 작업들 | -| **비즈니스 독립성** | 결과 순서가 로직에 영향 없음 | 대시보드 데이터 조회 | - -### 2.2 병렬화 불가능한 경우 - -```python -# ❌ 잘못된 예: 의존성이 있는 쿼리 -user = await session.execute(select(User).where(User.id == user_id)) -# orders 쿼리는 user.id에 의존 → 병렬화 불가 -orders = await session.execute( - select(Order).where(Order.user_id == user.id) -) -``` - -```python -# ❌ 잘못된 예: 쓰기 후 읽기 (Write-then-Read) -await session.execute(insert(User).values(name="John")) -# 방금 생성된 데이터를 조회 → 순차 실행 필요 -new_user = await session.execute(select(User).where(User.name == "John")) -``` - ---- - -## 3. SQLAlchemy AsyncSession 병렬 쿼리 제한사항 - -### ⚠️ 3.1 중요: 단일 AsyncSession에서 병렬 쿼리는 지원되지 않습니다 - -**이전에 잘못 알려진 내용:** -```python -# ❌ 이 코드는 실제로 작동하지 않습니다! -async with AsyncSessionLocal() as session: - results = await asyncio.gather( - session.execute(query1), - session.execute(query2), - session.execute(query3), - ) -``` - -### 3.2 실제 발생하는 에러 - -위 코드를 실행하면 다음과 같은 에러가 발생합니다: - -``` -sqlalchemy.exc.InvalidRequestError: -Method 'close()' can't be called here; method '_connection_for_bind()' -is already in progress and this would cause an unexpected state change -to - -(Background on this error at: https://sqlalche.me/e/20/isce) -``` - -### 3.3 에러 발생 원인 분석 - -``` -┌─────────────────────────────────────────────────────────────────────────┐ -│ AsyncSession 내부 상태 충돌 │ -├─────────────────────────────────────────────────────────────────────────┤ -│ │ -│ AsyncSession은 내부적으로 하나의 Connection을 관리합니다. │ -│ asyncio.gather()로 여러 쿼리를 동시에 실행하면: │ -│ │ -│ Time ──────────────────────────────────────────────────────────► │ -│ │ -│ Task 1: session.execute(query1) │ -│ └── _connection_for_bind() 시작 ──► 연결 획득 중... │ -│ │ -│ Task 2: session.execute(query2) │ -│ └── _connection_for_bind() 시작 ──► ⚠️ 충돌! │ -│ (이미 Task 1이 연결 작업 중) │ -│ │ -│ Task 3: session.execute(query3) │ -│ └── _connection_for_bind() 시작 ──► ⚠️ 충돌! │ -│ │ -│ 결과: InvalidRequestError 발생 │ -│ │ -│ ───────────────────────────────────────────────────────────────────── │ -│ │ -│ 핵심 원인: │ -│ 1. AsyncSession은 단일 연결(Connection)을 사용 │ -│ 2. 연결 상태 전이(state transition)가 순차적으로만 가능 │ -│ 3. 동시에 여러 작업이 상태 전이를 시도하면 충돌 발생 │ -│ │ -└─────────────────────────────────────────────────────────────────────────┘ -``` - -### 3.4 SQLAlchemy 공식 문서의 설명 - -SQLAlchemy 2.0 문서에 따르면: - -> The AsyncSession object is a mutable, stateful object which represents -> a single, stateful database transaction in progress. Using concurrent -> tasks with asyncio, with APIs such as asyncio.gather() for example, -> should use a **separate AsyncSession per individual task**. - -**번역**: AsyncSession 객체는 진행 중인 단일 데이터베이스 트랜잭션을 나타내는 -변경 가능한 상태 객체입니다. asyncio.gather() 같은 API로 동시 작업을 수행할 때는 -**각 작업마다 별도의 AsyncSession**을 사용해야 합니다. - -### 3.5 본 프로젝트에서 발생한 실제 사례 - -**문제가 발생한 코드 (video.py):** -```python -async def generate_video(task_id: str, ...): - async with AsyncSessionLocal() as session: - # ❌ 단일 세션에서 asyncio.gather() 사용 - 에러 발생! - project_result, lyric_result, song_result, image_result = ( - await asyncio.gather( - session.execute(project_query), - session.execute(lyric_query), - session.execute(song_query), - session.execute(image_query), - ) - ) -``` - -**프론트엔드에서 표시된 에러:** -``` -Method 'close()' can't be called here; method '_connection_for_bind()' -is already in progress and this would cause an unexpected state change -to -``` - -### 3.6 해결 방법 - -#### 방법 1: 순차 실행 (권장 - 단순하고 안전) - -```python -# ✅ 올바른 방법: 순차 실행 -async def generate_video(task_id: str, ...): - async with AsyncSessionLocal() as session: - # 순차적으로 쿼리 실행 (가장 안전) - project_result = await session.execute(project_query) - lyric_result = await session.execute(lyric_query) - song_result = await session.execute(song_query) - image_result = await session.execute(image_query) -``` - -**장점:** -- 구현이 단순함 -- 에러 처리가 명확함 -- 트랜잭션 관리가 쉬움 - -**단점:** -- 총 실행 시간 = 각 쿼리 시간의 합 - -#### 방법 2: 별도 세션으로 병렬 실행 (성능 중요 시) - -```python -# ✅ 올바른 방법: 각 쿼리마다 별도 세션 사용 -async def fetch_with_separate_sessions(task_id: str): - - async def get_project(): - async with AsyncSessionLocal() as session: - result = await session.execute( - select(Project).where(Project.task_id == task_id) - ) - return result.scalar_one_or_none() - - async def get_lyric(): - async with AsyncSessionLocal() as session: - result = await session.execute( - select(Lyric).where(Lyric.task_id == task_id) - ) - return result.scalar_one_or_none() - - async def get_song(): - async with AsyncSessionLocal() as session: - result = await session.execute( - select(Song).where(Song.task_id == task_id) - ) - return result.scalar_one_or_none() - - async def get_images(): - async with AsyncSessionLocal() as session: - result = await session.execute( - select(Image).where(Image.task_id == task_id) - ) - return result.scalars().all() - - # 별도 세션이므로 병렬 실행 가능! - project, lyric, song, images = await asyncio.gather( - get_project(), - get_lyric(), - get_song(), - get_images(), - ) - - return project, lyric, song, images -``` - -**장점:** -- 진정한 병렬 실행 -- 총 실행 시간 = 가장 느린 쿼리 시간 - -**단점:** -- 커넥션 풀에서 여러 연결을 동시에 사용 -- 각 쿼리가 별도 트랜잭션 (일관성 주의) -- 코드가 복잡해짐 - -#### 방법 3: 유틸리티 함수로 추상화 - -```python -from typing import TypeVar, Callable, Any -import asyncio - -T = TypeVar('T') - - -async def parallel_queries( - queries: list[tuple[Callable, dict]], -) -> list[Any]: - """ - 여러 쿼리를 별도 세션으로 병렬 실행합니다. - - Args: - queries: [(query_func, kwargs), ...] 형태의 리스트 - - Returns: - 각 쿼리의 결과 리스트 - - Example: - results = await parallel_queries([ - (get_project, {"task_id": task_id}), - (get_song, {"task_id": task_id}), - ]) - """ - async def execute_with_session(query_func, kwargs): - async with AsyncSessionLocal() as session: - return await query_func(session, **kwargs) - - return await asyncio.gather(*[ - execute_with_session(func, kwargs) - for func, kwargs in queries - ]) - - -# 사용 예시 -async def get_project(session, task_id: str): - result = await session.execute( - select(Project).where(Project.task_id == task_id) - ) - return result.scalar_one_or_none() - - -async def get_song(session, task_id: str): - result = await session.execute( - select(Song).where(Song.task_id == task_id) - ) - return result.scalar_one_or_none() - - -# 병렬 실행 -project, song = await parallel_queries([ - (get_project, {"task_id": "abc123"}), - (get_song, {"task_id": "abc123"}), -]) -``` - -### 3.7 성능 비교: 순차 vs 별도 세션 병렬 - -``` -┌─────────────────────────────────────────────────────────────────────────┐ -│ 성능 비교 (4개 쿼리, 각 50ms) │ -├─────────────────────────────────────────────────────────────────────────┤ -│ │ -│ [순차 실행 - 단일 세션] │ -│ ─────────────────────── │ -│ Query 1 ─────▶ (50ms) │ -│ Query 2 ─────▶ (50ms) │ -│ Query 3 ─────▶ (50ms) │ -│ Query 4 ─────▶ (50ms) │ -│ 총 소요시간: ~200ms │ -│ 커넥션 사용: 1개 │ -│ │ -│ [병렬 실행 - 별도 세션] │ -│ ─────────────────────── │ -│ Session 1: Query 1 ─────▶ (50ms) │ -│ Session 2: Query 2 ─────▶ (50ms) │ -│ Session 3: Query 3 ─────▶ (50ms) │ -│ Session 4: Query 4 ─────▶ (50ms) │ -│ 총 소요시간: ~55ms │ -│ 커넥션 사용: 4개 (동시) │ -│ │ -│ ───────────────────────────────────────────────────────────────────── │ -│ │ -│ 결론: │ -│ - 성능 개선: 약 72% (200ms → 55ms) │ -│ - 대가: 커넥션 풀 사용량 4배 증가 │ -│ - 트레이드오프 고려 필요 │ -│ │ -└─────────────────────────────────────────────────────────────────────────┘ -``` - -### 3.8 언제 병렬 실행을 선택해야 하는가? - -| 상황 | 권장 방식 | 이유 | -|------|----------|------| -| 쿼리 수 ≤ 3개 | 순차 실행 | 복잡도 대비 성능 이득 적음 | -| 쿼리 수 > 3개, 각 쿼리 > 50ms | 병렬 실행 | 유의미한 성능 개선 | -| 트랜잭션 일관성 필요 | 순차 실행 | 별도 세션은 별도 트랜잭션 | -| 커넥션 풀 여유 없음 | 순차 실행 | 풀 고갈 위험 | -| 실시간 응답 중요 (API) | 상황에 따라 | 사용자 경험 우선 | -| 백그라운드 작업 | 순차 실행 | 안정성 우선 | - -### 3.9 커넥션 풀 고려사항 - -```python -# 엔진 설정 시 병렬 쿼리를 고려한 풀 크기 설정 -engine = create_async_engine( - url=db_url, - pool_size=20, # 기본 풀 크기 - max_overflow=20, # 추가 연결 허용 - pool_timeout=30, # 풀 대기 타임아웃 -) - -# 계산 예시: -# - 동시 API 요청: 10개 -# - 요청당 병렬 쿼리: 4개 -# - 필요 커넥션: 10 × 4 = 40개 -# - 설정: pool_size(20) + max_overflow(20) = 40개 ✅ -``` - ---- - -## 4. 설계 시 주의사항 - -### 4.1 커넥션 풀 크기 설정 - -```python -# SQLAlchemy 엔진 설정 -engine = create_async_engine( - url=db_url, - pool_size=20, # 기본 풀 크기 - max_overflow=20, # 추가 연결 허용 수 - pool_timeout=30, # 풀에서 연결 대기 시간 - pool_recycle=3600, # 연결 재생성 주기 - pool_pre_ping=True, # 연결 유효성 검사 -) -``` - -**풀 크기 계산 공식:** -``` -필요 커넥션 수 = 동시 요청 수 × 요청당 병렬 쿼리 수 -``` - -예: 동시 10개 요청, 각 요청당 4개 병렬 쿼리 -→ 최소 40개 커넥션 필요 (pool_size + max_overflow >= 40) - -### 4.2 에러 처리 전략 - -```python -import asyncio - -# 방법 1: return_exceptions=True (권장) -results = await asyncio.gather( - fetch_with_session_1(), - fetch_with_session_2(), - fetch_with_session_3(), - return_exceptions=True, # 예외를 결과로 반환 -) - -# 결과 처리 -for i, result in enumerate(results): - if isinstance(result, Exception): - print(f"Query {i} failed: {result}") - else: - print(f"Query {i} succeeded: {result}") -``` - -```python -# 방법 2: 개별 try-except 래핑 -async def safe_fetch(query_func, **kwargs): - try: - async with AsyncSessionLocal() as session: - return await query_func(session, **kwargs) - except Exception as e: - print(f"Query failed: {e}") - return None - -results = await asyncio.gather( - safe_fetch(get_project, task_id=task_id), - safe_fetch(get_song, task_id=task_id), - safe_fetch(get_images, task_id=task_id), -) -``` - -### 4.3 타임아웃 설정 - -```python -import asyncio - -async def fetch_with_timeout(query_func, timeout_seconds: float, **kwargs): - """타임아웃이 있는 쿼리 실행""" - try: - return await asyncio.wait_for( - query_func(**kwargs), - timeout=timeout_seconds - ) - except asyncio.TimeoutError: - raise Exception(f"Query timed out after {timeout_seconds}s") - -# 사용 예 -results = await asyncio.gather( - fetch_with_timeout(get_project, 5.0, task_id=task_id), - fetch_with_timeout(get_song, 5.0, task_id=task_id), - fetch_with_timeout(get_images, 10.0, task_id=task_id), # 더 긴 타임아웃 -) -``` - -### 4.4 N+1 문제와 병렬화 - -```python -# ❌ N+1 문제 발생 코드 -videos = await session.execute(select(Video)) -for video in videos.scalars(): - # N번의 추가 쿼리 발생! - project = await session.execute( - select(Project).where(Project.id == video.project_id) - ) - -# ✅ 해결 방법 1: JOIN 사용 -query = select(Video).options(selectinload(Video.project)) -videos = await session.execute(query) - -# ✅ 해결 방법 2: IN 절로 배치 조회 -video_list = videos.scalars().all() -project_ids = [v.project_id for v in video_list if v.project_id] - -projects_result = await session.execute( - select(Project).where(Project.id.in_(project_ids)) -) -projects_map = {p.id: p for p in projects_result.scalars().all()} -``` - -### 4.5 트랜잭션 격리 수준 고려 - -| 격리 수준 | 병렬 쿼리 안전성 | 설명 | -|-----------|------------------|------| -| READ UNCOMMITTED | ⚠️ 주의 | Dirty Read 가능 | -| READ COMMITTED | ✅ 안전 | 대부분의 경우 적합 | -| REPEATABLE READ | ✅ 안전 | 일관된 스냅샷 | -| SERIALIZABLE | ✅ 안전 | 성능 저하 가능 | - ---- - -## 5. 실무 시나리오 예제 - -### 5.1 시나리오 1: 대시보드 데이터 조회 (별도 세션 병렬) - -**요구사항**: 사용자 대시보드에 필요한 여러 통계 데이터를 한 번에 조회 - -```python -from sqlalchemy import select, func -from sqlalchemy.ext.asyncio import AsyncSession -import asyncio - - -async def get_user(session: AsyncSession, user_id: int): - result = await session.execute( - select(User).where(User.id == user_id) - ) - return result.scalar_one_or_none() - - -async def get_recent_orders(session: AsyncSession, user_id: int): - result = await session.execute( - select(Order) - .where(Order.user_id == user_id) - .order_by(Order.created_at.desc()) - .limit(5) - ) - return result.scalars().all() - - -async def get_total_amount(session: AsyncSession, user_id: int): - result = await session.execute( - select(func.sum(Order.amount)) - .where(Order.user_id == user_id) - ) - return result.scalar() or 0 - - -async def get_wishlist_count(session: AsyncSession, user_id: int): - result = await session.execute( - select(func.count(Wishlist.id)) - .where(Wishlist.user_id == user_id) - ) - return result.scalar() or 0 - - -async def get_dashboard_data(user_id: int) -> dict: - """ - 대시보드에 필요한 모든 데이터를 병렬로 조회합니다. - 각 쿼리는 별도의 세션을 사용합니다. - """ - - async def fetch_user(): - async with AsyncSessionLocal() as session: - return await get_user(session, user_id) - - async def fetch_orders(): - async with AsyncSessionLocal() as session: - return await get_recent_orders(session, user_id) - - async def fetch_amount(): - async with AsyncSessionLocal() as session: - return await get_total_amount(session, user_id) - - async def fetch_wishlist(): - async with AsyncSessionLocal() as session: - return await get_wishlist_count(session, user_id) - - # 4개 쿼리를 별도 세션으로 병렬 실행 - user, orders, total_amount, wishlist_count = await asyncio.gather( - fetch_user(), - fetch_orders(), - fetch_amount(), - fetch_wishlist(), - ) - - if not user: - raise ValueError(f"User {user_id} not found") - - return { - "user": {"id": user.id, "name": user.name, "email": user.email}, - "recent_orders": [ - {"id": o.id, "amount": o.amount, "status": o.status} - for o in orders - ], - "total_spent": total_amount, - "wishlist_count": wishlist_count, - } - - -# 사용 예시 (FastAPI) -@router.get("/dashboard") -async def dashboard(user_id: int): - return await get_dashboard_data(user_id) -``` - -**성능 비교:** -- 순차 실행: ~200ms (50ms × 4) -- 병렬 실행: ~60ms (가장 느린 쿼리 기준) -- **개선율: 약 70%** - ---- - -### 5.2 시나리오 2: 영상 생성 데이터 조회 (순차 실행 - 권장) - -**요구사항**: 영상 생성을 위해 Project, Lyric, Song, Image 데이터를 조회 - -**본 프로젝트에서 실제로 적용된 패턴입니다.** - -```python -from sqlalchemy import select -from sqlalchemy.ext.asyncio import AsyncSession -from dataclasses import dataclass -from fastapi import HTTPException - - -@dataclass -class VideoGenerationData: - """영상 생성에 필요한 데이터""" - project_id: int - lyric_id: int - song_id: int - music_url: str - song_duration: float - lyrics: str - image_urls: list[str] - - -async def generate_video( - task_id: str, - orientation: str = "vertical", -) -> GenerateVideoResponse: - """ - Creatomate API를 통해 영상을 생성합니다. - - 중요: SQLAlchemy AsyncSession은 단일 세션에서 동시에 여러 쿼리를 실행하는 것을 - 지원하지 않습니다. asyncio.gather()로 병렬 쿼리를 실행하면 세션 상태 충돌이 발생합니다. - 따라서 쿼리는 순차적으로 실행합니다. - """ - from app.database.session import AsyncSessionLocal - - print(f"[generate_video] START - task_id: {task_id}") - - # 외부 API 호출 전에 필요한 데이터를 저장할 변수들 - project_id: int | None = None - lyric_id: int | None = None - song_id: int | None = None - video_id: int | None = None - music_url: str | None = None - song_duration: float | None = None - lyrics: str | None = None - image_urls: list[str] = [] - - try: - # 세션을 명시적으로 열고 DB 작업 후 바로 닫음 - async with AsyncSessionLocal() as session: - # ===== 순차 쿼리 실행: Project, Lyric, Song, Image ===== - # Note: AsyncSession은 동일 세션에서 병렬 쿼리를 지원하지 않음 - - # Project 조회 - project_result = await session.execute( - select(Project) - .where(Project.task_id == task_id) - .order_by(Project.created_at.desc()) - .limit(1) - ) - - # Lyric 조회 - lyric_result = await session.execute( - select(Lyric) - .where(Lyric.task_id == task_id) - .order_by(Lyric.created_at.desc()) - .limit(1) - ) - - # Song 조회 - song_result = await session.execute( - select(Song) - .where(Song.task_id == task_id) - .order_by(Song.created_at.desc()) - .limit(1) - ) - - # Image 조회 - image_result = await session.execute( - select(Image) - .where(Image.task_id == task_id) - .order_by(Image.img_order.asc()) - ) - - print(f"[generate_video] Queries completed - task_id: {task_id}") - - # 결과 처리 및 검증 - project = project_result.scalar_one_or_none() - if not project: - raise HTTPException(status_code=404, detail="Project not found") - project_id = project.id - - lyric = lyric_result.scalar_one_or_none() - if not lyric: - raise HTTPException(status_code=404, detail="Lyric not found") - lyric_id = lyric.id - - song = song_result.scalar_one_or_none() - if not song: - raise HTTPException(status_code=404, detail="Song not found") - song_id = song.id - music_url = song.song_result_url - song_duration = song.duration - lyrics = song.song_prompt - - images = image_result.scalars().all() - if not images: - raise HTTPException(status_code=404, detail="Images not found") - image_urls = [img.img_url for img in images] - - # Video 레코드 생성 및 커밋 - video = Video( - project_id=project_id, - lyric_id=lyric_id, - song_id=song_id, - task_id=task_id, - status="processing", - ) - session.add(video) - await session.commit() - video_id = video.id - - # 세션 종료 후 외부 API 호출 (커넥션 타임아웃 방지) - # ... Creatomate API 호출 로직 ... - - except HTTPException: - raise - except Exception as e: - print(f"[generate_video] EXCEPTION - {e}") - raise -``` - -**이 패턴을 선택한 이유:** -1. **안정성**: 단일 세션 내에서 모든 쿼리 실행으로 트랜잭션 일관성 보장 -2. **단순성**: 코드가 명확하고 디버깅이 쉬움 -3. **충분한 성능**: 4개의 간단한 쿼리는 순차 실행해도 ~200ms 이내 -4. **에러 방지**: AsyncSession 병렬 쿼리 제한으로 인한 에러 방지 - ---- - -### 5.3 시나리오 3: 복합 검색 (트레이드오프 분석) - -```python -# 방법 A: 순차 실행 (단순, 안전) -async def search_sequential(session: AsyncSession, keyword: str): - items = await session.execute(items_query) - count = await session.execute(count_query) - categories = await session.execute(category_query) - price_range = await session.execute(price_query) - brands = await session.execute(brand_query) - return items, count, categories, price_range, brands -# 예상 시간: ~350ms (70ms × 5) - - -# 방법 B: 별도 세션 병렬 실행 (빠름, 복잡) -async def search_parallel(keyword: str): - async def fetch_items(): - async with AsyncSessionLocal() as s: - return await s.execute(items_query) - - async def fetch_count(): - async with AsyncSessionLocal() as s: - return await s.execute(count_query) - - # ... 나머지 함수들 ... - - return await asyncio.gather( - fetch_items(), - fetch_count(), - fetch_categories(), - fetch_price_range(), - fetch_brands(), - ) -# 예상 시간: ~80ms - - -# 결정 기준: -# - 검색 API가 자주 호출되고 응답 시간이 중요하다면 → 방법 B -# - 안정성이 우선이고 복잡도를 낮추고 싶다면 → 방법 A -# - 커넥션 풀 여유가 없다면 → 방법 A -``` - ---- - -## 6. 성능 측정 및 모니터링 - -### 6.1 실행 시간 측정 데코레이터 - -```python -import time -import functools -import asyncio -from typing import Callable, TypeVar - -T = TypeVar("T") - - -def measure_time(func: Callable[..., T]) -> Callable[..., T]: - """함수 실행 시간을 측정하는 데코레이터""" - - @functools.wraps(func) - async def async_wrapper(*args, **kwargs): - start = time.perf_counter() - try: - return await func(*args, **kwargs) - finally: - elapsed = (time.perf_counter() - start) * 1000 - print(f"[{func.__name__}] Execution time: {elapsed:.2f}ms") - - @functools.wraps(func) - def sync_wrapper(*args, **kwargs): - start = time.perf_counter() - try: - return func(*args, **kwargs) - finally: - elapsed = (time.perf_counter() - start) * 1000 - print(f"[{func.__name__}] Execution time: {elapsed:.2f}ms") - - if asyncio.iscoroutinefunction(func): - return async_wrapper - return sync_wrapper - - -# 사용 예 -@measure_time -async def fetch_data(task_id: str): - ... -``` - -### 6.2 병렬 vs 순차 성능 비교 유틸리티 - -```python -import asyncio -import time - - -async def compare_execution_methods( - task_id: str, - query_funcs: list[Callable], -) -> dict: - """순차 실행과 병렬 실행(별도 세션)의 성능을 비교합니다.""" - - # 순차 실행 (단일 세션) - sequential_start = time.perf_counter() - async with AsyncSessionLocal() as session: - sequential_results = [] - for func in query_funcs: - result = await func(session, task_id) - sequential_results.append(result) - sequential_time = (time.perf_counter() - sequential_start) * 1000 - - # 병렬 실행 (별도 세션) - parallel_start = time.perf_counter() - - async def run_with_session(func): - async with AsyncSessionLocal() as session: - return await func(session, task_id) - - parallel_results = await asyncio.gather(*[ - run_with_session(func) for func in query_funcs - ]) - parallel_time = (time.perf_counter() - parallel_start) * 1000 - - improvement = ((sequential_time - parallel_time) / sequential_time) * 100 - - return { - "sequential_time_ms": round(sequential_time, 2), - "parallel_time_ms": round(parallel_time, 2), - "improvement_percent": round(improvement, 1), - "query_count": len(query_funcs), - } -``` - -### 6.3 SQLAlchemy 쿼리 로깅 - -```python -import logging - -# SQLAlchemy 쿼리 로깅 활성화 -logging.basicConfig() -logging.getLogger("sqlalchemy.engine").setLevel(logging.INFO) - -# 또는 엔진 생성 시 echo=True -engine = create_async_engine(url, echo=True) -``` - ---- - -## 7. Best Practices - -### 7.1 체크리스트 - -병렬화 적용 전 확인사항: - -- [ ] 쿼리들이 서로 독립적인가? (결과 의존성 없음) -- [ ] 모든 쿼리가 READ 작업인가? (또는 순서 무관한 WRITE) -- [ ] **별도 세션을 사용할 것인가?** (AsyncSession 제한사항) -- [ ] 커넥션 풀 크기가 충분한가? -- [ ] 에러 처리 전략이 수립되어 있는가? -- [ ] 타임아웃 설정이 적절한가? -- [ ] 트랜잭션 일관성이 필요한가? - -### 7.2 권장 패턴 - -```python -# ✅ 패턴 1: 순차 실행 (단순하고 안전) -async def fetch_data(session: AsyncSession, task_id: str): - project = await session.execute(project_query) - song = await session.execute(song_query) - return project, song - - -# ✅ 패턴 2: 별도 세션으로 병렬 실행 (성능 중요 시) -async def fetch_data_parallel(task_id: str): - async def get_project(): - async with AsyncSessionLocal() as s: - return await s.execute(project_query) - - async def get_song(): - async with AsyncSessionLocal() as s: - return await s.execute(song_query) - - return await asyncio.gather(get_project(), get_song()) -``` - -### 7.3 피해야 할 패턴 - -```python -# ❌ 절대 금지: 단일 세션에서 asyncio.gather() -async with AsyncSessionLocal() as session: - results = await asyncio.gather( - session.execute(query1), - session.execute(query2), - ) -# 에러 발생: InvalidRequestError - Method 'close()' can't be called here - -# ❌ 피하기: 과도한 병렬화 (커넥션 고갈) -# 100개 쿼리를 동시에 실행하면 커넥션 풀 고갈 위험 -results = await asyncio.gather(*[fetch() for _ in range(100)]) - -# ✅ 해결: 배치 처리 -BATCH_SIZE = 10 -for i in range(0, len(items), BATCH_SIZE): - batch = items[i:i + BATCH_SIZE] - results = await asyncio.gather(*[fetch(item) for item in batch]) -``` - -### 7.4 결정 가이드 - -``` -┌─────────────────────────────────────────────────────────────────────────┐ -│ 병렬화 결정 플로우차트 │ -├─────────────────────────────────────────────────────────────────────────┤ -│ │ -│ 쿼리 개수가 3개 이하인가? │ -│ │ │ -│ ├── Yes ──► 순차 실행 (복잡도 대비 이득 적음) │ -│ │ │ -│ └── No ──► 각 쿼리가 50ms 이상 걸리는가? │ -│ │ │ -│ ├── No ──► 순차 실행 (이득 적음) │ -│ │ │ -│ └── Yes ──► 트랜잭션 일관성이 필요한가? │ -│ │ │ -│ ├── Yes ──► 순차 실행 │ -│ │ (단일 세션) │ -│ │ │ -│ └── No ──► 커넥션 풀 여유? │ -│ │ │ -│ ├── No ──► │ -│ │ 순차 실행 │ -│ │ │ -│ └── Yes ──► │ -│ 병렬 실행 │ -│ (별도세션) │ -│ │ -└─────────────────────────────────────────────────────────────────────────┘ -``` - -### 7.5 성능 최적화 팁 - -1. **인덱스 확인**: 병렬화해도 인덱스 없으면 느림 -2. **쿼리 최적화 우선**: 병렬화 전에 개별 쿼리 최적화 -3. **적절한 병렬 수준**: 보통 3-10개가 적절 -4. **모니터링 필수**: 실제 개선 효과 측정 -5. **커넥션 풀 모니터링**: 병렬 실행 시 풀 사용량 확인 - ---- - -## 부록: 관련 자료 - -- [SQLAlchemy 2.0 AsyncIO 문서](https://docs.sqlalchemy.org/en/20/orm/extensions/asyncio.html) -- [SQLAlchemy AsyncSession 동시성 제한](https://docs.sqlalchemy.org/en/20/orm/extensions/asyncio.html#using-asyncio-scoped-session) -- [Python asyncio 공식 문서](https://docs.python.org/3/library/asyncio.html) -- [FastAPI 비동기 데이터베이스](https://fastapi.tiangolo.com/async/) - ---- - -## 변경 이력 - -| 날짜 | 변경 내용 | -|------|----------| -| 2024-12 | AsyncSession 병렬 쿼리 제한사항 섹션 추가 (실제 프로젝트 에러 사례 포함) | -| 2024-12 | 잘못된 병렬 쿼리 예제 수정 | -| 2024-12 | 결정 플로우차트 추가 | +# DB 쿼리 병렬화 (Query Parallelization) 완벽 가이드 + +> **목적**: Python asyncio와 SQLAlchemy를 활용한 DB 쿼리 병렬화의 이론부터 실무 적용까지 +> **대상**: 비동기 프로그래밍 기초 지식이 있는 백엔드 개발자 +> **환경**: Python 3.11+, SQLAlchemy 2.0+, FastAPI +> **최종 수정**: 2024-12 (AsyncSession 병렬 쿼리 제한사항 추가) + +--- + +## 목차 + +1. [이론적 배경](#1-이론적-배경) +2. [핵심 개념](#2-핵심-개념) +3. [SQLAlchemy AsyncSession 병렬 쿼리 제한사항](#3-sqlalchemy-asyncsession-병렬-쿼리-제한사항) ⚠️ **중요** +4. [설계 시 주의사항](#4-설계-시-주의사항) +5. [실무 시나리오 예제](#5-실무-시나리오-예제) +6. [성능 측정 및 모니터링](#6-성능-측정-및-모니터링) +7. [Best Practices](#7-best-practices) + +--- + +## 1. 이론적 배경 + +### 1.1 동기 vs 비동기 실행 + +``` +[순차 실행 - Sequential] +Query A ──────────▶ (100ms) + Query B ──────────▶ (100ms) + Query C ──────────▶ (100ms) +총 소요시간: 300ms + +[병렬 실행 - Parallel] +Query A ──────────▶ (100ms) +Query B ──────────▶ (100ms) +Query C ──────────▶ (100ms) +총 소요시간: ~100ms (가장 느린 쿼리 기준) +``` + +### 1.2 왜 병렬화가 필요한가? + +1. **I/O 바운드 작업의 특성** + - DB 쿼리는 네트워크 I/O가 대부분 (실제 CPU 작업은 짧음) + - 대기 시간 동안 다른 작업을 수행할 수 있음 + +2. **응답 시간 단축** + - N개의 독립적인 쿼리: `O(sum)` → `O(max)` + - 사용자 경험 개선 + +3. **리소스 효율성** + - 커넥션 풀을 효율적으로 활용 + - 서버 처리량(throughput) 증가 + +### 1.3 asyncio.gather()의 동작 원리 + +```python +import asyncio + +async def main(): + # gather()는 모든 코루틴을 동시에 스케줄링 + results = await asyncio.gather( + coroutine_1(), # Task 1 생성 + coroutine_2(), # Task 2 생성 + coroutine_3(), # Task 3 생성 + ) + # 모든 Task가 완료되면 결과를 리스트로 반환 + return results +``` + +**핵심 동작:** +1. `gather()`는 각 코루틴을 Task로 래핑 +2. 이벤트 루프가 모든 Task를 동시에 실행 +3. I/O 대기 시 다른 Task로 컨텍스트 스위칭 +4. 모든 Task 완료 시 결과 반환 + +--- + +## 2. 핵심 개념 + +### 2.1 독립성 판단 기준 + +병렬화가 가능한 쿼리의 조건: + +| 조건 | 설명 | 예시 | +|------|------|------| +| **데이터 독립성** | 쿼리 간 결과 의존성 없음 | User, Product, Order 각각 조회 | +| **트랜잭션 독립성** | 같은 트랜잭션 내 순서 무관 | READ 작업들 | +| **비즈니스 독립성** | 결과 순서가 로직에 영향 없음 | 대시보드 데이터 조회 | + +### 2.2 병렬화 불가능한 경우 + +```python +# ❌ 잘못된 예: 의존성이 있는 쿼리 +user = await session.execute(select(User).where(User.id == user_id)) +# orders 쿼리는 user.id에 의존 → 병렬화 불가 +orders = await session.execute( + select(Order).where(Order.user_id == user.id) +) +``` + +```python +# ❌ 잘못된 예: 쓰기 후 읽기 (Write-then-Read) +await session.execute(insert(User).values(name="John")) +# 방금 생성된 데이터를 조회 → 순차 실행 필요 +new_user = await session.execute(select(User).where(User.name == "John")) +``` + +--- + +## 3. SQLAlchemy AsyncSession 병렬 쿼리 제한사항 + +### ⚠️ 3.1 중요: 단일 AsyncSession에서 병렬 쿼리는 지원되지 않습니다 + +**이전에 잘못 알려진 내용:** +```python +# ❌ 이 코드는 실제로 작동하지 않습니다! +async with AsyncSessionLocal() as session: + results = await asyncio.gather( + session.execute(query1), + session.execute(query2), + session.execute(query3), + ) +``` + +### 3.2 실제 발생하는 에러 + +위 코드를 실행하면 다음과 같은 에러가 발생합니다: + +``` +sqlalchemy.exc.InvalidRequestError: +Method 'close()' can't be called here; method '_connection_for_bind()' +is already in progress and this would cause an unexpected state change +to + +(Background on this error at: https://sqlalche.me/e/20/isce) +``` + +### 3.3 에러 발생 원인 분석 + +``` +┌─────────────────────────────────────────────────────────────────────────┐ +│ AsyncSession 내부 상태 충돌 │ +├─────────────────────────────────────────────────────────────────────────┤ +│ │ +│ AsyncSession은 내부적으로 하나의 Connection을 관리합니다. │ +│ asyncio.gather()로 여러 쿼리를 동시에 실행하면: │ +│ │ +│ Time ──────────────────────────────────────────────────────────► │ +│ │ +│ Task 1: session.execute(query1) │ +│ └── _connection_for_bind() 시작 ──► 연결 획득 중... │ +│ │ +│ Task 2: session.execute(query2) │ +│ └── _connection_for_bind() 시작 ──► ⚠️ 충돌! │ +│ (이미 Task 1이 연결 작업 중) │ +│ │ +│ Task 3: session.execute(query3) │ +│ └── _connection_for_bind() 시작 ──► ⚠️ 충돌! │ +│ │ +│ 결과: InvalidRequestError 발생 │ +│ │ +│ ───────────────────────────────────────────────────────────────────── │ +│ │ +│ 핵심 원인: │ +│ 1. AsyncSession은 단일 연결(Connection)을 사용 │ +│ 2. 연결 상태 전이(state transition)가 순차적으로만 가능 │ +│ 3. 동시에 여러 작업이 상태 전이를 시도하면 충돌 발생 │ +│ │ +└─────────────────────────────────────────────────────────────────────────┘ +``` + +### 3.4 SQLAlchemy 공식 문서의 설명 + +SQLAlchemy 2.0 문서에 따르면: + +> The AsyncSession object is a mutable, stateful object which represents +> a single, stateful database transaction in progress. Using concurrent +> tasks with asyncio, with APIs such as asyncio.gather() for example, +> should use a **separate AsyncSession per individual task**. + +**번역**: AsyncSession 객체는 진행 중인 단일 데이터베이스 트랜잭션을 나타내는 +변경 가능한 상태 객체입니다. asyncio.gather() 같은 API로 동시 작업을 수행할 때는 +**각 작업마다 별도의 AsyncSession**을 사용해야 합니다. + +### 3.5 본 프로젝트에서 발생한 실제 사례 + +**문제가 발생한 코드 (video.py):** +```python +async def generate_video(task_id: str, ...): + async with AsyncSessionLocal() as session: + # ❌ 단일 세션에서 asyncio.gather() 사용 - 에러 발생! + project_result, lyric_result, song_result, image_result = ( + await asyncio.gather( + session.execute(project_query), + session.execute(lyric_query), + session.execute(song_query), + session.execute(image_query), + ) + ) +``` + +**프론트엔드에서 표시된 에러:** +``` +Method 'close()' can't be called here; method '_connection_for_bind()' +is already in progress and this would cause an unexpected state change +to +``` + +### 3.6 해결 방법 + +#### 방법 1: 순차 실행 (권장 - 단순하고 안전) + +```python +# ✅ 올바른 방법: 순차 실행 +async def generate_video(task_id: str, ...): + async with AsyncSessionLocal() as session: + # 순차적으로 쿼리 실행 (가장 안전) + project_result = await session.execute(project_query) + lyric_result = await session.execute(lyric_query) + song_result = await session.execute(song_query) + image_result = await session.execute(image_query) +``` + +**장점:** +- 구현이 단순함 +- 에러 처리가 명확함 +- 트랜잭션 관리가 쉬움 + +**단점:** +- 총 실행 시간 = 각 쿼리 시간의 합 + +#### 방법 2: 별도 세션으로 병렬 실행 (성능 중요 시) + +```python +# ✅ 올바른 방법: 각 쿼리마다 별도 세션 사용 +async def fetch_with_separate_sessions(task_id: str): + + async def get_project(): + async with AsyncSessionLocal() as session: + result = await session.execute( + select(Project).where(Project.task_id == task_id) + ) + return result.scalar_one_or_none() + + async def get_lyric(): + async with AsyncSessionLocal() as session: + result = await session.execute( + select(Lyric).where(Lyric.task_id == task_id) + ) + return result.scalar_one_or_none() + + async def get_song(): + async with AsyncSessionLocal() as session: + result = await session.execute( + select(Song).where(Song.task_id == task_id) + ) + return result.scalar_one_or_none() + + async def get_images(): + async with AsyncSessionLocal() as session: + result = await session.execute( + select(Image).where(Image.task_id == task_id) + ) + return result.scalars().all() + + # 별도 세션이므로 병렬 실행 가능! + project, lyric, song, images = await asyncio.gather( + get_project(), + get_lyric(), + get_song(), + get_images(), + ) + + return project, lyric, song, images +``` + +**장점:** +- 진정한 병렬 실행 +- 총 실행 시간 = 가장 느린 쿼리 시간 + +**단점:** +- 커넥션 풀에서 여러 연결을 동시에 사용 +- 각 쿼리가 별도 트랜잭션 (일관성 주의) +- 코드가 복잡해짐 + +#### 방법 3: 유틸리티 함수로 추상화 + +```python +from typing import TypeVar, Callable, Any +import asyncio + +T = TypeVar('T') + + +async def parallel_queries( + queries: list[tuple[Callable, dict]], +) -> list[Any]: + """ + 여러 쿼리를 별도 세션으로 병렬 실행합니다. + + Args: + queries: [(query_func, kwargs), ...] 형태의 리스트 + + Returns: + 각 쿼리의 결과 리스트 + + Example: + results = await parallel_queries([ + (get_project, {"task_id": task_id}), + (get_song, {"task_id": task_id}), + ]) + """ + async def execute_with_session(query_func, kwargs): + async with AsyncSessionLocal() as session: + return await query_func(session, **kwargs) + + return await asyncio.gather(*[ + execute_with_session(func, kwargs) + for func, kwargs in queries + ]) + + +# 사용 예시 +async def get_project(session, task_id: str): + result = await session.execute( + select(Project).where(Project.task_id == task_id) + ) + return result.scalar_one_or_none() + + +async def get_song(session, task_id: str): + result = await session.execute( + select(Song).where(Song.task_id == task_id) + ) + return result.scalar_one_or_none() + + +# 병렬 실행 +project, song = await parallel_queries([ + (get_project, {"task_id": "abc123"}), + (get_song, {"task_id": "abc123"}), +]) +``` + +### 3.7 성능 비교: 순차 vs 별도 세션 병렬 + +``` +┌─────────────────────────────────────────────────────────────────────────┐ +│ 성능 비교 (4개 쿼리, 각 50ms) │ +├─────────────────────────────────────────────────────────────────────────┤ +│ │ +│ [순차 실행 - 단일 세션] │ +│ ─────────────────────── │ +│ Query 1 ─────▶ (50ms) │ +│ Query 2 ─────▶ (50ms) │ +│ Query 3 ─────▶ (50ms) │ +│ Query 4 ─────▶ (50ms) │ +│ 총 소요시간: ~200ms │ +│ 커넥션 사용: 1개 │ +│ │ +│ [병렬 실행 - 별도 세션] │ +│ ─────────────────────── │ +│ Session 1: Query 1 ─────▶ (50ms) │ +│ Session 2: Query 2 ─────▶ (50ms) │ +│ Session 3: Query 3 ─────▶ (50ms) │ +│ Session 4: Query 4 ─────▶ (50ms) │ +│ 총 소요시간: ~55ms │ +│ 커넥션 사용: 4개 (동시) │ +│ │ +│ ───────────────────────────────────────────────────────────────────── │ +│ │ +│ 결론: │ +│ - 성능 개선: 약 72% (200ms → 55ms) │ +│ - 대가: 커넥션 풀 사용량 4배 증가 │ +│ - 트레이드오프 고려 필요 │ +│ │ +└─────────────────────────────────────────────────────────────────────────┘ +``` + +### 3.8 언제 병렬 실행을 선택해야 하는가? + +| 상황 | 권장 방식 | 이유 | +|------|----------|------| +| 쿼리 수 ≤ 3개 | 순차 실행 | 복잡도 대비 성능 이득 적음 | +| 쿼리 수 > 3개, 각 쿼리 > 50ms | 병렬 실행 | 유의미한 성능 개선 | +| 트랜잭션 일관성 필요 | 순차 실행 | 별도 세션은 별도 트랜잭션 | +| 커넥션 풀 여유 없음 | 순차 실행 | 풀 고갈 위험 | +| 실시간 응답 중요 (API) | 상황에 따라 | 사용자 경험 우선 | +| 백그라운드 작업 | 순차 실행 | 안정성 우선 | + +### 3.9 커넥션 풀 고려사항 + +```python +# 엔진 설정 시 병렬 쿼리를 고려한 풀 크기 설정 +engine = create_async_engine( + url=db_url, + pool_size=20, # 기본 풀 크기 + max_overflow=20, # 추가 연결 허용 + pool_timeout=30, # 풀 대기 타임아웃 +) + +# 계산 예시: +# - 동시 API 요청: 10개 +# - 요청당 병렬 쿼리: 4개 +# - 필요 커넥션: 10 × 4 = 40개 +# - 설정: pool_size(20) + max_overflow(20) = 40개 ✅ +``` + +--- + +## 4. 설계 시 주의사항 + +### 4.1 커넥션 풀 크기 설정 + +```python +# SQLAlchemy 엔진 설정 +engine = create_async_engine( + url=db_url, + pool_size=20, # 기본 풀 크기 + max_overflow=20, # 추가 연결 허용 수 + pool_timeout=30, # 풀에서 연결 대기 시간 + pool_recycle=3600, # 연결 재생성 주기 + pool_pre_ping=True, # 연결 유효성 검사 +) +``` + +**풀 크기 계산 공식:** +``` +필요 커넥션 수 = 동시 요청 수 × 요청당 병렬 쿼리 수 +``` + +예: 동시 10개 요청, 각 요청당 4개 병렬 쿼리 +→ 최소 40개 커넥션 필요 (pool_size + max_overflow >= 40) + +### 4.2 에러 처리 전략 + +```python +import asyncio + +# 방법 1: return_exceptions=True (권장) +results = await asyncio.gather( + fetch_with_session_1(), + fetch_with_session_2(), + fetch_with_session_3(), + return_exceptions=True, # 예외를 결과로 반환 +) + +# 결과 처리 +for i, result in enumerate(results): + if isinstance(result, Exception): + print(f"Query {i} failed: {result}") + else: + print(f"Query {i} succeeded: {result}") +``` + +```python +# 방법 2: 개별 try-except 래핑 +async def safe_fetch(query_func, **kwargs): + try: + async with AsyncSessionLocal() as session: + return await query_func(session, **kwargs) + except Exception as e: + print(f"Query failed: {e}") + return None + +results = await asyncio.gather( + safe_fetch(get_project, task_id=task_id), + safe_fetch(get_song, task_id=task_id), + safe_fetch(get_images, task_id=task_id), +) +``` + +### 4.3 타임아웃 설정 + +```python +import asyncio + +async def fetch_with_timeout(query_func, timeout_seconds: float, **kwargs): + """타임아웃이 있는 쿼리 실행""" + try: + return await asyncio.wait_for( + query_func(**kwargs), + timeout=timeout_seconds + ) + except asyncio.TimeoutError: + raise Exception(f"Query timed out after {timeout_seconds}s") + +# 사용 예 +results = await asyncio.gather( + fetch_with_timeout(get_project, 5.0, task_id=task_id), + fetch_with_timeout(get_song, 5.0, task_id=task_id), + fetch_with_timeout(get_images, 10.0, task_id=task_id), # 더 긴 타임아웃 +) +``` + +### 4.4 N+1 문제와 병렬화 + +```python +# ❌ N+1 문제 발생 코드 +videos = await session.execute(select(Video)) +for video in videos.scalars(): + # N번의 추가 쿼리 발생! + project = await session.execute( + select(Project).where(Project.id == video.project_id) + ) + +# ✅ 해결 방법 1: JOIN 사용 +query = select(Video).options(selectinload(Video.project)) +videos = await session.execute(query) + +# ✅ 해결 방법 2: IN 절로 배치 조회 +video_list = videos.scalars().all() +project_ids = [v.project_id for v in video_list if v.project_id] + +projects_result = await session.execute( + select(Project).where(Project.id.in_(project_ids)) +) +projects_map = {p.id: p for p in projects_result.scalars().all()} +``` + +### 4.5 트랜잭션 격리 수준 고려 + +| 격리 수준 | 병렬 쿼리 안전성 | 설명 | +|-----------|------------------|------| +| READ UNCOMMITTED | ⚠️ 주의 | Dirty Read 가능 | +| READ COMMITTED | ✅ 안전 | 대부분의 경우 적합 | +| REPEATABLE READ | ✅ 안전 | 일관된 스냅샷 | +| SERIALIZABLE | ✅ 안전 | 성능 저하 가능 | + +--- + +## 5. 실무 시나리오 예제 + +### 5.1 시나리오 1: 대시보드 데이터 조회 (별도 세션 병렬) + +**요구사항**: 사용자 대시보드에 필요한 여러 통계 데이터를 한 번에 조회 + +```python +from sqlalchemy import select, func +from sqlalchemy.ext.asyncio import AsyncSession +import asyncio + + +async def get_user(session: AsyncSession, user_id: int): + result = await session.execute( + select(User).where(User.id == user_id) + ) + return result.scalar_one_or_none() + + +async def get_recent_orders(session: AsyncSession, user_id: int): + result = await session.execute( + select(Order) + .where(Order.user_id == user_id) + .order_by(Order.created_at.desc()) + .limit(5) + ) + return result.scalars().all() + + +async def get_total_amount(session: AsyncSession, user_id: int): + result = await session.execute( + select(func.sum(Order.amount)) + .where(Order.user_id == user_id) + ) + return result.scalar() or 0 + + +async def get_wishlist_count(session: AsyncSession, user_id: int): + result = await session.execute( + select(func.count(Wishlist.id)) + .where(Wishlist.user_id == user_id) + ) + return result.scalar() or 0 + + +async def get_dashboard_data(user_id: int) -> dict: + """ + 대시보드에 필요한 모든 데이터를 병렬로 조회합니다. + 각 쿼리는 별도의 세션을 사용합니다. + """ + + async def fetch_user(): + async with AsyncSessionLocal() as session: + return await get_user(session, user_id) + + async def fetch_orders(): + async with AsyncSessionLocal() as session: + return await get_recent_orders(session, user_id) + + async def fetch_amount(): + async with AsyncSessionLocal() as session: + return await get_total_amount(session, user_id) + + async def fetch_wishlist(): + async with AsyncSessionLocal() as session: + return await get_wishlist_count(session, user_id) + + # 4개 쿼리를 별도 세션으로 병렬 실행 + user, orders, total_amount, wishlist_count = await asyncio.gather( + fetch_user(), + fetch_orders(), + fetch_amount(), + fetch_wishlist(), + ) + + if not user: + raise ValueError(f"User {user_id} not found") + + return { + "user": {"id": user.id, "name": user.name, "email": user.email}, + "recent_orders": [ + {"id": o.id, "amount": o.amount, "status": o.status} + for o in orders + ], + "total_spent": total_amount, + "wishlist_count": wishlist_count, + } + + +# 사용 예시 (FastAPI) +@router.get("/dashboard") +async def dashboard(user_id: int): + return await get_dashboard_data(user_id) +``` + +**성능 비교:** +- 순차 실행: ~200ms (50ms × 4) +- 병렬 실행: ~60ms (가장 느린 쿼리 기준) +- **개선율: 약 70%** + +--- + +### 5.2 시나리오 2: 영상 생성 데이터 조회 (순차 실행 - 권장) + +**요구사항**: 영상 생성을 위해 Project, Lyric, Song, Image 데이터를 조회 + +**본 프로젝트에서 실제로 적용된 패턴입니다.** + +```python +from sqlalchemy import select +from sqlalchemy.ext.asyncio import AsyncSession +from dataclasses import dataclass +from fastapi import HTTPException + + +@dataclass +class VideoGenerationData: + """영상 생성에 필요한 데이터""" + project_id: int + lyric_id: int + song_id: int + music_url: str + song_duration: float + lyrics: str + image_urls: list[str] + + +async def generate_video( + task_id: str, + orientation: str = "vertical", +) -> GenerateVideoResponse: + """ + Creatomate API를 통해 영상을 생성합니다. + + 중요: SQLAlchemy AsyncSession은 단일 세션에서 동시에 여러 쿼리를 실행하는 것을 + 지원하지 않습니다. asyncio.gather()로 병렬 쿼리를 실행하면 세션 상태 충돌이 발생합니다. + 따라서 쿼리는 순차적으로 실행합니다. + """ + from app.database.session import AsyncSessionLocal + + print(f"[generate_video] START - task_id: {task_id}") + + # 외부 API 호출 전에 필요한 데이터를 저장할 변수들 + project_id: int | None = None + lyric_id: int | None = None + song_id: int | None = None + video_id: int | None = None + music_url: str | None = None + song_duration: float | None = None + lyrics: str | None = None + image_urls: list[str] = [] + + try: + # 세션을 명시적으로 열고 DB 작업 후 바로 닫음 + async with AsyncSessionLocal() as session: + # ===== 순차 쿼리 실행: Project, Lyric, Song, Image ===== + # Note: AsyncSession은 동일 세션에서 병렬 쿼리를 지원하지 않음 + + # Project 조회 + project_result = await session.execute( + select(Project) + .where(Project.task_id == task_id) + .order_by(Project.created_at.desc()) + .limit(1) + ) + + # Lyric 조회 + lyric_result = await session.execute( + select(Lyric) + .where(Lyric.task_id == task_id) + .order_by(Lyric.created_at.desc()) + .limit(1) + ) + + # Song 조회 + song_result = await session.execute( + select(Song) + .where(Song.task_id == task_id) + .order_by(Song.created_at.desc()) + .limit(1) + ) + + # Image 조회 + image_result = await session.execute( + select(Image) + .where(Image.task_id == task_id) + .order_by(Image.img_order.asc()) + ) + + print(f"[generate_video] Queries completed - task_id: {task_id}") + + # 결과 처리 및 검증 + project = project_result.scalar_one_or_none() + if not project: + raise HTTPException(status_code=404, detail="Project not found") + project_id = project.id + + lyric = lyric_result.scalar_one_or_none() + if not lyric: + raise HTTPException(status_code=404, detail="Lyric not found") + lyric_id = lyric.id + + song = song_result.scalar_one_or_none() + if not song: + raise HTTPException(status_code=404, detail="Song not found") + song_id = song.id + music_url = song.song_result_url + song_duration = song.duration + lyrics = song.song_prompt + + images = image_result.scalars().all() + if not images: + raise HTTPException(status_code=404, detail="Images not found") + image_urls = [img.img_url for img in images] + + # Video 레코드 생성 및 커밋 + video = Video( + project_id=project_id, + lyric_id=lyric_id, + song_id=song_id, + task_id=task_id, + status="processing", + ) + session.add(video) + await session.commit() + video_id = video.id + + # 세션 종료 후 외부 API 호출 (커넥션 타임아웃 방지) + # ... Creatomate API 호출 로직 ... + + except HTTPException: + raise + except Exception as e: + print(f"[generate_video] EXCEPTION - {e}") + raise +``` + +**이 패턴을 선택한 이유:** +1. **안정성**: 단일 세션 내에서 모든 쿼리 실행으로 트랜잭션 일관성 보장 +2. **단순성**: 코드가 명확하고 디버깅이 쉬움 +3. **충분한 성능**: 4개의 간단한 쿼리는 순차 실행해도 ~200ms 이내 +4. **에러 방지**: AsyncSession 병렬 쿼리 제한으로 인한 에러 방지 + +--- + +### 5.3 시나리오 3: 복합 검색 (트레이드오프 분석) + +```python +# 방법 A: 순차 실행 (단순, 안전) +async def search_sequential(session: AsyncSession, keyword: str): + items = await session.execute(items_query) + count = await session.execute(count_query) + categories = await session.execute(category_query) + price_range = await session.execute(price_query) + brands = await session.execute(brand_query) + return items, count, categories, price_range, brands +# 예상 시간: ~350ms (70ms × 5) + + +# 방법 B: 별도 세션 병렬 실행 (빠름, 복잡) +async def search_parallel(keyword: str): + async def fetch_items(): + async with AsyncSessionLocal() as s: + return await s.execute(items_query) + + async def fetch_count(): + async with AsyncSessionLocal() as s: + return await s.execute(count_query) + + # ... 나머지 함수들 ... + + return await asyncio.gather( + fetch_items(), + fetch_count(), + fetch_categories(), + fetch_price_range(), + fetch_brands(), + ) +# 예상 시간: ~80ms + + +# 결정 기준: +# - 검색 API가 자주 호출되고 응답 시간이 중요하다면 → 방법 B +# - 안정성이 우선이고 복잡도를 낮추고 싶다면 → 방법 A +# - 커넥션 풀 여유가 없다면 → 방법 A +``` + +--- + +## 6. 성능 측정 및 모니터링 + +### 6.1 실행 시간 측정 데코레이터 + +```python +import time +import functools +import asyncio +from typing import Callable, TypeVar + +T = TypeVar("T") + + +def measure_time(func: Callable[..., T]) -> Callable[..., T]: + """함수 실행 시간을 측정하는 데코레이터""" + + @functools.wraps(func) + async def async_wrapper(*args, **kwargs): + start = time.perf_counter() + try: + return await func(*args, **kwargs) + finally: + elapsed = (time.perf_counter() - start) * 1000 + print(f"[{func.__name__}] Execution time: {elapsed:.2f}ms") + + @functools.wraps(func) + def sync_wrapper(*args, **kwargs): + start = time.perf_counter() + try: + return func(*args, **kwargs) + finally: + elapsed = (time.perf_counter() - start) * 1000 + print(f"[{func.__name__}] Execution time: {elapsed:.2f}ms") + + if asyncio.iscoroutinefunction(func): + return async_wrapper + return sync_wrapper + + +# 사용 예 +@measure_time +async def fetch_data(task_id: str): + ... +``` + +### 6.2 병렬 vs 순차 성능 비교 유틸리티 + +```python +import asyncio +import time + + +async def compare_execution_methods( + task_id: str, + query_funcs: list[Callable], +) -> dict: + """순차 실행과 병렬 실행(별도 세션)의 성능을 비교합니다.""" + + # 순차 실행 (단일 세션) + sequential_start = time.perf_counter() + async with AsyncSessionLocal() as session: + sequential_results = [] + for func in query_funcs: + result = await func(session, task_id) + sequential_results.append(result) + sequential_time = (time.perf_counter() - sequential_start) * 1000 + + # 병렬 실행 (별도 세션) + parallel_start = time.perf_counter() + + async def run_with_session(func): + async with AsyncSessionLocal() as session: + return await func(session, task_id) + + parallel_results = await asyncio.gather(*[ + run_with_session(func) for func in query_funcs + ]) + parallel_time = (time.perf_counter() - parallel_start) * 1000 + + improvement = ((sequential_time - parallel_time) / sequential_time) * 100 + + return { + "sequential_time_ms": round(sequential_time, 2), + "parallel_time_ms": round(parallel_time, 2), + "improvement_percent": round(improvement, 1), + "query_count": len(query_funcs), + } +``` + +### 6.3 SQLAlchemy 쿼리 로깅 + +```python +import logging + +# SQLAlchemy 쿼리 로깅 활성화 +logging.basicConfig() +logging.getLogger("sqlalchemy.engine").setLevel(logging.INFO) + +# 또는 엔진 생성 시 echo=True +engine = create_async_engine(url, echo=True) +``` + +--- + +## 7. Best Practices + +### 7.1 체크리스트 + +병렬화 적용 전 확인사항: + +- [ ] 쿼리들이 서로 독립적인가? (결과 의존성 없음) +- [ ] 모든 쿼리가 READ 작업인가? (또는 순서 무관한 WRITE) +- [ ] **별도 세션을 사용할 것인가?** (AsyncSession 제한사항) +- [ ] 커넥션 풀 크기가 충분한가? +- [ ] 에러 처리 전략이 수립되어 있는가? +- [ ] 타임아웃 설정이 적절한가? +- [ ] 트랜잭션 일관성이 필요한가? + +### 7.2 권장 패턴 + +```python +# ✅ 패턴 1: 순차 실행 (단순하고 안전) +async def fetch_data(session: AsyncSession, task_id: str): + project = await session.execute(project_query) + song = await session.execute(song_query) + return project, song + + +# ✅ 패턴 2: 별도 세션으로 병렬 실행 (성능 중요 시) +async def fetch_data_parallel(task_id: str): + async def get_project(): + async with AsyncSessionLocal() as s: + return await s.execute(project_query) + + async def get_song(): + async with AsyncSessionLocal() as s: + return await s.execute(song_query) + + return await asyncio.gather(get_project(), get_song()) +``` + +### 7.3 피해야 할 패턴 + +```python +# ❌ 절대 금지: 단일 세션에서 asyncio.gather() +async with AsyncSessionLocal() as session: + results = await asyncio.gather( + session.execute(query1), + session.execute(query2), + ) +# 에러 발생: InvalidRequestError - Method 'close()' can't be called here + +# ❌ 피하기: 과도한 병렬화 (커넥션 고갈) +# 100개 쿼리를 동시에 실행하면 커넥션 풀 고갈 위험 +results = await asyncio.gather(*[fetch() for _ in range(100)]) + +# ✅ 해결: 배치 처리 +BATCH_SIZE = 10 +for i in range(0, len(items), BATCH_SIZE): + batch = items[i:i + BATCH_SIZE] + results = await asyncio.gather(*[fetch(item) for item in batch]) +``` + +### 7.4 결정 가이드 + +``` +┌─────────────────────────────────────────────────────────────────────────┐ +│ 병렬화 결정 플로우차트 │ +├─────────────────────────────────────────────────────────────────────────┤ +│ │ +│ 쿼리 개수가 3개 이하인가? │ +│ │ │ +│ ├── Yes ──► 순차 실행 (복잡도 대비 이득 적음) │ +│ │ │ +│ └── No ──► 각 쿼리가 50ms 이상 걸리는가? │ +│ │ │ +│ ├── No ──► 순차 실행 (이득 적음) │ +│ │ │ +│ └── Yes ──► 트랜잭션 일관성이 필요한가? │ +│ │ │ +│ ├── Yes ──► 순차 실행 │ +│ │ (단일 세션) │ +│ │ │ +│ └── No ──► 커넥션 풀 여유? │ +│ │ │ +│ ├── No ──► │ +│ │ 순차 실행 │ +│ │ │ +│ └── Yes ──► │ +│ 병렬 실행 │ +│ (별도세션) │ +│ │ +└─────────────────────────────────────────────────────────────────────────┘ +``` + +### 7.5 성능 최적화 팁 + +1. **인덱스 확인**: 병렬화해도 인덱스 없으면 느림 +2. **쿼리 최적화 우선**: 병렬화 전에 개별 쿼리 최적화 +3. **적절한 병렬 수준**: 보통 3-10개가 적절 +4. **모니터링 필수**: 실제 개선 효과 측정 +5. **커넥션 풀 모니터링**: 병렬 실행 시 풀 사용량 확인 + +--- + +## 부록: 관련 자료 + +- [SQLAlchemy 2.0 AsyncIO 문서](https://docs.sqlalchemy.org/en/20/orm/extensions/asyncio.html) +- [SQLAlchemy AsyncSession 동시성 제한](https://docs.sqlalchemy.org/en/20/orm/extensions/asyncio.html#using-asyncio-scoped-session) +- [Python asyncio 공식 문서](https://docs.python.org/3/library/asyncio.html) +- [FastAPI 비동기 데이터베이스](https://fastapi.tiangolo.com/async/) + +--- + +## 변경 이력 + +| 날짜 | 변경 내용 | +|------|----------| +| 2024-12 | AsyncSession 병렬 쿼리 제한사항 섹션 추가 (실제 프로젝트 에러 사례 포함) | +| 2024-12 | 잘못된 병렬 쿼리 예제 수정 | +| 2024-12 | 결정 플로우차트 추가 | diff --git a/docs/analysis/lang_report.md b/docs/analysis/lang_report.md index 431f9ae..ab12a45 100644 --- a/docs/analysis/lang_report.md +++ b/docs/analysis/lang_report.md @@ -1,1705 +1,1705 @@ -# CastAD 백엔드 - LangChain, LangGraph, RAG 적용 설계 보고서 - -## 목차 -1. [현재 시스템 분석](#1-현재-시스템-분석) -2. [LangChain 적용 설계](#2-langchain-적용-설계) -3. [LangGraph 적용 설계](#3-langgraph-적용-설계) -4. [RAG 적용 설계](#4-rag-적용-설계) -5. [통합 아키텍처](#5-통합-아키텍처) -6. [기대 효과](#6-기대-효과) -7. [구현 로드맵](#7-구현-로드맵) -8. [결론](#8-결론) - ---- - -## 1. 현재 시스템 분석 - -### 1.1 프로젝트 개요 - -CastAD는 **AI 기반 광고 음악 및 영상 자동 생성 서비스**입니다. 네이버 지도에서 수집한 숙박시설 정보를 기반으로 마케팅용 자동 영상을 생성하는 통합 플랫폼입니다. - -**핵심 파이프라인:** -``` -사용자 입력 → 가사 자동 생성 → 음악 자동 생성 → 영상 자동 생성 -``` - -### 1.2 현재 기술 스택 - -| 구분 | 기술 | -|------|------| -| Backend Framework | FastAPI (async/await 기반) | -| ORM | SQLAlchemy 2.0 (비동기) | -| Database | MySQL (asyncmy 드라이버) | -| Cache | Redis | -| AI/API | OpenAI ChatGPT, Suno AI, Creatomate | -| Storage | Azure Blob Storage | - -### 1.3 현재 핵심 흐름 - -``` -┌─────────────────────────────────────────────────────────────────┐ -│ 현재 파이프라인 구조 │ -├─────────────────────────────────────────────────────────────────┤ -│ │ -│ POST /crawling (선택) │ -│ │ │ -│ ▼ │ -│ POST /lyric/generate ──────► ChatGPT API ──────► 가사 저장 │ -│ │ │ -│ ▼ │ -│ POST /song/generate ───────► Suno API ─────────► 음악 저장 │ -│ │ │ │ -│ │ 클라이언트 폴링 │ -│ │ │ │ -│ ▼ ▼ │ -│ POST /video/generate ──────► Creatomate API ───► 영상 저장 │ -│ │ │ │ -│ │ 클라이언트 폴링 │ -│ ▼ ▼ │ -│ GET /video/download ◄──────── 완료 ──────────► Azure Blob │ -│ │ -└─────────────────────────────────────────────────────────────────┘ -``` - -### 1.4 현재 시스템의 한계점 - -| 문제점 | 설명 | -|--------|------| -| **분산된 상태 관리** | 각 API 호출마다 독립적인 상태 관리, 전체 파이프라인 추적 어려움 | -| **클라이언트 의존적 폴링** | 음악/영상 생성 완료 여부를 클라이언트가 반복 확인해야 함 | -| **하드코딩된 프롬프트** | ChatGPT 프롬프트가 코드에 직접 작성, 유연성 부족 | -| **에러 복구 제한적** | 단순 실패 패턴 검사만 수행, 자동 복구 메커니즘 없음 | -| **과거 데이터 미활용** | 성공한 가사/마케팅 사례 재활용 불가 | -| **일관성 없는 품질** | 동일 조건에서도 결과물 품질 편차 존재 | - ---- - -## 2. LangChain 적용 설계 - -### 2.1 적용 대상 및 목적 - -LangChain은 **LLM 애플리케이션 개발을 위한 프레임워크**로, 프롬프트 관리, 체인 구성, 출력 파싱 등을 체계화합니다. - -**적용 대상:** -1. 가사 생성 서비스 (`ChatgptService`) -2. 마케팅 분석 서비스 -3. 다국어 처리 로직 - -### 2.2 설계 1: 프롬프트 템플릿 시스템 - -**현재 문제:** -```python -# 현재: chatgpt_prompt.py -prompt = f""" -[ROLE] You are a marketing expert... -[INPUT] Customer: {customer_name}, Region: {region}... -""" -``` - -**개선 설계:** -```python -# 개선: langchain 적용 -from langchain.prompts import PromptTemplate, ChatPromptTemplate -from langchain_openai import ChatOpenAI - -# 가사 생성 프롬프트 템플릿 -LYRIC_PROMPT = ChatPromptTemplate.from_messages([ - ("system", """[ROLE] You are a marketing expert and professional lyricist. -You specialize in creating catchy, emotional lyrics for travel and accommodation marketing. - -[LANGUAGE REQUIREMENT] -Output MUST be 100% in {language}. No other languages allowed."""), - - ("human", """[INPUT] -Customer Name: {customer_name} -Region: {region} -Detailed Information: {detail_info} - -[OUTPUT REQUIREMENTS] -- 8-12 lines of lyrics -- Focus on: relaxation, healing, beautiful scenery, memorable experiences -- Style: warm, inviting, poetic -- Include location-specific imagery - -Generate lyrics now:""") -]) - -# 체인 구성 -lyric_chain = LYRIC_PROMPT | ChatOpenAI(model="gpt-4o-mini") | StrOutputParser() - -# 사용 -result = await lyric_chain.ainvoke({ - "customer_name": "스테이뫰", - "region": "강원도 속초", - "detail_info": "해변 근처 펜션", - "language": "Korean" -}) -``` - -**이점:** -- 프롬프트 버전 관리 용이 -- A/B 테스팅 지원 -- 입력 변수 명확한 정의 - -### 2.3 설계 2: 다단계 마케팅 분석 체인 - -**목적:** 복잡한 마케팅 분석을 단계별로 수행하여 품질 향상 - -```python -from langchain.chains import SequentialChain -from langchain.prompts import PromptTemplate -from langchain_openai import ChatOpenAI - -# Step 1: 경쟁사 분석 체인 -competitor_prompt = PromptTemplate( - input_variables=["region", "business_type"], - template=""" - {region} 지역의 {business_type} 업종에 대해 분석하세요: - - 주요 경쟁사 특성 - - 차별화 포인트 - - 시장 포지셔닝 - """ -) -competitor_chain = competitor_prompt | ChatOpenAI() | StrOutputParser() - -# Step 2: 타겟 고객 분석 체인 -audience_prompt = PromptTemplate( - input_variables=["region", "competitor_analysis"], - template=""" - 경쟁사 분석 결과: {competitor_analysis} - - {region} 지역의 주요 타겟 고객층을 분석하세요: - - 연령대 및 특성 - - 주요 니즈 - - 결정 요인 - """ -) -audience_chain = audience_prompt | ChatOpenAI() | StrOutputParser() - -# Step 3: 마케팅 전략 종합 체인 -strategy_prompt = PromptTemplate( - input_variables=["customer_name", "competitor_analysis", "audience_analysis"], - template=""" - 경쟁사 분석: {competitor_analysis} - 타겟 고객: {audience_analysis} - - {customer_name}을 위한 마케팅 전략을 제안하세요: - - 핵심 메시지 - - 차별화 전략 - - 추천 가사 방향 - """ -) -strategy_chain = strategy_prompt | ChatOpenAI() | StrOutputParser() - -# 통합 순차 체인 -marketing_analysis_chain = ( - {"region": RunnablePassthrough(), "business_type": RunnablePassthrough()} - | competitor_chain - | {"competitor_analysis": RunnablePassthrough(), "region": RunnablePassthrough()} - | audience_chain - | {"competitor_analysis": ..., "audience_analysis": RunnablePassthrough(), "customer_name": ...} - | strategy_chain -) -``` - -**이점:** -- 분석의 깊이와 체계성 향상 -- 각 단계별 결과 추적 가능 -- 중간 결과 캐싱 가능 - -### 2.4 설계 3: 출력 파싱 및 검증 - -**목적:** ChatGPT 응답의 구조화 및 자동 검증 - -```python -from langchain.output_parsers import PydanticOutputParser -from langchain_core.output_parsers import OutputFixingParser -from pydantic import BaseModel, Field, validator - -# 가사 출력 스키마 -class LyricOutput(BaseModel): - title: str = Field(description="가사의 제목 (선택)") - lyrics: list[str] = Field(description="가사 각 줄", min_items=8, max_items=12) - mood: str = Field(description="가사의 분위기: warm, energetic, romantic 등") - - @validator('lyrics') - def validate_line_count(cls, v): - if len(v) < 8: - raise ValueError("가사는 최소 8줄 이상이어야 합니다") - return v - -# 파서 생성 -parser = PydanticOutputParser(pydantic_object=LyricOutput) - -# 자동 수정 파서 (파싱 실패 시 LLM으로 재시도) -fixing_parser = OutputFixingParser.from_llm( - parser=parser, - llm=ChatOpenAI(model="gpt-4o-mini") -) - -# 프롬프트에 포맷 지시 추가 -prompt_with_format = LYRIC_PROMPT.partial( - format_instructions=parser.get_format_instructions() -) -``` - -**이점:** -- 응답 형식 일관성 보장 -- 자동 오류 복구 -- 타입 안전성 확보 - -### 2.5 설계 4: Few-Shot 다국어 프롬프트 - -**목적:** 각 언어별 고품질 예시 제공으로 번역/생성 품질 향상 - -```python -from langchain.prompts import FewShotPromptTemplate, PromptTemplate - -# 언어별 예시 -LANGUAGE_EXAMPLES = { - "Korean": [ - { - "input": "강원도 속초 해변 펜션", - "output": """푸른 바다 물결 위에 -새벽빛이 춤을 추고 -당신의 하루를 담아 -스테이뫰에서 쉬어가요""" - } - ], - "English": [ - { - "input": "Sokcho beach pension, Gangwon-do", - "output": """Where ocean waves meet morning light -A peaceful haven comes in sight -Let your worries drift away -At Stay Meoum, find your stay""" - } - ], - "Japanese": [ - { - "input": "江原道束草ビーチペンション", - "output": """青い海の波の上に -朝の光が踊る時 -あなたの一日を包み込む -ステイメウムで休んでいこう""" - } - ], - "Chinese": [...], - "Thai": [...], - "Vietnamese": [...] -} - -# Few-Shot 프롬프트 생성 -def create_multilingual_prompt(language: str): - example_prompt = PromptTemplate( - input_variables=["input", "output"], - template="입력: {input}\n가사:\n{output}" - ) - - return FewShotPromptTemplate( - examples=LANGUAGE_EXAMPLES.get(language, LANGUAGE_EXAMPLES["Korean"]), - example_prompt=example_prompt, - prefix="다음 예시를 참고하여 고품질 가사를 생성하세요:", - suffix="입력: {customer_info}\n가사:", - input_variables=["customer_info"] - ) -``` - -**이점:** -- 언어별 문화적 뉘앙스 반영 -- 일관된 스타일 유지 -- 번역 품질 대폭 향상 - ---- - -## 3. LangGraph 적용 설계 - -### 3.1 적용 대상 및 목적 - -LangGraph는 **복잡한 다단계 워크플로우를 상태 기계(State Machine)로 관리**하는 프레임워크입니다. - -**적용 대상:** -1. 전체 영상 생성 파이프라인 (가사 → 음악 → 영상) -2. 비동기 폴링 자동화 -3. 에러 처리 및 재시도 로직 - -### 3.2 설계 1: 통합 파이프라인 그래프 - -**핵심 설계:** - -```python -from langgraph.graph import StateGraph, END -from typing import TypedDict, Optional, Literal -from datetime import datetime - -# 파이프라인 상태 정의 -class PipelineState(TypedDict): - # 입력 - task_id: str - customer_name: str - region: str - detail_info: str - language: str - images: list[str] - orientation: Literal["vertical", "horizontal"] - - # 중간 결과 - lyric: Optional[str] - lyric_status: Optional[str] - - song_url: Optional[str] - song_task_id: Optional[str] - song_status: Optional[str] - song_duration: Optional[float] - - video_url: Optional[str] - video_render_id: Optional[str] - video_status: Optional[str] - - # 메타데이터 - error: Optional[str] - error_step: Optional[str] - started_at: datetime - completed_at: Optional[datetime] - retry_count: int - -# 그래프 빌더 -def build_video_pipeline() -> StateGraph: - graph = StateGraph(PipelineState) - - # ===== 노드 정의 ===== - - # 1. 가사 생성 노드 - async def generate_lyric(state: PipelineState) -> PipelineState: - """ChatGPT로 가사 생성 (동기)""" - try: - lyric_chain = create_lyric_chain() # LangChain 체인 - lyric = await lyric_chain.ainvoke({ - "customer_name": state["customer_name"], - "region": state["region"], - "detail_info": state["detail_info"], - "language": state["language"] - }) - - # DB 저장 - await save_lyric_to_db(state["task_id"], lyric) - - return { - **state, - "lyric": lyric, - "lyric_status": "completed" - } - except Exception as e: - return { - **state, - "error": str(e), - "error_step": "lyric_generation", - "lyric_status": "failed" - } - - # 2. 음악 생성 요청 노드 - async def request_song(state: PipelineState) -> PipelineState: - """Suno API에 음악 생성 요청""" - try: - suno = SunoAPIClient() - task_id = await suno.generate( - prompt=state["lyric"], - genre="K-Pop, Emotional" - ) - - # DB 저장 - await save_song_request_to_db(state["task_id"], task_id) - - return { - **state, - "song_task_id": task_id, - "song_status": "processing" - } - except Exception as e: - return { - **state, - "error": str(e), - "error_step": "song_request", - "song_status": "failed" - } - - # 3. 음악 폴링 노드 - async def poll_song_status(state: PipelineState) -> PipelineState: - """Suno 상태 폴링 (최대 5분)""" - suno = SunoAPIClient() - max_attempts = 60 # 5초 간격 × 60 = 5분 - - for attempt in range(max_attempts): - result = await suno.get_task_status(state["song_task_id"]) - - if result["status"] == "SUCCESS": - audio_url = result["clips"][0]["audio_url"] - duration = result["clips"][0]["duration"] - - # DB 업데이트 - await update_song_status( - state["task_id"], - "completed", - audio_url, - duration - ) - - return { - **state, - "song_url": audio_url, - "song_duration": duration, - "song_status": "completed" - } - elif result["status"] == "FAILED": - return { - **state, - "error": "Suno generation failed", - "error_step": "song_polling", - "song_status": "failed" - } - - await asyncio.sleep(5) # 5초 대기 - - return { - **state, - "error": "Song generation timeout", - "error_step": "song_polling", - "song_status": "timeout" - } - - # 4. 영상 생성 요청 노드 - async def request_video(state: PipelineState) -> PipelineState: - """Creatomate API에 영상 렌더링 요청""" - try: - creatomate = CreatomateClient() - render_id = await creatomate.render( - images=state["images"], - music_url=state["song_url"], - lyrics=state["lyric"], - duration=state["song_duration"], - orientation=state["orientation"] - ) - - # DB 저장 - await save_video_request_to_db(state["task_id"], render_id) - - return { - **state, - "video_render_id": render_id, - "video_status": "processing" - } - except Exception as e: - return { - **state, - "error": str(e), - "error_step": "video_request", - "video_status": "failed" - } - - # 5. 영상 폴링 노드 - async def poll_video_status(state: PipelineState) -> PipelineState: - """Creatomate 상태 폴링 (최대 10분)""" - creatomate = CreatomateClient() - max_attempts = 120 # 5초 간격 × 120 = 10분 - - for attempt in range(max_attempts): - result = await creatomate.get_render_status(state["video_render_id"]) - - if result["status"] == "succeeded": - video_url = result["url"] - - # Azure Blob 업로드 - blob_url = await upload_to_azure(video_url, state["task_id"]) - - # DB 업데이트 - await update_video_status(state["task_id"], "completed", blob_url) - - return { - **state, - "video_url": blob_url, - "video_status": "completed", - "completed_at": datetime.now() - } - elif result["status"] == "failed": - return { - **state, - "error": "Creatomate rendering failed", - "error_step": "video_polling", - "video_status": "failed" - } - - await asyncio.sleep(5) - - return { - **state, - "error": "Video generation timeout", - "error_step": "video_polling", - "video_status": "timeout" - } - - # 6. 에러 처리 노드 - async def handle_error(state: PipelineState) -> PipelineState: - """에러 로깅 및 알림""" - await log_pipeline_error( - task_id=state["task_id"], - error=state["error"], - step=state["error_step"] - ) - - # 선택: 슬랙/이메일 알림 - await send_error_notification(state) - - return state - - # ===== 노드 추가 ===== - graph.add_node("generate_lyric", generate_lyric) - graph.add_node("request_song", request_song) - graph.add_node("poll_song", poll_song_status) - graph.add_node("request_video", request_video) - graph.add_node("poll_video", poll_video_status) - graph.add_node("handle_error", handle_error) - - # ===== 엣지 정의 ===== - - # 시작점 - graph.set_entry_point("generate_lyric") - - # 조건부 분기: 가사 생성 후 - def route_after_lyric(state: PipelineState): - if state.get("error"): - return "handle_error" - return "request_song" - - graph.add_conditional_edges( - "generate_lyric", - route_after_lyric, - { - "request_song": "request_song", - "handle_error": "handle_error" - } - ) - - # 조건부 분기: 음악 요청 후 - def route_after_song_request(state: PipelineState): - if state.get("error"): - return "handle_error" - return "poll_song" - - graph.add_conditional_edges( - "request_song", - route_after_song_request - ) - - # 조건부 분기: 음악 폴링 후 - def route_after_song_poll(state: PipelineState): - if state.get("error") or state["song_status"] in ["failed", "timeout"]: - return "handle_error" - return "request_video" - - graph.add_conditional_edges( - "poll_song", - route_after_song_poll - ) - - # 조건부 분기: 영상 요청 후 - graph.add_conditional_edges( - "request_video", - lambda s: "handle_error" if s.get("error") else "poll_video" - ) - - # 조건부 분기: 영상 폴링 후 - graph.add_conditional_edges( - "poll_video", - lambda s: "handle_error" if s.get("error") else END - ) - - # 에러 핸들러는 항상 종료 - graph.add_edge("handle_error", END) - - return graph.compile() -``` - -**그래프 시각화:** - -``` - ┌─────────────────┐ - │ generate_lyric │ - └────────┬────────┘ - │ - ┌────────▼────────┐ - ┌─────┤ route check ├─────┐ - │ └─────────────────┘ │ - [error] [success] - │ │ - ▼ ▼ - ┌─────────────────┐ ┌─────────────────┐ - │ handle_error │ │ request_song │ - └────────┬────────┘ └────────┬────────┘ - │ │ - ▼ ▼ - END ┌─────────────────┐ - │ poll_song │ - └────────┬────────┘ - │ - ┌────────▼────────┐ - ┌─────┤ route check ├─────┐ - │ └─────────────────┘ │ - [error/timeout] [success] - │ │ - ▼ ▼ - ┌─────────────────┐ ┌─────────────────┐ - │ handle_error │ │ request_video │ - └────────┬────────┘ └────────┬────────┘ - │ │ - ▼ ▼ - END ┌─────────────────┐ - │ poll_video │ - └────────┬────────┘ - │ - ┌────────▼────────┐ - ┌─────┤ route check ├─────┐ - │ └─────────────────┘ │ - [error] [success] - │ │ - ▼ ▼ - ┌─────────────────┐ END - │ handle_error │ (파이프라인 완료) - └────────┬────────┘ - │ - ▼ - END -``` - -### 3.3 설계 2: 재시도 및 폴백 메커니즘 - -```python -from langgraph.graph import StateGraph - -class RetryState(TypedDict): - task_id: str - retry_count: int - max_retries: int - last_error: Optional[str] - # ... 기타 필드 - -def build_retry_aware_pipeline(): - graph = StateGraph(RetryState) - - async def generate_song_with_retry(state: RetryState) -> RetryState: - """재시도 로직이 포함된 음악 생성""" - try: - # 1차 시도: Suno API - result = await suno_generate(state["lyric"]) - return {**state, "song_url": result, "retry_count": 0} - - except SunoRateLimitError: - # 재시도 1: 딜레이 후 재시도 - if state["retry_count"] < state["max_retries"]: - await asyncio.sleep(30) # 30초 대기 - return { - **state, - "retry_count": state["retry_count"] + 1, - "last_error": "rate_limit" - } - - except SunoAPIError as e: - # 재시도 2: 프롬프트 수정 후 재시도 - if "invalid lyrics" in str(e) and state["retry_count"] < 2: - simplified_lyric = await simplify_lyrics(state["lyric"]) - return { - **state, - "lyric": simplified_lyric, - "retry_count": state["retry_count"] + 1 - } - - # 폴백: 대체 서비스 사용 - try: - result = await alternative_music_service(state["lyric"]) - return {**state, "song_url": result, "used_fallback": True} - except: - pass - - return { - **state, - "error": "All music generation attempts failed", - "song_status": "failed" - } - - # 조건부 재시도 엣지 - def should_retry_song(state: RetryState): - if state.get("song_url"): - return "next_step" - if state["retry_count"] < state["max_retries"]: - return "retry_song" - return "handle_error" - - graph.add_conditional_edges( - "generate_song", - should_retry_song, - { - "retry_song": "generate_song", # 자기 자신으로 루프 - "next_step": "request_video", - "handle_error": "handle_error" - } - ) - - return graph.compile() -``` - -### 3.4 설계 3: 병렬 처리 지원 - -```python -from langgraph.types import Send -from langgraph.graph import StateGraph - -class ParallelState(TypedDict): - task_id: str - images: list[str] - analyzed_images: list[dict] # 병렬 분석 결과 - # ... - -def build_parallel_pipeline(): - graph = StateGraph(ParallelState) - - # 이미지 분석을 병렬로 수행 - async def analyze_single_image(state: dict) -> dict: - """단일 이미지 분석""" - image_url = state["image_url"] - analysis = await vision_model.analyze(image_url) - return { - "image_url": image_url, - "analysis": analysis, - "mood": analysis.get("mood"), - "colors": analysis.get("dominant_colors") - } - - # 팬아웃: 여러 이미지를 병렬로 분석 - def fanout_images(state: ParallelState): - return [ - Send("analyze_image", {"image_url": img, "task_id": state["task_id"]}) - for img in state["images"] - ] - - # 팬인: 분석 결과 수집 - async def collect_analyses(state: ParallelState) -> ParallelState: - # LangGraph가 자동으로 병렬 결과를 수집 - return state - - graph.add_node("analyze_image", analyze_single_image) - graph.add_node("collect", collect_analyses) - - graph.add_conditional_edges( - "start", - fanout_images # 여러 Send 반환 → 병렬 실행 - ) - - return graph.compile() -``` - -### 3.5 FastAPI 통합 - -```python -# main.py 또는 video/api/routers/v1/video.py - -from fastapi import APIRouter, BackgroundTasks -from langgraph.graph import StateGraph - -router = APIRouter() -pipeline = build_video_pipeline() - -@router.post("/video/generate-full") -async def generate_full_video( - request: FullVideoRequest, - background_tasks: BackgroundTasks -): - """단일 API 호출로 전체 파이프라인 실행""" - - initial_state: PipelineState = { - "task_id": str(uuid7()), - "customer_name": request.customer_name, - "region": request.region, - "detail_info": request.detail_info, - "language": request.language, - "images": request.images, - "orientation": request.orientation, - "lyric": None, - "lyric_status": None, - "song_url": None, - "song_task_id": None, - "song_status": None, - "song_duration": None, - "video_url": None, - "video_render_id": None, - "video_status": None, - "error": None, - "error_step": None, - "started_at": datetime.now(), - "completed_at": None, - "retry_count": 0 - } - - # 백그라운드에서 파이프라인 실행 - background_tasks.add_task(run_pipeline_async, initial_state) - - return { - "task_id": initial_state["task_id"], - "status": "processing", - "message": "Pipeline started. Use GET /video/pipeline-status/{task_id} to check progress." - } - -async def run_pipeline_async(initial_state: PipelineState): - """백그라운드에서 LangGraph 파이프라인 실행""" - try: - final_state = await pipeline.ainvoke(initial_state) - - # 결과 DB 저장 - await save_pipeline_result(final_state) - - # 완료 알림 (웹훅, 이메일 등) - if final_state.get("video_url"): - await send_completion_notification(final_state) - - except Exception as e: - await log_pipeline_error(initial_state["task_id"], str(e)) - -@router.get("/video/pipeline-status/{task_id}") -async def get_pipeline_status(task_id: str): - """파이프라인 진행 상태 조회""" - status = await get_status_from_db(task_id) - - return { - "task_id": task_id, - "lyric_status": status.lyric_status, - "song_status": status.song_status, - "video_status": status.video_status, - "overall_status": determine_overall_status(status), - "video_url": status.video_url if status.video_status == "completed" else None, - "error": status.error - } -``` - ---- - -## 4. RAG 적용 설계 - -### 4.1 적용 대상 및 목적 - -RAG(Retrieval-Augmented Generation)는 **외부 지식 기반을 검색하여 LLM 응답 품질을 향상**시키는 기법입니다. - -**적용 대상:** -1. 마케팅 지식베이스 (성공 사례) -2. 지역별/업종별 가사 예시 -3. 이미지 메타데이터 활용 -4. 프롬프트 최적화 - -### 4.2 설계 1: 마케팅 지식베이스 RAG - -**아키텍처:** - -``` -┌─────────────────────────────────────────────────────────────┐ -│ 마케팅 지식베이스 │ -├─────────────────────────────────────────────────────────────┤ -│ │ -│ Document Store (벡터 DB) │ -│ ┌─────────────────────────────────────────────────────┐ │ -│ │ Collection: marketing_knowledge │ │ -│ │ │ │ -│ │ ┌──────────────────────────────────────────────┐ │ │ -│ │ │ 문서 1: 강원도 속초 펜션 마케팅 성공 사례 │ │ │ -│ │ │ - 가사 예시 │ │ │ -│ │ │ - 타겟 고객 분석 │ │ │ -│ │ │ - 효과적인 키워드 │ │ │ -│ │ │ - 영상 조회수/반응 │ │ │ -│ │ └──────────────────────────────────────────────┘ │ │ -│ │ │ │ -│ │ ┌──────────────────────────────────────────────┐ │ │ -│ │ │ 문서 2: 제주도 게스트하우스 마케팅 사례 │ │ │ -│ │ │ ... │ │ │ -│ │ └──────────────────────────────────────────────┘ │ │ -│ │ │ │ -│ │ ... (수백 개의 사례) │ │ -│ └─────────────────────────────────────────────────────┘ │ -│ │ -└─────────────────────────────────────────────────────────────┘ - │ - │ 유사도 검색 - ▼ -┌─────────────────────────────────────────────────────────────┐ -│ 가사 생성 프롬프트 │ -├─────────────────────────────────────────────────────────────┤ -│ "다음 유사 사례를 참고하여 가사를 생성하세요: │ -│ [검색된 성공 사례 1] │ -│ [검색된 성공 사례 2] │ -│ ..." │ -└─────────────────────────────────────────────────────────────┘ -``` - -**구현 코드:** - -```python -from langchain.embeddings.openai import OpenAIEmbeddings -from langchain.vectorstores import Chroma -from langchain.document_loaders import JSONLoader -from langchain.text_splitter import RecursiveCharacterTextSplitter -from langchain.schema import Document - -# 1. 임베딩 모델 설정 -embeddings = OpenAIEmbeddings( - model="text-embedding-3-small", - openai_api_key=settings.CHATGPT_API_KEY -) - -# 2. 벡터 스토어 초기화 -vector_store = Chroma( - collection_name="marketing_knowledge", - embedding_function=embeddings, - persist_directory="./data/chroma_db" -) - -# 3. 마케팅 사례 문서 구조 -class MarketingCase(BaseModel): - case_id: str - region: str - business_type: str # "pension", "guesthouse", "hotel" - target_audience: str - successful_lyrics: str - keywords: list[str] - performance_metrics: dict # views, engagement, conversions - created_at: datetime - -# 4. 문서 추가 함수 -async def add_marketing_case(case: MarketingCase): - """성공한 마케팅 사례를 벡터 스토어에 추가""" - - # 메타데이터와 함께 문서 생성 - document = Document( - page_content=f""" -지역: {case.region} -업종: {case.business_type} -타겟 고객: {case.target_audience} -성공 가사: -{case.successful_lyrics} -효과적인 키워드: {', '.join(case.keywords)} -성과: 조회수 {case.performance_metrics.get('views', 0)}, - 참여율 {case.performance_metrics.get('engagement', 0)}% - """, - metadata={ - "case_id": case.case_id, - "region": case.region, - "business_type": case.business_type, - "created_at": case.created_at.isoformat() - } - ) - - vector_store.add_documents([document]) - vector_store.persist() - -# 5. RAG 기반 가사 생성 -async def generate_lyrics_with_rag( - customer_name: str, - region: str, - business_type: str, - language: str -) -> str: - """RAG를 활용한 고품질 가사 생성""" - - # 유사 사례 검색 - query = f"{region} {business_type} 마케팅 가사" - similar_cases = vector_store.similarity_search( - query, - k=3, - filter={"business_type": business_type} # 같은 업종만 - ) - - # 검색 결과를 프롬프트에 포함 - examples_text = "\n\n".join([ - f"### 참고 사례 {i+1}\n{doc.page_content}" - for i, doc in enumerate(similar_cases) - ]) - - # LangChain 프롬프트 구성 - rag_prompt = ChatPromptTemplate.from_messages([ - ("system", """당신은 마케팅 전문가이자 작사가입니다. -다음 성공 사례를 참고하여 새로운 가사를 생성하세요. -참고 사례의 스타일과 키워드를 활용하되, 고유한 내용을 만드세요. - -{examples}"""), - ("human", """ -고객명: {customer_name} -지역: {region} -언어: {language} - -위 정보를 바탕으로 8-12줄의 감성적인 마케팅 가사를 생성하세요. -""") - ]) - - chain = rag_prompt | ChatOpenAI(model="gpt-4o") | StrOutputParser() - - result = await chain.ainvoke({ - "examples": examples_text, - "customer_name": customer_name, - "region": region, - "language": language - }) - - return result -``` - -### 4.3 설계 2: 지역별 특화 RAG - -**목적:** 각 지역의 특성(문화, 관광지, 특산물 등)을 반영한 가사 생성 - -```python -# 지역 정보 문서 구조 -class RegionInfo(BaseModel): - region_name: str - province: str - famous_attractions: list[str] - local_foods: list[str] - cultural_keywords: list[str] - seasonal_events: list[dict] # {"season": "summer", "event": "해수욕장 개장"} - atmosphere: list[str] # ["고즈넉한", "활기찬", "낭만적인"] - -# 지역 정보 벡터 스토어 -region_store = Chroma( - collection_name="region_knowledge", - embedding_function=embeddings, - persist_directory="./data/chroma_region" -) - -# 지역 정보 추가 예시 -regions_data = [ - RegionInfo( - region_name="속초", - province="강원도", - famous_attractions=["설악산", "속초해변", "영금정", "아바이마을"], - local_foods=["오징어순대", "물회", "생선구이"], - cultural_keywords=["동해바다", "일출", "산과 바다", "청정자연"], - seasonal_events=[ - {"season": "summer", "event": "속초해변 피서"}, - {"season": "autumn", "event": "설악산 단풍"} - ], - atmosphere=["시원한", "청량한", "자연친화적", "힐링"] - ), - # ... 더 많은 지역 -] - -async def enrich_lyrics_with_region_info( - base_lyrics: str, - region: str -) -> str: - """지역 정보로 가사 보강""" - - # 지역 정보 검색 - region_docs = region_store.similarity_search(region, k=1) - - if not region_docs: - return base_lyrics - - region_info = region_docs[0].page_content - - # 가사에 지역 특성 반영 - enrichment_prompt = ChatPromptTemplate.from_messages([ - ("system", """당신은 가사 편집 전문가입니다. -주어진 기본 가사에 지역의 특성을 자연스럽게 녹여내세요. -지역 정보: -{region_info}"""), - ("human", """기본 가사: -{base_lyrics} - -위 가사에 지역의 특성(명소, 분위기, 키워드)을 2-3개 자연스럽게 추가하세요. -원래 가사의 운율과 분위기를 유지하세요.""") - ]) - - chain = enrichment_prompt | ChatOpenAI() | StrOutputParser() - - return await chain.ainvoke({ - "region_info": region_info, - "base_lyrics": base_lyrics - }) -``` - -### 4.4 설계 3: 이미지 메타데이터 RAG - -**목적:** 업로드된 이미지의 분석 결과를 저장하고, 영상 생성 시 최적의 이미지 순서 결정 - -```python -from langchain_openai import ChatOpenAI - -# Vision 모델로 이미지 분석 -vision_model = ChatOpenAI(model="gpt-4o") - -# 이미지 분석 문서 구조 -class ImageAnalysis(BaseModel): - image_url: str - task_id: str - description: str - dominant_colors: list[str] - mood: str # "warm", "cool", "neutral" - scene_type: str # "interior", "exterior", "nature", "food" - suggested_position: str # "opening", "middle", "closing" - quality_score: float # 0.0 ~ 1.0 - -# 이미지 메타데이터 벡터 스토어 -image_store = Chroma( - collection_name="image_metadata", - embedding_function=embeddings, - persist_directory="./data/chroma_images" -) - -async def analyze_and_store_image(image_url: str, task_id: str): - """이미지 분석 후 벡터 스토어에 저장""" - - # GPT-4o Vision으로 이미지 분석 - analysis_response = await vision_model.ainvoke([ - { - "type": "text", - "text": """이미지를 분석하고 다음 JSON 형식으로 응답하세요: -{ - "description": "이미지 설명 (2-3문장)", - "dominant_colors": ["색상1", "색상2"], - "mood": "warm/cool/neutral 중 하나", - "scene_type": "interior/exterior/nature/food 중 하나", - "suggested_position": "opening/middle/closing 중 하나 (영상에서 적합한 위치)", - "quality_score": 0.0~1.0 (이미지 품질/선명도) -}""" - }, - { - "type": "image_url", - "image_url": {"url": image_url} - } - ]) - - analysis = json.loads(analysis_response.content) - - # 문서 생성 및 저장 - document = Document( - page_content=f""" -이미지 설명: {analysis['description']} -분위기: {analysis['mood']} -장면 유형: {analysis['scene_type']} -추천 위치: {analysis['suggested_position']} -색상: {', '.join(analysis['dominant_colors'])} - """, - metadata={ - "image_url": image_url, - "task_id": task_id, - **analysis - } - ) - - image_store.add_documents([document]) - image_store.persist() - - return ImageAnalysis(image_url=image_url, task_id=task_id, **analysis) - -async def get_optimal_image_order( - task_id: str, - music_mood: str, # 음악 분위기 - lyrics_theme: str # 가사 주제 -) -> list[str]: - """음악과 가사에 맞는 최적의 이미지 순서 결정""" - - # 해당 task의 모든 이미지 조회 - all_images = image_store.get( - where={"task_id": task_id} - ) - - # 음악/가사 분위기에 맞는 이미지 우선 검색 - query = f"{music_mood} {lyrics_theme} 마케팅 영상" - sorted_images = image_store.similarity_search( - query, - k=len(all_images), - filter={"task_id": task_id} - ) - - # 이미지 순서 결정 로직 - opening_images = [img for img in sorted_images if img.metadata["suggested_position"] == "opening"] - middle_images = [img for img in sorted_images if img.metadata["suggested_position"] == "middle"] - closing_images = [img for img in sorted_images if img.metadata["suggested_position"] == "closing"] - - # 품질 점수로 정렬 - opening_images.sort(key=lambda x: x.metadata["quality_score"], reverse=True) - closing_images.sort(key=lambda x: x.metadata["quality_score"], reverse=True) - - # 최종 순서 - ordered = ( - opening_images[:2] + # 시작 2장 - middle_images + # 중간 이미지들 - closing_images[:1] # 마무리 1장 - ) - - return [img.metadata["image_url"] for img in ordered] -``` - -### 4.5 설계 4: 프롬프트 히스토리 RAG - -**목적:** 과거 성공/실패한 프롬프트를 학습하여 프롬프트 품질 지속 개선 - -```python -# 프롬프트 결과 문서 구조 -class PromptResult(BaseModel): - prompt_id: str - prompt_text: str - result_text: str - success: bool - failure_reason: Optional[str] - category: str # "lyric", "marketing_analysis", "region_enrichment" - metrics: dict # {"length": 10, "contains_region_keyword": True, ...} - created_at: datetime - -# 프롬프트 히스토리 벡터 스토어 -prompt_store = Chroma( - collection_name="prompt_history", - embedding_function=embeddings, - persist_directory="./data/chroma_prompts" -) - -async def log_prompt_result(result: PromptResult): - """프롬프트 결과 기록""" - - document = Document( - page_content=f""" -프롬프트: {result.prompt_text} -결과: {result.result_text[:500]}... -성공 여부: {'성공' if result.success else '실패'} -실패 사유: {result.failure_reason or 'N/A'} - """, - metadata={ - "prompt_id": result.prompt_id, - "success": result.success, - "category": result.category, - "created_at": result.created_at.isoformat(), - **result.metrics - } - ) - - prompt_store.add_documents([document]) - -async def get_improved_prompt( - base_prompt: str, - category: str -) -> str: - """과거 결과를 기반으로 프롬프트 개선""" - - # 유사한 성공 프롬프트 검색 - successful_prompts = prompt_store.similarity_search( - base_prompt, - k=3, - filter={"success": True, "category": category} - ) - - # 유사한 실패 프롬프트 검색 (피해야 할 패턴) - failed_prompts = prompt_store.similarity_search( - base_prompt, - k=2, - filter={"success": False, "category": category} - ) - - # 프롬프트 개선 요청 - improvement_prompt = ChatPromptTemplate.from_messages([ - ("system", """당신은 프롬프트 엔지니어링 전문가입니다. - -다음 성공/실패 사례를 참고하여 주어진 프롬프트를 개선하세요. - -### 성공 사례 (참고): -{successful_examples} - -### 실패 사례 (피할 것): -{failed_examples} - -### 개선 원칙: -1. 성공 사례의 패턴을 따르세요 -2. 실패 사례의 패턴을 피하세요 -3. 명확하고 구체적인 지시를 포함하세요 -4. 출력 형식을 명시하세요"""), - ("human", """개선할 프롬프트: -{base_prompt} - -위 프롬프트를 개선하세요. 개선된 프롬프트만 출력하세요.""") - ]) - - chain = improvement_prompt | ChatOpenAI() | StrOutputParser() - - improved = await chain.ainvoke({ - "successful_examples": "\n---\n".join([doc.page_content for doc in successful_prompts]), - "failed_examples": "\n---\n".join([doc.page_content for doc in failed_prompts]), - "base_prompt": base_prompt - }) - - return improved -``` - ---- - -## 5. 통합 아키텍처 - -### 5.1 전체 시스템 아키텍처 - -``` -┌──────────────────────────────────────────────────────────────────────────┐ -│ FastAPI 라우터 │ -│ /lyric/generate, /song/generate, /video/generate, /video/generate-full │ -└───────────────────────────────────┬──────────────────────────────────────┘ - │ - ▼ -┌──────────────────────────────────────────────────────────────────────────┐ -│ LangGraph 파이프라인 │ -│ ┌─────────────────────────────────────────────────────────────────┐ │ -│ │ StateGraph (상태 기계) │ │ -│ │ │ │ -│ │ [generate_lyric] → [request_song] → [poll_song] │ │ -│ │ │ │ │ │ -│ │ │ ▼ │ │ -│ │ │ [request_video] → [poll_video] → END │ │ -│ │ │ │ │ │ -│ │ └─────────────────────┴──────────→ [handle_error] │ │ -│ └─────────────────────────────────────────────────────────────────┘ │ -│ │ │ -│ ┌───────────────┼───────────────┐ │ -│ │ │ │ │ -│ ▼ ▼ ▼ │ -│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ -│ │ LangChain │ │ RAG │ │ External │ │ -│ │ Components │ │ Vector DBs │ │ APIs │ │ -│ └─────────────┘ └─────────────┘ └─────────────┘ │ -└──────────────────────────────────────────────────────────────────────────┘ - │ │ │ - ┌───────────┘ ┌──────────┘ ┌──────────┘ - │ │ │ - ▼ ▼ ▼ -┌─────────────┐ ┌─────────────┐ ┌─────────────┐ -│ Prompt │ │ Chroma │ │ OpenAI │ -│ Templates │ │ Vector │ │ Suno │ -│ Chains │ │ Store │ │ Creatomate │ -│ Parsers │ │ │ │ │ -└─────────────┘ └─────────────┘ └─────────────┘ - │ │ │ - └────────────────┴───────────────┘ - │ - ▼ - ┌─────────────────────────┐ - │ MySQL + Azure Blob │ - │ (영구 저장소) │ - └─────────────────────────┘ -``` - -### 5.2 데이터 흐름 - -``` -┌─────────────────────────────────────────────────────────────────────────┐ -│ 데이터 흐름 │ -├─────────────────────────────────────────────────────────────────────────┤ -│ │ -│ 1. 사용자 요청 │ -│ ├── 고객 정보 (이름, 지역, 상세정보) │ -│ └── 이미지 URL 리스트 │ -│ │ │ -│ ▼ │ -│ 2. RAG 검색 (병렬) │ -│ ├── 마케팅 지식베이스 → 유사 성공 사례 │ -│ ├── 지역 정보베이스 → 지역 특성 │ -│ └── 이미지 메타데이터 → 이미지 분석 │ -│ │ │ -│ ▼ │ -│ 3. LangChain 프롬프트 구성 │ -│ ├── 기본 템플릿 로드 │ -│ ├── RAG 결과 주입 │ -│ ├── Few-shot 예시 추가 │ -│ └── 출력 형식 지정 │ -│ │ │ -│ ▼ │ -│ 4. LangGraph 파이프라인 실행 │ -│ ├── 가사 생성 (ChatGPT) │ -│ ├── 음악 생성 (Suno, 폴링 자동화) │ -│ └── 영상 생성 (Creatomate, 폴링 자동화) │ -│ │ │ -│ ▼ │ -│ 5. 결과 저장 │ -│ ├── MySQL: 메타데이터, 상태 │ -│ ├── Azure Blob: 영상 파일 │ -│ └── Chroma: 성공 사례 피드백 │ -│ │ │ -│ ▼ │ -│ 6. 사용자 응답 │ -│ └── 영상 URL, 상태, 메타데이터 │ -│ │ -└─────────────────────────────────────────────────────────────────────────┘ -``` - -### 5.3 디렉토리 구조 (신규) - -``` -app/ -├── langchain/ # LangChain 관련 -│ ├── __init__.py -│ ├── prompts/ -│ │ ├── __init__.py -│ │ ├── lyric_prompts.py # 가사 생성 프롬프트 -│ │ ├── marketing_prompts.py # 마케팅 분석 프롬프트 -│ │ └── examples/ # Few-shot 예시 -│ │ ├── korean.json -│ │ ├── english.json -│ │ └── ... -│ ├── chains/ -│ │ ├── __init__.py -│ │ ├── lyric_chain.py # 가사 생성 체인 -│ │ └── marketing_chain.py # 마케팅 분석 체인 -│ └── parsers/ -│ ├── __init__.py -│ └── lyric_parser.py # 가사 출력 파서 -│ -├── langgraph/ # LangGraph 관련 -│ ├── __init__.py -│ ├── states/ -│ │ ├── __init__.py -│ │ └── pipeline_state.py # 파이프라인 상태 정의 -│ ├── nodes/ -│ │ ├── __init__.py -│ │ ├── lyric_node.py # 가사 생성 노드 -│ │ ├── song_node.py # 음악 생성 노드 -│ │ ├── video_node.py # 영상 생성 노드 -│ │ └── error_node.py # 에러 처리 노드 -│ └── graphs/ -│ ├── __init__.py -│ └── video_pipeline.py # 메인 파이프라인 그래프 -│ -├── rag/ # RAG 관련 -│ ├── __init__.py -│ ├── stores/ -│ │ ├── __init__.py -│ │ ├── marketing_store.py # 마케팅 지식베이스 -│ │ ├── region_store.py # 지역 정보베이스 -│ │ ├── image_store.py # 이미지 메타데이터 -│ │ └── prompt_store.py # 프롬프트 히스토리 -│ ├── loaders/ -│ │ ├── __init__.py -│ │ └── case_loader.py # 사례 데이터 로더 -│ └── retrievers/ -│ ├── __init__.py -│ └── hybrid_retriever.py # 하이브리드 검색 -│ -└── data/ # 데이터 저장소 - └── chroma_db/ # Chroma 벡터 DB - ├── marketing_knowledge/ - ├── region_knowledge/ - ├── image_metadata/ - └── prompt_history/ -``` - ---- - -## 6. 기대 효과 - -### 6.1 정량적 기대 효과 - -| 지표 | 현재 | 목표 | 개선율 | -|------|------|------|--------| -| **가사 생성 품질** | 70% 만족도 | 90% 만족도 | +29% | -| **재작업률** | 30% | 10% | -67% | -| **파이프라인 실패율** | 15% | 5% | -67% | -| **평균 처리 시간** | 10분 (수동 개입 필요) | 8분 (완전 자동) | -20% | -| **다국어 품질** | 60% | 85% | +42% | -| **프롬프트 튜닝 시간** | 2시간/버전 | 30분/버전 | -75% | - -### 6.2 정성적 기대 효과 - -#### 6.2.1 개발 생산성 향상 - -| 영역 | 효과 | -|------|------| -| **코드 유지보수** | 프롬프트와 비즈니스 로직 분리로 수정 용이 | -| **테스트 용이성** | 각 체인/노드 단위 테스트 가능 | -| **디버깅** | 상태 기계 기반으로 문제 지점 명확히 파악 | -| **확장성** | 새로운 AI 서비스 추가 시 노드만 추가하면 됨 | - -#### 6.2.2 품질 향상 - -| 영역 | 효과 | -|------|------| -| **일관성** | 동일 조건에서 일관된 품질의 결과물 생성 | -| **지역 맞춤화** | RAG로 지역별 특성 자동 반영 | -| **학습 효과** | 성공 사례 축적으로 시간이 지날수록 품질 향상 | -| **에러 복구** | 자동 재시도 및 폴백으로 안정성 강화 | - -#### 6.2.3 운영 효율성 - -| 영역 | 효과 | -|------|------| -| **모니터링** | 파이프라인 상태 추적으로 병목 지점 파악 | -| **비용 최적화** | 불필요한 API 호출 감소, 캐싱 활용 | -| **확장 대응** | 부하 증가 시 노드별 스케일링 가능 | - -### 6.3 비즈니스 가치 - -``` -┌────────────────────────────────────────────────────────────────┐ -│ 비즈니스 가치 │ -├────────────────────────────────────────────────────────────────┤ -│ │ -│ 1. 고객 만족도 향상 │ -│ └── 고품질 가사/영상으로 마케팅 효과 증대 │ -│ │ -│ 2. 서비스 차별화 │ -│ └── 지역 맞춤 콘텐츠로 경쟁사 대비 우위 │ -│ │ -│ 3. 운영 비용 절감 │ -│ └── 자동화로 수동 개입 최소화 │ -│ │ -│ 4. 확장 가능성 │ -│ └── 새로운 지역/업종 추가 시 RAG 학습만으로 대응 │ -│ │ -│ 5. 데이터 자산화 │ -│ └── 축적된 성공 사례가 진입 장벽 역할 │ -│ │ -└────────────────────────────────────────────────────────────────┘ -``` - ---- - -## 7. 구현 로드맵 - -### 7.1 Phase 1: 기초 (1-2주) - -**목표:** LangChain 기본 구조 구축 - -| 작업 | 설명 | 우선순위 | -|------|------|----------| -| 의존성 설치 | langchain, langchain-openai, chromadb | P0 | -| 프롬프트 템플릿 작성 | 가사 생성 프롬프트 이관 | P0 | -| 기본 체인 구현 | ChatGPT 서비스 LangChain으로 래핑 | P0 | -| 출력 파서 구현 | 가사 응답 검증 및 파싱 | P1 | -| 테스트 작성 | 체인 단위 테스트 | P1 | - -**산출물:** -- `app/langchain/` 디렉토리 구조 -- 가사 생성 LangChain 체인 -- 기본 테스트 코드 - -### 7.2 Phase 2: 파이프라인 (2-3주) - -**목표:** LangGraph 파이프라인 구축 - -| 작업 | 설명 | 우선순위 | -|------|------|----------| -| 상태 정의 | PipelineState TypedDict 작성 | P0 | -| 노드 구현 | 가사, 음악, 영상 생성 노드 | P0 | -| 그래프 구성 | 엣지 및 조건부 분기 정의 | P0 | -| 폴링 통합 | Suno, Creatomate 폴링 자동화 | P0 | -| 에러 처리 | 에러 노드 및 재시도 로직 | P1 | -| FastAPI 통합 | 새 엔드포인트 추가 | P1 | - -**산출물:** -- `app/langgraph/` 디렉토리 구조 -- 통합 파이프라인 그래프 -- `/video/generate-full` 엔드포인트 - -### 7.3 Phase 3: RAG (2-3주) - -**목표:** 지식베이스 구축 및 RAG 통합 - -| 작업 | 설명 | 우선순위 | -|------|------|----------| -| Chroma 설정 | 벡터 스토어 초기화 | P0 | -| 마케팅 사례 수집 | 기존 성공 사례 데이터화 | P0 | -| 지역 정보 구축 | 주요 지역 정보 입력 | P1 | -| 검색 통합 | 가사 생성 시 RAG 적용 | P0 | -| 이미지 분석 | Vision API 연동 | P2 | -| 프롬프트 히스토리 | 자동 학습 파이프라인 | P2 | - -**산출물:** -- `app/rag/` 디렉토리 구조 -- 마케팅/지역 지식베이스 -- RAG 통합 가사 생성 - -### 7.4 Phase 4: 고도화 (2-3주) - -**목표:** 최적화 및 모니터링 - -| 작업 | 설명 | 우선순위 | -|------|------|----------| -| 성능 최적화 | 캐싱, 병렬 처리 개선 | P1 | -| 모니터링 | 파이프라인 상태 대시보드 | P1 | -| A/B 테스팅 | 프롬프트 버전 비교 | P2 | -| 문서화 | API 문서, 운영 가이드 | P1 | -| 부하 테스트 | 동시 요청 처리 검증 | P2 | - -**산출물:** -- 최적화된 파이프라인 -- 모니터링 대시보드 -- 완성된 문서 - ---- - -## 8. 결론 - -### 8.1 요약 - -CastAD 백엔드에 LangChain, LangGraph, RAG를 적용하면: - -1. **LangChain**: 프롬프트 관리 체계화, 다단계 체인 구성, 출력 검증 자동화 -2. **LangGraph**: 복잡한 파이프라인 상태 관리, 폴링 자동화, 에러 처리 강화 -3. **RAG**: 과거 성공 사례 활용, 지역별 맞춤화, 지속적 품질 개선 - -### 8.2 핵심 가치 - -``` -┌───────────────────────────────────────────────────────────┐ -│ │ -│ 현재: 각 단계가 독립적 → 상태 관리 어려움 │ -│ 개선: 통합 파이프라인 → 자동화된 상태 추적 │ -│ │ -│ 현재: 하드코딩 프롬프트 → 수정 어려움 │ -│ 개선: 템플릿 기반 → 유연한 프롬프트 관리 │ -│ │ -│ 현재: 과거 데이터 미활용 → 일관성 없는 품질 │ -│ 개선: RAG 지식베이스 → 축적된 노하우 활용 │ -│ │ -└───────────────────────────────────────────────────────────┘ -``` - -### 8.3 권장 사항 - -1. **단계적 도입**: Phase 1(LangChain)부터 시작하여 검증 후 확장 -2. **기존 API 유지**: 새 엔드포인트 추가 방식으로 호환성 보장 -3. **데이터 축적 우선**: RAG 효과를 위해 초기 사례 데이터 확보 중요 -4. **모니터링 병행**: 각 단계별 성과 측정으로 ROI 검증 - ---- - -## 부록 - -### A. 필요 의존성 - -```toml -# pyproject.toml 추가 의존성 -[project.dependencies] -langchain = ">=0.1.0" -langchain-openai = ">=0.0.5" -langchain-community = ">=0.0.20" -langgraph = ">=0.0.30" -chromadb = ">=0.4.22" -tiktoken = ">=0.5.2" -``` - -### B. 환경 변수 추가 - -```env -# .env 추가 -CHROMA_PERSIST_DIR=./data/chroma_db -LANGCHAIN_TRACING_V2=true # 선택: LangSmith 모니터링 -LANGCHAIN_API_KEY=xxx # 선택: LangSmith 모니터링 -``` - -### C. 참고 자료 - -- [LangChain Documentation](https://python.langchain.com/) -- [LangGraph Documentation](https://langchain-ai.github.io/langgraph/) -- [Chroma Documentation](https://docs.trychroma.com/) -- [OpenAI Cookbook](https://cookbook.openai.com/) - ---- - -*이 보고서는 CastAD 백엔드 프로젝트 분석을 기반으로 작성되었습니다.* -*작성일: 2025-12-28* +# CastAD 백엔드 - LangChain, LangGraph, RAG 적용 설계 보고서 + +## 목차 +1. [현재 시스템 분석](#1-현재-시스템-분석) +2. [LangChain 적용 설계](#2-langchain-적용-설계) +3. [LangGraph 적용 설계](#3-langgraph-적용-설계) +4. [RAG 적용 설계](#4-rag-적용-설계) +5. [통합 아키텍처](#5-통합-아키텍처) +6. [기대 효과](#6-기대-효과) +7. [구현 로드맵](#7-구현-로드맵) +8. [결론](#8-결론) + +--- + +## 1. 현재 시스템 분석 + +### 1.1 프로젝트 개요 + +CastAD는 **AI 기반 광고 음악 및 영상 자동 생성 서비스**입니다. 네이버 지도에서 수집한 숙박시설 정보를 기반으로 마케팅용 자동 영상을 생성하는 통합 플랫폼입니다. + +**핵심 파이프라인:** +``` +사용자 입력 → 가사 자동 생성 → 음악 자동 생성 → 영상 자동 생성 +``` + +### 1.2 현재 기술 스택 + +| 구분 | 기술 | +|------|------| +| Backend Framework | FastAPI (async/await 기반) | +| ORM | SQLAlchemy 2.0 (비동기) | +| Database | MySQL (asyncmy 드라이버) | +| Cache | Redis | +| AI/API | OpenAI ChatGPT, Suno AI, Creatomate | +| Storage | Azure Blob Storage | + +### 1.3 현재 핵심 흐름 + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ 현재 파이프라인 구조 │ +├─────────────────────────────────────────────────────────────────┤ +│ │ +│ POST /crawling (선택) │ +│ │ │ +│ ▼ │ +│ POST /lyric/generate ──────► ChatGPT API ──────► 가사 저장 │ +│ │ │ +│ ▼ │ +│ POST /song/generate ───────► Suno API ─────────► 음악 저장 │ +│ │ │ │ +│ │ 클라이언트 폴링 │ +│ │ │ │ +│ ▼ ▼ │ +│ POST /video/generate ──────► Creatomate API ───► 영상 저장 │ +│ │ │ │ +│ │ 클라이언트 폴링 │ +│ ▼ ▼ │ +│ GET /video/download ◄──────── 완료 ──────────► Azure Blob │ +│ │ +└─────────────────────────────────────────────────────────────────┘ +``` + +### 1.4 현재 시스템의 한계점 + +| 문제점 | 설명 | +|--------|------| +| **분산된 상태 관리** | 각 API 호출마다 독립적인 상태 관리, 전체 파이프라인 추적 어려움 | +| **클라이언트 의존적 폴링** | 음악/영상 생성 완료 여부를 클라이언트가 반복 확인해야 함 | +| **하드코딩된 프롬프트** | ChatGPT 프롬프트가 코드에 직접 작성, 유연성 부족 | +| **에러 복구 제한적** | 단순 실패 패턴 검사만 수행, 자동 복구 메커니즘 없음 | +| **과거 데이터 미활용** | 성공한 가사/마케팅 사례 재활용 불가 | +| **일관성 없는 품질** | 동일 조건에서도 결과물 품질 편차 존재 | + +--- + +## 2. LangChain 적용 설계 + +### 2.1 적용 대상 및 목적 + +LangChain은 **LLM 애플리케이션 개발을 위한 프레임워크**로, 프롬프트 관리, 체인 구성, 출력 파싱 등을 체계화합니다. + +**적용 대상:** +1. 가사 생성 서비스 (`ChatgptService`) +2. 마케팅 분석 서비스 +3. 다국어 처리 로직 + +### 2.2 설계 1: 프롬프트 템플릿 시스템 + +**현재 문제:** +```python +# 현재: chatgpt_prompt.py +prompt = f""" +[ROLE] You are a marketing expert... +[INPUT] Customer: {customer_name}, Region: {region}... +""" +``` + +**개선 설계:** +```python +# 개선: langchain 적용 +from langchain.prompts import PromptTemplate, ChatPromptTemplate +from langchain_openai import ChatOpenAI + +# 가사 생성 프롬프트 템플릿 +LYRIC_PROMPT = ChatPromptTemplate.from_messages([ + ("system", """[ROLE] You are a marketing expert and professional lyricist. +You specialize in creating catchy, emotional lyrics for travel and accommodation marketing. + +[LANGUAGE REQUIREMENT] +Output MUST be 100% in {language}. No other languages allowed."""), + + ("human", """[INPUT] +Customer Name: {customer_name} +Region: {region} +Detailed Information: {detail_info} + +[OUTPUT REQUIREMENTS] +- 8-12 lines of lyrics +- Focus on: relaxation, healing, beautiful scenery, memorable experiences +- Style: warm, inviting, poetic +- Include location-specific imagery + +Generate lyrics now:""") +]) + +# 체인 구성 +lyric_chain = LYRIC_PROMPT | ChatOpenAI(model="gpt-5-mini-mini") | StrOutputParser() + +# 사용 +result = await lyric_chain.ainvoke({ + "customer_name": "스테이뫰", + "region": "강원도 속초", + "detail_info": "해변 근처 펜션", + "language": "Korean" +}) +``` + +**이점:** +- 프롬프트 버전 관리 용이 +- A/B 테스팅 지원 +- 입력 변수 명확한 정의 + +### 2.3 설계 2: 다단계 마케팅 분석 체인 + +**목적:** 복잡한 마케팅 분석을 단계별로 수행하여 품질 향상 + +```python +from langchain.chains import SequentialChain +from langchain.prompts import PromptTemplate +from langchain_openai import ChatOpenAI + +# Step 1: 경쟁사 분석 체인 +competitor_prompt = PromptTemplate( + input_variables=["region", "business_type"], + template=""" + {region} 지역의 {business_type} 업종에 대해 분석하세요: + - 주요 경쟁사 특성 + - 차별화 포인트 + - 시장 포지셔닝 + """ +) +competitor_chain = competitor_prompt | ChatOpenAI() | StrOutputParser() + +# Step 2: 타겟 고객 분석 체인 +audience_prompt = PromptTemplate( + input_variables=["region", "competitor_analysis"], + template=""" + 경쟁사 분석 결과: {competitor_analysis} + + {region} 지역의 주요 타겟 고객층을 분석하세요: + - 연령대 및 특성 + - 주요 니즈 + - 결정 요인 + """ +) +audience_chain = audience_prompt | ChatOpenAI() | StrOutputParser() + +# Step 3: 마케팅 전략 종합 체인 +strategy_prompt = PromptTemplate( + input_variables=["customer_name", "competitor_analysis", "audience_analysis"], + template=""" + 경쟁사 분석: {competitor_analysis} + 타겟 고객: {audience_analysis} + + {customer_name}을 위한 마케팅 전략을 제안하세요: + - 핵심 메시지 + - 차별화 전략 + - 추천 가사 방향 + """ +) +strategy_chain = strategy_prompt | ChatOpenAI() | StrOutputParser() + +# 통합 순차 체인 +marketing_analysis_chain = ( + {"region": RunnablePassthrough(), "business_type": RunnablePassthrough()} + | competitor_chain + | {"competitor_analysis": RunnablePassthrough(), "region": RunnablePassthrough()} + | audience_chain + | {"competitor_analysis": ..., "audience_analysis": RunnablePassthrough(), "customer_name": ...} + | strategy_chain +) +``` + +**이점:** +- 분석의 깊이와 체계성 향상 +- 각 단계별 결과 추적 가능 +- 중간 결과 캐싱 가능 + +### 2.4 설계 3: 출력 파싱 및 검증 + +**목적:** ChatGPT 응답의 구조화 및 자동 검증 + +```python +from langchain.output_parsers import PydanticOutputParser +from langchain_core.output_parsers import OutputFixingParser +from pydantic import BaseModel, Field, validator + +# 가사 출력 스키마 +class LyricOutput(BaseModel): + title: str = Field(description="가사의 제목 (선택)") + lyrics: list[str] = Field(description="가사 각 줄", min_items=8, max_items=12) + mood: str = Field(description="가사의 분위기: warm, energetic, romantic 등") + + @validator('lyrics') + def validate_line_count(cls, v): + if len(v) < 8: + raise ValueError("가사는 최소 8줄 이상이어야 합니다") + return v + +# 파서 생성 +parser = PydanticOutputParser(pydantic_object=LyricOutput) + +# 자동 수정 파서 (파싱 실패 시 LLM으로 재시도) +fixing_parser = OutputFixingParser.from_llm( + parser=parser, + llm=ChatOpenAI(model="gpt-5-mini-mini") +) + +# 프롬프트에 포맷 지시 추가 +prompt_with_format = LYRIC_PROMPT.partial( + format_instructions=parser.get_format_instructions() +) +``` + +**이점:** +- 응답 형식 일관성 보장 +- 자동 오류 복구 +- 타입 안전성 확보 + +### 2.5 설계 4: Few-Shot 다국어 프롬프트 + +**목적:** 각 언어별 고품질 예시 제공으로 번역/생성 품질 향상 + +```python +from langchain.prompts import FewShotPromptTemplate, PromptTemplate + +# 언어별 예시 +LANGUAGE_EXAMPLES = { + "Korean": [ + { + "input": "강원도 속초 해변 펜션", + "output": """푸른 바다 물결 위에 +새벽빛이 춤을 추고 +당신의 하루를 담아 +스테이뫰에서 쉬어가요""" + } + ], + "English": [ + { + "input": "Sokcho beach pension, Gangwon-do", + "output": """Where ocean waves meet morning light +A peaceful haven comes in sight +Let your worries drift away +At Stay Meoum, find your stay""" + } + ], + "Japanese": [ + { + "input": "江原道束草ビーチペンション", + "output": """青い海の波の上に +朝の光が踊る時 +あなたの一日を包み込む +ステイメウムで休んでいこう""" + } + ], + "Chinese": [...], + "Thai": [...], + "Vietnamese": [...] +} + +# Few-Shot 프롬프트 생성 +def create_multilingual_prompt(language: str): + example_prompt = PromptTemplate( + input_variables=["input", "output"], + template="입력: {input}\n가사:\n{output}" + ) + + return FewShotPromptTemplate( + examples=LANGUAGE_EXAMPLES.get(language, LANGUAGE_EXAMPLES["Korean"]), + example_prompt=example_prompt, + prefix="다음 예시를 참고하여 고품질 가사를 생성하세요:", + suffix="입력: {customer_info}\n가사:", + input_variables=["customer_info"] + ) +``` + +**이점:** +- 언어별 문화적 뉘앙스 반영 +- 일관된 스타일 유지 +- 번역 품질 대폭 향상 + +--- + +## 3. LangGraph 적용 설계 + +### 3.1 적용 대상 및 목적 + +LangGraph는 **복잡한 다단계 워크플로우를 상태 기계(State Machine)로 관리**하는 프레임워크입니다. + +**적용 대상:** +1. 전체 영상 생성 파이프라인 (가사 → 음악 → 영상) +2. 비동기 폴링 자동화 +3. 에러 처리 및 재시도 로직 + +### 3.2 설계 1: 통합 파이프라인 그래프 + +**핵심 설계:** + +```python +from langgraph.graph import StateGraph, END +from typing import TypedDict, Optional, Literal +from datetime import datetime + +# 파이프라인 상태 정의 +class PipelineState(TypedDict): + # 입력 + task_id: str + customer_name: str + region: str + detail_info: str + language: str + images: list[str] + orientation: Literal["vertical", "horizontal"] + + # 중간 결과 + lyric: Optional[str] + lyric_status: Optional[str] + + song_url: Optional[str] + song_task_id: Optional[str] + song_status: Optional[str] + song_duration: Optional[float] + + video_url: Optional[str] + video_render_id: Optional[str] + video_status: Optional[str] + + # 메타데이터 + error: Optional[str] + error_step: Optional[str] + started_at: datetime + completed_at: Optional[datetime] + retry_count: int + +# 그래프 빌더 +def build_video_pipeline() -> StateGraph: + graph = StateGraph(PipelineState) + + # ===== 노드 정의 ===== + + # 1. 가사 생성 노드 + async def generate_lyric(state: PipelineState) -> PipelineState: + """ChatGPT로 가사 생성 (동기)""" + try: + lyric_chain = create_lyric_chain() # LangChain 체인 + lyric = await lyric_chain.ainvoke({ + "customer_name": state["customer_name"], + "region": state["region"], + "detail_info": state["detail_info"], + "language": state["language"] + }) + + # DB 저장 + await save_lyric_to_db(state["task_id"], lyric) + + return { + **state, + "lyric": lyric, + "lyric_status": "completed" + } + except Exception as e: + return { + **state, + "error": str(e), + "error_step": "lyric_generation", + "lyric_status": "failed" + } + + # 2. 음악 생성 요청 노드 + async def request_song(state: PipelineState) -> PipelineState: + """Suno API에 음악 생성 요청""" + try: + suno = SunoAPIClient() + task_id = await suno.generate( + prompt=state["lyric"], + genre="K-Pop, Emotional" + ) + + # DB 저장 + await save_song_request_to_db(state["task_id"], task_id) + + return { + **state, + "song_task_id": task_id, + "song_status": "processing" + } + except Exception as e: + return { + **state, + "error": str(e), + "error_step": "song_request", + "song_status": "failed" + } + + # 3. 음악 폴링 노드 + async def poll_song_status(state: PipelineState) -> PipelineState: + """Suno 상태 폴링 (최대 5분)""" + suno = SunoAPIClient() + max_attempts = 60 # 5초 간격 × 60 = 5분 + + for attempt in range(max_attempts): + result = await suno.get_task_status(state["song_task_id"]) + + if result["status"] == "SUCCESS": + audio_url = result["clips"][0]["audio_url"] + duration = result["clips"][0]["duration"] + + # DB 업데이트 + await update_song_status( + state["task_id"], + "completed", + audio_url, + duration + ) + + return { + **state, + "song_url": audio_url, + "song_duration": duration, + "song_status": "completed" + } + elif result["status"] == "FAILED": + return { + **state, + "error": "Suno generation failed", + "error_step": "song_polling", + "song_status": "failed" + } + + await asyncio.sleep(5) # 5초 대기 + + return { + **state, + "error": "Song generation timeout", + "error_step": "song_polling", + "song_status": "timeout" + } + + # 4. 영상 생성 요청 노드 + async def request_video(state: PipelineState) -> PipelineState: + """Creatomate API에 영상 렌더링 요청""" + try: + creatomate = CreatomateClient() + render_id = await creatomate.render( + images=state["images"], + music_url=state["song_url"], + lyrics=state["lyric"], + duration=state["song_duration"], + orientation=state["orientation"] + ) + + # DB 저장 + await save_video_request_to_db(state["task_id"], render_id) + + return { + **state, + "video_render_id": render_id, + "video_status": "processing" + } + except Exception as e: + return { + **state, + "error": str(e), + "error_step": "video_request", + "video_status": "failed" + } + + # 5. 영상 폴링 노드 + async def poll_video_status(state: PipelineState) -> PipelineState: + """Creatomate 상태 폴링 (최대 10분)""" + creatomate = CreatomateClient() + max_attempts = 120 # 5초 간격 × 120 = 10분 + + for attempt in range(max_attempts): + result = await creatomate.get_render_status(state["video_render_id"]) + + if result["status"] == "succeeded": + video_url = result["url"] + + # Azure Blob 업로드 + blob_url = await upload_to_azure(video_url, state["task_id"]) + + # DB 업데이트 + await update_video_status(state["task_id"], "completed", blob_url) + + return { + **state, + "video_url": blob_url, + "video_status": "completed", + "completed_at": datetime.now() + } + elif result["status"] == "failed": + return { + **state, + "error": "Creatomate rendering failed", + "error_step": "video_polling", + "video_status": "failed" + } + + await asyncio.sleep(5) + + return { + **state, + "error": "Video generation timeout", + "error_step": "video_polling", + "video_status": "timeout" + } + + # 6. 에러 처리 노드 + async def handle_error(state: PipelineState) -> PipelineState: + """에러 로깅 및 알림""" + await log_pipeline_error( + task_id=state["task_id"], + error=state["error"], + step=state["error_step"] + ) + + # 선택: 슬랙/이메일 알림 + await send_error_notification(state) + + return state + + # ===== 노드 추가 ===== + graph.add_node("generate_lyric", generate_lyric) + graph.add_node("request_song", request_song) + graph.add_node("poll_song", poll_song_status) + graph.add_node("request_video", request_video) + graph.add_node("poll_video", poll_video_status) + graph.add_node("handle_error", handle_error) + + # ===== 엣지 정의 ===== + + # 시작점 + graph.set_entry_point("generate_lyric") + + # 조건부 분기: 가사 생성 후 + def route_after_lyric(state: PipelineState): + if state.get("error"): + return "handle_error" + return "request_song" + + graph.add_conditional_edges( + "generate_lyric", + route_after_lyric, + { + "request_song": "request_song", + "handle_error": "handle_error" + } + ) + + # 조건부 분기: 음악 요청 후 + def route_after_song_request(state: PipelineState): + if state.get("error"): + return "handle_error" + return "poll_song" + + graph.add_conditional_edges( + "request_song", + route_after_song_request + ) + + # 조건부 분기: 음악 폴링 후 + def route_after_song_poll(state: PipelineState): + if state.get("error") or state["song_status"] in ["failed", "timeout"]: + return "handle_error" + return "request_video" + + graph.add_conditional_edges( + "poll_song", + route_after_song_poll + ) + + # 조건부 분기: 영상 요청 후 + graph.add_conditional_edges( + "request_video", + lambda s: "handle_error" if s.get("error") else "poll_video" + ) + + # 조건부 분기: 영상 폴링 후 + graph.add_conditional_edges( + "poll_video", + lambda s: "handle_error" if s.get("error") else END + ) + + # 에러 핸들러는 항상 종료 + graph.add_edge("handle_error", END) + + return graph.compile() +``` + +**그래프 시각화:** + +``` + ┌─────────────────┐ + │ generate_lyric │ + └────────┬────────┘ + │ + ┌────────▼────────┐ + ┌─────┤ route check ├─────┐ + │ └─────────────────┘ │ + [error] [success] + │ │ + ▼ ▼ + ┌─────────────────┐ ┌─────────────────┐ + │ handle_error │ │ request_song │ + └────────┬────────┘ └────────┬────────┘ + │ │ + ▼ ▼ + END ┌─────────────────┐ + │ poll_song │ + └────────┬────────┘ + │ + ┌────────▼────────┐ + ┌─────┤ route check ├─────┐ + │ └─────────────────┘ │ + [error/timeout] [success] + │ │ + ▼ ▼ + ┌─────────────────┐ ┌─────────────────┐ + │ handle_error │ │ request_video │ + └────────┬────────┘ └────────┬────────┘ + │ │ + ▼ ▼ + END ┌─────────────────┐ + │ poll_video │ + └────────┬────────┘ + │ + ┌────────▼────────┐ + ┌─────┤ route check ├─────┐ + │ └─────────────────┘ │ + [error] [success] + │ │ + ▼ ▼ + ┌─────────────────┐ END + │ handle_error │ (파이프라인 완료) + └────────┬────────┘ + │ + ▼ + END +``` + +### 3.3 설계 2: 재시도 및 폴백 메커니즘 + +```python +from langgraph.graph import StateGraph + +class RetryState(TypedDict): + task_id: str + retry_count: int + max_retries: int + last_error: Optional[str] + # ... 기타 필드 + +def build_retry_aware_pipeline(): + graph = StateGraph(RetryState) + + async def generate_song_with_retry(state: RetryState) -> RetryState: + """재시도 로직이 포함된 음악 생성""" + try: + # 1차 시도: Suno API + result = await suno_generate(state["lyric"]) + return {**state, "song_url": result, "retry_count": 0} + + except SunoRateLimitError: + # 재시도 1: 딜레이 후 재시도 + if state["retry_count"] < state["max_retries"]: + await asyncio.sleep(30) # 30초 대기 + return { + **state, + "retry_count": state["retry_count"] + 1, + "last_error": "rate_limit" + } + + except SunoAPIError as e: + # 재시도 2: 프롬프트 수정 후 재시도 + if "invalid lyrics" in str(e) and state["retry_count"] < 2: + simplified_lyric = await simplify_lyrics(state["lyric"]) + return { + **state, + "lyric": simplified_lyric, + "retry_count": state["retry_count"] + 1 + } + + # 폴백: 대체 서비스 사용 + try: + result = await alternative_music_service(state["lyric"]) + return {**state, "song_url": result, "used_fallback": True} + except: + pass + + return { + **state, + "error": "All music generation attempts failed", + "song_status": "failed" + } + + # 조건부 재시도 엣지 + def should_retry_song(state: RetryState): + if state.get("song_url"): + return "next_step" + if state["retry_count"] < state["max_retries"]: + return "retry_song" + return "handle_error" + + graph.add_conditional_edges( + "generate_song", + should_retry_song, + { + "retry_song": "generate_song", # 자기 자신으로 루프 + "next_step": "request_video", + "handle_error": "handle_error" + } + ) + + return graph.compile() +``` + +### 3.4 설계 3: 병렬 처리 지원 + +```python +from langgraph.types import Send +from langgraph.graph import StateGraph + +class ParallelState(TypedDict): + task_id: str + images: list[str] + analyzed_images: list[dict] # 병렬 분석 결과 + # ... + +def build_parallel_pipeline(): + graph = StateGraph(ParallelState) + + # 이미지 분석을 병렬로 수행 + async def analyze_single_image(state: dict) -> dict: + """단일 이미지 분석""" + image_url = state["image_url"] + analysis = await vision_model.analyze(image_url) + return { + "image_url": image_url, + "analysis": analysis, + "mood": analysis.get("mood"), + "colors": analysis.get("dominant_colors") + } + + # 팬아웃: 여러 이미지를 병렬로 분석 + def fanout_images(state: ParallelState): + return [ + Send("analyze_image", {"image_url": img, "task_id": state["task_id"]}) + for img in state["images"] + ] + + # 팬인: 분석 결과 수집 + async def collect_analyses(state: ParallelState) -> ParallelState: + # LangGraph가 자동으로 병렬 결과를 수집 + return state + + graph.add_node("analyze_image", analyze_single_image) + graph.add_node("collect", collect_analyses) + + graph.add_conditional_edges( + "start", + fanout_images # 여러 Send 반환 → 병렬 실행 + ) + + return graph.compile() +``` + +### 3.5 FastAPI 통합 + +```python +# main.py 또는 video/api/routers/v1/video.py + +from fastapi import APIRouter, BackgroundTasks +from langgraph.graph import StateGraph + +router = APIRouter() +pipeline = build_video_pipeline() + +@router.post("/video/generate-full") +async def generate_full_video( + request: FullVideoRequest, + background_tasks: BackgroundTasks +): + """단일 API 호출로 전체 파이프라인 실행""" + + initial_state: PipelineState = { + "task_id": str(uuid7()), + "customer_name": request.customer_name, + "region": request.region, + "detail_info": request.detail_info, + "language": request.language, + "images": request.images, + "orientation": request.orientation, + "lyric": None, + "lyric_status": None, + "song_url": None, + "song_task_id": None, + "song_status": None, + "song_duration": None, + "video_url": None, + "video_render_id": None, + "video_status": None, + "error": None, + "error_step": None, + "started_at": datetime.now(), + "completed_at": None, + "retry_count": 0 + } + + # 백그라운드에서 파이프라인 실행 + background_tasks.add_task(run_pipeline_async, initial_state) + + return { + "task_id": initial_state["task_id"], + "status": "processing", + "message": "Pipeline started. Use GET /video/pipeline-status/{task_id} to check progress." + } + +async def run_pipeline_async(initial_state: PipelineState): + """백그라운드에서 LangGraph 파이프라인 실행""" + try: + final_state = await pipeline.ainvoke(initial_state) + + # 결과 DB 저장 + await save_pipeline_result(final_state) + + # 완료 알림 (웹훅, 이메일 등) + if final_state.get("video_url"): + await send_completion_notification(final_state) + + except Exception as e: + await log_pipeline_error(initial_state["task_id"], str(e)) + +@router.get("/video/pipeline-status/{task_id}") +async def get_pipeline_status(task_id: str): + """파이프라인 진행 상태 조회""" + status = await get_status_from_db(task_id) + + return { + "task_id": task_id, + "lyric_status": status.lyric_status, + "song_status": status.song_status, + "video_status": status.video_status, + "overall_status": determine_overall_status(status), + "video_url": status.video_url if status.video_status == "completed" else None, + "error": status.error + } +``` + +--- + +## 4. RAG 적용 설계 + +### 4.1 적용 대상 및 목적 + +RAG(Retrieval-Augmented Generation)는 **외부 지식 기반을 검색하여 LLM 응답 품질을 향상**시키는 기법입니다. + +**적용 대상:** +1. 마케팅 지식베이스 (성공 사례) +2. 지역별/업종별 가사 예시 +3. 이미지 메타데이터 활용 +4. 프롬프트 최적화 + +### 4.2 설계 1: 마케팅 지식베이스 RAG + +**아키텍처:** + +``` +┌─────────────────────────────────────────────────────────────┐ +│ 마케팅 지식베이스 │ +├─────────────────────────────────────────────────────────────┤ +│ │ +│ Document Store (벡터 DB) │ +│ ┌─────────────────────────────────────────────────────┐ │ +│ │ Collection: marketing_knowledge │ │ +│ │ │ │ +│ │ ┌──────────────────────────────────────────────┐ │ │ +│ │ │ 문서 1: 강원도 속초 펜션 마케팅 성공 사례 │ │ │ +│ │ │ - 가사 예시 │ │ │ +│ │ │ - 타겟 고객 분석 │ │ │ +│ │ │ - 효과적인 키워드 │ │ │ +│ │ │ - 영상 조회수/반응 │ │ │ +│ │ └──────────────────────────────────────────────┘ │ │ +│ │ │ │ +│ │ ┌──────────────────────────────────────────────┐ │ │ +│ │ │ 문서 2: 제주도 게스트하우스 마케팅 사례 │ │ │ +│ │ │ ... │ │ │ +│ │ └──────────────────────────────────────────────┘ │ │ +│ │ │ │ +│ │ ... (수백 개의 사례) │ │ +│ └─────────────────────────────────────────────────────┘ │ +│ │ +└─────────────────────────────────────────────────────────────┘ + │ + │ 유사도 검색 + ▼ +┌─────────────────────────────────────────────────────────────┐ +│ 가사 생성 프롬프트 │ +├─────────────────────────────────────────────────────────────┤ +│ "다음 유사 사례를 참고하여 가사를 생성하세요: │ +│ [검색된 성공 사례 1] │ +│ [검색된 성공 사례 2] │ +│ ..." │ +└─────────────────────────────────────────────────────────────┘ +``` + +**구현 코드:** + +```python +from langchain.embeddings.openai import OpenAIEmbeddings +from langchain.vectorstores import Chroma +from langchain.document_loaders import JSONLoader +from langchain.text_splitter import RecursiveCharacterTextSplitter +from langchain.schema import Document + +# 1. 임베딩 모델 설정 +embeddings = OpenAIEmbeddings( + model="text-embedding-3-small", + openai_api_key=settings.CHATGPT_API_KEY +) + +# 2. 벡터 스토어 초기화 +vector_store = Chroma( + collection_name="marketing_knowledge", + embedding_function=embeddings, + persist_directory="./data/chroma_db" +) + +# 3. 마케팅 사례 문서 구조 +class MarketingCase(BaseModel): + case_id: str + region: str + business_type: str # "pension", "guesthouse", "hotel" + target_audience: str + successful_lyrics: str + keywords: list[str] + performance_metrics: dict # views, engagement, conversions + created_at: datetime + +# 4. 문서 추가 함수 +async def add_marketing_case(case: MarketingCase): + """성공한 마케팅 사례를 벡터 스토어에 추가""" + + # 메타데이터와 함께 문서 생성 + document = Document( + page_content=f""" +지역: {case.region} +업종: {case.business_type} +타겟 고객: {case.target_audience} +성공 가사: +{case.successful_lyrics} +효과적인 키워드: {', '.join(case.keywords)} +성과: 조회수 {case.performance_metrics.get('views', 0)}, + 참여율 {case.performance_metrics.get('engagement', 0)}% + """, + metadata={ + "case_id": case.case_id, + "region": case.region, + "business_type": case.business_type, + "created_at": case.created_at.isoformat() + } + ) + + vector_store.add_documents([document]) + vector_store.persist() + +# 5. RAG 기반 가사 생성 +async def generate_lyrics_with_rag( + customer_name: str, + region: str, + business_type: str, + language: str +) -> str: + """RAG를 활용한 고품질 가사 생성""" + + # 유사 사례 검색 + query = f"{region} {business_type} 마케팅 가사" + similar_cases = vector_store.similarity_search( + query, + k=3, + filter={"business_type": business_type} # 같은 업종만 + ) + + # 검색 결과를 프롬프트에 포함 + examples_text = "\n\n".join([ + f"### 참고 사례 {i+1}\n{doc.page_content}" + for i, doc in enumerate(similar_cases) + ]) + + # LangChain 프롬프트 구성 + rag_prompt = ChatPromptTemplate.from_messages([ + ("system", """당신은 마케팅 전문가이자 작사가입니다. +다음 성공 사례를 참고하여 새로운 가사를 생성하세요. +참고 사례의 스타일과 키워드를 활용하되, 고유한 내용을 만드세요. + +{examples}"""), + ("human", """ +고객명: {customer_name} +지역: {region} +언어: {language} + +위 정보를 바탕으로 8-12줄의 감성적인 마케팅 가사를 생성하세요. +""") + ]) + + chain = rag_prompt | ChatOpenAI(model="gpt-5-mini") | StrOutputParser() + + result = await chain.ainvoke({ + "examples": examples_text, + "customer_name": customer_name, + "region": region, + "language": language + }) + + return result +``` + +### 4.3 설계 2: 지역별 특화 RAG + +**목적:** 각 지역의 특성(문화, 관광지, 특산물 등)을 반영한 가사 생성 + +```python +# 지역 정보 문서 구조 +class RegionInfo(BaseModel): + region_name: str + province: str + famous_attractions: list[str] + local_foods: list[str] + cultural_keywords: list[str] + seasonal_events: list[dict] # {"season": "summer", "event": "해수욕장 개장"} + atmosphere: list[str] # ["고즈넉한", "활기찬", "낭만적인"] + +# 지역 정보 벡터 스토어 +region_store = Chroma( + collection_name="region_knowledge", + embedding_function=embeddings, + persist_directory="./data/chroma_region" +) + +# 지역 정보 추가 예시 +regions_data = [ + RegionInfo( + region_name="속초", + province="강원도", + famous_attractions=["설악산", "속초해변", "영금정", "아바이마을"], + local_foods=["오징어순대", "물회", "생선구이"], + cultural_keywords=["동해바다", "일출", "산과 바다", "청정자연"], + seasonal_events=[ + {"season": "summer", "event": "속초해변 피서"}, + {"season": "autumn", "event": "설악산 단풍"} + ], + atmosphere=["시원한", "청량한", "자연친화적", "힐링"] + ), + # ... 더 많은 지역 +] + +async def enrich_lyrics_with_region_info( + base_lyrics: str, + region: str +) -> str: + """지역 정보로 가사 보강""" + + # 지역 정보 검색 + region_docs = region_store.similarity_search(region, k=1) + + if not region_docs: + return base_lyrics + + region_info = region_docs[0].page_content + + # 가사에 지역 특성 반영 + enrichment_prompt = ChatPromptTemplate.from_messages([ + ("system", """당신은 가사 편집 전문가입니다. +주어진 기본 가사에 지역의 특성을 자연스럽게 녹여내세요. +지역 정보: +{region_info}"""), + ("human", """기본 가사: +{base_lyrics} + +위 가사에 지역의 특성(명소, 분위기, 키워드)을 2-3개 자연스럽게 추가하세요. +원래 가사의 운율과 분위기를 유지하세요.""") + ]) + + chain = enrichment_prompt | ChatOpenAI() | StrOutputParser() + + return await chain.ainvoke({ + "region_info": region_info, + "base_lyrics": base_lyrics + }) +``` + +### 4.4 설계 3: 이미지 메타데이터 RAG + +**목적:** 업로드된 이미지의 분석 결과를 저장하고, 영상 생성 시 최적의 이미지 순서 결정 + +```python +from langchain_openai import ChatOpenAI + +# Vision 모델로 이미지 분석 +vision_model = ChatOpenAI(model="gpt-5-mini") + +# 이미지 분석 문서 구조 +class ImageAnalysis(BaseModel): + image_url: str + task_id: str + description: str + dominant_colors: list[str] + mood: str # "warm", "cool", "neutral" + scene_type: str # "interior", "exterior", "nature", "food" + suggested_position: str # "opening", "middle", "closing" + quality_score: float # 0.0 ~ 1.0 + +# 이미지 메타데이터 벡터 스토어 +image_store = Chroma( + collection_name="image_metadata", + embedding_function=embeddings, + persist_directory="./data/chroma_images" +) + +async def analyze_and_store_image(image_url: str, task_id: str): + """이미지 분석 후 벡터 스토어에 저장""" + + # gpt-5-mini Vision으로 이미지 분석 + analysis_response = await vision_model.ainvoke([ + { + "type": "text", + "text": """이미지를 분석하고 다음 JSON 형식으로 응답하세요: +{ + "description": "이미지 설명 (2-3문장)", + "dominant_colors": ["색상1", "색상2"], + "mood": "warm/cool/neutral 중 하나", + "scene_type": "interior/exterior/nature/food 중 하나", + "suggested_position": "opening/middle/closing 중 하나 (영상에서 적합한 위치)", + "quality_score": 0.0~1.0 (이미지 품질/선명도) +}""" + }, + { + "type": "image_url", + "image_url": {"url": image_url} + } + ]) + + analysis = json.loads(analysis_response.content) + + # 문서 생성 및 저장 + document = Document( + page_content=f""" +이미지 설명: {analysis['description']} +분위기: {analysis['mood']} +장면 유형: {analysis['scene_type']} +추천 위치: {analysis['suggested_position']} +색상: {', '.join(analysis['dominant_colors'])} + """, + metadata={ + "image_url": image_url, + "task_id": task_id, + **analysis + } + ) + + image_store.add_documents([document]) + image_store.persist() + + return ImageAnalysis(image_url=image_url, task_id=task_id, **analysis) + +async def get_optimal_image_order( + task_id: str, + music_mood: str, # 음악 분위기 + lyrics_theme: str # 가사 주제 +) -> list[str]: + """음악과 가사에 맞는 최적의 이미지 순서 결정""" + + # 해당 task의 모든 이미지 조회 + all_images = image_store.get( + where={"task_id": task_id} + ) + + # 음악/가사 분위기에 맞는 이미지 우선 검색 + query = f"{music_mood} {lyrics_theme} 마케팅 영상" + sorted_images = image_store.similarity_search( + query, + k=len(all_images), + filter={"task_id": task_id} + ) + + # 이미지 순서 결정 로직 + opening_images = [img for img in sorted_images if img.metadata["suggested_position"] == "opening"] + middle_images = [img for img in sorted_images if img.metadata["suggested_position"] == "middle"] + closing_images = [img for img in sorted_images if img.metadata["suggested_position"] == "closing"] + + # 품질 점수로 정렬 + opening_images.sort(key=lambda x: x.metadata["quality_score"], reverse=True) + closing_images.sort(key=lambda x: x.metadata["quality_score"], reverse=True) + + # 최종 순서 + ordered = ( + opening_images[:2] + # 시작 2장 + middle_images + # 중간 이미지들 + closing_images[:1] # 마무리 1장 + ) + + return [img.metadata["image_url"] for img in ordered] +``` + +### 4.5 설계 4: 프롬프트 히스토리 RAG + +**목적:** 과거 성공/실패한 프롬프트를 학습하여 프롬프트 품질 지속 개선 + +```python +# 프롬프트 결과 문서 구조 +class PromptResult(BaseModel): + prompt_id: str + prompt_text: str + result_text: str + success: bool + failure_reason: Optional[str] + category: str # "lyric", "marketing_analysis", "region_enrichment" + metrics: dict # {"length": 10, "contains_region_keyword": True, ...} + created_at: datetime + +# 프롬프트 히스토리 벡터 스토어 +prompt_store = Chroma( + collection_name="prompt_history", + embedding_function=embeddings, + persist_directory="./data/chroma_prompts" +) + +async def log_prompt_result(result: PromptResult): + """프롬프트 결과 기록""" + + document = Document( + page_content=f""" +프롬프트: {result.prompt_text} +결과: {result.result_text[:500]}... +성공 여부: {'성공' if result.success else '실패'} +실패 사유: {result.failure_reason or 'N/A'} + """, + metadata={ + "prompt_id": result.prompt_id, + "success": result.success, + "category": result.category, + "created_at": result.created_at.isoformat(), + **result.metrics + } + ) + + prompt_store.add_documents([document]) + +async def get_improved_prompt( + base_prompt: str, + category: str +) -> str: + """과거 결과를 기반으로 프롬프트 개선""" + + # 유사한 성공 프롬프트 검색 + successful_prompts = prompt_store.similarity_search( + base_prompt, + k=3, + filter={"success": True, "category": category} + ) + + # 유사한 실패 프롬프트 검색 (피해야 할 패턴) + failed_prompts = prompt_store.similarity_search( + base_prompt, + k=2, + filter={"success": False, "category": category} + ) + + # 프롬프트 개선 요청 + improvement_prompt = ChatPromptTemplate.from_messages([ + ("system", """당신은 프롬프트 엔지니어링 전문가입니다. + +다음 성공/실패 사례를 참고하여 주어진 프롬프트를 개선하세요. + +### 성공 사례 (참고): +{successful_examples} + +### 실패 사례 (피할 것): +{failed_examples} + +### 개선 원칙: +1. 성공 사례의 패턴을 따르세요 +2. 실패 사례의 패턴을 피하세요 +3. 명확하고 구체적인 지시를 포함하세요 +4. 출력 형식을 명시하세요"""), + ("human", """개선할 프롬프트: +{base_prompt} + +위 프롬프트를 개선하세요. 개선된 프롬프트만 출력하세요.""") + ]) + + chain = improvement_prompt | ChatOpenAI() | StrOutputParser() + + improved = await chain.ainvoke({ + "successful_examples": "\n---\n".join([doc.page_content for doc in successful_prompts]), + "failed_examples": "\n---\n".join([doc.page_content for doc in failed_prompts]), + "base_prompt": base_prompt + }) + + return improved +``` + +--- + +## 5. 통합 아키텍처 + +### 5.1 전체 시스템 아키텍처 + +``` +┌──────────────────────────────────────────────────────────────────────────┐ +│ FastAPI 라우터 │ +│ /lyric/generate, /song/generate, /video/generate, /video/generate-full │ +└───────────────────────────────────┬──────────────────────────────────────┘ + │ + ▼ +┌──────────────────────────────────────────────────────────────────────────┐ +│ LangGraph 파이프라인 │ +│ ┌─────────────────────────────────────────────────────────────────┐ │ +│ │ StateGraph (상태 기계) │ │ +│ │ │ │ +│ │ [generate_lyric] → [request_song] → [poll_song] │ │ +│ │ │ │ │ │ +│ │ │ ▼ │ │ +│ │ │ [request_video] → [poll_video] → END │ │ +│ │ │ │ │ │ +│ │ └─────────────────────┴──────────→ [handle_error] │ │ +│ └─────────────────────────────────────────────────────────────────┘ │ +│ │ │ +│ ┌───────────────┼───────────────┐ │ +│ │ │ │ │ +│ ▼ ▼ ▼ │ +│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ +│ │ LangChain │ │ RAG │ │ External │ │ +│ │ Components │ │ Vector DBs │ │ APIs │ │ +│ └─────────────┘ └─────────────┘ └─────────────┘ │ +└──────────────────────────────────────────────────────────────────────────┘ + │ │ │ + ┌───────────┘ ┌──────────┘ ┌──────────┘ + │ │ │ + ▼ ▼ ▼ +┌─────────────┐ ┌─────────────┐ ┌─────────────┐ +│ Prompt │ │ Chroma │ │ OpenAI │ +│ Templates │ │ Vector │ │ Suno │ +│ Chains │ │ Store │ │ Creatomate │ +│ Parsers │ │ │ │ │ +└─────────────┘ └─────────────┘ └─────────────┘ + │ │ │ + └────────────────┴───────────────┘ + │ + ▼ + ┌─────────────────────────┐ + │ MySQL + Azure Blob │ + │ (영구 저장소) │ + └─────────────────────────┘ +``` + +### 5.2 데이터 흐름 + +``` +┌─────────────────────────────────────────────────────────────────────────┐ +│ 데이터 흐름 │ +├─────────────────────────────────────────────────────────────────────────┤ +│ │ +│ 1. 사용자 요청 │ +│ ├── 고객 정보 (이름, 지역, 상세정보) │ +│ └── 이미지 URL 리스트 │ +│ │ │ +│ ▼ │ +│ 2. RAG 검색 (병렬) │ +│ ├── 마케팅 지식베이스 → 유사 성공 사례 │ +│ ├── 지역 정보베이스 → 지역 특성 │ +│ └── 이미지 메타데이터 → 이미지 분석 │ +│ │ │ +│ ▼ │ +│ 3. LangChain 프롬프트 구성 │ +│ ├── 기본 템플릿 로드 │ +│ ├── RAG 결과 주입 │ +│ ├── Few-shot 예시 추가 │ +│ └── 출력 형식 지정 │ +│ │ │ +│ ▼ │ +│ 4. LangGraph 파이프라인 실행 │ +│ ├── 가사 생성 (ChatGPT) │ +│ ├── 음악 생성 (Suno, 폴링 자동화) │ +│ └── 영상 생성 (Creatomate, 폴링 자동화) │ +│ │ │ +│ ▼ │ +│ 5. 결과 저장 │ +│ ├── MySQL: 메타데이터, 상태 │ +│ ├── Azure Blob: 영상 파일 │ +│ └── Chroma: 성공 사례 피드백 │ +│ │ │ +│ ▼ │ +│ 6. 사용자 응답 │ +│ └── 영상 URL, 상태, 메타데이터 │ +│ │ +└─────────────────────────────────────────────────────────────────────────┘ +``` + +### 5.3 디렉토리 구조 (신규) + +``` +app/ +├── langchain/ # LangChain 관련 +│ ├── __init__.py +│ ├── prompts/ +│ │ ├── __init__.py +│ │ ├── lyric_prompts.py # 가사 생성 프롬프트 +│ │ ├── marketing_prompts.py # 마케팅 분석 프롬프트 +│ │ └── examples/ # Few-shot 예시 +│ │ ├── korean.json +│ │ ├── english.json +│ │ └── ... +│ ├── chains/ +│ │ ├── __init__.py +│ │ ├── lyric_chain.py # 가사 생성 체인 +│ │ └── marketing_chain.py # 마케팅 분석 체인 +│ └── parsers/ +│ ├── __init__.py +│ └── lyric_parser.py # 가사 출력 파서 +│ +├── langgraph/ # LangGraph 관련 +│ ├── __init__.py +│ ├── states/ +│ │ ├── __init__.py +│ │ └── pipeline_state.py # 파이프라인 상태 정의 +│ ├── nodes/ +│ │ ├── __init__.py +│ │ ├── lyric_node.py # 가사 생성 노드 +│ │ ├── song_node.py # 음악 생성 노드 +│ │ ├── video_node.py # 영상 생성 노드 +│ │ └── error_node.py # 에러 처리 노드 +│ └── graphs/ +│ ├── __init__.py +│ └── video_pipeline.py # 메인 파이프라인 그래프 +│ +├── rag/ # RAG 관련 +│ ├── __init__.py +│ ├── stores/ +│ │ ├── __init__.py +│ │ ├── marketing_store.py # 마케팅 지식베이스 +│ │ ├── region_store.py # 지역 정보베이스 +│ │ ├── image_store.py # 이미지 메타데이터 +│ │ └── prompt_store.py # 프롬프트 히스토리 +│ ├── loaders/ +│ │ ├── __init__.py +│ │ └── case_loader.py # 사례 데이터 로더 +│ └── retrievers/ +│ ├── __init__.py +│ └── hybrid_retriever.py # 하이브리드 검색 +│ +└── data/ # 데이터 저장소 + └── chroma_db/ # Chroma 벡터 DB + ├── marketing_knowledge/ + ├── region_knowledge/ + ├── image_metadata/ + └── prompt_history/ +``` + +--- + +## 6. 기대 효과 + +### 6.1 정량적 기대 효과 + +| 지표 | 현재 | 목표 | 개선율 | +|------|------|------|--------| +| **가사 생성 품질** | 70% 만족도 | 90% 만족도 | +29% | +| **재작업률** | 30% | 10% | -67% | +| **파이프라인 실패율** | 15% | 5% | -67% | +| **평균 처리 시간** | 10분 (수동 개입 필요) | 8분 (완전 자동) | -20% | +| **다국어 품질** | 60% | 85% | +42% | +| **프롬프트 튜닝 시간** | 2시간/버전 | 30분/버전 | -75% | + +### 6.2 정성적 기대 효과 + +#### 6.2.1 개발 생산성 향상 + +| 영역 | 효과 | +|------|------| +| **코드 유지보수** | 프롬프트와 비즈니스 로직 분리로 수정 용이 | +| **테스트 용이성** | 각 체인/노드 단위 테스트 가능 | +| **디버깅** | 상태 기계 기반으로 문제 지점 명확히 파악 | +| **확장성** | 새로운 AI 서비스 추가 시 노드만 추가하면 됨 | + +#### 6.2.2 품질 향상 + +| 영역 | 효과 | +|------|------| +| **일관성** | 동일 조건에서 일관된 품질의 결과물 생성 | +| **지역 맞춤화** | RAG로 지역별 특성 자동 반영 | +| **학습 효과** | 성공 사례 축적으로 시간이 지날수록 품질 향상 | +| **에러 복구** | 자동 재시도 및 폴백으로 안정성 강화 | + +#### 6.2.3 운영 효율성 + +| 영역 | 효과 | +|------|------| +| **모니터링** | 파이프라인 상태 추적으로 병목 지점 파악 | +| **비용 최적화** | 불필요한 API 호출 감소, 캐싱 활용 | +| **확장 대응** | 부하 증가 시 노드별 스케일링 가능 | + +### 6.3 비즈니스 가치 + +``` +┌────────────────────────────────────────────────────────────────┐ +│ 비즈니스 가치 │ +├────────────────────────────────────────────────────────────────┤ +│ │ +│ 1. 고객 만족도 향상 │ +│ └── 고품질 가사/영상으로 마케팅 효과 증대 │ +│ │ +│ 2. 서비스 차별화 │ +│ └── 지역 맞춤 콘텐츠로 경쟁사 대비 우위 │ +│ │ +│ 3. 운영 비용 절감 │ +│ └── 자동화로 수동 개입 최소화 │ +│ │ +│ 4. 확장 가능성 │ +│ └── 새로운 지역/업종 추가 시 RAG 학습만으로 대응 │ +│ │ +│ 5. 데이터 자산화 │ +│ └── 축적된 성공 사례가 진입 장벽 역할 │ +│ │ +└────────────────────────────────────────────────────────────────┘ +``` + +--- + +## 7. 구현 로드맵 + +### 7.1 Phase 1: 기초 (1-2주) + +**목표:** LangChain 기본 구조 구축 + +| 작업 | 설명 | 우선순위 | +|------|------|----------| +| 의존성 설치 | langchain, langchain-openai, chromadb | P0 | +| 프롬프트 템플릿 작성 | 가사 생성 프롬프트 이관 | P0 | +| 기본 체인 구현 | ChatGPT 서비스 LangChain으로 래핑 | P0 | +| 출력 파서 구현 | 가사 응답 검증 및 파싱 | P1 | +| 테스트 작성 | 체인 단위 테스트 | P1 | + +**산출물:** +- `app/langchain/` 디렉토리 구조 +- 가사 생성 LangChain 체인 +- 기본 테스트 코드 + +### 7.2 Phase 2: 파이프라인 (2-3주) + +**목표:** LangGraph 파이프라인 구축 + +| 작업 | 설명 | 우선순위 | +|------|------|----------| +| 상태 정의 | PipelineState TypedDict 작성 | P0 | +| 노드 구현 | 가사, 음악, 영상 생성 노드 | P0 | +| 그래프 구성 | 엣지 및 조건부 분기 정의 | P0 | +| 폴링 통합 | Suno, Creatomate 폴링 자동화 | P0 | +| 에러 처리 | 에러 노드 및 재시도 로직 | P1 | +| FastAPI 통합 | 새 엔드포인트 추가 | P1 | + +**산출물:** +- `app/langgraph/` 디렉토리 구조 +- 통합 파이프라인 그래프 +- `/video/generate-full` 엔드포인트 + +### 7.3 Phase 3: RAG (2-3주) + +**목표:** 지식베이스 구축 및 RAG 통합 + +| 작업 | 설명 | 우선순위 | +|------|------|----------| +| Chroma 설정 | 벡터 스토어 초기화 | P0 | +| 마케팅 사례 수집 | 기존 성공 사례 데이터화 | P0 | +| 지역 정보 구축 | 주요 지역 정보 입력 | P1 | +| 검색 통합 | 가사 생성 시 RAG 적용 | P0 | +| 이미지 분석 | Vision API 연동 | P2 | +| 프롬프트 히스토리 | 자동 학습 파이프라인 | P2 | + +**산출물:** +- `app/rag/` 디렉토리 구조 +- 마케팅/지역 지식베이스 +- RAG 통합 가사 생성 + +### 7.4 Phase 4: 고도화 (2-3주) + +**목표:** 최적화 및 모니터링 + +| 작업 | 설명 | 우선순위 | +|------|------|----------| +| 성능 최적화 | 캐싱, 병렬 처리 개선 | P1 | +| 모니터링 | 파이프라인 상태 대시보드 | P1 | +| A/B 테스팅 | 프롬프트 버전 비교 | P2 | +| 문서화 | API 문서, 운영 가이드 | P1 | +| 부하 테스트 | 동시 요청 처리 검증 | P2 | + +**산출물:** +- 최적화된 파이프라인 +- 모니터링 대시보드 +- 완성된 문서 + +--- + +## 8. 결론 + +### 8.1 요약 + +CastAD 백엔드에 LangChain, LangGraph, RAG를 적용하면: + +1. **LangChain**: 프롬프트 관리 체계화, 다단계 체인 구성, 출력 검증 자동화 +2. **LangGraph**: 복잡한 파이프라인 상태 관리, 폴링 자동화, 에러 처리 강화 +3. **RAG**: 과거 성공 사례 활용, 지역별 맞춤화, 지속적 품질 개선 + +### 8.2 핵심 가치 + +``` +┌───────────────────────────────────────────────────────────┐ +│ │ +│ 현재: 각 단계가 독립적 → 상태 관리 어려움 │ +│ 개선: 통합 파이프라인 → 자동화된 상태 추적 │ +│ │ +│ 현재: 하드코딩 프롬프트 → 수정 어려움 │ +│ 개선: 템플릿 기반 → 유연한 프롬프트 관리 │ +│ │ +│ 현재: 과거 데이터 미활용 → 일관성 없는 품질 │ +│ 개선: RAG 지식베이스 → 축적된 노하우 활용 │ +│ │ +└───────────────────────────────────────────────────────────┘ +``` + +### 8.3 권장 사항 + +1. **단계적 도입**: Phase 1(LangChain)부터 시작하여 검증 후 확장 +2. **기존 API 유지**: 새 엔드포인트 추가 방식으로 호환성 보장 +3. **데이터 축적 우선**: RAG 효과를 위해 초기 사례 데이터 확보 중요 +4. **모니터링 병행**: 각 단계별 성과 측정으로 ROI 검증 + +--- + +## 부록 + +### A. 필요 의존성 + +```toml +# pyproject.toml 추가 의존성 +[project.dependencies] +langchain = ">=0.1.0" +langchain-openai = ">=0.0.5" +langchain-community = ">=0.0.20" +langgraph = ">=0.0.30" +chromadb = ">=0.4.22" +tiktoken = ">=0.5.2" +``` + +### B. 환경 변수 추가 + +```env +# .env 추가 +CHROMA_PERSIST_DIR=./data/chroma_db +LANGCHAIN_TRACING_V2=true # 선택: LangSmith 모니터링 +LANGCHAIN_API_KEY=xxx # 선택: LangSmith 모니터링 +``` + +### C. 참고 자료 + +- [LangChain Documentation](https://python.langchain.com/) +- [LangGraph Documentation](https://langchain-ai.github.io/langgraph/) +- [Chroma Documentation](https://docs.trychroma.com/) +- [OpenAI Cookbook](https://cookbook.openai.com/) + +--- + +*이 보고서는 CastAD 백엔드 프로젝트 분석을 기반으로 작성되었습니다.* +*작성일: 2025-12-28* diff --git a/docs/analysis/orm_report.md b/docs/analysis/orm_report.md index e430040..12c30e4 100644 --- a/docs/analysis/orm_report.md +++ b/docs/analysis/orm_report.md @@ -1,500 +1,500 @@ -# ORM 동기식 전환 보고서 - -## 개요 - -현재 프로젝트는 **SQLAlchemy 2.0+ 비동기 방식**으로 구현되어 있습니다. 이 보고서는 동기식으로 전환할 경우 필요한 코드 수정 사항을 정리합니다. - ---- - -## 1. 현재 비동기 구현 현황 - -### 1.1 사용 중인 라이브러리 -- `sqlalchemy[asyncio]>=2.0.45` -- `asyncmy>=0.2.10` (MySQL 비동기 드라이버) -- `aiomysql>=0.3.2` - -### 1.2 주요 비동기 컴포넌트 -| 컴포넌트 | 현재 (비동기) | 변경 후 (동기) | -|---------|-------------|--------------| -| 엔진 | `create_async_engine` | `create_engine` | -| 세션 팩토리 | `async_sessionmaker` | `sessionmaker` | -| 세션 클래스 | `AsyncSession` | `Session` | -| DB 드라이버 | `mysql+asyncmy` | `mysql+pymysql` | - ---- - -## 2. 파일별 수정 사항 - -### 2.1 pyproject.toml - 의존성 변경 - -**파일**: `pyproject.toml` - -```diff -dependencies = [ - "fastapi[standard]>=0.115.8", -- "sqlalchemy[asyncio]>=2.0.45", -+ "sqlalchemy>=2.0.45", -- "asyncmy>=0.2.10", -- "aiomysql>=0.3.2", -+ "pymysql>=1.1.0", - ... -] -``` - ---- - -### 2.2 config.py - 데이터베이스 URL 변경 - -**파일**: `config.py` (라인 74-96) - -```diff -class DatabaseSettings(BaseSettings): - @property - def MYSQL_URL(self) -> str: -- return f"mysql+asyncmy://{self.MYSQL_USER}:{self.MYSQL_PASSWORD}@{self.MYSQL_HOST}:{self.MYSQL_PORT}/{self.MYSQL_DB}" -+ return f"mysql+pymysql://{self.MYSQL_USER}:{self.MYSQL_PASSWORD}@{self.MYSQL_HOST}:{self.MYSQL_PORT}/{self.MYSQL_DB}" -``` - ---- - -### 2.3 app/database/session.py - 세션 설정 전면 수정 - -**파일**: `app/database/session.py` - -#### 현재 코드 (비동기) -```python -from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine -from typing import AsyncGenerator - -engine = create_async_engine( - url=db_settings.MYSQL_URL, - echo=False, - pool_size=10, - max_overflow=10, - pool_timeout=5, - pool_recycle=3600, - pool_pre_ping=True, - pool_reset_on_return="rollback", -) - -AsyncSessionLocal = async_sessionmaker( - bind=engine, - class_=AsyncSession, - expire_on_commit=False, - autoflush=False, -) - -async def get_session() -> AsyncGenerator[AsyncSession, None]: - async with AsyncSessionLocal() as session: - try: - yield session - except Exception as e: - await session.rollback() - raise e -``` - -#### 변경 후 코드 (동기) -```python -from sqlalchemy import create_engine -from sqlalchemy.orm import Session, sessionmaker -from typing import Generator - -engine = create_engine( - url=db_settings.MYSQL_URL, - echo=False, - pool_size=10, - max_overflow=10, - pool_timeout=5, - pool_recycle=3600, - pool_pre_ping=True, - pool_reset_on_return="rollback", -) - -SessionLocal = sessionmaker( - bind=engine, - class_=Session, - expire_on_commit=False, - autoflush=False, -) - -def get_session() -> Generator[Session, None, None]: - with SessionLocal() as session: - try: - yield session - except Exception as e: - session.rollback() - raise e -``` - -#### get_worker_session 함수 변경 - -```diff -- from contextlib import asynccontextmanager -+ from contextlib import contextmanager - -- @asynccontextmanager -- async def get_worker_session() -> AsyncGenerator[AsyncSession, None]: -- worker_engine = create_async_engine( -+ @contextmanager -+ def get_worker_session() -> Generator[Session, None, None]: -+ worker_engine = create_engine( - url=db_settings.MYSQL_URL, - poolclass=NullPool, - ) -- session_factory = async_sessionmaker( -- bind=worker_engine, -- class_=AsyncSession, -+ session_factory = sessionmaker( -+ bind=worker_engine, -+ class_=Session, - expire_on_commit=False, - autoflush=False, - ) - -- async with session_factory() as session: -+ with session_factory() as session: - try: - yield session - finally: -- await session.close() -- await worker_engine.dispose() -+ session.close() -+ worker_engine.dispose() -``` - ---- - -### 2.4 app/*/dependencies.py - 타입 힌트 변경 - -**파일**: `app/song/dependencies.py`, `app/lyric/dependencies.py`, `app/video/dependencies.py` - -```diff -- from sqlalchemy.ext.asyncio import AsyncSession -+ from sqlalchemy.orm import Session - -- SessionDep = Annotated[AsyncSession, Depends(get_session)] -+ SessionDep = Annotated[Session, Depends(get_session)] -``` - ---- - -### 2.5 라우터 파일들 - async/await 제거 - -**영향받는 파일**: -- `app/home/api/routers/v1/home.py` -- `app/lyric/api/routers/v1/lyric.py` -- `app/song/api/routers/v1/song.py` -- `app/video/api/routers/v1/video.py` - -#### 예시: lyric.py (라인 70-90) - -```diff -- async def get_lyric_by_task_id( -+ def get_lyric_by_task_id( - task_id: str, -- session: AsyncSession = Depends(get_session), -+ session: Session = Depends(get_session), - ): -- result = await session.execute(select(Lyric).where(Lyric.task_id == task_id)) -+ result = session.execute(select(Lyric).where(Lyric.task_id == task_id)) - lyric = result.scalar_one_or_none() - ... -``` - -#### 예시: CRUD 작업 (라인 218-260) - -```diff -- async def create_project( -+ def create_project( - request_body: ProjectCreateRequest, -- session: AsyncSession = Depends(get_session), -+ session: Session = Depends(get_session), - ): - project = Project( - store_name=request_body.customer_name, - region=request_body.region, - task_id=task_id, - ) - session.add(project) -- await session.commit() -- await session.refresh(project) -+ session.commit() -+ session.refresh(project) - return project -``` - -#### 예시: 플러시 작업 (home.py 라인 340-350) - -```diff - session.add(image) -- await session.flush() -+ session.flush() - result = image.id -``` - ---- - -### 2.6 서비스 파일들 - Raw SQL 쿼리 변경 - -**영향받는 파일**: -- `app/lyric/services/lyrics.py` -- `app/song/services/song.py` -- `app/video/services/video.py` - -#### 예시: lyrics.py (라인 20-30) - -```diff -- async def get_store_default_info(conn: AsyncConnection): -+ def get_store_default_info(conn: Connection): - query = """SELECT * FROM store_default_info;""" -- result = await conn.execute(text(query)) -+ result = conn.execute(text(query)) - return result.fetchall() -``` - -#### 예시: INSERT 쿼리 (라인 360-400) - -```diff -- async def insert_song_result(conn: AsyncConnection, params: dict): -+ def insert_song_result(conn: Connection, params: dict): - insert_query = """INSERT INTO song_results_all (...) VALUES (...)""" -- await conn.execute(text(insert_query), params) -- await conn.commit() -+ conn.execute(text(insert_query), params) -+ conn.commit() -``` - ---- - -### 2.7 app/home/services/base.py - BaseService 클래스 - -**파일**: `app/home/services/base.py` - -```diff -- from sqlalchemy.ext.asyncio import AsyncSession -+ from sqlalchemy.orm import Session - - class BaseService: -- def __init__(self, model, session: AsyncSession): -+ def __init__(self, model, session: Session): - self.model = model - self.session = session - -- async def _get(self, id: UUID): -- return await self.session.get(self.model, id) -+ def _get(self, id: UUID): -+ return self.session.get(self.model, id) - -- async def _add(self, entity): -+ def _add(self, entity): - self.session.add(entity) -- await self.session.commit() -- await self.session.refresh(entity) -+ self.session.commit() -+ self.session.refresh(entity) - return entity - -- async def _update(self, entity): -- return await self._add(entity) -+ def _update(self, entity): -+ return self._add(entity) - -- async def _delete(self, entity): -- await self.session.delete(entity) -+ def _delete(self, entity): -+ self.session.delete(entity) -``` - ---- - -## 3. 모델 파일 - 변경 불필요 - -다음 모델 파일들은 **변경이 필요 없습니다**: -- `app/home/models.py` -- `app/lyric/models.py` -- `app/song/models.py` -- `app/video/models.py` - -모델 정의 자체는 비동기/동기와 무관하게 동일합니다. `Mapped`, `mapped_column`, `relationship` 등은 그대로 사용 가능합니다. - -단, **관계 로딩 전략**에서 `lazy="selectin"` 설정은 동기 환경에서도 작동하지만, 필요에 따라 `lazy="joined"` 또는 `lazy="subquery"`로 변경할 수 있습니다. - ---- - -## 4. 수정 패턴 요약 - -### 4.1 Import 변경 패턴 - -```diff -# 엔진/세션 관련 -- from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine -+ from sqlalchemy import create_engine -+ from sqlalchemy.orm import Session, sessionmaker - -# 타입 힌트 -- from typing import AsyncGenerator -+ from typing import Generator - -# 컨텍스트 매니저 -- from contextlib import asynccontextmanager -+ from contextlib import contextmanager -``` - -### 4.2 함수 정의 변경 패턴 - -```diff -- async def function_name(...): -+ def function_name(...): -``` - -### 4.3 await 제거 패턴 - -```diff -- result = await session.execute(query) -+ result = session.execute(query) - -- await session.commit() -+ session.commit() - -- await session.refresh(obj) -+ session.refresh(obj) - -- await session.flush() -+ session.flush() - -- await session.rollback() -+ session.rollback() - -- await session.close() -+ session.close() - -- await engine.dispose() -+ engine.dispose() -``` - -### 4.4 컨텍스트 매니저 변경 패턴 - -```diff -- async with SessionLocal() as session: -+ with SessionLocal() as session: -``` - ---- - -## 5. 영향받는 파일 목록 - -### 5.1 반드시 수정해야 하는 파일 - -| 파일 | 수정 범위 | -|-----|---------| -| `pyproject.toml` | 의존성 변경 | -| `config.py` | DB URL 변경 | -| `app/database/session.py` | 전면 수정 | -| `app/database/session-prod.py` | 전면 수정 | -| `app/home/api/routers/v1/home.py` | async/await 제거 | -| `app/lyric/api/routers/v1/lyric.py` | async/await 제거 | -| `app/song/api/routers/v1/song.py` | async/await 제거 | -| `app/video/api/routers/v1/video.py` | async/await 제거 | -| `app/lyric/services/lyrics.py` | async/await 제거 | -| `app/song/services/song.py` | async/await 제거 | -| `app/video/services/video.py` | async/await 제거 | -| `app/home/services/base.py` | async/await 제거 | -| `app/song/dependencies.py` | 타입 힌트 변경 | -| `app/lyric/dependencies.py` | 타입 힌트 변경 | -| `app/video/dependencies.py` | 타입 힌트 변경 | -| `app/dependencies/database.py` | 타입 힌트 변경 | - -### 5.2 수정 불필요한 파일 - -| 파일 | 이유 | -|-----|-----| -| `app/home/models.py` | 모델 정의는 동기/비동기 무관 | -| `app/lyric/models.py` | 모델 정의는 동기/비동기 무관 | -| `app/song/models.py` | 모델 정의는 동기/비동기 무관 | -| `app/video/models.py` | 모델 정의는 동기/비동기 무관 | - ---- - -## 6. 주의사항 - -### 6.1 FastAPI와의 호환성 - -FastAPI는 동기 엔드포인트도 지원합니다. 동기 함수는 스레드 풀에서 실행됩니다: - -```python -# 동기 엔드포인트 - FastAPI가 자동으로 스레드풀에서 실행 -@router.get("/items/{item_id}") -def get_item(item_id: int, session: Session = Depends(get_session)): - return session.get(Item, item_id) -``` - -### 6.2 성능 고려사항 - -동기식으로 전환 시 고려할 점: -- **동시성 감소**: 비동기 I/O의 이점 상실 -- **스레드 풀 의존**: 동시 요청이 많을 경우 스레드 풀 크기 조정 필요 -- **블로킹 I/O**: DB 쿼리 중 다른 요청 처리 불가 - -### 6.3 백그라운드 작업 - -현재 `get_worker_session()`으로 별도 이벤트 루프에서 실행되는 백그라운드 작업이 있습니다. 동기식 전환 시 스레드 기반 백그라운드 작업으로 변경해야 합니다: - -```python -from concurrent.futures import ThreadPoolExecutor - -executor = ThreadPoolExecutor(max_workers=4) - -def background_task(): - with get_worker_session() as session: - # 작업 수행 - pass - -# 실행 -executor.submit(background_task) -``` - ---- - -## 7. 마이그레이션 단계 - -### Step 1: 의존성 변경 -1. `pyproject.toml` 수정 -2. `pip install pymysql` 또는 `uv sync` 실행 - -### Step 2: 설정 파일 수정 -1. `config.py`의 DB URL 변경 -2. `app/database/session.py` 전면 수정 - -### Step 3: 라우터 수정 -1. 각 라우터 파일의 `async def` → `def` 변경 -2. 모든 `await` 키워드 제거 -3. `AsyncSession` → `Session` 타입 힌트 변경 - -### Step 4: 서비스 수정 -1. 서비스 파일들의 async/await 제거 -2. Raw SQL 쿼리 함수들 수정 - -### Step 5: 의존성 수정 -1. `dependencies.py` 파일들의 타입 힌트 변경 - -### Step 6: 테스트 -1. 모든 엔드포인트 기능 테스트 -2. 성능 테스트 (동시 요청 처리 확인) - ---- - -## 8. 결론 - -비동기에서 동기로 전환은 기술적으로 가능하지만, 다음을 고려해야 합니다: - -**장점**: -- 코드 복잡도 감소 (async/await 제거) -- 디버깅 용이 -- 레거시 라이브러리와의 호환성 향상 - -**단점**: -- 동시성 처리 능력 감소 -- I/O 바운드 작업에서 성능 저하 가능 -- FastAPI의 비동기 장점 미활용 - -현재 프로젝트가 FastAPI 기반이고 I/O 작업(DB, 외부 API 호출)이 많다면, **비동기 유지를 권장**합니다. 동기 전환은 특별한 요구사항(레거시 통합, 팀 역량 등)이 있을 때만 고려하시기 바랍니다. +# ORM 동기식 전환 보고서 + +## 개요 + +현재 프로젝트는 **SQLAlchemy 2.0+ 비동기 방식**으로 구현되어 있습니다. 이 보고서는 동기식으로 전환할 경우 필요한 코드 수정 사항을 정리합니다. + +--- + +## 1. 현재 비동기 구현 현황 + +### 1.1 사용 중인 라이브러리 +- `sqlalchemy[asyncio]>=2.0.45` +- `asyncmy>=0.2.10` (MySQL 비동기 드라이버) +- `aiomysql>=0.3.2` + +### 1.2 주요 비동기 컴포넌트 +| 컴포넌트 | 현재 (비동기) | 변경 후 (동기) | +|---------|-------------|--------------| +| 엔진 | `create_async_engine` | `create_engine` | +| 세션 팩토리 | `async_sessionmaker` | `sessionmaker` | +| 세션 클래스 | `AsyncSession` | `Session` | +| DB 드라이버 | `mysql+asyncmy` | `mysql+pymysql` | + +--- + +## 2. 파일별 수정 사항 + +### 2.1 pyproject.toml - 의존성 변경 + +**파일**: `pyproject.toml` + +```diff +dependencies = [ + "fastapi[standard]>=0.115.8", +- "sqlalchemy[asyncio]>=2.0.45", ++ "sqlalchemy>=2.0.45", +- "asyncmy>=0.2.10", +- "aiomysql>=0.3.2", ++ "pymysql>=1.1.0", + ... +] +``` + +--- + +### 2.2 config.py - 데이터베이스 URL 변경 + +**파일**: `config.py` (라인 74-96) + +```diff +class DatabaseSettings(BaseSettings): + @property + def MYSQL_URL(self) -> str: +- return f"mysql+asyncmy://{self.MYSQL_USER}:{self.MYSQL_PASSWORD}@{self.MYSQL_HOST}:{self.MYSQL_PORT}/{self.MYSQL_DB}" ++ return f"mysql+pymysql://{self.MYSQL_USER}:{self.MYSQL_PASSWORD}@{self.MYSQL_HOST}:{self.MYSQL_PORT}/{self.MYSQL_DB}" +``` + +--- + +### 2.3 app/database/session.py - 세션 설정 전면 수정 + +**파일**: `app/database/session.py` + +#### 현재 코드 (비동기) +```python +from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine +from typing import AsyncGenerator + +engine = create_async_engine( + url=db_settings.MYSQL_URL, + echo=False, + pool_size=10, + max_overflow=10, + pool_timeout=5, + pool_recycle=3600, + pool_pre_ping=True, + pool_reset_on_return="rollback", +) + +AsyncSessionLocal = async_sessionmaker( + bind=engine, + class_=AsyncSession, + expire_on_commit=False, + autoflush=False, +) + +async def get_session() -> AsyncGenerator[AsyncSession, None]: + async with AsyncSessionLocal() as session: + try: + yield session + except Exception as e: + await session.rollback() + raise e +``` + +#### 변경 후 코드 (동기) +```python +from sqlalchemy import create_engine +from sqlalchemy.orm import Session, sessionmaker +from typing import Generator + +engine = create_engine( + url=db_settings.MYSQL_URL, + echo=False, + pool_size=10, + max_overflow=10, + pool_timeout=5, + pool_recycle=3600, + pool_pre_ping=True, + pool_reset_on_return="rollback", +) + +SessionLocal = sessionmaker( + bind=engine, + class_=Session, + expire_on_commit=False, + autoflush=False, +) + +def get_session() -> Generator[Session, None, None]: + with SessionLocal() as session: + try: + yield session + except Exception as e: + session.rollback() + raise e +``` + +#### get_worker_session 함수 변경 + +```diff +- from contextlib import asynccontextmanager ++ from contextlib import contextmanager + +- @asynccontextmanager +- async def get_worker_session() -> AsyncGenerator[AsyncSession, None]: +- worker_engine = create_async_engine( ++ @contextmanager ++ def get_worker_session() -> Generator[Session, None, None]: ++ worker_engine = create_engine( + url=db_settings.MYSQL_URL, + poolclass=NullPool, + ) +- session_factory = async_sessionmaker( +- bind=worker_engine, +- class_=AsyncSession, ++ session_factory = sessionmaker( ++ bind=worker_engine, ++ class_=Session, + expire_on_commit=False, + autoflush=False, + ) + +- async with session_factory() as session: ++ with session_factory() as session: + try: + yield session + finally: +- await session.close() +- await worker_engine.dispose() ++ session.close() ++ worker_engine.dispose() +``` + +--- + +### 2.4 app/*/dependencies.py - 타입 힌트 변경 + +**파일**: `app/song/dependencies.py`, `app/lyric/dependencies.py`, `app/video/dependencies.py` + +```diff +- from sqlalchemy.ext.asyncio import AsyncSession ++ from sqlalchemy.orm import Session + +- SessionDep = Annotated[AsyncSession, Depends(get_session)] ++ SessionDep = Annotated[Session, Depends(get_session)] +``` + +--- + +### 2.5 라우터 파일들 - async/await 제거 + +**영향받는 파일**: +- `app/home/api/routers/v1/home.py` +- `app/lyric/api/routers/v1/lyric.py` +- `app/song/api/routers/v1/song.py` +- `app/video/api/routers/v1/video.py` + +#### 예시: lyric.py (라인 70-90) + +```diff +- async def get_lyric_by_task_id( ++ def get_lyric_by_task_id( + task_id: str, +- session: AsyncSession = Depends(get_session), ++ session: Session = Depends(get_session), + ): +- result = await session.execute(select(Lyric).where(Lyric.task_id == task_id)) ++ result = session.execute(select(Lyric).where(Lyric.task_id == task_id)) + lyric = result.scalar_one_or_none() + ... +``` + +#### 예시: CRUD 작업 (라인 218-260) + +```diff +- async def create_project( ++ def create_project( + request_body: ProjectCreateRequest, +- session: AsyncSession = Depends(get_session), ++ session: Session = Depends(get_session), + ): + project = Project( + store_name=request_body.customer_name, + region=request_body.region, + task_id=task_id, + ) + session.add(project) +- await session.commit() +- await session.refresh(project) ++ session.commit() ++ session.refresh(project) + return project +``` + +#### 예시: 플러시 작업 (home.py 라인 340-350) + +```diff + session.add(image) +- await session.flush() ++ session.flush() + result = image.id +``` + +--- + +### 2.6 서비스 파일들 - Raw SQL 쿼리 변경 + +**영향받는 파일**: +- `app/lyric/services/lyrics.py` +- `app/song/services/song.py` +- `app/video/services/video.py` + +#### 예시: lyrics.py (라인 20-30) + +```diff +- async def get_store_default_info(conn: AsyncConnection): ++ def get_store_default_info(conn: Connection): + query = """SELECT * FROM store_default_info;""" +- result = await conn.execute(text(query)) ++ result = conn.execute(text(query)) + return result.fetchall() +``` + +#### 예시: INSERT 쿼리 (라인 360-400) + +```diff +- async def insert_song_result(conn: AsyncConnection, params: dict): ++ def insert_song_result(conn: Connection, params: dict): + insert_query = """INSERT INTO song_results_all (...) VALUES (...)""" +- await conn.execute(text(insert_query), params) +- await conn.commit() ++ conn.execute(text(insert_query), params) ++ conn.commit() +``` + +--- + +### 2.7 app/home/services/base.py - BaseService 클래스 + +**파일**: `app/home/services/base.py` + +```diff +- from sqlalchemy.ext.asyncio import AsyncSession ++ from sqlalchemy.orm import Session + + class BaseService: +- def __init__(self, model, session: AsyncSession): ++ def __init__(self, model, session: Session): + self.model = model + self.session = session + +- async def _get(self, id: UUID): +- return await self.session.get(self.model, id) ++ def _get(self, id: UUID): ++ return self.session.get(self.model, id) + +- async def _add(self, entity): ++ def _add(self, entity): + self.session.add(entity) +- await self.session.commit() +- await self.session.refresh(entity) ++ self.session.commit() ++ self.session.refresh(entity) + return entity + +- async def _update(self, entity): +- return await self._add(entity) ++ def _update(self, entity): ++ return self._add(entity) + +- async def _delete(self, entity): +- await self.session.delete(entity) ++ def _delete(self, entity): ++ self.session.delete(entity) +``` + +--- + +## 3. 모델 파일 - 변경 불필요 + +다음 모델 파일들은 **변경이 필요 없습니다**: +- `app/home/models.py` +- `app/lyric/models.py` +- `app/song/models.py` +- `app/video/models.py` + +모델 정의 자체는 비동기/동기와 무관하게 동일합니다. `Mapped`, `mapped_column`, `relationship` 등은 그대로 사용 가능합니다. + +단, **관계 로딩 전략**에서 `lazy="selectin"` 설정은 동기 환경에서도 작동하지만, 필요에 따라 `lazy="joined"` 또는 `lazy="subquery"`로 변경할 수 있습니다. + +--- + +## 4. 수정 패턴 요약 + +### 4.1 Import 변경 패턴 + +```diff +# 엔진/세션 관련 +- from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine ++ from sqlalchemy import create_engine ++ from sqlalchemy.orm import Session, sessionmaker + +# 타입 힌트 +- from typing import AsyncGenerator ++ from typing import Generator + +# 컨텍스트 매니저 +- from contextlib import asynccontextmanager ++ from contextlib import contextmanager +``` + +### 4.2 함수 정의 변경 패턴 + +```diff +- async def function_name(...): ++ def function_name(...): +``` + +### 4.3 await 제거 패턴 + +```diff +- result = await session.execute(query) ++ result = session.execute(query) + +- await session.commit() ++ session.commit() + +- await session.refresh(obj) ++ session.refresh(obj) + +- await session.flush() ++ session.flush() + +- await session.rollback() ++ session.rollback() + +- await session.close() ++ session.close() + +- await engine.dispose() ++ engine.dispose() +``` + +### 4.4 컨텍스트 매니저 변경 패턴 + +```diff +- async with SessionLocal() as session: ++ with SessionLocal() as session: +``` + +--- + +## 5. 영향받는 파일 목록 + +### 5.1 반드시 수정해야 하는 파일 + +| 파일 | 수정 범위 | +|-----|---------| +| `pyproject.toml` | 의존성 변경 | +| `config.py` | DB URL 변경 | +| `app/database/session.py` | 전면 수정 | +| `app/database/session-prod.py` | 전면 수정 | +| `app/home/api/routers/v1/home.py` | async/await 제거 | +| `app/lyric/api/routers/v1/lyric.py` | async/await 제거 | +| `app/song/api/routers/v1/song.py` | async/await 제거 | +| `app/video/api/routers/v1/video.py` | async/await 제거 | +| `app/lyric/services/lyrics.py` | async/await 제거 | +| `app/song/services/song.py` | async/await 제거 | +| `app/video/services/video.py` | async/await 제거 | +| `app/home/services/base.py` | async/await 제거 | +| `app/song/dependencies.py` | 타입 힌트 변경 | +| `app/lyric/dependencies.py` | 타입 힌트 변경 | +| `app/video/dependencies.py` | 타입 힌트 변경 | +| `app/dependencies/database.py` | 타입 힌트 변경 | + +### 5.2 수정 불필요한 파일 + +| 파일 | 이유 | +|-----|-----| +| `app/home/models.py` | 모델 정의는 동기/비동기 무관 | +| `app/lyric/models.py` | 모델 정의는 동기/비동기 무관 | +| `app/song/models.py` | 모델 정의는 동기/비동기 무관 | +| `app/video/models.py` | 모델 정의는 동기/비동기 무관 | + +--- + +## 6. 주의사항 + +### 6.1 FastAPI와의 호환성 + +FastAPI는 동기 엔드포인트도 지원합니다. 동기 함수는 스레드 풀에서 실행됩니다: + +```python +# 동기 엔드포인트 - FastAPI가 자동으로 스레드풀에서 실행 +@router.get("/items/{item_id}") +def get_item(item_id: int, session: Session = Depends(get_session)): + return session.get(Item, item_id) +``` + +### 6.2 성능 고려사항 + +동기식으로 전환 시 고려할 점: +- **동시성 감소**: 비동기 I/O의 이점 상실 +- **스레드 풀 의존**: 동시 요청이 많을 경우 스레드 풀 크기 조정 필요 +- **블로킹 I/O**: DB 쿼리 중 다른 요청 처리 불가 + +### 6.3 백그라운드 작업 + +현재 `get_worker_session()`으로 별도 이벤트 루프에서 실행되는 백그라운드 작업이 있습니다. 동기식 전환 시 스레드 기반 백그라운드 작업으로 변경해야 합니다: + +```python +from concurrent.futures import ThreadPoolExecutor + +executor = ThreadPoolExecutor(max_workers=4) + +def background_task(): + with get_worker_session() as session: + # 작업 수행 + pass + +# 실행 +executor.submit(background_task) +``` + +--- + +## 7. 마이그레이션 단계 + +### Step 1: 의존성 변경 +1. `pyproject.toml` 수정 +2. `pip install pymysql` 또는 `uv sync` 실행 + +### Step 2: 설정 파일 수정 +1. `config.py`의 DB URL 변경 +2. `app/database/session.py` 전면 수정 + +### Step 3: 라우터 수정 +1. 각 라우터 파일의 `async def` → `def` 변경 +2. 모든 `await` 키워드 제거 +3. `AsyncSession` → `Session` 타입 힌트 변경 + +### Step 4: 서비스 수정 +1. 서비스 파일들의 async/await 제거 +2. Raw SQL 쿼리 함수들 수정 + +### Step 5: 의존성 수정 +1. `dependencies.py` 파일들의 타입 힌트 변경 + +### Step 6: 테스트 +1. 모든 엔드포인트 기능 테스트 +2. 성능 테스트 (동시 요청 처리 확인) + +--- + +## 8. 결론 + +비동기에서 동기로 전환은 기술적으로 가능하지만, 다음을 고려해야 합니다: + +**장점**: +- 코드 복잡도 감소 (async/await 제거) +- 디버깅 용이 +- 레거시 라이브러리와의 호환성 향상 + +**단점**: +- 동시성 처리 능력 감소 +- I/O 바운드 작업에서 성능 저하 가능 +- FastAPI의 비동기 장점 미활용 + +현재 프로젝트가 FastAPI 기반이고 I/O 작업(DB, 외부 API 호출)이 많다면, **비동기 유지를 권장**합니다. 동기 전환은 특별한 요구사항(레거시 통합, 팀 역량 등)이 있을 때만 고려하시기 바랍니다. diff --git a/docs/analysis/performance_report.md b/docs/analysis/performance_report.md index 14201a0..5ab2b61 100644 --- a/docs/analysis/performance_report.md +++ b/docs/analysis/performance_report.md @@ -1,297 +1,297 @@ -# 비동기 처리 문제 분석 보고서 - -## 요약 - -전반적으로 이 프로젝트는 현대적인 비동기 아키텍처를 잘 구현하고 있습니다. 그러나 몇 가지 잠재적인 문제점과 개선 가능한 부분이 발견되었습니다. - ---- - -## 1. 심각도 높음 - 즉시 개선 권장 - -### 1.1 N+1 쿼리 문제 (video.py:596-612) - -```python -# get_videos() 엔드포인트에서 -for video in videos: - # 매 video마다 별도의 DB 쿼리 실행 - N+1 문제! - project_result = await session.execute( - select(Project).where(Project.id == video.project_id) - ) - project = project_result.scalar_one_or_none() -``` - -**문제점**: 비디오 목록 조회 시 각 비디오마다 별도의 Project 쿼리가 발생합니다. 10개 비디오 조회 시 11번의 DB 쿼리가 실행됩니다. - -**개선 방안**: -```python -# selectinload를 사용한 eager loading -from sqlalchemy.orm import selectinload - -query = ( - select(Video) - .options(selectinload(Video.project)) # relationship 필요 - .where(Video.id.in_(select(subquery.c.max_id))) - .order_by(Video.created_at.desc()) - .offset(offset) - .limit(pagination.page_size) -) - -# 또는 한 번에 project_ids 수집 후 일괄 조회 -project_ids = [v.project_id for v in videos] -projects_result = await session.execute( - select(Project).where(Project.id.in_(project_ids)) -) -projects_map = {p.id: p for p in projects_result.scalars().all()} -``` - ---- - -### 1.2 가사 생성 API의 블로킹 문제 (lyric.py:274-276) - -```python -# ChatGPT API 호출이 완료될 때까지 HTTP 응답이 블로킹됨 -print(f"[generate_lyric] ChatGPT generation started - task_id: {task_id}") -result = await service.generate(prompt=prompt) # 수 초~수십 초 소요 -print(f"[generate_lyric] ChatGPT generation completed - task_id: {task_id}") -``` - -**문제점**: -- ChatGPT API 응답이 5-30초 이상 걸릴 수 있음 -- 이 시간 동안 클라이언트 연결이 유지되어야 함 -- 다수 동시 요청 시 worker 스레드 고갈 가능성 - -**개선 방안 (BackgroundTask 패턴)**: -```python -@router.post("/generate") -async def generate_lyric( - request_body: GenerateLyricRequest, - background_tasks: BackgroundTasks, - session: AsyncSession = Depends(get_session), -) -> GenerateLyricResponse: - # DB에 processing 상태로 저장 - lyric = Lyric(status="processing", ...) - session.add(lyric) - await session.commit() - - # 백그라운드에서 ChatGPT 호출 - background_tasks.add_task( - generate_lyric_background, - task_id=task_id, - prompt=prompt, - ) - - # 즉시 응답 반환 - return GenerateLyricResponse( - success=True, - task_id=task_id, - message="가사 생성이 시작되었습니다. /status/{task_id}로 상태를 확인하세요.", - ) -``` - ---- - -### 1.3 Creatomate 서비스의 동기/비동기 메서드 혼재 (creatomate.py) - -**문제점**: 동기 메서드가 여전히 존재하여 실수로 async 컨텍스트에서 호출될 수 있습니다. - -| 동기 메서드 | 비동기 메서드 | -|------------|--------------| -| `get_all_templates_data()` | 없음 | -| `get_one_template_data()` | `get_one_template_data_async()` | -| `make_creatomate_call()` | 없음 | -| `make_creatomate_custom_call()` | `make_creatomate_custom_call_async()` | -| `get_render_status()` | `get_render_status_async()` | - -**개선 방안**: -```python -# 모든 HTTP 호출 메서드를 async로 통일 -async def get_all_templates_data(self) -> dict: - url = f"{self.BASE_URL}/v1/templates" - async with httpx.AsyncClient() as client: - response = await client.get(url, headers=self.headers, timeout=30.0) - response.raise_for_status() - return response.json() - -# 동기 버전 제거 또는 deprecated 표시 -``` - ---- - -## 2. 심각도 중간 - 개선 권장 - -### 2.1 백그라운드 태스크에서 매번 엔진 생성 (session.py:82-127) - -```python -@asynccontextmanager -async def get_worker_session() -> AsyncGenerator[AsyncSession, None]: - # 매 호출마다 새 엔진 생성 - 오버헤드 발생 - worker_engine = create_async_engine( - url=db_settings.MYSQL_URL, - poolclass=NullPool, - ... - ) -``` - -**문제점**: 백그라운드 태스크가 빈번하게 호출되면 엔진 생성/소멸 오버헤드가 증가합니다. - -**개선 방안**: -```python -# 모듈 레벨에서 워커 전용 엔진 생성 -_worker_engine = create_async_engine( - url=db_settings.MYSQL_URL, - poolclass=NullPool, -) -_WorkerSessionLocal = async_sessionmaker(bind=_worker_engine, ...) - -@asynccontextmanager -async def get_worker_session() -> AsyncGenerator[AsyncSession, None]: - async with _WorkerSessionLocal() as session: - try: - yield session - except Exception as e: - await session.rollback() - raise e -``` - ---- - -### 2.2 대용량 파일 다운로드 시 메모리 사용 (video_task.py:49-54) - -```python -async with httpx.AsyncClient() as client: - response = await client.get(video_url, timeout=180.0) - response.raise_for_status() - # 전체 파일을 메모리에 로드 - 대용량 영상 시 문제 - async with aiofiles.open(str(temp_file_path), "wb") as f: - await f.write(response.content) -``` - -**문제점**: 수백 MB 크기의 영상 파일을 한 번에 메모리에 로드합니다. - -**개선 방안 - 스트리밍 다운로드**: -```python -async with httpx.AsyncClient() as client: - async with client.stream("GET", video_url, timeout=180.0) as response: - response.raise_for_status() - async with aiofiles.open(str(temp_file_path), "wb") as f: - async for chunk in response.aiter_bytes(chunk_size=8192): - await f.write(chunk) -``` - ---- - -### 2.3 httpx.AsyncClient 반복 생성 - -여러 곳에서 `async with httpx.AsyncClient() as client:`를 사용하여 매번 새 클라이언트를 생성합니다. - -**개선 방안 - 재사용 가능한 클라이언트**: -```python -# app/utils/http_client.py -from contextlib import asynccontextmanager -import httpx - -_client: httpx.AsyncClient | None = None - -async def get_http_client() -> httpx.AsyncClient: - global _client - if _client is None: - _client = httpx.AsyncClient(timeout=30.0) - return _client - -async def close_http_client(): - global _client - if _client: - await _client.aclose() - _client = None -``` - ---- - -## 3. 심각도 낮음 - 선택적 개선 - -### 3.1 generate_video 엔드포인트의 다중 DB 조회 (video.py:109-191) - -```python -# 4개의 개별 쿼리가 순차적으로 실행됨 -project_result = await session.execute(select(Project).where(...)) -lyric_result = await session.execute(select(Lyric).where(...)) -song_result = await session.execute(select(Song).where(...)) -image_result = await session.execute(select(Image).where(...)) -``` - -**개선 방안 - 병렬 쿼리 실행**: -```python -import asyncio - -project_task = session.execute(select(Project).where(Project.task_id == task_id)) -lyric_task = session.execute(select(Lyric).where(Lyric.task_id == task_id)) -song_task = session.execute( - select(Song).where(Song.task_id == task_id).order_by(Song.created_at.desc()).limit(1) -) -image_task = session.execute( - select(Image).where(Image.task_id == task_id).order_by(Image.img_order.asc()) -) - -project_result, lyric_result, song_result, image_result = await asyncio.gather( - project_task, lyric_task, song_task, image_task -) -``` - ---- - -### 3.2 템플릿 조회 캐싱 미적용 - -`get_one_template_data_async()`가 매번 Creatomate API를 호출합니다. - -**개선 방안 - 간단한 메모리 캐싱**: -```python -from functools import lru_cache -from cachetools import TTLCache - -_template_cache = TTLCache(maxsize=100, ttl=3600) # 1시간 캐시 - -async def get_one_template_data_async(self, template_id: str) -> dict: - if template_id in _template_cache: - return _template_cache[template_id] - - url = f"{self.BASE_URL}/v1/templates/{template_id}" - async with httpx.AsyncClient() as client: - response = await client.get(url, headers=self.headers, timeout=30.0) - response.raise_for_status() - data = response.json() - - _template_cache[template_id] = data - return data -``` - ---- - -## 4. 긍정적인 부분 (잘 구현된 패턴) - -| 항목 | 상태 | 설명 | -|------|------|------| -| SQLAlchemy AsyncSession | O | `asyncmy` 드라이버와 `AsyncSessionLocal` 사용 | -| 파일 I/O | O | `aiofiles` 사용으로 비동기 파일 처리 | -| HTTP 클라이언트 | O | `httpx.AsyncClient` 사용 | -| OpenAI API | O | `AsyncOpenAI` 클라이언트 사용 | -| 백그라운드 태스크 | O | FastAPI `BackgroundTasks` 적절히 사용 | -| 세션 관리 | O | 메인/워커 세션 분리로 이벤트 루프 충돌 방지 | -| 연결 풀 설정 | O | `pool_size`, `pool_recycle`, `pool_pre_ping` 적절히 설정 | - ---- - -## 5. 우선순위별 개선 권장 사항 - -| 우선순위 | 항목 | 예상 효과 | -|----------|------|----------| -| **1** | N+1 쿼리 문제 해결 | DB 부하 감소, 응답 속도 개선 | -| **2** | 가사 생성 백그라운드 처리 | 동시 요청 처리 능력 향상 | -| **3** | Creatomate 동기 메서드 제거 | 실수로 인한 블로킹 방지 | -| **4** | 대용량 파일 스트리밍 다운로드 | 메모리 사용량 감소 | -| **5** | 워커 세션 엔진 재사용 | 오버헤드 감소 | - ---- - -## 분석 일자 - -2024-12-29 +# 비동기 처리 문제 분석 보고서 + +## 요약 + +전반적으로 이 프로젝트는 현대적인 비동기 아키텍처를 잘 구현하고 있습니다. 그러나 몇 가지 잠재적인 문제점과 개선 가능한 부분이 발견되었습니다. + +--- + +## 1. 심각도 높음 - 즉시 개선 권장 + +### 1.1 N+1 쿼리 문제 (video.py:596-612) + +```python +# get_videos() 엔드포인트에서 +for video in videos: + # 매 video마다 별도의 DB 쿼리 실행 - N+1 문제! + project_result = await session.execute( + select(Project).where(Project.id == video.project_id) + ) + project = project_result.scalar_one_or_none() +``` + +**문제점**: 비디오 목록 조회 시 각 비디오마다 별도의 Project 쿼리가 발생합니다. 10개 비디오 조회 시 11번의 DB 쿼리가 실행됩니다. + +**개선 방안**: +```python +# selectinload를 사용한 eager loading +from sqlalchemy.orm import selectinload + +query = ( + select(Video) + .options(selectinload(Video.project)) # relationship 필요 + .where(Video.id.in_(select(subquery.c.max_id))) + .order_by(Video.created_at.desc()) + .offset(offset) + .limit(pagination.page_size) +) + +# 또는 한 번에 project_ids 수집 후 일괄 조회 +project_ids = [v.project_id for v in videos] +projects_result = await session.execute( + select(Project).where(Project.id.in_(project_ids)) +) +projects_map = {p.id: p for p in projects_result.scalars().all()} +``` + +--- + +### 1.2 가사 생성 API의 블로킹 문제 (lyric.py:274-276) + +```python +# ChatGPT API 호출이 완료될 때까지 HTTP 응답이 블로킹됨 +print(f"[generate_lyric] ChatGPT generation started - task_id: {task_id}") +result = await service.generate(prompt=prompt) # 수 초~수십 초 소요 +print(f"[generate_lyric] ChatGPT generation completed - task_id: {task_id}") +``` + +**문제점**: +- ChatGPT API 응답이 5-30초 이상 걸릴 수 있음 +- 이 시간 동안 클라이언트 연결이 유지되어야 함 +- 다수 동시 요청 시 worker 스레드 고갈 가능성 + +**개선 방안 (BackgroundTask 패턴)**: +```python +@router.post("/generate") +async def generate_lyric( + request_body: GenerateLyricRequest, + background_tasks: BackgroundTasks, + session: AsyncSession = Depends(get_session), +) -> GenerateLyricResponse: + # DB에 processing 상태로 저장 + lyric = Lyric(status="processing", ...) + session.add(lyric) + await session.commit() + + # 백그라운드에서 ChatGPT 호출 + background_tasks.add_task( + generate_lyric_background, + task_id=task_id, + prompt=prompt, + ) + + # 즉시 응답 반환 + return GenerateLyricResponse( + success=True, + task_id=task_id, + message="가사 생성이 시작되었습니다. /status/{task_id}로 상태를 확인하세요.", + ) +``` + +--- + +### 1.3 Creatomate 서비스의 동기/비동기 메서드 혼재 (creatomate.py) + +**문제점**: 동기 메서드가 여전히 존재하여 실수로 async 컨텍스트에서 호출될 수 있습니다. + +| 동기 메서드 | 비동기 메서드 | +|------------|--------------| +| `get_all_templates_data()` | 없음 | +| `get_one_template_data()` | `get_one_template_data_async()` | +| `make_creatomate_call()` | 없음 | +| `make_creatomate_custom_call()` | `make_creatomate_custom_call_async()` | +| `get_render_status()` | `get_render_status_async()` | + +**개선 방안**: +```python +# 모든 HTTP 호출 메서드를 async로 통일 +async def get_all_templates_data(self) -> dict: + url = f"{self.BASE_URL}/v1/templates" + async with httpx.AsyncClient() as client: + response = await client.get(url, headers=self.headers, timeout=30.0) + response.raise_for_status() + return response.json() + +# 동기 버전 제거 또는 deprecated 표시 +``` + +--- + +## 2. 심각도 중간 - 개선 권장 + +### 2.1 백그라운드 태스크에서 매번 엔진 생성 (session.py:82-127) + +```python +@asynccontextmanager +async def get_worker_session() -> AsyncGenerator[AsyncSession, None]: + # 매 호출마다 새 엔진 생성 - 오버헤드 발생 + worker_engine = create_async_engine( + url=db_settings.MYSQL_URL, + poolclass=NullPool, + ... + ) +``` + +**문제점**: 백그라운드 태스크가 빈번하게 호출되면 엔진 생성/소멸 오버헤드가 증가합니다. + +**개선 방안**: +```python +# 모듈 레벨에서 워커 전용 엔진 생성 +_worker_engine = create_async_engine( + url=db_settings.MYSQL_URL, + poolclass=NullPool, +) +_WorkerSessionLocal = async_sessionmaker(bind=_worker_engine, ...) + +@asynccontextmanager +async def get_worker_session() -> AsyncGenerator[AsyncSession, None]: + async with _WorkerSessionLocal() as session: + try: + yield session + except Exception as e: + await session.rollback() + raise e +``` + +--- + +### 2.2 대용량 파일 다운로드 시 메모리 사용 (video_task.py:49-54) + +```python +async with httpx.AsyncClient() as client: + response = await client.get(video_url, timeout=180.0) + response.raise_for_status() + # 전체 파일을 메모리에 로드 - 대용량 영상 시 문제 + async with aiofiles.open(str(temp_file_path), "wb") as f: + await f.write(response.content) +``` + +**문제점**: 수백 MB 크기의 영상 파일을 한 번에 메모리에 로드합니다. + +**개선 방안 - 스트리밍 다운로드**: +```python +async with httpx.AsyncClient() as client: + async with client.stream("GET", video_url, timeout=180.0) as response: + response.raise_for_status() + async with aiofiles.open(str(temp_file_path), "wb") as f: + async for chunk in response.aiter_bytes(chunk_size=8192): + await f.write(chunk) +``` + +--- + +### 2.3 httpx.AsyncClient 반복 생성 + +여러 곳에서 `async with httpx.AsyncClient() as client:`를 사용하여 매번 새 클라이언트를 생성합니다. + +**개선 방안 - 재사용 가능한 클라이언트**: +```python +# app/utils/http_client.py +from contextlib import asynccontextmanager +import httpx + +_client: httpx.AsyncClient | None = None + +async def get_http_client() -> httpx.AsyncClient: + global _client + if _client is None: + _client = httpx.AsyncClient(timeout=30.0) + return _client + +async def close_http_client(): + global _client + if _client: + await _client.aclose() + _client = None +``` + +--- + +## 3. 심각도 낮음 - 선택적 개선 + +### 3.1 generate_video 엔드포인트의 다중 DB 조회 (video.py:109-191) + +```python +# 4개의 개별 쿼리가 순차적으로 실행됨 +project_result = await session.execute(select(Project).where(...)) +lyric_result = await session.execute(select(Lyric).where(...)) +song_result = await session.execute(select(Song).where(...)) +image_result = await session.execute(select(Image).where(...)) +``` + +**개선 방안 - 병렬 쿼리 실행**: +```python +import asyncio + +project_task = session.execute(select(Project).where(Project.task_id == task_id)) +lyric_task = session.execute(select(Lyric).where(Lyric.task_id == task_id)) +song_task = session.execute( + select(Song).where(Song.task_id == task_id).order_by(Song.created_at.desc()).limit(1) +) +image_task = session.execute( + select(Image).where(Image.task_id == task_id).order_by(Image.img_order.asc()) +) + +project_result, lyric_result, song_result, image_result = await asyncio.gather( + project_task, lyric_task, song_task, image_task +) +``` + +--- + +### 3.2 템플릿 조회 캐싱 미적용 + +`get_one_template_data_async()`가 매번 Creatomate API를 호출합니다. + +**개선 방안 - 간단한 메모리 캐싱**: +```python +from functools import lru_cache +from cachetools import TTLCache + +_template_cache = TTLCache(maxsize=100, ttl=3600) # 1시간 캐시 + +async def get_one_template_data_async(self, template_id: str) -> dict: + if template_id in _template_cache: + return _template_cache[template_id] + + url = f"{self.BASE_URL}/v1/templates/{template_id}" + async with httpx.AsyncClient() as client: + response = await client.get(url, headers=self.headers, timeout=30.0) + response.raise_for_status() + data = response.json() + + _template_cache[template_id] = data + return data +``` + +--- + +## 4. 긍정적인 부분 (잘 구현된 패턴) + +| 항목 | 상태 | 설명 | +|------|------|------| +| SQLAlchemy AsyncSession | O | `asyncmy` 드라이버와 `AsyncSessionLocal` 사용 | +| 파일 I/O | O | `aiofiles` 사용으로 비동기 파일 처리 | +| HTTP 클라이언트 | O | `httpx.AsyncClient` 사용 | +| OpenAI API | O | `AsyncOpenAI` 클라이언트 사용 | +| 백그라운드 태스크 | O | FastAPI `BackgroundTasks` 적절히 사용 | +| 세션 관리 | O | 메인/워커 세션 분리로 이벤트 루프 충돌 방지 | +| 연결 풀 설정 | O | `pool_size`, `pool_recycle`, `pool_pre_ping` 적절히 설정 | + +--- + +## 5. 우선순위별 개선 권장 사항 + +| 우선순위 | 항목 | 예상 효과 | +|----------|------|----------| +| **1** | N+1 쿼리 문제 해결 | DB 부하 감소, 응답 속도 개선 | +| **2** | 가사 생성 백그라운드 처리 | 동시 요청 처리 능력 향상 | +| **3** | Creatomate 동기 메서드 제거 | 실수로 인한 블로킹 방지 | +| **4** | 대용량 파일 스트리밍 다운로드 | 메모리 사용량 감소 | +| **5** | 워커 세션 엔진 재사용 | 오버헤드 감소 | + +--- + +## 분석 일자 + +2024-12-29 diff --git a/docs/analysis/pool_problem.md b/docs/analysis/pool_problem.md index 12fb370..f8ffa33 100644 --- a/docs/analysis/pool_problem.md +++ b/docs/analysis/pool_problem.md @@ -1,1781 +1,1781 @@ -# Database Connection Pool 문제 분석 및 해결 가이드 - -## 목차 -1. [발견된 문제점 요약](#1-발견된-문제점-요약) -2. [설계적 문제 분석](#2-설계적-문제-분석) -3. [해결 방안 및 설계 제안](#3-해결-방안-및-설계-제안) -4. [개선 효과](#4-개선-효과) -5. [이론적 배경: 커넥션 풀 관리 원칙](#5-이론적-배경-커넥션-풀-관리-원칙) -6. [실무 시나리오 예제 코드](#6-실무-시나리오-예제-코드) -7. [설계 원칙 요약](#7-설계-원칙-요약) - ---- - -## 1. 발견된 문제점 요약 - -### 1.1 "Multiple rows were found when one or none was required" 에러 - -**문제 상황:** -```python -# 기존 코드 (문제) -result = await session.execute(select(Project).where(Project.task_id == task_id)) -project = result.scalar_one_or_none() # task_id 중복 시 에러 발생! -``` - -**원인:** -- `task_id`로 조회 시 중복 레코드가 존재할 수 있음 -- `scalar_one_or_none()`은 정확히 0개 또는 1개의 결과만 허용 - -**해결:** -```python -# 수정된 코드 -result = await session.execute( - select(Project) - .where(Project.task_id == task_id) - .order_by(Project.created_at.desc()) - .limit(1) -) -project = result.scalar_one_or_none() -``` - -### 1.2 커넥션 풀 고갈 (Pool Exhaustion) - -**증상:** -- API 요청이 응답을 반환하지 않음 -- 동일한 요청이 중복으로 들어옴 (클라이언트 재시도) -- 서버 로그에 타임아웃 관련 메시지 - -**원인:** -- 외부 API 호출 중 DB 세션을 계속 점유 -- 백그라운드 태스크와 API 요청이 동일한 커넥션 풀 사용 - -### 1.3 세션 장시간 점유 - -**문제가 발생한 함수들:** - -| 파일 | 함수 | 문제 | -|------|------|------| -| `video.py` | `generate_video` | Creatomate API 호출 중 세션 점유 | -| `home.py` | `upload_images_blob` | Azure Blob 업로드 중 세션 점유 | -| `song_task.py` | 모든 함수 | API 풀과 동일한 세션 사용 | -| `video_task.py` | 모든 함수 | API 풀과 동일한 세션 사용 | -| `lyric_task.py` | `generate_lyric_background` | API 풀과 동일한 세션 사용 | - ---- - -## 2. 설계적 문제 분석 - -### 2.1 Anti-Pattern: Long-lived Session with External Calls - -``` -┌─────────────────────────────────────────────────────────────────┐ -│ 문제가 있는 패턴 │ -├─────────────────────────────────────────────────────────────────┤ -│ │ -│ Request ──► Session 획득 ──► DB 조회 ──► 외부 API 호출 ──► DB 저장 ──► Session 반환 -│ │ │ │ -│ │ 30초~수 분 소요 │ │ -│ │◄─────── 세션 점유 시간 ───────►│ │ -│ │ -└─────────────────────────────────────────────────────────────────┘ - -문제점: -1. 외부 API 응답 대기 동안 커넥션 점유 -2. Pool size=20일 때, 20개 요청만으로 풀 고갈 -3. 후속 요청들이 pool_timeout까지 대기 후 실패 -``` - -### 2.2 Anti-Pattern: Shared Pool for Different Workloads - -``` -┌─────────────────────────────────────────────────────────────────┐ -│ 공유 풀 문제 │ -├─────────────────────────────────────────────────────────────────┤ -│ │ -│ ┌──────────────┐ ┌─────────────────────┐ │ -│ │ API Requests │──────► │ │ -│ └──────────────┘ │ Single Pool │ │ -│ │ (pool_size=20) │ │ -│ ┌──────────────┐ │ │ │ -│ │ Background │──────► │ │ -│ │ Tasks │ └─────────────────────┘ │ -│ └──────────────┘ │ -│ │ -│ 문제: 백그라운드 태스크가 커넥션을 오래 점유하면 │ -│ API 요청이 커넥션을 얻지 못함 │ -│ │ -└─────────────────────────────────────────────────────────────────┘ -``` - -### 2.3 근본 원인 분석 - -``` -원인 1: 책임 분리 실패 (Separation of Concerns) -├── DB 작업과 외부 API 호출이 단일 함수에 혼재 -├── 트랜잭션 범위가 불필요하게 넓음 -└── 세션 생명주기 관리 부재 - -원인 2: 리소스 격리 실패 (Resource Isolation) -├── API 요청과 백그라운드 태스크가 동일 풀 사용 -├── 워크로드 특성 미고려 (빠른 API vs 느린 백그라운드) -└── 우선순위 기반 리소스 할당 부재 - -원인 3: 방어적 프로그래밍 부재 (Defensive Programming) -├── 중복 데이터 발생 가능성 미고려 -├── 타임아웃 및 재시도 로직 미흡 -└── 에러 상태에서의 세션 처리 미흡 -``` - ---- - -## 3. 해결 방안 및 설계 제안 - -### 3.1 해결책 1: 3-Stage Pattern (세션 분리 패턴) - -**핵심 아이디어:** 외부 API 호출 전에 세션을 반환하고, 호출 완료 후 새 세션으로 결과 저장 - -```python -async def process_with_external_api(task_id: str, session: AsyncSession): - """3-Stage Pattern 적용""" - - # ========== Stage 1: DB 조회 및 준비 (세션 사용) ========== - data = await session.execute(select(Model).where(...)) - prepared_data = extract_needed_info(data) - await session.commit() # 세션 해제 - - # ========== Stage 2: 외부 API 호출 (세션 없음) ========== - # 이 구간에서는 DB 커넥션을 점유하지 않음 - api_result = await external_api.call(prepared_data) - - # ========== Stage 3: 결과 저장 (새 세션) ========== - async with AsyncSessionLocal() as new_session: - record = await new_session.execute(select(Model).where(...)) - record.status = "completed" - record.result = api_result - await new_session.commit() - - return result -``` - -### 3.2 해결책 2: Separate Pool Strategy (풀 분리 전략) - -**핵심 아이디어:** API 요청과 백그라운드 태스크에 별도의 커넥션 풀 사용 - -```python -# 메인 엔진 (FastAPI 요청용) - 빠른 응답 필요 -engine = create_async_engine( - url=db_url, - pool_size=20, - max_overflow=20, - pool_timeout=30, # 빠른 실패 - pool_recycle=3600, -) -AsyncSessionLocal = async_sessionmaker(bind=engine, ...) - -# 백그라운드 엔진 (장시간 작업용) - 안정성 우선 -background_engine = create_async_engine( - url=db_url, - pool_size=10, - max_overflow=10, - pool_timeout=60, # 여유있는 대기 - pool_recycle=3600, -) -BackgroundSessionLocal = async_sessionmaker(bind=background_engine, ...) -``` - -### 3.3 해결책 3: Query Safety Pattern (안전한 쿼리 패턴) - -**핵심 아이디어:** 항상 최신 데이터 1개만 조회 - -```python -# 안전한 조회 패턴 -async def get_latest_record(session: AsyncSession, task_id: str): - result = await session.execute( - select(Model) - .where(Model.task_id == task_id) - .order_by(Model.created_at.desc()) - .limit(1) - ) - return result.scalar_one_or_none() -``` - ---- - -## 4. 개선 효과 - -### 4.1 정량적 효과 - -| 지표 | 개선 전 | 개선 후 | 개선율 | -|------|---------|---------|--------| -| 평균 세션 점유 시간 | 30-60초 | 0.1-0.5초 | 99% 감소 | -| 동시 처리 가능 요청 | ~20개 | ~200개+ | 10배 이상 | -| Pool Exhaustion 발생 | 빈번 | 거의 없음 | - | -| API 응답 실패율 | 높음 | 매우 낮음 | - | - -### 4.2 정성적 효과 - -``` -개선 효과 매트릭스: - - 개선 전 개선 후 - ───────────────────────── -안정성 │ ★★☆☆☆ │ ★★★★★ │ -확장성 │ ★★☆☆☆ │ ★★★★☆ │ -유지보수성 │ ★★★☆☆ │ ★★★★☆ │ -리소스 효율성 │ ★☆☆☆☆ │ ★★★★★ │ -에러 추적 용이성 │ ★★☆☆☆ │ ★★★★☆ │ -``` - ---- - -## 5. 이론적 배경: 커넥션 풀 관리 원칙 - -### 5.1 커넥션 풀의 목적 - -``` -┌─────────────────────────────────────────────────────────────────┐ -│ 커넥션 풀 동작 원리 │ -├─────────────────────────────────────────────────────────────────┤ -│ │ -│ Application Connection Pool Database│ -│ │ │ │ │ -│ │─── get_connection() ────────►│ │ │ -│ │◄── connection ───────────────│ │ │ -│ │ │ │ │ -│ │─── execute(query) ───────────┼──────────────────────►│ │ -│ │◄── result ───────────────────┼◄──────────────────────│ │ -│ │ │ │ │ -│ │─── release_connection() ────►│ │ │ -│ │ │ (connection 재사용) │ │ -│ │ -│ 장점: │ -│ 1. 연결 생성 오버헤드 제거 (TCP handshake, 인증 등) │ -│ 2. 동시 연결 수 제한으로 DB 과부하 방지 │ -│ 3. 연결 재사용으로 리소스 효율성 향상 │ -│ │ -└─────────────────────────────────────────────────────────────────┘ -``` - -### 5.2 핵심 파라미터 이해 - -```python -engine = create_async_engine( - url=database_url, - - # pool_size: 풀에서 유지하는 영구 연결 수 - # - 너무 작으면: 요청 대기 발생 - # - 너무 크면: DB 리소스 낭비 - pool_size=20, - - # max_overflow: pool_size 초과 시 생성 가능한 임시 연결 수 - # - 총 최대 연결 = pool_size + max_overflow - # - burst traffic 처리용 - max_overflow=20, - - # pool_timeout: 연결 대기 최대 시간 (초) - # - 초과 시 TimeoutError 발생 - # - API 서버: 짧게 (빠른 실패 선호) - # - Background: 길게 (안정성 선호) - pool_timeout=30, - - # pool_recycle: 연결 재생성 주기 (초) - # - MySQL wait_timeout보다 짧게 설정 - # - "MySQL has gone away" 에러 방지 - pool_recycle=3600, - - # pool_pre_ping: 연결 사용 전 유효성 검사 - # - True: SELECT 1 실행하여 연결 확인 - # - 약간의 오버헤드, 높은 안정성 - pool_pre_ping=True, -) -``` - -### 5.3 세션 관리 원칙 - -``` -┌─────────────────────────────────────────────────────────────────┐ -│ 세션 관리 원칙 │ -├─────────────────────────────────────────────────────────────────┤ -│ │ -│ 원칙 1: 최소 점유 시간 (Minimal Hold Time) │ -│ ───────────────────────────────────────── │ -│ "세션은 DB 작업에만 사용하고, 즉시 반환한다" │ -│ │ -│ ✗ 나쁜 예: │ -│ session.query() → http_call(30s) → session.commit() │ -│ │ -│ ✓ 좋은 예: │ -│ session.query() → session.commit() → http_call() → new_session│ -│ │ -│ 원칙 2: 범위 명확성 (Clear Scope) │ -│ ───────────────────────────────── │ -│ "세션의 시작과 끝을 명확히 정의한다" │ -│ │ -│ ✓ async with AsyncSessionLocal() as session: │ -│ # 이 블록 내에서만 세션 사용 │ -│ pass │ -│ # 블록 종료 시 자동 반환 │ -│ │ -│ 원칙 3: 단일 책임 (Single Responsibility) │ -│ ───────────────────────────────────────── │ -│ "하나의 세션 블록은 하나의 트랜잭션 단위만 처리한다" │ -│ │ -│ 원칙 4: 실패 대비 (Failure Handling) │ -│ ─────────────────────────────────── │ -│ "예외 발생 시에도 세션이 반환되도록 보장한다" │ -│ │ -│ async with session: │ -│ try: │ -│ ... │ -│ except Exception: │ -│ await session.rollback() │ -│ raise │ -│ # finally에서 자동 close │ -│ │ -└─────────────────────────────────────────────────────────────────┘ -``` - -### 5.4 워크로드 분리 원칙 - -``` -┌─────────────────────────────────────────────────────────────────┐ -│ 워크로드 분리 전략 │ -├─────────────────────────────────────────────────────────────────┤ -│ │ -│ 워크로드 유형별 특성: │ -│ │ -│ ┌─────────────────┬─────────────────┬─────────────────┐ │ -│ │ API 요청 │ 백그라운드 작업 │ 배치 작업 │ │ -│ ├─────────────────┼─────────────────┼─────────────────┤ │ -│ │ 짧은 응답 시간 │ 긴 처리 시간 │ 매우 긴 처리 │ │ -│ │ 높은 동시성 │ 중간 동시성 │ 낮은 동시성 │ │ -│ │ 빠른 실패 선호 │ 재시도 허용 │ 안정성 최우선 │ │ -│ └─────────────────┴─────────────────┴─────────────────┘ │ -│ │ -│ 분리 전략: │ -│ │ -│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ -│ │ API Pool │ │ Background │ │ Batch Pool │ │ -│ │ size=20 │ │ Pool │ │ size=5 │ │ -│ │ timeout=30s │ │ size=10 │ │ timeout=300s│ │ -│ └─────────────┘ │ timeout=60s │ └─────────────┘ │ -│ └─────────────┘ │ -│ │ -│ 이점: │ -│ 1. 워크로드 간 간섭 방지 │ -│ 2. 각 워크로드에 최적화된 설정 적용 │ -│ 3. 장애 격리 (한 풀의 문제가 다른 풀에 영향 X) │ -│ │ -└─────────────────────────────────────────────────────────────────┘ -``` - ---- - -## 6. 실무 시나리오 예제 코드 - -### 시나리오 1: 이미지 처리 서비스 - -실제 프로젝트에서 자주 발생하는 "이미지 업로드 → 외부 처리 → 결과 저장" 패턴 - -#### 6.1.1 프로젝트 구조 - -``` -image_processing_service/ -├── app/ -│ ├── __init__.py -│ ├── main.py -│ ├── config.py -│ ├── database/ -│ │ ├── __init__.py -│ │ ├── session.py -│ │ └── models.py -│ ├── api/ -│ │ ├── __init__.py -│ │ └── routes/ -│ │ ├── __init__.py -│ │ └── images.py -│ ├── services/ -│ │ ├── __init__.py -│ │ ├── image_processor.py -│ │ └── storage_service.py -│ └── workers/ -│ ├── __init__.py -│ └── image_tasks.py -└── requirements.txt -``` - -#### 6.1.2 코드 구현 - -**config.py - 설정** -```python -""" -Configuration module for the image processing service. -""" -from pydantic_settings import BaseSettings - - -class Settings(BaseSettings): - """Application settings""" - - # Database - DATABASE_URL: str = "mysql+asyncmy://user:pass@localhost/imagedb" - - # API Pool settings (빠른 응답 우선) - API_POOL_SIZE: int = 20 - API_POOL_MAX_OVERFLOW: int = 20 - API_POOL_TIMEOUT: int = 30 - - # Background Pool settings (안정성 우선) - BG_POOL_SIZE: int = 10 - BG_POOL_MAX_OVERFLOW: int = 10 - BG_POOL_TIMEOUT: int = 60 - - # External services - IMAGE_PROCESSOR_URL: str = "https://api.imageprocessor.com" - STORAGE_BUCKET: str = "processed-images" - - class Config: - env_file = ".env" - - -settings = Settings() -``` - -**database/session.py - 세션 관리** -```python -""" -Database session management with separate pools for different workloads. - -핵심 설계 원칙: -1. API 요청과 백그라운드 작업에 별도 풀 사용 -2. 각 풀은 워크로드 특성에 맞게 설정 -3. 세션 상태 모니터링을 위한 로깅 -""" -from contextlib import asynccontextmanager -from typing import AsyncGenerator - -from sqlalchemy.ext.asyncio import ( - AsyncSession, - async_sessionmaker, - create_async_engine, -) - -from app.config import settings - - -# ============================================================ -# 메인 엔진 (FastAPI 요청용) -# ============================================================ -# 특징: 빠른 응답, 짧은 타임아웃, 빠른 실패 -api_engine = create_async_engine( - url=settings.DATABASE_URL, - pool_size=settings.API_POOL_SIZE, - max_overflow=settings.API_POOL_MAX_OVERFLOW, - pool_timeout=settings.API_POOL_TIMEOUT, - pool_recycle=3600, - pool_pre_ping=True, - echo=False, # Production에서는 False -) - -ApiSessionLocal = async_sessionmaker( - bind=api_engine, - class_=AsyncSession, - expire_on_commit=False, - autoflush=False, -) - - -# ============================================================ -# 백그라운드 엔진 (비동기 작업용) -# ============================================================ -# 특징: 긴 타임아웃, 안정성 우선 -background_engine = create_async_engine( - url=settings.DATABASE_URL, - pool_size=settings.BG_POOL_SIZE, - max_overflow=settings.BG_POOL_MAX_OVERFLOW, - pool_timeout=settings.BG_POOL_TIMEOUT, - pool_recycle=3600, - pool_pre_ping=True, - echo=False, -) - -BackgroundSessionLocal = async_sessionmaker( - bind=background_engine, - class_=AsyncSession, - expire_on_commit=False, - autoflush=False, -) - - -# ============================================================ -# 세션 제공 함수 -# ============================================================ -async def get_api_session() -> AsyncGenerator[AsyncSession, None]: - """ - FastAPI Dependency로 사용할 API 세션 제공자. - - 사용 예: - @router.post("/images") - async def upload(session: AsyncSession = Depends(get_api_session)): - ... - """ - # 풀 상태 로깅 (디버깅용) - pool = api_engine.pool - print( - f"[API Pool] size={pool.size()}, " - f"checked_out={pool.checkedout()}, " - f"overflow={pool.overflow()}" - ) - - async with ApiSessionLocal() as session: - try: - yield session - except Exception: - await session.rollback() - raise - - -@asynccontextmanager -async def get_background_session() -> AsyncGenerator[AsyncSession, None]: - """ - 백그라운드 작업용 세션 컨텍스트 매니저. - - 사용 예: - async with get_background_session() as session: - result = await session.execute(query) - """ - pool = background_engine.pool - print( - f"[Background Pool] size={pool.size()}, " - f"checked_out={pool.checkedout()}, " - f"overflow={pool.overflow()}" - ) - - async with BackgroundSessionLocal() as session: - try: - yield session - except Exception: - await session.rollback() - raise - - -# ============================================================ -# 리소스 정리 -# ============================================================ -async def dispose_engines() -> None: - """애플리케이션 종료 시 모든 엔진 정리""" - await api_engine.dispose() - await background_engine.dispose() - print("[Database] All engines disposed") -``` - -**database/models.py - 모델** -```python -""" -Database models for image processing service. -""" -from datetime import datetime -from enum import Enum - -from sqlalchemy import String, Text, DateTime, Integer, Float -from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column - - -class Base(DeclarativeBase): - pass - - -class ImageStatus(str, Enum): - """이미지 처리 상태""" - PENDING = "pending" - PROCESSING = "processing" - COMPLETED = "completed" - FAILED = "failed" - - -class Image(Base): - """이미지 테이블""" - __tablename__ = "images" - - id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) - task_id: Mapped[str] = mapped_column(String(50), index=True, nullable=False) - original_url: Mapped[str] = mapped_column(Text, nullable=False) - processed_url: Mapped[str | None] = mapped_column(Text, nullable=True) - status: Mapped[str] = mapped_column( - String(20), - default=ImageStatus.PENDING.value, - nullable=False - ) - width: Mapped[int | None] = mapped_column(Integer, nullable=True) - height: Mapped[int | None] = mapped_column(Integer, nullable=True) - file_size: Mapped[int | None] = mapped_column(Integer, nullable=True) - processing_time: Mapped[float | None] = mapped_column(Float, nullable=True) - error_message: Mapped[str | None] = mapped_column(Text, nullable=True) - created_at: Mapped[datetime] = mapped_column( - DateTime, - default=datetime.utcnow, - nullable=False - ) - updated_at: Mapped[datetime] = mapped_column( - DateTime, - default=datetime.utcnow, - onupdate=datetime.utcnow, - nullable=False - ) -``` - -**services/image_processor.py - 외부 API 서비스** -```python -""" -External image processing service client. -""" -import httpx -from dataclasses import dataclass - - -@dataclass -class ProcessingResult: - """이미지 처리 결과""" - processed_url: str - width: int - height: int - file_size: int - processing_time: float - - -class ImageProcessorService: - """ - 외부 이미지 처리 API 클라이언트. - - 주의: 이 서비스 호출은 DB 세션 외부에서 수행해야 합니다! - """ - - def __init__(self, base_url: str): - self.base_url = base_url - self.timeout = httpx.Timeout(60.0, connect=10.0) - - async def process_image( - self, - image_url: str, - options: dict | None = None - ) -> ProcessingResult: - """ - 외부 API를 통해 이미지 처리. - - 이 함수는 30초~수 분이 소요될 수 있습니다. - 반드시 DB 세션 외부에서 호출하세요! - - Args: - image_url: 처리할 이미지 URL - options: 처리 옵션 (resize, filter 등) - - Returns: - ProcessingResult: 처리 결과 - """ - async with httpx.AsyncClient(timeout=self.timeout) as client: - response = await client.post( - f"{self.base_url}/process", - json={ - "image_url": image_url, - "options": options or {} - } - ) - response.raise_for_status() - data = response.json() - - return ProcessingResult( - processed_url=data["processed_url"], - width=data["width"], - height=data["height"], - file_size=data["file_size"], - processing_time=data["processing_time"], - ) -``` - -**api/routes/images.py - API 라우터 (3-Stage Pattern 적용)** -```python -""" -Image API routes with proper session management. - -핵심 패턴: 3-Stage Pattern -- Stage 1: DB 작업 (세션 사용) -- Stage 2: 외부 API 호출 (세션 없음) -- Stage 3: 결과 저장 (새 세션) -""" -import asyncio -from uuid import uuid4 - -from fastapi import APIRouter, BackgroundTasks, Depends, HTTPException -from pydantic import BaseModel, HttpUrl -from sqlalchemy import select -from sqlalchemy.ext.asyncio import AsyncSession - -from app.database.session import get_api_session, ApiSessionLocal -from app.database.models import Image, ImageStatus -from app.services.image_processor import ImageProcessorService -from app.config import settings - - -router = APIRouter(prefix="/images", tags=["images"]) - -# 외부 서비스 인스턴스 -processor_service = ImageProcessorService(settings.IMAGE_PROCESSOR_URL) - - -class ImageUploadRequest(BaseModel): - """이미지 업로드 요청""" - url: HttpUrl - options: dict | None = None - - -class ImageResponse(BaseModel): - """이미지 응답""" - task_id: str - status: str - original_url: str - processed_url: str | None = None - - class Config: - from_attributes = True - - -# ============================================================ -# 동기적 처리 (짧은 작업용) - 권장하지 않음 -# ============================================================ -@router.post("/process-sync", response_model=ImageResponse) -async def process_image_sync( - request: ImageUploadRequest, - session: AsyncSession = Depends(get_api_session), -) -> ImageResponse: - """ - 동기적 이미지 처리 (3-Stage Pattern 적용). - - 주의: 외부 API 호출이 길어지면 요청 타임아웃 발생 가능. - 대부분의 경우 비동기 처리를 권장합니다. - """ - task_id = str(uuid4()) - - # ========== Stage 1: 초기 레코드 생성 ========== - image = Image( - task_id=task_id, - original_url=str(request.url), - status=ImageStatus.PROCESSING.value, - ) - session.add(image) - await session.commit() - image_id = image.id # ID 저장 - print(f"[Stage 1] Image record created - task_id: {task_id}") - - # ========== Stage 2: 외부 API 호출 (세션 없음!) ========== - # 이 구간에서는 DB 커넥션을 점유하지 않습니다 - try: - print(f"[Stage 2] Calling external API - task_id: {task_id}") - result = await processor_service.process_image( - str(request.url), - request.options - ) - print(f"[Stage 2] External API completed - task_id: {task_id}") - except Exception as e: - # 실패 시 상태 업데이트 (새 세션 사용) - async with ApiSessionLocal() as error_session: - stmt = select(Image).where(Image.id == image_id) - db_image = (await error_session.execute(stmt)).scalar_one() - db_image.status = ImageStatus.FAILED.value - db_image.error_message = str(e) - await error_session.commit() - raise HTTPException(status_code=500, detail=str(e)) - - # ========== Stage 3: 결과 저장 (새 세션) ========== - async with ApiSessionLocal() as update_session: - stmt = select(Image).where(Image.id == image_id) - db_image = (await update_session.execute(stmt)).scalar_one() - - db_image.status = ImageStatus.COMPLETED.value - db_image.processed_url = result.processed_url - db_image.width = result.width - db_image.height = result.height - db_image.file_size = result.file_size - db_image.processing_time = result.processing_time - - await update_session.commit() - print(f"[Stage 3] Result saved - task_id: {task_id}") - - return ImageResponse( - task_id=task_id, - status=db_image.status, - original_url=db_image.original_url, - processed_url=db_image.processed_url, - ) - - -# ============================================================ -# 비동기 처리 (권장) -# ============================================================ -@router.post("/process-async", response_model=ImageResponse) -async def process_image_async( - request: ImageUploadRequest, - background_tasks: BackgroundTasks, - session: AsyncSession = Depends(get_api_session), -) -> ImageResponse: - """ - 비동기 이미지 처리 (즉시 응답 반환). - - 1. 초기 레코드 생성 후 즉시 응답 - 2. 백그라운드에서 처리 진행 - 3. 상태는 GET /images/{task_id} 로 조회 - """ - task_id = str(uuid4()) - - # DB 작업: 초기 레코드 생성 - image = Image( - task_id=task_id, - original_url=str(request.url), - status=ImageStatus.PENDING.value, - ) - session.add(image) - await session.commit() - - # 백그라운드 태스크 등록 (별도 세션 사용) - background_tasks.add_task( - process_image_background, - task_id=task_id, - image_url=str(request.url), - options=request.options, - ) - - # 즉시 응답 반환 - return ImageResponse( - task_id=task_id, - status=ImageStatus.PENDING.value, - original_url=str(request.url), - ) - - -@router.get("/{task_id}", response_model=ImageResponse) -async def get_image_status( - task_id: str, - session: AsyncSession = Depends(get_api_session), -) -> ImageResponse: - """이미지 처리 상태 조회""" - # 안전한 쿼리 패턴: 최신 레코드 1개만 조회 - stmt = ( - select(Image) - .where(Image.task_id == task_id) - .order_by(Image.created_at.desc()) - .limit(1) - ) - result = await session.execute(stmt) - image = result.scalar_one_or_none() - - if not image: - raise HTTPException(status_code=404, detail="Image not found") - - return ImageResponse( - task_id=image.task_id, - status=image.status, - original_url=image.original_url, - processed_url=image.processed_url, - ) - - -# ============================================================ -# 백그라운드 처리 함수 -# ============================================================ -async def process_image_background( - task_id: str, - image_url: str, - options: dict | None, -) -> None: - """ - 백그라운드에서 이미지 처리. - - 중요: 이 함수는 BackgroundSessionLocal을 사용합니다. - API 풀과 분리되어 있어 API 응답에 영향을 주지 않습니다. - """ - from app.database.session import BackgroundSessionLocal - - print(f"[Background] Starting - task_id: {task_id}") - - # 상태를 processing으로 업데이트 - async with BackgroundSessionLocal() as session: - stmt = ( - select(Image) - .where(Image.task_id == task_id) - .order_by(Image.created_at.desc()) - .limit(1) - ) - image = (await session.execute(stmt)).scalar_one_or_none() - if image: - image.status = ImageStatus.PROCESSING.value - await session.commit() - - # 외부 API 호출 (세션 없음!) - try: - result = await processor_service.process_image(image_url, options) - - # 성공: 결과 저장 - async with BackgroundSessionLocal() as session: - stmt = ( - select(Image) - .where(Image.task_id == task_id) - .order_by(Image.created_at.desc()) - .limit(1) - ) - image = (await session.execute(stmt)).scalar_one_or_none() - if image: - image.status = ImageStatus.COMPLETED.value - image.processed_url = result.processed_url - image.width = result.width - image.height = result.height - image.file_size = result.file_size - image.processing_time = result.processing_time - await session.commit() - - print(f"[Background] Completed - task_id: {task_id}") - - except Exception as e: - # 실패: 에러 저장 - async with BackgroundSessionLocal() as session: - stmt = ( - select(Image) - .where(Image.task_id == task_id) - .order_by(Image.created_at.desc()) - .limit(1) - ) - image = (await session.execute(stmt)).scalar_one_or_none() - if image: - image.status = ImageStatus.FAILED.value - image.error_message = str(e) - await session.commit() - - print(f"[Background] Failed - task_id: {task_id}, error: {e}") -``` - -**main.py - 애플리케이션 진입점** -```python -""" -Main application entry point. -""" -from contextlib import asynccontextmanager - -from fastapi import FastAPI - -from app.database.session import dispose_engines -from app.api.routes import images - - -@asynccontextmanager -async def lifespan(app: FastAPI): - """애플리케이션 생명주기 관리""" - # Startup - print("[App] Starting up...") - yield - # Shutdown - print("[App] Shutting down...") - await dispose_engines() - - -app = FastAPI( - title="Image Processing Service", - description="이미지 처리 서비스 API", - version="1.0.0", - lifespan=lifespan, -) - -app.include_router(images.router, prefix="/api/v1") - - -@app.get("/health") -async def health_check(): - """헬스 체크""" - return {"status": "healthy"} -``` - ---- - -### 시나리오 2: 결제 처리 서비스 - -결제 시스템에서의 "주문 생성 → 결제 처리 → 결과 저장" 패턴 - -#### 6.2.1 프로젝트 구조 - -``` -payment_service/ -├── app/ -│ ├── __init__.py -│ ├── main.py -│ ├── config.py -│ ├── database/ -│ │ ├── __init__.py -│ │ ├── session.py -│ │ └── models.py -│ ├── api/ -│ │ ├── __init__.py -│ │ └── routes/ -│ │ ├── __init__.py -│ │ └── payments.py -│ ├── services/ -│ │ ├── __init__.py -│ │ └── payment_gateway.py -│ └── workers/ -│ ├── __init__.py -│ └── payment_tasks.py -└── requirements.txt -``` - -#### 6.2.2 코드 구현 - -**config.py - 설정** -```python -""" -Payment service configuration. -""" -from pydantic_settings import BaseSettings - - -class Settings(BaseSettings): - """Application settings""" - - DATABASE_URL: str = "mysql+asyncmy://user:pass@localhost/paymentdb" - - # Pool settings - 결제는 더 보수적으로 설정 - API_POOL_SIZE: int = 30 # 결제는 트래픽이 많음 - API_POOL_MAX_OVERFLOW: int = 20 - API_POOL_TIMEOUT: int = 20 # 빠른 실패 - - BG_POOL_SIZE: int = 5 # 백그라운드는 적게 - BG_POOL_MAX_OVERFLOW: int = 5 - BG_POOL_TIMEOUT: int = 120 # 결제 검증은 시간이 걸릴 수 있음 - - # Payment gateway - PAYMENT_GATEWAY_URL: str = "https://api.payment-gateway.com" - PAYMENT_GATEWAY_KEY: str = "" - - class Config: - env_file = ".env" - - -settings = Settings() -``` - -**database/session.py - 세션 관리** -```python -""" -Database session management for payment service. - -결제 서비스 특성: -1. 데이터 정합성이 매우 중요 -2. 트랜잭션 롤백이 명확해야 함 -3. 장애 시에도 데이터 손실 없어야 함 -""" -from contextlib import asynccontextmanager -from typing import AsyncGenerator - -from sqlalchemy.ext.asyncio import ( - AsyncSession, - async_sessionmaker, - create_async_engine, -) - -from app.config import settings - - -# ============================================================ -# API 엔진 (결제 요청 처리용) -# ============================================================ -api_engine = create_async_engine( - url=settings.DATABASE_URL, - pool_size=settings.API_POOL_SIZE, - max_overflow=settings.API_POOL_MAX_OVERFLOW, - pool_timeout=settings.API_POOL_TIMEOUT, - pool_recycle=1800, # 30분 (결제는 더 자주 재생성) - pool_pre_ping=True, - echo=False, -) - -ApiSessionLocal = async_sessionmaker( - bind=api_engine, - class_=AsyncSession, - expire_on_commit=False, - autoflush=False, -) - - -# ============================================================ -# 백그라운드 엔진 (결제 검증, 정산 등) -# ============================================================ -background_engine = create_async_engine( - url=settings.DATABASE_URL, - pool_size=settings.BG_POOL_SIZE, - max_overflow=settings.BG_POOL_MAX_OVERFLOW, - pool_timeout=settings.BG_POOL_TIMEOUT, - pool_recycle=1800, - pool_pre_ping=True, - echo=False, -) - -BackgroundSessionLocal = async_sessionmaker( - bind=background_engine, - class_=AsyncSession, - expire_on_commit=False, - autoflush=False, -) - - -async def get_api_session() -> AsyncGenerator[AsyncSession, None]: - """API 세션 제공""" - async with ApiSessionLocal() as session: - try: - yield session - except Exception: - await session.rollback() - raise - - -@asynccontextmanager -async def get_background_session() -> AsyncGenerator[AsyncSession, None]: - """백그라운드 세션 제공""" - async with BackgroundSessionLocal() as session: - try: - yield session - except Exception: - await session.rollback() - raise - - -async def dispose_engines() -> None: - """엔진 정리""" - await api_engine.dispose() - await background_engine.dispose() -``` - -**database/models.py - 모델** -```python -""" -Payment database models. -""" -from datetime import datetime -from decimal import Decimal -from enum import Enum - -from sqlalchemy import String, Text, DateTime, Integer, Numeric, ForeignKey -from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship - - -class Base(DeclarativeBase): - pass - - -class PaymentStatus(str, Enum): - """결제 상태""" - PENDING = "pending" # 결제 대기 - PROCESSING = "processing" # 처리 중 - COMPLETED = "completed" # 완료 - FAILED = "failed" # 실패 - REFUNDED = "refunded" # 환불됨 - CANCELLED = "cancelled" # 취소됨 - - -class Order(Base): - """주문 테이블""" - __tablename__ = "orders" - - id: Mapped[int] = mapped_column(Integer, primary_key=True) - order_number: Mapped[str] = mapped_column(String(50), unique=True, index=True) - customer_id: Mapped[str] = mapped_column(String(50), index=True) - total_amount: Mapped[Decimal] = mapped_column(Numeric(10, 2)) - status: Mapped[str] = mapped_column(String(20), default="pending") - created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow) - updated_at: Mapped[datetime] = mapped_column( - DateTime, default=datetime.utcnow, onupdate=datetime.utcnow - ) - - # Relationships - payment: Mapped["Payment"] = relationship(back_populates="order", uselist=False) - - -class Payment(Base): - """결제 테이블""" - __tablename__ = "payments" - - id: Mapped[int] = mapped_column(Integer, primary_key=True) - payment_id: Mapped[str] = mapped_column(String(50), unique=True, index=True) - order_id: Mapped[int] = mapped_column(ForeignKey("orders.id"), index=True) - amount: Mapped[Decimal] = mapped_column(Numeric(10, 2)) - currency: Mapped[str] = mapped_column(String(3), default="KRW") - status: Mapped[str] = mapped_column( - String(20), default=PaymentStatus.PENDING.value - ) - gateway_transaction_id: Mapped[str | None] = mapped_column(String(100)) - gateway_response: Mapped[str | None] = mapped_column(Text) - error_message: Mapped[str | None] = mapped_column(Text) - created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow) - updated_at: Mapped[datetime] = mapped_column( - DateTime, default=datetime.utcnow, onupdate=datetime.utcnow - ) - - # Relationships - order: Mapped["Order"] = relationship(back_populates="payment") -``` - -**services/payment_gateway.py - 결제 게이트웨이** -```python -""" -Payment gateway service client. -""" -import httpx -from dataclasses import dataclass -from decimal import Decimal - - -@dataclass -class PaymentResult: - """결제 결과""" - transaction_id: str - status: str - message: str - raw_response: dict - - -class PaymentGatewayService: - """ - 외부 결제 게이트웨이 클라이언트. - - 주의: 결제 API 호출은 반드시 DB 세션 외부에서! - 결제는 3-10초 정도 소요될 수 있습니다. - """ - - def __init__(self, base_url: str, api_key: str): - self.base_url = base_url - self.api_key = api_key - self.timeout = httpx.Timeout(30.0, connect=10.0) - - async def process_payment( - self, - payment_id: str, - amount: Decimal, - currency: str, - card_token: str, - ) -> PaymentResult: - """ - 결제 처리. - - 이 함수는 3-10초가 소요될 수 있습니다. - 반드시 DB 세션 외부에서 호출하세요! - """ - async with httpx.AsyncClient(timeout=self.timeout) as client: - response = await client.post( - f"{self.base_url}/v1/payments", - headers={"Authorization": f"Bearer {self.api_key}"}, - json={ - "merchant_uid": payment_id, - "amount": float(amount), - "currency": currency, - "card_token": card_token, - } - ) - response.raise_for_status() - data = response.json() - - return PaymentResult( - transaction_id=data["transaction_id"], - status=data["status"], - message=data.get("message", ""), - raw_response=data, - ) - - async def verify_payment(self, transaction_id: str) -> PaymentResult: - """결제 검증""" - async with httpx.AsyncClient(timeout=self.timeout) as client: - response = await client.get( - f"{self.base_url}/v1/payments/{transaction_id}", - headers={"Authorization": f"Bearer {self.api_key}"}, - ) - response.raise_for_status() - data = response.json() - - return PaymentResult( - transaction_id=data["transaction_id"], - status=data["status"], - message=data.get("message", ""), - raw_response=data, - ) - - async def refund_payment( - self, - transaction_id: str, - amount: Decimal | None = None - ) -> PaymentResult: - """환불 처리""" - async with httpx.AsyncClient(timeout=self.timeout) as client: - payload = {"transaction_id": transaction_id} - if amount: - payload["amount"] = float(amount) - - response = await client.post( - f"{self.base_url}/v1/refunds", - headers={"Authorization": f"Bearer {self.api_key}"}, - json=payload, - ) - response.raise_for_status() - data = response.json() - - return PaymentResult( - transaction_id=data["refund_id"], - status=data["status"], - message=data.get("message", ""), - raw_response=data, - ) -``` - -**api/routes/payments.py - 결제 API (3-Stage Pattern)** -```python -""" -Payment API routes with proper session management. - -결제 시스템에서의 3-Stage Pattern: -- Stage 1: 주문/결제 레코드 생성 (트랜잭션 보장) -- Stage 2: 외부 결제 게이트웨이 호출 (세션 없음) -- Stage 3: 결과 업데이트 (새 트랜잭션) - -중요: 결제는 멱등성(Idempotency)을 보장해야 합니다! -""" -import json -from decimal import Decimal -from uuid import uuid4 - -from fastapi import APIRouter, Depends, HTTPException, Header -from pydantic import BaseModel -from sqlalchemy import select -from sqlalchemy.ext.asyncio import AsyncSession - -from app.database.session import get_api_session, ApiSessionLocal -from app.database.models import Order, Payment, PaymentStatus -from app.services.payment_gateway import PaymentGatewayService -from app.config import settings - - -router = APIRouter(prefix="/payments", tags=["payments"]) - -# 결제 게이트웨이 서비스 -gateway = PaymentGatewayService( - settings.PAYMENT_GATEWAY_URL, - settings.PAYMENT_GATEWAY_KEY, -) - - -class PaymentRequest(BaseModel): - """결제 요청""" - order_number: str - amount: Decimal - currency: str = "KRW" - card_token: str - - -class PaymentResponse(BaseModel): - """결제 응답""" - payment_id: str - order_number: str - status: str - amount: Decimal - transaction_id: str | None = None - message: str | None = None - - -@router.post("/process", response_model=PaymentResponse) -async def process_payment( - request: PaymentRequest, - idempotency_key: str = Header(..., alias="Idempotency-Key"), - session: AsyncSession = Depends(get_api_session), -) -> PaymentResponse: - """ - 결제 처리 (3-Stage Pattern 적용). - - 멱등성 보장: - - Idempotency-Key 헤더로 중복 결제 방지 - - 동일 키로 재요청 시 기존 결과 반환 - - 3-Stage Pattern: - - Stage 1: 주문 조회 및 결제 레코드 생성 - - Stage 2: 외부 결제 API 호출 (세션 해제) - - Stage 3: 결제 결과 업데이트 - """ - payment_id = f"PAY-{idempotency_key}" - - # ========== 멱등성 체크 ========== - existing = await session.execute( - select(Payment).where(Payment.payment_id == payment_id) - ) - existing_payment = existing.scalar_one_or_none() - - if existing_payment: - # 이미 처리된 결제가 있으면 기존 결과 반환 - return PaymentResponse( - payment_id=existing_payment.payment_id, - order_number=request.order_number, - status=existing_payment.status, - amount=existing_payment.amount, - transaction_id=existing_payment.gateway_transaction_id, - message="이미 처리된 결제입니다", - ) - - # ========== Stage 1: 주문 조회 및 결제 레코드 생성 ========== - print(f"[Stage 1] Creating payment - payment_id: {payment_id}") - - # 주문 조회 - order_result = await session.execute( - select(Order) - .where(Order.order_number == request.order_number) - .limit(1) - ) - order = order_result.scalar_one_or_none() - - if not order: - raise HTTPException(status_code=404, detail="주문을 찾을 수 없습니다") - - if order.total_amount != request.amount: - raise HTTPException(status_code=400, detail="결제 금액이 일치하지 않습니다") - - # 결제 레코드 생성 - payment = Payment( - payment_id=payment_id, - order_id=order.id, - amount=request.amount, - currency=request.currency, - status=PaymentStatus.PROCESSING.value, - ) - session.add(payment) - - # 주문 상태 업데이트 - order.status = "payment_processing" - - await session.commit() - payment_db_id = payment.id - order_id = order.id - print(f"[Stage 1] Payment record created - payment_id: {payment_id}") - - # ========== Stage 2: 외부 결제 API 호출 (세션 없음!) ========== - # 이 구간에서는 DB 커넥션을 점유하지 않습니다 - print(f"[Stage 2] Calling payment gateway - payment_id: {payment_id}") - - try: - gateway_result = await gateway.process_payment( - payment_id=payment_id, - amount=request.amount, - currency=request.currency, - card_token=request.card_token, - ) - print(f"[Stage 2] Gateway response - status: {gateway_result.status}") - - except Exception as e: - # 게이트웨이 오류 시 실패 처리 - print(f"[Stage 2] Gateway error - {e}") - - async with ApiSessionLocal() as error_session: - # 결제 실패 처리 - stmt = select(Payment).where(Payment.id == payment_db_id) - db_payment = (await error_session.execute(stmt)).scalar_one() - db_payment.status = PaymentStatus.FAILED.value - db_payment.error_message = str(e) - - # 주문 상태 복원 - order_stmt = select(Order).where(Order.id == order_id) - db_order = (await error_session.execute(order_stmt)).scalar_one() - db_order.status = "payment_failed" - - await error_session.commit() - - raise HTTPException( - status_code=500, - detail=f"결제 처리 중 오류가 발생했습니다: {str(e)}" - ) - - # ========== Stage 3: 결제 결과 업데이트 (새 세션) ========== - print(f"[Stage 3] Updating payment result - payment_id: {payment_id}") - - async with ApiSessionLocal() as update_session: - # 결제 정보 업데이트 - stmt = select(Payment).where(Payment.id == payment_db_id) - db_payment = (await update_session.execute(stmt)).scalar_one() - - if gateway_result.status == "success": - db_payment.status = PaymentStatus.COMPLETED.value - new_order_status = "paid" - else: - db_payment.status = PaymentStatus.FAILED.value - new_order_status = "payment_failed" - - db_payment.gateway_transaction_id = gateway_result.transaction_id - db_payment.gateway_response = json.dumps(gateway_result.raw_response) - - # 주문 상태 업데이트 - order_stmt = select(Order).where(Order.id == order_id) - db_order = (await update_session.execute(order_stmt)).scalar_one() - db_order.status = new_order_status - - await update_session.commit() - print(f"[Stage 3] Payment completed - status: {db_payment.status}") - - return PaymentResponse( - payment_id=db_payment.payment_id, - order_number=request.order_number, - status=db_payment.status, - amount=db_payment.amount, - transaction_id=db_payment.gateway_transaction_id, - message=gateway_result.message, - ) - - -@router.get("/{payment_id}", response_model=PaymentResponse) -async def get_payment_status( - payment_id: str, - session: AsyncSession = Depends(get_api_session), -) -> PaymentResponse: - """결제 상태 조회""" - # 안전한 쿼리 패턴 - stmt = ( - select(Payment) - .where(Payment.payment_id == payment_id) - .limit(1) - ) - result = await session.execute(stmt) - payment = result.scalar_one_or_none() - - if not payment: - raise HTTPException(status_code=404, detail="결제 정보를 찾을 수 없습니다") - - # 주문 정보 조회 - order_stmt = select(Order).where(Order.id == payment.order_id) - order = (await session.execute(order_stmt)).scalar_one() - - return PaymentResponse( - payment_id=payment.payment_id, - order_number=order.order_number, - status=payment.status, - amount=payment.amount, - transaction_id=payment.gateway_transaction_id, - ) - - -@router.post("/{payment_id}/refund") -async def refund_payment( - payment_id: str, - session: AsyncSession = Depends(get_api_session), -) -> PaymentResponse: - """ - 환불 처리 (3-Stage Pattern). - """ - # Stage 1: 결제 정보 조회 - stmt = select(Payment).where(Payment.payment_id == payment_id).limit(1) - result = await session.execute(stmt) - payment = result.scalar_one_or_none() - - if not payment: - raise HTTPException(status_code=404, detail="결제 정보를 찾을 수 없습니다") - - if payment.status != PaymentStatus.COMPLETED.value: - raise HTTPException(status_code=400, detail="환불 가능한 상태가 아닙니다") - - if not payment.gateway_transaction_id: - raise HTTPException(status_code=400, detail="거래 ID가 없습니다") - - transaction_id = payment.gateway_transaction_id - payment_db_id = payment.id - order_id = payment.order_id - amount = payment.amount - - # 상태를 processing으로 변경 - payment.status = "refund_processing" - await session.commit() - - # Stage 2: 환불 API 호출 (세션 없음) - try: - refund_result = await gateway.refund_payment(transaction_id, amount) - except Exception as e: - # 실패 시 상태 복원 - async with ApiSessionLocal() as error_session: - stmt = select(Payment).where(Payment.id == payment_db_id) - db_payment = (await error_session.execute(stmt)).scalar_one() - db_payment.status = PaymentStatus.COMPLETED.value # 원래 상태로 - await error_session.commit() - - raise HTTPException(status_code=500, detail=str(e)) - - # Stage 3: 결과 저장 - async with ApiSessionLocal() as update_session: - stmt = select(Payment).where(Payment.id == payment_db_id) - db_payment = (await update_session.execute(stmt)).scalar_one() - - if refund_result.status == "success": - db_payment.status = PaymentStatus.REFUNDED.value - - # 주문 상태도 업데이트 - order_stmt = select(Order).where(Order.id == order_id) - db_order = (await update_session.execute(order_stmt)).scalar_one() - db_order.status = "refunded" - else: - db_payment.status = PaymentStatus.COMPLETED.value # 환불 실패 시 원래 상태 - - await update_session.commit() - - return PaymentResponse( - payment_id=db_payment.payment_id, - order_number="", # 간단히 처리 - status=db_payment.status, - amount=db_payment.amount, - transaction_id=refund_result.transaction_id, - message=refund_result.message, - ) -``` - -**main.py - 애플리케이션** -```python -""" -Payment service main application. -""" -from contextlib import asynccontextmanager - -from fastapi import FastAPI - -from app.database.session import dispose_engines -from app.api.routes import payments - - -@asynccontextmanager -async def lifespan(app: FastAPI): - """생명주기 관리""" - print("[Payment Service] Starting...") - yield - print("[Payment Service] Shutting down...") - await dispose_engines() - - -app = FastAPI( - title="Payment Service", - description="결제 처리 서비스", - version="1.0.0", - lifespan=lifespan, -) - -app.include_router(payments.router, prefix="/api/v1") - - -@app.get("/health") -async def health(): - return {"status": "healthy", "service": "payment"} -``` - ---- - -## 7. 설계 원칙 요약 - -### 7.1 핵심 설계 원칙 - -``` -┌─────────────────────────────────────────────────────────────────┐ -│ 커넥션 풀 설계 원칙 │ -├─────────────────────────────────────────────────────────────────┤ -│ │ -│ 1. 최소 점유 원칙 (Minimal Hold Principle) │ -│ ───────────────────────────────────────── │ -│ "DB 커넥션은 DB 작업에만 사용하고 즉시 반환" │ -│ │ -│ ✗ session.query() → external_api() → session.commit() │ -│ ✓ session.query() → commit() → external_api() → new_session │ -│ │ -│ 2. 워크로드 분리 원칙 (Workload Isolation) │ -│ ───────────────────────────────────────── │ -│ "다른 특성의 워크로드는 다른 풀을 사용" │ -│ │ -│ API 요청 → ApiPool (빠른 응답, 짧은 타임아웃) │ -│ 백그라운드 → BackgroundPool (안정성, 긴 타임아웃) │ -│ │ -│ 3. 안전한 쿼리 원칙 (Safe Query Pattern) │ -│ ───────────────────────────────────── │ -│ "중복 가능성이 있는 조회는 항상 limit(1) 사용" │ -│ │ -│ select(Model).where(...).order_by(desc).limit(1) │ -│ │ -│ 4. 3-Stage 처리 원칙 (3-Stage Processing) │ -│ ───────────────────────────────────── │ -│ Stage 1: DB 작업 + 커밋 (세션 해제) │ -│ Stage 2: 외부 API 호출 (세션 없음) │ -│ Stage 3: 결과 저장 (새 세션) │ -│ │ -│ 5. 명시적 범위 원칙 (Explicit Scope) │ -│ ───────────────────────────────────── │ -│ "세션 범위를 async with로 명확히 정의" │ -│ │ -│ async with SessionLocal() as session: │ -│ # 이 블록 내에서만 세션 사용 │ -│ │ -└─────────────────────────────────────────────────────────────────┘ -``` - -### 7.2 체크리스트 - -새로운 API 엔드포인트를 작성할 때 확인해야 할 사항: - -``` -□ 외부 API 호출이 있는가? - → 있다면 3-Stage Pattern 적용 - -□ 백그라운드 작업이 있는가? - → 있다면 BackgroundSessionLocal 사용 - -□ 중복 데이터가 발생할 수 있는 쿼리가 있는가? - → 있다면 order_by().limit(1) 적용 - -□ 세션이 예외 상황에서도 반환되는가? - → async with 또는 try/finally 사용 - -□ 트랜잭션 범위가 적절한가? - → 필요한 작업만 포함, 외부 호출 제외 -``` - -### 7.3 Anti-Pattern 회피 - -``` -┌─────────────────────────────────────────────────────────────────┐ -│ 피해야 할 패턴 │ -├─────────────────────────────────────────────────────────────────┤ -│ │ -│ Anti-Pattern 1: Long-lived Session │ -│ ─────────────────────────────────── │ -│ ✗ async def handler(session): │ -│ data = await session.query() │ -│ result = await http_client.post() # 30초 소요 │ -│ session.add(result) │ -│ await session.commit() │ -│ │ -│ Anti-Pattern 2: Shared Pool for All │ -│ ─────────────────────────────────── │ -│ ✗ 모든 작업이 단일 풀 사용 │ -│ → 백그라운드 작업이 API 응답을 블록킹 │ -│ │ -│ Anti-Pattern 3: Unsafe Query │ -│ ─────────────────────────────── │ -│ ✗ scalar_one_or_none() without limit(1) │ -│ → 중복 데이터 시 예외 발생 │ -│ │ -│ Anti-Pattern 4: Missing Error Handling │ -│ ─────────────────────────────────────── │ -│ ✗ session = SessionLocal() │ -│ await session.query() # 예외 발생 시 세션 누수 │ -│ │ -└─────────────────────────────────────────────────────────────────┘ -``` - ---- - -## 결론 - -이 문서에서 다룬 문제들은 대부분 **"외부 리소스 접근 중 DB 세션 점유"**라는 공통된 원인에서 발생했습니다. - -해결의 핵심은: - -1. **책임 분리**: DB 작업과 외부 API 호출을 명확히 분리 -2. **리소스 격리**: 워크로드별 별도 커넥션 풀 사용 -3. **방어적 프로그래밍**: 중복 데이터, 예외 상황 대비 - -이러한 원칙을 코드 리뷰 시 체크리스트로 활용하면, 프로덕션 환경에서의 커넥션 풀 관련 장애를 예방할 수 있습니다. +# Database Connection Pool 문제 분석 및 해결 가이드 + +## 목차 +1. [발견된 문제점 요약](#1-발견된-문제점-요약) +2. [설계적 문제 분석](#2-설계적-문제-분석) +3. [해결 방안 및 설계 제안](#3-해결-방안-및-설계-제안) +4. [개선 효과](#4-개선-효과) +5. [이론적 배경: 커넥션 풀 관리 원칙](#5-이론적-배경-커넥션-풀-관리-원칙) +6. [실무 시나리오 예제 코드](#6-실무-시나리오-예제-코드) +7. [설계 원칙 요약](#7-설계-원칙-요약) + +--- + +## 1. 발견된 문제점 요약 + +### 1.1 "Multiple rows were found when one or none was required" 에러 + +**문제 상황:** +```python +# 기존 코드 (문제) +result = await session.execute(select(Project).where(Project.task_id == task_id)) +project = result.scalar_one_or_none() # task_id 중복 시 에러 발생! +``` + +**원인:** +- `task_id`로 조회 시 중복 레코드가 존재할 수 있음 +- `scalar_one_or_none()`은 정확히 0개 또는 1개의 결과만 허용 + +**해결:** +```python +# 수정된 코드 +result = await session.execute( + select(Project) + .where(Project.task_id == task_id) + .order_by(Project.created_at.desc()) + .limit(1) +) +project = result.scalar_one_or_none() +``` + +### 1.2 커넥션 풀 고갈 (Pool Exhaustion) + +**증상:** +- API 요청이 응답을 반환하지 않음 +- 동일한 요청이 중복으로 들어옴 (클라이언트 재시도) +- 서버 로그에 타임아웃 관련 메시지 + +**원인:** +- 외부 API 호출 중 DB 세션을 계속 점유 +- 백그라운드 태스크와 API 요청이 동일한 커넥션 풀 사용 + +### 1.3 세션 장시간 점유 + +**문제가 발생한 함수들:** + +| 파일 | 함수 | 문제 | +|------|------|------| +| `video.py` | `generate_video` | Creatomate API 호출 중 세션 점유 | +| `home.py` | `upload_images_blob` | Azure Blob 업로드 중 세션 점유 | +| `song_task.py` | 모든 함수 | API 풀과 동일한 세션 사용 | +| `video_task.py` | 모든 함수 | API 풀과 동일한 세션 사용 | +| `lyric_task.py` | `generate_lyric_background` | API 풀과 동일한 세션 사용 | + +--- + +## 2. 설계적 문제 분석 + +### 2.1 Anti-Pattern: Long-lived Session with External Calls + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ 문제가 있는 패턴 │ +├─────────────────────────────────────────────────────────────────┤ +│ │ +│ Request ──► Session 획득 ──► DB 조회 ──► 외부 API 호출 ──► DB 저장 ──► Session 반환 +│ │ │ │ +│ │ 30초~수 분 소요 │ │ +│ │◄─────── 세션 점유 시간 ───────►│ │ +│ │ +└─────────────────────────────────────────────────────────────────┘ + +문제점: +1. 외부 API 응답 대기 동안 커넥션 점유 +2. Pool size=20일 때, 20개 요청만으로 풀 고갈 +3. 후속 요청들이 pool_timeout까지 대기 후 실패 +``` + +### 2.2 Anti-Pattern: Shared Pool for Different Workloads + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ 공유 풀 문제 │ +├─────────────────────────────────────────────────────────────────┤ +│ │ +│ ┌──────────────┐ ┌─────────────────────┐ │ +│ │ API Requests │──────► │ │ +│ └──────────────┘ │ Single Pool │ │ +│ │ (pool_size=20) │ │ +│ ┌──────────────┐ │ │ │ +│ │ Background │──────► │ │ +│ │ Tasks │ └─────────────────────┘ │ +│ └──────────────┘ │ +│ │ +│ 문제: 백그라운드 태스크가 커넥션을 오래 점유하면 │ +│ API 요청이 커넥션을 얻지 못함 │ +│ │ +└─────────────────────────────────────────────────────────────────┘ +``` + +### 2.3 근본 원인 분석 + +``` +원인 1: 책임 분리 실패 (Separation of Concerns) +├── DB 작업과 외부 API 호출이 단일 함수에 혼재 +├── 트랜잭션 범위가 불필요하게 넓음 +└── 세션 생명주기 관리 부재 + +원인 2: 리소스 격리 실패 (Resource Isolation) +├── API 요청과 백그라운드 태스크가 동일 풀 사용 +├── 워크로드 특성 미고려 (빠른 API vs 느린 백그라운드) +└── 우선순위 기반 리소스 할당 부재 + +원인 3: 방어적 프로그래밍 부재 (Defensive Programming) +├── 중복 데이터 발생 가능성 미고려 +├── 타임아웃 및 재시도 로직 미흡 +└── 에러 상태에서의 세션 처리 미흡 +``` + +--- + +## 3. 해결 방안 및 설계 제안 + +### 3.1 해결책 1: 3-Stage Pattern (세션 분리 패턴) + +**핵심 아이디어:** 외부 API 호출 전에 세션을 반환하고, 호출 완료 후 새 세션으로 결과 저장 + +```python +async def process_with_external_api(task_id: str, session: AsyncSession): + """3-Stage Pattern 적용""" + + # ========== Stage 1: DB 조회 및 준비 (세션 사용) ========== + data = await session.execute(select(Model).where(...)) + prepared_data = extract_needed_info(data) + await session.commit() # 세션 해제 + + # ========== Stage 2: 외부 API 호출 (세션 없음) ========== + # 이 구간에서는 DB 커넥션을 점유하지 않음 + api_result = await external_api.call(prepared_data) + + # ========== Stage 3: 결과 저장 (새 세션) ========== + async with AsyncSessionLocal() as new_session: + record = await new_session.execute(select(Model).where(...)) + record.status = "completed" + record.result = api_result + await new_session.commit() + + return result +``` + +### 3.2 해결책 2: Separate Pool Strategy (풀 분리 전략) + +**핵심 아이디어:** API 요청과 백그라운드 태스크에 별도의 커넥션 풀 사용 + +```python +# 메인 엔진 (FastAPI 요청용) - 빠른 응답 필요 +engine = create_async_engine( + url=db_url, + pool_size=20, + max_overflow=20, + pool_timeout=30, # 빠른 실패 + pool_recycle=3600, +) +AsyncSessionLocal = async_sessionmaker(bind=engine, ...) + +# 백그라운드 엔진 (장시간 작업용) - 안정성 우선 +background_engine = create_async_engine( + url=db_url, + pool_size=10, + max_overflow=10, + pool_timeout=60, # 여유있는 대기 + pool_recycle=3600, +) +BackgroundSessionLocal = async_sessionmaker(bind=background_engine, ...) +``` + +### 3.3 해결책 3: Query Safety Pattern (안전한 쿼리 패턴) + +**핵심 아이디어:** 항상 최신 데이터 1개만 조회 + +```python +# 안전한 조회 패턴 +async def get_latest_record(session: AsyncSession, task_id: str): + result = await session.execute( + select(Model) + .where(Model.task_id == task_id) + .order_by(Model.created_at.desc()) + .limit(1) + ) + return result.scalar_one_or_none() +``` + +--- + +## 4. 개선 효과 + +### 4.1 정량적 효과 + +| 지표 | 개선 전 | 개선 후 | 개선율 | +|------|---------|---------|--------| +| 평균 세션 점유 시간 | 30-60초 | 0.1-0.5초 | 99% 감소 | +| 동시 처리 가능 요청 | ~20개 | ~200개+ | 10배 이상 | +| Pool Exhaustion 발생 | 빈번 | 거의 없음 | - | +| API 응답 실패율 | 높음 | 매우 낮음 | - | + +### 4.2 정성적 효과 + +``` +개선 효과 매트릭스: + + 개선 전 개선 후 + ───────────────────────── +안정성 │ ★★☆☆☆ │ ★★★★★ │ +확장성 │ ★★☆☆☆ │ ★★★★☆ │ +유지보수성 │ ★★★☆☆ │ ★★★★☆ │ +리소스 효율성 │ ★☆☆☆☆ │ ★★★★★ │ +에러 추적 용이성 │ ★★☆☆☆ │ ★★★★☆ │ +``` + +--- + +## 5. 이론적 배경: 커넥션 풀 관리 원칙 + +### 5.1 커넥션 풀의 목적 + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ 커넥션 풀 동작 원리 │ +├─────────────────────────────────────────────────────────────────┤ +│ │ +│ Application Connection Pool Database│ +│ │ │ │ │ +│ │─── get_connection() ────────►│ │ │ +│ │◄── connection ───────────────│ │ │ +│ │ │ │ │ +│ │─── execute(query) ───────────┼──────────────────────►│ │ +│ │◄── result ───────────────────┼◄──────────────────────│ │ +│ │ │ │ │ +│ │─── release_connection() ────►│ │ │ +│ │ │ (connection 재사용) │ │ +│ │ +│ 장점: │ +│ 1. 연결 생성 오버헤드 제거 (TCP handshake, 인증 등) │ +│ 2. 동시 연결 수 제한으로 DB 과부하 방지 │ +│ 3. 연결 재사용으로 리소스 효율성 향상 │ +│ │ +└─────────────────────────────────────────────────────────────────┘ +``` + +### 5.2 핵심 파라미터 이해 + +```python +engine = create_async_engine( + url=database_url, + + # pool_size: 풀에서 유지하는 영구 연결 수 + # - 너무 작으면: 요청 대기 발생 + # - 너무 크면: DB 리소스 낭비 + pool_size=20, + + # max_overflow: pool_size 초과 시 생성 가능한 임시 연결 수 + # - 총 최대 연결 = pool_size + max_overflow + # - burst traffic 처리용 + max_overflow=20, + + # pool_timeout: 연결 대기 최대 시간 (초) + # - 초과 시 TimeoutError 발생 + # - API 서버: 짧게 (빠른 실패 선호) + # - Background: 길게 (안정성 선호) + pool_timeout=30, + + # pool_recycle: 연결 재생성 주기 (초) + # - MySQL wait_timeout보다 짧게 설정 + # - "MySQL has gone away" 에러 방지 + pool_recycle=3600, + + # pool_pre_ping: 연결 사용 전 유효성 검사 + # - True: SELECT 1 실행하여 연결 확인 + # - 약간의 오버헤드, 높은 안정성 + pool_pre_ping=True, +) +``` + +### 5.3 세션 관리 원칙 + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ 세션 관리 원칙 │ +├─────────────────────────────────────────────────────────────────┤ +│ │ +│ 원칙 1: 최소 점유 시간 (Minimal Hold Time) │ +│ ───────────────────────────────────────── │ +│ "세션은 DB 작업에만 사용하고, 즉시 반환한다" │ +│ │ +│ ✗ 나쁜 예: │ +│ session.query() → http_call(30s) → session.commit() │ +│ │ +│ ✓ 좋은 예: │ +│ session.query() → session.commit() → http_call() → new_session│ +│ │ +│ 원칙 2: 범위 명확성 (Clear Scope) │ +│ ───────────────────────────────── │ +│ "세션의 시작과 끝을 명확히 정의한다" │ +│ │ +│ ✓ async with AsyncSessionLocal() as session: │ +│ # 이 블록 내에서만 세션 사용 │ +│ pass │ +│ # 블록 종료 시 자동 반환 │ +│ │ +│ 원칙 3: 단일 책임 (Single Responsibility) │ +│ ───────────────────────────────────────── │ +│ "하나의 세션 블록은 하나의 트랜잭션 단위만 처리한다" │ +│ │ +│ 원칙 4: 실패 대비 (Failure Handling) │ +│ ─────────────────────────────────── │ +│ "예외 발생 시에도 세션이 반환되도록 보장한다" │ +│ │ +│ async with session: │ +│ try: │ +│ ... │ +│ except Exception: │ +│ await session.rollback() │ +│ raise │ +│ # finally에서 자동 close │ +│ │ +└─────────────────────────────────────────────────────────────────┘ +``` + +### 5.4 워크로드 분리 원칙 + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ 워크로드 분리 전략 │ +├─────────────────────────────────────────────────────────────────┤ +│ │ +│ 워크로드 유형별 특성: │ +│ │ +│ ┌─────────────────┬─────────────────┬─────────────────┐ │ +│ │ API 요청 │ 백그라운드 작업 │ 배치 작업 │ │ +│ ├─────────────────┼─────────────────┼─────────────────┤ │ +│ │ 짧은 응답 시간 │ 긴 처리 시간 │ 매우 긴 처리 │ │ +│ │ 높은 동시성 │ 중간 동시성 │ 낮은 동시성 │ │ +│ │ 빠른 실패 선호 │ 재시도 허용 │ 안정성 최우선 │ │ +│ └─────────────────┴─────────────────┴─────────────────┘ │ +│ │ +│ 분리 전략: │ +│ │ +│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ +│ │ API Pool │ │ Background │ │ Batch Pool │ │ +│ │ size=20 │ │ Pool │ │ size=5 │ │ +│ │ timeout=30s │ │ size=10 │ │ timeout=300s│ │ +│ └─────────────┘ │ timeout=60s │ └─────────────┘ │ +│ └─────────────┘ │ +│ │ +│ 이점: │ +│ 1. 워크로드 간 간섭 방지 │ +│ 2. 각 워크로드에 최적화된 설정 적용 │ +│ 3. 장애 격리 (한 풀의 문제가 다른 풀에 영향 X) │ +│ │ +└─────────────────────────────────────────────────────────────────┘ +``` + +--- + +## 6. 실무 시나리오 예제 코드 + +### 시나리오 1: 이미지 처리 서비스 + +실제 프로젝트에서 자주 발생하는 "이미지 업로드 → 외부 처리 → 결과 저장" 패턴 + +#### 6.1.1 프로젝트 구조 + +``` +image_processing_service/ +├── app/ +│ ├── __init__.py +│ ├── main.py +│ ├── config.py +│ ├── database/ +│ │ ├── __init__.py +│ │ ├── session.py +│ │ └── models.py +│ ├── api/ +│ │ ├── __init__.py +│ │ └── routes/ +│ │ ├── __init__.py +│ │ └── images.py +│ ├── services/ +│ │ ├── __init__.py +│ │ ├── image_processor.py +│ │ └── storage_service.py +│ └── workers/ +│ ├── __init__.py +│ └── image_tasks.py +└── requirements.txt +``` + +#### 6.1.2 코드 구현 + +**config.py - 설정** +```python +""" +Configuration module for the image processing service. +""" +from pydantic_settings import BaseSettings + + +class Settings(BaseSettings): + """Application settings""" + + # Database + DATABASE_URL: str = "mysql+asyncmy://user:pass@localhost/imagedb" + + # API Pool settings (빠른 응답 우선) + API_POOL_SIZE: int = 20 + API_POOL_MAX_OVERFLOW: int = 20 + API_POOL_TIMEOUT: int = 30 + + # Background Pool settings (안정성 우선) + BG_POOL_SIZE: int = 10 + BG_POOL_MAX_OVERFLOW: int = 10 + BG_POOL_TIMEOUT: int = 60 + + # External services + IMAGE_PROCESSOR_URL: str = "https://api.imageprocessor.com" + STORAGE_BUCKET: str = "processed-images" + + class Config: + env_file = ".env" + + +settings = Settings() +``` + +**database/session.py - 세션 관리** +```python +""" +Database session management with separate pools for different workloads. + +핵심 설계 원칙: +1. API 요청과 백그라운드 작업에 별도 풀 사용 +2. 각 풀은 워크로드 특성에 맞게 설정 +3. 세션 상태 모니터링을 위한 로깅 +""" +from contextlib import asynccontextmanager +from typing import AsyncGenerator + +from sqlalchemy.ext.asyncio import ( + AsyncSession, + async_sessionmaker, + create_async_engine, +) + +from app.config import settings + + +# ============================================================ +# 메인 엔진 (FastAPI 요청용) +# ============================================================ +# 특징: 빠른 응답, 짧은 타임아웃, 빠른 실패 +api_engine = create_async_engine( + url=settings.DATABASE_URL, + pool_size=settings.API_POOL_SIZE, + max_overflow=settings.API_POOL_MAX_OVERFLOW, + pool_timeout=settings.API_POOL_TIMEOUT, + pool_recycle=3600, + pool_pre_ping=True, + echo=False, # Production에서는 False +) + +ApiSessionLocal = async_sessionmaker( + bind=api_engine, + class_=AsyncSession, + expire_on_commit=False, + autoflush=False, +) + + +# ============================================================ +# 백그라운드 엔진 (비동기 작업용) +# ============================================================ +# 특징: 긴 타임아웃, 안정성 우선 +background_engine = create_async_engine( + url=settings.DATABASE_URL, + pool_size=settings.BG_POOL_SIZE, + max_overflow=settings.BG_POOL_MAX_OVERFLOW, + pool_timeout=settings.BG_POOL_TIMEOUT, + pool_recycle=3600, + pool_pre_ping=True, + echo=False, +) + +BackgroundSessionLocal = async_sessionmaker( + bind=background_engine, + class_=AsyncSession, + expire_on_commit=False, + autoflush=False, +) + + +# ============================================================ +# 세션 제공 함수 +# ============================================================ +async def get_api_session() -> AsyncGenerator[AsyncSession, None]: + """ + FastAPI Dependency로 사용할 API 세션 제공자. + + 사용 예: + @router.post("/images") + async def upload(session: AsyncSession = Depends(get_api_session)): + ... + """ + # 풀 상태 로깅 (디버깅용) + pool = api_engine.pool + print( + f"[API Pool] size={pool.size()}, " + f"checked_out={pool.checkedout()}, " + f"overflow={pool.overflow()}" + ) + + async with ApiSessionLocal() as session: + try: + yield session + except Exception: + await session.rollback() + raise + + +@asynccontextmanager +async def get_background_session() -> AsyncGenerator[AsyncSession, None]: + """ + 백그라운드 작업용 세션 컨텍스트 매니저. + + 사용 예: + async with get_background_session() as session: + result = await session.execute(query) + """ + pool = background_engine.pool + print( + f"[Background Pool] size={pool.size()}, " + f"checked_out={pool.checkedout()}, " + f"overflow={pool.overflow()}" + ) + + async with BackgroundSessionLocal() as session: + try: + yield session + except Exception: + await session.rollback() + raise + + +# ============================================================ +# 리소스 정리 +# ============================================================ +async def dispose_engines() -> None: + """애플리케이션 종료 시 모든 엔진 정리""" + await api_engine.dispose() + await background_engine.dispose() + print("[Database] All engines disposed") +``` + +**database/models.py - 모델** +```python +""" +Database models for image processing service. +""" +from datetime import datetime +from enum import Enum + +from sqlalchemy import String, Text, DateTime, Integer, Float +from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column + + +class Base(DeclarativeBase): + pass + + +class ImageStatus(str, Enum): + """이미지 처리 상태""" + PENDING = "pending" + PROCESSING = "processing" + COMPLETED = "completed" + FAILED = "failed" + + +class Image(Base): + """이미지 테이블""" + __tablename__ = "images" + + id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) + task_id: Mapped[str] = mapped_column(String(50), index=True, nullable=False) + original_url: Mapped[str] = mapped_column(Text, nullable=False) + processed_url: Mapped[str | None] = mapped_column(Text, nullable=True) + status: Mapped[str] = mapped_column( + String(20), + default=ImageStatus.PENDING.value, + nullable=False + ) + width: Mapped[int | None] = mapped_column(Integer, nullable=True) + height: Mapped[int | None] = mapped_column(Integer, nullable=True) + file_size: Mapped[int | None] = mapped_column(Integer, nullable=True) + processing_time: Mapped[float | None] = mapped_column(Float, nullable=True) + error_message: Mapped[str | None] = mapped_column(Text, nullable=True) + created_at: Mapped[datetime] = mapped_column( + DateTime, + default=datetime.utcnow, + nullable=False + ) + updated_at: Mapped[datetime] = mapped_column( + DateTime, + default=datetime.utcnow, + onupdate=datetime.utcnow, + nullable=False + ) +``` + +**services/image_processor.py - 외부 API 서비스** +```python +""" +External image processing service client. +""" +import httpx +from dataclasses import dataclass + + +@dataclass +class ProcessingResult: + """이미지 처리 결과""" + processed_url: str + width: int + height: int + file_size: int + processing_time: float + + +class ImageProcessorService: + """ + 외부 이미지 처리 API 클라이언트. + + 주의: 이 서비스 호출은 DB 세션 외부에서 수행해야 합니다! + """ + + def __init__(self, base_url: str): + self.base_url = base_url + self.timeout = httpx.Timeout(60.0, connect=10.0) + + async def process_image( + self, + image_url: str, + options: dict | None = None + ) -> ProcessingResult: + """ + 외부 API를 통해 이미지 처리. + + 이 함수는 30초~수 분이 소요될 수 있습니다. + 반드시 DB 세션 외부에서 호출하세요! + + Args: + image_url: 처리할 이미지 URL + options: 처리 옵션 (resize, filter 등) + + Returns: + ProcessingResult: 처리 결과 + """ + async with httpx.AsyncClient(timeout=self.timeout) as client: + response = await client.post( + f"{self.base_url}/process", + json={ + "image_url": image_url, + "options": options or {} + } + ) + response.raise_for_status() + data = response.json() + + return ProcessingResult( + processed_url=data["processed_url"], + width=data["width"], + height=data["height"], + file_size=data["file_size"], + processing_time=data["processing_time"], + ) +``` + +**api/routes/images.py - API 라우터 (3-Stage Pattern 적용)** +```python +""" +Image API routes with proper session management. + +핵심 패턴: 3-Stage Pattern +- Stage 1: DB 작업 (세션 사용) +- Stage 2: 외부 API 호출 (세션 없음) +- Stage 3: 결과 저장 (새 세션) +""" +import asyncio +from uuid import uuid4 + +from fastapi import APIRouter, BackgroundTasks, Depends, HTTPException +from pydantic import BaseModel, HttpUrl +from sqlalchemy import select +from sqlalchemy.ext.asyncio import AsyncSession + +from app.database.session import get_api_session, ApiSessionLocal +from app.database.models import Image, ImageStatus +from app.services.image_processor import ImageProcessorService +from app.config import settings + + +router = APIRouter(prefix="/images", tags=["images"]) + +# 외부 서비스 인스턴스 +processor_service = ImageProcessorService(settings.IMAGE_PROCESSOR_URL) + + +class ImageUploadRequest(BaseModel): + """이미지 업로드 요청""" + url: HttpUrl + options: dict | None = None + + +class ImageResponse(BaseModel): + """이미지 응답""" + task_id: str + status: str + original_url: str + processed_url: str | None = None + + class Config: + from_attributes = True + + +# ============================================================ +# 동기적 처리 (짧은 작업용) - 권장하지 않음 +# ============================================================ +@router.post("/process-sync", response_model=ImageResponse) +async def process_image_sync( + request: ImageUploadRequest, + session: AsyncSession = Depends(get_api_session), +) -> ImageResponse: + """ + 동기적 이미지 처리 (3-Stage Pattern 적용). + + 주의: 외부 API 호출이 길어지면 요청 타임아웃 발생 가능. + 대부분의 경우 비동기 처리를 권장합니다. + """ + task_id = str(uuid4()) + + # ========== Stage 1: 초기 레코드 생성 ========== + image = Image( + task_id=task_id, + original_url=str(request.url), + status=ImageStatus.PROCESSING.value, + ) + session.add(image) + await session.commit() + image_id = image.id # ID 저장 + print(f"[Stage 1] Image record created - task_id: {task_id}") + + # ========== Stage 2: 외부 API 호출 (세션 없음!) ========== + # 이 구간에서는 DB 커넥션을 점유하지 않습니다 + try: + print(f"[Stage 2] Calling external API - task_id: {task_id}") + result = await processor_service.process_image( + str(request.url), + request.options + ) + print(f"[Stage 2] External API completed - task_id: {task_id}") + except Exception as e: + # 실패 시 상태 업데이트 (새 세션 사용) + async with ApiSessionLocal() as error_session: + stmt = select(Image).where(Image.id == image_id) + db_image = (await error_session.execute(stmt)).scalar_one() + db_image.status = ImageStatus.FAILED.value + db_image.error_message = str(e) + await error_session.commit() + raise HTTPException(status_code=500, detail=str(e)) + + # ========== Stage 3: 결과 저장 (새 세션) ========== + async with ApiSessionLocal() as update_session: + stmt = select(Image).where(Image.id == image_id) + db_image = (await update_session.execute(stmt)).scalar_one() + + db_image.status = ImageStatus.COMPLETED.value + db_image.processed_url = result.processed_url + db_image.width = result.width + db_image.height = result.height + db_image.file_size = result.file_size + db_image.processing_time = result.processing_time + + await update_session.commit() + print(f"[Stage 3] Result saved - task_id: {task_id}") + + return ImageResponse( + task_id=task_id, + status=db_image.status, + original_url=db_image.original_url, + processed_url=db_image.processed_url, + ) + + +# ============================================================ +# 비동기 처리 (권장) +# ============================================================ +@router.post("/process-async", response_model=ImageResponse) +async def process_image_async( + request: ImageUploadRequest, + background_tasks: BackgroundTasks, + session: AsyncSession = Depends(get_api_session), +) -> ImageResponse: + """ + 비동기 이미지 처리 (즉시 응답 반환). + + 1. 초기 레코드 생성 후 즉시 응답 + 2. 백그라운드에서 처리 진행 + 3. 상태는 GET /images/{task_id} 로 조회 + """ + task_id = str(uuid4()) + + # DB 작업: 초기 레코드 생성 + image = Image( + task_id=task_id, + original_url=str(request.url), + status=ImageStatus.PENDING.value, + ) + session.add(image) + await session.commit() + + # 백그라운드 태스크 등록 (별도 세션 사용) + background_tasks.add_task( + process_image_background, + task_id=task_id, + image_url=str(request.url), + options=request.options, + ) + + # 즉시 응답 반환 + return ImageResponse( + task_id=task_id, + status=ImageStatus.PENDING.value, + original_url=str(request.url), + ) + + +@router.get("/{task_id}", response_model=ImageResponse) +async def get_image_status( + task_id: str, + session: AsyncSession = Depends(get_api_session), +) -> ImageResponse: + """이미지 처리 상태 조회""" + # 안전한 쿼리 패턴: 최신 레코드 1개만 조회 + stmt = ( + select(Image) + .where(Image.task_id == task_id) + .order_by(Image.created_at.desc()) + .limit(1) + ) + result = await session.execute(stmt) + image = result.scalar_one_or_none() + + if not image: + raise HTTPException(status_code=404, detail="Image not found") + + return ImageResponse( + task_id=image.task_id, + status=image.status, + original_url=image.original_url, + processed_url=image.processed_url, + ) + + +# ============================================================ +# 백그라운드 처리 함수 +# ============================================================ +async def process_image_background( + task_id: str, + image_url: str, + options: dict | None, +) -> None: + """ + 백그라운드에서 이미지 처리. + + 중요: 이 함수는 BackgroundSessionLocal을 사용합니다. + API 풀과 분리되어 있어 API 응답에 영향을 주지 않습니다. + """ + from app.database.session import BackgroundSessionLocal + + print(f"[Background] Starting - task_id: {task_id}") + + # 상태를 processing으로 업데이트 + async with BackgroundSessionLocal() as session: + stmt = ( + select(Image) + .where(Image.task_id == task_id) + .order_by(Image.created_at.desc()) + .limit(1) + ) + image = (await session.execute(stmt)).scalar_one_or_none() + if image: + image.status = ImageStatus.PROCESSING.value + await session.commit() + + # 외부 API 호출 (세션 없음!) + try: + result = await processor_service.process_image(image_url, options) + + # 성공: 결과 저장 + async with BackgroundSessionLocal() as session: + stmt = ( + select(Image) + .where(Image.task_id == task_id) + .order_by(Image.created_at.desc()) + .limit(1) + ) + image = (await session.execute(stmt)).scalar_one_or_none() + if image: + image.status = ImageStatus.COMPLETED.value + image.processed_url = result.processed_url + image.width = result.width + image.height = result.height + image.file_size = result.file_size + image.processing_time = result.processing_time + await session.commit() + + print(f"[Background] Completed - task_id: {task_id}") + + except Exception as e: + # 실패: 에러 저장 + async with BackgroundSessionLocal() as session: + stmt = ( + select(Image) + .where(Image.task_id == task_id) + .order_by(Image.created_at.desc()) + .limit(1) + ) + image = (await session.execute(stmt)).scalar_one_or_none() + if image: + image.status = ImageStatus.FAILED.value + image.error_message = str(e) + await session.commit() + + print(f"[Background] Failed - task_id: {task_id}, error: {e}") +``` + +**main.py - 애플리케이션 진입점** +```python +""" +Main application entry point. +""" +from contextlib import asynccontextmanager + +from fastapi import FastAPI + +from app.database.session import dispose_engines +from app.api.routes import images + + +@asynccontextmanager +async def lifespan(app: FastAPI): + """애플리케이션 생명주기 관리""" + # Startup + print("[App] Starting up...") + yield + # Shutdown + print("[App] Shutting down...") + await dispose_engines() + + +app = FastAPI( + title="Image Processing Service", + description="이미지 처리 서비스 API", + version="1.0.0", + lifespan=lifespan, +) + +app.include_router(images.router, prefix="/api/v1") + + +@app.get("/health") +async def health_check(): + """헬스 체크""" + return {"status": "healthy"} +``` + +--- + +### 시나리오 2: 결제 처리 서비스 + +결제 시스템에서의 "주문 생성 → 결제 처리 → 결과 저장" 패턴 + +#### 6.2.1 프로젝트 구조 + +``` +payment_service/ +├── app/ +│ ├── __init__.py +│ ├── main.py +│ ├── config.py +│ ├── database/ +│ │ ├── __init__.py +│ │ ├── session.py +│ │ └── models.py +│ ├── api/ +│ │ ├── __init__.py +│ │ └── routes/ +│ │ ├── __init__.py +│ │ └── payments.py +│ ├── services/ +│ │ ├── __init__.py +│ │ └── payment_gateway.py +│ └── workers/ +│ ├── __init__.py +│ └── payment_tasks.py +└── requirements.txt +``` + +#### 6.2.2 코드 구현 + +**config.py - 설정** +```python +""" +Payment service configuration. +""" +from pydantic_settings import BaseSettings + + +class Settings(BaseSettings): + """Application settings""" + + DATABASE_URL: str = "mysql+asyncmy://user:pass@localhost/paymentdb" + + # Pool settings - 결제는 더 보수적으로 설정 + API_POOL_SIZE: int = 30 # 결제는 트래픽이 많음 + API_POOL_MAX_OVERFLOW: int = 20 + API_POOL_TIMEOUT: int = 20 # 빠른 실패 + + BG_POOL_SIZE: int = 5 # 백그라운드는 적게 + BG_POOL_MAX_OVERFLOW: int = 5 + BG_POOL_TIMEOUT: int = 120 # 결제 검증은 시간이 걸릴 수 있음 + + # Payment gateway + PAYMENT_GATEWAY_URL: str = "https://api.payment-gateway.com" + PAYMENT_GATEWAY_KEY: str = "" + + class Config: + env_file = ".env" + + +settings = Settings() +``` + +**database/session.py - 세션 관리** +```python +""" +Database session management for payment service. + +결제 서비스 특성: +1. 데이터 정합성이 매우 중요 +2. 트랜잭션 롤백이 명확해야 함 +3. 장애 시에도 데이터 손실 없어야 함 +""" +from contextlib import asynccontextmanager +from typing import AsyncGenerator + +from sqlalchemy.ext.asyncio import ( + AsyncSession, + async_sessionmaker, + create_async_engine, +) + +from app.config import settings + + +# ============================================================ +# API 엔진 (결제 요청 처리용) +# ============================================================ +api_engine = create_async_engine( + url=settings.DATABASE_URL, + pool_size=settings.API_POOL_SIZE, + max_overflow=settings.API_POOL_MAX_OVERFLOW, + pool_timeout=settings.API_POOL_TIMEOUT, + pool_recycle=1800, # 30분 (결제는 더 자주 재생성) + pool_pre_ping=True, + echo=False, +) + +ApiSessionLocal = async_sessionmaker( + bind=api_engine, + class_=AsyncSession, + expire_on_commit=False, + autoflush=False, +) + + +# ============================================================ +# 백그라운드 엔진 (결제 검증, 정산 등) +# ============================================================ +background_engine = create_async_engine( + url=settings.DATABASE_URL, + pool_size=settings.BG_POOL_SIZE, + max_overflow=settings.BG_POOL_MAX_OVERFLOW, + pool_timeout=settings.BG_POOL_TIMEOUT, + pool_recycle=1800, + pool_pre_ping=True, + echo=False, +) + +BackgroundSessionLocal = async_sessionmaker( + bind=background_engine, + class_=AsyncSession, + expire_on_commit=False, + autoflush=False, +) + + +async def get_api_session() -> AsyncGenerator[AsyncSession, None]: + """API 세션 제공""" + async with ApiSessionLocal() as session: + try: + yield session + except Exception: + await session.rollback() + raise + + +@asynccontextmanager +async def get_background_session() -> AsyncGenerator[AsyncSession, None]: + """백그라운드 세션 제공""" + async with BackgroundSessionLocal() as session: + try: + yield session + except Exception: + await session.rollback() + raise + + +async def dispose_engines() -> None: + """엔진 정리""" + await api_engine.dispose() + await background_engine.dispose() +``` + +**database/models.py - 모델** +```python +""" +Payment database models. +""" +from datetime import datetime +from decimal import Decimal +from enum import Enum + +from sqlalchemy import String, Text, DateTime, Integer, Numeric, ForeignKey +from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship + + +class Base(DeclarativeBase): + pass + + +class PaymentStatus(str, Enum): + """결제 상태""" + PENDING = "pending" # 결제 대기 + PROCESSING = "processing" # 처리 중 + COMPLETED = "completed" # 완료 + FAILED = "failed" # 실패 + REFUNDED = "refunded" # 환불됨 + CANCELLED = "cancelled" # 취소됨 + + +class Order(Base): + """주문 테이블""" + __tablename__ = "orders" + + id: Mapped[int] = mapped_column(Integer, primary_key=True) + order_number: Mapped[str] = mapped_column(String(50), unique=True, index=True) + customer_id: Mapped[str] = mapped_column(String(50), index=True) + total_amount: Mapped[Decimal] = mapped_column(Numeric(10, 2)) + status: Mapped[str] = mapped_column(String(20), default="pending") + created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow) + updated_at: Mapped[datetime] = mapped_column( + DateTime, default=datetime.utcnow, onupdate=datetime.utcnow + ) + + # Relationships + payment: Mapped["Payment"] = relationship(back_populates="order", uselist=False) + + +class Payment(Base): + """결제 테이블""" + __tablename__ = "payments" + + id: Mapped[int] = mapped_column(Integer, primary_key=True) + payment_id: Mapped[str] = mapped_column(String(50), unique=True, index=True) + order_id: Mapped[int] = mapped_column(ForeignKey("orders.id"), index=True) + amount: Mapped[Decimal] = mapped_column(Numeric(10, 2)) + currency: Mapped[str] = mapped_column(String(3), default="KRW") + status: Mapped[str] = mapped_column( + String(20), default=PaymentStatus.PENDING.value + ) + gateway_transaction_id: Mapped[str | None] = mapped_column(String(100)) + gateway_response: Mapped[str | None] = mapped_column(Text) + error_message: Mapped[str | None] = mapped_column(Text) + created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow) + updated_at: Mapped[datetime] = mapped_column( + DateTime, default=datetime.utcnow, onupdate=datetime.utcnow + ) + + # Relationships + order: Mapped["Order"] = relationship(back_populates="payment") +``` + +**services/payment_gateway.py - 결제 게이트웨이** +```python +""" +Payment gateway service client. +""" +import httpx +from dataclasses import dataclass +from decimal import Decimal + + +@dataclass +class PaymentResult: + """결제 결과""" + transaction_id: str + status: str + message: str + raw_response: dict + + +class PaymentGatewayService: + """ + 외부 결제 게이트웨이 클라이언트. + + 주의: 결제 API 호출은 반드시 DB 세션 외부에서! + 결제는 3-10초 정도 소요될 수 있습니다. + """ + + def __init__(self, base_url: str, api_key: str): + self.base_url = base_url + self.api_key = api_key + self.timeout = httpx.Timeout(30.0, connect=10.0) + + async def process_payment( + self, + payment_id: str, + amount: Decimal, + currency: str, + card_token: str, + ) -> PaymentResult: + """ + 결제 처리. + + 이 함수는 3-10초가 소요될 수 있습니다. + 반드시 DB 세션 외부에서 호출하세요! + """ + async with httpx.AsyncClient(timeout=self.timeout) as client: + response = await client.post( + f"{self.base_url}/v1/payments", + headers={"Authorization": f"Bearer {self.api_key}"}, + json={ + "merchant_uid": payment_id, + "amount": float(amount), + "currency": currency, + "card_token": card_token, + } + ) + response.raise_for_status() + data = response.json() + + return PaymentResult( + transaction_id=data["transaction_id"], + status=data["status"], + message=data.get("message", ""), + raw_response=data, + ) + + async def verify_payment(self, transaction_id: str) -> PaymentResult: + """결제 검증""" + async with httpx.AsyncClient(timeout=self.timeout) as client: + response = await client.get( + f"{self.base_url}/v1/payments/{transaction_id}", + headers={"Authorization": f"Bearer {self.api_key}"}, + ) + response.raise_for_status() + data = response.json() + + return PaymentResult( + transaction_id=data["transaction_id"], + status=data["status"], + message=data.get("message", ""), + raw_response=data, + ) + + async def refund_payment( + self, + transaction_id: str, + amount: Decimal | None = None + ) -> PaymentResult: + """환불 처리""" + async with httpx.AsyncClient(timeout=self.timeout) as client: + payload = {"transaction_id": transaction_id} + if amount: + payload["amount"] = float(amount) + + response = await client.post( + f"{self.base_url}/v1/refunds", + headers={"Authorization": f"Bearer {self.api_key}"}, + json=payload, + ) + response.raise_for_status() + data = response.json() + + return PaymentResult( + transaction_id=data["refund_id"], + status=data["status"], + message=data.get("message", ""), + raw_response=data, + ) +``` + +**api/routes/payments.py - 결제 API (3-Stage Pattern)** +```python +""" +Payment API routes with proper session management. + +결제 시스템에서의 3-Stage Pattern: +- Stage 1: 주문/결제 레코드 생성 (트랜잭션 보장) +- Stage 2: 외부 결제 게이트웨이 호출 (세션 없음) +- Stage 3: 결과 업데이트 (새 트랜잭션) + +중요: 결제는 멱등성(Idempotency)을 보장해야 합니다! +""" +import json +from decimal import Decimal +from uuid import uuid4 + +from fastapi import APIRouter, Depends, HTTPException, Header +from pydantic import BaseModel +from sqlalchemy import select +from sqlalchemy.ext.asyncio import AsyncSession + +from app.database.session import get_api_session, ApiSessionLocal +from app.database.models import Order, Payment, PaymentStatus +from app.services.payment_gateway import PaymentGatewayService +from app.config import settings + + +router = APIRouter(prefix="/payments", tags=["payments"]) + +# 결제 게이트웨이 서비스 +gateway = PaymentGatewayService( + settings.PAYMENT_GATEWAY_URL, + settings.PAYMENT_GATEWAY_KEY, +) + + +class PaymentRequest(BaseModel): + """결제 요청""" + order_number: str + amount: Decimal + currency: str = "KRW" + card_token: str + + +class PaymentResponse(BaseModel): + """결제 응답""" + payment_id: str + order_number: str + status: str + amount: Decimal + transaction_id: str | None = None + message: str | None = None + + +@router.post("/process", response_model=PaymentResponse) +async def process_payment( + request: PaymentRequest, + idempotency_key: str = Header(..., alias="Idempotency-Key"), + session: AsyncSession = Depends(get_api_session), +) -> PaymentResponse: + """ + 결제 처리 (3-Stage Pattern 적용). + + 멱등성 보장: + - Idempotency-Key 헤더로 중복 결제 방지 + - 동일 키로 재요청 시 기존 결과 반환 + + 3-Stage Pattern: + - Stage 1: 주문 조회 및 결제 레코드 생성 + - Stage 2: 외부 결제 API 호출 (세션 해제) + - Stage 3: 결제 결과 업데이트 + """ + payment_id = f"PAY-{idempotency_key}" + + # ========== 멱등성 체크 ========== + existing = await session.execute( + select(Payment).where(Payment.payment_id == payment_id) + ) + existing_payment = existing.scalar_one_or_none() + + if existing_payment: + # 이미 처리된 결제가 있으면 기존 결과 반환 + return PaymentResponse( + payment_id=existing_payment.payment_id, + order_number=request.order_number, + status=existing_payment.status, + amount=existing_payment.amount, + transaction_id=existing_payment.gateway_transaction_id, + message="이미 처리된 결제입니다", + ) + + # ========== Stage 1: 주문 조회 및 결제 레코드 생성 ========== + print(f"[Stage 1] Creating payment - payment_id: {payment_id}") + + # 주문 조회 + order_result = await session.execute( + select(Order) + .where(Order.order_number == request.order_number) + .limit(1) + ) + order = order_result.scalar_one_or_none() + + if not order: + raise HTTPException(status_code=404, detail="주문을 찾을 수 없습니다") + + if order.total_amount != request.amount: + raise HTTPException(status_code=400, detail="결제 금액이 일치하지 않습니다") + + # 결제 레코드 생성 + payment = Payment( + payment_id=payment_id, + order_id=order.id, + amount=request.amount, + currency=request.currency, + status=PaymentStatus.PROCESSING.value, + ) + session.add(payment) + + # 주문 상태 업데이트 + order.status = "payment_processing" + + await session.commit() + payment_db_id = payment.id + order_id = order.id + print(f"[Stage 1] Payment record created - payment_id: {payment_id}") + + # ========== Stage 2: 외부 결제 API 호출 (세션 없음!) ========== + # 이 구간에서는 DB 커넥션을 점유하지 않습니다 + print(f"[Stage 2] Calling payment gateway - payment_id: {payment_id}") + + try: + gateway_result = await gateway.process_payment( + payment_id=payment_id, + amount=request.amount, + currency=request.currency, + card_token=request.card_token, + ) + print(f"[Stage 2] Gateway response - status: {gateway_result.status}") + + except Exception as e: + # 게이트웨이 오류 시 실패 처리 + print(f"[Stage 2] Gateway error - {e}") + + async with ApiSessionLocal() as error_session: + # 결제 실패 처리 + stmt = select(Payment).where(Payment.id == payment_db_id) + db_payment = (await error_session.execute(stmt)).scalar_one() + db_payment.status = PaymentStatus.FAILED.value + db_payment.error_message = str(e) + + # 주문 상태 복원 + order_stmt = select(Order).where(Order.id == order_id) + db_order = (await error_session.execute(order_stmt)).scalar_one() + db_order.status = "payment_failed" + + await error_session.commit() + + raise HTTPException( + status_code=500, + detail=f"결제 처리 중 오류가 발생했습니다: {str(e)}" + ) + + # ========== Stage 3: 결제 결과 업데이트 (새 세션) ========== + print(f"[Stage 3] Updating payment result - payment_id: {payment_id}") + + async with ApiSessionLocal() as update_session: + # 결제 정보 업데이트 + stmt = select(Payment).where(Payment.id == payment_db_id) + db_payment = (await update_session.execute(stmt)).scalar_one() + + if gateway_result.status == "success": + db_payment.status = PaymentStatus.COMPLETED.value + new_order_status = "paid" + else: + db_payment.status = PaymentStatus.FAILED.value + new_order_status = "payment_failed" + + db_payment.gateway_transaction_id = gateway_result.transaction_id + db_payment.gateway_response = json.dumps(gateway_result.raw_response) + + # 주문 상태 업데이트 + order_stmt = select(Order).where(Order.id == order_id) + db_order = (await update_session.execute(order_stmt)).scalar_one() + db_order.status = new_order_status + + await update_session.commit() + print(f"[Stage 3] Payment completed - status: {db_payment.status}") + + return PaymentResponse( + payment_id=db_payment.payment_id, + order_number=request.order_number, + status=db_payment.status, + amount=db_payment.amount, + transaction_id=db_payment.gateway_transaction_id, + message=gateway_result.message, + ) + + +@router.get("/{payment_id}", response_model=PaymentResponse) +async def get_payment_status( + payment_id: str, + session: AsyncSession = Depends(get_api_session), +) -> PaymentResponse: + """결제 상태 조회""" + # 안전한 쿼리 패턴 + stmt = ( + select(Payment) + .where(Payment.payment_id == payment_id) + .limit(1) + ) + result = await session.execute(stmt) + payment = result.scalar_one_or_none() + + if not payment: + raise HTTPException(status_code=404, detail="결제 정보를 찾을 수 없습니다") + + # 주문 정보 조회 + order_stmt = select(Order).where(Order.id == payment.order_id) + order = (await session.execute(order_stmt)).scalar_one() + + return PaymentResponse( + payment_id=payment.payment_id, + order_number=order.order_number, + status=payment.status, + amount=payment.amount, + transaction_id=payment.gateway_transaction_id, + ) + + +@router.post("/{payment_id}/refund") +async def refund_payment( + payment_id: str, + session: AsyncSession = Depends(get_api_session), +) -> PaymentResponse: + """ + 환불 처리 (3-Stage Pattern). + """ + # Stage 1: 결제 정보 조회 + stmt = select(Payment).where(Payment.payment_id == payment_id).limit(1) + result = await session.execute(stmt) + payment = result.scalar_one_or_none() + + if not payment: + raise HTTPException(status_code=404, detail="결제 정보를 찾을 수 없습니다") + + if payment.status != PaymentStatus.COMPLETED.value: + raise HTTPException(status_code=400, detail="환불 가능한 상태가 아닙니다") + + if not payment.gateway_transaction_id: + raise HTTPException(status_code=400, detail="거래 ID가 없습니다") + + transaction_id = payment.gateway_transaction_id + payment_db_id = payment.id + order_id = payment.order_id + amount = payment.amount + + # 상태를 processing으로 변경 + payment.status = "refund_processing" + await session.commit() + + # Stage 2: 환불 API 호출 (세션 없음) + try: + refund_result = await gateway.refund_payment(transaction_id, amount) + except Exception as e: + # 실패 시 상태 복원 + async with ApiSessionLocal() as error_session: + stmt = select(Payment).where(Payment.id == payment_db_id) + db_payment = (await error_session.execute(stmt)).scalar_one() + db_payment.status = PaymentStatus.COMPLETED.value # 원래 상태로 + await error_session.commit() + + raise HTTPException(status_code=500, detail=str(e)) + + # Stage 3: 결과 저장 + async with ApiSessionLocal() as update_session: + stmt = select(Payment).where(Payment.id == payment_db_id) + db_payment = (await update_session.execute(stmt)).scalar_one() + + if refund_result.status == "success": + db_payment.status = PaymentStatus.REFUNDED.value + + # 주문 상태도 업데이트 + order_stmt = select(Order).where(Order.id == order_id) + db_order = (await update_session.execute(order_stmt)).scalar_one() + db_order.status = "refunded" + else: + db_payment.status = PaymentStatus.COMPLETED.value # 환불 실패 시 원래 상태 + + await update_session.commit() + + return PaymentResponse( + payment_id=db_payment.payment_id, + order_number="", # 간단히 처리 + status=db_payment.status, + amount=db_payment.amount, + transaction_id=refund_result.transaction_id, + message=refund_result.message, + ) +``` + +**main.py - 애플리케이션** +```python +""" +Payment service main application. +""" +from contextlib import asynccontextmanager + +from fastapi import FastAPI + +from app.database.session import dispose_engines +from app.api.routes import payments + + +@asynccontextmanager +async def lifespan(app: FastAPI): + """생명주기 관리""" + print("[Payment Service] Starting...") + yield + print("[Payment Service] Shutting down...") + await dispose_engines() + + +app = FastAPI( + title="Payment Service", + description="결제 처리 서비스", + version="1.0.0", + lifespan=lifespan, +) + +app.include_router(payments.router, prefix="/api/v1") + + +@app.get("/health") +async def health(): + return {"status": "healthy", "service": "payment"} +``` + +--- + +## 7. 설계 원칙 요약 + +### 7.1 핵심 설계 원칙 + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ 커넥션 풀 설계 원칙 │ +├─────────────────────────────────────────────────────────────────┤ +│ │ +│ 1. 최소 점유 원칙 (Minimal Hold Principle) │ +│ ───────────────────────────────────────── │ +│ "DB 커넥션은 DB 작업에만 사용하고 즉시 반환" │ +│ │ +│ ✗ session.query() → external_api() → session.commit() │ +│ ✓ session.query() → commit() → external_api() → new_session │ +│ │ +│ 2. 워크로드 분리 원칙 (Workload Isolation) │ +│ ───────────────────────────────────────── │ +│ "다른 특성의 워크로드는 다른 풀을 사용" │ +│ │ +│ API 요청 → ApiPool (빠른 응답, 짧은 타임아웃) │ +│ 백그라운드 → BackgroundPool (안정성, 긴 타임아웃) │ +│ │ +│ 3. 안전한 쿼리 원칙 (Safe Query Pattern) │ +│ ───────────────────────────────────── │ +│ "중복 가능성이 있는 조회는 항상 limit(1) 사용" │ +│ │ +│ select(Model).where(...).order_by(desc).limit(1) │ +│ │ +│ 4. 3-Stage 처리 원칙 (3-Stage Processing) │ +│ ───────────────────────────────────── │ +│ Stage 1: DB 작업 + 커밋 (세션 해제) │ +│ Stage 2: 외부 API 호출 (세션 없음) │ +│ Stage 3: 결과 저장 (새 세션) │ +│ │ +│ 5. 명시적 범위 원칙 (Explicit Scope) │ +│ ───────────────────────────────────── │ +│ "세션 범위를 async with로 명확히 정의" │ +│ │ +│ async with SessionLocal() as session: │ +│ # 이 블록 내에서만 세션 사용 │ +│ │ +└─────────────────────────────────────────────────────────────────┘ +``` + +### 7.2 체크리스트 + +새로운 API 엔드포인트를 작성할 때 확인해야 할 사항: + +``` +□ 외부 API 호출이 있는가? + → 있다면 3-Stage Pattern 적용 + +□ 백그라운드 작업이 있는가? + → 있다면 BackgroundSessionLocal 사용 + +□ 중복 데이터가 발생할 수 있는 쿼리가 있는가? + → 있다면 order_by().limit(1) 적용 + +□ 세션이 예외 상황에서도 반환되는가? + → async with 또는 try/finally 사용 + +□ 트랜잭션 범위가 적절한가? + → 필요한 작업만 포함, 외부 호출 제외 +``` + +### 7.3 Anti-Pattern 회피 + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ 피해야 할 패턴 │ +├─────────────────────────────────────────────────────────────────┤ +│ │ +│ Anti-Pattern 1: Long-lived Session │ +│ ─────────────────────────────────── │ +│ ✗ async def handler(session): │ +│ data = await session.query() │ +│ result = await http_client.post() # 30초 소요 │ +│ session.add(result) │ +│ await session.commit() │ +│ │ +│ Anti-Pattern 2: Shared Pool for All │ +│ ─────────────────────────────────── │ +│ ✗ 모든 작업이 단일 풀 사용 │ +│ → 백그라운드 작업이 API 응답을 블록킹 │ +│ │ +│ Anti-Pattern 3: Unsafe Query │ +│ ─────────────────────────────── │ +│ ✗ scalar_one_or_none() without limit(1) │ +│ → 중복 데이터 시 예외 발생 │ +│ │ +│ Anti-Pattern 4: Missing Error Handling │ +│ ─────────────────────────────────────── │ +│ ✗ session = SessionLocal() │ +│ await session.query() # 예외 발생 시 세션 누수 │ +│ │ +└─────────────────────────────────────────────────────────────────┘ +``` + +--- + +## 결론 + +이 문서에서 다룬 문제들은 대부분 **"외부 리소스 접근 중 DB 세션 점유"**라는 공통된 원인에서 발생했습니다. + +해결의 핵심은: + +1. **책임 분리**: DB 작업과 외부 API 호출을 명확히 분리 +2. **리소스 격리**: 워크로드별 별도 커넥션 풀 사용 +3. **방어적 프로그래밍**: 중복 데이터, 예외 상황 대비 + +이러한 원칙을 코드 리뷰 시 체크리스트로 활용하면, 프로덕션 환경에서의 커넥션 풀 관련 장애를 예방할 수 있습니다. diff --git a/docs/analysis/refactoring.md b/docs/analysis/refactoring.md index c4fca5a..bb88a4d 100644 --- a/docs/analysis/refactoring.md +++ b/docs/analysis/refactoring.md @@ -1,1488 +1,1488 @@ -# 디자인 패턴 기반 리팩토링 제안서 - -## 목차 - -1. [현재 아키텍처 분석](#1-현재-아키텍처-분석) -2. [제안하는 디자인 패턴](#2-제안하는-디자인-패턴) -3. [상세 리팩토링 방안](#3-상세-리팩토링-방안) -4. [모듈별 구현 예시](#4-모듈별-구현-예시) -5. [기대 효과](#5-기대-효과) -6. [마이그레이션 전략](#6-마이그레이션-전략) - ---- - -## 1. 현재 아키텍처 분석 - -### 1.1 현재 구조 - -``` -app/ -├── {module}/ -│ ├── models.py # SQLAlchemy 모델 -│ ├── schemas/ # Pydantic 스키마 -│ ├── services/ # 비즈니스 로직 (일부만 사용) -│ ├── api/routers/v1/ # FastAPI 라우터 -│ └── worker/ # 백그라운드 태스크 -└── utils/ # 외부 API 클라이언트 (Suno, Creatomate, ChatGPT) -``` - -### 1.2 현재 문제점 - -| 문제 | 설명 | 영향 | -|------|------|------| -| **Fat Controller** | 라우터에 비즈니스 로직이 직접 포함됨 | 테스트 어려움, 재사용 불가 | -| **서비스 레이어 미활용** | services/ 폴더가 있지만 대부분 사용되지 않음 | 코드 중복, 일관성 부족 | -| **외부 API 결합** | 라우터에서 직접 외부 API 호출 | 모킹 어려움, 의존성 강결합 | -| **Repository 부재** | 데이터 접근 로직이 분산됨 | 쿼리 중복, 최적화 어려움 | -| **트랜잭션 관리 분산** | 각 함수에서 개별적으로 세션 관리 | 일관성 부족 | -| **에러 처리 비일관** | HTTPException이 여러 계층에서 발생 | 디버깅 어려움 | - -### 1.3 현재 코드 예시 (문제점) - -```python -# app/lyric/api/routers/v1/lyric.py - 현재 구조 -@router.post("/generate") -async def generate_lyric( - request_body: GenerateLyricRequest, - background_tasks: BackgroundTasks, - session: AsyncSession = Depends(get_session), -) -> GenerateLyricResponse: - task_id = request_body.task_id - - try: - # 문제 1: 라우터에서 직접 비즈니스 로직 수행 - service = ChatgptService( - customer_name=request_body.customer_name, - region=request_body.region, - ... - ) - prompt = service.build_lyrics_prompt() - - # 문제 2: 라우터에서 직접 DB 조작 - project = Project( - store_name=request_body.customer_name, - ... - ) - session.add(project) - await session.commit() - - # 문제 3: 라우터에서 직접 모델 생성 - lyric = Lyric( - project_id=project.id, - ... - ) - session.add(lyric) - await session.commit() - - # 문제 4: 에러 처리가 각 함수마다 다름 - background_tasks.add_task(generate_lyric_background, ...) - - return GenerateLyricResponse(...) - except Exception as e: - await session.rollback() - return GenerateLyricResponse(success=False, ...) -``` - ---- - -## 2. 제안하는 디자인 패턴 - -### 2.1 Clean Architecture + 레이어드 아키텍처 - -``` -┌─────────────────────────────────────────────────────────────────┐ -│ Presentation Layer │ -│ (FastAPI Routers - HTTP 요청/응답만 처리) │ -└─────────────────────────────────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────────┐ -│ Application Layer │ -│ (Use Cases / Services - 비즈니스 로직 오케스트레이션) │ -└─────────────────────────────────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────────┐ -│ Domain Layer │ -│ (Entities, Value Objects, Domain Services) │ -└─────────────────────────────────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────────┐ -│ Infrastructure Layer │ -│ (Repositories, External APIs, Database) │ -└─────────────────────────────────────────────────────────────────┘ -``` - -### 2.2 적용할 디자인 패턴 - -| 패턴 | 적용 대상 | 목적 | -|------|----------|------| -| **Repository Pattern** | 데이터 접근 | DB 로직 캡슐화, 테스트 용이 | -| **Service Pattern** | 비즈니스 로직 | 유스케이스 구현, 트랜잭션 관리 | -| **Factory Pattern** | 객체 생성 | 복잡한 객체 생성 캡슐화 | -| **Strategy Pattern** | 외부 API | API 클라이언트 교체 용이 | -| **Unit of Work** | 트랜잭션 | 일관된 트랜잭션 관리 | -| **Dependency Injection** | 전체 | 느슨한 결합, 테스트 용이 | -| **DTO Pattern** | 계층 간 전달 | 명확한 데이터 경계 | - ---- - -## 3. 상세 리팩토링 방안 - -### 3.1 새로운 폴더 구조 - -``` -app/ -├── core/ -│ ├── __init__.py -│ ├── config.py # 설정 관리 (기존 config.py 이동) -│ ├── exceptions.py # 도메인 예외 정의 -│ ├── interfaces/ # 추상 인터페이스 -│ │ ├── __init__.py -│ │ ├── repository.py # IRepository 인터페이스 -│ │ ├── service.py # IService 인터페이스 -│ │ └── external_api.py # IExternalAPI 인터페이스 -│ └── uow.py # Unit of Work -│ -├── domain/ -│ ├── __init__.py -│ ├── entities/ # 도메인 엔티티 -│ │ ├── __init__.py -│ │ ├── project.py -│ │ ├── lyric.py -│ │ ├── song.py -│ │ └── video.py -│ ├── value_objects/ # 값 객체 -│ │ ├── __init__.py -│ │ ├── task_id.py -│ │ └── status.py -│ └── events/ # 도메인 이벤트 -│ ├── __init__.py -│ └── lyric_events.py -│ -├── infrastructure/ -│ ├── __init__.py -│ ├── database/ -│ │ ├── __init__.py -│ │ ├── session.py # DB 세션 관리 -│ │ ├── models/ # SQLAlchemy 모델 -│ │ │ ├── __init__.py -│ │ │ ├── project_model.py -│ │ │ ├── lyric_model.py -│ │ │ ├── song_model.py -│ │ │ └── video_model.py -│ │ └── repositories/ # Repository 구현 -│ │ ├── __init__.py -│ │ ├── base.py -│ │ ├── project_repository.py -│ │ ├── lyric_repository.py -│ │ ├── song_repository.py -│ │ └── video_repository.py -│ ├── external/ # 외부 API 클라이언트 -│ │ ├── __init__.py -│ │ ├── chatgpt/ -│ │ │ ├── __init__.py -│ │ │ ├── client.py -│ │ │ └── prompts.py -│ │ ├── suno/ -│ │ │ ├── __init__.py -│ │ │ └── client.py -│ │ ├── creatomate/ -│ │ │ ├── __init__.py -│ │ │ └── client.py -│ │ └── azure_blob/ -│ │ ├── __init__.py -│ │ └── client.py -│ └── cache/ -│ ├── __init__.py -│ └── redis.py -│ -├── application/ -│ ├── __init__.py -│ ├── services/ # 애플리케이션 서비스 -│ │ ├── __init__.py -│ │ ├── lyric_service.py -│ │ ├── song_service.py -│ │ └── video_service.py -│ ├── dto/ # Data Transfer Objects -│ │ ├── __init__.py -│ │ ├── lyric_dto.py -│ │ ├── song_dto.py -│ │ └── video_dto.py -│ └── tasks/ # 백그라운드 태스크 -│ ├── __init__.py -│ ├── lyric_tasks.py -│ ├── song_tasks.py -│ └── video_tasks.py -│ -├── presentation/ -│ ├── __init__.py -│ ├── api/ -│ │ ├── __init__.py -│ │ ├── v1/ -│ │ │ ├── __init__.py -│ │ │ ├── lyric_router.py -│ │ │ ├── song_router.py -│ │ │ └── video_router.py -│ │ └── dependencies.py # FastAPI 의존성 -│ ├── schemas/ # API 스키마 (요청/응답) -│ │ ├── __init__.py -│ │ ├── lyric_schema.py -│ │ ├── song_schema.py -│ │ └── video_schema.py -│ └── middleware/ -│ ├── __init__.py -│ └── error_handler.py -│ -└── main.py -``` - -### 3.2 Repository Pattern 구현 - -#### 3.2.1 추상 인터페이스 - -```python -# app/core/interfaces/repository.py -from abc import ABC, abstractmethod -from typing import Generic, TypeVar, Optional, List - -T = TypeVar("T") - -class IRepository(ABC, Generic[T]): - """Repository 인터페이스 - 데이터 접근 추상화""" - - @abstractmethod - async def get_by_id(self, id: int) -> Optional[T]: - """ID로 엔티티 조회""" - pass - - @abstractmethod - async def get_by_task_id(self, task_id: str) -> Optional[T]: - """task_id로 엔티티 조회""" - pass - - @abstractmethod - async def get_all( - self, - skip: int = 0, - limit: int = 100, - filters: dict = None - ) -> List[T]: - """전체 엔티티 조회 (페이지네이션)""" - pass - - @abstractmethod - async def create(self, entity: T) -> T: - """엔티티 생성""" - pass - - @abstractmethod - async def update(self, entity: T) -> T: - """엔티티 수정""" - pass - - @abstractmethod - async def delete(self, id: int) -> bool: - """엔티티 삭제""" - pass - - @abstractmethod - async def count(self, filters: dict = None) -> int: - """엔티티 개수 조회""" - pass -``` - -#### 3.2.2 Base Repository 구현 - -```python -# app/infrastructure/database/repositories/base.py -from typing import Generic, TypeVar, Optional, List, Type -from sqlalchemy import select, func, and_ -from sqlalchemy.ext.asyncio import AsyncSession - -from app.core.interfaces.repository import IRepository -from app.infrastructure.database.session import Base - -T = TypeVar("T", bound=Base) - -class BaseRepository(IRepository[T], Generic[T]): - """Repository 기본 구현""" - - def __init__(self, session: AsyncSession, model: Type[T]): - self._session = session - self._model = model - - async def get_by_id(self, id: int) -> Optional[T]: - result = await self._session.execute( - select(self._model).where(self._model.id == id) - ) - return result.scalar_one_or_none() - - async def get_by_task_id(self, task_id: str) -> Optional[T]: - result = await self._session.execute( - select(self._model) - .where(self._model.task_id == task_id) - .order_by(self._model.created_at.desc()) - .limit(1) - ) - return result.scalar_one_or_none() - - async def get_all( - self, - skip: int = 0, - limit: int = 100, - filters: dict = None - ) -> List[T]: - query = select(self._model) - - if filters: - conditions = [ - getattr(self._model, key) == value - for key, value in filters.items() - if hasattr(self._model, key) - ] - if conditions: - query = query.where(and_(*conditions)) - - query = query.offset(skip).limit(limit).order_by( - self._model.created_at.desc() - ) - result = await self._session.execute(query) - return list(result.scalars().all()) - - async def create(self, entity: T) -> T: - self._session.add(entity) - await self._session.flush() - await self._session.refresh(entity) - return entity - - async def update(self, entity: T) -> T: - await self._session.flush() - await self._session.refresh(entity) - return entity - - async def delete(self, id: int) -> bool: - entity = await self.get_by_id(id) - if entity: - await self._session.delete(entity) - return True - return False - - async def count(self, filters: dict = None) -> int: - query = select(func.count(self._model.id)) - - if filters: - conditions = [ - getattr(self._model, key) == value - for key, value in filters.items() - if hasattr(self._model, key) - ] - if conditions: - query = query.where(and_(*conditions)) - - result = await self._session.execute(query) - return result.scalar() or 0 -``` - -#### 3.2.3 특화된 Repository - -```python -# app/infrastructure/database/repositories/lyric_repository.py -from typing import Optional, List -from sqlalchemy import select - -from app.infrastructure.database.repositories.base import BaseRepository -from app.infrastructure.database.models.lyric_model import LyricModel - -class LyricRepository(BaseRepository[LyricModel]): - """Lyric 전용 Repository""" - - def __init__(self, session): - super().__init__(session, LyricModel) - - async def get_by_project_id(self, project_id: int) -> List[LyricModel]: - """프로젝트 ID로 가사 목록 조회""" - result = await self._session.execute( - select(self._model) - .where(self._model.project_id == project_id) - .order_by(self._model.created_at.desc()) - ) - return list(result.scalars().all()) - - async def get_completed_lyrics( - self, - skip: int = 0, - limit: int = 100 - ) -> List[LyricModel]: - """완료된 가사만 조회""" - return await self.get_all( - skip=skip, - limit=limit, - filters={"status": "completed"} - ) - - async def update_status( - self, - task_id: str, - status: str, - result: Optional[str] = None - ) -> Optional[LyricModel]: - """가사 상태 업데이트""" - lyric = await self.get_by_task_id(task_id) - if lyric: - lyric.status = status - if result is not None: - lyric.lyric_result = result - return await self.update(lyric) - return None -``` - -### 3.3 Unit of Work Pattern - -```python -# app/core/uow.py -from abc import ABC, abstractmethod -from typing import TYPE_CHECKING - -if TYPE_CHECKING: - from app.infrastructure.database.repositories.project_repository import ProjectRepository - from app.infrastructure.database.repositories.lyric_repository import LyricRepository - from app.infrastructure.database.repositories.song_repository import SongRepository - from app.infrastructure.database.repositories.video_repository import VideoRepository - -class IUnitOfWork(ABC): - """Unit of Work 인터페이스""" - - projects: "ProjectRepository" - lyrics: "LyricRepository" - songs: "SongRepository" - videos: "VideoRepository" - - @abstractmethod - async def __aenter__(self): - pass - - @abstractmethod - async def __aexit__(self, exc_type, exc_val, exc_tb): - pass - - @abstractmethod - async def commit(self): - pass - - @abstractmethod - async def rollback(self): - pass - - -# app/infrastructure/database/uow.py -from sqlalchemy.ext.asyncio import AsyncSession - -from app.core.uow import IUnitOfWork -from app.infrastructure.database.session import AsyncSessionLocal -from app.infrastructure.database.repositories.project_repository import ProjectRepository -from app.infrastructure.database.repositories.lyric_repository import LyricRepository -from app.infrastructure.database.repositories.song_repository import SongRepository -from app.infrastructure.database.repositories.video_repository import VideoRepository - -class UnitOfWork(IUnitOfWork): - """Unit of Work 구현 - 트랜잭션 관리""" - - def __init__(self, session_factory=AsyncSessionLocal): - self._session_factory = session_factory - self._session: AsyncSession = None - - async def __aenter__(self): - self._session = self._session_factory() - - # Repository 인스턴스 생성 - self.projects = ProjectRepository(self._session) - self.lyrics = LyricRepository(self._session) - self.songs = SongRepository(self._session) - self.videos = VideoRepository(self._session) - - return self - - async def __aexit__(self, exc_type, exc_val, exc_tb): - if exc_type is not None: - await self.rollback() - await self._session.close() - - async def commit(self): - await self._session.commit() - - async def rollback(self): - await self._session.rollback() -``` - -### 3.4 Service Layer 구현 - -```python -# app/application/services/lyric_service.py -from typing import Optional -from dataclasses import dataclass - -from app.core.uow import IUnitOfWork -from app.core.exceptions import ( - EntityNotFoundError, - ExternalAPIError, - ValidationError -) -from app.application.dto.lyric_dto import ( - CreateLyricDTO, - LyricResponseDTO, - LyricStatusDTO -) -from app.infrastructure.external.chatgpt.client import IChatGPTClient -from app.infrastructure.database.models.lyric_model import LyricModel -from app.infrastructure.database.models.project_model import ProjectModel - -@dataclass -class LyricService: - """Lyric 비즈니스 로직 서비스""" - - uow: IUnitOfWork - chatgpt_client: IChatGPTClient - - async def create_lyric(self, dto: CreateLyricDTO) -> LyricResponseDTO: - """가사 생성 요청 처리 - - 1. 프롬프트 생성 - 2. Project 저장 - 3. Lyric 저장 (processing) - 4. task_id 반환 (백그라운드 처리는 별도) - """ - async with self.uow: - # 프롬프트 생성 - prompt = self.chatgpt_client.build_lyrics_prompt( - customer_name=dto.customer_name, - region=dto.region, - detail_region_info=dto.detail_region_info, - language=dto.language - ) - - # Project 생성 - project = ProjectModel( - store_name=dto.customer_name, - region=dto.region, - task_id=dto.task_id, - detail_region_info=dto.detail_region_info, - language=dto.language - ) - project = await self.uow.projects.create(project) - - # Lyric 생성 (processing 상태) - lyric = LyricModel( - project_id=project.id, - task_id=dto.task_id, - status="processing", - lyric_prompt=prompt, - language=dto.language - ) - lyric = await self.uow.lyrics.create(lyric) - - await self.uow.commit() - - return LyricResponseDTO( - success=True, - task_id=dto.task_id, - lyric=None, # 백그라운드에서 생성 - language=dto.language, - prompt=prompt # 백그라운드 태스크에 전달 - ) - - async def process_lyric_generation( - self, - task_id: str, - prompt: str, - language: str - ) -> None: - """백그라운드에서 가사 실제 생성 - - 이 메서드는 백그라운드 태스크에서 호출됨 - """ - try: - # ChatGPT로 가사 생성 - result = await self.chatgpt_client.generate(prompt) - - # 실패 패턴 검사 - is_failure = self._check_failure_patterns(result) - - async with self.uow: - status = "failed" if is_failure else "completed" - await self.uow.lyrics.update_status( - task_id=task_id, - status=status, - result=result - ) - await self.uow.commit() - - except Exception as e: - async with self.uow: - await self.uow.lyrics.update_status( - task_id=task_id, - status="failed", - result=f"Error: {str(e)}" - ) - await self.uow.commit() - raise - - async def get_lyric_status(self, task_id: str) -> LyricStatusDTO: - """가사 생성 상태 조회""" - async with self.uow: - lyric = await self.uow.lyrics.get_by_task_id(task_id) - - if not lyric: - raise EntityNotFoundError( - f"task_id '{task_id}'에 해당하는 가사를 찾을 수 없습니다." - ) - - status_messages = { - "processing": "가사 생성 중입니다.", - "completed": "가사 생성이 완료되었습니다.", - "failed": "가사 생성에 실패했습니다.", - } - - return LyricStatusDTO( - task_id=lyric.task_id, - status=lyric.status, - message=status_messages.get(lyric.status, "알 수 없는 상태입니다.") - ) - - async def get_lyric_detail(self, task_id: str) -> LyricResponseDTO: - """가사 상세 조회""" - async with self.uow: - lyric = await self.uow.lyrics.get_by_task_id(task_id) - - if not lyric: - raise EntityNotFoundError( - f"task_id '{task_id}'에 해당하는 가사를 찾을 수 없습니다." - ) - - return LyricResponseDTO( - id=lyric.id, - task_id=lyric.task_id, - project_id=lyric.project_id, - status=lyric.status, - lyric_prompt=lyric.lyric_prompt, - lyric_result=lyric.lyric_result, - language=lyric.language, - created_at=lyric.created_at - ) - - def _check_failure_patterns(self, result: str) -> bool: - """ChatGPT 응답에서 실패 패턴 검사""" - failure_patterns = [ - "ERROR:", - "I'm sorry", - "I cannot", - "I can't", - "I apologize", - "I'm unable", - "I am unable", - "I'm not able", - "I am not able", - ] - return any( - pattern.lower() in result.lower() - for pattern in failure_patterns - ) -``` - -### 3.5 DTO (Data Transfer Objects) - -```python -# app/application/dto/lyric_dto.py -from dataclasses import dataclass -from datetime import datetime -from typing import Optional - -@dataclass -class CreateLyricDTO: - """가사 생성 요청 DTO""" - task_id: str - customer_name: str - region: str - detail_region_info: Optional[str] = None - language: str = "Korean" - -@dataclass -class LyricResponseDTO: - """가사 응답 DTO""" - success: bool = True - task_id: Optional[str] = None - lyric: Optional[str] = None - language: str = "Korean" - error_message: Optional[str] = None - - # 상세 조회 시 추가 필드 - id: Optional[int] = None - project_id: Optional[int] = None - status: Optional[str] = None - lyric_prompt: Optional[str] = None - lyric_result: Optional[str] = None - created_at: Optional[datetime] = None - prompt: Optional[str] = None # 백그라운드 태스크용 - -@dataclass -class LyricStatusDTO: - """가사 상태 조회 DTO""" - task_id: str - status: str - message: str -``` - -### 3.6 Strategy Pattern for External APIs - -```python -# app/core/interfaces/external_api.py -from abc import ABC, abstractmethod -from typing import Optional - -class ILLMClient(ABC): - """LLM 클라이언트 인터페이스""" - - @abstractmethod - def build_lyrics_prompt( - self, - customer_name: str, - region: str, - detail_region_info: str, - language: str - ) -> str: - pass - - @abstractmethod - async def generate(self, prompt: str) -> str: - pass - - -class IMusicGeneratorClient(ABC): - """음악 생성 클라이언트 인터페이스""" - - @abstractmethod - async def generate( - self, - prompt: str, - genre: str, - callback_url: Optional[str] = None - ) -> str: - """음악 생성 요청, task_id 반환""" - pass - - @abstractmethod - async def get_status(self, task_id: str) -> dict: - pass - - -class IVideoGeneratorClient(ABC): - """영상 생성 클라이언트 인터페이스""" - - @abstractmethod - async def get_template(self, template_id: str) -> dict: - pass - - @abstractmethod - async def render(self, source: dict) -> dict: - pass - - @abstractmethod - async def get_render_status(self, render_id: str) -> dict: - pass - - -# app/infrastructure/external/chatgpt/client.py -from openai import AsyncOpenAI - -from app.core.interfaces.external_api import ILLMClient -from app.infrastructure.external.chatgpt.prompts import LYRICS_PROMPT_TEMPLATE - -class ChatGPTClient(ILLMClient): - """ChatGPT 클라이언트 구현""" - - def __init__(self, api_key: str, model: str = "gpt-4o"): - self._client = AsyncOpenAI(api_key=api_key) - self._model = model - - def build_lyrics_prompt( - self, - customer_name: str, - region: str, - detail_region_info: str, - language: str - ) -> str: - return LYRICS_PROMPT_TEMPLATE.format( - customer_name=customer_name, - region=region, - detail_region_info=detail_region_info, - language=language - ) - - async def generate(self, prompt: str) -> str: - completion = await self._client.chat.completions.create( - model=self._model, - messages=[{"role": "user", "content": prompt}] - ) - return completion.choices[0].message.content or "" -``` - -### 3.7 Presentation Layer (Thin Router) - -```python -# app/presentation/api/v1/lyric_router.py -from fastapi import APIRouter, BackgroundTasks, Depends, HTTPException, status - -from app.presentation.schemas.lyric_schema import ( - GenerateLyricRequest, - GenerateLyricResponse, - LyricStatusResponse, - LyricDetailResponse -) -from app.application.services.lyric_service import LyricService -from app.application.dto.lyric_dto import CreateLyricDTO -from app.core.exceptions import EntityNotFoundError -from app.presentation.api.dependencies import get_lyric_service - -router = APIRouter(prefix="/lyric", tags=["lyric"]) - -@router.post( - "/generate", - response_model=GenerateLyricResponse, - summary="가사 생성", - description="고객 정보를 기반으로 ChatGPT를 이용하여 가사를 생성합니다." -) -async def generate_lyric( - request: GenerateLyricRequest, - background_tasks: BackgroundTasks, - service: LyricService = Depends(get_lyric_service) -) -> GenerateLyricResponse: - """ - 라우터는 HTTP 요청/응답만 처리 - 비즈니스 로직은 서비스에 위임 - """ - # DTO로 변환 - dto = CreateLyricDTO( - task_id=request.task_id, - customer_name=request.customer_name, - region=request.region, - detail_region_info=request.detail_region_info, - language=request.language - ) - - # 서비스 호출 - result = await service.create_lyric(dto) - - # 백그라운드 태스크 등록 - background_tasks.add_task( - service.process_lyric_generation, - task_id=result.task_id, - prompt=result.prompt, - language=result.language - ) - - # 응답 반환 - return GenerateLyricResponse( - success=result.success, - task_id=result.task_id, - lyric=result.lyric, - language=result.language, - error_message=result.error_message - ) - -@router.get( - "/status/{task_id}", - response_model=LyricStatusResponse, - summary="가사 생성 상태 조회" -) -async def get_lyric_status( - task_id: str, - service: LyricService = Depends(get_lyric_service) -) -> LyricStatusResponse: - try: - result = await service.get_lyric_status(task_id) - return LyricStatusResponse( - task_id=result.task_id, - status=result.status, - message=result.message - ) - except EntityNotFoundError as e: - raise HTTPException( - status_code=status.HTTP_404_NOT_FOUND, - detail=str(e) - ) - -@router.get( - "/{task_id}", - response_model=LyricDetailResponse, - summary="가사 상세 조회" -) -async def get_lyric_detail( - task_id: str, - service: LyricService = Depends(get_lyric_service) -) -> LyricDetailResponse: - try: - result = await service.get_lyric_detail(task_id) - return LyricDetailResponse.model_validate(result.__dict__) - except EntityNotFoundError as e: - raise HTTPException( - status_code=status.HTTP_404_NOT_FOUND, - detail=str(e) - ) -``` - -### 3.8 Dependency Injection 설정 - -```python -# app/presentation/api/dependencies.py -from functools import lru_cache -from fastapi import Depends - -from app.core.config import get_settings, Settings -from app.infrastructure.database.uow import UnitOfWork -from app.infrastructure.external.chatgpt.client import ChatGPTClient -from app.infrastructure.external.suno.client import SunoClient -from app.infrastructure.external.creatomate.client import CreatomateClient -from app.application.services.lyric_service import LyricService -from app.application.services.song_service import SongService -from app.application.services.video_service import VideoService - -@lru_cache() -def get_settings() -> Settings: - return Settings() - -def get_chatgpt_client( - settings: Settings = Depends(get_settings) -) -> ChatGPTClient: - return ChatGPTClient( - api_key=settings.CHATGPT_API_KEY, - model="gpt-4o" - ) - -def get_suno_client( - settings: Settings = Depends(get_settings) -) -> SunoClient: - return SunoClient( - api_key=settings.SUNO_API_KEY, - callback_url=settings.SUNO_CALLBACK_URL - ) - -def get_creatomate_client( - settings: Settings = Depends(get_settings) -) -> CreatomateClient: - return CreatomateClient( - api_key=settings.CREATOMATE_API_KEY - ) - -def get_unit_of_work() -> UnitOfWork: - return UnitOfWork() - -def get_lyric_service( - uow: UnitOfWork = Depends(get_unit_of_work), - chatgpt: ChatGPTClient = Depends(get_chatgpt_client) -) -> LyricService: - return LyricService(uow=uow, chatgpt_client=chatgpt) - -def get_song_service( - uow: UnitOfWork = Depends(get_unit_of_work), - suno: SunoClient = Depends(get_suno_client) -) -> SongService: - return SongService(uow=uow, suno_client=suno) - -def get_video_service( - uow: UnitOfWork = Depends(get_unit_of_work), - creatomate: CreatomateClient = Depends(get_creatomate_client) -) -> VideoService: - return VideoService(uow=uow, creatomate_client=creatomate) -``` - -### 3.9 도메인 예외 정의 - -```python -# app/core/exceptions.py - -class DomainException(Exception): - """도메인 예외 기본 클래스""" - - def __init__(self, message: str, code: str = None): - self.message = message - self.code = code - super().__init__(message) - -class EntityNotFoundError(DomainException): - """엔티티를 찾을 수 없음""" - - def __init__(self, message: str): - super().__init__(message, code="ENTITY_NOT_FOUND") - -class ValidationError(DomainException): - """유효성 검증 실패""" - - def __init__(self, message: str): - super().__init__(message, code="VALIDATION_ERROR") - -class ExternalAPIError(DomainException): - """외부 API 호출 실패""" - - def __init__(self, message: str, service: str = None): - self.service = service - super().__init__(message, code="EXTERNAL_API_ERROR") - -class BusinessRuleViolation(DomainException): - """비즈니스 규칙 위반""" - - def __init__(self, message: str): - super().__init__(message, code="BUSINESS_RULE_VIOLATION") -``` - -### 3.10 전역 예외 핸들러 - -```python -# app/presentation/middleware/error_handler.py -from fastapi import FastAPI, Request -from fastapi.responses import JSONResponse - -from app.core.exceptions import ( - DomainException, - EntityNotFoundError, - ValidationError, - ExternalAPIError -) - -def setup_exception_handlers(app: FastAPI): - """전역 예외 핸들러 설정""" - - @app.exception_handler(EntityNotFoundError) - async def entity_not_found_handler( - request: Request, - exc: EntityNotFoundError - ) -> JSONResponse: - return JSONResponse( - status_code=404, - content={ - "success": False, - "error": { - "code": exc.code, - "message": exc.message - } - } - ) - - @app.exception_handler(ValidationError) - async def validation_error_handler( - request: Request, - exc: ValidationError - ) -> JSONResponse: - return JSONResponse( - status_code=400, - content={ - "success": False, - "error": { - "code": exc.code, - "message": exc.message - } - } - ) - - @app.exception_handler(ExternalAPIError) - async def external_api_error_handler( - request: Request, - exc: ExternalAPIError - ) -> JSONResponse: - return JSONResponse( - status_code=503, - content={ - "success": False, - "error": { - "code": exc.code, - "message": exc.message, - "service": exc.service - } - } - ) - - @app.exception_handler(DomainException) - async def domain_exception_handler( - request: Request, - exc: DomainException - ) -> JSONResponse: - return JSONResponse( - status_code=500, - content={ - "success": False, - "error": { - "code": exc.code or "UNKNOWN_ERROR", - "message": exc.message - } - } - ) -``` - ---- - -## 4. 모듈별 구현 예시 - -### 4.1 Song 모듈 리팩토링 - -```python -# app/application/services/song_service.py -from dataclasses import dataclass - -from app.core.uow import IUnitOfWork -from app.core.interfaces.external_api import IMusicGeneratorClient -from app.application.dto.song_dto import CreateSongDTO, SongResponseDTO - -@dataclass -class SongService: - """Song 비즈니스 로직 서비스""" - - uow: IUnitOfWork - suno_client: IMusicGeneratorClient - - async def create_song(self, dto: CreateSongDTO) -> SongResponseDTO: - """음악 생성 요청""" - async with self.uow: - # Lyric 조회 - lyric = await self.uow.lyrics.get_by_task_id(dto.task_id) - if not lyric: - raise EntityNotFoundError( - f"task_id '{dto.task_id}'에 해당하는 가사를 찾을 수 없습니다." - ) - - # Song 생성 - song = SongModel( - project_id=lyric.project_id, - lyric_id=lyric.id, - task_id=dto.task_id, - status="processing", - song_prompt=lyric.lyric_result, - language=lyric.language - ) - song = await self.uow.songs.create(song) - - # Suno API 호출 - suno_task_id = await self.suno_client.generate( - prompt=lyric.lyric_result, - genre=dto.genre, - callback_url=dto.callback_url - ) - - # suno_task_id 업데이트 - song.suno_task_id = suno_task_id - await self.uow.commit() - - return SongResponseDTO( - success=True, - task_id=dto.task_id, - suno_task_id=suno_task_id - ) - - async def handle_callback( - self, - suno_task_id: str, - audio_url: str, - duration: float - ) -> None: - """Suno 콜백 처리""" - async with self.uow: - song = await self.uow.songs.get_by_suno_task_id(suno_task_id) - if song: - song.status = "completed" - song.song_result_url = audio_url - song.duration = duration - await self.uow.commit() -``` - -### 4.2 Video 모듈 리팩토링 - -```python -# app/application/services/video_service.py -from dataclasses import dataclass - -from app.core.uow import IUnitOfWork -from app.core.interfaces.external_api import IVideoGeneratorClient -from app.application.dto.video_dto import CreateVideoDTO, VideoResponseDTO - -@dataclass -class VideoService: - """Video 비즈니스 로직 서비스""" - - uow: IUnitOfWork - creatomate_client: IVideoGeneratorClient - - async def create_video(self, dto: CreateVideoDTO) -> VideoResponseDTO: - """영상 생성 요청""" - async with self.uow: - # 관련 데이터 조회 - project = await self.uow.projects.get_by_task_id(dto.task_id) - lyric = await self.uow.lyrics.get_by_task_id(dto.task_id) - song = await self.uow.songs.get_by_task_id(dto.task_id) - images = await self.uow.images.get_by_task_id(dto.task_id) - - # 유효성 검사 - self._validate_video_creation(project, lyric, song, images) - - # Video 생성 - video = VideoModel( - project_id=project.id, - lyric_id=lyric.id, - song_id=song.id, - task_id=dto.task_id, - status="processing" - ) - video = await self.uow.videos.create(video) - await self.uow.commit() - - # 외부 API 호출 (트랜잭션 외부) - try: - render_id = await self._render_video( - images=[img.img_url for img in images], - lyrics=song.song_prompt, - music_url=song.song_result_url, - duration=song.duration, - orientation=dto.orientation - ) - - # render_id 업데이트 - async with self.uow: - video = await self.uow.videos.get_by_id(video.id) - video.creatomate_render_id = render_id - await self.uow.commit() - - return VideoResponseDTO( - success=True, - task_id=dto.task_id, - creatomate_render_id=render_id - ) - - except Exception as e: - async with self.uow: - video = await self.uow.videos.get_by_id(video.id) - video.status = "failed" - await self.uow.commit() - raise - - async def _render_video( - self, - images: list[str], - lyrics: str, - music_url: str, - duration: float, - orientation: str - ) -> str: - """Creatomate로 영상 렌더링""" - # 템플릿 조회 - template_id = self._get_template_id(orientation) - template = await self.creatomate_client.get_template(template_id) - - # 템플릿 수정 - modified_template = self._prepare_template( - template, images, lyrics, music_url, duration - ) - - # 렌더링 요청 - result = await self.creatomate_client.render(modified_template) - - return result[0]["id"] if isinstance(result, list) else result["id"] - - def _validate_video_creation(self, project, lyric, song, images): - """영상 생성 유효성 검사""" - if not project: - raise EntityNotFoundError("Project를 찾을 수 없습니다.") - if not lyric: - raise EntityNotFoundError("Lyric을 찾을 수 없습니다.") - if not song: - raise EntityNotFoundError("Song을 찾을 수 없습니다.") - if not song.song_result_url: - raise ValidationError("음악 URL이 없습니다.") - if not images: - raise EntityNotFoundError("이미지를 찾을 수 없습니다.") -``` - ---- - -## 5. 기대 효과 - -### 5.1 코드 품질 향상 - -| 측면 | 현재 | 개선 후 | 기대 효과 | -|------|------|---------|----------| -| **테스트 용이성** | 라우터에서 직접 DB/API 호출 | Repository/Service 모킹 가능 | 단위 테스트 커버리지 80%+ | -| **코드 재사용** | 로직 중복 | 서비스 레이어 공유 | 중복 코드 50% 감소 | -| **유지보수** | 변경 시 여러 파일 수정 | 단일 책임 원칙 | 수정 범위 최소화 | -| **확장성** | 새 기능 추가 어려움 | 인터페이스 기반 확장 | 새 LLM/API 추가 용이 | - -### 5.2 아키텍처 개선 - -``` -변경 전: -Router → DB + External API (강결합) - -변경 후: -Router → Service → Repository → DB - ↓ - Interface → External API (약결합) -``` - -### 5.3 테스트 가능성 - -```python -# 단위 테스트 예시 -import pytest -from unittest.mock import AsyncMock, MagicMock - -from app.application.services.lyric_service import LyricService -from app.application.dto.lyric_dto import CreateLyricDTO - -@pytest.fixture -def mock_uow(): - uow = MagicMock() - uow.__aenter__ = AsyncMock(return_value=uow) - uow.__aexit__ = AsyncMock(return_value=None) - uow.commit = AsyncMock() - uow.lyrics = MagicMock() - uow.projects = MagicMock() - return uow - -@pytest.fixture -def mock_chatgpt(): - client = MagicMock() - client.build_lyrics_prompt = MagicMock(return_value="test prompt") - client.generate = AsyncMock(return_value="생성된 가사") - return client - -@pytest.mark.asyncio -async def test_create_lyric_success(mock_uow, mock_chatgpt): - # Given - service = LyricService(uow=mock_uow, chatgpt_client=mock_chatgpt) - dto = CreateLyricDTO( - task_id="test-task-id", - customer_name="테스트 업체", - region="서울" - ) - - mock_uow.projects.create = AsyncMock(return_value=MagicMock(id=1)) - mock_uow.lyrics.create = AsyncMock(return_value=MagicMock(id=1)) - - # When - result = await service.create_lyric(dto) - - # Then - assert result.success is True - assert result.task_id == "test-task-id" - mock_uow.commit.assert_called_once() - -@pytest.mark.asyncio -async def test_get_lyric_status_not_found(mock_uow, mock_chatgpt): - # Given - service = LyricService(uow=mock_uow, chatgpt_client=mock_chatgpt) - mock_uow.lyrics.get_by_task_id = AsyncMock(return_value=None) - - # When & Then - with pytest.raises(EntityNotFoundError): - await service.get_lyric_status("non-existent-id") -``` - -### 5.4 개발 생산성 - -| 항목 | 기대 개선 | -|------|----------| -| 새 기능 개발 | 템플릿 기반으로 30% 단축 | -| 버그 수정 | 단일 책임으로 원인 파악 용이 | -| 코드 리뷰 | 계층별 리뷰로 효율성 향상 | -| 온보딩 | 명확한 구조로 학습 시간 단축 | - -### 5.5 운영 안정성 - -| 항목 | 현재 | 개선 후 | -|------|------|---------| -| 트랜잭션 관리 | 분산되어 일관성 부족 | UoW로 일관된 관리 | -| 에러 처리 | HTTPException 혼재 | 도메인 예외로 통일 | -| 로깅 | 각 함수에서 개별 | 서비스 레벨에서 일관 | -| 모니터링 | 어려움 | 서비스 경계에서 명확한 메트릭 | - ---- - -## 6. 마이그레이션 전략 - -### 6.1 단계별 접근 - -``` -Phase 1: 기반 구축 (1주) -├── core/ 인터페이스 정의 -├── 도메인 예외 정의 -└── Base Repository 구현 - -Phase 2: Lyric 모듈 리팩토링 (1주) -├── LyricRepository 구현 -├── LyricService 구현 -├── 라우터 슬림화 -└── 테스트 작성 - -Phase 3: Song 모듈 리팩토링 (1주) -├── SongRepository 구현 -├── SongService 구현 -├── Suno 클라이언트 인터페이스화 -└── 테스트 작성 - -Phase 4: Video 모듈 리팩토링 (1주) -├── VideoRepository 구현 -├── VideoService 구현 -├── Creatomate 클라이언트 인터페이스화 -└── 테스트 작성 - -Phase 5: 정리 및 최적화 (1주) -├── 기존 코드 제거 -├── 문서화 -├── 성능 테스트 -└── 리뷰 및 배포 -``` - -### 6.2 점진적 마이그레이션 전략 - -기존 코드를 유지하면서 새 구조로 점진적 이전: - -```python -# 1단계: 새 서비스를 기존 라우터에서 호출 -@router.post("/generate") -async def generate_lyric( - request: GenerateLyricRequest, - background_tasks: BackgroundTasks, - session: AsyncSession = Depends(get_session), - # 새 서비스 주입 (optional) - service: LyricService = Depends(get_lyric_service) -) -> GenerateLyricResponse: - # 피처 플래그로 분기 - if settings.USE_NEW_ARCHITECTURE: - return await _generate_lyric_new(request, background_tasks, service) - else: - return await _generate_lyric_legacy(request, background_tasks, session) -``` - -### 6.3 리스크 관리 - -| 리스크 | 완화 전략 | -|--------|----------| -| 기능 회귀 | 기존 테스트 유지, 새 테스트 추가 | -| 성능 저하 | 벤치마크 테스트 | -| 배포 실패 | 피처 플래그로 롤백 가능 | -| 학습 곡선 | 문서화 및 페어 프로그래밍 | - ---- - -## 결론 - -이 리팩토링을 통해: - -1. **명확한 책임 분리**: 각 계층이 하나의 역할만 수행 -2. **높은 테스트 커버리지**: 비즈니스 로직 단위 테스트 가능 -3. **유연한 확장성**: 새로운 LLM/API 추가 시 인터페이스만 구현 -4. **일관된 에러 처리**: 도메인 예외로 통일된 에러 응답 -5. **트랜잭션 안정성**: Unit of Work로 데이터 일관성 보장 - -현재 프로젝트가 잘 동작하고 있다면, 점진적 마이그레이션을 통해 리스크를 최소화하면서 아키텍처를 개선할 수 있습니다. - ---- - -**작성일**: 2024-12-29 -**버전**: 1.0 +# 디자인 패턴 기반 리팩토링 제안서 + +## 목차 + +1. [현재 아키텍처 분석](#1-현재-아키텍처-분석) +2. [제안하는 디자인 패턴](#2-제안하는-디자인-패턴) +3. [상세 리팩토링 방안](#3-상세-리팩토링-방안) +4. [모듈별 구현 예시](#4-모듈별-구현-예시) +5. [기대 효과](#5-기대-효과) +6. [마이그레이션 전략](#6-마이그레이션-전략) + +--- + +## 1. 현재 아키텍처 분석 + +### 1.1 현재 구조 + +``` +app/ +├── {module}/ +│ ├── models.py # SQLAlchemy 모델 +│ ├── schemas/ # Pydantic 스키마 +│ ├── services/ # 비즈니스 로직 (일부만 사용) +│ ├── api/routers/v1/ # FastAPI 라우터 +│ └── worker/ # 백그라운드 태스크 +└── utils/ # 외부 API 클라이언트 (Suno, Creatomate, ChatGPT) +``` + +### 1.2 현재 문제점 + +| 문제 | 설명 | 영향 | +|------|------|------| +| **Fat Controller** | 라우터에 비즈니스 로직이 직접 포함됨 | 테스트 어려움, 재사용 불가 | +| **서비스 레이어 미활용** | services/ 폴더가 있지만 대부분 사용되지 않음 | 코드 중복, 일관성 부족 | +| **외부 API 결합** | 라우터에서 직접 외부 API 호출 | 모킹 어려움, 의존성 강결합 | +| **Repository 부재** | 데이터 접근 로직이 분산됨 | 쿼리 중복, 최적화 어려움 | +| **트랜잭션 관리 분산** | 각 함수에서 개별적으로 세션 관리 | 일관성 부족 | +| **에러 처리 비일관** | HTTPException이 여러 계층에서 발생 | 디버깅 어려움 | + +### 1.3 현재 코드 예시 (문제점) + +```python +# app/lyric/api/routers/v1/lyric.py - 현재 구조 +@router.post("/generate") +async def generate_lyric( + request_body: GenerateLyricRequest, + background_tasks: BackgroundTasks, + session: AsyncSession = Depends(get_session), +) -> GenerateLyricResponse: + task_id = request_body.task_id + + try: + # 문제 1: 라우터에서 직접 비즈니스 로직 수행 + service = ChatgptService( + customer_name=request_body.customer_name, + region=request_body.region, + ... + ) + prompt = service.build_lyrics_prompt() + + # 문제 2: 라우터에서 직접 DB 조작 + project = Project( + store_name=request_body.customer_name, + ... + ) + session.add(project) + await session.commit() + + # 문제 3: 라우터에서 직접 모델 생성 + lyric = Lyric( + project_id=project.id, + ... + ) + session.add(lyric) + await session.commit() + + # 문제 4: 에러 처리가 각 함수마다 다름 + background_tasks.add_task(generate_lyric_background, ...) + + return GenerateLyricResponse(...) + except Exception as e: + await session.rollback() + return GenerateLyricResponse(success=False, ...) +``` + +--- + +## 2. 제안하는 디자인 패턴 + +### 2.1 Clean Architecture + 레이어드 아키텍처 + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ Presentation Layer │ +│ (FastAPI Routers - HTTP 요청/응답만 처리) │ +└─────────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ Application Layer │ +│ (Use Cases / Services - 비즈니스 로직 오케스트레이션) │ +└─────────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ Domain Layer │ +│ (Entities, Value Objects, Domain Services) │ +└─────────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ Infrastructure Layer │ +│ (Repositories, External APIs, Database) │ +└─────────────────────────────────────────────────────────────────┘ +``` + +### 2.2 적용할 디자인 패턴 + +| 패턴 | 적용 대상 | 목적 | +|------|----------|------| +| **Repository Pattern** | 데이터 접근 | DB 로직 캡슐화, 테스트 용이 | +| **Service Pattern** | 비즈니스 로직 | 유스케이스 구현, 트랜잭션 관리 | +| **Factory Pattern** | 객체 생성 | 복잡한 객체 생성 캡슐화 | +| **Strategy Pattern** | 외부 API | API 클라이언트 교체 용이 | +| **Unit of Work** | 트랜잭션 | 일관된 트랜잭션 관리 | +| **Dependency Injection** | 전체 | 느슨한 결합, 테스트 용이 | +| **DTO Pattern** | 계층 간 전달 | 명확한 데이터 경계 | + +--- + +## 3. 상세 리팩토링 방안 + +### 3.1 새로운 폴더 구조 + +``` +app/ +├── core/ +│ ├── __init__.py +│ ├── config.py # 설정 관리 (기존 config.py 이동) +│ ├── exceptions.py # 도메인 예외 정의 +│ ├── interfaces/ # 추상 인터페이스 +│ │ ├── __init__.py +│ │ ├── repository.py # IRepository 인터페이스 +│ │ ├── service.py # IService 인터페이스 +│ │ └── external_api.py # IExternalAPI 인터페이스 +│ └── uow.py # Unit of Work +│ +├── domain/ +│ ├── __init__.py +│ ├── entities/ # 도메인 엔티티 +│ │ ├── __init__.py +│ │ ├── project.py +│ │ ├── lyric.py +│ │ ├── song.py +│ │ └── video.py +│ ├── value_objects/ # 값 객체 +│ │ ├── __init__.py +│ │ ├── task_id.py +│ │ └── status.py +│ └── events/ # 도메인 이벤트 +│ ├── __init__.py +│ └── lyric_events.py +│ +├── infrastructure/ +│ ├── __init__.py +│ ├── database/ +│ │ ├── __init__.py +│ │ ├── session.py # DB 세션 관리 +│ │ ├── models/ # SQLAlchemy 모델 +│ │ │ ├── __init__.py +│ │ │ ├── project_model.py +│ │ │ ├── lyric_model.py +│ │ │ ├── song_model.py +│ │ │ └── video_model.py +│ │ └── repositories/ # Repository 구현 +│ │ ├── __init__.py +│ │ ├── base.py +│ │ ├── project_repository.py +│ │ ├── lyric_repository.py +│ │ ├── song_repository.py +│ │ └── video_repository.py +│ ├── external/ # 외부 API 클라이언트 +│ │ ├── __init__.py +│ │ ├── chatgpt/ +│ │ │ ├── __init__.py +│ │ │ ├── client.py +│ │ │ └── prompts.py +│ │ ├── suno/ +│ │ │ ├── __init__.py +│ │ │ └── client.py +│ │ ├── creatomate/ +│ │ │ ├── __init__.py +│ │ │ └── client.py +│ │ └── azure_blob/ +│ │ ├── __init__.py +│ │ └── client.py +│ └── cache/ +│ ├── __init__.py +│ └── redis.py +│ +├── application/ +│ ├── __init__.py +│ ├── services/ # 애플리케이션 서비스 +│ │ ├── __init__.py +│ │ ├── lyric_service.py +│ │ ├── song_service.py +│ │ └── video_service.py +│ ├── dto/ # Data Transfer Objects +│ │ ├── __init__.py +│ │ ├── lyric_dto.py +│ │ ├── song_dto.py +│ │ └── video_dto.py +│ └── tasks/ # 백그라운드 태스크 +│ ├── __init__.py +│ ├── lyric_tasks.py +│ ├── song_tasks.py +│ └── video_tasks.py +│ +├── presentation/ +│ ├── __init__.py +│ ├── api/ +│ │ ├── __init__.py +│ │ ├── v1/ +│ │ │ ├── __init__.py +│ │ │ ├── lyric_router.py +│ │ │ ├── song_router.py +│ │ │ └── video_router.py +│ │ └── dependencies.py # FastAPI 의존성 +│ ├── schemas/ # API 스키마 (요청/응답) +│ │ ├── __init__.py +│ │ ├── lyric_schema.py +│ │ ├── song_schema.py +│ │ └── video_schema.py +│ └── middleware/ +│ ├── __init__.py +│ └── error_handler.py +│ +└── main.py +``` + +### 3.2 Repository Pattern 구현 + +#### 3.2.1 추상 인터페이스 + +```python +# app/core/interfaces/repository.py +from abc import ABC, abstractmethod +from typing import Generic, TypeVar, Optional, List + +T = TypeVar("T") + +class IRepository(ABC, Generic[T]): + """Repository 인터페이스 - 데이터 접근 추상화""" + + @abstractmethod + async def get_by_id(self, id: int) -> Optional[T]: + """ID로 엔티티 조회""" + pass + + @abstractmethod + async def get_by_task_id(self, task_id: str) -> Optional[T]: + """task_id로 엔티티 조회""" + pass + + @abstractmethod + async def get_all( + self, + skip: int = 0, + limit: int = 100, + filters: dict = None + ) -> List[T]: + """전체 엔티티 조회 (페이지네이션)""" + pass + + @abstractmethod + async def create(self, entity: T) -> T: + """엔티티 생성""" + pass + + @abstractmethod + async def update(self, entity: T) -> T: + """엔티티 수정""" + pass + + @abstractmethod + async def delete(self, id: int) -> bool: + """엔티티 삭제""" + pass + + @abstractmethod + async def count(self, filters: dict = None) -> int: + """엔티티 개수 조회""" + pass +``` + +#### 3.2.2 Base Repository 구현 + +```python +# app/infrastructure/database/repositories/base.py +from typing import Generic, TypeVar, Optional, List, Type +from sqlalchemy import select, func, and_ +from sqlalchemy.ext.asyncio import AsyncSession + +from app.core.interfaces.repository import IRepository +from app.infrastructure.database.session import Base + +T = TypeVar("T", bound=Base) + +class BaseRepository(IRepository[T], Generic[T]): + """Repository 기본 구현""" + + def __init__(self, session: AsyncSession, model: Type[T]): + self._session = session + self._model = model + + async def get_by_id(self, id: int) -> Optional[T]: + result = await self._session.execute( + select(self._model).where(self._model.id == id) + ) + return result.scalar_one_or_none() + + async def get_by_task_id(self, task_id: str) -> Optional[T]: + result = await self._session.execute( + select(self._model) + .where(self._model.task_id == task_id) + .order_by(self._model.created_at.desc()) + .limit(1) + ) + return result.scalar_one_or_none() + + async def get_all( + self, + skip: int = 0, + limit: int = 100, + filters: dict = None + ) -> List[T]: + query = select(self._model) + + if filters: + conditions = [ + getattr(self._model, key) == value + for key, value in filters.items() + if hasattr(self._model, key) + ] + if conditions: + query = query.where(and_(*conditions)) + + query = query.offset(skip).limit(limit).order_by( + self._model.created_at.desc() + ) + result = await self._session.execute(query) + return list(result.scalars().all()) + + async def create(self, entity: T) -> T: + self._session.add(entity) + await self._session.flush() + await self._session.refresh(entity) + return entity + + async def update(self, entity: T) -> T: + await self._session.flush() + await self._session.refresh(entity) + return entity + + async def delete(self, id: int) -> bool: + entity = await self.get_by_id(id) + if entity: + await self._session.delete(entity) + return True + return False + + async def count(self, filters: dict = None) -> int: + query = select(func.count(self._model.id)) + + if filters: + conditions = [ + getattr(self._model, key) == value + for key, value in filters.items() + if hasattr(self._model, key) + ] + if conditions: + query = query.where(and_(*conditions)) + + result = await self._session.execute(query) + return result.scalar() or 0 +``` + +#### 3.2.3 특화된 Repository + +```python +# app/infrastructure/database/repositories/lyric_repository.py +from typing import Optional, List +from sqlalchemy import select + +from app.infrastructure.database.repositories.base import BaseRepository +from app.infrastructure.database.models.lyric_model import LyricModel + +class LyricRepository(BaseRepository[LyricModel]): + """Lyric 전용 Repository""" + + def __init__(self, session): + super().__init__(session, LyricModel) + + async def get_by_project_id(self, project_id: int) -> List[LyricModel]: + """프로젝트 ID로 가사 목록 조회""" + result = await self._session.execute( + select(self._model) + .where(self._model.project_id == project_id) + .order_by(self._model.created_at.desc()) + ) + return list(result.scalars().all()) + + async def get_completed_lyrics( + self, + skip: int = 0, + limit: int = 100 + ) -> List[LyricModel]: + """완료된 가사만 조회""" + return await self.get_all( + skip=skip, + limit=limit, + filters={"status": "completed"} + ) + + async def update_status( + self, + task_id: str, + status: str, + result: Optional[str] = None + ) -> Optional[LyricModel]: + """가사 상태 업데이트""" + lyric = await self.get_by_task_id(task_id) + if lyric: + lyric.status = status + if result is not None: + lyric.lyric_result = result + return await self.update(lyric) + return None +``` + +### 3.3 Unit of Work Pattern + +```python +# app/core/uow.py +from abc import ABC, abstractmethod +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from app.infrastructure.database.repositories.project_repository import ProjectRepository + from app.infrastructure.database.repositories.lyric_repository import LyricRepository + from app.infrastructure.database.repositories.song_repository import SongRepository + from app.infrastructure.database.repositories.video_repository import VideoRepository + +class IUnitOfWork(ABC): + """Unit of Work 인터페이스""" + + projects: "ProjectRepository" + lyrics: "LyricRepository" + songs: "SongRepository" + videos: "VideoRepository" + + @abstractmethod + async def __aenter__(self): + pass + + @abstractmethod + async def __aexit__(self, exc_type, exc_val, exc_tb): + pass + + @abstractmethod + async def commit(self): + pass + + @abstractmethod + async def rollback(self): + pass + + +# app/infrastructure/database/uow.py +from sqlalchemy.ext.asyncio import AsyncSession + +from app.core.uow import IUnitOfWork +from app.infrastructure.database.session import AsyncSessionLocal +from app.infrastructure.database.repositories.project_repository import ProjectRepository +from app.infrastructure.database.repositories.lyric_repository import LyricRepository +from app.infrastructure.database.repositories.song_repository import SongRepository +from app.infrastructure.database.repositories.video_repository import VideoRepository + +class UnitOfWork(IUnitOfWork): + """Unit of Work 구현 - 트랜잭션 관리""" + + def __init__(self, session_factory=AsyncSessionLocal): + self._session_factory = session_factory + self._session: AsyncSession = None + + async def __aenter__(self): + self._session = self._session_factory() + + # Repository 인스턴스 생성 + self.projects = ProjectRepository(self._session) + self.lyrics = LyricRepository(self._session) + self.songs = SongRepository(self._session) + self.videos = VideoRepository(self._session) + + return self + + async def __aexit__(self, exc_type, exc_val, exc_tb): + if exc_type is not None: + await self.rollback() + await self._session.close() + + async def commit(self): + await self._session.commit() + + async def rollback(self): + await self._session.rollback() +``` + +### 3.4 Service Layer 구현 + +```python +# app/application/services/lyric_service.py +from typing import Optional +from dataclasses import dataclass + +from app.core.uow import IUnitOfWork +from app.core.exceptions import ( + EntityNotFoundError, + ExternalAPIError, + ValidationError +) +from app.application.dto.lyric_dto import ( + CreateLyricDTO, + LyricResponseDTO, + LyricStatusDTO +) +from app.infrastructure.external.chatgpt.client import IChatGPTClient +from app.infrastructure.database.models.lyric_model import LyricModel +from app.infrastructure.database.models.project_model import ProjectModel + +@dataclass +class LyricService: + """Lyric 비즈니스 로직 서비스""" + + uow: IUnitOfWork + chatgpt_client: IChatGPTClient + + async def create_lyric(self, dto: CreateLyricDTO) -> LyricResponseDTO: + """가사 생성 요청 처리 + + 1. 프롬프트 생성 + 2. Project 저장 + 3. Lyric 저장 (processing) + 4. task_id 반환 (백그라운드 처리는 별도) + """ + async with self.uow: + # 프롬프트 생성 + prompt = self.chatgpt_client.build_lyrics_prompt( + customer_name=dto.customer_name, + region=dto.region, + detail_region_info=dto.detail_region_info, + language=dto.language + ) + + # Project 생성 + project = ProjectModel( + store_name=dto.customer_name, + region=dto.region, + task_id=dto.task_id, + detail_region_info=dto.detail_region_info, + language=dto.language + ) + project = await self.uow.projects.create(project) + + # Lyric 생성 (processing 상태) + lyric = LyricModel( + project_id=project.id, + task_id=dto.task_id, + status="processing", + lyric_prompt=prompt, + language=dto.language + ) + lyric = await self.uow.lyrics.create(lyric) + + await self.uow.commit() + + return LyricResponseDTO( + success=True, + task_id=dto.task_id, + lyric=None, # 백그라운드에서 생성 + language=dto.language, + prompt=prompt # 백그라운드 태스크에 전달 + ) + + async def process_lyric_generation( + self, + task_id: str, + prompt: str, + language: str + ) -> None: + """백그라운드에서 가사 실제 생성 + + 이 메서드는 백그라운드 태스크에서 호출됨 + """ + try: + # ChatGPT로 가사 생성 + result = await self.chatgpt_client.generate(prompt) + + # 실패 패턴 검사 + is_failure = self._check_failure_patterns(result) + + async with self.uow: + status = "failed" if is_failure else "completed" + await self.uow.lyrics.update_status( + task_id=task_id, + status=status, + result=result + ) + await self.uow.commit() + + except Exception as e: + async with self.uow: + await self.uow.lyrics.update_status( + task_id=task_id, + status="failed", + result=f"Error: {str(e)}" + ) + await self.uow.commit() + raise + + async def get_lyric_status(self, task_id: str) -> LyricStatusDTO: + """가사 생성 상태 조회""" + async with self.uow: + lyric = await self.uow.lyrics.get_by_task_id(task_id) + + if not lyric: + raise EntityNotFoundError( + f"task_id '{task_id}'에 해당하는 가사를 찾을 수 없습니다." + ) + + status_messages = { + "processing": "가사 생성 중입니다.", + "completed": "가사 생성이 완료되었습니다.", + "failed": "가사 생성에 실패했습니다.", + } + + return LyricStatusDTO( + task_id=lyric.task_id, + status=lyric.status, + message=status_messages.get(lyric.status, "알 수 없는 상태입니다.") + ) + + async def get_lyric_detail(self, task_id: str) -> LyricResponseDTO: + """가사 상세 조회""" + async with self.uow: + lyric = await self.uow.lyrics.get_by_task_id(task_id) + + if not lyric: + raise EntityNotFoundError( + f"task_id '{task_id}'에 해당하는 가사를 찾을 수 없습니다." + ) + + return LyricResponseDTO( + id=lyric.id, + task_id=lyric.task_id, + project_id=lyric.project_id, + status=lyric.status, + lyric_prompt=lyric.lyric_prompt, + lyric_result=lyric.lyric_result, + language=lyric.language, + created_at=lyric.created_at + ) + + def _check_failure_patterns(self, result: str) -> bool: + """ChatGPT 응답에서 실패 패턴 검사""" + failure_patterns = [ + "ERROR:", + "I'm sorry", + "I cannot", + "I can't", + "I apologize", + "I'm unable", + "I am unable", + "I'm not able", + "I am not able", + ] + return any( + pattern.lower() in result.lower() + for pattern in failure_patterns + ) +``` + +### 3.5 DTO (Data Transfer Objects) + +```python +# app/application/dto/lyric_dto.py +from dataclasses import dataclass +from datetime import datetime +from typing import Optional + +@dataclass +class CreateLyricDTO: + """가사 생성 요청 DTO""" + task_id: str + customer_name: str + region: str + detail_region_info: Optional[str] = None + language: str = "Korean" + +@dataclass +class LyricResponseDTO: + """가사 응답 DTO""" + success: bool = True + task_id: Optional[str] = None + lyric: Optional[str] = None + language: str = "Korean" + error_message: Optional[str] = None + + # 상세 조회 시 추가 필드 + id: Optional[int] = None + project_id: Optional[int] = None + status: Optional[str] = None + lyric_prompt: Optional[str] = None + lyric_result: Optional[str] = None + created_at: Optional[datetime] = None + prompt: Optional[str] = None # 백그라운드 태스크용 + +@dataclass +class LyricStatusDTO: + """가사 상태 조회 DTO""" + task_id: str + status: str + message: str +``` + +### 3.6 Strategy Pattern for External APIs + +```python +# app/core/interfaces/external_api.py +from abc import ABC, abstractmethod +from typing import Optional + +class ILLMClient(ABC): + """LLM 클라이언트 인터페이스""" + + @abstractmethod + def build_lyrics_prompt( + self, + customer_name: str, + region: str, + detail_region_info: str, + language: str + ) -> str: + pass + + @abstractmethod + async def generate(self, prompt: str) -> str: + pass + + +class IMusicGeneratorClient(ABC): + """음악 생성 클라이언트 인터페이스""" + + @abstractmethod + async def generate( + self, + prompt: str, + genre: str, + callback_url: Optional[str] = None + ) -> str: + """음악 생성 요청, task_id 반환""" + pass + + @abstractmethod + async def get_status(self, task_id: str) -> dict: + pass + + +class IVideoGeneratorClient(ABC): + """영상 생성 클라이언트 인터페이스""" + + @abstractmethod + async def get_template(self, template_id: str) -> dict: + pass + + @abstractmethod + async def render(self, source: dict) -> dict: + pass + + @abstractmethod + async def get_render_status(self, render_id: str) -> dict: + pass + + +# app/infrastructure/external/chatgpt/client.py +from openai import AsyncOpenAI + +from app.core.interfaces.external_api import ILLMClient +from app.infrastructure.external.chatgpt.prompts import LYRICS_PROMPT_TEMPLATE + +class ChatGPTClient(ILLMClient): + """ChatGPT 클라이언트 구현""" + + def __init__(self, api_key: str, model: str = "gpt-5-mini"): + self._client = AsyncOpenAI(api_key=api_key) + self._model = model + + def build_lyrics_prompt( + self, + customer_name: str, + region: str, + detail_region_info: str, + language: str + ) -> str: + return LYRICS_PROMPT_TEMPLATE.format( + customer_name=customer_name, + region=region, + detail_region_info=detail_region_info, + language=language + ) + + async def generate(self, prompt: str) -> str: + completion = await self._client.chat.completions.create( + model=self._model, + messages=[{"role": "user", "content": prompt}] + ) + return completion.choices[0].message.content or "" +``` + +### 3.7 Presentation Layer (Thin Router) + +```python +# app/presentation/api/v1/lyric_router.py +from fastapi import APIRouter, BackgroundTasks, Depends, HTTPException, status + +from app.presentation.schemas.lyric_schema import ( + GenerateLyricRequest, + GenerateLyricResponse, + LyricStatusResponse, + LyricDetailResponse +) +from app.application.services.lyric_service import LyricService +from app.application.dto.lyric_dto import CreateLyricDTO +from app.core.exceptions import EntityNotFoundError +from app.presentation.api.dependencies import get_lyric_service + +router = APIRouter(prefix="/lyric", tags=["lyric"]) + +@router.post( + "/generate", + response_model=GenerateLyricResponse, + summary="가사 생성", + description="고객 정보를 기반으로 ChatGPT를 이용하여 가사를 생성합니다." +) +async def generate_lyric( + request: GenerateLyricRequest, + background_tasks: BackgroundTasks, + service: LyricService = Depends(get_lyric_service) +) -> GenerateLyricResponse: + """ + 라우터는 HTTP 요청/응답만 처리 + 비즈니스 로직은 서비스에 위임 + """ + # DTO로 변환 + dto = CreateLyricDTO( + task_id=request.task_id, + customer_name=request.customer_name, + region=request.region, + detail_region_info=request.detail_region_info, + language=request.language + ) + + # 서비스 호출 + result = await service.create_lyric(dto) + + # 백그라운드 태스크 등록 + background_tasks.add_task( + service.process_lyric_generation, + task_id=result.task_id, + prompt=result.prompt, + language=result.language + ) + + # 응답 반환 + return GenerateLyricResponse( + success=result.success, + task_id=result.task_id, + lyric=result.lyric, + language=result.language, + error_message=result.error_message + ) + +@router.get( + "/status/{task_id}", + response_model=LyricStatusResponse, + summary="가사 생성 상태 조회" +) +async def get_lyric_status( + task_id: str, + service: LyricService = Depends(get_lyric_service) +) -> LyricStatusResponse: + try: + result = await service.get_lyric_status(task_id) + return LyricStatusResponse( + task_id=result.task_id, + status=result.status, + message=result.message + ) + except EntityNotFoundError as e: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=str(e) + ) + +@router.get( + "/{task_id}", + response_model=LyricDetailResponse, + summary="가사 상세 조회" +) +async def get_lyric_detail( + task_id: str, + service: LyricService = Depends(get_lyric_service) +) -> LyricDetailResponse: + try: + result = await service.get_lyric_detail(task_id) + return LyricDetailResponse.model_validate(result.__dict__) + except EntityNotFoundError as e: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail=str(e) + ) +``` + +### 3.8 Dependency Injection 설정 + +```python +# app/presentation/api/dependencies.py +from functools import lru_cache +from fastapi import Depends + +from app.core.config import get_settings, Settings +from app.infrastructure.database.uow import UnitOfWork +from app.infrastructure.external.chatgpt.client import ChatGPTClient +from app.infrastructure.external.suno.client import SunoClient +from app.infrastructure.external.creatomate.client import CreatomateClient +from app.application.services.lyric_service import LyricService +from app.application.services.song_service import SongService +from app.application.services.video_service import VideoService + +@lru_cache() +def get_settings() -> Settings: + return Settings() + +def get_chatgpt_client( + settings: Settings = Depends(get_settings) +) -> ChatGPTClient: + return ChatGPTClient( + api_key=settings.CHATGPT_API_KEY, + model="gpt-5-mini" + ) + +def get_suno_client( + settings: Settings = Depends(get_settings) +) -> SunoClient: + return SunoClient( + api_key=settings.SUNO_API_KEY, + callback_url=settings.SUNO_CALLBACK_URL + ) + +def get_creatomate_client( + settings: Settings = Depends(get_settings) +) -> CreatomateClient: + return CreatomateClient( + api_key=settings.CREATOMATE_API_KEY + ) + +def get_unit_of_work() -> UnitOfWork: + return UnitOfWork() + +def get_lyric_service( + uow: UnitOfWork = Depends(get_unit_of_work), + chatgpt: ChatGPTClient = Depends(get_chatgpt_client) +) -> LyricService: + return LyricService(uow=uow, chatgpt_client=chatgpt) + +def get_song_service( + uow: UnitOfWork = Depends(get_unit_of_work), + suno: SunoClient = Depends(get_suno_client) +) -> SongService: + return SongService(uow=uow, suno_client=suno) + +def get_video_service( + uow: UnitOfWork = Depends(get_unit_of_work), + creatomate: CreatomateClient = Depends(get_creatomate_client) +) -> VideoService: + return VideoService(uow=uow, creatomate_client=creatomate) +``` + +### 3.9 도메인 예외 정의 + +```python +# app/core/exceptions.py + +class DomainException(Exception): + """도메인 예외 기본 클래스""" + + def __init__(self, message: str, code: str = None): + self.message = message + self.code = code + super().__init__(message) + +class EntityNotFoundError(DomainException): + """엔티티를 찾을 수 없음""" + + def __init__(self, message: str): + super().__init__(message, code="ENTITY_NOT_FOUND") + +class ValidationError(DomainException): + """유효성 검증 실패""" + + def __init__(self, message: str): + super().__init__(message, code="VALIDATION_ERROR") + +class ExternalAPIError(DomainException): + """외부 API 호출 실패""" + + def __init__(self, message: str, service: str = None): + self.service = service + super().__init__(message, code="EXTERNAL_API_ERROR") + +class BusinessRuleViolation(DomainException): + """비즈니스 규칙 위반""" + + def __init__(self, message: str): + super().__init__(message, code="BUSINESS_RULE_VIOLATION") +``` + +### 3.10 전역 예외 핸들러 + +```python +# app/presentation/middleware/error_handler.py +from fastapi import FastAPI, Request +from fastapi.responses import JSONResponse + +from app.core.exceptions import ( + DomainException, + EntityNotFoundError, + ValidationError, + ExternalAPIError +) + +def setup_exception_handlers(app: FastAPI): + """전역 예외 핸들러 설정""" + + @app.exception_handler(EntityNotFoundError) + async def entity_not_found_handler( + request: Request, + exc: EntityNotFoundError + ) -> JSONResponse: + return JSONResponse( + status_code=404, + content={ + "success": False, + "error": { + "code": exc.code, + "message": exc.message + } + } + ) + + @app.exception_handler(ValidationError) + async def validation_error_handler( + request: Request, + exc: ValidationError + ) -> JSONResponse: + return JSONResponse( + status_code=400, + content={ + "success": False, + "error": { + "code": exc.code, + "message": exc.message + } + } + ) + + @app.exception_handler(ExternalAPIError) + async def external_api_error_handler( + request: Request, + exc: ExternalAPIError + ) -> JSONResponse: + return JSONResponse( + status_code=503, + content={ + "success": False, + "error": { + "code": exc.code, + "message": exc.message, + "service": exc.service + } + } + ) + + @app.exception_handler(DomainException) + async def domain_exception_handler( + request: Request, + exc: DomainException + ) -> JSONResponse: + return JSONResponse( + status_code=500, + content={ + "success": False, + "error": { + "code": exc.code or "UNKNOWN_ERROR", + "message": exc.message + } + } + ) +``` + +--- + +## 4. 모듈별 구현 예시 + +### 4.1 Song 모듈 리팩토링 + +```python +# app/application/services/song_service.py +from dataclasses import dataclass + +from app.core.uow import IUnitOfWork +from app.core.interfaces.external_api import IMusicGeneratorClient +from app.application.dto.song_dto import CreateSongDTO, SongResponseDTO + +@dataclass +class SongService: + """Song 비즈니스 로직 서비스""" + + uow: IUnitOfWork + suno_client: IMusicGeneratorClient + + async def create_song(self, dto: CreateSongDTO) -> SongResponseDTO: + """음악 생성 요청""" + async with self.uow: + # Lyric 조회 + lyric = await self.uow.lyrics.get_by_task_id(dto.task_id) + if not lyric: + raise EntityNotFoundError( + f"task_id '{dto.task_id}'에 해당하는 가사를 찾을 수 없습니다." + ) + + # Song 생성 + song = SongModel( + project_id=lyric.project_id, + lyric_id=lyric.id, + task_id=dto.task_id, + status="processing", + song_prompt=lyric.lyric_result, + language=lyric.language + ) + song = await self.uow.songs.create(song) + + # Suno API 호출 + suno_task_id = await self.suno_client.generate( + prompt=lyric.lyric_result, + genre=dto.genre, + callback_url=dto.callback_url + ) + + # suno_task_id 업데이트 + song.suno_task_id = suno_task_id + await self.uow.commit() + + return SongResponseDTO( + success=True, + task_id=dto.task_id, + suno_task_id=suno_task_id + ) + + async def handle_callback( + self, + suno_task_id: str, + audio_url: str, + duration: float + ) -> None: + """Suno 콜백 처리""" + async with self.uow: + song = await self.uow.songs.get_by_suno_task_id(suno_task_id) + if song: + song.status = "completed" + song.song_result_url = audio_url + song.duration = duration + await self.uow.commit() +``` + +### 4.2 Video 모듈 리팩토링 + +```python +# app/application/services/video_service.py +from dataclasses import dataclass + +from app.core.uow import IUnitOfWork +from app.core.interfaces.external_api import IVideoGeneratorClient +from app.application.dto.video_dto import CreateVideoDTO, VideoResponseDTO + +@dataclass +class VideoService: + """Video 비즈니스 로직 서비스""" + + uow: IUnitOfWork + creatomate_client: IVideoGeneratorClient + + async def create_video(self, dto: CreateVideoDTO) -> VideoResponseDTO: + """영상 생성 요청""" + async with self.uow: + # 관련 데이터 조회 + project = await self.uow.projects.get_by_task_id(dto.task_id) + lyric = await self.uow.lyrics.get_by_task_id(dto.task_id) + song = await self.uow.songs.get_by_task_id(dto.task_id) + images = await self.uow.images.get_by_task_id(dto.task_id) + + # 유효성 검사 + self._validate_video_creation(project, lyric, song, images) + + # Video 생성 + video = VideoModel( + project_id=project.id, + lyric_id=lyric.id, + song_id=song.id, + task_id=dto.task_id, + status="processing" + ) + video = await self.uow.videos.create(video) + await self.uow.commit() + + # 외부 API 호출 (트랜잭션 외부) + try: + render_id = await self._render_video( + images=[img.img_url for img in images], + lyrics=song.song_prompt, + music_url=song.song_result_url, + duration=song.duration, + orientation=dto.orientation + ) + + # render_id 업데이트 + async with self.uow: + video = await self.uow.videos.get_by_id(video.id) + video.creatomate_render_id = render_id + await self.uow.commit() + + return VideoResponseDTO( + success=True, + task_id=dto.task_id, + creatomate_render_id=render_id + ) + + except Exception as e: + async with self.uow: + video = await self.uow.videos.get_by_id(video.id) + video.status = "failed" + await self.uow.commit() + raise + + async def _render_video( + self, + images: list[str], + lyrics: str, + music_url: str, + duration: float, + orientation: str + ) -> str: + """Creatomate로 영상 렌더링""" + # 템플릿 조회 + template_id = self._get_template_id(orientation) + template = await self.creatomate_client.get_template(template_id) + + # 템플릿 수정 + modified_template = self._prepare_template( + template, images, lyrics, music_url, duration + ) + + # 렌더링 요청 + result = await self.creatomate_client.render(modified_template) + + return result[0]["id"] if isinstance(result, list) else result["id"] + + def _validate_video_creation(self, project, lyric, song, images): + """영상 생성 유효성 검사""" + if not project: + raise EntityNotFoundError("Project를 찾을 수 없습니다.") + if not lyric: + raise EntityNotFoundError("Lyric을 찾을 수 없습니다.") + if not song: + raise EntityNotFoundError("Song을 찾을 수 없습니다.") + if not song.song_result_url: + raise ValidationError("음악 URL이 없습니다.") + if not images: + raise EntityNotFoundError("이미지를 찾을 수 없습니다.") +``` + +--- + +## 5. 기대 효과 + +### 5.1 코드 품질 향상 + +| 측면 | 현재 | 개선 후 | 기대 효과 | +|------|------|---------|----------| +| **테스트 용이성** | 라우터에서 직접 DB/API 호출 | Repository/Service 모킹 가능 | 단위 테스트 커버리지 80%+ | +| **코드 재사용** | 로직 중복 | 서비스 레이어 공유 | 중복 코드 50% 감소 | +| **유지보수** | 변경 시 여러 파일 수정 | 단일 책임 원칙 | 수정 범위 최소화 | +| **확장성** | 새 기능 추가 어려움 | 인터페이스 기반 확장 | 새 LLM/API 추가 용이 | + +### 5.2 아키텍처 개선 + +``` +변경 전: +Router → DB + External API (강결합) + +변경 후: +Router → Service → Repository → DB + ↓ + Interface → External API (약결합) +``` + +### 5.3 테스트 가능성 + +```python +# 단위 테스트 예시 +import pytest +from unittest.mock import AsyncMock, MagicMock + +from app.application.services.lyric_service import LyricService +from app.application.dto.lyric_dto import CreateLyricDTO + +@pytest.fixture +def mock_uow(): + uow = MagicMock() + uow.__aenter__ = AsyncMock(return_value=uow) + uow.__aexit__ = AsyncMock(return_value=None) + uow.commit = AsyncMock() + uow.lyrics = MagicMock() + uow.projects = MagicMock() + return uow + +@pytest.fixture +def mock_chatgpt(): + client = MagicMock() + client.build_lyrics_prompt = MagicMock(return_value="test prompt") + client.generate = AsyncMock(return_value="생성된 가사") + return client + +@pytest.mark.asyncio +async def test_create_lyric_success(mock_uow, mock_chatgpt): + # Given + service = LyricService(uow=mock_uow, chatgpt_client=mock_chatgpt) + dto = CreateLyricDTO( + task_id="test-task-id", + customer_name="테스트 업체", + region="서울" + ) + + mock_uow.projects.create = AsyncMock(return_value=MagicMock(id=1)) + mock_uow.lyrics.create = AsyncMock(return_value=MagicMock(id=1)) + + # When + result = await service.create_lyric(dto) + + # Then + assert result.success is True + assert result.task_id == "test-task-id" + mock_uow.commit.assert_called_once() + +@pytest.mark.asyncio +async def test_get_lyric_status_not_found(mock_uow, mock_chatgpt): + # Given + service = LyricService(uow=mock_uow, chatgpt_client=mock_chatgpt) + mock_uow.lyrics.get_by_task_id = AsyncMock(return_value=None) + + # When & Then + with pytest.raises(EntityNotFoundError): + await service.get_lyric_status("non-existent-id") +``` + +### 5.4 개발 생산성 + +| 항목 | 기대 개선 | +|------|----------| +| 새 기능 개발 | 템플릿 기반으로 30% 단축 | +| 버그 수정 | 단일 책임으로 원인 파악 용이 | +| 코드 리뷰 | 계층별 리뷰로 효율성 향상 | +| 온보딩 | 명확한 구조로 학습 시간 단축 | + +### 5.5 운영 안정성 + +| 항목 | 현재 | 개선 후 | +|------|------|---------| +| 트랜잭션 관리 | 분산되어 일관성 부족 | UoW로 일관된 관리 | +| 에러 처리 | HTTPException 혼재 | 도메인 예외로 통일 | +| 로깅 | 각 함수에서 개별 | 서비스 레벨에서 일관 | +| 모니터링 | 어려움 | 서비스 경계에서 명확한 메트릭 | + +--- + +## 6. 마이그레이션 전략 + +### 6.1 단계별 접근 + +``` +Phase 1: 기반 구축 (1주) +├── core/ 인터페이스 정의 +├── 도메인 예외 정의 +└── Base Repository 구현 + +Phase 2: Lyric 모듈 리팩토링 (1주) +├── LyricRepository 구현 +├── LyricService 구현 +├── 라우터 슬림화 +└── 테스트 작성 + +Phase 3: Song 모듈 리팩토링 (1주) +├── SongRepository 구현 +├── SongService 구현 +├── Suno 클라이언트 인터페이스화 +└── 테스트 작성 + +Phase 4: Video 모듈 리팩토링 (1주) +├── VideoRepository 구현 +├── VideoService 구현 +├── Creatomate 클라이언트 인터페이스화 +└── 테스트 작성 + +Phase 5: 정리 및 최적화 (1주) +├── 기존 코드 제거 +├── 문서화 +├── 성능 테스트 +└── 리뷰 및 배포 +``` + +### 6.2 점진적 마이그레이션 전략 + +기존 코드를 유지하면서 새 구조로 점진적 이전: + +```python +# 1단계: 새 서비스를 기존 라우터에서 호출 +@router.post("/generate") +async def generate_lyric( + request: GenerateLyricRequest, + background_tasks: BackgroundTasks, + session: AsyncSession = Depends(get_session), + # 새 서비스 주입 (optional) + service: LyricService = Depends(get_lyric_service) +) -> GenerateLyricResponse: + # 피처 플래그로 분기 + if settings.USE_NEW_ARCHITECTURE: + return await _generate_lyric_new(request, background_tasks, service) + else: + return await _generate_lyric_legacy(request, background_tasks, session) +``` + +### 6.3 리스크 관리 + +| 리스크 | 완화 전략 | +|--------|----------| +| 기능 회귀 | 기존 테스트 유지, 새 테스트 추가 | +| 성능 저하 | 벤치마크 테스트 | +| 배포 실패 | 피처 플래그로 롤백 가능 | +| 학습 곡선 | 문서화 및 페어 프로그래밍 | + +--- + +## 결론 + +이 리팩토링을 통해: + +1. **명확한 책임 분리**: 각 계층이 하나의 역할만 수행 +2. **높은 테스트 커버리지**: 비즈니스 로직 단위 테스트 가능 +3. **유연한 확장성**: 새로운 LLM/API 추가 시 인터페이스만 구현 +4. **일관된 에러 처리**: 도메인 예외로 통일된 에러 응답 +5. **트랜잭션 안정성**: Unit of Work로 데이터 일관성 보장 + +현재 프로젝트가 잘 동작하고 있다면, 점진적 마이그레이션을 통해 리스크를 최소화하면서 아키텍처를 개선할 수 있습니다. + +--- + +**작성일**: 2024-12-29 +**버전**: 1.0 diff --git a/docs/database-schema/mysql_create_tables-dev.sql b/docs/database-schema/mysql_create_tables-dev.sql index 460ca2d..db1ce27 100644 --- a/docs/database-schema/mysql_create_tables-dev.sql +++ b/docs/database-schema/mysql_create_tables-dev.sql @@ -1,82 +1,82 @@ --- input_history 테이블 -CREATE TABLE input_history ( - id INT AUTO_INCREMENT PRIMARY KEY, - customer_name VARCHAR(255) NOT NULL, - region VARCHAR(100) NOT NULL, - task_id CHAR(36) NOT NULL, - detail_region_info TEXT, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP -); - --- upload_img_url 테이블 -CREATE TABLE upload_img_url ( - id INT AUTO_INCREMENT PRIMARY KEY, - task_id CHAR(36) NOT NULL, - img_uid INT NOT NULL, - img_url VARCHAR(2048) NOT NULL, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - FOREIGN KEY (task_id) REFERENCES input_history(task_id) ON DELETE CASCADE -); - --- lyrics 테이블 -CREATE TABLE lyrics ( - id INT AUTO_INCREMENT PRIMARY KEY, - input_history_id INT NOT NULL, - task_id CHAR(36) NOT NULL, - status VARCHAR(50) NOT NULL, - lyrics_prompt TEXT NOT NULL, - lyrics_result LONGTEXT NOT NULL, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - FOREIGN KEY (input_history_id) REFERENCES input_history(id) ON DELETE CASCADE -); - --- song 테이블 -CREATE TABLE song ( - id INT AUTO_INCREMENT PRIMARY KEY, - input_history_id INT NOT NULL, - lyrics_id INT NOT NULL, - task_id CHAR(36) NOT NULL, - status VARCHAR(50) NOT NULL, - song_prompt TEXT NOT NULL, - song_result_url_1 VARCHAR(2048), - song_result_url_2 VARCHAR(2048), - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - FOREIGN KEY (input_history_id) REFERENCES input_history(id) ON DELETE CASCADE, - FOREIGN KEY (lyrics_id) REFERENCES lyrics(id) ON DELETE CASCADE -); - --- creatomate_result_url 테이블 -CREATE TABLE creatomate_result_url ( - id INT AUTO_INCREMENT PRIMARY KEY, - input_history_id INT NOT NULL, - song_id INT NOT NULL, - task_id CHAR(36) NOT NULL, - status VARCHAR(50) NOT NULL, - result_movie_url VARCHAR(2048), - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - FOREIGN KEY (input_history_id) REFERENCES input_history(id) ON DELETE CASCADE, - FOREIGN KEY (song_id) REFERENCES song(id) ON DELETE CASCADE -); - --- ===== 인덱스 추가 (쿼리 성능 최적화) ===== - --- input_history -CREATE INDEX idx_input_history_task_id ON input_history(task_id); - --- upload_img_url (task_id 인덱스 + 복합 인덱스) -CREATE INDEX idx_upload_img_url_task_id ON upload_img_url(task_id); -CREATE INDEX idx_upload_img_url_task_id_img_uid ON upload_img_url(task_id, img_uid); - --- lyrics (input_history_id + task_id 인덱스) -CREATE INDEX idx_lyrics_input_history_id ON lyrics(input_history_id); -CREATE INDEX idx_lyrics_task_id ON lyrics(task_id); - --- song (input_history_id + lyrics_id + task_id 인덱스) -CREATE INDEX idx_song_input_history_id ON song(input_history_id); -CREATE INDEX idx_song_lyrics_id ON song(lyrics_id); -CREATE INDEX idx_song_task_id ON song(task_id); - --- creatomate_result_url (input_history_id + song_id + task_id 인덱스) -CREATE INDEX idx_creatomate_input_history_id ON creatomate_result_url(input_history_id); -CREATE INDEX idx_creatomate_song_id ON creatomate_result_url(song_id); +-- input_history 테이블 +CREATE TABLE input_history ( + id INT AUTO_INCREMENT PRIMARY KEY, + customer_name VARCHAR(255) NOT NULL, + region VARCHAR(100) NOT NULL, + task_id CHAR(36) NOT NULL, + detail_region_info TEXT, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); + +-- upload_img_url 테이블 +CREATE TABLE upload_img_url ( + id INT AUTO_INCREMENT PRIMARY KEY, + task_id CHAR(36) NOT NULL, + img_uid INT NOT NULL, + img_url VARCHAR(2048) NOT NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (task_id) REFERENCES input_history(task_id) ON DELETE CASCADE +); + +-- lyrics 테이블 +CREATE TABLE lyrics ( + id INT AUTO_INCREMENT PRIMARY KEY, + input_history_id INT NOT NULL, + task_id CHAR(36) NOT NULL, + status VARCHAR(50) NOT NULL, + lyrics_prompt TEXT NOT NULL, + lyrics_result LONGTEXT NOT NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (input_history_id) REFERENCES input_history(id) ON DELETE CASCADE +); + +-- song 테이블 +CREATE TABLE song ( + id INT AUTO_INCREMENT PRIMARY KEY, + input_history_id INT NOT NULL, + lyrics_id INT NOT NULL, + task_id CHAR(36) NOT NULL, + status VARCHAR(50) NOT NULL, + song_prompt TEXT NOT NULL, + song_result_url_1 VARCHAR(2048), + song_result_url_2 VARCHAR(2048), + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (input_history_id) REFERENCES input_history(id) ON DELETE CASCADE, + FOREIGN KEY (lyrics_id) REFERENCES lyrics(id) ON DELETE CASCADE +); + +-- creatomate_result_url 테이블 +CREATE TABLE creatomate_result_url ( + id INT AUTO_INCREMENT PRIMARY KEY, + input_history_id INT NOT NULL, + song_id INT NOT NULL, + task_id CHAR(36) NOT NULL, + status VARCHAR(50) NOT NULL, + result_movie_url VARCHAR(2048), + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (input_history_id) REFERENCES input_history(id) ON DELETE CASCADE, + FOREIGN KEY (song_id) REFERENCES song(id) ON DELETE CASCADE +); + +-- ===== 인덱스 추가 (쿼리 성능 최적화) ===== + +-- input_history +CREATE INDEX idx_input_history_task_id ON input_history(task_id); + +-- upload_img_url (task_id 인덱스 + 복합 인덱스) +CREATE INDEX idx_upload_img_url_task_id ON upload_img_url(task_id); +CREATE INDEX idx_upload_img_url_task_id_img_uid ON upload_img_url(task_id, img_uid); + +-- lyrics (input_history_id + task_id 인덱스) +CREATE INDEX idx_lyrics_input_history_id ON lyrics(input_history_id); +CREATE INDEX idx_lyrics_task_id ON lyrics(task_id); + +-- song (input_history_id + lyrics_id + task_id 인덱스) +CREATE INDEX idx_song_input_history_id ON song(input_history_id); +CREATE INDEX idx_song_lyrics_id ON song(lyrics_id); +CREATE INDEX idx_song_task_id ON song(task_id); + +-- creatomate_result_url (input_history_id + song_id + task_id 인덱스) +CREATE INDEX idx_creatomate_input_history_id ON creatomate_result_url(input_history_id); +CREATE INDEX idx_creatomate_song_id ON creatomate_result_url(song_id); CREATE INDEX idx_creatomate_task_id ON creatomate_result_url(task_id); \ No newline at end of file diff --git a/docs/database-schema/mysql_create_tables.sql b/docs/database-schema/mysql_create_tables.sql index 564f3bf..301ac89 100644 --- a/docs/database-schema/mysql_create_tables.sql +++ b/docs/database-schema/mysql_create_tables.sql @@ -1,83 +1,83 @@ --- input_history 테이블 -CREATE TABLE input_history ( - id INT AUTO_INCREMENT PRIMARY KEY, - customer_name VARCHAR(255) NOT NULL, - region VARCHAR(100) NOT NULL, - task_id CHAR(36) NOT NULL UNIQUE, -- 유니크 UUID - detail_region_info TEXT, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP -); - --- upload_img_url 테이블 -CREATE TABLE upload_img_url ( - id INT AUTO_INCREMENT PRIMARY KEY, - task_id CHAR(36) NOT NULL, -- input_history와 연결 - img_uid INT NOT NULL, - img_url VARCHAR(2048) NOT NULL, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - UNIQUE KEY unique_img_task_image (task_id, img_uid), - FOREIGN KEY (task_id) REFERENCES input_history(task_id) ON DELETE CASCADE -); - --- lyrics 테이블 -CREATE TABLE lyrics ( - id INT AUTO_INCREMENT PRIMARY KEY, - input_history_id INT NOT NULL, - task_id CHAR(36) NOT NULL UNIQUE, - status VARCHAR(50) NOT NULL, - lyrics_prompt TEXT NOT NULL, - lyrics_result LONGTEXT NOT NULL, - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - FOREIGN KEY (input_history_id) REFERENCES input_history(id) ON DELETE CASCADE -); - --- song 테이블 -CREATE TABLE song ( - id INT AUTO_INCREMENT PRIMARY KEY, - input_history_id INT NOT NULL, - lyrics_id INT NOT NULL, - task_id CHAR(36) NOT NULL UNIQUE, - status VARCHAR(50) NOT NULL, - song_prompt TEXT NOT NULL, - song_result_url_1 VARCHAR(2048), - song_result_url_2 VARCHAR(2048), - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - FOREIGN KEY (input_history_id) REFERENCES input_history(id) ON DELETE CASCADE, - FOREIGN KEY (lyrics_id) REFERENCES lyrics(id) ON DELETE CASCADE -); - --- creatomate_result_url 테이블 -CREATE TABLE creatomate_result_url ( - id INT AUTO_INCREMENT PRIMARY KEY, - input_history_id INT NOT NULL, - song_id INT NOT NULL, - task_id CHAR(36) NOT NULL UNIQUE, - status VARCHAR(50) NOT NULL, - result_movie_url VARCHAR(2048), - created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, - FOREIGN KEY (input_history_id) REFERENCES input_history(id) ON DELETE CASCADE, - FOREIGN KEY (song_id) REFERENCES song(id) ON DELETE CASCADE -); - --- ===== 인덱스 추가 (쿼리 성능 최적화) ===== - --- input_history -CREATE INDEX idx_input_history_task_id ON input_history(task_id); - --- upload_img_url (task_id 인덱스 + 복합 인덱스) -CREATE INDEX idx_upload_img_url_task_id ON upload_img_url(task_id); -CREATE INDEX idx_upload_img_url_task_id_img_uid ON upload_img_url(task_id, img_uid); - --- lyrics (input_history_id + task_id 인덱스) -CREATE INDEX idx_lyrics_input_history_id ON lyrics(input_history_id); -CREATE INDEX idx_lyrics_task_id ON lyrics(task_id); - --- song (input_history_id + lyrics_id + task_id 인덱스) -CREATE INDEX idx_song_input_history_id ON song(input_history_id); -CREATE INDEX idx_song_lyrics_id ON song(lyrics_id); -CREATE INDEX idx_song_task_id ON song(task_id); - --- creatomate_result_url (input_history_id + song_id + task_id 인덱스) -CREATE INDEX idx_creatomate_input_history_id ON creatomate_result_url(input_history_id); -CREATE INDEX idx_creatomate_song_id ON creatomate_result_url(song_id); +-- input_history 테이블 +CREATE TABLE input_history ( + id INT AUTO_INCREMENT PRIMARY KEY, + customer_name VARCHAR(255) NOT NULL, + region VARCHAR(100) NOT NULL, + task_id CHAR(36) NOT NULL UNIQUE, -- 유니크 UUID + detail_region_info TEXT, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); + +-- upload_img_url 테이블 +CREATE TABLE upload_img_url ( + id INT AUTO_INCREMENT PRIMARY KEY, + task_id CHAR(36) NOT NULL, -- input_history와 연결 + img_uid INT NOT NULL, + img_url VARCHAR(2048) NOT NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + UNIQUE KEY unique_img_task_image (task_id, img_uid), + FOREIGN KEY (task_id) REFERENCES input_history(task_id) ON DELETE CASCADE +); + +-- lyrics 테이블 +CREATE TABLE lyrics ( + id INT AUTO_INCREMENT PRIMARY KEY, + input_history_id INT NOT NULL, + task_id CHAR(36) NOT NULL UNIQUE, + status VARCHAR(50) NOT NULL, + lyrics_prompt TEXT NOT NULL, + lyrics_result LONGTEXT NOT NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (input_history_id) REFERENCES input_history(id) ON DELETE CASCADE +); + +-- song 테이블 +CREATE TABLE song ( + id INT AUTO_INCREMENT PRIMARY KEY, + input_history_id INT NOT NULL, + lyrics_id INT NOT NULL, + task_id CHAR(36) NOT NULL UNIQUE, + status VARCHAR(50) NOT NULL, + song_prompt TEXT NOT NULL, + song_result_url_1 VARCHAR(2048), + song_result_url_2 VARCHAR(2048), + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (input_history_id) REFERENCES input_history(id) ON DELETE CASCADE, + FOREIGN KEY (lyrics_id) REFERENCES lyrics(id) ON DELETE CASCADE +); + +-- creatomate_result_url 테이블 +CREATE TABLE creatomate_result_url ( + id INT AUTO_INCREMENT PRIMARY KEY, + input_history_id INT NOT NULL, + song_id INT NOT NULL, + task_id CHAR(36) NOT NULL UNIQUE, + status VARCHAR(50) NOT NULL, + result_movie_url VARCHAR(2048), + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (input_history_id) REFERENCES input_history(id) ON DELETE CASCADE, + FOREIGN KEY (song_id) REFERENCES song(id) ON DELETE CASCADE +); + +-- ===== 인덱스 추가 (쿼리 성능 최적화) ===== + +-- input_history +CREATE INDEX idx_input_history_task_id ON input_history(task_id); + +-- upload_img_url (task_id 인덱스 + 복합 인덱스) +CREATE INDEX idx_upload_img_url_task_id ON upload_img_url(task_id); +CREATE INDEX idx_upload_img_url_task_id_img_uid ON upload_img_url(task_id, img_uid); + +-- lyrics (input_history_id + task_id 인덱스) +CREATE INDEX idx_lyrics_input_history_id ON lyrics(input_history_id); +CREATE INDEX idx_lyrics_task_id ON lyrics(task_id); + +-- song (input_history_id + lyrics_id + task_id 인덱스) +CREATE INDEX idx_song_input_history_id ON song(input_history_id); +CREATE INDEX idx_song_lyrics_id ON song(lyrics_id); +CREATE INDEX idx_song_task_id ON song(task_id); + +-- creatomate_result_url (input_history_id + song_id + task_id 인덱스) +CREATE INDEX idx_creatomate_input_history_id ON creatomate_result_url(input_history_id); +CREATE INDEX idx_creatomate_song_id ON creatomate_result_url(song_id); CREATE INDEX idx_creatomate_task_id ON creatomate_result_url(task_id); \ No newline at end of file diff --git a/docs/reference/ConfigDict.md b/docs/reference/ConfigDict.md index 2ad9af7..b96ac9d 100644 --- a/docs/reference/ConfigDict.md +++ b/docs/reference/ConfigDict.md @@ -1,382 +1,382 @@ -# Pydantic ConfigDict 사용 매뉴얼 - -## 개요 - -Pydantic v2에서 `ConfigDict`는 모델의 유효성 검사, 직렬화, JSON 스키마 생성 등의 동작을 제어하는 설정을 정의하는 TypedDict입니다. - -> Pydantic v1의 `class Config`는 더 이상 권장되지 않으며, `ConfigDict`를 사용해야 합니다. - -## 기본 사용법 - -```python -from pydantic import BaseModel, ConfigDict - -class MyModel(BaseModel): - model_config = ConfigDict( - str_strip_whitespace=True, - strict=True - ) - - name: str - age: int -``` - -## 설정 옵션 전체 목록 - -### 문자열 처리 - -| 옵션 | 타입 | 기본값 | 설명 | -|------|------|--------|------| -| `str_to_lower` | `bool` | `False` | 문자열을 소문자로 변환 | -| `str_to_upper` | `bool` | `False` | 문자열을 대문자로 변환 | -| `str_strip_whitespace` | `bool` | `False` | 문자열 앞뒤 공백 제거 | -| `str_min_length` | `int \| None` | `None` | 문자열 최소 길이 | -| `str_max_length` | `int \| None` | `None` | 문자열 최대 길이 | - -**예시:** -```python -class UserInput(BaseModel): - model_config = ConfigDict( - str_strip_whitespace=True, - str_to_lower=True, - str_min_length=1, - str_max_length=100 - ) - - username: str - -user = UserInput(username=" HELLO ") -print(user.username) # "hello" -``` - -### 유효성 검사 - -| 옵션 | 타입 | 기본값 | 설명 | -|------|------|--------|------| -| `strict` | `bool` | `False` | 엄격한 타입 검사 활성화 (타입 강제 변환 비활성화) | -| `validate_assignment` | `bool` | `False` | 속성 할당 시 유효성 검사 수행 | -| `validate_default` | `bool` | `False` | 기본값도 유효성 검사 수행 | -| `validate_return` | `bool` | `False` | 반환값 유효성 검사 | -| `revalidate_instances` | `Literal['always', 'never', 'subclass-instances']` | `'never'` | 모델 인스턴스 재검증 시점 | -| `arbitrary_types_allowed` | `bool` | `False` | Pydantic이 지원하지 않는 타입 허용 | - -**예시 - strict 모드:** -```python -class StrictModel(BaseModel): - model_config = ConfigDict(strict=True) - - count: int - -# strict=False (기본값): "123" -> 123 자동 변환 -# strict=True: "123" 입력 시 ValidationError 발생 -``` - -**예시 - validate_assignment:** -```python -class User(BaseModel): - model_config = ConfigDict(validate_assignment=True) - - age: int - -user = User(age=25) -user.age = "invalid" # ValidationError 발생 -``` - -### Extra 필드 처리 - -| 옵션 | 타입 | 기본값 | 설명 | -|------|------|--------|------| -| `extra` | `'allow' \| 'ignore' \| 'forbid'` | `'ignore'` | 추가 필드 처리 방식 | - -**값 설명:** -- `'ignore'`: 추가 필드 무시 (기본값) -- `'allow'`: 추가 필드 허용, `__pydantic_extra__`에 저장 -- `'forbid'`: 추가 필드 입력 시 에러 발생 - -**예시:** -```python -class AllowExtra(BaseModel): - model_config = ConfigDict(extra='allow') - - name: str - -data = AllowExtra(name="John", unknown_field="value") -print(data.__pydantic_extra__) # {'unknown_field': 'value'} - -class ForbidExtra(BaseModel): - model_config = ConfigDict(extra='forbid') - - name: str - -ForbidExtra(name="John", unknown="value") # ValidationError 발생 -``` - -### 불변성 (Immutability) - -| 옵션 | 타입 | 기본값 | 설명 | -|------|------|--------|------| -| `frozen` | `bool` | `False` | 모델을 불변(immutable)으로 만듦, `__hash__()` 구현 | - -**예시:** -```python -class ImmutableUser(BaseModel): - model_config = ConfigDict(frozen=True) - - name: str - age: int - -user = ImmutableUser(name="John", age=30) -user.age = 31 # 에러 발생: Instance is frozen - -# frozen=True이면 해시 가능 -users_set = {user} # 정상 작동 -``` - -### 별칭 (Alias) 설정 - -| 옵션 | 타입 | 기본값 | 설명 | -|------|------|--------|------| -| `populate_by_name` | `bool` | `False` | 필드명과 별칭 모두로 값 설정 허용 (deprecated) | -| `validate_by_alias` | `bool` | `True` | 별칭으로 필드 값 설정 허용 | -| `validate_by_name` | `bool` | `False` | 별칭이 있어도 필드명으로 값 설정 허용 | -| `serialize_by_alias` | `bool` | `False` | 직렬화 시 별칭 사용 | -| `alias_generator` | `Callable[[str], str] \| None` | `None` | 별칭 자동 생성 함수 | -| `loc_by_alias` | `bool` | `True` | 에러 위치에 별칭 사용 | - -**예시:** -```python -from pydantic import Field - -class APIResponse(BaseModel): - model_config = ConfigDict( - validate_by_alias=True, - validate_by_name=True, - serialize_by_alias=True - ) - - user_name: str = Field(alias="userName") - -# 둘 다 가능 -response1 = APIResponse(userName="John") -response2 = APIResponse(user_name="John") - -print(response1.model_dump(by_alias=True)) # {"userName": "John"} -``` - -**예시 - alias_generator:** -```python -def to_camel(name: str) -> str: - parts = name.split('_') - return parts[0] + ''.join(word.capitalize() for word in parts[1:]) - -class CamelModel(BaseModel): - model_config = ConfigDict( - alias_generator=to_camel, - serialize_by_alias=True - ) - - first_name: str - last_name: str - -data = CamelModel(firstName="John", lastName="Doe") -print(data.model_dump(by_alias=True)) -# {"firstName": "John", "lastName": "Doe"} -``` - -### JSON 스키마 - -| 옵션 | 타입 | 기본값 | 설명 | -|------|------|--------|------| -| `title` | `str \| None` | `None` | JSON 스키마 타이틀 | -| `json_schema_extra` | `dict \| Callable \| None` | `None` | JSON 스키마에 추가할 정보 | -| `json_schema_serialization_defaults_required` | `bool` | `False` | 직렬화 스키마에서 기본값이 있는 필드도 required로 표시 | -| `json_schema_mode_override` | `Literal['validation', 'serialization', None]` | `None` | JSON 스키마 모드 강제 지정 | - -**예시 - json_schema_extra:** -```python -class Product(BaseModel): - model_config = ConfigDict( - title="상품 정보", - json_schema_extra={ - "example": { - "name": "노트북", - "price": 1500000 - }, - "description": "상품 데이터를 나타내는 모델" - } - ) - - name: str - price: int - -# OpenAPI/Swagger 문서에 예시가 표시됨 -``` - -**예시 - Callable json_schema_extra:** -```python -def add_examples(schema: dict) -> dict: - schema["examples"] = [ - {"name": "예시1", "value": 100}, - {"name": "예시2", "value": 200} - ] - return schema - -class DynamicSchema(BaseModel): - model_config = ConfigDict(json_schema_extra=add_examples) - - name: str - value: int -``` - -### ORM/속성 모드 - -| 옵션 | 타입 | 기본값 | 설명 | -|------|------|--------|------| -| `from_attributes` | `bool` | `False` | 객체 속성에서 모델 생성 허용 (SQLAlchemy 등) | - -**예시:** -```python -class UserORM: - def __init__(self, name: str, age: int): - self.name = name - self.age = age - -class UserModel(BaseModel): - model_config = ConfigDict(from_attributes=True) - - name: str - age: int - -orm_user = UserORM(name="John", age=30) -pydantic_user = UserModel.model_validate(orm_user) -print(pydantic_user) # name='John' age=30 -``` - -### Enum 처리 - -| 옵션 | 타입 | 기본값 | 설명 | -|------|------|--------|------| -| `use_enum_values` | `bool` | `False` | Enum 대신 값(value)으로 저장 | - -**예시:** -```python -from enum import Enum - -class Status(Enum): - ACTIVE = "active" - INACTIVE = "inactive" - -class User(BaseModel): - model_config = ConfigDict(use_enum_values=True) - - status: Status - -user = User(status=Status.ACTIVE) -print(user.status) # "active" (문자열) -print(type(user.status)) # - -# use_enum_values=False (기본값)이면 -# user.status는 Status.ACTIVE (Enum 객체) -``` - -### 직렬화 설정 - -| 옵션 | 타입 | 기본값 | 설명 | -|------|------|--------|------| -| `ser_json_timedelta` | `'iso8601' \| 'float'` | `'iso8601'` | timedelta JSON 직렬화 형식 | -| `ser_json_bytes` | `'utf8' \| 'base64' \| 'hex'` | `'utf8'` | bytes JSON 직렬화 인코딩 | -| `ser_json_inf_nan` | `'null' \| 'constants' \| 'strings'` | `'null'` | 무한대/NaN JSON 직렬화 형식 | - -### 숫자/Float 설정 - -| 옵션 | 타입 | 기본값 | 설명 | -|------|------|--------|------| -| `allow_inf_nan` | `bool` | `True` | float에서 무한대/NaN 허용 | -| `coerce_numbers_to_str` | `bool` | `False` | 숫자를 문자열로 강제 변환 허용 | - -### 기타 설정 - -| 옵션 | 타입 | 기본값 | 설명 | -|------|------|--------|------| -| `protected_namespaces` | `tuple[str, ...]` | `('model_',)` | 보호할 필드명 접두사 | -| `hide_input_in_errors` | `bool` | `False` | 에러 메시지에서 입력값 숨김 | -| `defer_build` | `bool` | `False` | validator/serializer 빌드 지연 | -| `use_attribute_docstrings` | `bool` | `False` | 속성 docstring을 필드 설명으로 사용 | -| `regex_engine` | `'rust-regex' \| 'python-re'` | `'rust-regex'` | 정규식 엔진 선택 | -| `validation_error_cause` | `bool` | `False` | Python 예외를 에러 원인에 포함 | - -## 설정 상속 - -자식 모델은 부모 모델의 `model_config`를 상속받습니다. - -```python -class ParentModel(BaseModel): - model_config = ConfigDict( - str_strip_whitespace=True, - extra='allow' - ) - - name: str - -class ChildModel(ParentModel): - model_config = ConfigDict( - frozen=True # 부모 설정 + frozen=True - ) - - age: int - -# ChildModel은 str_strip_whitespace=True, extra='allow', frozen=True -``` - -## FastAPI와 함께 사용 - -FastAPI에서 요청/응답 스키마로 사용할 때 특히 유용합니다. - -```python -from fastapi import FastAPI -from pydantic import BaseModel, ConfigDict, Field - -app = FastAPI() - -class CreateUserRequest(BaseModel): - model_config = ConfigDict( - str_strip_whitespace=True, - json_schema_extra={ - "example": { - "username": "johndoe", - "email": "john@example.com" - } - } - ) - - username: str = Field(..., min_length=3, max_length=50) - email: str - -class UserResponse(BaseModel): - model_config = ConfigDict( - from_attributes=True, # ORM 객체에서 변환 가능 - serialize_by_alias=True - ) - - id: int - user_name: str = Field(alias="userName") - -@app.post("/users", response_model=UserResponse) -async def create_user(user: CreateUserRequest): - # user.username은 자동으로 공백이 제거됨 - ... -``` - -## 주의사항 - -1. **v1에서 마이그레이션**: `class Config`는 deprecated입니다. `model_config = ConfigDict(...)`를 사용하세요. - -2. **populate_by_name은 deprecated**: `validate_by_alias`와 `validate_by_name`을 함께 사용하세요. - -3. **json_encoders는 deprecated**: 커스텀 직렬화가 필요하면 `@field_serializer` 데코레이터를 사용하세요. - -## 참고 자료 - -- [Pydantic Configuration API 공식 문서](https://docs.pydantic.dev/latest/api/config/) -- [Pydantic Models 개념](https://docs.pydantic.dev/latest/concepts/models/) -- [Pydantic Migration Guide](https://docs.pydantic.dev/latest/migration/) +# Pydantic ConfigDict 사용 매뉴얼 + +## 개요 + +Pydantic v2에서 `ConfigDict`는 모델의 유효성 검사, 직렬화, JSON 스키마 생성 등의 동작을 제어하는 설정을 정의하는 TypedDict입니다. + +> Pydantic v1의 `class Config`는 더 이상 권장되지 않으며, `ConfigDict`를 사용해야 합니다. + +## 기본 사용법 + +```python +from pydantic import BaseModel, ConfigDict + +class MyModel(BaseModel): + model_config = ConfigDict( + str_strip_whitespace=True, + strict=True + ) + + name: str + age: int +``` + +## 설정 옵션 전체 목록 + +### 문자열 처리 + +| 옵션 | 타입 | 기본값 | 설명 | +|------|------|--------|------| +| `str_to_lower` | `bool` | `False` | 문자열을 소문자로 변환 | +| `str_to_upper` | `bool` | `False` | 문자열을 대문자로 변환 | +| `str_strip_whitespace` | `bool` | `False` | 문자열 앞뒤 공백 제거 | +| `str_min_length` | `int \| None` | `None` | 문자열 최소 길이 | +| `str_max_length` | `int \| None` | `None` | 문자열 최대 길이 | + +**예시:** +```python +class UserInput(BaseModel): + model_config = ConfigDict( + str_strip_whitespace=True, + str_to_lower=True, + str_min_length=1, + str_max_length=100 + ) + + username: str + +user = UserInput(username=" HELLO ") +print(user.username) # "hello" +``` + +### 유효성 검사 + +| 옵션 | 타입 | 기본값 | 설명 | +|------|------|--------|------| +| `strict` | `bool` | `False` | 엄격한 타입 검사 활성화 (타입 강제 변환 비활성화) | +| `validate_assignment` | `bool` | `False` | 속성 할당 시 유효성 검사 수행 | +| `validate_default` | `bool` | `False` | 기본값도 유효성 검사 수행 | +| `validate_return` | `bool` | `False` | 반환값 유효성 검사 | +| `revalidate_instances` | `Literal['always', 'never', 'subclass-instances']` | `'never'` | 모델 인스턴스 재검증 시점 | +| `arbitrary_types_allowed` | `bool` | `False` | Pydantic이 지원하지 않는 타입 허용 | + +**예시 - strict 모드:** +```python +class StrictModel(BaseModel): + model_config = ConfigDict(strict=True) + + count: int + +# strict=False (기본값): "123" -> 123 자동 변환 +# strict=True: "123" 입력 시 ValidationError 발생 +``` + +**예시 - validate_assignment:** +```python +class User(BaseModel): + model_config = ConfigDict(validate_assignment=True) + + age: int + +user = User(age=25) +user.age = "invalid" # ValidationError 발생 +``` + +### Extra 필드 처리 + +| 옵션 | 타입 | 기본값 | 설명 | +|------|------|--------|------| +| `extra` | `'allow' \| 'ignore' \| 'forbid'` | `'ignore'` | 추가 필드 처리 방식 | + +**값 설명:** +- `'ignore'`: 추가 필드 무시 (기본값) +- `'allow'`: 추가 필드 허용, `__pydantic_extra__`에 저장 +- `'forbid'`: 추가 필드 입력 시 에러 발생 + +**예시:** +```python +class AllowExtra(BaseModel): + model_config = ConfigDict(extra='allow') + + name: str + +data = AllowExtra(name="John", unknown_field="value") +print(data.__pydantic_extra__) # {'unknown_field': 'value'} + +class ForbidExtra(BaseModel): + model_config = ConfigDict(extra='forbid') + + name: str + +ForbidExtra(name="John", unknown="value") # ValidationError 발생 +``` + +### 불변성 (Immutability) + +| 옵션 | 타입 | 기본값 | 설명 | +|------|------|--------|------| +| `frozen` | `bool` | `False` | 모델을 불변(immutable)으로 만듦, `__hash__()` 구현 | + +**예시:** +```python +class ImmutableUser(BaseModel): + model_config = ConfigDict(frozen=True) + + name: str + age: int + +user = ImmutableUser(name="John", age=30) +user.age = 31 # 에러 발생: Instance is frozen + +# frozen=True이면 해시 가능 +users_set = {user} # 정상 작동 +``` + +### 별칭 (Alias) 설정 + +| 옵션 | 타입 | 기본값 | 설명 | +|------|------|--------|------| +| `populate_by_name` | `bool` | `False` | 필드명과 별칭 모두로 값 설정 허용 (deprecated) | +| `validate_by_alias` | `bool` | `True` | 별칭으로 필드 값 설정 허용 | +| `validate_by_name` | `bool` | `False` | 별칭이 있어도 필드명으로 값 설정 허용 | +| `serialize_by_alias` | `bool` | `False` | 직렬화 시 별칭 사용 | +| `alias_generator` | `Callable[[str], str] \| None` | `None` | 별칭 자동 생성 함수 | +| `loc_by_alias` | `bool` | `True` | 에러 위치에 별칭 사용 | + +**예시:** +```python +from pydantic import Field + +class APIResponse(BaseModel): + model_config = ConfigDict( + validate_by_alias=True, + validate_by_name=True, + serialize_by_alias=True + ) + + user_name: str = Field(alias="userName") + +# 둘 다 가능 +response1 = APIResponse(userName="John") +response2 = APIResponse(user_name="John") + +print(response1.model_dump(by_alias=True)) # {"userName": "John"} +``` + +**예시 - alias_generator:** +```python +def to_camel(name: str) -> str: + parts = name.split('_') + return parts[0] + ''.join(word.capitalize() for word in parts[1:]) + +class CamelModel(BaseModel): + model_config = ConfigDict( + alias_generator=to_camel, + serialize_by_alias=True + ) + + first_name: str + last_name: str + +data = CamelModel(firstName="John", lastName="Doe") +print(data.model_dump(by_alias=True)) +# {"firstName": "John", "lastName": "Doe"} +``` + +### JSON 스키마 + +| 옵션 | 타입 | 기본값 | 설명 | +|------|------|--------|------| +| `title` | `str \| None` | `None` | JSON 스키마 타이틀 | +| `json_schema_extra` | `dict \| Callable \| None` | `None` | JSON 스키마에 추가할 정보 | +| `json_schema_serialization_defaults_required` | `bool` | `False` | 직렬화 스키마에서 기본값이 있는 필드도 required로 표시 | +| `json_schema_mode_override` | `Literal['validation', 'serialization', None]` | `None` | JSON 스키마 모드 강제 지정 | + +**예시 - json_schema_extra:** +```python +class Product(BaseModel): + model_config = ConfigDict( + title="상품 정보", + json_schema_extra={ + "example": { + "name": "노트북", + "price": 1500000 + }, + "description": "상품 데이터를 나타내는 모델" + } + ) + + name: str + price: int + +# OpenAPI/Swagger 문서에 예시가 표시됨 +``` + +**예시 - Callable json_schema_extra:** +```python +def add_examples(schema: dict) -> dict: + schema["examples"] = [ + {"name": "예시1", "value": 100}, + {"name": "예시2", "value": 200} + ] + return schema + +class DynamicSchema(BaseModel): + model_config = ConfigDict(json_schema_extra=add_examples) + + name: str + value: int +``` + +### ORM/속성 모드 + +| 옵션 | 타입 | 기본값 | 설명 | +|------|------|--------|------| +| `from_attributes` | `bool` | `False` | 객체 속성에서 모델 생성 허용 (SQLAlchemy 등) | + +**예시:** +```python +class UserORM: + def __init__(self, name: str, age: int): + self.name = name + self.age = age + +class UserModel(BaseModel): + model_config = ConfigDict(from_attributes=True) + + name: str + age: int + +orm_user = UserORM(name="John", age=30) +pydantic_user = UserModel.model_validate(orm_user) +print(pydantic_user) # name='John' age=30 +``` + +### Enum 처리 + +| 옵션 | 타입 | 기본값 | 설명 | +|------|------|--------|------| +| `use_enum_values` | `bool` | `False` | Enum 대신 값(value)으로 저장 | + +**예시:** +```python +from enum import Enum + +class Status(Enum): + ACTIVE = "active" + INACTIVE = "inactive" + +class User(BaseModel): + model_config = ConfigDict(use_enum_values=True) + + status: Status + +user = User(status=Status.ACTIVE) +print(user.status) # "active" (문자열) +print(type(user.status)) # + +# use_enum_values=False (기본값)이면 +# user.status는 Status.ACTIVE (Enum 객체) +``` + +### 직렬화 설정 + +| 옵션 | 타입 | 기본값 | 설명 | +|------|------|--------|------| +| `ser_json_timedelta` | `'iso8601' \| 'float'` | `'iso8601'` | timedelta JSON 직렬화 형식 | +| `ser_json_bytes` | `'utf8' \| 'base64' \| 'hex'` | `'utf8'` | bytes JSON 직렬화 인코딩 | +| `ser_json_inf_nan` | `'null' \| 'constants' \| 'strings'` | `'null'` | 무한대/NaN JSON 직렬화 형식 | + +### 숫자/Float 설정 + +| 옵션 | 타입 | 기본값 | 설명 | +|------|------|--------|------| +| `allow_inf_nan` | `bool` | `True` | float에서 무한대/NaN 허용 | +| `coerce_numbers_to_str` | `bool` | `False` | 숫자를 문자열로 강제 변환 허용 | + +### 기타 설정 + +| 옵션 | 타입 | 기본값 | 설명 | +|------|------|--------|------| +| `protected_namespaces` | `tuple[str, ...]` | `('model_',)` | 보호할 필드명 접두사 | +| `hide_input_in_errors` | `bool` | `False` | 에러 메시지에서 입력값 숨김 | +| `defer_build` | `bool` | `False` | validator/serializer 빌드 지연 | +| `use_attribute_docstrings` | `bool` | `False` | 속성 docstring을 필드 설명으로 사용 | +| `regex_engine` | `'rust-regex' \| 'python-re'` | `'rust-regex'` | 정규식 엔진 선택 | +| `validation_error_cause` | `bool` | `False` | Python 예외를 에러 원인에 포함 | + +## 설정 상속 + +자식 모델은 부모 모델의 `model_config`를 상속받습니다. + +```python +class ParentModel(BaseModel): + model_config = ConfigDict( + str_strip_whitespace=True, + extra='allow' + ) + + name: str + +class ChildModel(ParentModel): + model_config = ConfigDict( + frozen=True # 부모 설정 + frozen=True + ) + + age: int + +# ChildModel은 str_strip_whitespace=True, extra='allow', frozen=True +``` + +## FastAPI와 함께 사용 + +FastAPI에서 요청/응답 스키마로 사용할 때 특히 유용합니다. + +```python +from fastapi import FastAPI +from pydantic import BaseModel, ConfigDict, Field + +app = FastAPI() + +class CreateUserRequest(BaseModel): + model_config = ConfigDict( + str_strip_whitespace=True, + json_schema_extra={ + "example": { + "username": "johndoe", + "email": "john@example.com" + } + } + ) + + username: str = Field(..., min_length=3, max_length=50) + email: str + +class UserResponse(BaseModel): + model_config = ConfigDict( + from_attributes=True, # ORM 객체에서 변환 가능 + serialize_by_alias=True + ) + + id: int + user_name: str = Field(alias="userName") + +@app.post("/users", response_model=UserResponse) +async def create_user(user: CreateUserRequest): + # user.username은 자동으로 공백이 제거됨 + ... +``` + +## 주의사항 + +1. **v1에서 마이그레이션**: `class Config`는 deprecated입니다. `model_config = ConfigDict(...)`를 사용하세요. + +2. **populate_by_name은 deprecated**: `validate_by_alias`와 `validate_by_name`을 함께 사용하세요. + +3. **json_encoders는 deprecated**: 커스텀 직렬화가 필요하면 `@field_serializer` 데코레이터를 사용하세요. + +## 참고 자료 + +- [Pydantic Configuration API 공식 문서](https://docs.pydantic.dev/latest/api/config/) +- [Pydantic Models 개념](https://docs.pydantic.dev/latest/concepts/models/) +- [Pydantic Migration Guide](https://docs.pydantic.dev/latest/migration/) diff --git a/docs/reference/fastapi_sqlalchemy_guide.md b/docs/reference/fastapi_sqlalchemy_guide.md index 511a324..e4c1fb6 100644 --- a/docs/reference/fastapi_sqlalchemy_guide.md +++ b/docs/reference/fastapi_sqlalchemy_guide.md @@ -1,2965 +1,2965 @@ -# FastAPI + SQLAlchemy ORM 완벽 실무 가이드 - -> SQLAlchemy 2.0+ / FastAPI 0.100+ / Python 3.10+ 기준 - ---- - -## 목차 - -1. [기본 설정](#1-기본-설정) -2. [모델 정의](#2-모델-정의) -3. [CRUD 기본 작업](#3-crud-기본-작업) -4. [조회 쿼리 심화](#4-조회-쿼리-심화) -5. [필터링과 조건](#5-필터링과-조건) -6. [정렬, 페이징, 제한](#6-정렬-페이징-제한) -7. [집계 함수 (Aggregation)](#7-집계-함수-aggregation) -8. [JOIN 쿼리](#8-join-쿼리) -9. [서브쿼리 (Subquery)](#9-서브쿼리-subquery) -10. [집합 연산 (Union, Intersect, Except)](#10-집합-연산-union-intersect-except) -11. [고급 표현식](#11-고급-표현식) -12. [Relationship과 Eager Loading](#12-relationship과-eager-loading) -13. [트랜잭션 관리](#13-트랜잭션-관리) -14. [FastAPI 통합 패턴](#14-fastapi-통합-패턴) -15. [성능 최적화](#15-성능-최적화) -16. [실무 레시피](#16-실무-레시피) - ---- - -## 1. 기본 설정 - -### 1.1 프로젝트 구조 - -``` -project/ -├── app/ -│ ├── __init__.py -│ ├── main.py -│ ├── config.py -│ ├── database.py -│ ├── models/ -│ │ ├── __init__.py -│ │ ├── base.py -│ │ ├── user.py -│ │ └── product.py -│ ├── schemas/ -│ │ ├── __init__.py -│ │ ├── user.py -│ │ └── product.py -│ ├── repositories/ -│ │ ├── __init__.py -│ │ └── user.py -│ ├── services/ -│ │ ├── __init__.py -│ │ └── user.py -│ └── routers/ -│ ├── __init__.py -│ └── user.py -├── alembic/ -├── tests/ -├── alembic.ini -├── requirements.txt -└── .env -``` - -### 1.2 Database 설정 - -```python -# app/config.py -from pydantic_settings import BaseSettings -from functools import lru_cache - - -class Settings(BaseSettings): - DATABASE_URL: str = "mysql+pymysql://user:pass@localhost:3306/dbname" - DATABASE_ECHO: bool = False # SQL 로그 출력 - DATABASE_POOL_SIZE: int = 5 - DATABASE_MAX_OVERFLOW: int = 10 - - class Config: - env_file = ".env" - - -@lru_cache -def get_settings() -> Settings: - return Settings() -``` - -```python -# app/database.py -from sqlalchemy import create_engine -from sqlalchemy.orm import sessionmaker, Session -from typing import Generator - -from app.config import get_settings - -settings = get_settings() - -# Engine 생성 -engine = create_engine( - settings.DATABASE_URL, - echo=settings.DATABASE_ECHO, - pool_size=settings.DATABASE_POOL_SIZE, - max_overflow=settings.DATABASE_MAX_OVERFLOW, - pool_pre_ping=True, # 연결 유효성 검사 - pool_recycle=3600, # 1시간마다 연결 재생성 -) - -# Session Factory -SessionLocal = sessionmaker( - bind=engine, - autocommit=False, - autoflush=False, - expire_on_commit=False, # commit 후에도 객체 접근 가능 -) - - -# Dependency -def get_db() -> Generator[Session, None, None]: - db = SessionLocal() - try: - yield db - finally: - db.close() -``` - -### 1.3 Base 모델 정의 - -```python -# app/models/base.py -from datetime import datetime -from sqlalchemy import func -from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column - - -class Base(DeclarativeBase): - """모든 모델의 기본 클래스""" - pass - - -class TimestampMixin: - """생성/수정 시간 믹스인""" - created_at: Mapped[datetime] = mapped_column( - default=func.now(), - nullable=False, - ) - updated_at: Mapped[datetime] = mapped_column( - default=func.now(), - onupdate=func.now(), - nullable=False, - ) - - -class SoftDeleteMixin: - """소프트 삭제 믹스인""" - is_deleted: Mapped[bool] = mapped_column(default=False) - deleted_at: Mapped[datetime | None] = mapped_column(default=None) -``` - ---- - -## 2. 모델 정의 - -### 2.1 기본 모델 - -```python -# app/models/user.py -from typing import List, Optional -from sqlalchemy import String, Text, Boolean, Integer, ForeignKey, Index -from sqlalchemy.orm import Mapped, mapped_column, relationship - -from app.models.base import Base, TimestampMixin - - -class User(TimestampMixin, Base): - __tablename__ = "user" - - # Primary Key - id: Mapped[int] = mapped_column(primary_key=True) - - # 필수 필드 - email: Mapped[str] = mapped_column(String(255), unique=True, index=True) - username: Mapped[str] = mapped_column(String(50), unique=True) - hashed_password: Mapped[str] = mapped_column(String(255)) - - # 선택 필드 (nullable) - full_name: Mapped[Optional[str]] = mapped_column(String(100)) - bio: Mapped[Optional[str]] = mapped_column(Text) - - # 기본값이 있는 필드 - is_active: Mapped[bool] = mapped_column(default=True) - is_superuser: Mapped[bool] = mapped_column(default=False) - login_count: Mapped[int] = mapped_column(default=0) - - # Relationships - posts: Mapped[List["Post"]] = relationship( - "Post", - back_populates="author", - cascade="all, delete-orphan", - lazy="selectin", - ) - - profile: Mapped[Optional["Profile"]] = relationship( - "Profile", - back_populates="user", - uselist=False, - cascade="all, delete-orphan", - ) - - # 테이블 설정 - __table_args__ = ( - Index("idx_user_email_active", "email", "is_active"), - {"mysql_engine": "InnoDB", "mysql_charset": "utf8mb4"}, - ) - - def __repr__(self) -> str: - return f"" -``` - -### 2.2 관계가 있는 모델들 - -```python -# app/models/post.py -from typing import List, Optional -from sqlalchemy import String, Text, ForeignKey, Index -from sqlalchemy.orm import Mapped, mapped_column, relationship - -from app.models.base import Base, TimestampMixin - - -class Post(TimestampMixin, Base): - __tablename__ = "post" - - id: Mapped[int] = mapped_column(primary_key=True) - title: Mapped[str] = mapped_column(String(200)) - content: Mapped[str] = mapped_column(Text) - view_count: Mapped[int] = mapped_column(default=0) - is_published: Mapped[bool] = mapped_column(default=False) - - # Foreign Key - author_id: Mapped[int] = mapped_column( - ForeignKey("user.id", ondelete="CASCADE"), - index=True, - ) - category_id: Mapped[Optional[int]] = mapped_column( - ForeignKey("category.id", ondelete="SET NULL"), - nullable=True, - ) - - # Relationships - author: Mapped["User"] = relationship("User", back_populates="posts") - category: Mapped[Optional["Category"]] = relationship("Category", back_populates="posts") - comments: Mapped[List["Comment"]] = relationship( - "Comment", - back_populates="post", - cascade="all, delete-orphan", - order_by="Comment.created_at.desc()", - ) - - # N:M 관계 - tags: Mapped[List["Tag"]] = relationship( - "Tag", - secondary="post_tag", - back_populates="posts", - ) - - __table_args__ = ( - Index("idx_post_author_published", "author_id", "is_published"), - ) - - -class Category(Base): - __tablename__ = "category" - - id: Mapped[int] = mapped_column(primary_key=True) - name: Mapped[str] = mapped_column(String(50), unique=True) - description: Mapped[Optional[str]] = mapped_column(Text) - - posts: Mapped[List["Post"]] = relationship("Post", back_populates="category") - - -class Tag(Base): - __tablename__ = "tag" - - id: Mapped[int] = mapped_column(primary_key=True) - name: Mapped[str] = mapped_column(String(30), unique=True) - - posts: Mapped[List["Post"]] = relationship( - "Post", - secondary="post_tag", - back_populates="tags", - ) - - -# N:M 중간 테이블 -from sqlalchemy import Table, Column, Integer, ForeignKey -from app.models.base import Base - -post_tag = Table( - "post_tag", - Base.metadata, - Column("post_id", Integer, ForeignKey("post.id", ondelete="CASCADE"), primary_key=True), - Column("tag_id", Integer, ForeignKey("tag.id", ondelete="CASCADE"), primary_key=True), -) -``` - ---- - -## 3. CRUD 기본 작업 - -### 3.1 Create (생성) - -```python -from sqlalchemy import select -from sqlalchemy.orm import Session -from app.models.user import User - - -# ───────────────────────────────────────────────────── -# 단일 레코드 생성 -# ───────────────────────────────────────────────────── - -def create_user(db: Session, email: str, username: str, password: str) -> User: - user = User( - email=email, - username=username, - hashed_password=password, - ) - db.add(user) - db.commit() - db.refresh(user) # DB에서 생성된 값(id, created_at 등) 로드 - return user - - -# ───────────────────────────────────────────────────── -# 여러 레코드 한번에 생성 -# ───────────────────────────────────────────────────── - -def create_users_bulk(db: Session, users_data: list[dict]) -> list[User]: - users = [User(**data) for data in users_data] - db.add_all(users) - db.commit() - - # 각 객체 refresh - for user in users: - db.refresh(user) - - return users - - -# ───────────────────────────────────────────────────── -# 관계와 함께 생성 -# ───────────────────────────────────────────────────── - -def create_post_with_tags( - db: Session, - title: str, - content: str, - author_id: int, - tag_names: list[str] -) -> Post: - # 기존 태그 조회 또는 생성 - tags = [] - for name in tag_names: - tag = db.scalar(select(Tag).where(Tag.name == name)) - if not tag: - tag = Tag(name=name) - tags.append(tag) - - post = Post( - title=title, - content=content, - author_id=author_id, - tags=tags, - ) - db.add(post) - db.commit() - db.refresh(post) - return post - - -# ───────────────────────────────────────────────────── -# Insert ... ON DUPLICATE KEY UPDATE (Upsert) -# ───────────────────────────────────────────────────── - -from sqlalchemy.dialects.mysql import insert as mysql_insert - -def upsert_user(db: Session, email: str, username: str) -> None: - stmt = mysql_insert(User).values( - email=email, - username=username, - ) - stmt = stmt.on_duplicate_key_update( - username=stmt.inserted.username, - updated_at=func.now(), - ) - db.execute(stmt) - db.commit() - - -# PostgreSQL의 경우 -from sqlalchemy.dialects.postgresql import insert as pg_insert - -def upsert_user_pg(db: Session, email: str, username: str) -> None: - stmt = pg_insert(User).values(email=email, username=username) - stmt = stmt.on_conflict_do_update( - index_elements=["email"], - set_={"username": username}, - ) - db.execute(stmt) - db.commit() -``` - -### 3.2 Read (조회) - -```python -from sqlalchemy import select -from sqlalchemy.orm import Session - - -# ───────────────────────────────────────────────────── -# Primary Key로 조회 -# ───────────────────────────────────────────────────── - -def get_user_by_id(db: Session, user_id: int) -> User | None: - return db.get(User, user_id) - - -# ───────────────────────────────────────────────────── -# 단일 레코드 조회 (조건) -# ───────────────────────────────────────────────────── - -def get_user_by_email(db: Session, email: str) -> User | None: - stmt = select(User).where(User.email == email) - return db.scalar(stmt) - - -# scalar(): 단일 값 반환 (없으면 None) -# scalars(): 여러 값의 ScalarResult 반환 -# one(): 정확히 1개 (0개 또는 2개 이상이면 에러) -# one_or_none(): 0개면 None, 1개면 반환, 2개 이상이면 에러 -# first(): 첫 번째 결과 (없으면 None) - - -# ───────────────────────────────────────────────────── -# 여러 레코드 조회 -# ───────────────────────────────────────────────────── - -def get_all_users(db: Session) -> list[User]: - stmt = select(User) - return list(db.scalars(stmt).all()) - - -def get_active_users(db: Session) -> list[User]: - stmt = select(User).where(User.is_active == True) - return list(db.scalars(stmt).all()) - - -# ───────────────────────────────────────────────────── -# 특정 컬럼만 조회 -# ───────────────────────────────────────────────────── - -def get_user_emails(db: Session) -> list[str]: - stmt = select(User.email) - return list(db.scalars(stmt).all()) - - -def get_user_summary(db: Session) -> list[tuple]: - stmt = select(User.id, User.email, User.username) - return list(db.execute(stmt).all()) - - -# ───────────────────────────────────────────────────── -# 존재 여부 확인 -# ───────────────────────────────────────────────────── - -def user_exists(db: Session, email: str) -> bool: - stmt = select(User.id).where(User.email == email) - return db.scalar(stmt) is not None - - -# 또는 exists() 사용 -from sqlalchemy import exists - -def user_exists_v2(db: Session, email: str) -> bool: - stmt = select(exists().where(User.email == email)) - return db.scalar(stmt) -``` - -### 3.3 Update (수정) - -```python -from sqlalchemy import update -from sqlalchemy.orm import Session - - -# ───────────────────────────────────────────────────── -# 단일 레코드 수정 (ORM 방식) -# ───────────────────────────────────────────────────── - -def update_user(db: Session, user_id: int, **kwargs) -> User | None: - user = db.get(User, user_id) - if not user: - return None - - for key, value in kwargs.items(): - if hasattr(user, key): - setattr(user, key, value) - - db.commit() - db.refresh(user) - return user - - -# ───────────────────────────────────────────────────── -# Bulk Update (Core 방식) - 더 효율적 -# ───────────────────────────────────────────────────── - -def deactivate_users(db: Session, user_ids: list[int]) -> int: - stmt = ( - update(User) - .where(User.id.in_(user_ids)) - .values(is_active=False) - ) - result = db.execute(stmt) - db.commit() - return result.rowcount # 영향받은 행 수 - - -# ───────────────────────────────────────────────────── -# 조건부 Update -# ───────────────────────────────────────────────────── - -def increment_login_count(db: Session, user_id: int) -> None: - stmt = ( - update(User) - .where(User.id == user_id) - .values(login_count=User.login_count + 1) - ) - db.execute(stmt) - db.commit() - - -# ───────────────────────────────────────────────────── -# CASE를 사용한 조건부 Update -# ───────────────────────────────────────────────────── - -from sqlalchemy import case - -def update_user_levels(db: Session) -> None: - stmt = ( - update(User) - .values( - level=case( - (User.login_count >= 100, "gold"), - (User.login_count >= 50, "silver"), - else_="bronze", - ) - ) - ) - db.execute(stmt) - db.commit() -``` - -### 3.4 Delete (삭제) - -```python -from sqlalchemy import delete -from sqlalchemy.orm import Session - - -# ───────────────────────────────────────────────────── -# 단일 레코드 삭제 (ORM 방식) -# ───────────────────────────────────────────────────── - -def delete_user(db: Session, user_id: int) -> bool: - user = db.get(User, user_id) - if not user: - return False - - db.delete(user) # cascade 설정에 따라 관련 데이터도 삭제 - db.commit() - return True - - -# ───────────────────────────────────────────────────── -# Bulk Delete (Core 방식) - 더 효율적 -# ───────────────────────────────────────────────────── - -def delete_inactive_users(db: Session) -> int: - stmt = delete(User).where(User.is_active == False) - result = db.execute(stmt) - db.commit() - return result.rowcount - - -# ───────────────────────────────────────────────────── -# Soft Delete -# ───────────────────────────────────────────────────── - -from datetime import datetime - -def soft_delete_user(db: Session, user_id: int) -> bool: - stmt = ( - update(User) - .where(User.id == user_id) - .values(is_deleted=True, deleted_at=datetime.utcnow()) - ) - result = db.execute(stmt) - db.commit() - return result.rowcount > 0 - - -# ───────────────────────────────────────────────────── -# 관계 데이터 삭제 -# ───────────────────────────────────────────────────── - -def remove_tag_from_post(db: Session, post_id: int, tag_id: int) -> None: - post = db.get(Post, post_id) - tag = db.get(Tag, tag_id) - - if post and tag and tag in post.tags: - post.tags.remove(tag) - db.commit() -``` - ---- - -## 4. 조회 쿼리 심화 - -### 4.1 select() 기본 사용법 - -```python -from sqlalchemy import select - - -# ───────────────────────────────────────────────────── -# 전체 모델 조회 -# ───────────────────────────────────────────────────── - -stmt = select(User) -# SELECT user.id, user.email, user.username, ... FROM user - - -# ───────────────────────────────────────────────────── -# 특정 컬럼만 조회 -# ───────────────────────────────────────────────────── - -stmt = select(User.id, User.email) -# SELECT user.id, user.email FROM user - - -# ───────────────────────────────────────────────────── -# 컬럼 별칭 (alias) -# ───────────────────────────────────────────────────── - -stmt = select(User.email.label("user_email")) -# SELECT user.email AS user_email FROM user - - -# ───────────────────────────────────────────────────── -# DISTINCT -# ───────────────────────────────────────────────────── - -stmt = select(User.category_id).distinct() -# SELECT DISTINCT user.category_id FROM user - - -# ───────────────────────────────────────────────────── -# 여러 테이블에서 조회 -# ───────────────────────────────────────────────────── - -stmt = select(User, Post).join(Post) -# SELECT user.*, post.* FROM user JOIN post ON ... - - -stmt = select(User.email, Post.title).join(Post) -# SELECT user.email, post.title FROM user JOIN post ON ... -``` - -### 4.2 실행 메서드 비교 - -```python -from sqlalchemy.orm import Session - - -# ───────────────────────────────────────────────────── -# execute() - Row 객체 반환 -# ───────────────────────────────────────────────────── - -stmt = select(User.id, User.email) -result = db.execute(stmt) - -for row in result: - print(row.id, row.email) # Row 객체 - print(row[0], row[1]) # 인덱스 접근 - print(row._mapping) # dict-like 접근 - - -# ───────────────────────────────────────────────────── -# scalars() - 첫 번째 컬럼만 반환 -# ───────────────────────────────────────────────────── - -stmt = select(User) -users = db.scalars(stmt).all() # list[User] - -stmt = select(User.email) -emails = db.scalars(stmt).all() # list[str] - - -# ───────────────────────────────────────────────────── -# scalar() - 단일 값 반환 -# ───────────────────────────────────────────────────── - -stmt = select(User).where(User.id == 1) -user = db.scalar(stmt) # User | None - -stmt = select(func.count(User.id)) -count = db.scalar(stmt) # int - - -# ───────────────────────────────────────────────────── -# 결과 처리 메서드 -# ───────────────────────────────────────────────────── - -result = db.scalars(stmt) - -result.all() # 모든 결과를 리스트로 -result.first() # 첫 번째 결과 (없으면 None) -result.one() # 정확히 1개 (아니면 예외) -result.one_or_none()# 0-1개 (2개 이상이면 예외) -result.fetchmany(5) # 5개만 가져오기 -result.unique() # 중복 제거 (relationship 로딩 시 필요) -``` - ---- - -## 5. 필터링과 조건 - -### 5.1 기본 비교 연산자 - -```python -from sqlalchemy import select, and_, or_, not_ - - -# ───────────────────────────────────────────────────── -# 동등 비교 -# ───────────────────────────────────────────────────── - -stmt = select(User).where(User.email == "test@example.com") -stmt = select(User).where(User.is_active == True) -stmt = select(User).where(User.category_id == None) # IS NULL - - -# ───────────────────────────────────────────────────── -# 부등 비교 -# ───────────────────────────────────────────────────── - -stmt = select(User).where(User.age != 30) -stmt = select(User).where(User.age > 18) -stmt = select(User).where(User.age >= 18) -stmt = select(User).where(User.age < 65) -stmt = select(User).where(User.age <= 65) - - -# ───────────────────────────────────────────────────── -# BETWEEN -# ───────────────────────────────────────────────────── - -stmt = select(User).where(User.age.between(18, 65)) -# WHERE age BETWEEN 18 AND 65 - - -# ───────────────────────────────────────────────────── -# IN / NOT IN -# ───────────────────────────────────────────────────── - -stmt = select(User).where(User.status.in_(["active", "pending"])) -stmt = select(User).where(User.id.in_([1, 2, 3, 4, 5])) -stmt = select(User).where(User.status.not_in(["deleted", "banned"])) - - -# ───────────────────────────────────────────────────── -# IS NULL / IS NOT NULL -# ───────────────────────────────────────────────────── - -stmt = select(User).where(User.deleted_at.is_(None)) # IS NULL -stmt = select(User).where(User.deleted_at.is_not(None)) # IS NOT NULL -stmt = select(User).where(User.bio.isnot(None)) # 또 다른 방법 -``` - -### 5.2 문자열 연산 - -```python -# ───────────────────────────────────────────────────── -# LIKE / ILIKE -# ───────────────────────────────────────────────────── - -stmt = select(User).where(User.email.like("%@gmail.com")) -stmt = select(User).where(User.username.like("john%")) -stmt = select(User).where(User.name.like("%홍길%")) - -# 대소문자 무시 (PostgreSQL) -stmt = select(User).where(User.email.ilike("%@GMAIL.COM")) - - -# ───────────────────────────────────────────────────── -# CONTAINS (LIKE '%value%') -# ───────────────────────────────────────────────────── - -stmt = select(User).where(User.bio.contains("python")) -# WHERE bio LIKE '%python%' - - -# ───────────────────────────────────────────────────── -# STARTSWITH / ENDSWITH -# ───────────────────────────────────────────────────── - -stmt = select(User).where(User.email.startswith("admin")) -# WHERE email LIKE 'admin%' - -stmt = select(User).where(User.email.endswith("@company.com")) -# WHERE email LIKE '%@company.com' - - -# ───────────────────────────────────────────────────── -# 정규표현식 (DB 지원 필요) -# ───────────────────────────────────────────────────── - -stmt = select(User).where(User.email.regexp_match(r"^[a-z]+@")) -``` - -### 5.3 논리 연산자 - -```python -from sqlalchemy import and_, or_, not_ - - -# ───────────────────────────────────────────────────── -# AND -# ───────────────────────────────────────────────────── - -# 방법 1: and_() 함수 -stmt = select(User).where( - and_( - User.is_active == True, - User.age >= 18, - ) -) - -# 방법 2: where() 체이닝 (암묵적 AND) -stmt = select(User).where(User.is_active == True).where(User.age >= 18) - -# 방법 3: 콤마로 구분 -stmt = select(User).where(User.is_active == True, User.age >= 18) - - -# ───────────────────────────────────────────────────── -# OR -# ───────────────────────────────────────────────────── - -stmt = select(User).where( - or_( - User.role == "admin", - User.role == "moderator", - ) -) - - -# ───────────────────────────────────────────────────── -# NOT -# ───────────────────────────────────────────────────── - -stmt = select(User).where(not_(User.is_deleted == True)) -stmt = select(User).where(~(User.is_deleted == True)) # ~ 연산자 - - -# ───────────────────────────────────────────────────── -# 복합 조건 -# ───────────────────────────────────────────────────── - -stmt = select(User).where( - and_( - User.is_active == True, - or_( - User.role == "admin", - User.age >= 21, - ), - not_(User.is_deleted == True), - ) -) -# WHERE is_active = true -# AND (role = 'admin' OR age >= 21) -# AND NOT is_deleted = true -``` - -### 5.4 동적 필터링 - -```python -from typing import Optional - - -def search_users( - db: Session, - email: Optional[str] = None, - username: Optional[str] = None, - is_active: Optional[bool] = None, - min_age: Optional[int] = None, - max_age: Optional[int] = None, -) -> list[User]: - stmt = select(User) - - # 동적으로 조건 추가 - if email: - stmt = stmt.where(User.email.contains(email)) - - if username: - stmt = stmt.where(User.username.like(f"%{username}%")) - - if is_active is not None: - stmt = stmt.where(User.is_active == is_active) - - if min_age is not None: - stmt = stmt.where(User.age >= min_age) - - if max_age is not None: - stmt = stmt.where(User.age <= max_age) - - return list(db.scalars(stmt).all()) - - -# 사용 -users = search_users(db, email="gmail", is_active=True, min_age=18) -``` - ---- - -## 6. 정렬, 페이징, 제한 - -### 6.1 정렬 (ORDER BY) - -```python -from sqlalchemy import select, asc, desc - - -# ───────────────────────────────────────────────────── -# 기본 정렬 -# ───────────────────────────────────────────────────── - -# 오름차순 (기본) -stmt = select(User).order_by(User.created_at) -stmt = select(User).order_by(asc(User.created_at)) - -# 내림차순 -stmt = select(User).order_by(desc(User.created_at)) -stmt = select(User).order_by(User.created_at.desc()) - - -# ───────────────────────────────────────────────────── -# 다중 정렬 -# ───────────────────────────────────────────────────── - -stmt = select(User).order_by( - User.is_active.desc(), - User.created_at.desc(), -) -# ORDER BY is_active DESC, created_at DESC - - -# ───────────────────────────────────────────────────── -# NULL 처리 -# ───────────────────────────────────────────────────── - -stmt = select(User).order_by(User.last_login.desc().nullslast()) -# NULL 값을 마지막에 - -stmt = select(User).order_by(User.last_login.asc().nullsfirst()) -# NULL 값을 처음에 -``` - -### 6.2 제한과 오프셋 (LIMIT, OFFSET) - -```python -# ───────────────────────────────────────────────────── -# LIMIT -# ───────────────────────────────────────────────────── - -stmt = select(User).limit(10) -# SELECT ... FROM user LIMIT 10 - - -# ───────────────────────────────────────────────────── -# OFFSET -# ───────────────────────────────────────────────────── - -stmt = select(User).offset(20).limit(10) -# SELECT ... FROM user LIMIT 10 OFFSET 20 - - -# ───────────────────────────────────────────────────── -# 슬라이스 문법 -# ───────────────────────────────────────────────────── - -stmt = select(User).slice(20, 30) # offset=20, limit=10과 동일 -``` - -### 6.3 페이지네이션 구현 - -```python -from typing import TypeVar, Generic -from pydantic import BaseModel -from sqlalchemy import select, func -from sqlalchemy.orm import Session - -T = TypeVar("T") - - -class PaginatedResult(BaseModel, Generic[T]): - items: list[T] - total: int - page: int - page_size: int - total_pages: int - has_next: bool - has_prev: bool - - -def paginate( - db: Session, - stmt, - page: int = 1, - page_size: int = 20, -) -> dict: - # 페이지 유효성 검사 - page = max(1, page) - page_size = min(max(1, page_size), 100) # 최대 100개 - - # 전체 개수 조회 - count_stmt = select(func.count()).select_from(stmt.subquery()) - total = db.scalar(count_stmt) - - # 페이지네이션 적용 - offset = (page - 1) * page_size - paginated_stmt = stmt.offset(offset).limit(page_size) - items = list(db.scalars(paginated_stmt).all()) - - total_pages = (total + page_size - 1) // page_size - - return { - "items": items, - "total": total, - "page": page, - "page_size": page_size, - "total_pages": total_pages, - "has_next": page < total_pages, - "has_prev": page > 1, - } - - -# 사용 예시 -def get_users_paginated( - db: Session, - page: int = 1, - page_size: int = 20, - is_active: bool | None = None, -) -> dict: - stmt = select(User).order_by(User.created_at.desc()) - - if is_active is not None: - stmt = stmt.where(User.is_active == is_active) - - return paginate(db, stmt, page, page_size) - - -# FastAPI 엔드포인트 -@router.get("/users") -def list_users( - page: int = Query(1, ge=1), - page_size: int = Query(20, ge=1, le=100), - is_active: bool | None = None, - db: Session = Depends(get_db), -): - return get_users_paginated(db, page, page_size, is_active) -``` - -### 6.4 커서 기반 페이지네이션 - -```python -from datetime import datetime -from typing import Optional - - -def get_users_cursor( - db: Session, - limit: int = 20, - cursor: Optional[datetime] = None, -) -> dict: - stmt = select(User).order_by(User.created_at.desc()) - - if cursor: - stmt = stmt.where(User.created_at < cursor) - - stmt = stmt.limit(limit + 1) # 다음 페이지 확인용으로 1개 더 - - items = list(db.scalars(stmt).all()) - - has_next = len(items) > limit - if has_next: - items = items[:limit] - - next_cursor = items[-1].created_at if items and has_next else None - - return { - "items": items, - "next_cursor": next_cursor, - "has_next": has_next, - } - - -# 복합 커서 (동일 시간 처리) -def get_users_cursor_v2( - db: Session, - limit: int = 20, - cursor_time: Optional[datetime] = None, - cursor_id: Optional[int] = None, -) -> dict: - stmt = select(User).order_by( - User.created_at.desc(), - User.id.desc(), - ) - - if cursor_time and cursor_id: - stmt = stmt.where( - or_( - User.created_at < cursor_time, - and_( - User.created_at == cursor_time, - User.id < cursor_id, - ), - ) - ) - - stmt = stmt.limit(limit + 1) - items = list(db.scalars(stmt).all()) - - has_next = len(items) > limit - if has_next: - items = items[:limit] - - return { - "items": items, - "next_cursor": { - "time": items[-1].created_at, - "id": items[-1].id, - } if items and has_next else None, - "has_next": has_next, - } -``` - ---- - -## 7. 집계 함수 (Aggregation) - -### 7.1 기본 집계 함수 - -```python -from sqlalchemy import select, func - - -# ───────────────────────────────────────────────────── -# COUNT -# ───────────────────────────────────────────────────── - -# 전체 개수 -stmt = select(func.count(User.id)) -total = db.scalar(stmt) - -# 조건부 개수 -stmt = select(func.count(User.id)).where(User.is_active == True) -active_count = db.scalar(stmt) - -# COUNT(DISTINCT) -stmt = select(func.count(func.distinct(User.category_id))) -unique_categories = db.scalar(stmt) - - -# ───────────────────────────────────────────────────── -# SUM -# ───────────────────────────────────────────────────── - -stmt = select(func.sum(Order.amount)) -total_amount = db.scalar(stmt) - -stmt = select(func.sum(Order.amount)).where(Order.status == "completed") -completed_amount = db.scalar(stmt) - - -# ───────────────────────────────────────────────────── -# AVG -# ───────────────────────────────────────────────────── - -stmt = select(func.avg(Product.price)) -avg_price = db.scalar(stmt) - -# 반올림 -stmt = select(func.round(func.avg(Product.price), 2)) -avg_price_rounded = db.scalar(stmt) - - -# ───────────────────────────────────────────────────── -# MIN / MAX -# ───────────────────────────────────────────────────── - -stmt = select(func.min(Product.price), func.max(Product.price)) -result = db.execute(stmt).first() -min_price, max_price = result - - -# ───────────────────────────────────────────────────── -# 여러 집계 함수 함께 사용 -# ───────────────────────────────────────────────────── - -stmt = select( - func.count(Order.id).label("order_count"), - func.sum(Order.amount).label("total_amount"), - func.avg(Order.amount).label("avg_amount"), - func.min(Order.amount).label("min_amount"), - func.max(Order.amount).label("max_amount"), -) -result = db.execute(stmt).first() - -print(f"주문 수: {result.order_count}") -print(f"총 금액: {result.total_amount}") -print(f"평균 금액: {result.avg_amount}") -``` - -### 7.2 GROUP BY - -```python -# ───────────────────────────────────────────────────── -# 기본 GROUP BY -# ───────────────────────────────────────────────────── - -# 카테고리별 상품 수 -stmt = ( - select( - Product.category_id, - func.count(Product.id).label("product_count"), - ) - .group_by(Product.category_id) -) -results = db.execute(stmt).all() - -for row in results: - print(f"Category {row.category_id}: {row.product_count} products") - - -# ───────────────────────────────────────────────────── -# JOIN과 함께 GROUP BY -# ───────────────────────────────────────────────────── - -# 카테고리 이름과 함께 -stmt = ( - select( - Category.name, - func.count(Product.id).label("product_count"), - func.avg(Product.price).label("avg_price"), - ) - .join(Product, Category.id == Product.category_id) - .group_by(Category.id, Category.name) -) - - -# ───────────────────────────────────────────────────── -# 날짜별 GROUP BY -# ───────────────────────────────────────────────────── - -# 일별 주문 통계 -stmt = ( - select( - func.date(Order.created_at).label("order_date"), - func.count(Order.id).label("order_count"), - func.sum(Order.amount).label("total_amount"), - ) - .group_by(func.date(Order.created_at)) - .order_by(func.date(Order.created_at).desc()) -) - -# 월별 주문 통계 -stmt = ( - select( - func.year(Order.created_at).label("year"), - func.month(Order.created_at).label("month"), - func.count(Order.id).label("order_count"), - func.sum(Order.amount).label("total_amount"), - ) - .group_by( - func.year(Order.created_at), - func.month(Order.created_at), - ) - .order_by( - func.year(Order.created_at).desc(), - func.month(Order.created_at).desc(), - ) -) - - -# ───────────────────────────────────────────────────── -# 다중 컬럼 GROUP BY -# ───────────────────────────────────────────────────── - -stmt = ( - select( - User.country, - User.city, - func.count(User.id).label("user_count"), - ) - .group_by(User.country, User.city) - .order_by(func.count(User.id).desc()) -) -``` - -### 7.3 HAVING - -```python -# ───────────────────────────────────────────────────── -# 집계 결과 필터링 -# ───────────────────────────────────────────────────── - -# 5개 이상 상품이 있는 카테고리만 -stmt = ( - select( - Category.name, - func.count(Product.id).label("product_count"), - ) - .join(Product) - .group_by(Category.id, Category.name) - .having(func.count(Product.id) >= 5) -) - - -# ───────────────────────────────────────────────────── -# 복합 HAVING 조건 -# ───────────────────────────────────────────────────── - -stmt = ( - select( - User.id, - User.username, - func.count(Order.id).label("order_count"), - func.sum(Order.amount).label("total_spent"), - ) - .join(Order) - .group_by(User.id, User.username) - .having( - and_( - func.count(Order.id) >= 10, - func.sum(Order.amount) >= 100000, - ) - ) - .order_by(func.sum(Order.amount).desc()) -) -# 10건 이상 주문하고 10만원 이상 사용한 고객 -``` - -### 7.4 윈도우 함수 - -```python -from sqlalchemy import over - - -# ───────────────────────────────────────────────────── -# ROW_NUMBER -# ───────────────────────────────────────────────────── - -stmt = ( - select( - User.id, - User.username, - User.created_at, - func.row_number().over( - order_by=User.created_at.desc() - ).label("row_num"), - ) -) - - -# ───────────────────────────────────────────────────── -# 파티션별 순위 -# ───────────────────────────────────────────────────── - -stmt = ( - select( - Product.id, - Product.name, - Product.category_id, - Product.price, - func.rank().over( - partition_by=Product.category_id, - order_by=Product.price.desc(), - ).label("price_rank"), - ) -) -# 카테고리 내에서 가격 순위 - - -# ───────────────────────────────────────────────────── -# 누적 합계 -# ───────────────────────────────────────────────────── - -stmt = ( - select( - Order.id, - Order.created_at, - Order.amount, - func.sum(Order.amount).over( - order_by=Order.created_at, - ).label("cumulative_amount"), - ) -) - - -# ───────────────────────────────────────────────────── -# 이동 평균 -# ───────────────────────────────────────────────────── - -from sqlalchemy import text - -stmt = ( - select( - Order.id, - Order.created_at, - Order.amount, - func.avg(Order.amount).over( - order_by=Order.created_at, - rows=(2, 0), # 현재 행 포함 최근 3개 - ).label("moving_avg"), - ) -) -``` - ---- - -## 8. JOIN 쿼리 - -### 8.1 기본 JOIN - -```python -from sqlalchemy import select - - -# ───────────────────────────────────────────────────── -# INNER JOIN -# ───────────────────────────────────────────────────── - -# 방법 1: relationship 사용 (자동 조건) -stmt = select(User, Post).join(User.posts) -# SELECT ... FROM user JOIN post ON user.id = post.author_id - -# 방법 2: 명시적 조건 -stmt = select(User, Post).join(Post, User.id == Post.author_id) - -# 방법 3: 모델만 지정 (FK 자동 감지) -stmt = select(User, Post).join(Post) - - -# ───────────────────────────────────────────────────── -# LEFT OUTER JOIN -# ───────────────────────────────────────────────────── - -stmt = select(User, Post).join(Post, isouter=True) -# SELECT ... FROM user LEFT JOIN post ON ... - -# 또는 -stmt = select(User, Post).outerjoin(Post) - - -# ───────────────────────────────────────────────────── -# RIGHT OUTER JOIN -# ───────────────────────────────────────────────────── - -stmt = select(User, Post).join(Post, full=True) # FULL OUTER -# RIGHT JOIN은 순서를 바꿔서 구현 -stmt = select(Post, User).outerjoin(User) - - -# ───────────────────────────────────────────────────── -# 다중 JOIN -# ───────────────────────────────────────────────────── - -stmt = ( - select(User, Post, Comment) - .join(Post, User.id == Post.author_id) - .join(Comment, Post.id == Comment.post_id) -) - -# relationship 사용 -stmt = ( - select(User, Post, Comment) - .join(User.posts) - .join(Post.comments) -) -``` - -### 8.2 JOIN 결과 처리 - -```python -# ───────────────────────────────────────────────────── -# 여러 모델 조회 -# ───────────────────────────────────────────────────── - -stmt = select(User, Post).join(Post) -results = db.execute(stmt).all() - -for user, post in results: - print(f"Author: {user.username}, Post: {post.title}") - - -# ───────────────────────────────────────────────────── -# 특정 컬럼만 조회 -# ───────────────────────────────────────────────────── - -stmt = ( - select(User.username, Post.title, Post.created_at) - .join(Post) - .order_by(Post.created_at.desc()) -) -results = db.execute(stmt).all() - -for row in results: - print(f"{row.username}: {row.title}") - - -# ───────────────────────────────────────────────────── -# 하나의 모델만 필요할 때 -# ───────────────────────────────────────────────────── - -# 게시글이 있는 사용자만 조회 -stmt = ( - select(User) - .join(Post) - .distinct() -) -users = db.scalars(stmt).all() -``` - -### 8.3 Self JOIN - -```python -# ───────────────────────────────────────────────────── -# 같은 테이블 조인 (별칭 필요) -# ───────────────────────────────────────────────────── - -from sqlalchemy.orm import aliased - -# 사용자와 그 추천인 -Referrer = aliased(User, name="referrer") - -stmt = ( - select(User.username, Referrer.username.label("referrer_name")) - .join(Referrer, User.referrer_id == Referrer.id, isouter=True) -) - - -# ───────────────────────────────────────────────────── -# 계층 구조 조회 (상위/하위) -# ───────────────────────────────────────────────────── - -Parent = aliased(Category, name="parent") - -stmt = ( - select(Category.name, Parent.name.label("parent_name")) - .join(Parent, Category.parent_id == Parent.id, isouter=True) -) - - -# ───────────────────────────────────────────────────── -# 같은 테이블 비교 -# ───────────────────────────────────────────────────── - -# 같은 카테고리의 다른 상품 -OtherProduct = aliased(Product, name="other") - -stmt = ( - select(Product.name, OtherProduct.name.label("related_product")) - .join( - OtherProduct, - and_( - Product.category_id == OtherProduct.category_id, - Product.id != OtherProduct.id, - ) - ) - .where(Product.id == 1) -) -``` - ---- - -## 9. 서브쿼리 (Subquery) - -### 9.1 스칼라 서브쿼리 - -```python -from sqlalchemy import select, func - - -# ───────────────────────────────────────────────────── -# SELECT 절의 서브쿼리 -# ───────────────────────────────────────────────────── - -# 각 사용자의 게시글 수 -post_count_subq = ( - select(func.count(Post.id)) - .where(Post.author_id == User.id) - .correlate(User) - .scalar_subquery() -) - -stmt = select( - User.username, - post_count_subq.label("post_count"), -) - - -# ───────────────────────────────────────────────────── -# 평균과 비교 -# ───────────────────────────────────────────────────── - -avg_price = select(func.avg(Product.price)).scalar_subquery() - -stmt = select(Product).where(Product.price > avg_price) -# 평균보다 비싼 상품 -``` - -### 9.2 FROM 절의 서브쿼리 - -```python -# ───────────────────────────────────────────────────── -# 서브쿼리를 테이블처럼 사용 -# ───────────────────────────────────────────────────── - -# 카테고리별 통계 서브쿼리 -category_stats = ( - select( - Product.category_id, - func.count(Product.id).label("product_count"), - func.avg(Product.price).label("avg_price"), - ) - .group_by(Product.category_id) - .subquery() -) - -# 메인 쿼리에서 조인 -stmt = ( - select( - Category.name, - category_stats.c.product_count, - category_stats.c.avg_price, - ) - .join(category_stats, Category.id == category_stats.c.category_id) -) - - -# ───────────────────────────────────────────────────── -# 파생 테이블 -# ───────────────────────────────────────────────────── - -# 최근 7일 활성 사용자 -recent_active = ( - select( - User.id, - User.username, - func.count(Order.id).label("order_count"), - ) - .join(Order) - .where(Order.created_at >= func.date_sub(func.now(), text("INTERVAL 7 DAY"))) - .group_by(User.id) - .subquery() -) - -# 많이 주문한 순으로 -stmt = ( - select(recent_active) - .order_by(recent_active.c.order_count.desc()) - .limit(10) -) -``` - -### 9.3 WHERE 절의 서브쿼리 - -```python -from sqlalchemy import exists, any_, all_ - - -# ───────────────────────────────────────────────────── -# IN 서브쿼리 -# ───────────────────────────────────────────────────── - -# 주문한 적 있는 사용자 -ordered_user_ids = select(Order.user_id).distinct() - -stmt = select(User).where(User.id.in_(ordered_user_ids)) - - -# ───────────────────────────────────────────────────── -# EXISTS -# ───────────────────────────────────────────────────── - -# 게시글이 있는 사용자 -has_posts = ( - exists() - .where(Post.author_id == User.id) -) - -stmt = select(User).where(has_posts) - - -# NOT EXISTS -stmt = select(User).where(~has_posts) # 게시글 없는 사용자 - - -# ───────────────────────────────────────────────────── -# ANY / ALL -# ───────────────────────────────────────────────────── - -# 어떤 주문보다 비싼 상품 (ANY) -any_order_amount = select(Order.amount) -stmt = select(Product).where(Product.price > any_(any_order_amount)) - -# 모든 주문보다 비싼 상품 (ALL) -stmt = select(Product).where(Product.price > all_(any_order_amount)) -``` - -### 9.4 Lateral 서브쿼리 (PostgreSQL) - -```python -from sqlalchemy import lateral - - -# 각 사용자의 최근 3개 주문 -recent_orders = ( - select(Order) - .where(Order.user_id == User.id) - .order_by(Order.created_at.desc()) - .limit(3) - .lateral() -) - -stmt = ( - select(User, recent_orders) - .outerjoin(recent_orders, True) -) -``` - ---- - -## 10. 집합 연산 (Union, Intersect, Except) - -### 10.1 UNION - -```python -from sqlalchemy import union, union_all - - -# ───────────────────────────────────────────────────── -# UNION (중복 제거) -# ───────────────────────────────────────────────────── - -# 관리자 + 최근 활동 사용자 -admins = select(User.id, User.username).where(User.is_admin == True) -recent_active = select(User.id, User.username).where( - User.last_login >= func.date_sub(func.now(), text("INTERVAL 7 DAY")) -) - -stmt = union(admins, recent_active) -results = db.execute(stmt).all() - - -# ───────────────────────────────────────────────────── -# UNION ALL (중복 허용, 더 빠름) -# ───────────────────────────────────────────────────── - -stmt = union_all(admins, recent_active) - - -# ───────────────────────────────────────────────────── -# 여러 개 UNION -# ───────────────────────────────────────────────────── - -query1 = select(User.email.label("contact")).where(User.is_active == True) -query2 = select(Contact.email.label("contact")).where(Contact.subscribed == True) -query3 = select(Lead.email.label("contact")).where(Lead.status == "qualified") - -stmt = union(query1, query2, query3) - - -# ───────────────────────────────────────────────────── -# UNION 결과 정렬/제한 -# ───────────────────────────────────────────────────── - -combined = union(admins, recent_active).subquery() - -stmt = ( - select(combined) - .order_by(combined.c.username) - .limit(10) -) -``` - -### 10.2 INTERSECT - -```python -from sqlalchemy import intersect, intersect_all - - -# ───────────────────────────────────────────────────── -# INTERSECT (교집합) -# ───────────────────────────────────────────────────── - -# 관리자이면서 최근 활동한 사용자 -admins = select(User.id).where(User.is_admin == True) -recent_active = select(User.id).where( - User.last_login >= func.date_sub(func.now(), text("INTERVAL 7 DAY")) -) - -stmt = intersect(admins, recent_active) - - -# ───────────────────────────────────────────────────── -# 여러 조건의 교집합 -# ───────────────────────────────────────────────────── - -# 세 가지 모두 만족하는 사용자 -has_orders = select(Order.user_id).distinct() -has_reviews = select(Review.user_id).distinct() -is_verified = select(User.id).where(User.is_verified == True) - -stmt = intersect(has_orders, has_reviews, is_verified) -``` - -### 10.3 EXCEPT - -```python -from sqlalchemy import except_, except_all - - -# ───────────────────────────────────────────────────── -# EXCEPT (차집합) -# ───────────────────────────────────────────────────── - -# 주문은 했지만 리뷰는 안 쓴 사용자 -ordered = select(Order.user_id).distinct() -reviewed = select(Review.user_id).distinct() - -stmt = except_(ordered, reviewed) - - -# ───────────────────────────────────────────────────── -# 실용 예: 미처리 항목 찾기 -# ───────────────────────────────────────────────────── - -# 모든 신규 사용자 중 환영 이메일 미발송 대상 -all_new_users = select(User.id).where( - User.created_at >= func.date_sub(func.now(), text("INTERVAL 24 HOUR")) -) -email_sent = select(EmailLog.user_id).where(EmailLog.type == "welcome") - -stmt = except_(all_new_users, email_sent) -``` - ---- - -## 11. 고급 표현식 - -### 11.1 CASE 문 - -```python -from sqlalchemy import case - - -# ───────────────────────────────────────────────────── -# 단순 CASE -# ───────────────────────────────────────────────────── - -status_label = case( - (User.status == "active", "활성"), - (User.status == "pending", "대기"), - (User.status == "suspended", "정지"), - else_="알 수 없음", -) - -stmt = select(User.username, status_label.label("status_label")) - - -# ───────────────────────────────────────────────────── -# 조건부 집계 -# ───────────────────────────────────────────────────── - -stmt = select( - func.count(case((Order.status == "completed", 1))).label("completed_count"), - func.count(case((Order.status == "pending", 1))).label("pending_count"), - func.count(case((Order.status == "cancelled", 1))).label("cancelled_count"), - func.sum(case((Order.status == "completed", Order.amount), else_=0)).label("completed_amount"), -) - - -# ───────────────────────────────────────────────────── -# 정렬에서 CASE -# ───────────────────────────────────────────────────── - -priority_order = case( - (User.role == "admin", 1), - (User.role == "moderator", 2), - else_=3, -) - -stmt = select(User).order_by(priority_order, User.username) -``` - -### 11.2 형변환 (CAST) - -```python -from sqlalchemy import cast -from sqlalchemy.types import String, Integer, Float, Date - - -# ───────────────────────────────────────────────────── -# 타입 변환 -# ───────────────────────────────────────────────────── - -stmt = select(cast(User.age, String).label("age_str")) -stmt = select(cast(Product.price, Integer).label("price_int")) -stmt = select(cast(Order.created_at, Date).label("order_date")) - - -# ───────────────────────────────────────────────────── -# 문자열 연결 시 형변환 -# ───────────────────────────────────────────────────── - -stmt = select( - (User.username + " (" + cast(User.age, String) + "세)").label("display_name") -) -``` - -### 11.3 문자열 함수 - -```python -from sqlalchemy import func - - -# ───────────────────────────────────────────────────── -# 기본 문자열 함수 -# ───────────────────────────────────────────────────── - -stmt = select( - func.upper(User.username), - func.lower(User.email), - func.length(User.bio), - func.trim(User.name), - func.concat(User.first_name, " ", User.last_name).label("full_name"), -) - - -# ───────────────────────────────────────────────────── -# 문자열 추출 -# ───────────────────────────────────────────────────── - -stmt = select( - func.substring(User.email, 1, 10), # 처음 10자 - func.left(User.username, 5), - func.right(User.email, 10), -) - - -# ───────────────────────────────────────────────────── -# 문자열 연결 (|| 연산자) -# ───────────────────────────────────────────────────── - -from sqlalchemy import literal_column - -# PostgreSQL/SQLite -full_name = User.first_name + " " + User.last_name - -# MySQL -full_name = func.concat(User.first_name, " ", User.last_name) -``` - -### 11.4 날짜/시간 함수 - -```python -from sqlalchemy import func, extract - - -# ───────────────────────────────────────────────────── -# 현재 날짜/시간 -# ───────────────────────────────────────────────────── - -stmt = select( - func.now(), - func.current_date(), - func.current_time(), - func.current_timestamp(), -) - - -# ───────────────────────────────────────────────────── -# 날짜 추출 -# ───────────────────────────────────────────────────── - -stmt = select( - extract("year", Order.created_at).label("year"), - extract("month", Order.created_at).label("month"), - extract("day", Order.created_at).label("day"), - extract("hour", Order.created_at).label("hour"), -) - -# 또는 -stmt = select( - func.year(Order.created_at), - func.month(Order.created_at), - func.day(Order.created_at), -) - - -# ───────────────────────────────────────────────────── -# 날짜 연산 -# ───────────────────────────────────────────────────── - -# MySQL -from sqlalchemy import text - -stmt = select(User).where( - User.created_at >= func.date_sub(func.now(), text("INTERVAL 30 DAY")) -) - -# PostgreSQL -from datetime import timedelta -stmt = select(User).where( - User.created_at >= func.now() - timedelta(days=30) -) - - -# ───────────────────────────────────────────────────── -# 날짜 차이 -# ───────────────────────────────────────────────────── - -stmt = select( - func.datediff(func.now(), User.created_at).label("days_since_signup") -) -``` - -### 11.5 NULL 처리 - -```python -from sqlalchemy import func, coalesce, nullif - - -# ───────────────────────────────────────────────────── -# COALESCE (첫 번째 non-null 값) -# ───────────────────────────────────────────────────── - -stmt = select( - coalesce(User.nickname, User.username, "Anonymous").label("display_name") -) - - -# ───────────────────────────────────────────────────── -# NULLIF (같으면 NULL) -# ───────────────────────────────────────────────────── - -# 0으로 나누기 방지 -stmt = select( - Order.total / nullif(Order.quantity, 0) -) - - -# ───────────────────────────────────────────────────── -# IFNULL / NVL (MySQL / Oracle) -# ───────────────────────────────────────────────────── - -stmt = select( - func.ifnull(User.nickname, "No nickname") -) -``` - -### 11.6 Raw SQL 사용 - -```python -from sqlalchemy import text, literal_column - - -# ───────────────────────────────────────────────────── -# text() - Raw SQL -# ───────────────────────────────────────────────────── - -# WHERE 절에서 -stmt = select(User).where(text("MATCH(bio) AGAINST(:keyword)")).params(keyword="python") - -# 전체 쿼리 -result = db.execute(text("SELECT * FROM user WHERE id = :id"), {"id": 1}) - - -# ───────────────────────────────────────────────────── -# literal_column() - 컬럼 표현식 -# ───────────────────────────────────────────────────── - -stmt = select( - User.username, - literal_column("'active'").label("status"), -) - - -# ───────────────────────────────────────────────────── -# literal() - 리터럴 값 -# ───────────────────────────────────────────────────── - -from sqlalchemy import literal - -stmt = select( - User.username, - literal(1).label("constant"), - literal("active").label("status"), -) -``` - ---- - -## 12. Relationship과 Eager Loading - -### 12.1 Lazy Loading (기본) - -```python -# ───────────────────────────────────────────────────── -# N+1 문제 발생 예시 -# ───────────────────────────────────────────────────── - -users = db.scalars(select(User)).all() # 쿼리 1회 - -for user in users: - print(user.posts) # 각 사용자마다 추가 쿼리! (N회) - -# 총 N+1회 쿼리 발생 -``` - -### 12.2 Eager Loading 옵션 - -```python -from sqlalchemy.orm import selectinload, joinedload, subqueryload, raiseload - - -# ───────────────────────────────────────────────────── -# selectinload (권장: 1:N) -# ───────────────────────────────────────────────────── - -stmt = select(User).options(selectinload(User.posts)) -users = db.scalars(stmt).all() - -# 쿼리 1: SELECT * FROM user -# 쿼리 2: SELECT * FROM post WHERE user_id IN (1, 2, 3, ...) - -for user in users: - print(user.posts) # 추가 쿼리 없음! - - -# ───────────────────────────────────────────────────── -# joinedload (권장: N:1, 1:1) -# ───────────────────────────────────────────────────── - -stmt = select(Post).options(joinedload(Post.author)) -posts = db.scalars(stmt).unique().all() # unique() 필요! - -# 쿼리: SELECT post.*, user.* FROM post JOIN user ON ... - - -# ───────────────────────────────────────────────────── -# subqueryload -# ───────────────────────────────────────────────────── - -stmt = select(User).options(subqueryload(User.posts)) - -# 쿼리 1: SELECT * FROM user -# 쿼리 2: SELECT * FROM post WHERE user_id IN (SELECT id FROM user) - - -# ───────────────────────────────────────────────────── -# raiseload (로딩 금지) -# ───────────────────────────────────────────────────── - -stmt = select(User).options(raiseload(User.posts)) -user = db.scalar(stmt) -print(user.posts) # 에러 발생! 명시적 로딩 필요 -``` - -### 12.3 중첩 Eager Loading - -```python -# ───────────────────────────────────────────────────── -# 다단계 관계 로딩 -# ───────────────────────────────────────────────────── - -stmt = ( - select(User) - .options( - selectinload(User.posts) - .selectinload(Post.comments) - .selectinload(Comment.author) - ) -) - -# 쿼리 1: SELECT * FROM user -# 쿼리 2: SELECT * FROM post WHERE user_id IN (...) -# 쿼리 3: SELECT * FROM comment WHERE post_id IN (...) -# 쿼리 4: SELECT * FROM user WHERE id IN (...) # 댓글 작성자 - - -# ───────────────────────────────────────────────────── -# 여러 관계 동시 로딩 -# ───────────────────────────────────────────────────── - -stmt = ( - select(User) - .options( - selectinload(User.posts), - selectinload(User.comments), - joinedload(User.profile), - ) -) - - -# ───────────────────────────────────────────────────── -# contains_eager (이미 조인된 경우) -# ───────────────────────────────────────────────────── - -from sqlalchemy.orm import contains_eager - -stmt = ( - select(Post) - .join(Post.author) - .where(User.is_active == True) - .options(contains_eager(Post.author)) # 조인 결과 사용 -) -``` - -### 12.4 로딩 전략 비교 - -| 전략 | 쿼리 수 | 적합한 관계 | 장점 | 단점 | -|------|--------|------------|------|------| -| `selectinload` | 2 | 1:N | 효율적, 간단 | 대량 ID 시 IN 절 길어짐 | -| `joinedload` | 1 | N:1, 1:1 | 단일 쿼리 | 1:N에서 중복 발생 | -| `subqueryload` | 2 | 1:N | 복잡한 필터 지원 | 서브쿼리 오버헤드 | -| `raiseload` | - | - | 실수 방지 | 명시적 로딩 필요 | - ---- - -## 13. 트랜잭션 관리 - -### 13.1 기본 트랜잭션 - -```python -from sqlalchemy.orm import Session - - -# ───────────────────────────────────────────────────── -# 명시적 commit/rollback -# ───────────────────────────────────────────────────── - -def create_order(db: Session, user_id: int, items: list) -> Order: - try: - order = Order(user_id=user_id) - db.add(order) - db.flush() # ID 생성을 위해 flush - - for item in items: - order_item = OrderItem( - order_id=order.id, - product_id=item["product_id"], - quantity=item["quantity"], - ) - db.add(order_item) - - db.commit() - db.refresh(order) - return order - - except Exception as e: - db.rollback() - raise - - -# ───────────────────────────────────────────────────── -# context manager 사용 -# ───────────────────────────────────────────────────── - -from sqlalchemy.orm import Session - -def transfer_money(engine, from_id: int, to_id: int, amount: float): - with Session(engine) as session: - with session.begin(): # 자동 commit/rollback - from_account = session.get(Account, from_id) - to_account = session.get(Account, to_id) - - if from_account.balance < amount: - raise ValueError("잔액 부족") - - from_account.balance -= amount - to_account.balance += amount - # begin() 블록 종료 시 자동 commit - # Session 종료 시 자동 close -``` - -### 13.2 Savepoint (중첩 트랜잭션) - -```python -def complex_operation(db: Session): - try: - # 메인 작업 - user = User(username="test") - db.add(user) - db.flush() - - # 선택적 작업 (실패해도 메인은 유지) - savepoint = db.begin_nested() - try: - risky_operation() - savepoint.commit() - except Exception: - savepoint.rollback() - # 메인 트랜잭션은 유지됨 - - db.commit() - - except Exception: - db.rollback() - raise -``` - -### 13.3 FastAPI에서 트랜잭션 - -```python -# app/database.py -from contextlib import contextmanager - - -def get_db() -> Generator[Session, None, None]: - db = SessionLocal() - try: - yield db - except Exception: - db.rollback() - raise - finally: - db.close() - - -# 트랜잭션이 필요한 서비스 -class OrderService: - def __init__(self, db: Session): - self.db = db - - def create_order_with_payment(self, data: OrderCreate) -> Order: - # 여러 작업이 하나의 트랜잭션 - order = self._create_order(data) - self._process_payment(order) - self._update_inventory(order) - self._send_notification(order) - - self.db.commit() - return order - - -# 라우터 -@router.post("/orders") -def create_order( - data: OrderCreate, - db: Session = Depends(get_db), -): - service = OrderService(db) - return service.create_order_with_payment(data) -``` - ---- - -## 14. FastAPI 통합 패턴 - -### 14.1 Repository 패턴 - -```python -# app/repositories/base.py -from typing import TypeVar, Generic, Type, Optional, List -from sqlalchemy import select -from sqlalchemy.orm import Session - -from app.models.base import Base - -ModelType = TypeVar("ModelType", bound=Base) - - -class BaseRepository(Generic[ModelType]): - def __init__(self, model: Type[ModelType], db: Session): - self.model = model - self.db = db - - def get(self, id: int) -> Optional[ModelType]: - return self.db.get(self.model, id) - - def get_all(self, skip: int = 0, limit: int = 100) -> List[ModelType]: - stmt = select(self.model).offset(skip).limit(limit) - return list(self.db.scalars(stmt).all()) - - def create(self, obj: ModelType) -> ModelType: - self.db.add(obj) - self.db.commit() - self.db.refresh(obj) - return obj - - def update(self, obj: ModelType) -> ModelType: - self.db.commit() - self.db.refresh(obj) - return obj - - def delete(self, obj: ModelType) -> None: - self.db.delete(obj) - self.db.commit() - - -# app/repositories/user.py -from sqlalchemy import select -from app.models.user import User - - -class UserRepository(BaseRepository[User]): - def __init__(self, db: Session): - super().__init__(User, db) - - def get_by_email(self, email: str) -> Optional[User]: - stmt = select(User).where(User.email == email) - return self.db.scalar(stmt) - - def get_active_users(self) -> List[User]: - stmt = select(User).where(User.is_active == True) - return list(self.db.scalars(stmt).all()) - - def search(self, keyword: str) -> List[User]: - stmt = select(User).where( - or_( - User.username.contains(keyword), - User.email.contains(keyword), - ) - ) - return list(self.db.scalars(stmt).all()) -``` - -### 14.2 Service 패턴 - -```python -# app/services/user.py -from typing import Optional, List -from fastapi import HTTPException, status -from sqlalchemy.orm import Session - -from app.models.user import User -from app.schemas.user import UserCreate, UserUpdate -from app.repositories.user import UserRepository -from app.core.security import hash_password - - -class UserService: - def __init__(self, db: Session): - self.db = db - self.repository = UserRepository(db) - - def get_user(self, user_id: int) -> User: - user = self.repository.get(user_id) - if not user: - raise HTTPException( - status_code=status.HTTP_404_NOT_FOUND, - detail="User not found", - ) - return user - - def get_user_by_email(self, email: str) -> Optional[User]: - return self.repository.get_by_email(email) - - def create_user(self, data: UserCreate) -> User: - # 이메일 중복 확인 - if self.repository.get_by_email(data.email): - raise HTTPException( - status_code=status.HTTP_400_BAD_REQUEST, - detail="Email already registered", - ) - - user = User( - email=data.email, - username=data.username, - hashed_password=hash_password(data.password), - ) - return self.repository.create(user) - - def update_user(self, user_id: int, data: UserUpdate) -> User: - user = self.get_user(user_id) - - update_data = data.model_dump(exclude_unset=True) - for field, value in update_data.items(): - setattr(user, field, value) - - return self.repository.update(user) - - def delete_user(self, user_id: int) -> None: - user = self.get_user(user_id) - self.repository.delete(user) - - -# Dependency -def get_user_service(db: Session = Depends(get_db)) -> UserService: - return UserService(db) -``` - -### 14.3 Router (Endpoints) - -```python -# app/routers/user.py -from fastapi import APIRouter, Depends, Query, status -from sqlalchemy.orm import Session - -from app.database import get_db -from app.schemas.user import UserCreate, UserUpdate, UserResponse, UserListResponse -from app.services.user import UserService, get_user_service - -router = APIRouter(prefix="/users", tags=["users"]) - - -@router.get("/", response_model=UserListResponse) -def list_users( - skip: int = Query(0, ge=0), - limit: int = Query(20, ge=1, le=100), - service: UserService = Depends(get_user_service), -): - users = service.repository.get_all(skip=skip, limit=limit) - return {"items": users, "total": len(users)} - - -@router.get("/{user_id}", response_model=UserResponse) -def get_user( - user_id: int, - service: UserService = Depends(get_user_service), -): - return service.get_user(user_id) - - -@router.post("/", response_model=UserResponse, status_code=status.HTTP_201_CREATED) -def create_user( - data: UserCreate, - service: UserService = Depends(get_user_service), -): - return service.create_user(data) - - -@router.patch("/{user_id}", response_model=UserResponse) -def update_user( - user_id: int, - data: UserUpdate, - service: UserService = Depends(get_user_service), -): - return service.update_user(user_id, data) - - -@router.delete("/{user_id}", status_code=status.HTTP_204_NO_CONTENT) -def delete_user( - user_id: int, - service: UserService = Depends(get_user_service), -): - service.delete_user(user_id) -``` - -### 14.4 Pydantic 스키마 - -```python -# app/schemas/user.py -from datetime import datetime -from typing import Optional, List -from pydantic import BaseModel, EmailStr, Field, ConfigDict - - -class UserBase(BaseModel): - email: EmailStr - username: str = Field(..., min_length=3, max_length=50) - full_name: Optional[str] = None - - -class UserCreate(UserBase): - password: str = Field(..., min_length=8) - - -class UserUpdate(BaseModel): - email: Optional[EmailStr] = None - username: Optional[str] = Field(None, min_length=3, max_length=50) - full_name: Optional[str] = None - is_active: Optional[bool] = None - - -class UserResponse(UserBase): - id: int - is_active: bool - created_at: datetime - - model_config = ConfigDict(from_attributes=True) - - -class UserListResponse(BaseModel): - items: List[UserResponse] - total: int -``` - ---- - -## 15. 성능 최적화 - -### 15.1 인덱스 최적화 - -```python -from sqlalchemy import Index - - -class User(Base): - __tablename__ = "user" - - id: Mapped[int] = mapped_column(primary_key=True) - email: Mapped[str] = mapped_column(String(255), unique=True) - status: Mapped[str] = mapped_column(String(20)) - created_at: Mapped[datetime] = mapped_column(default=func.now()) - - __table_args__ = ( - # 단일 인덱스 - Index("idx_user_status", "status"), - - # 복합 인덱스 - Index("idx_user_status_created", "status", "created_at"), - - # 부분 인덱스 (PostgreSQL) - Index( - "idx_user_active", - "email", - postgresql_where=text("status = 'active'"), - ), - ) -``` - -### 15.2 쿼리 최적화 - -```python -# ───────────────────────────────────────────────────── -# 1. 필요한 컬럼만 조회 -# ───────────────────────────────────────────────────── - -# Bad -users = db.scalars(select(User)).all() -emails = [u.email for u in users] - -# Good -emails = db.scalars(select(User.email)).all() - - -# ───────────────────────────────────────────────────── -# 2. N+1 문제 해결 -# ───────────────────────────────────────────────────── - -# Bad -users = db.scalars(select(User)).all() -for user in users: - print(user.posts) # N+1 - -# Good -stmt = select(User).options(selectinload(User.posts)) -users = db.scalars(stmt).all() - - -# ───────────────────────────────────────────────────── -# 3. Bulk 작업 사용 -# ───────────────────────────────────────────────────── - -# Bad - 개별 업데이트 -for user in users: - user.is_active = False - db.commit() - -# Good - Bulk 업데이트 -db.execute( - update(User) - .where(User.id.in_([u.id for u in users])) - .values(is_active=False) -) -db.commit() - - -# ───────────────────────────────────────────────────── -# 4. 존재 확인은 EXISTS 사용 -# ───────────────────────────────────────────────────── - -# Bad -user = db.scalar(select(User).where(User.email == email)) -exists = user is not None - -# Good -exists = db.scalar( - select(exists().where(User.email == email)) -) - - -# ───────────────────────────────────────────────────── -# 5. 카운트는 count() 사용 -# ───────────────────────────────────────────────────── - -# Bad -count = len(db.scalars(select(User)).all()) - -# Good -count = db.scalar(select(func.count(User.id))) -``` - -### 15.3 연결 풀 설정 - -```python -engine = create_engine( - DATABASE_URL, - pool_size=10, # 기본 연결 수 - max_overflow=20, # 추가 허용 연결 수 - pool_timeout=30, # 연결 대기 시간 - pool_recycle=1800, # 연결 재생성 주기 (30분) - pool_pre_ping=True, # 연결 유효성 사전 검사 -) -``` - -### 15.4 쿼리 실행 계획 확인 - -```python -from sqlalchemy import explain - -stmt = select(User).where(User.email == "test@example.com") - -# 실행 계획 출력 -print(db.execute(explain(stmt)).fetchall()) - -# MySQL EXPLAIN -print(db.execute(text(f"EXPLAIN {stmt}")).fetchall()) -``` - ---- - -## 16. 실무 레시피 - -### 16.1 Soft Delete 구현 - -```python -from datetime import datetime -from sqlalchemy import event - - -class SoftDeleteMixin: - is_deleted: Mapped[bool] = mapped_column(default=False) - deleted_at: Mapped[Optional[datetime]] = mapped_column(default=None) - - def soft_delete(self): - self.is_deleted = True - self.deleted_at = datetime.utcnow() - - -# 자동 필터링 (Global Filter) -@event.listens_for(Session, "do_orm_execute") -def _add_filtering_criteria(execute_state): - if execute_state.is_select: - execute_state.statement = execute_state.statement.options( - with_loader_criteria( - SoftDeleteMixin, - lambda cls: cls.is_deleted == False, - include_aliases=True, - ) - ) -``` - -### 16.2 Audit Log - -```python -from sqlalchemy import event - - -class AuditMixin: - created_by: Mapped[Optional[int]] = mapped_column(ForeignKey("user.id")) - updated_by: Mapped[Optional[int]] = mapped_column(ForeignKey("user.id")) - - -# 현재 사용자 컨텍스트 -from contextvars import ContextVar -current_user_id: ContextVar[Optional[int]] = ContextVar("current_user_id", default=None) - - -@event.listens_for(AuditMixin, "before_insert", propagate=True) -def set_created_by(mapper, connection, target): - if user_id := current_user_id.get(): - target.created_by = user_id - target.updated_by = user_id - - -@event.listens_for(AuditMixin, "before_update", propagate=True) -def set_updated_by(mapper, connection, target): - if user_id := current_user_id.get(): - target.updated_by = user_id - - -# FastAPI 미들웨어 -@app.middleware("http") -async def set_current_user(request: Request, call_next): - user_id = get_user_id_from_token(request) - token = current_user_id.set(user_id) - try: - response = await call_next(request) - return response - finally: - current_user_id.reset(token) -``` - -### 16.3 전체 텍스트 검색 - -```python -from sqlalchemy import Index, text - - -class Post(Base): - __tablename__ = "post" - - id: Mapped[int] = mapped_column(primary_key=True) - title: Mapped[str] = mapped_column(String(200)) - content: Mapped[str] = mapped_column(Text) - - __table_args__ = ( - # MySQL FULLTEXT 인덱스 - Index( - "idx_post_fulltext", - "title", "content", - mysql_prefix="FULLTEXT", - ), - ) - - -def search_posts(db: Session, keyword: str) -> list[Post]: - stmt = ( - select(Post) - .where( - text("MATCH(title, content) AGAINST(:keyword IN BOOLEAN MODE)") - ) - .params(keyword=keyword) - ) - return list(db.scalars(stmt).all()) -``` - -### 16.4 슬러그 자동 생성 - -```python -from sqlalchemy import event -import re - - -def slugify(text: str) -> str: - text = text.lower() - text = re.sub(r'[^\w\s-]', '', text) - text = re.sub(r'[-\s]+', '-', text).strip('-') - return text - - -class Post(Base): - title: Mapped[str] = mapped_column(String(200)) - slug: Mapped[str] = mapped_column(String(200), unique=True) - - -@event.listens_for(Post.title, "set") -def generate_slug(target, value, oldvalue, initiator): - if value and (not target.slug or oldvalue != value): - target.slug = slugify(value) -``` - -### 16.5 캐싱 패턴 - -```python -from functools import lru_cache -from typing import Optional -import json -import redis - -redis_client = redis.Redis() - - -class CachedUserRepository: - def __init__(self, db: Session): - self.db = db - self.cache_ttl = 3600 # 1시간 - - def _cache_key(self, user_id: int) -> str: - return f"user:{user_id}" - - def get(self, user_id: int) -> Optional[User]: - # 캐시 확인 - cached = redis_client.get(self._cache_key(user_id)) - if cached: - data = json.loads(cached) - return User(**data) - - # DB 조회 - user = self.db.get(User, user_id) - if user: - # 캐시 저장 - redis_client.setex( - self._cache_key(user_id), - self.cache_ttl, - json.dumps(user.to_dict()), - ) - - return user - - def invalidate(self, user_id: int) -> None: - redis_client.delete(self._cache_key(user_id)) -``` - ---- - -## 부록: Quick Reference - -### 자주 사용하는 import - -```python -from sqlalchemy import ( - create_engine, select, insert, update, delete, - and_, or_, not_, func, case, cast, exists, - text, literal, literal_column, - Index, ForeignKey, String, Integer, Text, Boolean, - desc, asc, nullsfirst, nullslast, -) -from sqlalchemy.orm import ( - Session, sessionmaker, relationship, - Mapped, mapped_column, - selectinload, joinedload, subqueryload, raiseload, - contains_eager, aliased, -) -from sqlalchemy.dialects.mysql import insert as mysql_insert -from sqlalchemy.dialects.postgresql import insert as pg_insert -``` - -### 쿼리 실행 메서드 - -```python -db.execute(stmt) # Result 반환 -db.scalars(stmt) # ScalarResult 반환 -db.scalar(stmt) # 단일 값 반환 - -result.all() # 모든 결과 -result.first() # 첫 번째 (없으면 None) -result.one() # 정확히 1개 (아니면 예외) -result.one_or_none() # 0-1개 (2개 이상 예외) -result.unique() # 중복 제거 -``` - -### 관계 로딩 전략 - -```python -selectinload(Model.relation) # 1:N - SELECT ... IN -joinedload(Model.relation) # N:1, 1:1 - JOIN -subqueryload(Model.relation) # 복잡한 필터 -raiseload(Model.relation) # 로딩 금지 -``` +# FastAPI + SQLAlchemy ORM 완벽 실무 가이드 + +> SQLAlchemy 2.0+ / FastAPI 0.100+ / Python 3.10+ 기준 + +--- + +## 목차 + +1. [기본 설정](#1-기본-설정) +2. [모델 정의](#2-모델-정의) +3. [CRUD 기본 작업](#3-crud-기본-작업) +4. [조회 쿼리 심화](#4-조회-쿼리-심화) +5. [필터링과 조건](#5-필터링과-조건) +6. [정렬, 페이징, 제한](#6-정렬-페이징-제한) +7. [집계 함수 (Aggregation)](#7-집계-함수-aggregation) +8. [JOIN 쿼리](#8-join-쿼리) +9. [서브쿼리 (Subquery)](#9-서브쿼리-subquery) +10. [집합 연산 (Union, Intersect, Except)](#10-집합-연산-union-intersect-except) +11. [고급 표현식](#11-고급-표현식) +12. [Relationship과 Eager Loading](#12-relationship과-eager-loading) +13. [트랜잭션 관리](#13-트랜잭션-관리) +14. [FastAPI 통합 패턴](#14-fastapi-통합-패턴) +15. [성능 최적화](#15-성능-최적화) +16. [실무 레시피](#16-실무-레시피) + +--- + +## 1. 기본 설정 + +### 1.1 프로젝트 구조 + +``` +project/ +├── app/ +│ ├── __init__.py +│ ├── main.py +│ ├── config.py +│ ├── database.py +│ ├── models/ +│ │ ├── __init__.py +│ │ ├── base.py +│ │ ├── user.py +│ │ └── product.py +│ ├── schemas/ +│ │ ├── __init__.py +│ │ ├── user.py +│ │ └── product.py +│ ├── repositories/ +│ │ ├── __init__.py +│ │ └── user.py +│ ├── services/ +│ │ ├── __init__.py +│ │ └── user.py +│ └── routers/ +│ ├── __init__.py +│ └── user.py +├── alembic/ +├── tests/ +├── alembic.ini +├── requirements.txt +└── .env +``` + +### 1.2 Database 설정 + +```python +# app/config.py +from pydantic_settings import BaseSettings +from functools import lru_cache + + +class Settings(BaseSettings): + DATABASE_URL: str = "mysql+pymysql://user:pass@localhost:3306/dbname" + DATABASE_ECHO: bool = False # SQL 로그 출력 + DATABASE_POOL_SIZE: int = 5 + DATABASE_MAX_OVERFLOW: int = 10 + + class Config: + env_file = ".env" + + +@lru_cache +def get_settings() -> Settings: + return Settings() +``` + +```python +# app/database.py +from sqlalchemy import create_engine +from sqlalchemy.orm import sessionmaker, Session +from typing import Generator + +from app.config import get_settings + +settings = get_settings() + +# Engine 생성 +engine = create_engine( + settings.DATABASE_URL, + echo=settings.DATABASE_ECHO, + pool_size=settings.DATABASE_POOL_SIZE, + max_overflow=settings.DATABASE_MAX_OVERFLOW, + pool_pre_ping=True, # 연결 유효성 검사 + pool_recycle=3600, # 1시간마다 연결 재생성 +) + +# Session Factory +SessionLocal = sessionmaker( + bind=engine, + autocommit=False, + autoflush=False, + expire_on_commit=False, # commit 후에도 객체 접근 가능 +) + + +# Dependency +def get_db() -> Generator[Session, None, None]: + db = SessionLocal() + try: + yield db + finally: + db.close() +``` + +### 1.3 Base 모델 정의 + +```python +# app/models/base.py +from datetime import datetime +from sqlalchemy import func +from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column + + +class Base(DeclarativeBase): + """모든 모델의 기본 클래스""" + pass + + +class TimestampMixin: + """생성/수정 시간 믹스인""" + created_at: Mapped[datetime] = mapped_column( + default=func.now(), + nullable=False, + ) + updated_at: Mapped[datetime] = mapped_column( + default=func.now(), + onupdate=func.now(), + nullable=False, + ) + + +class SoftDeleteMixin: + """소프트 삭제 믹스인""" + is_deleted: Mapped[bool] = mapped_column(default=False) + deleted_at: Mapped[datetime | None] = mapped_column(default=None) +``` + +--- + +## 2. 모델 정의 + +### 2.1 기본 모델 + +```python +# app/models/user.py +from typing import List, Optional +from sqlalchemy import String, Text, Boolean, Integer, ForeignKey, Index +from sqlalchemy.orm import Mapped, mapped_column, relationship + +from app.models.base import Base, TimestampMixin + + +class User(TimestampMixin, Base): + __tablename__ = "user" + + # Primary Key + id: Mapped[int] = mapped_column(primary_key=True) + + # 필수 필드 + email: Mapped[str] = mapped_column(String(255), unique=True, index=True) + username: Mapped[str] = mapped_column(String(50), unique=True) + hashed_password: Mapped[str] = mapped_column(String(255)) + + # 선택 필드 (nullable) + full_name: Mapped[Optional[str]] = mapped_column(String(100)) + bio: Mapped[Optional[str]] = mapped_column(Text) + + # 기본값이 있는 필드 + is_active: Mapped[bool] = mapped_column(default=True) + is_superuser: Mapped[bool] = mapped_column(default=False) + login_count: Mapped[int] = mapped_column(default=0) + + # Relationships + posts: Mapped[List["Post"]] = relationship( + "Post", + back_populates="author", + cascade="all, delete-orphan", + lazy="selectin", + ) + + profile: Mapped[Optional["Profile"]] = relationship( + "Profile", + back_populates="user", + uselist=False, + cascade="all, delete-orphan", + ) + + # 테이블 설정 + __table_args__ = ( + Index("idx_user_email_active", "email", "is_active"), + {"mysql_engine": "InnoDB", "mysql_charset": "utf8mb4"}, + ) + + def __repr__(self) -> str: + return f"" +``` + +### 2.2 관계가 있는 모델들 + +```python +# app/models/post.py +from typing import List, Optional +from sqlalchemy import String, Text, ForeignKey, Index +from sqlalchemy.orm import Mapped, mapped_column, relationship + +from app.models.base import Base, TimestampMixin + + +class Post(TimestampMixin, Base): + __tablename__ = "post" + + id: Mapped[int] = mapped_column(primary_key=True) + title: Mapped[str] = mapped_column(String(200)) + content: Mapped[str] = mapped_column(Text) + view_count: Mapped[int] = mapped_column(default=0) + is_published: Mapped[bool] = mapped_column(default=False) + + # Foreign Key + author_id: Mapped[int] = mapped_column( + ForeignKey("user.id", ondelete="CASCADE"), + index=True, + ) + category_id: Mapped[Optional[int]] = mapped_column( + ForeignKey("category.id", ondelete="SET NULL"), + nullable=True, + ) + + # Relationships + author: Mapped["User"] = relationship("User", back_populates="posts") + category: Mapped[Optional["Category"]] = relationship("Category", back_populates="posts") + comments: Mapped[List["Comment"]] = relationship( + "Comment", + back_populates="post", + cascade="all, delete-orphan", + order_by="Comment.created_at.desc()", + ) + + # N:M 관계 + tags: Mapped[List["Tag"]] = relationship( + "Tag", + secondary="post_tag", + back_populates="posts", + ) + + __table_args__ = ( + Index("idx_post_author_published", "author_id", "is_published"), + ) + + +class Category(Base): + __tablename__ = "category" + + id: Mapped[int] = mapped_column(primary_key=True) + name: Mapped[str] = mapped_column(String(50), unique=True) + description: Mapped[Optional[str]] = mapped_column(Text) + + posts: Mapped[List["Post"]] = relationship("Post", back_populates="category") + + +class Tag(Base): + __tablename__ = "tag" + + id: Mapped[int] = mapped_column(primary_key=True) + name: Mapped[str] = mapped_column(String(30), unique=True) + + posts: Mapped[List["Post"]] = relationship( + "Post", + secondary="post_tag", + back_populates="tags", + ) + + +# N:M 중간 테이블 +from sqlalchemy import Table, Column, Integer, ForeignKey +from app.models.base import Base + +post_tag = Table( + "post_tag", + Base.metadata, + Column("post_id", Integer, ForeignKey("post.id", ondelete="CASCADE"), primary_key=True), + Column("tag_id", Integer, ForeignKey("tag.id", ondelete="CASCADE"), primary_key=True), +) +``` + +--- + +## 3. CRUD 기본 작업 + +### 3.1 Create (생성) + +```python +from sqlalchemy import select +from sqlalchemy.orm import Session +from app.models.user import User + + +# ───────────────────────────────────────────────────── +# 단일 레코드 생성 +# ───────────────────────────────────────────────────── + +def create_user(db: Session, email: str, username: str, password: str) -> User: + user = User( + email=email, + username=username, + hashed_password=password, + ) + db.add(user) + db.commit() + db.refresh(user) # DB에서 생성된 값(id, created_at 등) 로드 + return user + + +# ───────────────────────────────────────────────────── +# 여러 레코드 한번에 생성 +# ───────────────────────────────────────────────────── + +def create_users_bulk(db: Session, users_data: list[dict]) -> list[User]: + users = [User(**data) for data in users_data] + db.add_all(users) + db.commit() + + # 각 객체 refresh + for user in users: + db.refresh(user) + + return users + + +# ───────────────────────────────────────────────────── +# 관계와 함께 생성 +# ───────────────────────────────────────────────────── + +def create_post_with_tags( + db: Session, + title: str, + content: str, + author_id: int, + tag_names: list[str] +) -> Post: + # 기존 태그 조회 또는 생성 + tags = [] + for name in tag_names: + tag = db.scalar(select(Tag).where(Tag.name == name)) + if not tag: + tag = Tag(name=name) + tags.append(tag) + + post = Post( + title=title, + content=content, + author_id=author_id, + tags=tags, + ) + db.add(post) + db.commit() + db.refresh(post) + return post + + +# ───────────────────────────────────────────────────── +# Insert ... ON DUPLICATE KEY UPDATE (Upsert) +# ───────────────────────────────────────────────────── + +from sqlalchemy.dialects.mysql import insert as mysql_insert + +def upsert_user(db: Session, email: str, username: str) -> None: + stmt = mysql_insert(User).values( + email=email, + username=username, + ) + stmt = stmt.on_duplicate_key_update( + username=stmt.inserted.username, + updated_at=func.now(), + ) + db.execute(stmt) + db.commit() + + +# PostgreSQL의 경우 +from sqlalchemy.dialects.postgresql import insert as pg_insert + +def upsert_user_pg(db: Session, email: str, username: str) -> None: + stmt = pg_insert(User).values(email=email, username=username) + stmt = stmt.on_conflict_do_update( + index_elements=["email"], + set_={"username": username}, + ) + db.execute(stmt) + db.commit() +``` + +### 3.2 Read (조회) + +```python +from sqlalchemy import select +from sqlalchemy.orm import Session + + +# ───────────────────────────────────────────────────── +# Primary Key로 조회 +# ───────────────────────────────────────────────────── + +def get_user_by_id(db: Session, user_id: int) -> User | None: + return db.get(User, user_id) + + +# ───────────────────────────────────────────────────── +# 단일 레코드 조회 (조건) +# ───────────────────────────────────────────────────── + +def get_user_by_email(db: Session, email: str) -> User | None: + stmt = select(User).where(User.email == email) + return db.scalar(stmt) + + +# scalar(): 단일 값 반환 (없으면 None) +# scalars(): 여러 값의 ScalarResult 반환 +# one(): 정확히 1개 (0개 또는 2개 이상이면 에러) +# one_or_none(): 0개면 None, 1개면 반환, 2개 이상이면 에러 +# first(): 첫 번째 결과 (없으면 None) + + +# ───────────────────────────────────────────────────── +# 여러 레코드 조회 +# ───────────────────────────────────────────────────── + +def get_all_users(db: Session) -> list[User]: + stmt = select(User) + return list(db.scalars(stmt).all()) + + +def get_active_users(db: Session) -> list[User]: + stmt = select(User).where(User.is_active == True) + return list(db.scalars(stmt).all()) + + +# ───────────────────────────────────────────────────── +# 특정 컬럼만 조회 +# ───────────────────────────────────────────────────── + +def get_user_emails(db: Session) -> list[str]: + stmt = select(User.email) + return list(db.scalars(stmt).all()) + + +def get_user_summary(db: Session) -> list[tuple]: + stmt = select(User.id, User.email, User.username) + return list(db.execute(stmt).all()) + + +# ───────────────────────────────────────────────────── +# 존재 여부 확인 +# ───────────────────────────────────────────────────── + +def user_exists(db: Session, email: str) -> bool: + stmt = select(User.id).where(User.email == email) + return db.scalar(stmt) is not None + + +# 또는 exists() 사용 +from sqlalchemy import exists + +def user_exists_v2(db: Session, email: str) -> bool: + stmt = select(exists().where(User.email == email)) + return db.scalar(stmt) +``` + +### 3.3 Update (수정) + +```python +from sqlalchemy import update +from sqlalchemy.orm import Session + + +# ───────────────────────────────────────────────────── +# 단일 레코드 수정 (ORM 방식) +# ───────────────────────────────────────────────────── + +def update_user(db: Session, user_id: int, **kwargs) -> User | None: + user = db.get(User, user_id) + if not user: + return None + + for key, value in kwargs.items(): + if hasattr(user, key): + setattr(user, key, value) + + db.commit() + db.refresh(user) + return user + + +# ───────────────────────────────────────────────────── +# Bulk Update (Core 방식) - 더 효율적 +# ───────────────────────────────────────────────────── + +def deactivate_users(db: Session, user_ids: list[int]) -> int: + stmt = ( + update(User) + .where(User.id.in_(user_ids)) + .values(is_active=False) + ) + result = db.execute(stmt) + db.commit() + return result.rowcount # 영향받은 행 수 + + +# ───────────────────────────────────────────────────── +# 조건부 Update +# ───────────────────────────────────────────────────── + +def increment_login_count(db: Session, user_id: int) -> None: + stmt = ( + update(User) + .where(User.id == user_id) + .values(login_count=User.login_count + 1) + ) + db.execute(stmt) + db.commit() + + +# ───────────────────────────────────────────────────── +# CASE를 사용한 조건부 Update +# ───────────────────────────────────────────────────── + +from sqlalchemy import case + +def update_user_levels(db: Session) -> None: + stmt = ( + update(User) + .values( + level=case( + (User.login_count >= 100, "gold"), + (User.login_count >= 50, "silver"), + else_="bronze", + ) + ) + ) + db.execute(stmt) + db.commit() +``` + +### 3.4 Delete (삭제) + +```python +from sqlalchemy import delete +from sqlalchemy.orm import Session + + +# ───────────────────────────────────────────────────── +# 단일 레코드 삭제 (ORM 방식) +# ───────────────────────────────────────────────────── + +def delete_user(db: Session, user_id: int) -> bool: + user = db.get(User, user_id) + if not user: + return False + + db.delete(user) # cascade 설정에 따라 관련 데이터도 삭제 + db.commit() + return True + + +# ───────────────────────────────────────────────────── +# Bulk Delete (Core 방식) - 더 효율적 +# ───────────────────────────────────────────────────── + +def delete_inactive_users(db: Session) -> int: + stmt = delete(User).where(User.is_active == False) + result = db.execute(stmt) + db.commit() + return result.rowcount + + +# ───────────────────────────────────────────────────── +# Soft Delete +# ───────────────────────────────────────────────────── + +from datetime import datetime + +def soft_delete_user(db: Session, user_id: int) -> bool: + stmt = ( + update(User) + .where(User.id == user_id) + .values(is_deleted=True, deleted_at=datetime.utcnow()) + ) + result = db.execute(stmt) + db.commit() + return result.rowcount > 0 + + +# ───────────────────────────────────────────────────── +# 관계 데이터 삭제 +# ───────────────────────────────────────────────────── + +def remove_tag_from_post(db: Session, post_id: int, tag_id: int) -> None: + post = db.get(Post, post_id) + tag = db.get(Tag, tag_id) + + if post and tag and tag in post.tags: + post.tags.remove(tag) + db.commit() +``` + +--- + +## 4. 조회 쿼리 심화 + +### 4.1 select() 기본 사용법 + +```python +from sqlalchemy import select + + +# ───────────────────────────────────────────────────── +# 전체 모델 조회 +# ───────────────────────────────────────────────────── + +stmt = select(User) +# SELECT user.id, user.email, user.username, ... FROM user + + +# ───────────────────────────────────────────────────── +# 특정 컬럼만 조회 +# ───────────────────────────────────────────────────── + +stmt = select(User.id, User.email) +# SELECT user.id, user.email FROM user + + +# ───────────────────────────────────────────────────── +# 컬럼 별칭 (alias) +# ───────────────────────────────────────────────────── + +stmt = select(User.email.label("user_email")) +# SELECT user.email AS user_email FROM user + + +# ───────────────────────────────────────────────────── +# DISTINCT +# ───────────────────────────────────────────────────── + +stmt = select(User.category_id).distinct() +# SELECT DISTINCT user.category_id FROM user + + +# ───────────────────────────────────────────────────── +# 여러 테이블에서 조회 +# ───────────────────────────────────────────────────── + +stmt = select(User, Post).join(Post) +# SELECT user.*, post.* FROM user JOIN post ON ... + + +stmt = select(User.email, Post.title).join(Post) +# SELECT user.email, post.title FROM user JOIN post ON ... +``` + +### 4.2 실행 메서드 비교 + +```python +from sqlalchemy.orm import Session + + +# ───────────────────────────────────────────────────── +# execute() - Row 객체 반환 +# ───────────────────────────────────────────────────── + +stmt = select(User.id, User.email) +result = db.execute(stmt) + +for row in result: + print(row.id, row.email) # Row 객체 + print(row[0], row[1]) # 인덱스 접근 + print(row._mapping) # dict-like 접근 + + +# ───────────────────────────────────────────────────── +# scalars() - 첫 번째 컬럼만 반환 +# ───────────────────────────────────────────────────── + +stmt = select(User) +users = db.scalars(stmt).all() # list[User] + +stmt = select(User.email) +emails = db.scalars(stmt).all() # list[str] + + +# ───────────────────────────────────────────────────── +# scalar() - 단일 값 반환 +# ───────────────────────────────────────────────────── + +stmt = select(User).where(User.id == 1) +user = db.scalar(stmt) # User | None + +stmt = select(func.count(User.id)) +count = db.scalar(stmt) # int + + +# ───────────────────────────────────────────────────── +# 결과 처리 메서드 +# ───────────────────────────────────────────────────── + +result = db.scalars(stmt) + +result.all() # 모든 결과를 리스트로 +result.first() # 첫 번째 결과 (없으면 None) +result.one() # 정확히 1개 (아니면 예외) +result.one_or_none()# 0-1개 (2개 이상이면 예외) +result.fetchmany(5) # 5개만 가져오기 +result.unique() # 중복 제거 (relationship 로딩 시 필요) +``` + +--- + +## 5. 필터링과 조건 + +### 5.1 기본 비교 연산자 + +```python +from sqlalchemy import select, and_, or_, not_ + + +# ───────────────────────────────────────────────────── +# 동등 비교 +# ───────────────────────────────────────────────────── + +stmt = select(User).where(User.email == "test@example.com") +stmt = select(User).where(User.is_active == True) +stmt = select(User).where(User.category_id == None) # IS NULL + + +# ───────────────────────────────────────────────────── +# 부등 비교 +# ───────────────────────────────────────────────────── + +stmt = select(User).where(User.age != 30) +stmt = select(User).where(User.age > 18) +stmt = select(User).where(User.age >= 18) +stmt = select(User).where(User.age < 65) +stmt = select(User).where(User.age <= 65) + + +# ───────────────────────────────────────────────────── +# BETWEEN +# ───────────────────────────────────────────────────── + +stmt = select(User).where(User.age.between(18, 65)) +# WHERE age BETWEEN 18 AND 65 + + +# ───────────────────────────────────────────────────── +# IN / NOT IN +# ───────────────────────────────────────────────────── + +stmt = select(User).where(User.status.in_(["active", "pending"])) +stmt = select(User).where(User.id.in_([1, 2, 3, 4, 5])) +stmt = select(User).where(User.status.not_in(["deleted", "banned"])) + + +# ───────────────────────────────────────────────────── +# IS NULL / IS NOT NULL +# ───────────────────────────────────────────────────── + +stmt = select(User).where(User.deleted_at.is_(None)) # IS NULL +stmt = select(User).where(User.deleted_at.is_not(None)) # IS NOT NULL +stmt = select(User).where(User.bio.isnot(None)) # 또 다른 방법 +``` + +### 5.2 문자열 연산 + +```python +# ───────────────────────────────────────────────────── +# LIKE / ILIKE +# ───────────────────────────────────────────────────── + +stmt = select(User).where(User.email.like("%@gmail.com")) +stmt = select(User).where(User.username.like("john%")) +stmt = select(User).where(User.name.like("%홍길%")) + +# 대소문자 무시 (PostgreSQL) +stmt = select(User).where(User.email.ilike("%@GMAIL.COM")) + + +# ───────────────────────────────────────────────────── +# CONTAINS (LIKE '%value%') +# ───────────────────────────────────────────────────── + +stmt = select(User).where(User.bio.contains("python")) +# WHERE bio LIKE '%python%' + + +# ───────────────────────────────────────────────────── +# STARTSWITH / ENDSWITH +# ───────────────────────────────────────────────────── + +stmt = select(User).where(User.email.startswith("admin")) +# WHERE email LIKE 'admin%' + +stmt = select(User).where(User.email.endswith("@company.com")) +# WHERE email LIKE '%@company.com' + + +# ───────────────────────────────────────────────────── +# 정규표현식 (DB 지원 필요) +# ───────────────────────────────────────────────────── + +stmt = select(User).where(User.email.regexp_match(r"^[a-z]+@")) +``` + +### 5.3 논리 연산자 + +```python +from sqlalchemy import and_, or_, not_ + + +# ───────────────────────────────────────────────────── +# AND +# ───────────────────────────────────────────────────── + +# 방법 1: and_() 함수 +stmt = select(User).where( + and_( + User.is_active == True, + User.age >= 18, + ) +) + +# 방법 2: where() 체이닝 (암묵적 AND) +stmt = select(User).where(User.is_active == True).where(User.age >= 18) + +# 방법 3: 콤마로 구분 +stmt = select(User).where(User.is_active == True, User.age >= 18) + + +# ───────────────────────────────────────────────────── +# OR +# ───────────────────────────────────────────────────── + +stmt = select(User).where( + or_( + User.role == "admin", + User.role == "moderator", + ) +) + + +# ───────────────────────────────────────────────────── +# NOT +# ───────────────────────────────────────────────────── + +stmt = select(User).where(not_(User.is_deleted == True)) +stmt = select(User).where(~(User.is_deleted == True)) # ~ 연산자 + + +# ───────────────────────────────────────────────────── +# 복합 조건 +# ───────────────────────────────────────────────────── + +stmt = select(User).where( + and_( + User.is_active == True, + or_( + User.role == "admin", + User.age >= 21, + ), + not_(User.is_deleted == True), + ) +) +# WHERE is_active = true +# AND (role = 'admin' OR age >= 21) +# AND NOT is_deleted = true +``` + +### 5.4 동적 필터링 + +```python +from typing import Optional + + +def search_users( + db: Session, + email: Optional[str] = None, + username: Optional[str] = None, + is_active: Optional[bool] = None, + min_age: Optional[int] = None, + max_age: Optional[int] = None, +) -> list[User]: + stmt = select(User) + + # 동적으로 조건 추가 + if email: + stmt = stmt.where(User.email.contains(email)) + + if username: + stmt = stmt.where(User.username.like(f"%{username}%")) + + if is_active is not None: + stmt = stmt.where(User.is_active == is_active) + + if min_age is not None: + stmt = stmt.where(User.age >= min_age) + + if max_age is not None: + stmt = stmt.where(User.age <= max_age) + + return list(db.scalars(stmt).all()) + + +# 사용 +users = search_users(db, email="gmail", is_active=True, min_age=18) +``` + +--- + +## 6. 정렬, 페이징, 제한 + +### 6.1 정렬 (ORDER BY) + +```python +from sqlalchemy import select, asc, desc + + +# ───────────────────────────────────────────────────── +# 기본 정렬 +# ───────────────────────────────────────────────────── + +# 오름차순 (기본) +stmt = select(User).order_by(User.created_at) +stmt = select(User).order_by(asc(User.created_at)) + +# 내림차순 +stmt = select(User).order_by(desc(User.created_at)) +stmt = select(User).order_by(User.created_at.desc()) + + +# ───────────────────────────────────────────────────── +# 다중 정렬 +# ───────────────────────────────────────────────────── + +stmt = select(User).order_by( + User.is_active.desc(), + User.created_at.desc(), +) +# ORDER BY is_active DESC, created_at DESC + + +# ───────────────────────────────────────────────────── +# NULL 처리 +# ───────────────────────────────────────────────────── + +stmt = select(User).order_by(User.last_login.desc().nullslast()) +# NULL 값을 마지막에 + +stmt = select(User).order_by(User.last_login.asc().nullsfirst()) +# NULL 값을 처음에 +``` + +### 6.2 제한과 오프셋 (LIMIT, OFFSET) + +```python +# ───────────────────────────────────────────────────── +# LIMIT +# ───────────────────────────────────────────────────── + +stmt = select(User).limit(10) +# SELECT ... FROM user LIMIT 10 + + +# ───────────────────────────────────────────────────── +# OFFSET +# ───────────────────────────────────────────────────── + +stmt = select(User).offset(20).limit(10) +# SELECT ... FROM user LIMIT 10 OFFSET 20 + + +# ───────────────────────────────────────────────────── +# 슬라이스 문법 +# ───────────────────────────────────────────────────── + +stmt = select(User).slice(20, 30) # offset=20, limit=10과 동일 +``` + +### 6.3 페이지네이션 구현 + +```python +from typing import TypeVar, Generic +from pydantic import BaseModel +from sqlalchemy import select, func +from sqlalchemy.orm import Session + +T = TypeVar("T") + + +class PaginatedResult(BaseModel, Generic[T]): + items: list[T] + total: int + page: int + page_size: int + total_pages: int + has_next: bool + has_prev: bool + + +def paginate( + db: Session, + stmt, + page: int = 1, + page_size: int = 20, +) -> dict: + # 페이지 유효성 검사 + page = max(1, page) + page_size = min(max(1, page_size), 100) # 최대 100개 + + # 전체 개수 조회 + count_stmt = select(func.count()).select_from(stmt.subquery()) + total = db.scalar(count_stmt) + + # 페이지네이션 적용 + offset = (page - 1) * page_size + paginated_stmt = stmt.offset(offset).limit(page_size) + items = list(db.scalars(paginated_stmt).all()) + + total_pages = (total + page_size - 1) // page_size + + return { + "items": items, + "total": total, + "page": page, + "page_size": page_size, + "total_pages": total_pages, + "has_next": page < total_pages, + "has_prev": page > 1, + } + + +# 사용 예시 +def get_users_paginated( + db: Session, + page: int = 1, + page_size: int = 20, + is_active: bool | None = None, +) -> dict: + stmt = select(User).order_by(User.created_at.desc()) + + if is_active is not None: + stmt = stmt.where(User.is_active == is_active) + + return paginate(db, stmt, page, page_size) + + +# FastAPI 엔드포인트 +@router.get("/users") +def list_users( + page: int = Query(1, ge=1), + page_size: int = Query(20, ge=1, le=100), + is_active: bool | None = None, + db: Session = Depends(get_db), +): + return get_users_paginated(db, page, page_size, is_active) +``` + +### 6.4 커서 기반 페이지네이션 + +```python +from datetime import datetime +from typing import Optional + + +def get_users_cursor( + db: Session, + limit: int = 20, + cursor: Optional[datetime] = None, +) -> dict: + stmt = select(User).order_by(User.created_at.desc()) + + if cursor: + stmt = stmt.where(User.created_at < cursor) + + stmt = stmt.limit(limit + 1) # 다음 페이지 확인용으로 1개 더 + + items = list(db.scalars(stmt).all()) + + has_next = len(items) > limit + if has_next: + items = items[:limit] + + next_cursor = items[-1].created_at if items and has_next else None + + return { + "items": items, + "next_cursor": next_cursor, + "has_next": has_next, + } + + +# 복합 커서 (동일 시간 처리) +def get_users_cursor_v2( + db: Session, + limit: int = 20, + cursor_time: Optional[datetime] = None, + cursor_id: Optional[int] = None, +) -> dict: + stmt = select(User).order_by( + User.created_at.desc(), + User.id.desc(), + ) + + if cursor_time and cursor_id: + stmt = stmt.where( + or_( + User.created_at < cursor_time, + and_( + User.created_at == cursor_time, + User.id < cursor_id, + ), + ) + ) + + stmt = stmt.limit(limit + 1) + items = list(db.scalars(stmt).all()) + + has_next = len(items) > limit + if has_next: + items = items[:limit] + + return { + "items": items, + "next_cursor": { + "time": items[-1].created_at, + "id": items[-1].id, + } if items and has_next else None, + "has_next": has_next, + } +``` + +--- + +## 7. 집계 함수 (Aggregation) + +### 7.1 기본 집계 함수 + +```python +from sqlalchemy import select, func + + +# ───────────────────────────────────────────────────── +# COUNT +# ───────────────────────────────────────────────────── + +# 전체 개수 +stmt = select(func.count(User.id)) +total = db.scalar(stmt) + +# 조건부 개수 +stmt = select(func.count(User.id)).where(User.is_active == True) +active_count = db.scalar(stmt) + +# COUNT(DISTINCT) +stmt = select(func.count(func.distinct(User.category_id))) +unique_categories = db.scalar(stmt) + + +# ───────────────────────────────────────────────────── +# SUM +# ───────────────────────────────────────────────────── + +stmt = select(func.sum(Order.amount)) +total_amount = db.scalar(stmt) + +stmt = select(func.sum(Order.amount)).where(Order.status == "completed") +completed_amount = db.scalar(stmt) + + +# ───────────────────────────────────────────────────── +# AVG +# ───────────────────────────────────────────────────── + +stmt = select(func.avg(Product.price)) +avg_price = db.scalar(stmt) + +# 반올림 +stmt = select(func.round(func.avg(Product.price), 2)) +avg_price_rounded = db.scalar(stmt) + + +# ───────────────────────────────────────────────────── +# MIN / MAX +# ───────────────────────────────────────────────────── + +stmt = select(func.min(Product.price), func.max(Product.price)) +result = db.execute(stmt).first() +min_price, max_price = result + + +# ───────────────────────────────────────────────────── +# 여러 집계 함수 함께 사용 +# ───────────────────────────────────────────────────── + +stmt = select( + func.count(Order.id).label("order_count"), + func.sum(Order.amount).label("total_amount"), + func.avg(Order.amount).label("avg_amount"), + func.min(Order.amount).label("min_amount"), + func.max(Order.amount).label("max_amount"), +) +result = db.execute(stmt).first() + +print(f"주문 수: {result.order_count}") +print(f"총 금액: {result.total_amount}") +print(f"평균 금액: {result.avg_amount}") +``` + +### 7.2 GROUP BY + +```python +# ───────────────────────────────────────────────────── +# 기본 GROUP BY +# ───────────────────────────────────────────────────── + +# 카테고리별 상품 수 +stmt = ( + select( + Product.category_id, + func.count(Product.id).label("product_count"), + ) + .group_by(Product.category_id) +) +results = db.execute(stmt).all() + +for row in results: + print(f"Category {row.category_id}: {row.product_count} products") + + +# ───────────────────────────────────────────────────── +# JOIN과 함께 GROUP BY +# ───────────────────────────────────────────────────── + +# 카테고리 이름과 함께 +stmt = ( + select( + Category.name, + func.count(Product.id).label("product_count"), + func.avg(Product.price).label("avg_price"), + ) + .join(Product, Category.id == Product.category_id) + .group_by(Category.id, Category.name) +) + + +# ───────────────────────────────────────────────────── +# 날짜별 GROUP BY +# ───────────────────────────────────────────────────── + +# 일별 주문 통계 +stmt = ( + select( + func.date(Order.created_at).label("order_date"), + func.count(Order.id).label("order_count"), + func.sum(Order.amount).label("total_amount"), + ) + .group_by(func.date(Order.created_at)) + .order_by(func.date(Order.created_at).desc()) +) + +# 월별 주문 통계 +stmt = ( + select( + func.year(Order.created_at).label("year"), + func.month(Order.created_at).label("month"), + func.count(Order.id).label("order_count"), + func.sum(Order.amount).label("total_amount"), + ) + .group_by( + func.year(Order.created_at), + func.month(Order.created_at), + ) + .order_by( + func.year(Order.created_at).desc(), + func.month(Order.created_at).desc(), + ) +) + + +# ───────────────────────────────────────────────────── +# 다중 컬럼 GROUP BY +# ───────────────────────────────────────────────────── + +stmt = ( + select( + User.country, + User.city, + func.count(User.id).label("user_count"), + ) + .group_by(User.country, User.city) + .order_by(func.count(User.id).desc()) +) +``` + +### 7.3 HAVING + +```python +# ───────────────────────────────────────────────────── +# 집계 결과 필터링 +# ───────────────────────────────────────────────────── + +# 5개 이상 상품이 있는 카테고리만 +stmt = ( + select( + Category.name, + func.count(Product.id).label("product_count"), + ) + .join(Product) + .group_by(Category.id, Category.name) + .having(func.count(Product.id) >= 5) +) + + +# ───────────────────────────────────────────────────── +# 복합 HAVING 조건 +# ───────────────────────────────────────────────────── + +stmt = ( + select( + User.id, + User.username, + func.count(Order.id).label("order_count"), + func.sum(Order.amount).label("total_spent"), + ) + .join(Order) + .group_by(User.id, User.username) + .having( + and_( + func.count(Order.id) >= 10, + func.sum(Order.amount) >= 100000, + ) + ) + .order_by(func.sum(Order.amount).desc()) +) +# 10건 이상 주문하고 10만원 이상 사용한 고객 +``` + +### 7.4 윈도우 함수 + +```python +from sqlalchemy import over + + +# ───────────────────────────────────────────────────── +# ROW_NUMBER +# ───────────────────────────────────────────────────── + +stmt = ( + select( + User.id, + User.username, + User.created_at, + func.row_number().over( + order_by=User.created_at.desc() + ).label("row_num"), + ) +) + + +# ───────────────────────────────────────────────────── +# 파티션별 순위 +# ───────────────────────────────────────────────────── + +stmt = ( + select( + Product.id, + Product.name, + Product.category_id, + Product.price, + func.rank().over( + partition_by=Product.category_id, + order_by=Product.price.desc(), + ).label("price_rank"), + ) +) +# 카테고리 내에서 가격 순위 + + +# ───────────────────────────────────────────────────── +# 누적 합계 +# ───────────────────────────────────────────────────── + +stmt = ( + select( + Order.id, + Order.created_at, + Order.amount, + func.sum(Order.amount).over( + order_by=Order.created_at, + ).label("cumulative_amount"), + ) +) + + +# ───────────────────────────────────────────────────── +# 이동 평균 +# ───────────────────────────────────────────────────── + +from sqlalchemy import text + +stmt = ( + select( + Order.id, + Order.created_at, + Order.amount, + func.avg(Order.amount).over( + order_by=Order.created_at, + rows=(2, 0), # 현재 행 포함 최근 3개 + ).label("moving_avg"), + ) +) +``` + +--- + +## 8. JOIN 쿼리 + +### 8.1 기본 JOIN + +```python +from sqlalchemy import select + + +# ───────────────────────────────────────────────────── +# INNER JOIN +# ───────────────────────────────────────────────────── + +# 방법 1: relationship 사용 (자동 조건) +stmt = select(User, Post).join(User.posts) +# SELECT ... FROM user JOIN post ON user.id = post.author_id + +# 방법 2: 명시적 조건 +stmt = select(User, Post).join(Post, User.id == Post.author_id) + +# 방법 3: 모델만 지정 (FK 자동 감지) +stmt = select(User, Post).join(Post) + + +# ───────────────────────────────────────────────────── +# LEFT OUTER JOIN +# ───────────────────────────────────────────────────── + +stmt = select(User, Post).join(Post, isouter=True) +# SELECT ... FROM user LEFT JOIN post ON ... + +# 또는 +stmt = select(User, Post).outerjoin(Post) + + +# ───────────────────────────────────────────────────── +# RIGHT OUTER JOIN +# ───────────────────────────────────────────────────── + +stmt = select(User, Post).join(Post, full=True) # FULL OUTER +# RIGHT JOIN은 순서를 바꿔서 구현 +stmt = select(Post, User).outerjoin(User) + + +# ───────────────────────────────────────────────────── +# 다중 JOIN +# ───────────────────────────────────────────────────── + +stmt = ( + select(User, Post, Comment) + .join(Post, User.id == Post.author_id) + .join(Comment, Post.id == Comment.post_id) +) + +# relationship 사용 +stmt = ( + select(User, Post, Comment) + .join(User.posts) + .join(Post.comments) +) +``` + +### 8.2 JOIN 결과 처리 + +```python +# ───────────────────────────────────────────────────── +# 여러 모델 조회 +# ───────────────────────────────────────────────────── + +stmt = select(User, Post).join(Post) +results = db.execute(stmt).all() + +for user, post in results: + print(f"Author: {user.username}, Post: {post.title}") + + +# ───────────────────────────────────────────────────── +# 특정 컬럼만 조회 +# ───────────────────────────────────────────────────── + +stmt = ( + select(User.username, Post.title, Post.created_at) + .join(Post) + .order_by(Post.created_at.desc()) +) +results = db.execute(stmt).all() + +for row in results: + print(f"{row.username}: {row.title}") + + +# ───────────────────────────────────────────────────── +# 하나의 모델만 필요할 때 +# ───────────────────────────────────────────────────── + +# 게시글이 있는 사용자만 조회 +stmt = ( + select(User) + .join(Post) + .distinct() +) +users = db.scalars(stmt).all() +``` + +### 8.3 Self JOIN + +```python +# ───────────────────────────────────────────────────── +# 같은 테이블 조인 (별칭 필요) +# ───────────────────────────────────────────────────── + +from sqlalchemy.orm import aliased + +# 사용자와 그 추천인 +Referrer = aliased(User, name="referrer") + +stmt = ( + select(User.username, Referrer.username.label("referrer_name")) + .join(Referrer, User.referrer_id == Referrer.id, isouter=True) +) + + +# ───────────────────────────────────────────────────── +# 계층 구조 조회 (상위/하위) +# ───────────────────────────────────────────────────── + +Parent = aliased(Category, name="parent") + +stmt = ( + select(Category.name, Parent.name.label("parent_name")) + .join(Parent, Category.parent_id == Parent.id, isouter=True) +) + + +# ───────────────────────────────────────────────────── +# 같은 테이블 비교 +# ───────────────────────────────────────────────────── + +# 같은 카테고리의 다른 상품 +OtherProduct = aliased(Product, name="other") + +stmt = ( + select(Product.name, OtherProduct.name.label("related_product")) + .join( + OtherProduct, + and_( + Product.category_id == OtherProduct.category_id, + Product.id != OtherProduct.id, + ) + ) + .where(Product.id == 1) +) +``` + +--- + +## 9. 서브쿼리 (Subquery) + +### 9.1 스칼라 서브쿼리 + +```python +from sqlalchemy import select, func + + +# ───────────────────────────────────────────────────── +# SELECT 절의 서브쿼리 +# ───────────────────────────────────────────────────── + +# 각 사용자의 게시글 수 +post_count_subq = ( + select(func.count(Post.id)) + .where(Post.author_id == User.id) + .correlate(User) + .scalar_subquery() +) + +stmt = select( + User.username, + post_count_subq.label("post_count"), +) + + +# ───────────────────────────────────────────────────── +# 평균과 비교 +# ───────────────────────────────────────────────────── + +avg_price = select(func.avg(Product.price)).scalar_subquery() + +stmt = select(Product).where(Product.price > avg_price) +# 평균보다 비싼 상품 +``` + +### 9.2 FROM 절의 서브쿼리 + +```python +# ───────────────────────────────────────────────────── +# 서브쿼리를 테이블처럼 사용 +# ───────────────────────────────────────────────────── + +# 카테고리별 통계 서브쿼리 +category_stats = ( + select( + Product.category_id, + func.count(Product.id).label("product_count"), + func.avg(Product.price).label("avg_price"), + ) + .group_by(Product.category_id) + .subquery() +) + +# 메인 쿼리에서 조인 +stmt = ( + select( + Category.name, + category_stats.c.product_count, + category_stats.c.avg_price, + ) + .join(category_stats, Category.id == category_stats.c.category_id) +) + + +# ───────────────────────────────────────────────────── +# 파생 테이블 +# ───────────────────────────────────────────────────── + +# 최근 7일 활성 사용자 +recent_active = ( + select( + User.id, + User.username, + func.count(Order.id).label("order_count"), + ) + .join(Order) + .where(Order.created_at >= func.date_sub(func.now(), text("INTERVAL 7 DAY"))) + .group_by(User.id) + .subquery() +) + +# 많이 주문한 순으로 +stmt = ( + select(recent_active) + .order_by(recent_active.c.order_count.desc()) + .limit(10) +) +``` + +### 9.3 WHERE 절의 서브쿼리 + +```python +from sqlalchemy import exists, any_, all_ + + +# ───────────────────────────────────────────────────── +# IN 서브쿼리 +# ───────────────────────────────────────────────────── + +# 주문한 적 있는 사용자 +ordered_user_ids = select(Order.user_id).distinct() + +stmt = select(User).where(User.id.in_(ordered_user_ids)) + + +# ───────────────────────────────────────────────────── +# EXISTS +# ───────────────────────────────────────────────────── + +# 게시글이 있는 사용자 +has_posts = ( + exists() + .where(Post.author_id == User.id) +) + +stmt = select(User).where(has_posts) + + +# NOT EXISTS +stmt = select(User).where(~has_posts) # 게시글 없는 사용자 + + +# ───────────────────────────────────────────────────── +# ANY / ALL +# ───────────────────────────────────────────────────── + +# 어떤 주문보다 비싼 상품 (ANY) +any_order_amount = select(Order.amount) +stmt = select(Product).where(Product.price > any_(any_order_amount)) + +# 모든 주문보다 비싼 상품 (ALL) +stmt = select(Product).where(Product.price > all_(any_order_amount)) +``` + +### 9.4 Lateral 서브쿼리 (PostgreSQL) + +```python +from sqlalchemy import lateral + + +# 각 사용자의 최근 3개 주문 +recent_orders = ( + select(Order) + .where(Order.user_id == User.id) + .order_by(Order.created_at.desc()) + .limit(3) + .lateral() +) + +stmt = ( + select(User, recent_orders) + .outerjoin(recent_orders, True) +) +``` + +--- + +## 10. 집합 연산 (Union, Intersect, Except) + +### 10.1 UNION + +```python +from sqlalchemy import union, union_all + + +# ───────────────────────────────────────────────────── +# UNION (중복 제거) +# ───────────────────────────────────────────────────── + +# 관리자 + 최근 활동 사용자 +admins = select(User.id, User.username).where(User.is_admin == True) +recent_active = select(User.id, User.username).where( + User.last_login >= func.date_sub(func.now(), text("INTERVAL 7 DAY")) +) + +stmt = union(admins, recent_active) +results = db.execute(stmt).all() + + +# ───────────────────────────────────────────────────── +# UNION ALL (중복 허용, 더 빠름) +# ───────────────────────────────────────────────────── + +stmt = union_all(admins, recent_active) + + +# ───────────────────────────────────────────────────── +# 여러 개 UNION +# ───────────────────────────────────────────────────── + +query1 = select(User.email.label("contact")).where(User.is_active == True) +query2 = select(Contact.email.label("contact")).where(Contact.subscribed == True) +query3 = select(Lead.email.label("contact")).where(Lead.status == "qualified") + +stmt = union(query1, query2, query3) + + +# ───────────────────────────────────────────────────── +# UNION 결과 정렬/제한 +# ───────────────────────────────────────────────────── + +combined = union(admins, recent_active).subquery() + +stmt = ( + select(combined) + .order_by(combined.c.username) + .limit(10) +) +``` + +### 10.2 INTERSECT + +```python +from sqlalchemy import intersect, intersect_all + + +# ───────────────────────────────────────────────────── +# INTERSECT (교집합) +# ───────────────────────────────────────────────────── + +# 관리자이면서 최근 활동한 사용자 +admins = select(User.id).where(User.is_admin == True) +recent_active = select(User.id).where( + User.last_login >= func.date_sub(func.now(), text("INTERVAL 7 DAY")) +) + +stmt = intersect(admins, recent_active) + + +# ───────────────────────────────────────────────────── +# 여러 조건의 교집합 +# ───────────────────────────────────────────────────── + +# 세 가지 모두 만족하는 사용자 +has_orders = select(Order.user_id).distinct() +has_reviews = select(Review.user_id).distinct() +is_verified = select(User.id).where(User.is_verified == True) + +stmt = intersect(has_orders, has_reviews, is_verified) +``` + +### 10.3 EXCEPT + +```python +from sqlalchemy import except_, except_all + + +# ───────────────────────────────────────────────────── +# EXCEPT (차집합) +# ───────────────────────────────────────────────────── + +# 주문은 했지만 리뷰는 안 쓴 사용자 +ordered = select(Order.user_id).distinct() +reviewed = select(Review.user_id).distinct() + +stmt = except_(ordered, reviewed) + + +# ───────────────────────────────────────────────────── +# 실용 예: 미처리 항목 찾기 +# ───────────────────────────────────────────────────── + +# 모든 신규 사용자 중 환영 이메일 미발송 대상 +all_new_users = select(User.id).where( + User.created_at >= func.date_sub(func.now(), text("INTERVAL 24 HOUR")) +) +email_sent = select(EmailLog.user_id).where(EmailLog.type == "welcome") + +stmt = except_(all_new_users, email_sent) +``` + +--- + +## 11. 고급 표현식 + +### 11.1 CASE 문 + +```python +from sqlalchemy import case + + +# ───────────────────────────────────────────────────── +# 단순 CASE +# ───────────────────────────────────────────────────── + +status_label = case( + (User.status == "active", "활성"), + (User.status == "pending", "대기"), + (User.status == "suspended", "정지"), + else_="알 수 없음", +) + +stmt = select(User.username, status_label.label("status_label")) + + +# ───────────────────────────────────────────────────── +# 조건부 집계 +# ───────────────────────────────────────────────────── + +stmt = select( + func.count(case((Order.status == "completed", 1))).label("completed_count"), + func.count(case((Order.status == "pending", 1))).label("pending_count"), + func.count(case((Order.status == "cancelled", 1))).label("cancelled_count"), + func.sum(case((Order.status == "completed", Order.amount), else_=0)).label("completed_amount"), +) + + +# ───────────────────────────────────────────────────── +# 정렬에서 CASE +# ───────────────────────────────────────────────────── + +priority_order = case( + (User.role == "admin", 1), + (User.role == "moderator", 2), + else_=3, +) + +stmt = select(User).order_by(priority_order, User.username) +``` + +### 11.2 형변환 (CAST) + +```python +from sqlalchemy import cast +from sqlalchemy.types import String, Integer, Float, Date + + +# ───────────────────────────────────────────────────── +# 타입 변환 +# ───────────────────────────────────────────────────── + +stmt = select(cast(User.age, String).label("age_str")) +stmt = select(cast(Product.price, Integer).label("price_int")) +stmt = select(cast(Order.created_at, Date).label("order_date")) + + +# ───────────────────────────────────────────────────── +# 문자열 연결 시 형변환 +# ───────────────────────────────────────────────────── + +stmt = select( + (User.username + " (" + cast(User.age, String) + "세)").label("display_name") +) +``` + +### 11.3 문자열 함수 + +```python +from sqlalchemy import func + + +# ───────────────────────────────────────────────────── +# 기본 문자열 함수 +# ───────────────────────────────────────────────────── + +stmt = select( + func.upper(User.username), + func.lower(User.email), + func.length(User.bio), + func.trim(User.name), + func.concat(User.first_name, " ", User.last_name).label("full_name"), +) + + +# ───────────────────────────────────────────────────── +# 문자열 추출 +# ───────────────────────────────────────────────────── + +stmt = select( + func.substring(User.email, 1, 10), # 처음 10자 + func.left(User.username, 5), + func.right(User.email, 10), +) + + +# ───────────────────────────────────────────────────── +# 문자열 연결 (|| 연산자) +# ───────────────────────────────────────────────────── + +from sqlalchemy import literal_column + +# PostgreSQL/SQLite +full_name = User.first_name + " " + User.last_name + +# MySQL +full_name = func.concat(User.first_name, " ", User.last_name) +``` + +### 11.4 날짜/시간 함수 + +```python +from sqlalchemy import func, extract + + +# ───────────────────────────────────────────────────── +# 현재 날짜/시간 +# ───────────────────────────────────────────────────── + +stmt = select( + func.now(), + func.current_date(), + func.current_time(), + func.current_timestamp(), +) + + +# ───────────────────────────────────────────────────── +# 날짜 추출 +# ───────────────────────────────────────────────────── + +stmt = select( + extract("year", Order.created_at).label("year"), + extract("month", Order.created_at).label("month"), + extract("day", Order.created_at).label("day"), + extract("hour", Order.created_at).label("hour"), +) + +# 또는 +stmt = select( + func.year(Order.created_at), + func.month(Order.created_at), + func.day(Order.created_at), +) + + +# ───────────────────────────────────────────────────── +# 날짜 연산 +# ───────────────────────────────────────────────────── + +# MySQL +from sqlalchemy import text + +stmt = select(User).where( + User.created_at >= func.date_sub(func.now(), text("INTERVAL 30 DAY")) +) + +# PostgreSQL +from datetime import timedelta +stmt = select(User).where( + User.created_at >= func.now() - timedelta(days=30) +) + + +# ───────────────────────────────────────────────────── +# 날짜 차이 +# ───────────────────────────────────────────────────── + +stmt = select( + func.datediff(func.now(), User.created_at).label("days_since_signup") +) +``` + +### 11.5 NULL 처리 + +```python +from sqlalchemy import func, coalesce, nullif + + +# ───────────────────────────────────────────────────── +# COALESCE (첫 번째 non-null 값) +# ───────────────────────────────────────────────────── + +stmt = select( + coalesce(User.nickname, User.username, "Anonymous").label("display_name") +) + + +# ───────────────────────────────────────────────────── +# NULLIF (같으면 NULL) +# ───────────────────────────────────────────────────── + +# 0으로 나누기 방지 +stmt = select( + Order.total / nullif(Order.quantity, 0) +) + + +# ───────────────────────────────────────────────────── +# IFNULL / NVL (MySQL / Oracle) +# ───────────────────────────────────────────────────── + +stmt = select( + func.ifnull(User.nickname, "No nickname") +) +``` + +### 11.6 Raw SQL 사용 + +```python +from sqlalchemy import text, literal_column + + +# ───────────────────────────────────────────────────── +# text() - Raw SQL +# ───────────────────────────────────────────────────── + +# WHERE 절에서 +stmt = select(User).where(text("MATCH(bio) AGAINST(:keyword)")).params(keyword="python") + +# 전체 쿼리 +result = db.execute(text("SELECT * FROM user WHERE id = :id"), {"id": 1}) + + +# ───────────────────────────────────────────────────── +# literal_column() - 컬럼 표현식 +# ───────────────────────────────────────────────────── + +stmt = select( + User.username, + literal_column("'active'").label("status"), +) + + +# ───────────────────────────────────────────────────── +# literal() - 리터럴 값 +# ───────────────────────────────────────────────────── + +from sqlalchemy import literal + +stmt = select( + User.username, + literal(1).label("constant"), + literal("active").label("status"), +) +``` + +--- + +## 12. Relationship과 Eager Loading + +### 12.1 Lazy Loading (기본) + +```python +# ───────────────────────────────────────────────────── +# N+1 문제 발생 예시 +# ───────────────────────────────────────────────────── + +users = db.scalars(select(User)).all() # 쿼리 1회 + +for user in users: + print(user.posts) # 각 사용자마다 추가 쿼리! (N회) + +# 총 N+1회 쿼리 발생 +``` + +### 12.2 Eager Loading 옵션 + +```python +from sqlalchemy.orm import selectinload, joinedload, subqueryload, raiseload + + +# ───────────────────────────────────────────────────── +# selectinload (권장: 1:N) +# ───────────────────────────────────────────────────── + +stmt = select(User).options(selectinload(User.posts)) +users = db.scalars(stmt).all() + +# 쿼리 1: SELECT * FROM user +# 쿼리 2: SELECT * FROM post WHERE user_id IN (1, 2, 3, ...) + +for user in users: + print(user.posts) # 추가 쿼리 없음! + + +# ───────────────────────────────────────────────────── +# joinedload (권장: N:1, 1:1) +# ───────────────────────────────────────────────────── + +stmt = select(Post).options(joinedload(Post.author)) +posts = db.scalars(stmt).unique().all() # unique() 필요! + +# 쿼리: SELECT post.*, user.* FROM post JOIN user ON ... + + +# ───────────────────────────────────────────────────── +# subqueryload +# ───────────────────────────────────────────────────── + +stmt = select(User).options(subqueryload(User.posts)) + +# 쿼리 1: SELECT * FROM user +# 쿼리 2: SELECT * FROM post WHERE user_id IN (SELECT id FROM user) + + +# ───────────────────────────────────────────────────── +# raiseload (로딩 금지) +# ───────────────────────────────────────────────────── + +stmt = select(User).options(raiseload(User.posts)) +user = db.scalar(stmt) +print(user.posts) # 에러 발생! 명시적 로딩 필요 +``` + +### 12.3 중첩 Eager Loading + +```python +# ───────────────────────────────────────────────────── +# 다단계 관계 로딩 +# ───────────────────────────────────────────────────── + +stmt = ( + select(User) + .options( + selectinload(User.posts) + .selectinload(Post.comments) + .selectinload(Comment.author) + ) +) + +# 쿼리 1: SELECT * FROM user +# 쿼리 2: SELECT * FROM post WHERE user_id IN (...) +# 쿼리 3: SELECT * FROM comment WHERE post_id IN (...) +# 쿼리 4: SELECT * FROM user WHERE id IN (...) # 댓글 작성자 + + +# ───────────────────────────────────────────────────── +# 여러 관계 동시 로딩 +# ───────────────────────────────────────────────────── + +stmt = ( + select(User) + .options( + selectinload(User.posts), + selectinload(User.comments), + joinedload(User.profile), + ) +) + + +# ───────────────────────────────────────────────────── +# contains_eager (이미 조인된 경우) +# ───────────────────────────────────────────────────── + +from sqlalchemy.orm import contains_eager + +stmt = ( + select(Post) + .join(Post.author) + .where(User.is_active == True) + .options(contains_eager(Post.author)) # 조인 결과 사용 +) +``` + +### 12.4 로딩 전략 비교 + +| 전략 | 쿼리 수 | 적합한 관계 | 장점 | 단점 | +|------|--------|------------|------|------| +| `selectinload` | 2 | 1:N | 효율적, 간단 | 대량 ID 시 IN 절 길어짐 | +| `joinedload` | 1 | N:1, 1:1 | 단일 쿼리 | 1:N에서 중복 발생 | +| `subqueryload` | 2 | 1:N | 복잡한 필터 지원 | 서브쿼리 오버헤드 | +| `raiseload` | - | - | 실수 방지 | 명시적 로딩 필요 | + +--- + +## 13. 트랜잭션 관리 + +### 13.1 기본 트랜잭션 + +```python +from sqlalchemy.orm import Session + + +# ───────────────────────────────────────────────────── +# 명시적 commit/rollback +# ───────────────────────────────────────────────────── + +def create_order(db: Session, user_id: int, items: list) -> Order: + try: + order = Order(user_id=user_id) + db.add(order) + db.flush() # ID 생성을 위해 flush + + for item in items: + order_item = OrderItem( + order_id=order.id, + product_id=item["product_id"], + quantity=item["quantity"], + ) + db.add(order_item) + + db.commit() + db.refresh(order) + return order + + except Exception as e: + db.rollback() + raise + + +# ───────────────────────────────────────────────────── +# context manager 사용 +# ───────────────────────────────────────────────────── + +from sqlalchemy.orm import Session + +def transfer_money(engine, from_id: int, to_id: int, amount: float): + with Session(engine) as session: + with session.begin(): # 자동 commit/rollback + from_account = session.get(Account, from_id) + to_account = session.get(Account, to_id) + + if from_account.balance < amount: + raise ValueError("잔액 부족") + + from_account.balance -= amount + to_account.balance += amount + # begin() 블록 종료 시 자동 commit + # Session 종료 시 자동 close +``` + +### 13.2 Savepoint (중첩 트랜잭션) + +```python +def complex_operation(db: Session): + try: + # 메인 작업 + user = User(username="test") + db.add(user) + db.flush() + + # 선택적 작업 (실패해도 메인은 유지) + savepoint = db.begin_nested() + try: + risky_operation() + savepoint.commit() + except Exception: + savepoint.rollback() + # 메인 트랜잭션은 유지됨 + + db.commit() + + except Exception: + db.rollback() + raise +``` + +### 13.3 FastAPI에서 트랜잭션 + +```python +# app/database.py +from contextlib import contextmanager + + +def get_db() -> Generator[Session, None, None]: + db = SessionLocal() + try: + yield db + except Exception: + db.rollback() + raise + finally: + db.close() + + +# 트랜잭션이 필요한 서비스 +class OrderService: + def __init__(self, db: Session): + self.db = db + + def create_order_with_payment(self, data: OrderCreate) -> Order: + # 여러 작업이 하나의 트랜잭션 + order = self._create_order(data) + self._process_payment(order) + self._update_inventory(order) + self._send_notification(order) + + self.db.commit() + return order + + +# 라우터 +@router.post("/orders") +def create_order( + data: OrderCreate, + db: Session = Depends(get_db), +): + service = OrderService(db) + return service.create_order_with_payment(data) +``` + +--- + +## 14. FastAPI 통합 패턴 + +### 14.1 Repository 패턴 + +```python +# app/repositories/base.py +from typing import TypeVar, Generic, Type, Optional, List +from sqlalchemy import select +from sqlalchemy.orm import Session + +from app.models.base import Base + +ModelType = TypeVar("ModelType", bound=Base) + + +class BaseRepository(Generic[ModelType]): + def __init__(self, model: Type[ModelType], db: Session): + self.model = model + self.db = db + + def get(self, id: int) -> Optional[ModelType]: + return self.db.get(self.model, id) + + def get_all(self, skip: int = 0, limit: int = 100) -> List[ModelType]: + stmt = select(self.model).offset(skip).limit(limit) + return list(self.db.scalars(stmt).all()) + + def create(self, obj: ModelType) -> ModelType: + self.db.add(obj) + self.db.commit() + self.db.refresh(obj) + return obj + + def update(self, obj: ModelType) -> ModelType: + self.db.commit() + self.db.refresh(obj) + return obj + + def delete(self, obj: ModelType) -> None: + self.db.delete(obj) + self.db.commit() + + +# app/repositories/user.py +from sqlalchemy import select +from app.models.user import User + + +class UserRepository(BaseRepository[User]): + def __init__(self, db: Session): + super().__init__(User, db) + + def get_by_email(self, email: str) -> Optional[User]: + stmt = select(User).where(User.email == email) + return self.db.scalar(stmt) + + def get_active_users(self) -> List[User]: + stmt = select(User).where(User.is_active == True) + return list(self.db.scalars(stmt).all()) + + def search(self, keyword: str) -> List[User]: + stmt = select(User).where( + or_( + User.username.contains(keyword), + User.email.contains(keyword), + ) + ) + return list(self.db.scalars(stmt).all()) +``` + +### 14.2 Service 패턴 + +```python +# app/services/user.py +from typing import Optional, List +from fastapi import HTTPException, status +from sqlalchemy.orm import Session + +from app.models.user import User +from app.schemas.user import UserCreate, UserUpdate +from app.repositories.user import UserRepository +from app.core.security import hash_password + + +class UserService: + def __init__(self, db: Session): + self.db = db + self.repository = UserRepository(db) + + def get_user(self, user_id: int) -> User: + user = self.repository.get(user_id) + if not user: + raise HTTPException( + status_code=status.HTTP_404_NOT_FOUND, + detail="User not found", + ) + return user + + def get_user_by_email(self, email: str) -> Optional[User]: + return self.repository.get_by_email(email) + + def create_user(self, data: UserCreate) -> User: + # 이메일 중복 확인 + if self.repository.get_by_email(data.email): + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail="Email already registered", + ) + + user = User( + email=data.email, + username=data.username, + hashed_password=hash_password(data.password), + ) + return self.repository.create(user) + + def update_user(self, user_id: int, data: UserUpdate) -> User: + user = self.get_user(user_id) + + update_data = data.model_dump(exclude_unset=True) + for field, value in update_data.items(): + setattr(user, field, value) + + return self.repository.update(user) + + def delete_user(self, user_id: int) -> None: + user = self.get_user(user_id) + self.repository.delete(user) + + +# Dependency +def get_user_service(db: Session = Depends(get_db)) -> UserService: + return UserService(db) +``` + +### 14.3 Router (Endpoints) + +```python +# app/routers/user.py +from fastapi import APIRouter, Depends, Query, status +from sqlalchemy.orm import Session + +from app.database import get_db +from app.schemas.user import UserCreate, UserUpdate, UserResponse, UserListResponse +from app.services.user import UserService, get_user_service + +router = APIRouter(prefix="/users", tags=["users"]) + + +@router.get("/", response_model=UserListResponse) +def list_users( + skip: int = Query(0, ge=0), + limit: int = Query(20, ge=1, le=100), + service: UserService = Depends(get_user_service), +): + users = service.repository.get_all(skip=skip, limit=limit) + return {"items": users, "total": len(users)} + + +@router.get("/{user_id}", response_model=UserResponse) +def get_user( + user_id: int, + service: UserService = Depends(get_user_service), +): + return service.get_user(user_id) + + +@router.post("/", response_model=UserResponse, status_code=status.HTTP_201_CREATED) +def create_user( + data: UserCreate, + service: UserService = Depends(get_user_service), +): + return service.create_user(data) + + +@router.patch("/{user_id}", response_model=UserResponse) +def update_user( + user_id: int, + data: UserUpdate, + service: UserService = Depends(get_user_service), +): + return service.update_user(user_id, data) + + +@router.delete("/{user_id}", status_code=status.HTTP_204_NO_CONTENT) +def delete_user( + user_id: int, + service: UserService = Depends(get_user_service), +): + service.delete_user(user_id) +``` + +### 14.4 Pydantic 스키마 + +```python +# app/schemas/user.py +from datetime import datetime +from typing import Optional, List +from pydantic import BaseModel, EmailStr, Field, ConfigDict + + +class UserBase(BaseModel): + email: EmailStr + username: str = Field(..., min_length=3, max_length=50) + full_name: Optional[str] = None + + +class UserCreate(UserBase): + password: str = Field(..., min_length=8) + + +class UserUpdate(BaseModel): + email: Optional[EmailStr] = None + username: Optional[str] = Field(None, min_length=3, max_length=50) + full_name: Optional[str] = None + is_active: Optional[bool] = None + + +class UserResponse(UserBase): + id: int + is_active: bool + created_at: datetime + + model_config = ConfigDict(from_attributes=True) + + +class UserListResponse(BaseModel): + items: List[UserResponse] + total: int +``` + +--- + +## 15. 성능 최적화 + +### 15.1 인덱스 최적화 + +```python +from sqlalchemy import Index + + +class User(Base): + __tablename__ = "user" + + id: Mapped[int] = mapped_column(primary_key=True) + email: Mapped[str] = mapped_column(String(255), unique=True) + status: Mapped[str] = mapped_column(String(20)) + created_at: Mapped[datetime] = mapped_column(default=func.now()) + + __table_args__ = ( + # 단일 인덱스 + Index("idx_user_status", "status"), + + # 복합 인덱스 + Index("idx_user_status_created", "status", "created_at"), + + # 부분 인덱스 (PostgreSQL) + Index( + "idx_user_active", + "email", + postgresql_where=text("status = 'active'"), + ), + ) +``` + +### 15.2 쿼리 최적화 + +```python +# ───────────────────────────────────────────────────── +# 1. 필요한 컬럼만 조회 +# ───────────────────────────────────────────────────── + +# Bad +users = db.scalars(select(User)).all() +emails = [u.email for u in users] + +# Good +emails = db.scalars(select(User.email)).all() + + +# ───────────────────────────────────────────────────── +# 2. N+1 문제 해결 +# ───────────────────────────────────────────────────── + +# Bad +users = db.scalars(select(User)).all() +for user in users: + print(user.posts) # N+1 + +# Good +stmt = select(User).options(selectinload(User.posts)) +users = db.scalars(stmt).all() + + +# ───────────────────────────────────────────────────── +# 3. Bulk 작업 사용 +# ───────────────────────────────────────────────────── + +# Bad - 개별 업데이트 +for user in users: + user.is_active = False + db.commit() + +# Good - Bulk 업데이트 +db.execute( + update(User) + .where(User.id.in_([u.id for u in users])) + .values(is_active=False) +) +db.commit() + + +# ───────────────────────────────────────────────────── +# 4. 존재 확인은 EXISTS 사용 +# ───────────────────────────────────────────────────── + +# Bad +user = db.scalar(select(User).where(User.email == email)) +exists = user is not None + +# Good +exists = db.scalar( + select(exists().where(User.email == email)) +) + + +# ───────────────────────────────────────────────────── +# 5. 카운트는 count() 사용 +# ───────────────────────────────────────────────────── + +# Bad +count = len(db.scalars(select(User)).all()) + +# Good +count = db.scalar(select(func.count(User.id))) +``` + +### 15.3 연결 풀 설정 + +```python +engine = create_engine( + DATABASE_URL, + pool_size=10, # 기본 연결 수 + max_overflow=20, # 추가 허용 연결 수 + pool_timeout=30, # 연결 대기 시간 + pool_recycle=1800, # 연결 재생성 주기 (30분) + pool_pre_ping=True, # 연결 유효성 사전 검사 +) +``` + +### 15.4 쿼리 실행 계획 확인 + +```python +from sqlalchemy import explain + +stmt = select(User).where(User.email == "test@example.com") + +# 실행 계획 출력 +print(db.execute(explain(stmt)).fetchall()) + +# MySQL EXPLAIN +print(db.execute(text(f"EXPLAIN {stmt}")).fetchall()) +``` + +--- + +## 16. 실무 레시피 + +### 16.1 Soft Delete 구현 + +```python +from datetime import datetime +from sqlalchemy import event + + +class SoftDeleteMixin: + is_deleted: Mapped[bool] = mapped_column(default=False) + deleted_at: Mapped[Optional[datetime]] = mapped_column(default=None) + + def soft_delete(self): + self.is_deleted = True + self.deleted_at = datetime.utcnow() + + +# 자동 필터링 (Global Filter) +@event.listens_for(Session, "do_orm_execute") +def _add_filtering_criteria(execute_state): + if execute_state.is_select: + execute_state.statement = execute_state.statement.options( + with_loader_criteria( + SoftDeleteMixin, + lambda cls: cls.is_deleted == False, + include_aliases=True, + ) + ) +``` + +### 16.2 Audit Log + +```python +from sqlalchemy import event + + +class AuditMixin: + created_by: Mapped[Optional[int]] = mapped_column(ForeignKey("user.id")) + updated_by: Mapped[Optional[int]] = mapped_column(ForeignKey("user.id")) + + +# 현재 사용자 컨텍스트 +from contextvars import ContextVar +current_user_id: ContextVar[Optional[int]] = ContextVar("current_user_id", default=None) + + +@event.listens_for(AuditMixin, "before_insert", propagate=True) +def set_created_by(mapper, connection, target): + if user_id := current_user_id.get(): + target.created_by = user_id + target.updated_by = user_id + + +@event.listens_for(AuditMixin, "before_update", propagate=True) +def set_updated_by(mapper, connection, target): + if user_id := current_user_id.get(): + target.updated_by = user_id + + +# FastAPI 미들웨어 +@app.middleware("http") +async def set_current_user(request: Request, call_next): + user_id = get_user_id_from_token(request) + token = current_user_id.set(user_id) + try: + response = await call_next(request) + return response + finally: + current_user_id.reset(token) +``` + +### 16.3 전체 텍스트 검색 + +```python +from sqlalchemy import Index, text + + +class Post(Base): + __tablename__ = "post" + + id: Mapped[int] = mapped_column(primary_key=True) + title: Mapped[str] = mapped_column(String(200)) + content: Mapped[str] = mapped_column(Text) + + __table_args__ = ( + # MySQL FULLTEXT 인덱스 + Index( + "idx_post_fulltext", + "title", "content", + mysql_prefix="FULLTEXT", + ), + ) + + +def search_posts(db: Session, keyword: str) -> list[Post]: + stmt = ( + select(Post) + .where( + text("MATCH(title, content) AGAINST(:keyword IN BOOLEAN MODE)") + ) + .params(keyword=keyword) + ) + return list(db.scalars(stmt).all()) +``` + +### 16.4 슬러그 자동 생성 + +```python +from sqlalchemy import event +import re + + +def slugify(text: str) -> str: + text = text.lower() + text = re.sub(r'[^\w\s-]', '', text) + text = re.sub(r'[-\s]+', '-', text).strip('-') + return text + + +class Post(Base): + title: Mapped[str] = mapped_column(String(200)) + slug: Mapped[str] = mapped_column(String(200), unique=True) + + +@event.listens_for(Post.title, "set") +def generate_slug(target, value, oldvalue, initiator): + if value and (not target.slug or oldvalue != value): + target.slug = slugify(value) +``` + +### 16.5 캐싱 패턴 + +```python +from functools import lru_cache +from typing import Optional +import json +import redis + +redis_client = redis.Redis() + + +class CachedUserRepository: + def __init__(self, db: Session): + self.db = db + self.cache_ttl = 3600 # 1시간 + + def _cache_key(self, user_id: int) -> str: + return f"user:{user_id}" + + def get(self, user_id: int) -> Optional[User]: + # 캐시 확인 + cached = redis_client.get(self._cache_key(user_id)) + if cached: + data = json.loads(cached) + return User(**data) + + # DB 조회 + user = self.db.get(User, user_id) + if user: + # 캐시 저장 + redis_client.setex( + self._cache_key(user_id), + self.cache_ttl, + json.dumps(user.to_dict()), + ) + + return user + + def invalidate(self, user_id: int) -> None: + redis_client.delete(self._cache_key(user_id)) +``` + +--- + +## 부록: Quick Reference + +### 자주 사용하는 import + +```python +from sqlalchemy import ( + create_engine, select, insert, update, delete, + and_, or_, not_, func, case, cast, exists, + text, literal, literal_column, + Index, ForeignKey, String, Integer, Text, Boolean, + desc, asc, nullsfirst, nullslast, +) +from sqlalchemy.orm import ( + Session, sessionmaker, relationship, + Mapped, mapped_column, + selectinload, joinedload, subqueryload, raiseload, + contains_eager, aliased, +) +from sqlalchemy.dialects.mysql import insert as mysql_insert +from sqlalchemy.dialects.postgresql import insert as pg_insert +``` + +### 쿼리 실행 메서드 + +```python +db.execute(stmt) # Result 반환 +db.scalars(stmt) # ScalarResult 반환 +db.scalar(stmt) # 단일 값 반환 + +result.all() # 모든 결과 +result.first() # 첫 번째 (없으면 None) +result.one() # 정확히 1개 (아니면 예외) +result.one_or_none() # 0-1개 (2개 이상 예외) +result.unique() # 중복 제거 +``` + +### 관계 로딩 전략 + +```python +selectinload(Model.relation) # 1:N - SELECT ... IN +joinedload(Model.relation) # N:1, 1:1 - JOIN +subqueryload(Model.relation) # 복잡한 필터 +raiseload(Model.relation) # 로딩 금지 +``` diff --git a/docs/reference/sqlalchemy_relationship_guide.md b/docs/reference/sqlalchemy_relationship_guide.md index 49e3f7b..5f0db8d 100644 --- a/docs/reference/sqlalchemy_relationship_guide.md +++ b/docs/reference/sqlalchemy_relationship_guide.md @@ -1,1440 +1,1440 @@ -# SQLAlchemy Relationship 완벽 가이드 - -> SQLAlchemy 2.0+ / Python 3.10+ 기준 - ---- - -## 목차 - -1. [개요](#1-개요) -2. [기본 개념](#2-기본-개념) -3. [relationship 정의 문법](#3-relationship-정의-문법) -4. [부모와 자식에서의 정의 차이](#4-부모와-자식에서의-정의-차이) -5. [FK 필드 vs back_populates](#5-fk-필드-vs-back_populates) -6. [relationship 옵션 상세](#6-relationship-옵션-상세) -7. [관계별 정의 방법 (1:1, 1:N, N:M)](#7-관계별-정의-방법-11-1n-nm) -8. [ORM 사용법](#8-orm-사용법) -9. [실무 패턴](#9-실무-패턴) -10. [Quick Reference](#10-quick-reference) - ---- - -## 1. 개요 - -### 1.1 relationship이란? - -`relationship()`은 SQLAlchemy ORM에서 **테이블 간의 관계를 Python 객체로 매핑**하는 기능입니다. - -``` -┌─────────────────────────────────────────────────────────┐ -│ Database Level ORM Level │ -│ ────────────── ───────── │ -│ FOREIGN KEY → relationship() │ -│ JOIN 쿼리 → object.related_objects │ -└─────────────────────────────────────────────────────────┘ -``` - -### 1.2 ForeignKey vs relationship - -| 구분 | ForeignKey | relationship | -|------|------------|--------------| -| **역할** | DB 레벨 제약조건 | ORM 레벨 객체 연결 | -| **위치** | 자식 테이블에만 | 양쪽 모두 가능 | -| **필수 여부** | FK 관계에 필수 | 선택사항 (편의 기능) | -| **결과** | 컬럼 생성 | Python 속성 생성 | - -```python -# ForeignKey: DB에 실제 컬럼 생성 -project_id: Mapped[int] = mapped_column(ForeignKey("project.id")) - -# relationship: Python 객체 접근 경로 생성 -project: Mapped["Project"] = relationship("Project") -``` - ---- - -## 2. 기본 개념 - -### 2.1 용어 정의 - -``` -┌─────────────────────────────────────────────────────────┐ -│ 부모 (Parent) 자식 (Child) │ -│ ───────────── ───────────── │ -│ • "One" 쪽 • "Many" 쪽 │ -│ • FK를 참조받음 • FK를 정의함 │ -│ • 예: Project • 예: Image │ -└─────────────────────────────────────────────────────────┘ -``` - -### 2.2 관계 방향 - -```python -# 단방향 (Unidirectional) -# - 한쪽에서만 relationship 정의 -# - 반대쪽 접근 불가 - -# 양방향 (Bidirectional) -# - 양쪽 모두 relationship 정의 -# - back_populates로 연결 -# - 실무 권장 방식 -``` - -### 2.3 기본 예제 (가장 간단한 형태) - -```python -from sqlalchemy import ForeignKey, String -from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship - - -class Base(DeclarativeBase): - pass - - -# 부모 테이블 -class Project(Base): - __tablename__ = "project" - - id: Mapped[int] = mapped_column(primary_key=True) - name: Mapped[str] = mapped_column(String(100)) - - # 자식들에 대한 접근 경로 - images: Mapped[list["Image"]] = relationship("Image", back_populates="project") - - -# 자식 테이블 -class Image(Base): - __tablename__ = "image" - - id: Mapped[int] = mapped_column(primary_key=True) - project_id: Mapped[int] = mapped_column(ForeignKey("project.id")) # FK - filename: Mapped[str] = mapped_column(String(255)) - - # 부모에 대한 접근 경로 - project: Mapped["Project"] = relationship("Project", back_populates="images") -``` - ---- - -## 3. relationship 정의 문법 - -### 3.1 기본 문법 - -```python -from sqlalchemy.orm import relationship, Mapped -from typing import List - -# 기본 형태 -속성명: Mapped[타입] = relationship("대상클래스", 옵션들...) - -# 부모 측 (1:N에서 "1") -children: Mapped[List["Child"]] = relationship("Child", back_populates="parent") - -# 자식 측 (1:N에서 "N") -parent: Mapped["Parent"] = relationship("Parent", back_populates="children") -``` - -### 3.2 필수 항목 - -| 항목 | 설명 | 예시 | -|------|------|------| -| **첫 번째 인자** | 대상 모델 클래스명 (문자열) | `"Project"` | - -```python -# 최소한의 정의 (단방향) -project: Mapped["Project"] = relationship("Project") -``` - -### 3.3 권장 항목 - -| 항목 | 설명 | 예시 | -|------|------|------| -| `back_populates` | 반대편 relationship 속성명 | `back_populates="images"` | - -```python -# 권장하는 정의 (양방향) -project: Mapped["Project"] = relationship("Project", back_populates="images") -``` - ---- - -## 4. 부모와 자식에서의 정의 차이 - -### 4.1 구조 비교 - -``` -┌─────────────────────────────────────────────────────────────────┐ -│ 부모 (Parent) │ -├─────────────────────────────────────────────────────────────────┤ -│ • ForeignKey: 없음 │ -│ • relationship 타입: List["Child"] 또는 list["Child"] │ -│ • cascade 옵션: 여기에 정의 (삭제 정책) │ -│ • 역할: 자식 컬렉션에 대한 접근 제공 │ -└─────────────────────────────────────────────────────────────────┘ - │ - │ 참조 - ▼ -┌─────────────────────────────────────────────────────────────────┐ -│ 자식 (Child) │ -├─────────────────────────────────────────────────────────────────┤ -│ • ForeignKey: 있음 (필수) │ -│ • relationship 타입: "Parent" (단수) │ -│ • cascade 옵션: 일반적으로 정의 안 함 │ -│ • 역할: 부모 객체에 대한 접근 제공 │ -└─────────────────────────────────────────────────────────────────┘ -``` - -### 4.2 부모 클래스 정의 - -```python -class Project(Base): - """부모 클래스 - FK 없음, 자식 컬렉션 관리""" - __tablename__ = "project" - - id: Mapped[int] = mapped_column(primary_key=True) - store_name: Mapped[str] = mapped_column(String(255)) - - # ───────────────────────────────────────────────────── - # relationship 정의 (부모 측) - # ───────────────────────────────────────────────────── - images: Mapped[list["Image"]] = relationship( - "Image", # 대상 클래스 - back_populates="project", # 자식의 relationship 속성명 - cascade="all, delete-orphan", # 삭제 정책 (부모에서 정의) - lazy="selectin", # 로딩 전략 - order_by="Image.created_at", # 정렬 (선택) - ) -``` - -**부모 측 특징:** -- `Mapped[list["Child"]]` - 복수형 리스트 타입 -- `cascade` 옵션을 여기서 정의 -- FK 컬럼 없음 - -### 4.3 자식 클래스 정의 - -```python -class Image(Base): - """자식 클래스 - FK 있음, 부모 참조""" - __tablename__ = "image" - - id: Mapped[int] = mapped_column(primary_key=True) - original_filename: Mapped[str] = mapped_column(String(255)) - - # ───────────────────────────────────────────────────── - # ForeignKey 정의 (자식 측에서만) - # ───────────────────────────────────────────────────── - project_id: Mapped[int] = mapped_column( - ForeignKey("project.id", ondelete="CASCADE") - ) - - # ───────────────────────────────────────────────────── - # relationship 정의 (자식 측) - # ───────────────────────────────────────────────────── - project: Mapped["Project"] = relationship( - "Project", # 대상 클래스 - back_populates="images", # 부모의 relationship 속성명 - ) -``` - -**자식 측 특징:** -- `Mapped["Parent"]` - 단수형 타입 -- FK 컬럼 정의 필수 -- cascade는 보통 정의하지 않음 - -### 4.4 비교 표 - -| 항목 | 부모 (One) | 자식 (Many) | -|------|-----------|-------------| -| **ForeignKey** | ❌ 없음 | ✅ 필수 | -| **Mapped 타입** | `list["Child"]` | `"Parent"` | -| **cascade** | ✅ 여기서 정의 | ❌ 보통 안 함 | -| **back_populates** | 자식의 속성명 | 부모의 속성명 | -| **접근 결과** | 리스트 | 단일 객체 | - ---- - -## 5. FK 필드 vs back_populates - -### 5.1 두 가지 접근 방식 - -```python -class Image(Base): - # 방식 1: FK 필드 직접 사용 - project_id: Mapped[int] = mapped_column(ForeignKey("project.id")) - - # 방식 2: relationship 사용 - project: Mapped["Project"] = relationship("Project", back_populates="images") -``` - -### 5.2 FK 필드 직접 사용 - -```python -# ───────────────────────────────────────────────────── -# FK 필드로 직접 조작 -# ───────────────────────────────────────────────────── - -# 생성 -image = Image( - project_id=1, # FK 값 직접 지정 - original_filename="photo.jpg" -) -session.add(image) -session.commit() - - -# 수정 -image = session.get(Image, 1) -image.project_id = 2 # FK 값 직접 변경 -session.commit() - - -# 조회 -image = session.get(Image, 1) -print(image.project_id) # 정수 값: 1 - -# 부모 객체 접근하려면 추가 쿼리 필요 -project = session.get(Project, image.project_id) -``` - -**특징:** -- 단순 정수 값 조작 -- 객체 관계를 신경 쓰지 않음 -- 추가 쿼리 없이 FK 값만 필요할 때 유용 - -### 5.3 relationship (back_populates) 사용 - -```python -# ───────────────────────────────────────────────────── -# relationship으로 객체 조작 -# ───────────────────────────────────────────────────── - -# 생성 - 객체로 연결 -project = session.get(Project, 1) -image = Image( - project=project, # 객체로 연결 (FK 자동 설정) - original_filename="photo.jpg" -) -session.add(image) -session.commit() - -print(image.project_id) # 자동으로 1 설정됨! - - -# 수정 - 객체로 변경 -image = session.get(Image, 1) -new_project = session.get(Project, 2) -image.project = new_project # 객체로 변경 -session.commit() - -print(image.project_id) # 자동으로 2로 변경됨! - - -# 조회 - 객체 직접 접근 -image = session.get(Image, 1) -print(image.project.store_name) # 바로 객체 속성 접근 -``` - -**특징:** -- 객체 지향적 접근 -- FK 값 자동 동기화 -- 양방향 자동 업데이트 - -### 5.4 양방향 동기화 동작 - -```python -# back_populates의 핵심: 양쪽 자동 동기화 - -project = Project(store_name="카페") -image = Image(original_filename="photo.jpg") - -# 방법 1: 부모에 자식 추가 -project.images.append(image) -print(image.project) # - 자동 설정! -print(image.project_id) # None (아직 flush 전) - -session.add(project) -session.flush() -print(image.project_id) # 1 - flush 후 FK 설정됨 - - -# 방법 2: 자식에 부모 지정 -image2 = Image(original_filename="logo.png") -image2.project = project -print(image2 in project.images) # True - 자동 추가! -``` - -### 5.5 비교 표 - -| 상황 | FK 필드 사용 | relationship 사용 | -|------|-------------|------------------| -| **부모 ID만 필요** | ✅ `image.project_id` | ⚠️ 불필요한 객체 로딩 가능 | -| **부모 객체 접근** | ❌ 추가 쿼리 필요 | ✅ `image.project.name` | -| **자식 추가** | `image.project_id = 1` | `project.images.append(image)` | -| **일괄 생성** | FK 값 직접 지정 | 객체 연결로 자동 설정 | -| **양방향 동기화** | ❌ 수동 관리 | ✅ 자동 | - -### 5.6 공식 권장 사용 방식 - -```python -class Image(Base): - __tablename__ = "image" - - id: Mapped[int] = mapped_column(primary_key=True) - - # 1. FK 필드 - DB 레벨 관계 (필수) - project_id: Mapped[int] = mapped_column(ForeignKey("project.id")) - - # 2. relationship - ORM 레벨 편의 기능 (권장) - project: Mapped["Project"] = relationship("Project", back_populates="images") - - -# 사용 시: -# - 단순 FK 값 조회/설정: project_id 사용 -# - 객체 조작/탐색: project (relationship) 사용 - -image = session.get(Image, 1) -print(image.project_id) # 빠름 (추가 쿼리 없음) -print(image.project.store_name) # 객체 접근 (필요시 쿼리) -``` - ---- - -## 6. relationship 옵션 상세 - -### 6.1 필수/권장 옵션 - -#### 첫 번째 인자: 대상 클래스 - -```python -# 문자열 (Forward Reference) - 권장 -relationship("Project") - -# 클래스 직접 참조 (순환 import 주의) -relationship(Project) -``` - -#### back_populates (양방향 연결) - -```python -# 부모 측 -images: Mapped[list["Image"]] = relationship( - "Image", - back_populates="project" # Image.project와 연결 -) - -# 자식 측 -project: Mapped["Project"] = relationship( - "Project", - back_populates="images" # Project.images와 연결 -) -``` - -### 6.2 cascade 옵션 - -자식 객체의 생명주기 관리. **부모 측에서 정의**합니다. - -```python -images: Mapped[list["Image"]] = relationship( - "Image", - cascade="all, delete-orphan", # 가장 일반적 -) -``` - -#### cascade 값 종류 - -| 값 | 설명 | -|----|------| -| `save-update` | 부모 저장 시 자식도 저장 (기본값에 포함) | -| `merge` | 부모 merge 시 자식도 merge | -| `expunge` | 부모 expunge 시 자식도 expunge | -| `delete` | 부모 삭제 시 자식도 삭제 | -| `delete-orphan` | 부모에서 분리된 자식 삭제 | -| `refresh-expire` | 부모 refresh 시 자식도 refresh | -| `all` | 위 모든 것 (delete-orphan 제외) | - -#### 일반적인 조합 - -```python -# 1. 기본값 (자동 적용) -cascade="save-update, merge" - -# 2. 부모 삭제 시 자식도 삭제 -cascade="all, delete" - -# 3. 부모에서 분리 시에도 삭제 (가장 엄격) -cascade="all, delete-orphan" - -# 4. 삭제 방지 (자식은 독립적) -cascade="save-update, merge" # delete 없음 -``` - -#### cascade 동작 예시 - -```python -class Project(Base): - images: Mapped[list["Image"]] = relationship( - "Image", - cascade="all, delete-orphan", - ) - -# delete-orphan 동작 -project = session.get(Project, 1) -image = project.images[0] -project.images.remove(image) # 부모에서 분리 -session.commit() -# → image가 DB에서도 삭제됨 (orphan이 됨) - -# delete 동작 -project = session.get(Project, 1) -session.delete(project) -session.commit() -# → 모든 project.images도 삭제됨 -``` - -### 6.3 lazy 옵션 (로딩 전략) - -관계 데이터를 언제/어떻게 로딩할지 결정합니다. - -```python -images: Mapped[list["Image"]] = relationship( - "Image", - lazy="selectin", # 로딩 전략 -) -``` - -#### lazy 값 종류 - -| 값 | 로딩 시점 | 쿼리 방식 | 사용 상황 | -|----|----------|----------|----------| -| `select` | 접근 시 (기본값) | 개별 SELECT | 거의 사용 안 함 | -| `selectin` | 부모 로딩 후 | SELECT ... IN | **1:N 권장** | -| `joined` | 부모와 함께 | JOIN | 1:1, N:1 권장 | -| `subquery` | 부모 로딩 후 | 서브쿼리 | 복잡한 경우 | -| `raise` | 접근 시 에러 | - | 명시적 로딩 강제 | -| `noload` | 로딩 안 함 | - | 특수 상황 | -| `dynamic` | Query 객체 반환 | - | 대량 데이터 | -| `write_only` | 쓰기 전용 | - | 대량 데이터 (2.0) | - -#### 로딩 전략 예시 - -```python -# 1. Lazy Loading (기본값) - N+1 문제 발생! -class Project(Base): - images: Mapped[list["Image"]] = relationship("Image", lazy="select") - -projects = session.scalars(select(Project)).all() -for project in projects: - print(project.images) # 매번 쿼리 발생! (N+1) - - -# 2. selectin - 권장 (1:N) -class Project(Base): - images: Mapped[list["Image"]] = relationship("Image", lazy="selectin") - -projects = session.scalars(select(Project)).all() -# 쿼리 1: SELECT * FROM project -# 쿼리 2: SELECT * FROM image WHERE project_id IN (1, 2, 3, ...) -for project in projects: - print(project.images) # 추가 쿼리 없음 - - -# 3. joined - 권장 (1:1, N:1) -class Image(Base): - project: Mapped["Project"] = relationship("Project", lazy="joined") - -images = session.scalars(select(Image)).all() -# 쿼리: SELECT image.*, project.* FROM image JOIN project ... -for image in images: - print(image.project.name) # 추가 쿼리 없음 - - -# 4. raise - 명시적 로딩 강제 -class Project(Base): - images: Mapped[list["Image"]] = relationship("Image", lazy="raise") - -project = session.get(Project, 1) -print(project.images) # 에러! 명시적 로딩 필요 -``` - -### 6.4 uselist 옵션 - -반환 타입을 리스트/단일 객체로 지정합니다. - -```python -# 기본값: True (리스트) -images: Mapped[list["Image"]] = relationship("Image", uselist=True) - -# 1:1 관계에서 단일 객체 -profile: Mapped["Profile"] = relationship("Profile", uselist=False) -``` - -### 6.5 foreign_keys 옵션 - -여러 FK가 있을 때 명시적 지정이 필요합니다. - -```python -class Message(Base): - sender_id: Mapped[int] = mapped_column(ForeignKey("user.id")) - receiver_id: Mapped[int] = mapped_column(ForeignKey("user.id")) - - # 어떤 FK를 사용할지 명시 - sender: Mapped["User"] = relationship( - "User", - foreign_keys=[sender_id], - ) - receiver: Mapped["User"] = relationship( - "User", - foreign_keys=[receiver_id], - ) -``` - -### 6.6 primaryjoin 옵션 - -복잡한 조인 조건을 직접 정의합니다. - -```python -from sqlalchemy import and_ - -class Project(Base): - # 활성 이미지만 조회 - active_images: Mapped[list["Image"]] = relationship( - "Image", - primaryjoin=lambda: and_( - Project.id == Image.project_id, - Image.is_active == True - ), - viewonly=True, - ) -``` - -### 6.7 order_by 옵션 - -자식 컬렉션의 기본 정렬 순서를 지정합니다. - -```python -images: Mapped[list["Image"]] = relationship( - "Image", - order_by="Image.created_at.desc()", # 최신순 -) - -# 또는 명시적으로 -from sqlalchemy import desc -images: Mapped[list["Image"]] = relationship( - "Image", - order_by=desc(Image.created_at), -) -``` - -### 6.8 viewonly 옵션 - -읽기 전용 관계로 지정합니다 (쓰기 비활성화). - -```python -# 통계/조회용 관계 -recent_images: Mapped[list["Image"]] = relationship( - "Image", - primaryjoin="and_(Project.id == Image.project_id, Image.created_at > func.now() - interval '7 days')", - viewonly=True, # 이 관계로는 추가/삭제 불가 -) -``` - -### 6.9 옵션 종합 표 - -| 옵션 | 기본값 | 설명 | 주로 사용 위치 | -|------|--------|------|---------------| -| `back_populates` | None | 양방향 연결 | 양쪽 | -| `cascade` | `save-update, merge` | 삭제 정책 | 부모 | -| `lazy` | `select` | 로딩 전략 | 양쪽 | -| `uselist` | True | 리스트/단일 | 1:1에서 False | -| `foreign_keys` | 자동 감지 | FK 명시 | 복수 FK 시 | -| `primaryjoin` | 자동 생성 | 조인 조건 | 복잡한 조건 | -| `order_by` | None | 정렬 순서 | 부모 | -| `viewonly` | False | 읽기 전용 | 특수 관계 | - ---- - -## 7. 관계별 정의 방법 (1:1, 1:N, N:M) - -### 7.1 1:1 (One-to-One) - -한 레코드가 다른 테이블의 한 레코드와만 연결됩니다. - -``` -┌─────────────┐ ┌─────────────┐ -│ User │────────│ Profile │ -│ (parent) │ 1:1 │ (child) │ -└─────────────┘ └─────────────┘ -``` - -#### 기본 예제 - -```python -class User(Base): - __tablename__ = "user" - - id: Mapped[int] = mapped_column(primary_key=True) - username: Mapped[str] = mapped_column(String(50), unique=True) - - # 1:1 관계 - uselist=False - profile: Mapped["Profile"] = relationship( - "Profile", - back_populates="user", - uselist=False, # 핵심! 단일 객체 반환 - cascade="all, delete-orphan", - ) - - -class Profile(Base): - __tablename__ = "profile" - - id: Mapped[int] = mapped_column(primary_key=True) - user_id: Mapped[int] = mapped_column( - ForeignKey("user.id"), - unique=True # 1:1 보장 - ) - bio: Mapped[str | None] = mapped_column(Text) - - user: Mapped["User"] = relationship( - "User", - back_populates="profile", - ) -``` - -#### 1:1 핵심 포인트 - -```python -# 1. FK에 unique=True -user_id: Mapped[int] = mapped_column(ForeignKey("user.id"), unique=True) - -# 2. 부모 relationship에 uselist=False -profile: Mapped["Profile"] = relationship("Profile", uselist=False) -``` - -#### 사용 예시 - -```python -# 생성 -user = User(username="john") -user.profile = Profile(bio="Hello, I'm John") # 단일 객체 할당 -session.add(user) -session.commit() - -# 조회 -user = session.get(User, 1) -print(user.profile.bio) # 직접 접근 (리스트 아님) - -# 수정 -user.profile.bio = "Updated bio" -session.commit() - -# 교체 -user.profile = Profile(bio="New profile") # 기존 profile은 orphan 삭제 -session.commit() -``` - -### 7.2 1:N (One-to-Many) - -한 레코드가 여러 레코드와 연결됩니다. **가장 일반적인 관계입니다.** - -``` -┌─────────────┐ ┌─────────────┐ -│ Project │────────<│ Image │ -│ (parent) │ 1:N │ (child) │ -└─────────────┘ └─────────────┘ -``` - -#### 기본 예제 - -```python -class Project(Base): - __tablename__ = "project" - - id: Mapped[int] = mapped_column(primary_key=True) - store_name: Mapped[str] = mapped_column(String(255)) - - # 1:N 관계 - 리스트 타입 - images: Mapped[list["Image"]] = relationship( - "Image", - back_populates="project", - cascade="all, delete-orphan", - lazy="selectin", - ) - - -class Image(Base): - __tablename__ = "image" - - id: Mapped[int] = mapped_column(primary_key=True) - project_id: Mapped[int] = mapped_column(ForeignKey("project.id")) - filename: Mapped[str] = mapped_column(String(255)) - - # N:1 관계 - project: Mapped["Project"] = relationship( - "Project", - back_populates="images", - ) -``` - -#### 사용 예시 - -```python -# 생성 - 방법 1: 부모에 추가 -project = Project(store_name="카페") -project.images.append(Image(filename="logo.png")) -project.images.append(Image(filename="photo.jpg")) -session.add(project) -session.commit() - -# 생성 - 방법 2: 한번에 정의 -project = Project( - store_name="카페", - images=[ - Image(filename="logo.png"), - Image(filename="photo.jpg"), - ] -) -session.add(project) -session.commit() - -# 조회 -project = session.get(Project, 1) -for image in project.images: - print(image.filename) - -# 자식에서 부모 접근 -image = session.get(Image, 1) -print(image.project.store_name) - -# 자식 추가 -project.images.append(Image(filename="new.png")) -session.commit() - -# 자식 제거 (delete-orphan이면 DB에서도 삭제) -image_to_remove = project.images[0] -project.images.remove(image_to_remove) -session.commit() -``` - -### 7.3 N:M (Many-to-Many) - -양쪽 모두 여러 레코드와 연결됩니다. **연결 테이블(Association Table)이 필요합니다.** - -``` -┌─────────────┐ ┌─────────────┐ ┌─────────────┐ -│ Post │────────<│ post_tag │>────────│ Tag │ -│ │ N:M │ (중간테이블) │ N:M │ │ -└─────────────┘ └─────────────┘ └─────────────┘ -``` - -#### 방법 1: Association Table (단순 연결) - -```python -from sqlalchemy import Table, Column, Integer, ForeignKey - -# 중간 테이블 정의 (모델 클래스 없이) -post_tag = Table( - "post_tag", - Base.metadata, - Column("post_id", Integer, ForeignKey("post.id"), primary_key=True), - Column("tag_id", Integer, ForeignKey("tag.id"), primary_key=True), -) - - -class Post(Base): - __tablename__ = "post" - - id: Mapped[int] = mapped_column(primary_key=True) - title: Mapped[str] = mapped_column(String(200)) - - # N:M 관계 - secondary로 중간 테이블 지정 - tags: Mapped[list["Tag"]] = relationship( - "Tag", - secondary=post_tag, # 중간 테이블 - back_populates="posts", - ) - - -class Tag(Base): - __tablename__ = "tag" - - id: Mapped[int] = mapped_column(primary_key=True) - name: Mapped[str] = mapped_column(String(50), unique=True) - - posts: Mapped[list["Post"]] = relationship( - "Post", - secondary=post_tag, - back_populates="tags", - ) -``` - -#### N:M 사용 예시 - -```python -# 생성 -post = Post(title="Python 팁") -tag1 = Tag(name="python") -tag2 = Tag(name="tutorial") - -post.tags.append(tag1) -post.tags.append(tag2) -session.add(post) -session.commit() - -# 또는 한번에 -post = Post( - title="Python 팁", - tags=[Tag(name="python"), Tag(name="tutorial")] -) - -# 조회 -post = session.get(Post, 1) -for tag in post.tags: - print(tag.name) - -tag = session.get(Tag, 1) -for post in tag.posts: - print(post.title) - -# 태그 추가/제거 -post.tags.append(existing_tag) -post.tags.remove(tag_to_remove) # 중간 테이블에서만 삭제 -session.commit() -``` - -#### 방법 2: Association Object (추가 데이터 필요 시) - -중간 테이블에 추가 컬럼이 필요한 경우 사용합니다. - -```python -class PostTag(Base): - """중간 테이블 - 추가 데이터 포함""" - __tablename__ = "post_tag" - - post_id: Mapped[int] = mapped_column(ForeignKey("post.id"), primary_key=True) - tag_id: Mapped[int] = mapped_column(ForeignKey("tag.id"), primary_key=True) - - # 추가 데이터 - created_at: Mapped[datetime] = mapped_column(default=func.now()) - created_by: Mapped[int | None] = mapped_column(ForeignKey("user.id")) - - # 양쪽 관계 - post: Mapped["Post"] = relationship("Post", back_populates="post_tags") - tag: Mapped["Tag"] = relationship("Tag", back_populates="post_tags") - - -class Post(Base): - __tablename__ = "post" - - id: Mapped[int] = mapped_column(primary_key=True) - title: Mapped[str] = mapped_column(String(200)) - - post_tags: Mapped[list["PostTag"]] = relationship( - "PostTag", - back_populates="post", - cascade="all, delete-orphan", - ) - - # 편의를 위한 프로퍼티 - @property - def tags(self) -> list["Tag"]: - return [pt.tag for pt in self.post_tags] - - -class Tag(Base): - __tablename__ = "tag" - - id: Mapped[int] = mapped_column(primary_key=True) - name: Mapped[str] = mapped_column(String(50)) - - post_tags: Mapped[list["PostTag"]] = relationship( - "PostTag", - back_populates="tag", - ) -``` - -#### Association Object 사용 예시 - -```python -# 생성 - 추가 데이터 포함 -post = Post(title="Python 팁") -tag = Tag(name="python") - -post_tag = PostTag(tag=tag, created_by=current_user.id) -post.post_tags.append(post_tag) - -session.add(post) -session.commit() - -# 조회 - 추가 데이터 접근 -for pt in post.post_tags: - print(f"Tag: {pt.tag.name}, Added: {pt.created_at}") -``` - -### 7.4 관계 비교 표 - -| 관계 | FK 위치 | 부모 타입 | 자식 타입 | 특수 설정 | -|------|---------|----------|----------|----------| -| **1:1** | 자식 | `Mapped["Child"]` | `Mapped["Parent"]` | `uselist=False`, `unique=True` | -| **1:N** | 자식 | `Mapped[list["Child"]]` | `Mapped["Parent"]` | 기본 설정 | -| **N:M** | 중간 테이블 | `Mapped[list["Other"]]` | `Mapped[list["Other"]]` | `secondary=` | - ---- - -## 8. ORM 사용법 - -### 8.1 생성 (Create) - -```python -# ───────────────────────────────────────────────────── -# 방법 1: relationship으로 연결 -# ───────────────────────────────────────────────────── -project = Project(store_name="카페") - -# append로 추가 -project.images.append(Image(filename="logo.png")) -project.images.append(Image(filename="photo.jpg")) - -session.add(project) # project만 add해도 images도 저장됨 -session.commit() - - -# ───────────────────────────────────────────────────── -# 방법 2: 생성자에서 한번에 -# ───────────────────────────────────────────────────── -project = Project( - store_name="카페", - images=[ - Image(filename="logo.png"), - Image(filename="photo.jpg"), - ] -) -session.add(project) -session.commit() - - -# ───────────────────────────────────────────────────── -# 방법 3: FK 직접 지정 -# ───────────────────────────────────────────────────── -project = Project(store_name="카페") -session.add(project) -session.flush() # ID 생성 - -image = Image(project_id=project.id, filename="logo.png") -session.add(image) -session.commit() -``` - -### 8.2 조회 (Read) - -```python -# ───────────────────────────────────────────────────── -# 기본 조회 -# ───────────────────────────────────────────────────── -project = session.get(Project, 1) -print(project.images) # lazy 설정에 따라 로딩 - - -# ───────────────────────────────────────────────────── -# Eager Loading (명시적) -# ───────────────────────────────────────────────────── -from sqlalchemy.orm import selectinload, joinedload - -# selectinload - 1:N에 권장 -stmt = ( - select(Project) - .options(selectinload(Project.images)) - .where(Project.id == 1) -) -project = session.scalar(stmt) - -# joinedload - 1:1, N:1에 권장 -stmt = ( - select(Image) - .options(joinedload(Image.project)) - .where(Image.id == 1) -) -image = session.scalar(stmt) - -# 중첩 로딩 -stmt = ( - select(Project) - .options( - selectinload(Project.lyrics) - .selectinload(Lyric.songs) - ) -) - - -# ───────────────────────────────────────────────────── -# 필터링과 함께 -# ───────────────────────────────────────────────────── -# 특정 조건의 자식을 가진 부모 -stmt = ( - select(Project) - .join(Project.images) - .where(Image.filename.like("%.png")) - .distinct() -) - -# 자식 개수와 함께 -from sqlalchemy import func - -stmt = ( - select(Project, func.count(Image.id).label("image_count")) - .join(Project.images, isouter=True) - .group_by(Project.id) -) -``` - -### 8.3 수정 (Update) - -```python -# ───────────────────────────────────────────────────── -# 자식 추가 -# ───────────────────────────────────────────────────── -project = session.get(Project, 1) -project.images.append(Image(filename="new.png")) -session.commit() - - -# ───────────────────────────────────────────────────── -# 자식 수정 -# ───────────────────────────────────────────────────── -project = session.get(Project, 1) -project.images[0].filename = "updated.png" -session.commit() - - -# ───────────────────────────────────────────────────── -# 부모 변경 (relationship 사용) -# ───────────────────────────────────────────────────── -image = session.get(Image, 1) -new_project = session.get(Project, 2) -image.project = new_project # FK 자동 업데이트 -session.commit() - - -# ───────────────────────────────────────────────────── -# 부모 변경 (FK 직접 사용) -# ───────────────────────────────────────────────────── -image = session.get(Image, 1) -image.project_id = 2 -session.commit() -``` - -### 8.4 삭제 (Delete) - -```python -# ───────────────────────────────────────────────────── -# 부모 삭제 (cascade 동작) -# ───────────────────────────────────────────────────── -# cascade="all, delete-orphan" 설정 시 -project = session.get(Project, 1) -session.delete(project) -session.commit() -# → 모든 images도 삭제됨 - - -# ───────────────────────────────────────────────────── -# 자식만 삭제 -# ───────────────────────────────────────────────────── -image = session.get(Image, 1) -session.delete(image) -session.commit() - - -# ───────────────────────────────────────────────────── -# 부모에서 분리 (delete-orphan 시 삭제됨) -# ───────────────────────────────────────────────────── -project = session.get(Project, 1) -image = project.images[0] -project.images.remove(image) -session.commit() -# → delete-orphan이면 image도 DB에서 삭제 - - -# ───────────────────────────────────────────────────── -# 자식 전체 교체 -# ───────────────────────────────────────────────────── -project = session.get(Project, 1) -project.images = [Image(filename="new1.png"), Image(filename="new2.png")] -session.commit() -# → 기존 images는 orphan이 되어 삭제됨 (delete-orphan 시) -``` - ---- - -## 9. 실무 패턴 - -### 9.1 표준 모델 템플릿 - -```python -from datetime import datetime -from typing import List -from sqlalchemy import String, Text, ForeignKey, func -from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship - - -class Base(DeclarativeBase): - pass - - -class TimestampMixin: - """생성/수정 시간 공통 믹스인""" - created_at: Mapped[datetime] = mapped_column(default=func.now()) - updated_at: Mapped[datetime] = mapped_column( - default=func.now(), - onupdate=func.now() - ) - - -class Project(TimestampMixin, Base): - __tablename__ = "project" - - id: Mapped[int] = mapped_column(primary_key=True) - store_name: Mapped[str] = mapped_column(String(255)) - task_id: Mapped[str] = mapped_column(String(36), unique=True, index=True) - - # 1:N 관계들 - images: Mapped[List["Image"]] = relationship( - "Image", - back_populates="project", - cascade="all, delete-orphan", - lazy="selectin", - order_by="Image.created_at.desc()", - ) - - lyrics: Mapped[List["Lyric"]] = relationship( - "Lyric", - back_populates="project", - cascade="all, delete-orphan", - lazy="selectin", - ) - - def __repr__(self) -> str: - return f"" - - -class Image(TimestampMixin, Base): - __tablename__ = "image" - - id: Mapped[int] = mapped_column(primary_key=True) - project_id: Mapped[int] = mapped_column( - ForeignKey("project.id", ondelete="CASCADE"), - index=True, - ) - original_filename: Mapped[str] = mapped_column(String(255)) - stored_filename: Mapped[str] = mapped_column(String(255)) - url: Mapped[str] = mapped_column(Text) - - # N:1 관계 - project: Mapped["Project"] = relationship( - "Project", - back_populates="images", - ) - - def __repr__(self) -> str: - return f"" -``` - -### 9.2 서비스 레이어 패턴 - -```python -from sqlalchemy import select -from sqlalchemy.orm import Session, selectinload - - -class ProjectService: - def __init__(self, session: Session): - self.session = session - - def create_with_images( - self, - store_name: str, - task_id: str, - image_data: list[dict] - ) -> Project: - """프로젝트와 이미지를 함께 생성""" - project = Project( - store_name=store_name, - task_id=task_id, - images=[Image(**data) for data in image_data], - ) - self.session.add(project) - self.session.commit() - self.session.refresh(project) - return project - - def get_with_images(self, project_id: int) -> Project | None: - """프로젝트와 이미지를 함께 조회""" - stmt = ( - select(Project) - .options(selectinload(Project.images)) - .where(Project.id == project_id) - ) - return self.session.scalar(stmt) - - def get_by_task_id(self, task_id: str) -> Project | None: - """task_id로 조회""" - stmt = ( - select(Project) - .options(selectinload(Project.images)) - .where(Project.task_id == task_id) - ) - return self.session.scalar(stmt) - - def add_image(self, project_id: int, image: Image) -> Image: - """기존 프로젝트에 이미지 추가""" - project = self.session.get(Project, project_id) - if not project: - raise ValueError("Project not found") - - project.images.append(image) - self.session.commit() - self.session.refresh(image) - return image - - def delete(self, project_id: int) -> bool: - """프로젝트 삭제 (이미지도 cascade 삭제)""" - project = self.session.get(Project, project_id) - if not project: - return False - - self.session.delete(project) - self.session.commit() - return True -``` - -### 9.3 FastAPI 엔드포인트 패턴 - -```python -from fastapi import APIRouter, Depends, HTTPException -from sqlalchemy.orm import Session - -router = APIRouter(prefix="/projects", tags=["projects"]) - - -@router.post("/", response_model=ProjectResponse) -def create_project( - data: ProjectCreate, - session: Session = Depends(get_session), -): - service = ProjectService(session) - project = service.create_with_images( - store_name=data.store_name, - task_id=data.task_id, - image_data=[img.model_dump() for img in data.images], - ) - return project - - -@router.get("/{project_id}", response_model=ProjectWithImagesResponse) -def get_project( - project_id: int, - session: Session = Depends(get_session), -): - service = ProjectService(session) - project = service.get_with_images(project_id) - if not project: - raise HTTPException(status_code=404, detail="Project not found") - return project - - -@router.post("/{project_id}/images", response_model=ImageResponse) -def add_image( - project_id: int, - data: ImageCreate, - session: Session = Depends(get_session), -): - service = ProjectService(session) - image = Image(**data.model_dump()) - return service.add_image(project_id, image) -``` - ---- - -## 10. Quick Reference - -### 10.1 relationship 정의 체크리스트 - -```python -# ✅ 부모 (1 쪽) -children: Mapped[list["Child"]] = relationship( - "Child", # 1. 대상 클래스 - back_populates="parent", # 2. 반대편 속성명 - cascade="all, delete-orphan", # 3. 삭제 정책 - lazy="selectin", # 4. 로딩 전략 -) - -# ✅ 자식 (N 쪽) -parent_id: Mapped[int] = mapped_column(ForeignKey("parent.id")) # FK 필수! -parent: Mapped["Parent"] = relationship( - "Parent", # 1. 대상 클래스 - back_populates="children", # 2. 반대편 속성명 -) -``` - -### 10.2 관계별 빠른 참조 - -```python -# 1:1 -# 부모: uselist=False -# 자식 FK: unique=True - -# 1:N -# 부모: list["Child"] -# 자식: "Parent" - -# N:M -# secondary=association_table -# 또는 Association Object 패턴 -``` - -### 10.3 자주 쓰는 옵션 조합 - -```python -# 기본 1:N (부모 측) -cascade="all, delete-orphan", lazy="selectin" - -# 기본 N:1 (자식 측) -# 옵션 없이 back_populates만 - -# 1:1 (부모 측) -uselist=False, cascade="all, delete-orphan" - -# 읽기 전용 관계 -viewonly=True - -# 복수 FK -foreign_keys=[column] -``` - -### 10.4 흔한 실수 - -```python -# ❌ 잘못된 예 -class Parent(Base): - children = relationship("Child") # Mapped 타입 힌트 없음 - -class Child(Base): - parent_id = Column(Integer) # ForeignKey 없음 - parent = relationship("Parent", back_populates="childs") # 오타 - - -# ✅ 올바른 예 -class Parent(Base): - children: Mapped[list["Child"]] = relationship("Child", back_populates="parent") - -class Child(Base): - parent_id: Mapped[int] = mapped_column(ForeignKey("parent.id")) - parent: Mapped["Parent"] = relationship("Parent", back_populates="children") -``` - ---- - -## 부록: 참고 자료 - -- [SQLAlchemy 2.0 공식 문서](https://docs.sqlalchemy.org/en/20/) -- [SQLAlchemy Relationship Configuration](https://docs.sqlalchemy.org/en/20/orm/relationships.html) -- [SQLAlchemy Basic Relationship Patterns](https://docs.sqlalchemy.org/en/20/orm/basic_relationships.html) +# SQLAlchemy Relationship 완벽 가이드 + +> SQLAlchemy 2.0+ / Python 3.10+ 기준 + +--- + +## 목차 + +1. [개요](#1-개요) +2. [기본 개념](#2-기본-개념) +3. [relationship 정의 문법](#3-relationship-정의-문법) +4. [부모와 자식에서의 정의 차이](#4-부모와-자식에서의-정의-차이) +5. [FK 필드 vs back_populates](#5-fk-필드-vs-back_populates) +6. [relationship 옵션 상세](#6-relationship-옵션-상세) +7. [관계별 정의 방법 (1:1, 1:N, N:M)](#7-관계별-정의-방법-11-1n-nm) +8. [ORM 사용법](#8-orm-사용법) +9. [실무 패턴](#9-실무-패턴) +10. [Quick Reference](#10-quick-reference) + +--- + +## 1. 개요 + +### 1.1 relationship이란? + +`relationship()`은 SQLAlchemy ORM에서 **테이블 간의 관계를 Python 객체로 매핑**하는 기능입니다. + +``` +┌─────────────────────────────────────────────────────────┐ +│ Database Level ORM Level │ +│ ────────────── ───────── │ +│ FOREIGN KEY → relationship() │ +│ JOIN 쿼리 → object.related_objects │ +└─────────────────────────────────────────────────────────┘ +``` + +### 1.2 ForeignKey vs relationship + +| 구분 | ForeignKey | relationship | +|------|------------|--------------| +| **역할** | DB 레벨 제약조건 | ORM 레벨 객체 연결 | +| **위치** | 자식 테이블에만 | 양쪽 모두 가능 | +| **필수 여부** | FK 관계에 필수 | 선택사항 (편의 기능) | +| **결과** | 컬럼 생성 | Python 속성 생성 | + +```python +# ForeignKey: DB에 실제 컬럼 생성 +project_id: Mapped[int] = mapped_column(ForeignKey("project.id")) + +# relationship: Python 객체 접근 경로 생성 +project: Mapped["Project"] = relationship("Project") +``` + +--- + +## 2. 기본 개념 + +### 2.1 용어 정의 + +``` +┌─────────────────────────────────────────────────────────┐ +│ 부모 (Parent) 자식 (Child) │ +│ ───────────── ───────────── │ +│ • "One" 쪽 • "Many" 쪽 │ +│ • FK를 참조받음 • FK를 정의함 │ +│ • 예: Project • 예: Image │ +└─────────────────────────────────────────────────────────┘ +``` + +### 2.2 관계 방향 + +```python +# 단방향 (Unidirectional) +# - 한쪽에서만 relationship 정의 +# - 반대쪽 접근 불가 + +# 양방향 (Bidirectional) +# - 양쪽 모두 relationship 정의 +# - back_populates로 연결 +# - 실무 권장 방식 +``` + +### 2.3 기본 예제 (가장 간단한 형태) + +```python +from sqlalchemy import ForeignKey, String +from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship + + +class Base(DeclarativeBase): + pass + + +# 부모 테이블 +class Project(Base): + __tablename__ = "project" + + id: Mapped[int] = mapped_column(primary_key=True) + name: Mapped[str] = mapped_column(String(100)) + + # 자식들에 대한 접근 경로 + images: Mapped[list["Image"]] = relationship("Image", back_populates="project") + + +# 자식 테이블 +class Image(Base): + __tablename__ = "image" + + id: Mapped[int] = mapped_column(primary_key=True) + project_id: Mapped[int] = mapped_column(ForeignKey("project.id")) # FK + filename: Mapped[str] = mapped_column(String(255)) + + # 부모에 대한 접근 경로 + project: Mapped["Project"] = relationship("Project", back_populates="images") +``` + +--- + +## 3. relationship 정의 문법 + +### 3.1 기본 문법 + +```python +from sqlalchemy.orm import relationship, Mapped +from typing import List + +# 기본 형태 +속성명: Mapped[타입] = relationship("대상클래스", 옵션들...) + +# 부모 측 (1:N에서 "1") +children: Mapped[List["Child"]] = relationship("Child", back_populates="parent") + +# 자식 측 (1:N에서 "N") +parent: Mapped["Parent"] = relationship("Parent", back_populates="children") +``` + +### 3.2 필수 항목 + +| 항목 | 설명 | 예시 | +|------|------|------| +| **첫 번째 인자** | 대상 모델 클래스명 (문자열) | `"Project"` | + +```python +# 최소한의 정의 (단방향) +project: Mapped["Project"] = relationship("Project") +``` + +### 3.3 권장 항목 + +| 항목 | 설명 | 예시 | +|------|------|------| +| `back_populates` | 반대편 relationship 속성명 | `back_populates="images"` | + +```python +# 권장하는 정의 (양방향) +project: Mapped["Project"] = relationship("Project", back_populates="images") +``` + +--- + +## 4. 부모와 자식에서의 정의 차이 + +### 4.1 구조 비교 + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ 부모 (Parent) │ +├─────────────────────────────────────────────────────────────────┤ +│ • ForeignKey: 없음 │ +│ • relationship 타입: List["Child"] 또는 list["Child"] │ +│ • cascade 옵션: 여기에 정의 (삭제 정책) │ +│ • 역할: 자식 컬렉션에 대한 접근 제공 │ +└─────────────────────────────────────────────────────────────────┘ + │ + │ 참조 + ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ 자식 (Child) │ +├─────────────────────────────────────────────────────────────────┤ +│ • ForeignKey: 있음 (필수) │ +│ • relationship 타입: "Parent" (단수) │ +│ • cascade 옵션: 일반적으로 정의 안 함 │ +│ • 역할: 부모 객체에 대한 접근 제공 │ +└─────────────────────────────────────────────────────────────────┘ +``` + +### 4.2 부모 클래스 정의 + +```python +class Project(Base): + """부모 클래스 - FK 없음, 자식 컬렉션 관리""" + __tablename__ = "project" + + id: Mapped[int] = mapped_column(primary_key=True) + store_name: Mapped[str] = mapped_column(String(255)) + + # ───────────────────────────────────────────────────── + # relationship 정의 (부모 측) + # ───────────────────────────────────────────────────── + images: Mapped[list["Image"]] = relationship( + "Image", # 대상 클래스 + back_populates="project", # 자식의 relationship 속성명 + cascade="all, delete-orphan", # 삭제 정책 (부모에서 정의) + lazy="selectin", # 로딩 전략 + order_by="Image.created_at", # 정렬 (선택) + ) +``` + +**부모 측 특징:** +- `Mapped[list["Child"]]` - 복수형 리스트 타입 +- `cascade` 옵션을 여기서 정의 +- FK 컬럼 없음 + +### 4.3 자식 클래스 정의 + +```python +class Image(Base): + """자식 클래스 - FK 있음, 부모 참조""" + __tablename__ = "image" + + id: Mapped[int] = mapped_column(primary_key=True) + original_filename: Mapped[str] = mapped_column(String(255)) + + # ───────────────────────────────────────────────────── + # ForeignKey 정의 (자식 측에서만) + # ───────────────────────────────────────────────────── + project_id: Mapped[int] = mapped_column( + ForeignKey("project.id", ondelete="CASCADE") + ) + + # ───────────────────────────────────────────────────── + # relationship 정의 (자식 측) + # ───────────────────────────────────────────────────── + project: Mapped["Project"] = relationship( + "Project", # 대상 클래스 + back_populates="images", # 부모의 relationship 속성명 + ) +``` + +**자식 측 특징:** +- `Mapped["Parent"]` - 단수형 타입 +- FK 컬럼 정의 필수 +- cascade는 보통 정의하지 않음 + +### 4.4 비교 표 + +| 항목 | 부모 (One) | 자식 (Many) | +|------|-----------|-------------| +| **ForeignKey** | ❌ 없음 | ✅ 필수 | +| **Mapped 타입** | `list["Child"]` | `"Parent"` | +| **cascade** | ✅ 여기서 정의 | ❌ 보통 안 함 | +| **back_populates** | 자식의 속성명 | 부모의 속성명 | +| **접근 결과** | 리스트 | 단일 객체 | + +--- + +## 5. FK 필드 vs back_populates + +### 5.1 두 가지 접근 방식 + +```python +class Image(Base): + # 방식 1: FK 필드 직접 사용 + project_id: Mapped[int] = mapped_column(ForeignKey("project.id")) + + # 방식 2: relationship 사용 + project: Mapped["Project"] = relationship("Project", back_populates="images") +``` + +### 5.2 FK 필드 직접 사용 + +```python +# ───────────────────────────────────────────────────── +# FK 필드로 직접 조작 +# ───────────────────────────────────────────────────── + +# 생성 +image = Image( + project_id=1, # FK 값 직접 지정 + original_filename="photo.jpg" +) +session.add(image) +session.commit() + + +# 수정 +image = session.get(Image, 1) +image.project_id = 2 # FK 값 직접 변경 +session.commit() + + +# 조회 +image = session.get(Image, 1) +print(image.project_id) # 정수 값: 1 + +# 부모 객체 접근하려면 추가 쿼리 필요 +project = session.get(Project, image.project_id) +``` + +**특징:** +- 단순 정수 값 조작 +- 객체 관계를 신경 쓰지 않음 +- 추가 쿼리 없이 FK 값만 필요할 때 유용 + +### 5.3 relationship (back_populates) 사용 + +```python +# ───────────────────────────────────────────────────── +# relationship으로 객체 조작 +# ───────────────────────────────────────────────────── + +# 생성 - 객체로 연결 +project = session.get(Project, 1) +image = Image( + project=project, # 객체로 연결 (FK 자동 설정) + original_filename="photo.jpg" +) +session.add(image) +session.commit() + +print(image.project_id) # 자동으로 1 설정됨! + + +# 수정 - 객체로 변경 +image = session.get(Image, 1) +new_project = session.get(Project, 2) +image.project = new_project # 객체로 변경 +session.commit() + +print(image.project_id) # 자동으로 2로 변경됨! + + +# 조회 - 객체 직접 접근 +image = session.get(Image, 1) +print(image.project.store_name) # 바로 객체 속성 접근 +``` + +**특징:** +- 객체 지향적 접근 +- FK 값 자동 동기화 +- 양방향 자동 업데이트 + +### 5.4 양방향 동기화 동작 + +```python +# back_populates의 핵심: 양쪽 자동 동기화 + +project = Project(store_name="카페") +image = Image(original_filename="photo.jpg") + +# 방법 1: 부모에 자식 추가 +project.images.append(image) +print(image.project) # - 자동 설정! +print(image.project_id) # None (아직 flush 전) + +session.add(project) +session.flush() +print(image.project_id) # 1 - flush 후 FK 설정됨 + + +# 방법 2: 자식에 부모 지정 +image2 = Image(original_filename="logo.png") +image2.project = project +print(image2 in project.images) # True - 자동 추가! +``` + +### 5.5 비교 표 + +| 상황 | FK 필드 사용 | relationship 사용 | +|------|-------------|------------------| +| **부모 ID만 필요** | ✅ `image.project_id` | ⚠️ 불필요한 객체 로딩 가능 | +| **부모 객체 접근** | ❌ 추가 쿼리 필요 | ✅ `image.project.name` | +| **자식 추가** | `image.project_id = 1` | `project.images.append(image)` | +| **일괄 생성** | FK 값 직접 지정 | 객체 연결로 자동 설정 | +| **양방향 동기화** | ❌ 수동 관리 | ✅ 자동 | + +### 5.6 공식 권장 사용 방식 + +```python +class Image(Base): + __tablename__ = "image" + + id: Mapped[int] = mapped_column(primary_key=True) + + # 1. FK 필드 - DB 레벨 관계 (필수) + project_id: Mapped[int] = mapped_column(ForeignKey("project.id")) + + # 2. relationship - ORM 레벨 편의 기능 (권장) + project: Mapped["Project"] = relationship("Project", back_populates="images") + + +# 사용 시: +# - 단순 FK 값 조회/설정: project_id 사용 +# - 객체 조작/탐색: project (relationship) 사용 + +image = session.get(Image, 1) +print(image.project_id) # 빠름 (추가 쿼리 없음) +print(image.project.store_name) # 객체 접근 (필요시 쿼리) +``` + +--- + +## 6. relationship 옵션 상세 + +### 6.1 필수/권장 옵션 + +#### 첫 번째 인자: 대상 클래스 + +```python +# 문자열 (Forward Reference) - 권장 +relationship("Project") + +# 클래스 직접 참조 (순환 import 주의) +relationship(Project) +``` + +#### back_populates (양방향 연결) + +```python +# 부모 측 +images: Mapped[list["Image"]] = relationship( + "Image", + back_populates="project" # Image.project와 연결 +) + +# 자식 측 +project: Mapped["Project"] = relationship( + "Project", + back_populates="images" # Project.images와 연결 +) +``` + +### 6.2 cascade 옵션 + +자식 객체의 생명주기 관리. **부모 측에서 정의**합니다. + +```python +images: Mapped[list["Image"]] = relationship( + "Image", + cascade="all, delete-orphan", # 가장 일반적 +) +``` + +#### cascade 값 종류 + +| 값 | 설명 | +|----|------| +| `save-update` | 부모 저장 시 자식도 저장 (기본값에 포함) | +| `merge` | 부모 merge 시 자식도 merge | +| `expunge` | 부모 expunge 시 자식도 expunge | +| `delete` | 부모 삭제 시 자식도 삭제 | +| `delete-orphan` | 부모에서 분리된 자식 삭제 | +| `refresh-expire` | 부모 refresh 시 자식도 refresh | +| `all` | 위 모든 것 (delete-orphan 제외) | + +#### 일반적인 조합 + +```python +# 1. 기본값 (자동 적용) +cascade="save-update, merge" + +# 2. 부모 삭제 시 자식도 삭제 +cascade="all, delete" + +# 3. 부모에서 분리 시에도 삭제 (가장 엄격) +cascade="all, delete-orphan" + +# 4. 삭제 방지 (자식은 독립적) +cascade="save-update, merge" # delete 없음 +``` + +#### cascade 동작 예시 + +```python +class Project(Base): + images: Mapped[list["Image"]] = relationship( + "Image", + cascade="all, delete-orphan", + ) + +# delete-orphan 동작 +project = session.get(Project, 1) +image = project.images[0] +project.images.remove(image) # 부모에서 분리 +session.commit() +# → image가 DB에서도 삭제됨 (orphan이 됨) + +# delete 동작 +project = session.get(Project, 1) +session.delete(project) +session.commit() +# → 모든 project.images도 삭제됨 +``` + +### 6.3 lazy 옵션 (로딩 전략) + +관계 데이터를 언제/어떻게 로딩할지 결정합니다. + +```python +images: Mapped[list["Image"]] = relationship( + "Image", + lazy="selectin", # 로딩 전략 +) +``` + +#### lazy 값 종류 + +| 값 | 로딩 시점 | 쿼리 방식 | 사용 상황 | +|----|----------|----------|----------| +| `select` | 접근 시 (기본값) | 개별 SELECT | 거의 사용 안 함 | +| `selectin` | 부모 로딩 후 | SELECT ... IN | **1:N 권장** | +| `joined` | 부모와 함께 | JOIN | 1:1, N:1 권장 | +| `subquery` | 부모 로딩 후 | 서브쿼리 | 복잡한 경우 | +| `raise` | 접근 시 에러 | - | 명시적 로딩 강제 | +| `noload` | 로딩 안 함 | - | 특수 상황 | +| `dynamic` | Query 객체 반환 | - | 대량 데이터 | +| `write_only` | 쓰기 전용 | - | 대량 데이터 (2.0) | + +#### 로딩 전략 예시 + +```python +# 1. Lazy Loading (기본값) - N+1 문제 발생! +class Project(Base): + images: Mapped[list["Image"]] = relationship("Image", lazy="select") + +projects = session.scalars(select(Project)).all() +for project in projects: + print(project.images) # 매번 쿼리 발생! (N+1) + + +# 2. selectin - 권장 (1:N) +class Project(Base): + images: Mapped[list["Image"]] = relationship("Image", lazy="selectin") + +projects = session.scalars(select(Project)).all() +# 쿼리 1: SELECT * FROM project +# 쿼리 2: SELECT * FROM image WHERE project_id IN (1, 2, 3, ...) +for project in projects: + print(project.images) # 추가 쿼리 없음 + + +# 3. joined - 권장 (1:1, N:1) +class Image(Base): + project: Mapped["Project"] = relationship("Project", lazy="joined") + +images = session.scalars(select(Image)).all() +# 쿼리: SELECT image.*, project.* FROM image JOIN project ... +for image in images: + print(image.project.name) # 추가 쿼리 없음 + + +# 4. raise - 명시적 로딩 강제 +class Project(Base): + images: Mapped[list["Image"]] = relationship("Image", lazy="raise") + +project = session.get(Project, 1) +print(project.images) # 에러! 명시적 로딩 필요 +``` + +### 6.4 uselist 옵션 + +반환 타입을 리스트/단일 객체로 지정합니다. + +```python +# 기본값: True (리스트) +images: Mapped[list["Image"]] = relationship("Image", uselist=True) + +# 1:1 관계에서 단일 객체 +profile: Mapped["Profile"] = relationship("Profile", uselist=False) +``` + +### 6.5 foreign_keys 옵션 + +여러 FK가 있을 때 명시적 지정이 필요합니다. + +```python +class Message(Base): + sender_id: Mapped[int] = mapped_column(ForeignKey("user.id")) + receiver_id: Mapped[int] = mapped_column(ForeignKey("user.id")) + + # 어떤 FK를 사용할지 명시 + sender: Mapped["User"] = relationship( + "User", + foreign_keys=[sender_id], + ) + receiver: Mapped["User"] = relationship( + "User", + foreign_keys=[receiver_id], + ) +``` + +### 6.6 primaryjoin 옵션 + +복잡한 조인 조건을 직접 정의합니다. + +```python +from sqlalchemy import and_ + +class Project(Base): + # 활성 이미지만 조회 + active_images: Mapped[list["Image"]] = relationship( + "Image", + primaryjoin=lambda: and_( + Project.id == Image.project_id, + Image.is_active == True + ), + viewonly=True, + ) +``` + +### 6.7 order_by 옵션 + +자식 컬렉션의 기본 정렬 순서를 지정합니다. + +```python +images: Mapped[list["Image"]] = relationship( + "Image", + order_by="Image.created_at.desc()", # 최신순 +) + +# 또는 명시적으로 +from sqlalchemy import desc +images: Mapped[list["Image"]] = relationship( + "Image", + order_by=desc(Image.created_at), +) +``` + +### 6.8 viewonly 옵션 + +읽기 전용 관계로 지정합니다 (쓰기 비활성화). + +```python +# 통계/조회용 관계 +recent_images: Mapped[list["Image"]] = relationship( + "Image", + primaryjoin="and_(Project.id == Image.project_id, Image.created_at > func.now() - interval '7 days')", + viewonly=True, # 이 관계로는 추가/삭제 불가 +) +``` + +### 6.9 옵션 종합 표 + +| 옵션 | 기본값 | 설명 | 주로 사용 위치 | +|------|--------|------|---------------| +| `back_populates` | None | 양방향 연결 | 양쪽 | +| `cascade` | `save-update, merge` | 삭제 정책 | 부모 | +| `lazy` | `select` | 로딩 전략 | 양쪽 | +| `uselist` | True | 리스트/단일 | 1:1에서 False | +| `foreign_keys` | 자동 감지 | FK 명시 | 복수 FK 시 | +| `primaryjoin` | 자동 생성 | 조인 조건 | 복잡한 조건 | +| `order_by` | None | 정렬 순서 | 부모 | +| `viewonly` | False | 읽기 전용 | 특수 관계 | + +--- + +## 7. 관계별 정의 방법 (1:1, 1:N, N:M) + +### 7.1 1:1 (One-to-One) + +한 레코드가 다른 테이블의 한 레코드와만 연결됩니다. + +``` +┌─────────────┐ ┌─────────────┐ +│ User │────────│ Profile │ +│ (parent) │ 1:1 │ (child) │ +└─────────────┘ └─────────────┘ +``` + +#### 기본 예제 + +```python +class User(Base): + __tablename__ = "user" + + id: Mapped[int] = mapped_column(primary_key=True) + username: Mapped[str] = mapped_column(String(50), unique=True) + + # 1:1 관계 - uselist=False + profile: Mapped["Profile"] = relationship( + "Profile", + back_populates="user", + uselist=False, # 핵심! 단일 객체 반환 + cascade="all, delete-orphan", + ) + + +class Profile(Base): + __tablename__ = "profile" + + id: Mapped[int] = mapped_column(primary_key=True) + user_id: Mapped[int] = mapped_column( + ForeignKey("user.id"), + unique=True # 1:1 보장 + ) + bio: Mapped[str | None] = mapped_column(Text) + + user: Mapped["User"] = relationship( + "User", + back_populates="profile", + ) +``` + +#### 1:1 핵심 포인트 + +```python +# 1. FK에 unique=True +user_id: Mapped[int] = mapped_column(ForeignKey("user.id"), unique=True) + +# 2. 부모 relationship에 uselist=False +profile: Mapped["Profile"] = relationship("Profile", uselist=False) +``` + +#### 사용 예시 + +```python +# 생성 +user = User(username="john") +user.profile = Profile(bio="Hello, I'm John") # 단일 객체 할당 +session.add(user) +session.commit() + +# 조회 +user = session.get(User, 1) +print(user.profile.bio) # 직접 접근 (리스트 아님) + +# 수정 +user.profile.bio = "Updated bio" +session.commit() + +# 교체 +user.profile = Profile(bio="New profile") # 기존 profile은 orphan 삭제 +session.commit() +``` + +### 7.2 1:N (One-to-Many) + +한 레코드가 여러 레코드와 연결됩니다. **가장 일반적인 관계입니다.** + +``` +┌─────────────┐ ┌─────────────┐ +│ Project │────────<│ Image │ +│ (parent) │ 1:N │ (child) │ +└─────────────┘ └─────────────┘ +``` + +#### 기본 예제 + +```python +class Project(Base): + __tablename__ = "project" + + id: Mapped[int] = mapped_column(primary_key=True) + store_name: Mapped[str] = mapped_column(String(255)) + + # 1:N 관계 - 리스트 타입 + images: Mapped[list["Image"]] = relationship( + "Image", + back_populates="project", + cascade="all, delete-orphan", + lazy="selectin", + ) + + +class Image(Base): + __tablename__ = "image" + + id: Mapped[int] = mapped_column(primary_key=True) + project_id: Mapped[int] = mapped_column(ForeignKey("project.id")) + filename: Mapped[str] = mapped_column(String(255)) + + # N:1 관계 + project: Mapped["Project"] = relationship( + "Project", + back_populates="images", + ) +``` + +#### 사용 예시 + +```python +# 생성 - 방법 1: 부모에 추가 +project = Project(store_name="카페") +project.images.append(Image(filename="logo.png")) +project.images.append(Image(filename="photo.jpg")) +session.add(project) +session.commit() + +# 생성 - 방법 2: 한번에 정의 +project = Project( + store_name="카페", + images=[ + Image(filename="logo.png"), + Image(filename="photo.jpg"), + ] +) +session.add(project) +session.commit() + +# 조회 +project = session.get(Project, 1) +for image in project.images: + print(image.filename) + +# 자식에서 부모 접근 +image = session.get(Image, 1) +print(image.project.store_name) + +# 자식 추가 +project.images.append(Image(filename="new.png")) +session.commit() + +# 자식 제거 (delete-orphan이면 DB에서도 삭제) +image_to_remove = project.images[0] +project.images.remove(image_to_remove) +session.commit() +``` + +### 7.3 N:M (Many-to-Many) + +양쪽 모두 여러 레코드와 연결됩니다. **연결 테이블(Association Table)이 필요합니다.** + +``` +┌─────────────┐ ┌─────────────┐ ┌─────────────┐ +│ Post │────────<│ post_tag │>────────│ Tag │ +│ │ N:M │ (중간테이블) │ N:M │ │ +└─────────────┘ └─────────────┘ └─────────────┘ +``` + +#### 방법 1: Association Table (단순 연결) + +```python +from sqlalchemy import Table, Column, Integer, ForeignKey + +# 중간 테이블 정의 (모델 클래스 없이) +post_tag = Table( + "post_tag", + Base.metadata, + Column("post_id", Integer, ForeignKey("post.id"), primary_key=True), + Column("tag_id", Integer, ForeignKey("tag.id"), primary_key=True), +) + + +class Post(Base): + __tablename__ = "post" + + id: Mapped[int] = mapped_column(primary_key=True) + title: Mapped[str] = mapped_column(String(200)) + + # N:M 관계 - secondary로 중간 테이블 지정 + tags: Mapped[list["Tag"]] = relationship( + "Tag", + secondary=post_tag, # 중간 테이블 + back_populates="posts", + ) + + +class Tag(Base): + __tablename__ = "tag" + + id: Mapped[int] = mapped_column(primary_key=True) + name: Mapped[str] = mapped_column(String(50), unique=True) + + posts: Mapped[list["Post"]] = relationship( + "Post", + secondary=post_tag, + back_populates="tags", + ) +``` + +#### N:M 사용 예시 + +```python +# 생성 +post = Post(title="Python 팁") +tag1 = Tag(name="python") +tag2 = Tag(name="tutorial") + +post.tags.append(tag1) +post.tags.append(tag2) +session.add(post) +session.commit() + +# 또는 한번에 +post = Post( + title="Python 팁", + tags=[Tag(name="python"), Tag(name="tutorial")] +) + +# 조회 +post = session.get(Post, 1) +for tag in post.tags: + print(tag.name) + +tag = session.get(Tag, 1) +for post in tag.posts: + print(post.title) + +# 태그 추가/제거 +post.tags.append(existing_tag) +post.tags.remove(tag_to_remove) # 중간 테이블에서만 삭제 +session.commit() +``` + +#### 방법 2: Association Object (추가 데이터 필요 시) + +중간 테이블에 추가 컬럼이 필요한 경우 사용합니다. + +```python +class PostTag(Base): + """중간 테이블 - 추가 데이터 포함""" + __tablename__ = "post_tag" + + post_id: Mapped[int] = mapped_column(ForeignKey("post.id"), primary_key=True) + tag_id: Mapped[int] = mapped_column(ForeignKey("tag.id"), primary_key=True) + + # 추가 데이터 + created_at: Mapped[datetime] = mapped_column(default=func.now()) + created_by: Mapped[int | None] = mapped_column(ForeignKey("user.id")) + + # 양쪽 관계 + post: Mapped["Post"] = relationship("Post", back_populates="post_tags") + tag: Mapped["Tag"] = relationship("Tag", back_populates="post_tags") + + +class Post(Base): + __tablename__ = "post" + + id: Mapped[int] = mapped_column(primary_key=True) + title: Mapped[str] = mapped_column(String(200)) + + post_tags: Mapped[list["PostTag"]] = relationship( + "PostTag", + back_populates="post", + cascade="all, delete-orphan", + ) + + # 편의를 위한 프로퍼티 + @property + def tags(self) -> list["Tag"]: + return [pt.tag for pt in self.post_tags] + + +class Tag(Base): + __tablename__ = "tag" + + id: Mapped[int] = mapped_column(primary_key=True) + name: Mapped[str] = mapped_column(String(50)) + + post_tags: Mapped[list["PostTag"]] = relationship( + "PostTag", + back_populates="tag", + ) +``` + +#### Association Object 사용 예시 + +```python +# 생성 - 추가 데이터 포함 +post = Post(title="Python 팁") +tag = Tag(name="python") + +post_tag = PostTag(tag=tag, created_by=current_user.id) +post.post_tags.append(post_tag) + +session.add(post) +session.commit() + +# 조회 - 추가 데이터 접근 +for pt in post.post_tags: + print(f"Tag: {pt.tag.name}, Added: {pt.created_at}") +``` + +### 7.4 관계 비교 표 + +| 관계 | FK 위치 | 부모 타입 | 자식 타입 | 특수 설정 | +|------|---------|----------|----------|----------| +| **1:1** | 자식 | `Mapped["Child"]` | `Mapped["Parent"]` | `uselist=False`, `unique=True` | +| **1:N** | 자식 | `Mapped[list["Child"]]` | `Mapped["Parent"]` | 기본 설정 | +| **N:M** | 중간 테이블 | `Mapped[list["Other"]]` | `Mapped[list["Other"]]` | `secondary=` | + +--- + +## 8. ORM 사용법 + +### 8.1 생성 (Create) + +```python +# ───────────────────────────────────────────────────── +# 방법 1: relationship으로 연결 +# ───────────────────────────────────────────────────── +project = Project(store_name="카페") + +# append로 추가 +project.images.append(Image(filename="logo.png")) +project.images.append(Image(filename="photo.jpg")) + +session.add(project) # project만 add해도 images도 저장됨 +session.commit() + + +# ───────────────────────────────────────────────────── +# 방법 2: 생성자에서 한번에 +# ───────────────────────────────────────────────────── +project = Project( + store_name="카페", + images=[ + Image(filename="logo.png"), + Image(filename="photo.jpg"), + ] +) +session.add(project) +session.commit() + + +# ───────────────────────────────────────────────────── +# 방법 3: FK 직접 지정 +# ───────────────────────────────────────────────────── +project = Project(store_name="카페") +session.add(project) +session.flush() # ID 생성 + +image = Image(project_id=project.id, filename="logo.png") +session.add(image) +session.commit() +``` + +### 8.2 조회 (Read) + +```python +# ───────────────────────────────────────────────────── +# 기본 조회 +# ───────────────────────────────────────────────────── +project = session.get(Project, 1) +print(project.images) # lazy 설정에 따라 로딩 + + +# ───────────────────────────────────────────────────── +# Eager Loading (명시적) +# ───────────────────────────────────────────────────── +from sqlalchemy.orm import selectinload, joinedload + +# selectinload - 1:N에 권장 +stmt = ( + select(Project) + .options(selectinload(Project.images)) + .where(Project.id == 1) +) +project = session.scalar(stmt) + +# joinedload - 1:1, N:1에 권장 +stmt = ( + select(Image) + .options(joinedload(Image.project)) + .where(Image.id == 1) +) +image = session.scalar(stmt) + +# 중첩 로딩 +stmt = ( + select(Project) + .options( + selectinload(Project.lyrics) + .selectinload(Lyric.songs) + ) +) + + +# ───────────────────────────────────────────────────── +# 필터링과 함께 +# ───────────────────────────────────────────────────── +# 특정 조건의 자식을 가진 부모 +stmt = ( + select(Project) + .join(Project.images) + .where(Image.filename.like("%.png")) + .distinct() +) + +# 자식 개수와 함께 +from sqlalchemy import func + +stmt = ( + select(Project, func.count(Image.id).label("image_count")) + .join(Project.images, isouter=True) + .group_by(Project.id) +) +``` + +### 8.3 수정 (Update) + +```python +# ───────────────────────────────────────────────────── +# 자식 추가 +# ───────────────────────────────────────────────────── +project = session.get(Project, 1) +project.images.append(Image(filename="new.png")) +session.commit() + + +# ───────────────────────────────────────────────────── +# 자식 수정 +# ───────────────────────────────────────────────────── +project = session.get(Project, 1) +project.images[0].filename = "updated.png" +session.commit() + + +# ───────────────────────────────────────────────────── +# 부모 변경 (relationship 사용) +# ───────────────────────────────────────────────────── +image = session.get(Image, 1) +new_project = session.get(Project, 2) +image.project = new_project # FK 자동 업데이트 +session.commit() + + +# ───────────────────────────────────────────────────── +# 부모 변경 (FK 직접 사용) +# ───────────────────────────────────────────────────── +image = session.get(Image, 1) +image.project_id = 2 +session.commit() +``` + +### 8.4 삭제 (Delete) + +```python +# ───────────────────────────────────────────────────── +# 부모 삭제 (cascade 동작) +# ───────────────────────────────────────────────────── +# cascade="all, delete-orphan" 설정 시 +project = session.get(Project, 1) +session.delete(project) +session.commit() +# → 모든 images도 삭제됨 + + +# ───────────────────────────────────────────────────── +# 자식만 삭제 +# ───────────────────────────────────────────────────── +image = session.get(Image, 1) +session.delete(image) +session.commit() + + +# ───────────────────────────────────────────────────── +# 부모에서 분리 (delete-orphan 시 삭제됨) +# ───────────────────────────────────────────────────── +project = session.get(Project, 1) +image = project.images[0] +project.images.remove(image) +session.commit() +# → delete-orphan이면 image도 DB에서 삭제 + + +# ───────────────────────────────────────────────────── +# 자식 전체 교체 +# ───────────────────────────────────────────────────── +project = session.get(Project, 1) +project.images = [Image(filename="new1.png"), Image(filename="new2.png")] +session.commit() +# → 기존 images는 orphan이 되어 삭제됨 (delete-orphan 시) +``` + +--- + +## 9. 실무 패턴 + +### 9.1 표준 모델 템플릿 + +```python +from datetime import datetime +from typing import List +from sqlalchemy import String, Text, ForeignKey, func +from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship + + +class Base(DeclarativeBase): + pass + + +class TimestampMixin: + """생성/수정 시간 공통 믹스인""" + created_at: Mapped[datetime] = mapped_column(default=func.now()) + updated_at: Mapped[datetime] = mapped_column( + default=func.now(), + onupdate=func.now() + ) + + +class Project(TimestampMixin, Base): + __tablename__ = "project" + + id: Mapped[int] = mapped_column(primary_key=True) + store_name: Mapped[str] = mapped_column(String(255)) + task_id: Mapped[str] = mapped_column(String(36), unique=True, index=True) + + # 1:N 관계들 + images: Mapped[List["Image"]] = relationship( + "Image", + back_populates="project", + cascade="all, delete-orphan", + lazy="selectin", + order_by="Image.created_at.desc()", + ) + + lyrics: Mapped[List["Lyric"]] = relationship( + "Lyric", + back_populates="project", + cascade="all, delete-orphan", + lazy="selectin", + ) + + def __repr__(self) -> str: + return f"" + + +class Image(TimestampMixin, Base): + __tablename__ = "image" + + id: Mapped[int] = mapped_column(primary_key=True) + project_id: Mapped[int] = mapped_column( + ForeignKey("project.id", ondelete="CASCADE"), + index=True, + ) + original_filename: Mapped[str] = mapped_column(String(255)) + stored_filename: Mapped[str] = mapped_column(String(255)) + url: Mapped[str] = mapped_column(Text) + + # N:1 관계 + project: Mapped["Project"] = relationship( + "Project", + back_populates="images", + ) + + def __repr__(self) -> str: + return f"" +``` + +### 9.2 서비스 레이어 패턴 + +```python +from sqlalchemy import select +from sqlalchemy.orm import Session, selectinload + + +class ProjectService: + def __init__(self, session: Session): + self.session = session + + def create_with_images( + self, + store_name: str, + task_id: str, + image_data: list[dict] + ) -> Project: + """프로젝트와 이미지를 함께 생성""" + project = Project( + store_name=store_name, + task_id=task_id, + images=[Image(**data) for data in image_data], + ) + self.session.add(project) + self.session.commit() + self.session.refresh(project) + return project + + def get_with_images(self, project_id: int) -> Project | None: + """프로젝트와 이미지를 함께 조회""" + stmt = ( + select(Project) + .options(selectinload(Project.images)) + .where(Project.id == project_id) + ) + return self.session.scalar(stmt) + + def get_by_task_id(self, task_id: str) -> Project | None: + """task_id로 조회""" + stmt = ( + select(Project) + .options(selectinload(Project.images)) + .where(Project.task_id == task_id) + ) + return self.session.scalar(stmt) + + def add_image(self, project_id: int, image: Image) -> Image: + """기존 프로젝트에 이미지 추가""" + project = self.session.get(Project, project_id) + if not project: + raise ValueError("Project not found") + + project.images.append(image) + self.session.commit() + self.session.refresh(image) + return image + + def delete(self, project_id: int) -> bool: + """프로젝트 삭제 (이미지도 cascade 삭제)""" + project = self.session.get(Project, project_id) + if not project: + return False + + self.session.delete(project) + self.session.commit() + return True +``` + +### 9.3 FastAPI 엔드포인트 패턴 + +```python +from fastapi import APIRouter, Depends, HTTPException +from sqlalchemy.orm import Session + +router = APIRouter(prefix="/projects", tags=["projects"]) + + +@router.post("/", response_model=ProjectResponse) +def create_project( + data: ProjectCreate, + session: Session = Depends(get_session), +): + service = ProjectService(session) + project = service.create_with_images( + store_name=data.store_name, + task_id=data.task_id, + image_data=[img.model_dump() for img in data.images], + ) + return project + + +@router.get("/{project_id}", response_model=ProjectWithImagesResponse) +def get_project( + project_id: int, + session: Session = Depends(get_session), +): + service = ProjectService(session) + project = service.get_with_images(project_id) + if not project: + raise HTTPException(status_code=404, detail="Project not found") + return project + + +@router.post("/{project_id}/images", response_model=ImageResponse) +def add_image( + project_id: int, + data: ImageCreate, + session: Session = Depends(get_session), +): + service = ProjectService(session) + image = Image(**data.model_dump()) + return service.add_image(project_id, image) +``` + +--- + +## 10. Quick Reference + +### 10.1 relationship 정의 체크리스트 + +```python +# ✅ 부모 (1 쪽) +children: Mapped[list["Child"]] = relationship( + "Child", # 1. 대상 클래스 + back_populates="parent", # 2. 반대편 속성명 + cascade="all, delete-orphan", # 3. 삭제 정책 + lazy="selectin", # 4. 로딩 전략 +) + +# ✅ 자식 (N 쪽) +parent_id: Mapped[int] = mapped_column(ForeignKey("parent.id")) # FK 필수! +parent: Mapped["Parent"] = relationship( + "Parent", # 1. 대상 클래스 + back_populates="children", # 2. 반대편 속성명 +) +``` + +### 10.2 관계별 빠른 참조 + +```python +# 1:1 +# 부모: uselist=False +# 자식 FK: unique=True + +# 1:N +# 부모: list["Child"] +# 자식: "Parent" + +# N:M +# secondary=association_table +# 또는 Association Object 패턴 +``` + +### 10.3 자주 쓰는 옵션 조합 + +```python +# 기본 1:N (부모 측) +cascade="all, delete-orphan", lazy="selectin" + +# 기본 N:1 (자식 측) +# 옵션 없이 back_populates만 + +# 1:1 (부모 측) +uselist=False, cascade="all, delete-orphan" + +# 읽기 전용 관계 +viewonly=True + +# 복수 FK +foreign_keys=[column] +``` + +### 10.4 흔한 실수 + +```python +# ❌ 잘못된 예 +class Parent(Base): + children = relationship("Child") # Mapped 타입 힌트 없음 + +class Child(Base): + parent_id = Column(Integer) # ForeignKey 없음 + parent = relationship("Parent", back_populates="childs") # 오타 + + +# ✅ 올바른 예 +class Parent(Base): + children: Mapped[list["Child"]] = relationship("Child", back_populates="parent") + +class Child(Base): + parent_id: Mapped[int] = mapped_column(ForeignKey("parent.id")) + parent: Mapped["Parent"] = relationship("Parent", back_populates="children") +``` + +--- + +## 부록: 참고 자료 + +- [SQLAlchemy 2.0 공식 문서](https://docs.sqlalchemy.org/en/20/) +- [SQLAlchemy Relationship Configuration](https://docs.sqlalchemy.org/en/20/orm/relationships.html) +- [SQLAlchemy Basic Relationship Patterns](https://docs.sqlalchemy.org/en/20/orm/basic_relationships.html) diff --git a/docs/sample/models.py b/docs/sample/models.py index 1cdebf0..d0e6038 100644 --- a/docs/sample/models.py +++ b/docs/sample/models.py @@ -1,158 +1,158 @@ -from app.core.database import Base -from sqlalchemy import ( - Boolean, - DateTime, - Enum, - ForeignKey, - Index, - Integer, - PrimaryKeyConstraint, - String, - func, -) -from sqlalchemy.orm import Mapped, mapped_column, relationship -from starlette.authentication import BaseUser - - -class User(Base, BaseUser): - __tablename__ = "users" - - id: Mapped[int] = mapped_column( - Integer, primary_key=True, nullable=False, autoincrement=True - ) - username: Mapped[str] = mapped_column( - String(255), unique=True, nullable=False, index=True - ) - email: Mapped[str] = mapped_column( - String(255), unique=True, nullable=False, index=True - ) - hashed_password: Mapped[str] = mapped_column(String(60), nullable=False) - # age_level 컬럼을 Enum으로 정의 - age_level_choices = ["10", "20", "30", "40", "50", "60", "70", "80"] - age_level: Mapped[str] = mapped_column( - Enum(*age_level_choices, name="age_level_enum"), - nullable=False, - default="10", - ) - is_active: Mapped[bool] = mapped_column(Boolean, default=True) - created_at: Mapped[DateTime] = mapped_column(DateTime, server_default=func.now()) - - # One-to-many relationship with Post (DynamicMapped + lazy="dynamic") - posts_user: Mapped[list["Post"]] = relationship("Post", back_populates="user_posts") - - # # Many-to-many relationship with Group - # user_groups: DynamicMapped["UserGroupAssociation"] = relationship( - # "UserGroupAssociation", back_populates="user", lazy="dynamic" - # ) - # n:m 관계 (Group) – 최적의 lazy 옵션: selectin - group_user: Mapped[list["Group"]] = relationship( - "Group", - secondary="user_group_association", - back_populates="user_group", - lazy="selectin", - ) - - def __repr__(self) -> str: - return f"id={self.id}, username={self.username}" - - @property - def is_authenticated(self) -> bool: - return self.is_active - - @property - def display_name(self) -> str: - return self.username - - @property - def identity(self) -> str: - return self.username - - -# 1:N Relationship - Posts -class Post(Base): - __tablename__ = "posts" - - id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) - user_id: Mapped[int] = mapped_column( - Integer, ForeignKey("users.id", ondelete="CASCADE"), nullable=False - ) - title: Mapped[str] = mapped_column(String(255), nullable=False) - content: Mapped[str] = mapped_column(String(10000), nullable=False) - is_published: Mapped[bool] = mapped_column(Boolean, default=False) - created_at: Mapped[DateTime] = mapped_column(DateTime, server_default=func.now()) - updated_at: Mapped[DateTime] = mapped_column( - DateTime, server_default=func.now(), onupdate=func.now() - ) - # tags: Mapped[dict] = mapped_column(MutableDict.as_mutable(JSONB), default=[]) // sqlite 지원 안함 - view_count: Mapped[int] = mapped_column(Integer, default=0) - - # Many-to-one relationship with User (using dynamic loading) - user_posts: Mapped["User"] = relationship("User", back_populates="posts_user") - - def __repr__(self) -> str: - return f"Post(id={self.id}, user_id={self.user_id}, title={self.title})" - - __table_args__ = ( - Index("idx_posts_user_id", "user_id"), - Index("idx_posts_created_at", "created_at"), - Index( - "idx_posts_user_id_created_at", "user_id", "created_at" - ), # Composite index - ) - - -# N:M Relationship - Users and Groups -# Association table for many-to-many relationship -# N:M Association Table (중간 테이블) -class UserGroupAssociation(Base): - __tablename__ = "user_group_association" - - user_id: Mapped[int] = mapped_column( - Integer, ForeignKey("users.id", ondelete="CASCADE"), primary_key=True - ) - group_id: Mapped[int] = mapped_column( - Integer, ForeignKey("groups.id", ondelete="CASCADE"), primary_key=True - ) - - # # 관계 정의 - # user: Mapped["User"] = relationship("User", back_populates="user_groups") - # group: Mapped["Group"] = relationship("Group", back_populates="group_users") - # # 복합 기본 키 설정 - - # 기본 키 설정을 위한 __table_args__ 추가 - __table_args__ = (PrimaryKeyConstraint("user_id", "group_id"),) - - def __repr__(self) -> str: - return f"UserGroupAssociation(user_id={self.user_id}, group_id={self.group_id})" - - -# Group 테이블 -class Group(Base): - __tablename__ = "groups" - - id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) - name: Mapped[str] = mapped_column(String(255), nullable=False, unique=True) - description: Mapped[str] = mapped_column(String(1000)) - is_public: Mapped[bool] = mapped_column(Boolean, default=True) - created_at: Mapped[DateTime] = mapped_column(DateTime, server_default=func.now()) - updated_at: Mapped[DateTime] = mapped_column( - DateTime, server_default=func.now(), onupdate=func.now() - ) - - user_group: Mapped[list["User"]] = relationship( - "User", - secondary="user_group_association", - back_populates="group_user", - lazy="selectin", - ) - - # Group을 만든 사용자와 관계 (일반적인 1:N 관계) - def __repr__(self) -> str: - return f"Group(id={self.id}, name={self.name})" - - __table_args__ = ( - Index("idx_groups_name", "name"), - Index("idx_groups_is_public", "is_public"), - Index("idx_groups_created_at", "created_at"), - Index("idx_groups_composite", "is_public", "created_at"), - ) +from app.core.database import Base +from sqlalchemy import ( + Boolean, + DateTime, + Enum, + ForeignKey, + Index, + Integer, + PrimaryKeyConstraint, + String, + func, +) +from sqlalchemy.orm import Mapped, mapped_column, relationship +from starlette.authentication import BaseUser + + +class User(Base, BaseUser): + __tablename__ = "users" + + id: Mapped[int] = mapped_column( + Integer, primary_key=True, nullable=False, autoincrement=True + ) + username: Mapped[str] = mapped_column( + String(255), unique=True, nullable=False, index=True + ) + email: Mapped[str] = mapped_column( + String(255), unique=True, nullable=False, index=True + ) + hashed_password: Mapped[str] = mapped_column(String(60), nullable=False) + # age_level 컬럼을 Enum으로 정의 + age_level_choices = ["10", "20", "30", "40", "50", "60", "70", "80"] + age_level: Mapped[str] = mapped_column( + Enum(*age_level_choices, name="age_level_enum"), + nullable=False, + default="10", + ) + is_active: Mapped[bool] = mapped_column(Boolean, default=True) + created_at: Mapped[DateTime] = mapped_column(DateTime, server_default=func.now()) + + # One-to-many relationship with Post (DynamicMapped + lazy="dynamic") + posts_user: Mapped[list["Post"]] = relationship("Post", back_populates="user_posts") + + # # Many-to-many relationship with Group + # user_groups: DynamicMapped["UserGroupAssociation"] = relationship( + # "UserGroupAssociation", back_populates="user", lazy="dynamic" + # ) + # n:m 관계 (Group) – 최적의 lazy 옵션: selectin + group_user: Mapped[list["Group"]] = relationship( + "Group", + secondary="user_group_association", + back_populates="user_group", + lazy="selectin", + ) + + def __repr__(self) -> str: + return f"id={self.id}, username={self.username}" + + @property + def is_authenticated(self) -> bool: + return self.is_active + + @property + def display_name(self) -> str: + return self.username + + @property + def identity(self) -> str: + return self.username + + +# 1:N Relationship - Posts +class Post(Base): + __tablename__ = "posts" + + id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) + user_id: Mapped[int] = mapped_column( + Integer, ForeignKey("users.id", ondelete="CASCADE"), nullable=False + ) + title: Mapped[str] = mapped_column(String(255), nullable=False) + content: Mapped[str] = mapped_column(String(10000), nullable=False) + is_published: Mapped[bool] = mapped_column(Boolean, default=False) + created_at: Mapped[DateTime] = mapped_column(DateTime, server_default=func.now()) + updated_at: Mapped[DateTime] = mapped_column( + DateTime, server_default=func.now(), onupdate=func.now() + ) + # tags: Mapped[dict] = mapped_column(MutableDict.as_mutable(JSONB), default=[]) // sqlite 지원 안함 + view_count: Mapped[int] = mapped_column(Integer, default=0) + + # Many-to-one relationship with User (using dynamic loading) + user_posts: Mapped["User"] = relationship("User", back_populates="posts_user") + + def __repr__(self) -> str: + return f"Post(id={self.id}, user_id={self.user_id}, title={self.title})" + + __table_args__ = ( + Index("idx_posts_user_id", "user_id"), + Index("idx_posts_created_at", "created_at"), + Index( + "idx_posts_user_id_created_at", "user_id", "created_at" + ), # Composite index + ) + + +# N:M Relationship - Users and Groups +# Association table for many-to-many relationship +# N:M Association Table (중간 테이블) +class UserGroupAssociation(Base): + __tablename__ = "user_group_association" + + user_id: Mapped[int] = mapped_column( + Integer, ForeignKey("users.id", ondelete="CASCADE"), primary_key=True + ) + group_id: Mapped[int] = mapped_column( + Integer, ForeignKey("groups.id", ondelete="CASCADE"), primary_key=True + ) + + # # 관계 정의 + # user: Mapped["User"] = relationship("User", back_populates="user_groups") + # group: Mapped["Group"] = relationship("Group", back_populates="group_users") + # # 복합 기본 키 설정 + + # 기본 키 설정을 위한 __table_args__ 추가 + __table_args__ = (PrimaryKeyConstraint("user_id", "group_id"),) + + def __repr__(self) -> str: + return f"UserGroupAssociation(user_id={self.user_id}, group_id={self.group_id})" + + +# Group 테이블 +class Group(Base): + __tablename__ = "groups" + + id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) + name: Mapped[str] = mapped_column(String(255), nullable=False, unique=True) + description: Mapped[str] = mapped_column(String(1000)) + is_public: Mapped[bool] = mapped_column(Boolean, default=True) + created_at: Mapped[DateTime] = mapped_column(DateTime, server_default=func.now()) + updated_at: Mapped[DateTime] = mapped_column( + DateTime, server_default=func.now(), onupdate=func.now() + ) + + user_group: Mapped[list["User"]] = relationship( + "User", + secondary="user_group_association", + back_populates="group_user", + lazy="selectin", + ) + + # Group을 만든 사용자와 관계 (일반적인 1:N 관계) + def __repr__(self) -> str: + return f"Group(id={self.id}, name={self.name})" + + __table_args__ = ( + Index("idx_groups_name", "name"), + Index("idx_groups_is_public", "is_public"), + Index("idx_groups_created_at", "created_at"), + Index("idx_groups_composite", "is_public", "created_at"), + ) diff --git a/image/2025-12-26/0694e0e7-0f71-7671-8000-0ecf2ee67bac/darak-1_000.jpg b/image/2025-12-26/0694e0e7-0f71-7671-8000-0ecf2ee67bac/darak-1_000.jpg new file mode 100644 index 0000000000000000000000000000000000000000..05462d6f14cc6cf89c60a81f5dfc22b83e0034ec GIT binary patch literal 195312 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%0DF1Y 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 z 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 TI{RN~)q4-P{`!!=j935JmEGzb literal 0 HcmV?d00001 diff --git a/image/2025-12-26/0694e0e7-0f71-7671-8000-0ecf2ee67bac/darak-2_001.jpg b/image/2025-12-26/0694e0e7-0f71-7671-8000-0ecf2ee67bac/darak-2_001.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7ba93ea22b944f2f57d6dcd323af6d9daa0822f9 GIT binary patch literal 96737 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%0DZa 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 U&3Ugi^?hDz&3Ugi^?hIe*=mOZhX4Qo literal 0 HcmV?d00001 diff --git a/image/2025-12-26/0694e1d2-9814-79dc-8000-23a0cfce1183/darak-1_000.jpg b/image/2025-12-26/0694e1d2-9814-79dc-8000-23a0cfce1183/darak-1_000.jpg new file mode 100644 index 0000000000000000000000000000000000000000..05462d6f14cc6cf89c60a81f5dfc22b83e0034ec GIT binary patch literal 195312 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%0DF1Y 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 z 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 TI{RN~)q4-P{`!!=j935JmEGzb literal 0 HcmV?d00001 diff --git a/image/2025-12-26/0694e1d2-9814-79dc-8000-23a0cfce1183/darak-2_001.jpg b/image/2025-12-26/0694e1d2-9814-79dc-8000-23a0cfce1183/darak-2_001.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7ba93ea22b944f2f57d6dcd323af6d9daa0822f9 GIT binary patch literal 96737 zcmbq)19L82(Cri3c21HL+qQXPJ2|m!+qQj@C$??dwv#vJ&G%K^`v>mYGgVWytGf5} z%yg~pz20Q+Bn{{Z5D00jjJ2?YfQ4f8YLP~hO< zehw5QR3yZo6AuFo4Fit|7YCP!oP>m&k&cm{U*&&{fc$?O=>?!bgR+2LgMp9$Kv6)z zP(Z#10R#X5021tHq5lt{VBiptPyi5Un4f7SWB@1#7$`Ux1Ozw~Bse%I90({F02~G4 z7bGf^5EPmsI*Fk}0CPe?T^}?CsW6L@kz-)u9GOUAeg7UNtMM(CveVsf(V!%9Hj|=; zdDY^9ADj3;fq?+|p9uY5fC51N*D3VRtPlzS1pI$of`dUq{9Hi%L=hAW1swGk6NC_& zqM-vMNk9TRvoHp!(vMRX5hKSrD6+sk%-^iaqQ*{%_226N_@Da$MFB$r2mt;IQIIRw z>;tkgmpX=7La~1XsB0S@)Y;>v_iG8t^Cf`LD9^K3DkXqbN~2(YiV~~@VLZ38CKhvW zb87=vAm$XnuF3F1I*`t}(RY@$p6f71P|4v;ic;`K6yX>By@H|+Y0lFNE^q8t;~=7E zCO=PxF)0-3>|%^xCKfM+a`vZ{CSkIY?%)YLm(=5#1hZpwG_t3nMhRNTI?8kVa%8of zh38y|D|y0iW*T%eNRXID~c@QBcx zJ~T+3gYoj_!(*Gn3Fn25R9g0pZ73t7z46@2F+0-6k4>MHdDQOs5>*gz|2yh*8B+U5!SZOP42~-%zhwe@Xp9ExE6!2OCfo zl(j}qG{>FPeg(oiD2gv55mUispEycA3le{r3);+w{?ph6Rp?KVFm!(%L?yaScwO8q zk4opVCp;p<0n82`JX8ir-}1z{P#Uzdr!LPa;7Z|5*mqP$2Zg`J?pOJMJ^fv>D>+(Z z+mHn4B!Dwe38+y?2DO!-m4p*bW6>G!iGy>!K38AWeWtyzZ$LgPFJ6zHqmRJmjiNCl zcBkLb`1sY}IN*jM=CKZRWKO?t)H-e+1fylP{2A#sx2EP!`t~Zbpv$5(oHiEuFMjHn zz*hCitjN zp)c#t$1QPW{X1xA+@S~4;GO8 zZRI-i+mc|D$&(`#j)IN$?jtDYe^F)Syc|X)hgI5!eW>2VX@`(2B$LUTz*?_kzby&@bZ$OL#wLpX3 z86BD=`}0!3#cJ%5`0e4>OohhSr*`=_0CPyM)33S(=2Sup#iP=~2_ylekMbI&?yhgW z(I}?I_|X=6d&x#&ktW_%O)d=4!eIdWezNKx2s69Xh?Bys#nYXE1S-RrV0j*#1AEqB zyKZw?>GbbN)s01zB@I{7`Ld_$q5z@oK*N*|LJmqFn2X`Y@jPNR16r? z@($IT3Z=ZuBt3;y^U+i{X1N8)#l37>GK1!U!l(iA!rw2V8z%&~T@ps0B@Mj1FA6!a zB20Lt2DKm-LiKGtF4J@G5#5Bo0gP`e%?R>XPkK%be(kX@fv7wkZjR_q>{6Uyc3MFe zn?j`#Vha?MR37~R{<#9@>0EL%5~p>4!Rrh6!p*-Agc#vxh+K^=OZC;G=2Z4mViz? zi~#ki5A{9Ih2#+wmttOdwda9`rpuL)gFmK*x&Wl&a*Z!$qXw&$gv1GIAKsyJpVm>k z11=e0XUc5L)uZ(A?@nP@y&thbWPn37@#%`F3xvFH6F*OoB0Y`j=bW=c3&o+8Txs~T zWmyhptk975x{gM1;anOGl7V_QaDSgi^Pz&>wS9%bkkFU&% z=?BN`BtX99dViQo@9f#+`|Ra({2R@SE(udEn<8|lq=0NSTG=gmNUzxfFv6h9X*T5IB2!W) z4G_q3TSAuNO7LII`y5&zyvJs8Jhg1ANz*UIu>eG4~`L+;RhKExiQ=V2jeUS&g;s^-rRH_GH0HMtu$uMZWG}aI1 zWW42%G_Bgl`Xg4~Hp@zRhQquqgbXXS`K`qmz#DJHs7Y zcUW)Ih|dJRvYza%R6Km>?=RApN23U2#J|0x#DCkBrS~U%^z|01esTeP8ZOUHF#_SX zN+Jl3>*Xq5jgggVapyTgfx3|BLi0z(7#Ay{wHq)g5(M2KSZD|?{kS%1$4Q8yE`RQi zLIqO#i6;!13lOb!%9!y=a#mQUS$lh|u-IDdKd~mxUo?#}_{$)fglhy}sebaZ0;V@#m_D)WIwT~^7kT9JbO zN%inbu28IP&u>cVc(dTmzuigb8Eg6Ph)hOy|E20}njMIW{PJFI*xh(=a@Hd8Qf_EG8=DNnI_5A17NNcu z>4M=wmO;`WAWfGj8G-ss`3}SX`9(Rn1$ydK@Y1~7a@%5oG=L-|JCh7eWRx`?MY4s0 zOsTy3cZ_|N;6w3i)vIEd68ag!`AMo!%v;Ralmqd2yleR^XD>-ytVG;pBEQPpCrTq| z9&}$HMit1S5@n5lZ?caVS6K>ms2YMe6@PqE!h+|lKn}hN!=^dJPhyew6KxDO&{@vq zH;ip7QZcq&G*?`mz0P5oG6kc8@YQ%MrRfkc7XoL_4Vy0|1C_&k8ly%QBz|HYDt?v~ zD<$9%YhNt*&zQ1uQlis`U)8`qF3j~qs7lDx$=3)`-UHdpaJ7l`j9IL7c@&NsCU|6!zUo}r-t&<2K{r#UVe|VTrI3M)Ctf3CU zb%Ls*&!zQmz+ka@`h#A_VmX+?Q!v52@O8_IMf-i!~U+ zl&(9jLjC!kYk9g4Xp%HgQkSF9MUP@HhLXr``C&teN5%yg?H>Ga$?2c_#-4Aw0)G$u zq(CZkaeCgrY60AQEd@*x|BR|-DUX43nA~agssueLz;pyE8{9!+)&!Z#LH5G%e8rx;O`IAVXV>Q ze-&Ii@c@8jl@TpCm|=^)Y7Gs1H6n(IZNMP6X5D9jCLyL1dy(~B83U6Y7Z*Cn4tcwy zHfKp2p^6DcEay6NX9+GF^hE3`Nd=)mS3}#~Ovt0Q6vja&0<&yvL1CML(2GB$RjHkg zpX*&N(AsZnTdL=IhT}r>RgT3Rb~*r$)WvaVVAIF^%`d#YO1?yfRiWqUKv_&wf|$Zv zWne@jn2-|d4^&>+dfUj7z*)JsObWmaW5sznwRbtU&#BGX6tDShoW) z(GqbMI+zEZ&uaLS3*Ufny^{5pxW3F4l7T7@+SO-4wGYLJ%Fqe%rnnH>ru3!@Wpsze z0PXDm!k>QyndGG+xOZUIIRevSvA*v8N~EEPE^-kCfgF9GIGLi@ z!<9Zt7`#4KY*+lWOJB<&r<>V+{m)p4PgQfmp5^eW8rB|g1_!f*DZ~6!_D9PV!|kbM zrMp59 zU{SqtUXLz5rKYw<*3=i}EHyY8AWM=WK=uLFv(|2pn{0tN4e^1D*vNh)=2ylF`#icn zO$glU2RUR7sa#6Tz1-pj?Jj+zB>889OkhnzZ{Fa8Umj)X`|be{E^vq60MvN?N49mb z9C+h<&MTQLU)pMyFu0}_w|2d(!A=6ZYLcd|m5$@}o;EUDyp$2D%^G{JNPh>&KsFiL z$;6h_q7=u?RwCFEo0k>EFn+x{=0K)UK|f-u<()wUTTF63OGeN4@r#$rC4(0>EUXTv z+G;+OFG9;Mx_0?ZE6cg_w?%45c=k)E3NYhm)r)};zuT{56#zmq6oEjzDsC>rT``J( zdoWu0C3!s2OGFu-K5lEDa7F00AU6Xqt;5%EHU%_TcsEHu6vOLU)&v(ku7~%Z822IkJb%e(4HVwZsSPR*12CXepF^|5vdhYnm$a6^n z@8v$8_{CpYU$+_@9^5 zEHRwN96m`e(FcE;l;YfCtqS^3809y zw0V#vXp`b#7ngrY6I~b=T+$ds@I4Yp;(5BV;Xrvoz?hdX&c5U+&6`AW(*M?w0U^^l zq$!_aBrSaQ>bcRRjgy_@_A3gvcYpi(b_R={e{8{PfiF1$26V@bcU6a#}$v|>q%=aa45T?lD zIaRlp8!tJieYOK#ftizkfnk*Wkd$PzcbQ<`jla60)&($kB4l^T6zOD$AiQ4p53VA_C4HD$E+Wg3?CkY-B0ibq^YM}J>dFmV(? zl58%zIcqN^S56Anssr?#Ax?HB$g~KZDnvQMzM>Ab49QLP-0k-op`zoY^kL{Jio|se zaOS|)Q!#olt|>z$3HfB>DJBCql0{n|$Zfd=rj`K*xtOwZcDpG;4X`DoGi6z0{ygeo z-E%{luyWO$Fth+-#fLw0|GHsy`s=-ip@Dcl>=*8)OiW*DXG&gC*tSS_$n0LvrP?vz z$g<4HK8TN`CKeB>JJC;1itKB$1eke$a(A=)Bxp&_b1Cd}( zON7-qFT^A8-HHe9iiD=PFtbVF>V%O>AK>VOZxq@i_qWES&_eYNNEiPkgF;Z`GFK@W zD|TZaT3BU5^9DwvA_S?l$A$7bE&Od{vYZ8Gk49O)w~04>Th8X~g;JXW}MU*PMpAV|srXhH$%*eUYc@p`g6;cs^Evks8pH zL_>!FYJZ*j@FS8y`97(X$sK&L%wLr@)h^l66{Ngw8TFgiMIXY)RCM3y?-R%-dHmCx z_IosQ`-VX9`i`ka#g9%fOF z;Th0JW@7|e4B&Q#uMWJ^M&=zGKpiLp1)e z@iJd}dvJbihbCZY4&A`Ij19t6RRgj<@qO!WK|ID8`A{IzI?ccq>`2H9O$_TV8m;r? zZPhWelY!Af^A4NqR2|PqDCs#;hOo$YI?8Zob{;|{KX|rEddB5eKlx=9FC{&}IvoSh zfpohT@ec&o5kl>fnh4y&>U|OTpbtf$Q(7$Mx&(qyFL!gCm6b8cmh5UEThx~MK?2MX zSbJu|MJ~(fTXl<_A4bXG%zO8o34I@!WH?yDQ!_=0dPu0$^oEnUW6AAZQNr+}2H2Xa zexr(>I_~K+*ynL_<(HKHr)75#IjiB8m?W>k{__5ox@b;S>XKokiVl}!Z+%jt;8|vz zb}bW9JjTL4E;zlfx|O-3CJ6Q60Z>1)pT4ATfyOyW-mk)Z^dEd6KxO-}i?tTWz1K!lRGNIXWkfLz7!{Pgg#5Kf1AlrtSs zM_$B~6RHVQ@LGO5xlyFz!CPpr0jAdRkd&c~8#5?aBHh?rlF_rr44(SG_Ubcu$Fg9P5r$VF|2`+>X}% zjU0_o{L{QX18<>2YZMV)9%($1v6d&0>9#^N=2Buy)WFSN*)FALx%p4^L#rs_11aHZ z5h`UTE>#EVe6WR3XtQ!NwcxGt88HduW9}{26d@@=h+%X>6Q{jgaqieoC>{AyYnW_3 z{7dHfZ=0F5nXVVu)2Iss!ukDingmnuw23L}L`)_1Itpx@E7hGKZlR9-HhSrk)ra>C z6+fG_afO%Mc4fWWeOtEX`Y`3DI0g0uffNTckHnk$0wn+}BpiIs6NVoqbO~-T>qaGP z@yzX(NT%x42&{y~xUG$GEV~hW1Ph^Vlu00DFRYCX=tO*nkPo2W!!RWxEw7CDIf7yV zsI|$_mpK#?KG)O{;DrlU1fu>s`WLt*46)-$_O8i(_JRn9+Fc`udXfzM=A5i38pJPY zWHn}xQJeP#xzOXzP-XvX^mw`0@B%XpCCznw-obZh7O}Whak^I*)*$|OxI~Rag zxR;{FwD(f1^ziip>RePo*^A^bLzgPMd#!QX77aZvVq3SW|LP;e%FXyssgd(i9|GmU z!qS-j8Tu1f#j-!*Ewz>3R@G~-8S!Xp;mP$+V5%8x8{EIv1>~eZqpMZ)bD(Z(Y)IJt z4cw+A)$FX_wF#V<2-#>gqNM-3J+0hAgmVRuo<97<;<}g>Dcs6p_b5!8P=hcr0#MB6 zb|{N#T@`xdJzUC8dPC?SX~U%#Cr>W`$vvF_EX7I z4dSa0y0$VpKrH%E>H3i>L3fHBq$j=Ts5=h2T4bNxkpB}|09yZzHkqb5p%g&Ea%KI* zSi*`TBol?AZ>~44_R#(^l&3mi2tW6Ez4}WSV+ZmPkDEVjC6<>@aZ>@Qv$g%F1D6DX z6~d1Q`z2TZV>_yN^Bdqh$MIhG)B4y?>G%d5yWV8(D+5P9{qT)nRE+UbD^*Sr5K?|wosjdA^b1gh#0^K z=m*+6o~!4ZO|hCU-3WgJq+S%^Tfkm5pM>oX1S)o1PDKTp>8iI~QpR&XmMi1>&aQW! z`uEPD?u=9)j{^n$AlZ&jmv7QY(}_yJt=zE5{-JtaDMj~sMD&QE)oOcjhMax2Tv_!o z8&A5cByCE!eglFRHi?=j!WIrV*bjOhhWw5d^^}_HW}bG1%^|%McFP$Ve759xM(Vl?KZ%1p9f=~yFCT0k5>C;;M?#+ z{|deVU__(1cY=Bry_Y7s?`RSOJ{CCSJQ?wCp~MScq{vV1!VaeR7*~hhR{irtZmKOr z+rRyIl@9my2)!YeXvg@VvWp&T&1Ts z&xPpGTD`(r6|=1~S3$cfW8cOV)2|J^zX7U!9~FWwhIK?Dddvg+Wq9I3p9gmI0zlNS z^a_Zym`*pFmJIV%f~c~?B}(jK8;;Fij3!8PeySG}6(**~)RM%E=Pa9MUB4Cxl`ZQg zrBX4OB&EiTy09PKMLh49SDs=ICX~u1oNi@W6km>u*#(-2(6kh2fflZWMy29t5pa&t zNR3?~ct+uo)|ZrU%WxAD^Ew#`>v zL-kyi{Nc$&qW?4xAPvlJibX#LEo3oA{Y4JL%(2!?dLh+zV}o2gml$TvIQoX7 zY>k+ktSyRd7%EhBhvcI8V$H7EQW%71CDZ8vPnz@wtQDXZVr9|pp)D7DJm-H)-!gxy zPgLGC-twD|&(gm5BY4!RaNeSoQB#XS#iX~fTHaru8yc2#mmsgSzB)eW^;GZ4`0Se; z@o>?amLceJsqV=rq>4W^&Om0(c^t#Apr2YjLKD_;akPE~|h*tcgJA zLP1xRKSkFV$Ag|77Ar7(jq?(`WY~u>k<57k1k{rYye3Hviiz+4epguIp zy9-8mf0gC!Utm@_%ww{A13np-hC~~;AA;KiCb#c)PQ;77qx>0J1esh2rpFZ{CFs@k zV-IBRSY+oV5U{$IoZrI+b-FbZVbphy7^36HThYrxuJaFW)>jIa zwbdJy5zyky8|ZZ*zL^w^?D|5<5o)d(4u)+jp1}{Efox7HlVOv-%6;XhUnF-uigR|C zjUZ)WxL$07eQl)BfE1Mj+n&FbRuTxW11F3Gt99U? zmJRMO?ftMeSIRD^LuXsiDQxK4ttiy!qLG5DJH@uUQQ_01Ig zlj{QygWt#rODv}BdDyALTb zW&~yF7ZyQx3z8mJP`)(}vzt71KE>NeQ#DXF^|T+-ZAsZsY(AgoxsIyvByL$16+t)i z4MD0p8TZD3?Yd-8YV+yiZz}c7qX0z5OvE}w%#M_az@)7EO=vUf+ z6(&yX(aK(Qq*k^BWgnSR$-Zn%FL{=Nk{K#z;T^ZttFiAm6GbRPTkI7-es84c7w$PV z5^WvR)eXvPWNr;=!Izdwwge1bq~D;6xEsZ3w#a-)d0xHxw!Lk9SrUcZN;n6QO}5LK$04Z>oj;uRYtZ`Ja*9rb{Mg8YDE z47Z2a1eOR6v#~|syFRizIpAaV9P?Qj_uBD72+nA=jwv7(&Brh(IjN9oPF67VLIL-t8#m;2gGzb|qkMry(di3#cz?VLya3|*D8*n6i6Jp$xL>5N_d)>M>O_s<@UXRp?C`%0q$vzFk#b=&w zUBi03NZ-T>jK)l0O_(kZ*rcSD>IFw;=WmiP&9lJdjkq@Ci&jUa=Rc4xlM_E)*EU;r zArIAk4vKAJ|F`C8oG#@vd&mk+bkO6hU}**QkJMwdU$ICubiR7IjQFTk*D z3FZD_Zth`catrQ0HDb9MDbFv*rFLq)ZfI=6UkSOhNP#z{=WT~m<|AFQN4uY{?|%w?gPlG=u0;T8vgUjTIP&NhHt=I3J#?YjhG{ofR7)C&u57;mqL}V$G(8`{)d@`&6aixd;Q^U=;CHYgxrlwFN~IpKER+%_6UZgKpf(@ z&rQj0td%&Y(FvL_L4tq^l`u(4Z4|dqr{pUq=W8xqgf&{QphEwRT_kD-v`QlK;m^;E zoYip#MzX|5PXF=zbH0U2;V@sz8^lR*Q-DDd6x&}6Wve3JJ!<5!QdIjk*S+Q}u-$|b zh+rGkj+jW%_U?TY?buuCRI!8RW^U|BWx^8- zQB#3$jH{OelY2)WOJX2-aA`}q;k_xV3PH$^lqkV%TKbdk36nt!bLT=Mr6QxRX+RNs zVFl7`Q>x6YmCx7sK-P$J*SXT*3%ZRm^re}Y%ykd=BY!?&wYu0cfioe-Pzu)d@a^$H z9rMHOWZYx8e54F~r^9Ae8VJ;;T%&D465!@QW~R+R_(TAE-(%+ z)pc1kmu!*t+cz)L6N8AD3cb^{mYuq!M@G}*?Yox8uNs9SE{aFWkx|L6#|#95L4ZG% zw&kQB){(~p2g=&ZY4Vrj!6ycXr7y*xzVkIoKQJs*Tgi-!OW!g?2z<~!@FRN75Z60$5+w6N& zdW?32Re&{YekdabQEp<<03{a5#Gv^gYJdTJfJK*cr}B0x>1}{S9cc z*Uh*;iRqvLds*>0y{`;`XC^?u*<|Adwys;Aje9!@mao9PL=AXu$06+N2`6yhw~zKR zQW#a0Rr{f+u3)|>mhNb5>e>h2ZLn;CUk+tki3C?1z^e$)XK=l_F@+l(XeGj)I1FN#R%V#5PZy z&)@VY+upd{>em&$<3$r3B7@Ly!gm(n{z)rSW;g^MZk5I(Kuv=lOvW-^w|3peZUK ze|@`HG=!x*EQ15*(4REs`o0+EH-EMmUwSMcR%cBjH8M?`QvSwhUwru};{yh)BhB`S4ey{7kN@-^Pf1XH8IFT|15!&naRe|dCRw)$ zL+8a?kBK+&(WhS^G9)G{*!pFnUd;IU#CAFzdYGi zzz^Qol0Zogi4hmRZvc0Yp5X0X_>jv}TmOe)CGDIQ$1*X71-tx#Z6lPvWotfF`jIz$!cB-C_RNvd4lPo?phCl*I--MG*q_^=^Gds;}a@K_&O6D9&YAjZb7jY{f5dHTBJuI0r zIQNEhEQZyFnmfR3Ptfs^r7ja^rq=t}shKl$p>VjcmIXUMjyp*rG zSF|ykV85>LqMbEavw-p)zt}1AlpOFpgz$Jai+H8Xp*V;fnpE>S$ur$y({kwLHcbid z??KLwLOsXeGSq;qyL|)L1i#{9uK}=XE)@aWD+&}S60rk&5;e#JId?jfnbW03TWx;b zF}i+gB6;Ry-h$;wB2jf}+AF%77zu5pIZ;C~#b-pE587mQws$BGC$Bp*;TT%`w z(QlW2%Y|;jJ>&c6R~K_vHoDaG4=e97IIjVsow%%9hQV>yktYemEBSuHVMM4@(sx6> z-+=p37W5Sp~ZIVEKJ5vj1Y>jP5u*_Y5tpsVl;P);@W3h0)>h{ ze$-J6ME%^a1813}?#&bA{A9 z=BEjxtlziq+EG=;c2}^qJ$Jy0Gbf@Qx#vzZv}m%s+zs3YL^~aNKvVZa#mquGnuZR( zm$+J~o3-1XuQp;0)0IXN?tsLJWLs63&W%QN1<}Ed}AZ1n~F!< z8M}f;`%;`T$SyltX&xo4d_#Npp%8atPf5gbpb6b(ipeq_xk%1daD+ix^6CA!Ntt1o$5V@3U2=^$R#Xg% zI)O9gBINC)Fj~-4#OIHl;tx-4PSTTUpKLxzq2| zlLJ|GZllBa&X`4v4bO}Qk4R0HT`9sxLy4g1+#PO|*SQt@BTQ?9law#t#;A<6f=YOM z``U7@VDvK2)%7S;u$3-&A}uytWG-tp6Mu8AzI>MZ5A(jSh(2lKjHGTcNq5I-IT5vH z(~ytGcos%Hcw3Iw`EK03AA#@kx!Q^BK@uJ)50O^O!@CCEfyRND3PA`qc|Y}uv$eg! z!xa83S|B8o^c-M2TIJGmf`?MSO*DVgyQ2SBLhPb&zWzgr;-xDFv7&vlus1{JZau-(vIS8|8Yniu9GY5?tp)2IA7Pcv?ga&=|qpN$R$UB#`3hi!q}n))|t&(k?3- zc594KQ&D{5SH7vgk>A?t;axs1HaU17eFDY@Y4JByp*|WP|3=Xyy3ymsSCwS%iKl>1 z-pUT!BBk&JE{`nU`dO)%C*<7Ht2Y+&{)^dB7KLMT(6waU{^Xx7` z@u&A6YaFFb9wnqv>`WuF+?WAPf$f^Ii3MEhKO(BShpN%t^Am-LG{RUJ91IQq;^e41 z`a#=8#KDgC+SUoF+iDFxT`0Ytj-|C;y zB-DlhW-NnZ8C#8MLyUT>&YjaF7$~Dee|Ym!HBh*Q>qx&-WkzxCgo+e-0-Fz7A+g+9UjcAi__?u`KoGGcx*8iljpMdPce#*bw z&4_saR@nEMi&lcD?JPK$pdWw6P%}N!rcZ?-8MmKK_>$gsUoteFx|WaBP-1@!afb8a zwu5_t4lB60V*dzw+Tv}*O>!Tzzk+*hGPvLgg@vnIs(ArKabTY^!e`=p4A9rH#<}|> zUbG`bvF3SSI4>StUzlwU*bl$8AF5rX2t1jHv^aHj5tAhOWzGFej#~b@z>KstQCwL| z_*z3F)t2~P08Hy8Rn&x|5V;>{>3cqG69IaU~7XkY6@UYyDXR$Wit1!MCrw-FI2;nFwtvc zvHb=t_vN%Ysx_iM8zW`d?#~g0XU+;U0vGZm7gq<=Sn78yU&s-jq}O-Fb`9fBS^auE zVSZa7KjulASmpM<0l3{Q8aUfRQ*OFOYoP&1d!fheL~3_kd%kxe9D&7FFd`r1^BbZpScfMn-(hg? zw)njEqA63|1Hs$=-S?!;k=kK$HFWY_J@8~S#0uxUBg%#}bAQL;0d@Iy@Xrff{c|xA=_%4wG-M_zwg4e$d--4mAes>NKKU+w; z0o^XTD7|<_`;J>ue9g@Zz3y&NpgJiTK{@K} z~9$>3U%McAYeD3#%Yr`$1v>V;CcySN2Z zr_LuM)&54%9N&INLQqm>>m(PRw{3X`JBtcT!C^syC05eyNOoWBgN^(zhMmNC1MMEKL}e@d$_D;ml-7>1`} zQb5k!du_?%=Fj=@nwW5E#l#+)Pb*Zlg$)Jg&-4>d~#qsmxSI{ha&lggAzqBir70x2_Gq{QXF6PkD{!RFom4`kT4mt z1!q$^3g$ybQM`EvzcHt(mjFQ~ruHII`lN3~pL!ZKD({D^B4+pkNvs zMkLM6HNS++Gy){hXRSUEieouf!d=p|Z=zwjtZ3Ie$ zKSJoz4|_#02Lwy%yBS1fJCAYhbg^%rw!G0jG-Ev_Zs_!Sm_&+Fj!PIJ$Y2xO9Jf_h zE<`i8O(HUBmZ^=m>2klxVg!5x7^c&NiY(*CMa_$PSdbRj_(IX5eIAYwx+MX2%5||0 z8e&y;{{krBEm3VvBUsjiILos5K~TL`uwY++T`Y8X`YZGYebK zKY01j_w&g3+Nz8l+f1N3N>w0q^8N$i;%`c*7Jq2|-Fudq&I%6E-=>Xn2qF>QJG?R5 z@6SjjT;rs~21Qwi&7bU90ak)t(OR_5pF+bSC`Tt+%t=~K(%wFx5Tr71ZDKmZ*J%y? zTaptmkOQ(!k13F*vK7~lCye#!A)Mh=UO>7Fh0eG#*`ceyKOWCQStxT^Q_BLPxZK3B z1GNl%B|Wn#JS>9E%AOJTTzupkpz_~W(>a&3TM7vHgFVvP=rq!#dX|oj?J_^Hr7_`I zB8B2=tQb*xHM0eDqR3ko!=skFEb~zMzz%+19fZW+y{LCDW8&!g$5F1{(k@H|dc%Zh zb_8eQKrS%JgkVj@`hR?L3E4*FSiyZh_E?7a*R8Ki7!*UdU+&&u6 zaT$9!V=YFVf}Qw4?lZCXP-sQu3LlYgoap}$8EVHRwRCOhyF3J;BAryY0Z5Hhi%Icn z^|a4lv369tQSM(Qk+v|Sy(!a&jF9RtlmvxKo`_5CcSm5&#HAB8O*Q%(7x_H)dJDg9 zBoN=GpH^w^s9m(3-ip2y*(dD1$B@n`{MyT*h_Smmtm|x;zrH3TG)zm^n#eoW6CA>R z#y;Y!Q*A-Bf2!zTpPEkjr=4yVQO{EquFyedGnY^oFUDu?%`%+na-pLsV*#{~-|T-{ zo5NuFs27!_+%Cf4?m9qVK40IF*|(wQxiB@x({T*xYLRb^^hQNTi$~mUNoplsi-S4LsuLRdQb7~ypsHwg8YNSb#M^y(TP%vKHc6E+J0xoaT(1G( zp9m25lQ%5h2s41=>((`FiJRa7*IXWLk`P?4%q+2==W>H(GD-3p=tgS64ut=DxsV5^@TD&^%(W6m?&r}Z(TN5f7zwbVr`WH#cDWuaRrd9-J+j^$U` zNYiDw*{E{hca-?Op#ma;yJyZb=85ZXDv>go_7DUc56eRA~SJ?nHT z7Ez?5+>&DaYM#5ICyB{YYYN!3O_ZP?S)eXfeH_e`EB4fR7N6756*p@98%@M|!aVB# zs0u(d++5)<-8BQU3#hpLiB8oKYw{*kY2(A`;ua($F}Sr#P`xakyS14b=F3x^JDLHm z5BhzX(a|a(wkF&i;lVV_iuu4LJ+q0aTQZtBvtB2a`(~_t1Cj)GgR^25Mz^7mp1OO= zl|pYfVwN1+e-HX2)+PV^<^jVxiIG5SsAc~E>svuCf6j)B@p-KjVubrV zkL-Z-{4NBtk9LFo)pd=w=~=g}SwoI>M<2zp(dHe)X}0U1sw$c}c+SnXxZzy_Z1)!L z8UFx<#wdRumOuR{KGF~F5Pr_aJY?6q65F)-6l)F;NbsF#OnaeG5tphy04v1>mhM{{W%ly&3&EjIsX!&Wlbuo-cn9zVWz!WWQ$R z1Ga~INE8Dd=wPrI1d5+G09>&iMzx_&k^H)ZK>f@`6ns45Qh$XNwE5}e+(#yV%1t=x zST5VfVE5TS;4>O8!*{qK{{Te_TZ@G0EQ936mB*;+5$BTXU_ZWUNd6x2nki$V-Vi#K zjGxMz<>5{wx5<-9yaY4z)bRs}5PwdG;8voFzzh&E@}n2Z+bSv}i-viHpJ1kDMtB=c@%1WUABem{zih<* znFM~ctvpH8@(h;IHrwElnu3uT{!vBps2JrGKZ3zOT$|F&~P^&3Z=B0c*{KRxleURV0~+(_;w&+&N{@0KQUcD zL}X2L?2K;4w|}bSI{T-1#(alq9__t?YZ?`*;}H$LccPn2lXX~?M*I9KcGl`gN-Wx^ zFG}6geO4VeunG)xvP$K`jBk%x7}Fu!EJ@F;J_{EtS(qp%ah&%b=|;zBGt6?wIXE3~ zb50^DynQMw%$&e5>0_2t|68vqe*cB9E#vV1+%vxxZ`${cR3C_VTi zVbPEpGn5XLPLh1hHrcxSnER=~C>s%6_~0u5*2yO(cc3y1>?vUYbQPk5tt57v*>SxC zlderHk}=p(Dzy7|Pe~zB(|W+2>0yYRng~NqXoUNDBz&9iSYsL3Z%a!0iUC~qrWTzc zc<7-SrR69AI{Hy*B|1yxjm;Kf&eY}QeI##E>RpGg0LigYPbF6!}7bwFFm`fvXIJgka5&zt{Y|Y_4p4#BrGxO zTiWEkdd-p&5qj^Bvrk7A!!2lrI|FQCvZ1C)Xg;Od5L=)v|ld4VApkPP&~V-2pyXaKjO^~;stMEM%khM^-C#(P z+qZH?NBlXb4`cb#ebt!q8L@1HDLZM9$(}>EP{4)=C7gNJY3O6Sg%69l(q;h zq&c*{LP*F8_&;?lmiJe*Lar8Q&crh3IrYU6#)0F@*sH9}ly?paW8ps%X*v#@#5zu` zXCo%13@4df!z#VIbEX>yq2Co2@h6ENjChJoLDzDKfsQ$_gOqa-)a}-js1Gpw1qSj1}sMz5LNlgHbI8G_A^`qRV~>V$rD zwO~}(4XHxJ1}N^hT#NZAq)dEidd6@%P-8<*2^hsYRdMuPLR7{m_|pVap|l=MV-&4W6s%az`SqnLzUbPfjRT1(Dy9hZ zu9fiGPHr86f2z_C_`mO5>Q~d3yGTasL3# zu#!Lj09PSD^;bGvmTNZyeSrhyb6lQ&JAV}+8(9XH6ME)vPwK9PjvgD`q=GNya_ESj zDKyI!h%jF!CqUhKWRE{^IRoKb^{RrJzNUu*mf}PAoYz`#tai8jIm7chD*--FNkzj&Ih%spRUx?YUw0Odx};h@^AFHNAh1n-|-6XSbjxIPwxVf zc*zep4_mkOFOdD}!ny4-bjyG`t;8&TSYi6tO!%`1ZV|g|1Le;HeewnUYnttMwY^VR zRQ=K|a=l`|5p~(CujxSeJ9(8c;Z7^m_*%uTEM1kw$PI(D2Sc+1u?Lr-r%U}x(^9z? z_LhlcZs9FGymB){Wkw*nD`%HD2Loz@!IPz2r=-v~;KTK)E{lI2n{8z)#ImWHc-S4V z2tqMj<8k9|L*!$AcWi6A+RAx2j1S?2QTJ0$4~9-CxVDZdBZ5nammKebn8zvloK=~u z=~ghq3ToGKTiie!+zXPxbRgrWrBb{ZZGAjk)=C7neq_ICLj{eAC3%R+8R#-<#o~=- zULsp*=aMljaD{0wM>i@8IH(yClYMoP0C@zihDqn8>& z`xKX}C@3Wh$Xe9(OC#x)U4K`Wtd1k?qXHX>`TLn)cq+>q=Q^bFb>x zR_Su{$YO_?ZXNjpxcfLPbBt`X88qD{R)6+;cPjjagkucHeYW4PQBIsUrP=WZv`q6V z6_5mu-PuSXMjg4ju^qY!Kg69rOKulwV`nBAAw1_C+2#wKvA*@pz0EnXAFR{T;|RmplrDOsve1G?m@ML?ncGO4}=U&FjH+VUrl0}ZzvaI~0x?)=$ zJoSmk_g^2FG(X+8825befBK4l>7{C5QUP|!>F$s9rI5oE-6Twj!%B2eg zkrD@@Y{)!Rs{4U||A7uoR(&awfGOx`Dq@_7d`x>#p znNCAV^kOS!OMpgXay}Awr9V)sOcS*TC#6`XM{EL-u=vD>^rX^7 z8+EmTv($NNzmTcf)>=&%kK8C9@Z^JWFh4?|JeliR%03k{HkO3@)<`}euq<^gd>5O_wAJ2dEqyGTu?-p4Z{{X}&d=8}_cm30=amNri z#I0v9_pIRk5K%w)w(RXChM4*FwhR9NE-9(>$w%3AKU{udiETFEk@i2#D1=xChOiH} z^ijFpMV;UMQ^N5~C;D9nN`3nzsDB5bKDneweeDh;&;I}}XJ5~nnHx{J2l_I1>_Pmf zCdTL==v(fo20kZZN3+U>)8}wS`>-cTbuAeEoi0Tm3xa>?q1nTyYH~WIys;`SOBcu= zhV;VlO1)!o^HWm|IbgT3fd&<&0H0Q4y$(y6j}^w}7ZXF~x>I5{Ou4kk#)g4s<*QBd zTCJtD$r&UOoSwDPyc-ykPPSvdZ6H5-3Zg~46GtM+o4EhDd zbRP-MCU#(U?(o`wn!xzO7{ML`ngD5);18mDme0%p0!IC*IkAmY1}ALeH6vSQW1Qet zp4C0FFn9hFeqy@PXj0@TDC)ri{{SgJ;iFa)k9Hz{ds0iQgL|k;4>LyuB!=btO@oid zhT4vur)n0qaV(~3+ze+R1M8Xy-1$ijVKvHmV~Q4sJ>U~td!u=HE&Ie%?k_Ph$F~iNbzTI1W{n7Z+%Nt!f!V__Sf{a2cmfx6;Zr*}~FYPX_Vzq+V z-4pn66O1v=d5Fe+O#Ab9M)OQFx)JU4P;saUHydH@8q(RFRct9eyIEc_$cw%UlY{&L29enK9b8%05&!1z3jK zw~tUOJh{h}LvHAjFby1=jL?42IHRCKR8wl%EkcM!u0{`fv^X$(PKl{UA?M_nFy$NP>z!x&09Yrd;jF6vEioe(^vK>&8JktY5md-0&l)03Hiol!G=~+)E(MrDxUWza? zLP$Yfg$_0PQM6Ks3r3mYV_{2@Jma=#(74$_RnKkc;4npPR0=$F=}M5G zAj^CyVkr~|#^8`KOAuuJDs}`V$c9{zw@#IE_+2OaHS~G=Ga<*!WAv(!punp?!xsy6 ze1~Jn8-65JxOR8ZCLftszqI>7ZEeF7$Xl7Dyg(EKoCwbO#d2xY?Y*7RVwjgw19Jrf zJ7=M;#{H=5)_w@muDNp7+PZ+rnZuJKft(LnI|utAk(=D}6Q#A73BsdJ6} z2&w-75s+`K_?IYnI}m7 za%sZz5eS%!gq0iQIjN92hT|h`^HK|*S#2GN$OupCT^kLumX@!WQn>h%-%QkWso~U- z+Rj8%C`aMY(n{{s{W)Snq4n5@s5T0?7xnH`it|OgS zh3@Wg%&}N`qz>U%oAj!8LgMwgURxWH%-vvqyLtoqR~hjL$`i5hkVc9vKI^jR(?ZD0 zWWH<_UfKp0dW38+Q4o>Sb&)~a>reW1lHPFr%$fJ?Zjt?c*HRe%6=R)OL)Mk8^{WI7 zQ_C}_yDE&1kMPGsQvMX+2rMjhd+Sp!siZV&9KE?dQ!a2F)N*(0wPE39GEBxrC^0?G z+V=-;#4Wy}FQ&^RdR`g_2h~%2CwH!C*Au>sZbjOO)EEIR<*)(zb|B)O=HpAz16n|a z295lt0ZN`^#zsakcc*U*E>}n5?6ioEnuWhAV75!JINPws^)d1HL5|N^k65vQM{R$H za)S!8e>OgKuw$v2slS_p?72fFhgW4(T-{#lRvLtNmr(>wK3Tou#IweEl~-fAHCM57 z5Fq4{kbhc{TNlODvJzt!^C{mMB@RCtjz~!xe7393j5V#Q-=9U3Gn*vMCdF6sNtnA% zSnf#XKU%Z+SA_3%UL4f5g;)|DF6Q1@WOiP19Qk1sXD1|s)3sKi{{WDUpC5s)tMF>q zfiCPXt@Zh(QZ3#{6iXaQ=At(tViNKp~>SZqT?(Pdb9?aNWr#B&Cui0TCE%M<~JV-+FZMCfCm3y-Wo@ z=#9E|R|oW`-4^QCQMjGpX$r#LPofqZu>f`S&)rLS+QsfTOIeI>{=snA^(z@+UPdz| zcU8x9go4>wvD&xcX?08}@gI`}W91sFdt9}`2(w*U#CjK(@Qj*YsinoXuGXcn9yr?o zY&nN&L%@h1T(V8KcNqD`->9i~7s2Fl1*;Lcg+V_RVk@o6b6cERXxj_;#v%g~PFy(Nvz8pJG!rNKwpxp}gBW46bCg>GYX%zU_*UR`FEK381L!kOWLv@VS# zvFgwh$a$3fY03-Rd7V`CJu|lcl=-f3rM2^{mV`$%q>wZ279D%BctaLF(_% zIL^k$b8L;Q9zE1b@_%BUIPRrrBtGy-8 zQ&WrvDv{zO7zhS^)lBv4lUb(l{oK;4#~Y%7&CXYy$sU0FpnOep$Kf_)WO!KF4t4%g z;0N7rH{*$6hs2)@G!AroouFWbE`O<+pjkkQ!ekv*e( z$Cw;^XoGCn&I$Qchf?9~M@h7_o@uRlF6EUGR$#;!vCK&9GH?wM9)+(rgl~n z>qN|T@lFXLP%9e(g6_pZIr-w0S}IE_tAN1gtuvbD0$d2MM9h00>S+Y~r;RQINIcd& z%^)LwfKz6vXzg=uiOh<}0f%nq6yqppWVMbTbQY7ZOk$Ul%%Eps(?6YOwpX@N`><|; z)_yw#LApRXc?l#)sG&x{3<~J32g$I9ZT*@t_*XwKEF+z;aC458&^{kbF03G%0Q1|a zA46TI!H#pXb2iw+{nwrRbj>)pM)=4gz1pX+$DDycmLK-WKe*%arvwBh;0i@?BxXpN zB|zgK1HO5_RoxJ6a27yO-9p<@w|Djjw;bm!<{=~>nCng2K7y9luc%&3Zf=kBa^Np* zg-Qg`$YjO9B^)bqCqjOCptHl7K=WLuY~v^4im=&BBP|pxQ6O%qz5w|{++6B50Xuz= ze|heHt1B$@fIvWY zx_}PEj>q|j`YT;GDtv6&d^Z;Ah+o|XUO(3S#A|U4xKwpKiMt0FAd|mJWqu{r-HBV4 zPlA9bE2lE2FcqP1%mGw5tSt;3g57^o%zraK=xKD{1760Omy%BMDFe3Rt+KtUpW%%I zP_fif@?wEk7+mjG(%uJ|RKmbFSK9;US+I?`S79{DJc5nn+aiEh6uXohVuDlQQ&N#P zGJ`}i{3*rI4uX<8Vwj3gMJ51Hd3T{4=8W2q7L_7Mp#{jJF_H1D;0jcnI+0wMt@7lG z8Q&XL9>$5bj5!q1jl}>*j+CSw>o9jTL|S{aPbmB7T$^p$jSIbRxfrA@C3Ko~P)46S z0rpcrbvVT3-Yjy;C1egce$O;vhv!K(Ku(=@0Lk)SA9Y6flFs_)hP1oAHd!N?nLNUz z?gDcDm46N4n#mWp9?FhWb-Ainsc8B}+xxnf1sIAWdaDD0bZG=p~ zu;g|_jN_rGBwD8&SpA!aa5J-H{&}Ua@vjrxj7@7BgZ-Qz!xd=FhamamucEB%d0I!x z3SV>KK9<0nYsusE3oF^2tApZn5?xaUDF zx3pXHvoQpg-M2XAJ5(Qs>GE(u`k^q_EmeKj1#um&b7ou)@vv%j;CpMkEqX|F}}P%#(x0 z$(s;i4i=$Wdh+U=zNCy&tIdc5rcF71>14TC(n1LLin8M$P-zvyA0>Ig=D^84%_$=- z18(Y8y5o5AO)c*n{Ak5P*A=k2GjCpd22c&`@vmr2#_{eQ30( z3xPvb00T!iT^&jzCe8S1< z?IKp6^rOf-oK*h+S#dp%iE*}G%qjl>4h2BL+XkhxO=~X?=_-?{o*5=tBJQeiLHSh% zKSYe@cT%B&6Xncfn?pb(-<5V+ilPS-+9uN2&kJ7K3y(_|R6uDx%x3Ijp$SRUAm2|l5GlnDJG7WM6 z01@SkM?_r|Ph}@55U?I>zqLh4edRmKIrNj>Z*WLivjP+_}y=*Cy_xhnU-mg}O!X z8$@?oFB4)9nCcES&D!Gs01b3)6U2TxxVY6KmeT1gnrB-yh6I(Pkw-B+q?RG@b6rEJ zcxA%6{fby>mR{3o8-`VTnFHjyg@oso=*IT1A=W z7D+G!?pEGZnU3Cygx8V*ff*PB({X6P;olm9YNtHXMk+~IaJPjdo-w;C_S#XHh z8Vfsnpz^b@$6VvmpKSF%CPhc{8UW#3DaSSsO#G>qBlev1RnOGyKN`zmd7XP?WaFSG zsIKES2;^-zeqR1XblnfCW%PK%apWv>+eW*E)?OFGr_Eqzw3xY-z?Ua=C^7+4(;3El z)vvAT=6w?OJPud1l~2_Os(ZsIt#nNq)Ul1{n6PrBb8~YL6|?D$$E|b>maTVa(FOoW zr9PN7;(b}(4^?pvacG-jeG2V7Nirf5NPcHF&${5A2IX!h(c*maOMM!?4i4bsaq+7| zjP0b*s!{J5_Njm|xR@@(Da=cxo#~O1q8iXbH005Ez#F9V& z4_dlYig@Nf5X2g0jT^-tq;1>yUT~H*lannX2794nHVD>h^ZT$j{9R9(tBC$;@33kjBA3+=CC6muJ}Lu z=~rhK_-n^d>zcl&CX03Krsm>NaEr_s7iU7;yNrYBR5_hSpb29fi84Cpea6Ig>x@@Z z(lesSf*B%v96%SO-5;Xmx~4muB&~2Yxfk797T30t$n%K-hB?n6P}tupM&NC}X%@Yq zS?ZQ|-eRj1jhR~mDshlh_N2Pxp3M$WGTJ);*7?8oSt$v+Bg zn$qQrQ^#@UA=z`eR!};D%rQX+QFc4p-3-%Y?%sZ?XW%kOp5Y_)P#Zhz!n1U(9xIq2 zk{h_=1|S1e0=+%AjML zt9*N6w`qMW!oo=>=W8tIkaDstXPjX7+OvjBrVo6Z+xB;s)U;iU$Xv!px5>MF_q6Eh zZY^Sp4A~;BASh>az|`P zR+b2X$?6En{Ap#jvvs9tnx&P#Gku8U+XTdiErusk)~AA4-1cj6wl>@4w*gk3 zH-1iURdAivilD>w24Amt8M%)VgbMdbBvKv{WAS$vVcP*%X;qi+KUF> zMdt=7S(q?T7~r|=cB;Bb`K5|(R+XfSan1G{peNR!>~0m*+2@|x^ASzvfy%tu3geqA zmE7mGTj`xbe0;+-&~YH|!l~4-;g=Dx)}knj?@Cf$#^TsQrd>wr?)Ta4Ac`#i01gw9 z@rU>ZBJ5(o% zv_{djmA7?8X0k`+P@|VDf2v5%DP)?Bq10`>>$aGzQ%Nc+m=im`GlgP${QYVrsp<`X zf9(qrM1^pOofSdYbQR2eSCfO2(&M#t-Bk~yHdzk^}P!|M<}d0!(#AE~E}#>r|0 zV4w_;ax?MjYbAAoGEPY7D2Q&Yqmd()b%eM%atmMqz5wcd1tq?_uv@u}ysabxd_-hW z8PGPxmvO(PdCn(GpCP*T5rQ zrhF=m^3fTI;9m5TyN>Pc_bottIH zttaz#t@^csc}WeOtW4!1P+tU}Tx~*F)egW9kfRU1*w8)UMM)zRk4nM=XB}u5IH3c9 zkH(gel8fwIp1TEn(O{5kQ+$X{{U4#I_G_B!yYWx zHQUR}OGPkTOU#lyfk7C@N`pC$b`YRVNPnVyR{@+sq5HqS>Zmu&=WBG>V+5Y`THjqS zML;_MD=uJ`*5+$>Bbpf*8wYHu!NH&+NbQAQVh2D8tP5MEf|q7k&unFlU2~QLH8D08 z>)h360~I5&6=>T^X0?h#)TpfJ-dwa=-96HEwg^utY8RH{`Kf8Z0)dU{ZItb_kiy5) zdLiv!bG11ElaET#9`Wx?QQ1t*WhvYN_t9qFKn_sT>D#3PIHv$6Oa%z|8VJT|#_R$? z6o&)7H6(+}o$DC}JJ9-y(;k%K$xaFZ=ml*~)w}`gS%HnHlY&AJ0PjJ34wby)6`0AS zjBbmPF)T7BKGHDz#V6sT7~z{}t~p1P%%_-v_D{x^gW95#8J~qXfg>!B0l0K^I3phR z#B}La@Z1|N{{X^vRWknoC_GV8{{UpMm!csb3>r%=iKjnU$K71coI|b0j9xkTunqqJ zFf_70GvX+*i?BzhmaG2&AX>fnm`JMrOFzdTkC?0OUK-P6&QN{S*Ea^(H$@dw!{Qdd z8QjGG05d250NqY;_?fGz_wCV#!GQeK(CfrMr}-%cOS`#CrQl0eISMJJNoGL!FhA*2?i<$Q;u{vaL}UpwMpb|ZDgiwS^{FF|7D59K{)mL`J8kw= zj)`Nc+Rq4{;!+XhM*)b*M=QVGQ@f~)$ix5&oa5jqo48SL?i2q2lXmBB-eQOU0Ir>R z0Ra;9@)VBNd^h$(k}qV zT!@&D#=N;hu)}t*T1as8qQG@D*L9tTG;W=mPWR-Uj8ZfsKf8AxI?kXHm!DNi(Uw@$R8#A0Ob zGAm)Gh+Pwfg0Fr7ets0TPySr9C)~&VY8R+TUggek!PsPMK?k)<{5oZRADuz|j{0Rk zPz^z~RFWIZrYdpg$@nqFVf9vr0q12=>oQ3USg&Ctb9L;lzX*8h@;ycLE+Ewe_BSv; zlP%PM2w4=8rQfp+w>@!PIc?&vhPqCP`=?XlZ8;%C3at&mmB%mHIE$E)IvVpwS-Fuc zn83kYf>h%;&edG=YEzzHYdp+w0>(0b8ssGCFyzSh6QQqemo#h$JgvT$*PL*JCU&Pa z+Y`^C?mc_N?+>j!UD7z7-(Fj*J3Sua%6~4_;7H8wSvf zPQ;{fsrs|$@UK6cLe%=o*Mnev;pGe-KN3r4NaWtZc0Uz<)lh0WMgE;@!||fs+D`*K*PO%&P^NII zGuNeX{GQ?k&c|wWX!M9v+#*Rc{IPq#1I*+f!kMOGUmeF^t#q9ap>*z!9?U3wHoS*F za%_QJ)mP?C)F)%42jvE>8pN%-pZ;W-KPCSF?@I0Cxe?t=h~8KMUHfjsZ2mNgVnY?} z8wCFVDBtnT9FnqoPz*=#+x}o{TP>u;up9ZUjCntJET2WtJ{v4rt)DyHGEZ$3%%?oX zr6jmx*MFZ;n(AH?xNS#HdEb#GhH{Szlaa6?uySy~?02q4@TXP+)>~FFL{#%3W6S0+ z3>iiS?S>fmX1ZrZyWxF%Q_}40TH){PF0Ex}wj9yN&aBL{Hh#}3Am^rbuNC-`2@ZVC zEq<1gLx8;@dOig0egsCrBv$9iLhtxjTGKA?XS1=hoddTiR0$%IM4S5OIHuko@rzpE z$gkENCOKZ|qgN9a3mH;<;uL~+JJ(A!lXFZQ1I;TIBLo~A41F_ zkfD?Z0NT(SGFPFA~arD(*S|CHrSKBclenMm4uf5@HUqdk&fm%wGho$ z_f&ND^7|_?{gHVho&D_mej6H;Y1}&vFNH3-bnyUmytnc|s_6a%;)9s5=8+&mzATdU-}T`UqB>?4)tkD5TLSTbQ=n- z?!A*yyS-Qsl^hn=4m{(MMpdxIlx2=_pIX&0N25?7+t$YS3p7h6y*5P)s-*{pEBM&D zT!RzFLWkd#jy>Lk({Ebbjj3DP!jds);gUnk%6UnXVh+b@d$EEPF-s(pBAF0wyvM(9 zrAcGaS5k2uyucZwbuo}mJgl*Ddu^Ibk60iY**SZdN6U0nIJ8%h+QecB0LDf^5u)Xr zru@JCslH2_c78~Ql?*)07bFlDxjop^)r2;BJ+;lP^ok|8f=Px?*pCE8K0L>A2Wo2; z(B0k~$H^SwOCjjHe=+TkjZto=yXQ8+VY~B7Oo1B-i~#Zhe%xAGnt_(Yyo5iPKpDpP z$j8sUHb`UA>rWRJRA4||;G%f%4Ezq(N{b@nTXB@YtY!-KfaNyg`{DKjaaJhYtS z%OjD0m;;<=)OFgN^$UAX+?K>h&2(fjw=XLoL<0mIsmM9hM5l6Dx+y1Zk6N%FBLQyU6T+%YZz0vV zNY#CyNh_I5vXG111qUY?>@X=rpddwD`=bPw<|U5j<+-P8Egw+1VQp;@c|zny4okZn za)5fAjNni%bR9=Yo5;M2%Xb{;3CSvU$sI;u?L#~`X5?svC|&%@+c94mkqhV=ri1k>Awjq zX4CW=+i8FjM}Ht;w_pcu`&7LVgD5qmogkhQ{6;?uGn@y`Lr&_k9u4ZqV3y+U&@@Sg zz+=ouL(p`q2Z1dPnIl?~q(aW48w_=;M)odf$OAhXsODXBPQ0JlZG6D)ST{E=GBN0D zvBAWH5=T2x1fPwJk`*T`qvl0Zw>KPEAd-8Bg4!6= zv%3?819C|wshwZM9dhn=gG;%010&Al3J=9W8OOxc{ZIjA=Dh-~6j@U|GB~Zru`90L z`pz!1CjEiUCv9s?g-J4lwt9M3Cbfr&n(i(PxBP?+p^cF~-~ir}t)~-dGpW8=n0HCl zmzW--J5)zA0lc~A)~Rbp@aJ2XX2%`>01lylWz?4(U8F`orcJu#fTpRq>q=00WDI+9 zg5Qv+-v`+6?+~UVghg{2=15<2^9Q)A8Xgm{j~InM>X1(hnhRsUTUoQTcel=@pLRHfs5+^H&@<*n7QP%n$qy!a>ay}I3@q~%6 zIw_)j`s30V0Odg3Z4w7-EEvHG zOTpv^CTS1T?Nyg&@5G0fs2@tnEuLeBj9_#<{#Be{i2jhS_>zAS`>uV2`}q5+#L%Vl zEO~mE*o;+g6p@A*H8SD5sKk>-PudwDO5~#0u9r}?FJ%k{D6DUahVfS)=o~NPLvwPg zG|hmZ5>$65&{M9D#JXmt<{^1(WFsgQz$A71CwjFqEArXqE#MR@tN243mRJoMMe6isWT-J!t`2a<~AYrus?NfEle7+KlDL zY6}W(=^(F4-!EFw19~$#8KVNyzeHJIm26~CN&3)9Cp3s1li5Qc9qKz}7o8swS#G@S z-9~wXpcwgYPs&(zIi@={SarQrd16AaM>i%3=D_WZ{{WJv#-TGwRr0LFS26d;r50P( zoHbZIlT*F7>E&F?pXFjHt(a%$K<~^}G7umdP&!gn+|lb%5=PdQlxlUWo5J~vSzp1Q zv2d^cb;tcROpdv$N5dJpFZBq2uMAKAMkD^Jv(w#KO&)fnX`rW<@SolnV;JTT%b#C& zm;RbKv1@x*BNPJR28dZ0nJ3ga7eI)?YEmS2G=X;@`qtsxG`cYtXqjG4~XC2YXF-I>^L@N?^ zqt|0j6C=7B5!hCha(AJa@zZ)mzyv|Nqt~3GjE#jDqka8olmrg6scE$-1yb0~3uC9H z9}LeFuu2q?7$3TVqZ@-l9jUb&v_q8sHQpmg;|Erd-~xGLL7e<>O-JRj)24TMq7pog z?CeR)7daZnft0CiYwF&ImOMc0zL%zSpnK#ih@U>6`m8p>l#X9FgOA0#&cJE z$92c&MqWm-%76{ART%G-6`otUS1*Q4A5PT}fH`kNV1H>q{VJ>C{wUO}HSJSPjbd1% zx@J;Snf>w2)w7Phs?G3}l68oV_-G&R1XV%ej6P2t>SG^lK*Q@2)@E*(ID@|GT&S4r zD9eB}RAy~+RFz#?ROMoJSYuwl5Hm<4)U_y167qEbU}8oaeLhs5WA{)F05wbi2LWUj zwYvZS^hHeN$tS)^ImtPsC$CCa-A-vUY)wAMo3$d;@}2uu?7@=gG3bE4{mAG(rvi$9 zuzhJn2vQhNLveBxd{#Zr-bnkZ)FPVW-0T*v7(belB+r)lIU(17o@x6;vTa9Gk_A=4 zfD}+trCX*56#F5B10F3)NV0ZK*HAk$-V8EV6 z^2nUw^cJ@IYkW+|SneF~58YTiE#dw9YT9O<1kY;?;zcy`pax~;4pjy~Aw~#(*#f$2 z!=4w@cusv@cq1zFPLX*-VG=?KQPbXL=Ovi>)nVc8p?$*82WseeEv_WhFYSD_5I>bSFe95Rq&|1(c|Zr}UKQ~NP|T6ehF8|8o2&}o z=D(`+SRsNYjRRm!dUjcH#2Rn2nL|p8zuJ$f9kw-HH<5WbN4Q8MNI~Xe12c1MS2)H! zYHzCO&>|L%03fagP6kNa4wt4+qvD-qgAClpm6dr3VUyfsk&lg7dIq9ox`G081hOjoF( zkl-lD#z`P_#csc>W5JT_XFbf3z|pOa*0LGXGqIa*~BXfhfmo6g5^Yi}$>BYaZp(%8eA+8_-^@5rWY zV^p=XxrHOWxRxmHS#6BbG(ui>-b?^ME&$JbVww0-!Unt7gIxJ7HkBgbqby{Rm|+0? zJxv$Hn*0e4lk9#&CAf3Wsm#b&Y#fjWHcm#_^rtQsg4wS1Z!=JcK=utQNHdL@PE?F< zzW$Z!Ftw~KjkU0{K&vEjxT&qd&wq2UChC(Gg`mNIZww0&Nkhz!&$BnWTOmsAjCJ1> zlE+V9ZxQGAUh?lddcztK&K);?Qv!&=d2>DfYf zh9;Kw%TbkA?W}BtK;#LRRl(SRqpdedacw;Ja+uYil6f6+M=J&-_V^B!Bh@Y*<43!O zS$w>Cb431I5h-1WT=d3qij3$M-qC7`GsunQrXno3Y~;2#C(|3%cd*l09{>s-%FJ#S z=SV>=Jo}(Rp3&^~=3aj=$a!37z| zLlxXnnMs*s^Q6Xn+^zYp- zxww)?Y!y;LW7Lt19`seD@>-eZWCzPZoa3V%w(585iho7 z%0>h;@}ia`;|tgtxcohXQ`GJr*H*Tk8SS7`$ttLC;t)Z|3U?SdHHYzDN8r95%E$zg zz|uYLmqGArKNayNEKUG4>a*w?qdG4Psn)EL;@Vjue=%JUg=Pf~z?@*3x%d)II%_>a zwDskHUrGk#=iVf4N$3a^qr{E_;>!&qOoq=ymRHo0S$Tq%qm!dTNc)gt8f(m082UFl>8GTZ(6zd z2g5xthBVuGuHZ@a84xtCz%Y!R`BWa`*0}>vyqYd4yu6fiNdT}wPrn|iEUXW9SxaEo zZ)n~k@Q$@%9n$KyuoggMig{KyM(zk=GxHUDA`jh08p1&36j?8eP-)UgTDBG6!qz-GG2t0#DbXOB-Qt&RfXR7JM`!h?G zQ~Zbdkotl;S3pAX&kR!`_hdz7`7q5>oI$OB;$I9j{Yq%LX1aI?P(R*et7GSbR_>c_ z)|zddyZxwbqeJsm0M=AdcoWMX=>%=$x{j}wdY4D(`BH)7hshJ2-NB$yKXk7Eb)u)w zmgC@P?atnmMC+Jbe`c(%T`RPnKP^BbJqANSF?>2djTgCW# zPN?!(BV%i7$@N73wA>iLb4$rP1!=y6#+Lb1*Dn76#N_^Yq^%E#HswIoS@Li>kx%JR zT@S>5Gti8&Um(=2?eXTN!TurxxaE_t-`wJHz?)>P!4YY0AvGB*%_p> zrzOmaMljT%V-=9VTe0LVYrW9P&0)o8(1jXEECA_6o#?}i&}r=?UtwA_JOe=>nn-~Z zv3)7B8PeN|?IYMV#k+6o$iQR%Ds%vhRBKv3&8}!SSpW-`jFbJb)9(U~BT_ff!AC#% zXW3F5cL%cZcCj8X4asr;0O6QnpGdIaWvQ0cL$njoLZMMXume;VTQ!f7^) zuii_HU=M<+IjTlI15tg7BK+I^GfNkS?!TH;A0SWqRd@9_owb4NrEVGStbyZJyt&P- zlW({1+hd4BewAI_N!9)# zQ#TL<;Ql7@lg_gpLnTPt%S8ldaj@uW+2KzRW8$rP8xdmG<)CNt8e-?27bGYnp{jUr z^{5BjVsLOtG;fA;n{GJLiQGHO8UFwhF#PD?%yf?cIGy*kBcN*=!tC8P>Puitg_9$0 zU^d5aMH{Hs6nOu=zZ4%m?(gP&eI`{VL4xx>f%G#8)eydRqgxZ*{?_caHXQFBI5Hqi54c z-jX(dI>^j*WDtCUwJQvrHo)QPkL^IsYs~HILRjUH;UaeV0&1~%9FVcR7oHkXE!v1+ zI(kz70AsvA?j#%k091-C?Cz0EG8F@@FndpMrEWZ&=|5!J>#!K@PkM#A+G>_oz~o!3 zD#IHIGnog`i62VM9u$2+C6Rfew^yD)*ocQV5BG@2){#!~N$k_R67H<-dzSMXHF`32 zG42O-};a^0JQxMKQIe$D=mEm4L_?5%Q1czl$z54c2fKmJDl09DX34Q|VbWxBMtDr2>_ zwvj}fieQdG8XkuXP16! z4I<}Mhnn0iyLqY_b{xmbQb}T`Yz&jVSpFZ{Lvsbbvn_(#&v#&umj{)d_jfFvR~XnG z^O9@lyxgeg#Se2Er~u0caqsqCn)Yb~S=~KfS*)iF0T}&iwwXZkQzUalig&@l!RzuB zaNI_7xCa25fLqyE4N}#$7^RZjFfNg|D;4GC7&TL;Ovay>?O|8mh_1_)JWEe+(r+J` zLq-;Ck&Fb~kFF{w!TJXc@t%cdy7sRwmj$k=EGFtGgs1(oK6FyMY+56aompIe!}qTG zjn%!K(9(4eH`u3SVyvg!<>$r=3~%?-Z-PD*>YPV$s_FWLh1|MZTSx68DPxXE$~cxc zjhy3~BOfDPsRP-K(&CYl>G^>KdigAg2Z@mX01>+e(X+zmeia7WSA4qv00@@%#t*u2 zf<0@#=Hi_P#9kM)(pl!W)^E%f&43}aF~mH?cU8|bBOHQyovV+p_(xt&DAjIlqKXvu z`TU^LqcC4E<0Uc)1F0Qq%HiuRX2;7`G5e^zt{n3RQ?}UYS{Zl{W-+-flrnZSmXbCn zuqqfPd`=LU%cIrEJGcJ;O3KnWQ&aHYjqZmMT1^xd_LANSVQeg--X@f^MYd(g`DVF} z)_E>Mr1M6w+$dye2`&sx(Bss}@UKAhX>}ef;7vzPzS5z-xfYKC>XM_%U|I1N7X%Oh zY~UPiRSoxoT28xVV`rpWh}%r_7WY(-o0jA;0bC@Fgk8FhwUyI))+92zX`<5k2@avb zZpXI#c2=@+XO*50h$=b` z@czmhl)ExaWJE+j8+YY-7?M&A?b+l^ufeu$2jNpB0VV=q5YnUuF8tuxEVfYaiy0;?x@T!g| zo@={M$gdO-6oNRs!rt*4;d8Q{Qc3wz>v#s4qQP-1If25-&l~dr$KBLaxvb*k zz=|*zpyeH@9l{l5uRRn>C$;lmSL^E5RW~?mdKR^SK?4kD8zr9+< z;{EPRLx}Mjs+>lgr~zzm?(S(%6I!K>-BIVkqV3r#!hezCe^LImKzxuMm+f0(G>GCu6c69B;=4y0c(6SuqU}qZ*%U* z9!aaqxe&(es!WVe&mGUpH89}aCsDt**Bah7ZcQ$4HG_aTdX#W-O1?3k#|EMgE??aD zM?gw3TL z*fm(8c%g>Q;uu;vtr^Tsk{y@=S0r>JpgRh?xG!71n}}v>rMFC2t3;8vGZZcuJ9=|< z#Zj`&4xaC)Ucv;{*Ak+-1)4Q61BF~S*#v>|H6Y;Ine_YFE?z$=WQUb9IZNPzST9h% zhoP=l<5;Ah;mqixCw77W^dPRs;73It#F$0(xpPmgw68=ppB`4rgy%!2{{R*nCi7RbKby@7Qw(F4k)Te{^LsR2DVk-+IA$ftGY zdbWG!j!f1x5Y5kH*)w9d4ORk;S!kBm*E(gLvSUTilq^~4ad3l_W7Si9p6yl+3HsI| zENG~T6;(i00{{Wod?;D0n%ubZPb)%vgDWD9yGIjggWr?xfr>6~b|xp%jCNE~#NZCJ z30Qedf3r@jC%DKUXRx6a40A-NBcQGMhbJF(Lg1WI=7`6;y%~;jSK-o&8w^(e0E(9K z-4Y5X@`0B0*mtfSbcEXFUL=58@eZR9*b9dv)IVNN!v(2Ws%g{?~sAskz)GF zN4n;^pO#3!h+99!AdF}9sN1|iNUE93lB{!(I|`EP(QzLS+{X>w+>9iQNfeRHSshPx zG$pj+M&ao-vw1MKSwvtN8=10k%m<)5S5zd70Cfs+pnTR)Yp?R1mr-ap9@(Jimjsez z(=Cf1R#Xaq5mE)|iiGeLKQGnsa^e7 zqu{?@947w&KtrJo_N*Dfp#X7I)wEvuHLPt|Mr$@5X(WOxdHB{GR&?(~M*$=Xj&VmQ zvA3C&A0qbI&%k+r6ZaaDo|M-&uY7XVFUl%Rzm{X_0scz?=jI@Jr1&|l z??#=d1l2-NB1t)?oeJRFYZ`o~VIABoenG}*k(+u^8?rEE>Ifs|DdTpT8t*3rLEV>H z>Oi)iCOWIa!~8NS{VAeOScHq50uJQ&r&fP!(q(1qC95+0%H&fG)bULv#2^w@6?5oB znZ_~luBt()x8@OoTK4%UZxPxp){%UtsD;=ZXY7prmCsY#haEPqlho0qvcHXU%+}K= z`IR`XdcZ1i^{!q&ca6isyG4o0Y{?H}U0ClJbm~*op^`k4Eta0%*oA_56x0PG=ghOEvQh6?*Jvp*}_u87Z37~6GtDbf{ z`~@`@InGbtML9clt612e%G)Px{>hG5c+v%0dbYPP@YVg^Ms98*wOs!IQGbf~_~b1# zPZ0JiMnB9XA9H`+rFy!@ZEG%=6a%N}w#^|O=9*C>=i;J3hx@e{oPnms0|(1f_ke0VF``lpRqhpIVEZk2U8-1k zhr{=rF|SGO3v9BTI@_Dd3nGFPlDN)0XKHZKcuQ8%_#08t?DYH9zPo9qH#YJ4(Od`* zxf-w|mn;Weus$_IO~CwV!i#ULdo+UEP`Htxcwd>YSe!Dh<7&S+7sW0njINb?G?vj> z!bE_(Oz2wP?tz#$JxNLoZ(<>K_g+=XUiMq4}1ZI)(K(Q0^71H z&$wK$bg8Uv&Ajn4G;CGXh6<2yK_0c#d^y3~8?A6sU&m)MU06#Ix^->kjhF|(CmhN* z9q5iU;9eGr5vp0ot*leHnA{jvXx=6To>a>#Y);_sOME=kv|R$q-u3k>=-BEB7>~W~zZyQJnE4q2X)PK^c)Ao@&H5%|bwK$d)L*TowB76<%6-)JG(H{S2zZVQ zfp>MKh^-M2saAKG^MnnB8+!Em)@yq9i+7`Ga6XX~G6_V280BmWarSwdG6^l{dL8H- zPiq9aOxoSu%-67LIm#T&yirB%o~!1vfH_y+ ze3C%*s>@!UKp49h8OQ|eDph-N3^ry#gRsZc)HhN~nNUe3yvZ5aS&)TejNlVd;yJ=m zspNrV0(KYVw9Iiv32OsMpnS**y}#40oEdz!<@9Ft^n zhhhL+b;-?iou09KrEvcM?hv+v_oAzLzU!FcZHaEUX54%QMm$NO%1e8sIP3=JKPq2xnCAG?1jcD+ zXo4_v9ye}dD(7H5F^-jMA=+3R6%brqlHaXwDJKLK} zi6DF8sU5inVG@CeSb)G2l3RU&?@6H4?sS1~acmMBn_GaqfpGlWFl>*wk5067T69{b zrwU1^TXHl}MrB287v$L$N4)G#+3so(b^~HmrnkEusz@|m4!pdQO(Hx004@Bq4RF|w zBE$j8BT`w#VZMLfy4B20{WB}3EfdW1U2+$dNm5IC_4ri24L?t`;oUb;vSMCGk}3K5 zmSFu#$c^@Kjj^^WD?bO`!LHxwvCQ$clBCTp(hxn;8wgk&WPGXC^8C#MdDjx(PYlK; zzH5*~hznzu-;^|Y>+c%L>XB>dd137~=IwrkY;*|>U2g&5+crV{6ULo?I%<|p8-3xO;1_HLhGNiXxVB3rQX_tgJrLp2oSWg)Rx=ofMM5e(<;ZBnI8U z+dF2ugN5|HXGu%AbzMm66EvZtnWIS9MoHyHl%$#N|{tA-5x?I^5{9+UO4+mj$)H zrj}Ai41j0Lc~3lnS+a0jBxaiUdq&kQW7J&4_UdhfHVJbo+)EP>OP+C@BQ_5&!kimS zOMH`k#~Nxj)_RMyRuan=jV=6bZ!1cX@?!}uakD?$;-b*UZm2?Jtv4_(*1@_H$&x;AeSed`DZ-1W_4K9WYfj|ovul#TV2@R z+rX)4(8&yuv!gK}h5=c37{JXsM@nbYxPw%>*Pygu4Xfy~+@!p!JoXNX94I89!+n!c zn_eR0Q=qS$t?j1VlbZ(&BqL#x%DD%=F;*?EnW;-8zr5}&?qiY$h@^I=BZ7JsF57%5 zwD3O)#@qqWQE_6F&>=Qh!K&5&~ZqnmNJ zT3;>%Y(;7dcr9T_V2vV;1{D!Ps*gYiO5CF{oOdIwBgznLT6b2?-6*y!53OtxMsZpy zdf?P_2~N4F6V{{iS>7(7E@D#KbT7&e%x_QY+KvM%dgi!rx+OyRo|pdJWi7~!RK&`G z4tgA%nt)gn@2}RbFBPrxrrAzEl2X6sANHzh#GZ0K6}5!#m7isqIH^faN=G$FEiH9h z{{UvR)76Q)Mz@gTBLVsMJ+aoK$6`h*UBg;m7wZW!Xini^WqAOZV#78-KJgxv)bxpj zSzDF><`Hh-EZoMKBHGCWPzp=Lx=oA`Y0zr2T-sP!K-SjsEPT>UAj30Y^iN83g8u-8 zHJt}kw2phx4ZfKHc!C8Hh*%zE&r(?A=9;ejJn<7$MO*ur9Z|WIO?-`lcH47F;_#P= zhd2KKi0M&tE*J}=xIK?5ovWeOhvBudW-vLX#+PiUHaWw|5IBM>ak{a*BDoWAWRYik zeM(S1PKtj@wByHmuY5n@i_R0%@2##cEpC0Lc;sIoxe3Um9F|qa9wTDNz|u& zZVqdl2qW2cJt#f6F}3Y2AQ43$v0Tt|wP#^kI5m>AR=2FhVWCn<10RiR01^!tcke(r zqPz4-Xn{%Y2Q)G-s+v5S17PHOiWI8CtN7~6&fu$i&TM&7+o4=;IeEr&{yL(oq;>m$ zXz=@6gQ9t0p6s^He+|20>PMRmBZC&??sWd8Mn%UO;jo*je(=n9X{$Q zhSY3$+M4L81yEg4!t;Ahfu^=|&1)K;qVk{0n^YDtg2xSLxR19%zt4T>o&lW8!xmXP z#?qlbCnSCbmoDi4O(R_0EfH*D8GJ8DOJs-1WjL5$(*KIw++6HJ!?&mE8me|BWnjsr%=c5D56)t~kI~~{^#p#E9^!b!I`!h?9LyMhhyzZ(9?TO`xrvTE z+i+AKEFe=4^!_EzifBT-< z#>d|U`hR$uWbpmf_;XJn(BE~5r9LVVc22wkM20^ZP{h^@e;O#0{9vOV4jKEPa;|WP#R;efm-D4EuiuPT$IV z&;%1P2^QqI1i&KJc!dHI5>%wUI+aW%DLqSfU*6Kgta;z?P4N}Q+r)oG0)2e=QIjV<>(EesGHI|H}|&#>Jx z$A31W+Wp-7%W)Bzzr6P`lljs~Bv#Tb_P~zrZ2tg_6Cd)?x^i;MszAWytnLOrF_9{EpFO=V{Hll~s^wIwS&$5OxJ$a)sQQ9;U+-dq}lDyI`tU{>jOp6#8`mJL1 zHUWty{{W;9xFKrbAN!`)nf}FklOiA9lJb%LJizwA<~TovR@_l%#F6-gr8TO>ac6lI zt4oE$hKtNVOoV`=_=7uS)q@+zbsMjDCzzAJbG|NM;&7Q@eI?qNM9em3QG!Xp8}Ev+FSzSi@Xt_tZDw!Yy7bYkjVQP# z7-PXiLaU7Q$rTduGxtTehq^_=+1$mcTJp&p?B!KfX+n?}zG|1Uznh6MWp^QajI&x! z=iUx?^4X77bJINz{}1r9$#a3?DfMa8CRE)_+ti{6W^irN!SXhVB8?$UH8) z;Ql7N@iC3Qu>_OaS=%#W*+6heA-zim9_d~4MN1Bu!5V}RX}UzZoKix!0!!E!`!mYi ztM4csIX4&^)f?g08*1DieId0XH_s%ABJMHN5Pd7EwA~v@;@t+}^qpC(FD{eJmL;9= zZVPi3IXf$!sy3j>izG_yL8;Q07e?pN)X`KLTz5NgRSC4?xwB~l72q|@VITwCxDGyu z*{0OAO&eI$JnL)w$nImB7LwXX@OBw1V%>xr@sV%BrIz zXFl;gD%K#*ns%6@e)?_Ypl#35Oz7D7T4i%cZRuz(q1%&0@oBa`KHgf=w~p z&b+O@cCSe3T{1j&g56i@u(NW*i<>}wN-B0F<2`AHf47lNGDrAs!?(`&O1@}ah+3!E-fKQlH%RgNXcBw zF$e5MPuWljC)D6o>DUY$@Tf;2Y@A=3YrWNFy*hrWEbleVt)G)BGOxH7-HfR{K-(v= z-ld!$qtA9UtBY9Vv+`q_?dJ!~EMh#W+?e-wI0T#;fZ2N_S{>G+x`QRubBN{B-XqB( zFx;z;v%bYht5d_>OIeb`Qq(LV4F#2vjT6fpq9V-ltDKF-dYrdT)mIZ~!(KK!g=-+| zhf@f?91ogL#8F&u+?N(p!)mvmy$sG{Vy?+52?GPZ**G}pMI^Mf(KL&~y12Z#g5i^v z@;hz(<_DP<%?EOGhV&W54~XuyEqeUxHwCTMcp5D_K^XvfO^^pJ=REjcqN%VF+1 z?}R%Ld(>|7dyW~tw!M;RFD15~+3oJ)IgV2n?aa^2NykB-U8!!ZbEn?fdwiEFbxlTT zCb_ltbpj#GaATAJ+^1v8Nvi!qM!OFrZF+b;ty}2e{?o&*(hbL=jap9DS8!a1WiU*V z22;wzm4V1TkEM0D0_zvr?vO8UIa!zmNkb_zpl0P~3IGl22HoqGG?59_^!1o2jjrJi z8AAf4z#xN=Yp}E(CqdDg=G#ZJTU&f17}PKYw*=w7RR_Xl!a0CHE}{2YzZ+4=#x=i& z?f$AkjE=M%deNEQwTzy%+FIcVK)}stjp$SpnsMfYgdA|0AsCbj_0){F2y$3`kIDo{739}sbd`R znZ!a@PH%WC5}=XjNT{^xBh3*Wii@<=EpDbUK_@)Go@jtP!yR^`rqyjNXAsRQM<(9m z93B1!p!_GVY1}(ucXe}Rs4k%}BsBKV8WY(=Ha=#z!8$y=O|8qTUuEKoPIk{nld$;; zW+Bf$~d_XbXaOCJPS|>*%JAt0H&-SO1Wj?!CP4RWKH#T~$ zxQ`Mfaslxe<`v9vLoA9eA!i(0o;<#e%Dmwjfn!PocoIMla(4B;i>#LI56#-Tx0QvwZ{{SXDeVWC| z6gD27m5^L~%G@AYZ@UA_JfjElqzH08H0LU18|6)j@#{zu8ow-WRZjP_tV`Mo;#z!2HE>e6W~hmOOojW&4gQNwqmgjM1$bJ?OQMe!Xe7M&1?i;f(zHEzD=EcWsZ8Dw>!}5EEVx{amhl zb0VF-wOx2$J{wYiob3~j#2T^n2_%WGUL_9VD4Z$pl2rZzx_n1##*ffaNAlW^-m z?xO1L)zaAS;czMqZ~LH4a~)V%nJUsYH=m?_K9n4aR-#bSs58* zT=MOmuth;5w9MTjkh?ZE+70Y!RLiH|$@VQS8|51x(v_zV>yM6II_v8hADuq88f&Mc z!n<`?{{YmQPW)NK4WIVHzuiS2rAew|`at@l@XaL2!hAy^$FQ*ZvX9o5rvvd5V6-tH z&+|w>Owt)Rhg^QQ^Y7@~zm+1BRn+Ckd)t=z%HQisvJZ9-x_u1;btPT_)=%1&-G9W# z^r1HcO&HADjkJEf{{S*767xwR_oR`&Y)|J!{HgR#e^~n<01`Gr!4ni}=x`&p6LLN2>dK^e9 z4|C(S{{WREMWaA4589oM56A&ijdF9T@GZoxkAF*sVgc^RueD?RMCQI+M>O7-8~#go z;r7%yYskw@6x790a1;!=}50`Beb=+ozJ-xWsk=lstbGE z8Y;?&!4p9zu)b9*uFmg%@yNiKecgrzdY+ViwQwwA&}>s9*`gPd1J}*EA^!mWnx!`B zc9LtF)wQ!YQ+IL%j(Q+w_n7 zh7Hb$^%LvI_gS&Nqn1(K;iKE1?3^v3E5tgKIp~_2ZT|q#kW(~3of_!+U0ePuB{)QL z#S?O!rjl|ye@ch_X{OR%Z7)zjGF4%eA5K>b{{USJ<97A`0PU4KT-~qD;XOp5wO$<~ z`J=bb(q>=MjL>xk)1XI)D!sMOoEg3B5T!xD-(!p(#+%mQDADEvK14VppvunejQoul zFFc(t_7N0Zw=>7@AGDmAZM)#~HP3Y;a2V?B*Yhi13E`79`wssA$#y@7{w2P-#ET8p zF%r7-vw#4Qw=M<&85aR+ z%;*8z1b|P-SCr*^Fb`4^F^v&uEO;PM1XYh!*hkd^;N0827fo=Uxv5?FgC)FCqph-{ zNF@Fgg&YFXHZ$+;J=3u0D(Bbi^h^62Ekx=q4zCzs`gXvDko~@3aht}#dT=m>3@4l*Kx(CTHaiMmrjlpuwB{MjAZ`+R3D9U zJ$n=IQyALT{{VzE?YX_Lp37UN$|ag99QQVzW`)=tyV@(opEmEqdm^#i7J@5yq-SPj z0L&O|{J8JyT;Xc0r2q$|b+;I6+D3)IjilW~bqj0w;Em;vnkG@s3bHeNMnE9qv%~)Y z3%G9ATG6k6cv@<0_x_3x)ayMJv{ea`MYW)>XtrLu) z<)x7`UV}vH7pR^1`l=%0ONs7u)R30Ek_9t4*syc_K6BlgKJMx` zr;X8WB6!J?ECc+<8ya7#@IH&fnufQ;nx&+s#c!kI~uNa%f2V#n@cn{ zIF8=jBDgCW$Qa}j2^k)nQ$HD6%cWSws@cyC&5g@@%@PQNQn2PRgw9AA*o~c=FsB_QuBz0fR#Z;8y0jy6&~{V#kGz(&stB$9IxQ zJQ@du9l78hF1tpRBDKgHMrZerz-^5EYL5NgsA}5cX;DO0?pvV;mfLc_Hz^JBuEpWb zEzfKR zkPJblD6fj&$ye$U0jAygom886>p-7{IGa$>WSGn?OkA>K9O6jT^N&sH1nj{`>s|fC z{txiq7V%ZqwW-}*;z;6OXNi_I{u=V-n1W7m+ZD>*Gg@#CiK^IGaI?ndD5dt_E@Lnb zND2!aj$wn4E2`*Sa~n1A<28?Tx_)z~E`qs-7XyZb0Io_(7b$Gg8;r|q>{nUx8* zjR%*X;p8(O-8R9l)(neabbx|Ds^Bh1HyFV;hZzI|xjoVRNo_5hG5bxt(cA4LaThG5 z+y*@0vE?VFZaeEcz8OgE;d3NYFSN?#T$Uh_%1Gu5kEUur#0Ku-(nnYf3ZQcZKWHyZ z`tMO)6i9B2o0JMc`JL(vxdWh3EbmtMBk4+m$Hws-6#BL!H?HQFh&i?>sJM^xu z@ciH1#i?pHtfEW#qm^L{OFp*1C*imll6mKIODk)-qR99Wo8dbKr#uwK2mo}Ek8VH=Bayf~|efFx)UDq8E zr@5J=lOFFgXa4|Vm0#Rl-d)^FZv)8kNbE`3S0_I69k!^>iNaUBYp)00nJZ6gp!Tx>d>>1TRo;wEVHJLXbD2pobsgO1e`%`~4NtT0=E zO^?MkP%^X0ki%h|fCtLCBaAqt$>L_Se;dlNn|Po=G7c3~^gkMqS@Cq*cAOz7votYs zuTWQPWcr$maP^jlscX8u*1IEx{vRe7f?39YAz5cLQ`#8nBbA`o16u84$s4Td_dIvR z5!>0YF>`XlnfoiifTW(ab~=t; z-6|{`bFK5d>U)mffl)E&7j{alID***vnJbJT93SKT%$C8P27ljq=bFOyAO#W9@VGH zHus(~eq$r@u2tfDe`Vqe`0>(aBkR30+oK`l*sCOJiH7*FlDFD5Dd2mfX~lYEnIktS zr{u>K5=Q1gPBV?^cAIhR*Y@*{vC6DIhc#i_u=<2CTO?`q3%wU`Htj+^DK)&SEJ(}I zlo9eHG=r$o-^#oDpD&~uNSXqrgYcQhXK zELMpCQb`4kXrI2Y)`_P~R*BkxMQM{H~ZAp<{JzHZAaTi}c|jE6pqg#KVx zNzBl>S6ul|)0#2Yum1O{i;pdaEN(|%ek1Y6ygypHHDnEG8)GCKe5$GA zsQI*ecFyT`z5P_xKAH$kMYw0rs`bYFtOAN2dnw)M&si%I#Q)HtA)@k0C9Rb{? z{XRnmv1j^I#FBZk70vF9R4&&AHplW3v5;r zD>1OAwF&H;^mp?0dj`)-sI&fIRu>;9Bvz7oOjrEFKc!YS?d8uC=Nzu5KO>s9IQ}yF zLb%_SbRN)9gV%K@{+dY< zFKz(txul#^s|DqPbQQWaOMM>FK>4YTVEvQ?W`sX(OJ?4TQ2{k^<27kVwCx z*^8dqZk)uQ^{$<=#n*?h5x#U(2Og^yKT77P!mLwrj$%en&lSBw+T#rm}xDFn*`UCaLJ1>~k10B?RsA2ciH;wfJ7Mbkmcer&2AJt!Y(>!{;&mdwq zJDut=tlmv|I++_hg8+JGdLE2fnViOeNMO`{h`Ov#!^3llA2HGqT6B$Nr|Q?oAd6#b z6Asc{We@)V%jY!9elsLZjB{GS{{RXF{VBs#X1CL9EisQYz0{u^pDi=;3P}0Wb>jwG zP5%J=vX8l#ewEiXw=1OnH&FI!=dPh^JcXZfpCTo=s>7I%ep@V_*mO_O(?*^TvFc0E zn=$_Y4AHmgMoBv+rD-_ovDy_U{{T%Cev|}Z9NK~p=8k2@z&3wMsOB2K^f&nxX|8Uf zFZH|mgmMye>qaC1vd+JEDg9`xl7*z@7*a`5oZ~;80U3^;8g1^)BM?_dv!6x`V%|uQRke)waF2cO+rJ$T;YGS8M3{ z{92usjqEcu)OM=TJ7cVzqa$v? z8@BwFugAPG#GFl{X^?3aZ*t6*-tys7E0!afumSnfE)msuPeaoz#fsfsaa41(e326* zSulE+(Yc5^^6$-zXXR1f3Upmdg|$w7O_twN zD6$CFRCbL)*d9`G+pTl4AS2~bl71pnt2NYuf%MBEMmuzyZWxF z@cV@1(KYyWSal0)>wQu=46Pcsxib!OFa`qWILkk1sWvsK8aP&5J@CzjO40hs67U1 z@$mi&G~gLEc=T(1LiHq_m3b4*kSkyS#2%aCxb?L*U=KA9OC*M+Z}h(jOJnE0VesQPMm`GB4T;{F z_>aVXIOF$CG3Ij=>=kTn5U7y$3>Pf_03%avEB1cWMV-Ch5$o0(5=xrzCn+ zvPTe(2Ph?Cftsv9syZ z$N`L3>beT7FR-GEU=itB1nspH=dE_7i=Gc2XfjEFH>*#Btf8AvOR3f*TS<$F*ku7Y zA~xn5vChgfRSbtC6)6C?Ku5pOr)!Aewwopxeq>bnDjtnWCpO*f+L64;Jd&y(+#1cu1Y1~E-{wuWs+{>IBvu$}D& zB~pY)jf~-xAJ(hR81Vw{gCM!Kdw03ho;IP>Jj(eq>h+RyRGFPvcd6o}o3bBsd;qe9@LsoOx%LzG=46!`|j++76pG-48p{Y$2Z3Hoela-W$GqwoE**z=P%iP9BBs+n*3(cf^a$e`P zwPh7^J>2M4;!ws#<>`-f^#`Wa9knsYg@Oerc}W8UBAlkYGI=b;m85m|3CFs-fw1dM z(YfZGBRe$N!5A4k{lcrwBV5;xc2i+O=1m)@51Ab&DZnGC71KToTdlT>sUXHZtw=b= za-(|YiBVCukT@76v5o7cyc(6{(zPyS<;B8s^%(_rHFx2&{{VO>@(OQ?LHsyAp%9reNU}Ro&-_G*fH9E zSeyM^d!@MAwLywSnj~?M7y<$7Lai0gppm^W@lpvmb5mdITF5@}QVdjgirbTiH6lA( zIs1i0F+LQZ?J7us@f+^Ayy@~O=Cq|FN-u{vpHogFOL>fr zuQ66e0ENeKj@8qJ`K^Pd#@ww52x6rI}#c~(`f0Q;e^TDog@e0_%#4^dsN1BMk z?!h(G+Wq#QX=OOOxQZ@hI1a!Qk3n4R;#$Eq<%H;YmRL4mb~xUr$gdm#K_q#o7ay_0 z=g;9AF_KIzBxmT^AAzeXGJDobfes+~u8qGmZ9nM8sl3rO z7IW6Ooy8V+p^m#!MubN61CvH?jL~G%*9jnZHKKkMym!R_=AOtth!&5oYeel@KN<$ymeD}u8P6*bnzr>ozq{@UByyo_kL>ST zzP-1KYfM^QUEEHJu*Gi|nIn6-I0qXJ^==6Kc$~|tAgURS`J3!lJX!E(5Z+@JrZMW| zFW_oRY2lsZfO+?Erhk z7**~DepO|?GBH+3`l{=%1!FxtXhgR;*a;9z^r$~}5!m|=%kamgHZ_J~P4mYuRrN#6pW z*cGvG$C;G_XQo*WbGO7*nB2knMI`cjq*~gt*|R7I4!O^!cdE0Dm7hdzUV?bpzC$DR zt4mP^NOb^QzbuIAyZfL4x85^Q4Qk!4bgQVBsfdyOAA9ty&Y(VapY)=0d|Vuc4oga- z&waa7e4`-Kh@_H?R!Jt;4Hbtd_2S}fhf!CQZS8y|AtawOOy>Up5I|~?y&uG1x~+W| zQnR$-%V)ip%7#QSa}ZAFBLe{XR5Fq)ZsB&AM^-FG`zp;(N-%Fya}NVW%3D;pe!D8? zr}${qy5IyqZvIb@8~#-;yRVhsWq-tI?xIehj+B*`6@Nj%{66T8A!ZDrhGcGpZP3z# z!CDHBcFj8VC6DH4PD=r;(7C{_cjfw4z^;#rg!DAq*kC8)7(bmTULMk89_^eXANp(l zl*cW*>{Mo#GzDxPyH&}>W6$A}AV0|i{p5eGOXkz`$Q6S{3IXaARC|e|SK;fxryxPh z2s>d&J-$^|NxVn1YNCh)`Qd!QxNVa^X5sVj$Q3oY(k*V^o=GNV#@T<<7#~WkJS(^> zq}>C$t-}8R#46}9^K|Qq(R6H@7B#}fa8-CFd=fd#G;ft%aZZhCZK2#wf%(y+AeP7( za5{Zyw@Y=F#xlN``BdMDVG?LJ(Xj)XEx*EZ`cxlChsw3(-|JU;d~w6_G*z3W4s_B_ zPkV_xZk(g%ics>9-Afm}Ev=<=3j8t&4mjYmeavq_{eAdVD~nEG<>RKX2%GLPnw$KFj{ULoEK zI~nblX1Taz{{RY{nxvV`F-&06SKO@ar^8UcR5`UMA7%944T6P!qC zzq(1PU3+BfAU@*eIKC0ac~|i3NoL((^bryN02x267q^oaz_;mJkpBPzz<|)vw3V+ zIOYd9^ait&ufsLCfGiuJQf;@wrf(s1GaF5@`$7-Kr_q!K;Ee$e;?ZUzbIPRqxdzYFWDdl&J9xoJ#< z^D`d4_xjgn@Xvt07@HV1Yl~ZuOR8YqH!fX*sP{lSlZrdVJ{|DifjC=ClJiTphT2_L zB`hNI3rrz)i<>)yETfwptBaFAr%##S9-L$kX=~UT8-Hck$M~q?v65QgY&h@zRa2w* z=N7G`U0k(|(n)HnB=Yd&WD(3zk&rRity0`n+($m5+Qy}DZ&u+WWSk>M$s6RNn54rZ zp2u}3p*7xIC*k)B>e>~J^}d^@y4*yPOuV61VIaw1Q*HCmil{$o4K{rrg!KOaBH0Wh zQ;IKWMZrkCw`Ga{0JF?8xZB}J@XXk_-Cj8Hx_5-xouIw%1cBrgPOmfP!gq<1T;^|0 zZ30ps0fvQfd!*i5-$ZptuGn4MzuGZM3`(jFHryQ4WA=(gwebetMUTpBjW#}YI~>OB zfRKIz8Sjc?@Slfu?jM^);ybN4`8WE#sJ4-rLX}qB?nd7CF!d`^588qsD~$Aeh5rD1 zV=^{zoX06AIR5=@^r%BVFO|*7@tH2aFO-41cJf)7vbp^dBIv^lSi$`HRD#@W38MX| z41x2eaXH363fDb)Q*puME;-o_92ETyxqD@)rlV;)+ucVmn;emzQjeU1JuyUTI^LtH z-96Rq-1jrN%SkJ=jDD<5F-ZC8p0q)ex2;Yv;nW;h-BnjsR1V9O0yUcQUGMuZT(RLj zS(&}x-XIVE09Gou{i-iyekstQ{{VKHY>dA)kc0UOr8q~$E-Bz`KIX?rxQ;mPC0QSy zC44X#+n5?*;;uO2J~g_E<5|2nF9Nc~?kWTfazF|PrEu7P4)qv5Et9A@k&JC_Ejqq! z#c;YDo~wx`LvA>GjM`cVuOn%gN^!qREu{_V@}kx<2Q-eU@IPzrAFTzh;DnDUH(svz zZ2d8T_}6(Pplr}weLv-MOpo}8Z@SZNMmnC=c5qggWx|$Mmz+TqO+KSw@mbhOlPOto z{8FRrZIYbWC#a~00nH=Du3cHh9nP<5rEbg0KUClVCR|vF;ZkBv~4N?c5sXNDHrmFL0UW)e!0v{{Rd) z&cwbp z>H)^|?rU3&02}F7ah~&-(s3W_{adLod)7`FJdAZ0Pv(mbA z!ARLGHFJ_xt|BA+rmuWD2+bRE3NMM=AC5QR?5_}URZocARj+7I3_2XqPj=`Xti_|; zJaGbf=W>niqK<(`oUe&U%Ry<59?c4skj#T#XiuncfP^se`@TnOfh zh3Fh(s%yMwG%iZ%gNGLG6vD8PgvEUEuwl#x**z(*OyZs`)%=V5HkNH3TN~*f>RWgq zD)FNT`4wblKJecntSv80y_a9Q)i3m`TWMvmOHVQ@wx2PhmkG#YKn7Uk&?ex18-~*1 zEHsN4CooEoy2KZeol1j{HtX7zJGvn7I|87VJY%c3g;3v5axJxciw5>PiRFhkGJ&3T z2i+ZUhQ&s-zYzGE_gc{7ywohAvw}nW%ah1nVafd5vdT{X0M!DnT?2;y0Cw<(o1tAf zX1B7A8D1G0Gt39PQO7F{`W=lh#o_ciXAo(+hLLkUv?AhZwM2Wl?uEs)IN3@~Mfk~)IA2vSkiN?&HU>^H>E5K( z7vnsC;eAtl5o-IM+f-9;6aAC0{O$K#MRv%Gh~y=3H!FkpR9^l!V4)eYoyT9TORjAp zafswBK_#=+k*r7*0vO}IGxV-kOSK)yTEJPlObM!88<_4ge8|ED-}=2OT`!2dPbIL0 zEA1nnY>(-*t>FiDjH05ulhGCJKryJ&vX1I&;QMwIaYA0k>t-hhH-l@2i+nK%M zNhIguYEj45{zj3faw`Raf((wtZHjr(ELJjy9S@}_q+@g;3`z4b{8E0h#4Dyq`ZboccsoWLNUJYKX+9ln- zPGP#q`8tpEtD!Nr4@%~52=%Q$PrKA&y1Ir0k|bc#I6z91-2CeAZZqLXe%7^OH~#?V zDg3KGb`dM6Y*zL>j4(3D^5siIC(Bn zPaU;0_B5+y`MV$1kvEPUK-uN6vR_Q|pVpUyCz5Z)zz^pBOQmjO6I;z0{&?9>)MB7q zNnwAiaNdtCocA{K#8f2K=MTEFkVs`9ZM{f0+Cm~g9%%=d@;7%XoS-r9 z)}0$jySV=V&T3aOjD3V}B|hZFMRKH`DDlLA58jNp{;X)fkf!-K{{W0-9`>_$gXsLf zm0c3BGy`X4RLMtbU4w6=Y1U+zZKGE1+_@*_O&Ubs+npTes0Z(-j+;9O9%v=EM0en)ICIPKs~dvm<+Zy{{ZM}KRm>z580;!j!PkLr z?`?OVh6AIg-+m6ce6K~?;#BPHX)ll`PCQ41s8A0|43_IrMmo!Gf717U~aJAM?h<}wE$ zBxCN#q-nn}$pabrR}4q>Tdi#cv|ym)qYu}5$)z9wGv9xm00ZRqI3ypfCoD<=4&!PP z-PEmdYB@+g?tVRf6!WBBPhoQn)Gf&@POOdSSG`B=%DlMg>r#6--ZhF(EIO9u8368n ze}z|>qNwmyh)Hv-c3z@zdR+0JgZ8l`-p@7T+J=@ga)oAIW>eH043A2#KWcp)tT+dT zG_;;uz}!U`R-E%WRJD_4J-iK1b-KBSJ7 z*Zvb9rS(pcBPpzV9$a|c!pT1CJmk&PF!ST0T-N}=Jg;E5rDP(FSI9Id^xLUaGT@Ez z?*L9Z;1j+nHrFS*};r&hbJya%yjxuZEZZhWA4nVS&8d`Nrklh-41u# z6$?6!1g<3HwukB9DIL=Kgg^m|>pkkq)RK}$D1z9|X;-sKNEqeG#!VF^wCXZYesy8U7aQ|4U<_5Ct7#V( zx_n$pnseAstux0hw=b5GO$i1`VFz%JoyIU5II5Our_$En$mfn#WR;(xS6$E#mtUP* zwm1As#ZRVBu4*#fyimA?HUWIKkd6J&Hz7rEpA}@6wmg`fAA(6~Hgz}+>W8ZBz8S}K zb3Yzdzr+Jk6|lXNpAG2xv^VqLUR(PzHK>X>{J_Px2b&5=9V#WqmQ$TV&f!-vlgLhY zQa#{)wR+2SFwm?UPl`xUl%%Ry^AolYTA|P~hD1_4G&kj{ z0dzSygYlTLmw%cKlBpgBo(I;o4j=wTX?on6 zP54-DtuCaB<2$OD7^x%GPimELe+Fr~&lGCY-s)n`-r7Gk0LL_p>-KVUfstC{9u+}% zCZ}hpO{qm8CQ~6MO!9_i1ocox=hC`Xn53D}f=P@E+hJ>k$aCXqaiOY50p?Uz+x@D3 zQ9MwpL^+s_pl5NPT+)bzjG8>RGF>{|nGs^P^2t_D=4Nts-?l0#BSvIzEVd8Fw@Pwn zm)YZD#HfB=UGST9`q9Y9!w9R`{nKL0A(4ja+&}h}B%{nuY;u?5@!3Fj|#5w-AVd;wECwvT(U2EV@sduaCnzZ*byv(-|sugRli(0N~afR#p?%y8zY5lSmn?+O{fy@gK&>IBNE7Cq#xTtJse$ z^GTBwP5n>?Ihc3sDtMxjcZRT8`yeh?!IAx;qcF1}QOe=40r-qjm=(hkc+uiYN+o;o z8n)pLv_VMtWpj$S{5$crHT&3fy>=*|xtN89;xI&R$D*(#;GV~&T9>BJ8#Qb|9gU_g z9!sG+R&86X?^I}}K{XiTJpTaUeNzA*_Gv#Vlo3&$E>AOuucQ97L}Ra7j$!+!`zd4m ziQsOza>%rDD|9*7)NW~JXGOX6ueGL$;bA|`}eJ4NNC+>H=Yu1W+$#k#)XrL2*K$>?@g%r zsTTQ&6~1cF-?a;BV&spa22W929jgroy%;D_xix}=lUo_bNmqpzyh|YF}Thtz)I0TblVg#q@2;1-i68!P3h7u^g!j`rEipaQH4kq zgl$TKVpath%?FTm?_2ID&ZDJ0CJsRe25wI8qP9Q>P2b$;9^qd_9Veox{^4Qe=h)VsX}-bT;JTt9|yC)=)wI&h?`3OlR3r zfa#ojs2_@7?A%jxKmP#1!y^3fRDL3<)!NvO;zd7!6>|8{yt<{FfREza#v2`d#&SP8 zrx1S$$H>;6F7Pn<3Q*2JeIfI5#@auqqTB2p`-(OH0HZ%jDUM?_bN*L*0-8QWpp%r_ zvk%6eU6+*7+RKP8?QeKi8*7;%aV67|jg5do`qgparypEsy4|b!&v#)1o@p2z-yd1wo4Qbr;->V&5Zs{HroDck#z1A;v2*5 z5LigD7bRKnn`f|WSE1e^*uJ;mt>#3Z!_c6*MI#|ix-6%^_G#CL{0gT{NQMrmd z;2u>5P&&3Tx5BTxeiG88(w9to0QPTeZ5}sV^FztWhUwIGpv(A*Ua6IiT^m^(HX2)Z zM{Vs%jfIQT<9~-Mp7)SnU{#IRjxfuo&WSX|0EGl>Bvv4d^LvDUHvK6}YT9fu294R} z@|G~I8O{ORfw%+fUH7m4$etRccQ?zb>ed$MjNv@QkSGW2pk&TBz#VFayZxNBm*+N` z)!aRKOwpvje=j9j5_ESEB+8Y$@uzR(tbW$cA;v6d-RrCVS32EmaY;079Gu6^EzISZ zpvO*LQGxIT(IZib?ij7qhnfafkd}1~zA#v1C7_OHeq2o^rB!+NW;jylM>mpByGNXBG@#ural=&U&z?UUv zVppeM`_hkZ62!54Q^MSlv&a;ak(`YDcBt31Oxet1{Nk}>o<_n)lhpg*V0=$O zQyzf9xtMv~D8KnE?jSY}-epP#qiD`1l14!jxmDyOxFBO;)1?;m)x#AGUyjC9zZwP>FPwa82P`gC|oia!KYSD(!%IhW)FZILCp%@a~w?PGUxRRZ$R= z%E$SMI}bxuU5p-e%EKVTG>Dk^=b_$Y#UDS@s zWFP~}$PPE&xd)1tJuiwin>B1Dwe`eU2sa4jK*&3aCqcKh)o)(Fxeak|Ad8uQ-YDix z^Xf5IIzL03r^eq7O>7_?+vmTUgQ#`?0K~b?b7}1)ST)D8yll8@g{?HbV^mHcS)^uV zh0uQhglrsw3m=9t>rj}uyxZN$40lnFBw-{`l#yf@Ad}PL4OFRdkKy@@B0p*{2+1C! zJ!s{YE>Hs>wUdSHKDDij(evVyA@V)aiCt|Q4K4Cmxm`;ZQ4WwAV;kP~eA0`Hh+gvI zSQC;amk6i%S3mZpa!d>{j2v=|XR*%z0R5?_%!C4Y$v@ri_t3qr7XehiFguKUwPIX3 zqhT&-0+T_R8{}XP1lm_A$obb-e$OO+=GHOIwbWP#ZGu-N`Gc!;$j{2VAHe7#hR;|K zpW(c*GLKJmkGigOENNXM`Oc`k08fbH)0C%sYA_?g7_3dUhz^PHIOTE-7LB6^f?xdi&u zTZpW0G~OW8?C&{*@ZHKJC#gKd^L={M>%u+@(>U9R=e5+HUuU(oGnnH%rcxbOl%B(V z@x65s!HtcMAEa#CC%H|kg($v{qwz-_YLUTj=iW~v@|mWQnN*Nl-geG58OK^dt!cL$ zH?H1kuQI&WGnm>)@&_{SmCpToS9a*Sb(WcDqT1QOkV77)c&dmn00Lk>dk*!*o+X@d z{{RsB`+Stx`6hXs&;V!~ebNpl>~K}h;YW-5i|Q8oCcQbhj&dWnx^wTVo{H!Bf$5XI zb#cXcpTkyHT9*)McDBHoX1s}49Y?*Aew}O5?EV#<)gg{4T3P@u2Et%$m9tSUH+4=I z)JqTtki#V44DFI?SDK4)g2yKh-K2pz8F0bIRDFxsw>lpZYY|$<9PIEU zv8i-Aa#+MXrWfbhi<#vsuer9u$#Ip?K)+l2fM`fx@nh6`-CF+?V z4z#fs9J^2o;kF$&rO2Gi&5o6njJnaNrvn(HLX)=LchAPOfT+*Hfpu_}w(m13VuK+^ zbLmfeCC+-H@Do_oyY*f@#cvW0(w&rYdK|v(Is>T}wC$^6$z!3~V#r zpwEC8@vTi)8-0S$EYTx}stE$N4F}S&8Wi?W$6f0MYiw2uNh|=Gkm>v>#Colfy|L3S zZf(PqGDL;&$}&a<{po;Ub*_%^kHl^r(6qCoYL3>V+&q!o5zQIr0AaDZ^y|{BLe{<7 zT7T@M! zU8Seq+3Hr2UD?kZ@Jce0Av8OOGyM?nwhN z$o@1q+o>m?9qKK_JSD_jFFHf3*hy;AXONN^UmbZ_Ne8WZHGSB+KW^d$Khk+N zsiTG+#VT)zSa%qs~lQhlNF=f-bVvU?d^&hHI5)hF*(7>0;JYn3_y6U z(@CFIV{dt-HT|9-@@_5y{{Xo$NPmX^027f!+-VN0p*ihC~Dq=LDTfEIn(X6 zeGgR9tr|q~?PUu*vp8>b7L-PXSl~7W0H+@vt@Jw%Jh`>gZ9SFZjv+i~k;ew{sb4Kn z4fpqn>S{v+ubKy7t@Uym6AXVamf@LfQs@rBal?q7vrM#WmX zHMW6g!MZlFscES{FBJ%`8<~U6Y_JDt@zWWp=ZHK%Z^Sws&k^wcw{JHM>Gx5n)6&@4 zi(up~5Csb(4sNG>Qt$}`+Fmdnmo}6=XtSE^?kmx_Q-*9c8##1qYuyrkE6viymYim| z2b2?YE%5*@7#xh9v9)obLNGH!Bt@0p!YHK=CvFjEr3I+cxa@bJH>TpCa8uaWgpNgF zxg_9?s>|VWd0PhxA7VNafw8LAOprjSpA6hw`MWO#RPs$Q8#@(m9N8mo z6}M;_IF)+u^6GQao%E*(#M)~g=2=tk8T~1e!<*UFoB-U!;d%m1INP@_yQLiO?HK$k zVmfv^PoP-;0GA}u?wCAhfGcT?y#kaU;Qs*cRH}bPC-+C@D*5r6EZAwX`b{X$%rE*? z3mNxVda12kQTwgCC~|g`tsMDBn;x9@SG`aG~z5hubfrJ01xkF znBV{b-nfs6v*YRbY%ko%@YaFK={gn+nfVTDXa+F2lDW?A10tibZhtLMXSXQXcldOs z2Nx>z%2VRV^PV$GkJQrC~)Ods^z`E7L>a zz0C)Lnxuh|KxqRKxjwo0(kTKi9{^+;(#G+~=vM@QeRe%7Q=>9-fsmm_eLGa(QRPKP zgnA6RvFJws031`I&4t2{2KisYno&SS?16tXstrDvni!hQqGTD?h7ri5ZL=fr|IJ$L4VTAxn*s zj>$jnW@Bhr4z1Tv%KBZ&#Iv_wvn9jh{w5>u-lNx?J;S<_;(ObkLVu%=P$;B&5g7-6 zol}th(_S1(-^3cEd*^$6=js}l$NNHfVK>{(gr+h(<@aDmi+TiIW zXq=vrAfq$~(@+Wfj(j2DPAAadwzylnYg<{Gbrz11`@u-&a>~VyJ$I_1{{Usa4U*2? zmsHi`na~#gBqU_-gYIV|H7wLTVDQ@hDAM0tw?%1CNL?99pgAN41AVbiRz4>9X>%ff z`1O#H27JeqM!#_+R=YC(C}6WTRr<950C1o<-3`D~G0pQ%3aGmMm$+6HLYnpXVv0y8 zkAhA?2X3HK2Cw@%`!q-`xPbXBB)rJh#YhS^ISua|?Sr?abOZ740NuQ0HM;`MFEbHy z$}pgTupP9B=jG+L6fNW`P0;zk)cBLuSnx20Q$sC+_P-EzuDlcU@EAvk?0 ztvVRN>K*?8wL@s$A07g_T}|)ezY#Yh!1lxj^CNOM<~;!4=U22^+j~1o*Q6!P5xfFR zPDta6lr)@&oP+?8zBlbu_Y-k1u(HaNbHNUwZb2jx%2`)&$}xeS^!>ydn(AiDPPw&^ zS~b)KE+8awsUb?f+YRd8iQUxkWSm@&-&Y$B)Pd!L0(M2S8L%AkpuRKQMR~)J&l`e| za~msQ@3AA(txy_bd77S?bjk;xa{wc;D%__Z6O5moUYbJX;xgpUx!)>-*$orc}gEMb~Q zK7bFuQ@;U5_3Nml;tg4>rBQDBg~^Kp-6&){xW{aCrugn;7|9<#^o~Vf;ddRz+hU3L zci-@>Mm_pR%yu4YImNn((mC=@qUFH^1S8kwMy<=tR22YZ^rmyL8`6tir5_M!q%JKs zN!c7u0!EN4bm;C_a^&>Ib|38VckNm(rVj5Ekt2LS2b7Pcak;Lw{hC`kcD_9>A^!lB z)y|0LHc0?G5G@B+aC2j^y_zehd)7DEt&QtMWLHEM7kX7c8+cE{+-a#>YE$`;+(tQO z@`zD7kFp%#;Ez$hHmEC&E5qx_Ev$@sG=+IQ&tQ2x#m;w`%#6U1R~u_u_?kqILykbK zLbBh*xX#3aHu+H+Ca!DylJb(rSys_?LqCcZxO3%}p+~OFN6X zOp@FCD$R#Ic}QhA`PGr7T=;XWXd2fM+h~atdPJ8iD#Aj$2p5}~c^C{g^3>-};vG8I zgXH2fVRZ$hc829+cUdK9xp{#HnX#WjXd{w%4aF%NSDLF78Nk!z+wP)X8u)9caI~#{ zEvECz6-lnSeB3u)R9uL``If7kbf{hL9cdbW4{18w(OmmJsV%f{qNKqG3aB^V@n9M$#Wowy#(>T(Im`I@6{ zAU;`eKFwZ;+XAH~(vW+k8Q!-+280brnG14jW36EO>wD&iB)5@`=wltI9KRY6>DG*L zg>`rA`Ks!7cDkjE*9GkD1YSf$4{@X{TL-QVI#C`uac2~0dZmSxjr6v*b6a_z!90x4 ztU(3F_#16YKWCdlnhvdWf8Jj#W91qH{{U4P`$K8zHi4yI;0L$8F>lnYs7c4wMQQ@? z!&p1gra%+@S2jt-97S`JHm`o)JBbhLOtQ+;Id@{joRUsS&vQTeO!1 zZ9?IwQoC%p>xZ-}?P^^yb%`L=Ew7cJo>)gUtL1t!e)pj3_|ilE4OEPoG~YT@rr^kQI51S z3m=H06TEp8-V-@ihZp#dd&H3Fwy@eqXKSPHY@$b%%N%8$+~oA8?l|MyjySp(S6W`1 zZE)fvHN-Kun<ot}xd4RxL_BHfZBr zM%ck{8Z~}oIT#$>4)v`cjP;!dO4W4B84^2vQYDV*N(L;T5rA7b*^f$$h4)G6S`f2j zfN|W?4tM|r?rTXUOSG;%;$0g|{o7}A7`0o0JZU5`&E?7lIpgycxm)5XC6^mba(2Q@mpkM+9XnaT2CJbe7MN4&_IpR%v>ek}=>^Ze^ z_UMsE5=P8J76^(5F(Y%-)@vMh#k@moEp;tg^6K4KFosD9j1kcC^xC3@PH+LwVT_uQ z>Kq@%Iz@=SztQjQt&0WoWPz1IJ&7Y~LGpT}TESZc-ulL-)=Oq?=QhJ9$uc*WpYHUg z&ZdXRanRGR_2W4Cj8#cm3wP{QmO8K5 zTQ-Hc0VmxV+Lj3nT8^6_?R0>jKz5{dqcMzn(6t8Sju`S50`WADhB*K0d_px36M9TIN`fPyO|+EHUyF z83b#!i@E{uG@di=$RFm*MifGMWx>2RVZZBYnZe(!3=B~%o^)M{CuERh$>D?^AJIBcj5X2SDLmIR&>zGpZ?*x>JiJt?KE zWSJYw9OV}n#^m?KT7DvG+D4{yX)WYg653f6D)Gn}`lTvnz$ zl1T$z=4p2J7G_p6BFHRbwKP>ZBD961V57h3PVvJf&B2XTna?p8>T$WP&JkxV9>f6I zA7>}w+Mo0_jddG&!5ra^2STmbk6I^gR00xBSfwoC`w1>AESk+4M}}8vz|P>2f=)a1 zt6x&otgke6)69~4ZLp5!TX_@%6mk-seF-@Nn0RK|Z8uq$%OJ-i46j0fj@UgZCa&)f ziTbQ;*%#Uze7_S2R{sG0b!6j@3j5N(8;nCp+;EV-2k^+q$GiTN!FyuypE54}R-}v; zRRkTqdSHqz;Br5t&(KzJYP1|efZZ(j5wshra0W=&P-5UMMq~vpVFdpGSU2gKk>4sQ zMF4%Fnwx3k_%Zy2O#va=LD^Hw#$?p@-GQ>Nt$ZfpJF|$Vvn2G(u+RK81L7Sf?}jyL zwA=nsJV8k)d6b431RCr;22iZOFqY@G?n`W(-H-|j7D>WCm8xsPiZ0rW{8eql_hbXh^uo_u@-L} zcCv&+AZG$K&PLsRJ`~q?3&`BfBfBbq3o$qYpdNsF3d)DAI!ZblN7UN2H^W{K`Enjl zmXNEsA(m$HV%psB(&@zy%=56l`bsq|=9Wx^;^A^TI1ON_u ziWFDcgiPRE%e!yy6TjA@%_lNgWDNksY+pO87!f;k7y_$_B#rdjh+vK0Zd70ZCnOP(^T8&hX{>8LQxS5_jC-auU_N}n^`z&B zwIs$or6BIYH5vM1v<^;0<+mGtTH8|05SX=_y+glb(PhB8)%}9q0Lmo{O0WQXr)}~n z1aV(!g@f4nryEPiNf_=3sj~4_x?o=};2e?+EQyZ4%aQm~JiJe@i5N88j0P|wMaF&@ z6=%kg<+R3+FsS%B5fVWL`;`~G(zTspDQ?$KxG0C-b&TzS-)-t8>~eaHXY;ELZA(+U zjKw|N&a84nNW>f-<2a^SVaeP82V4rj8;BdIOCEQ9DBD;_f0<}W1Hjp056d+q5r!c0 z{h$pdx``PVY<8n_$rO`Yr28h$ZHVn%U;8qV>^wj}_2B;im8+LywO3UDZ;Tr1U)i=J zZ66WDz=P)7F!>PGd!!nj&GQPkQ327k`7WeWzAFgE^`VO1Yo!Yek_zX8;WY9(o9!P* zy=b*L?vhlO+04L+Fpxhau)@HtUz_#0tl(o@K%|taK4qI z>M3;{t)y`)Tcy#%h{q^dSpsv8{RZ_rWyu@Rc}_a!l_4)Y-6~UxJT5I^r$eD!Uio&q zrL^l~E!j5FMvayzuaXD{VVb*%9eU6)fG9$oCndx*c?G;}Q64yW;^Et;kxMG_Gzs4lg`acTTrr%Q2dEEc!z zJZ|k9G6GO?q7H1FcE}%Ech@c3hktk6TKTt;JafimxCD~LgZ-e&57LS$WNDD;{adbX zTwHmXj=?9*;e3bLN-|D5Z%ScM1p@+&i*B{WFGWY~v8^rv&1Ob3_g0DJKMG0rP=63? z4aSKz)R@95svPv*x%ft22>=~czbffoDbnZEboXat63}8~tcNVvJI4 zsdd-v`F{+YIjGt54>B9?FpuoWfCK*k38~MBz8>50<(w*R?L{*SNSxlGf%gE@e)m2O)qxaa~O>i{2f>7-rT35&;U3O2_1IxCXT0 za~}w4J*cWu2Z<~TRep#2JvT9ZXH^*Jv05&3@h;==#aKFDf!qtF+%44N=ILVhnJ#5t zD{kxpuEXMSOnTRkoH=K1-@2_XFK0Om<_{(@@g(G*mMfk3r^G%e;^!k#zF}@oR@N+} zBm5(;%;uQ>9x<~)DZrWhnq4kDS+Kd|y%&cxRgHAjxG>E+s0$(FAyObV2pb#stFKwJ zlTp$&3nU;t)tu0&JpqvljQ#cJp8}A0*FfJG)NRQ>;}z(g)%}%(es$H%Hs}UR%OawW zs}L&0G8q`+c2LN`*8mrow@^)Kb1l51l1QDA*RBej5%8OSs+PtJkcHG#cFLq$jht+3e9L5|}%qlxS& zfz;#gpzet*NsmE;in}!52=A^hthAfWX2Q={zO@$?`g;i^ZbH1kO6oaLh#L*+le3kr zZlIWZ!Z}g-eR)oCT_vdahryHa^|u^aO{fc`wD+{;w_Z~+#A8rp=KwDI;2OIKY2`yM zp~8i5w*f`2=zLv$cXKVY`US9%MaT$u0n00A82cC>8Ye^Gt2>??mx%R!MA>P}b}eF9 z;q#}smmI_*mPG&#tWRUL8^gS9Yp3wf99ilQESK8sQ29=(3bcXPxntWr)Uwx&xN7gi zt8Nz6Ep-)=%Jr^ouB}XGEaZ|HIT#pnHuzP5Vim%J=G`UZ9}jMLXH>DbvXX5|-u}ir zyIGdpqcn1MC<|bY`}d`M55ru%Wuw8bX?H@}=2umYOL+*9!X8|%GRhkTfbB{3j}o=3 z&0Z^=ChGG{g4;}kPPbK;_?|>62foSxEW~8sQJg8_HmRd=PMxdjmlt}BcBWusdD)v2 zAx7mcNC$d0i1l5eaF8^qpB?bpX`BqNai!Q#sl}_hoBb{XTX^lj$0W@NRSsDDs&}IG zeglHjg*06<&rMmlhFcjmeL_PgA-A>uRA9s}ef#879;L?m29v|O)`!E*)2Yg~cQAgSADo1#FuKOtM zN<_ElH$(NBWocn3{H87E00nJX~)4k{X)}Hj(66Q4L&Iy8%r|# z_pd78B1GQlB;(#BVyoRFj;^%69O4}u#FGtVMdnQGd634%i5|S!-!xwg@fQ#1GTYu< zX!2j(+so!gB)R0b$onOuRpvOxe%1{Iuo1d$=|)aRVDmO(4T~(#>sm zbrcJ3w=B+x3l$6i?xPhW;7<&Fua9)g8>_88`Uqn;w?4-@+^?4le@1ybvB1Zns;h}O zr%~dKZu?igC?~v-Gpt~$C;$aj1e1UUH>RjH8;fp#CPz+n-rZB-zEI55?<

+f?mSKeYr%Ba0(j4$<_D@D@h5&Jfi9LWd(hGR4HvpLS>pG;Hoc#W#s z=-0YlnQddG+g~p&*tLj0DWNscBkK zu+g+;cz-q3B*5URYm4$#HRW?bh=y1ekUO<0x{V zHagW&pmD~f!@4fJrCP&nBpSpk6y|8l6;%fXHyA$mQ<_bt@xK!3T4cI@pQuY`ZzfEO z01>lis4kQ7G&WECFoJpuXj+JR8)a<7Uqh;Hv zJpibthY4EsFrt@eJAp?xAkE5#2$_DMsaR9ZDWn>~KwRIgq-1r?4LTeHTxO zGh&T|-s5!{z2Hkt2?FZ+<)l)L{FoHZ-+>=~Dm^{73B*S%nvDL0Cm<*MLafH{rq1v) z>3aNw%skk;RuU3==1B9C@x>v!@N14|VdPy|Oc$puz(U_XV6`i-q-YTf-~scq*l9$%M*8)KN@_r^}t=c(}L{t(g*rFt8p$!bRN+~oVb ztUG6~psS-n{hG8}Ns?W6UzY441+DE<%Lm|H@^SJ2(SNjLa5o0&b~cctHkxY%f+g&v zfO312wMOofJP|a|4R0Ww)Zersna-i}8zQ(+UK7;i)h)F9=?aNvi!yS62Qsk-1GOK= z2rT&Xg)Yv^a|>Is-+p3OzyAPIp}rel1ENNxjKOy#d!Eb#j=wWf{{R*<4w=Kcnhou* zv7CC2asL1%SuF+vrDT@YpJI|N+y`RgAa6jH?%h`+RO#zTF7(}c&id@bBvQg>kjAVt z?vs`LDFl}qssI|s(4S6BS28jqbBGRZ#P?echDLx(9k}vET-`w|qm{uq=~In4*`SZ) zD!+NPAlYpq(Dw%v;U2%LK)^1X0O^4L0QRZjEDyay?yE_tiqh}0yYxpOsn0`HSB*K7 zi_07l>{j4^#ZoIiG}SF}n-tsn&PU`bxZ_=B<6G9+dC?JsF|R7;7z1v#sWwDT#n9JT zu#2SQNbK-*>=OKa6=QHPjuEq&bXdG z(pO#hcC>1)6@jP;x$u&f`S(f@^1yzQ=B& zv0x2g0*AVzldac9M?mu=e2jnq-`BorM0UYf?14*dZ4r^#iRLcb4}r(&LY5*32cWC% zaJpHtM(rZfd==(gk<14+{dVt3n%*048!gMj8fPGA(y5O;A7J@w1wN4`byot0)~-DI;KW<17nW(_|?%$p$5;A&n7-l zQ9|IHZJ&?pM9XGEd4+)IC%5J(qVobqaqn-Rm;I>t+C#IBWji+b+NA-*brB7A#WaDO zss2eBeuv&4ooebeDS!q}^sCtAOPL}B7I@Xv^aqi#pSh_m^|bMB=aluq{AyO6)Gu$! zc1_U+SM=OhSNI3X0$$%|rOpitTtiK)BSV0o_L=5fl9+t@c;t-25w@qWz%wnBX>*r!n{mNBu^- zOm3Z(mcsbiZ3e8GSQ1SfW}JI2isH^9)N}>0YfUbD)t>4&rD%X+ihUH3l6nr+y;E1# zB;mPlbgeyw`#{eft2$dIyhBeX82qYPx;BwY1O3^TzG&6VQ;^+dXR5 z)h%?5CtQzQxz;Z&*5F4Ng=A)mPcI}40N&}(K~hbK{7ns>FxPSqA>NxOhgM7ULJQn> z4Fbx1;j8^;P_gFKbl+i_LV!H=o6H=e-uG2`PJ2{@kBu_h@dk}@Ve+ogy!3aB0Da*f z+Q!|zDzn$M`L6YKn@-ipg_a=~@g60G!+Yh>uf7PXFCot^05l%MfVD8XMovtwjljpH zq?bLUaIPjkm4NIsOcvZz!`FA`Plr;sd&MlK5ZHXD+SvM2UZKbQEvNYfuMFa7o>eyS zw83MH^0To(c~lvSM`kDJ8^j@pUD#^HBcu^y^MKR}^S^)#b&epLre3kVcX@jPoxnoiM{}`if-n8~2y~6}$c2wa_W$kTQPI z&e$(AAB@ zIrN{#^d>Z#Z8ZLNZ|HSbrI`Jl*@322xP>QQzLVOh(DJ2v}!nY zQaTj|h6ps>rbs8#?OUlafN|<6#YJ$<0eWLir7Cv8q4JU_0|0!eV|~RkMJQsD*vkZf zW0dm!Yn85{FkMXr4ZgM&)%H9PzHIqt4zxNqxAA#=CIvq%X!+pS>)_THaS17c86Cd$nGYYEs^ zV;yTViioL43r#^g8Z#h_deM2Nv_Wq;?M36>9~v3ynk<|!%|@IhY16G3tWLo6qGBU( z4IHBf=TicEAa?wrfs@vcO}bG72j@mEHmODIqS+tLN6LmI$lp1n**UF--*dekq>g4g zWQqx5b`%!DtPO#TQYAK>_(B~rYha27a&l`atrZkt01DW^+KJ6zJBn72M-kAD)G&6% z6OcM)jOOo72uWZhX0{t0D6)2~jC#@~D@KM~&?Pxj^P5S2Q#Pu`;qX3=Oj>4UE z!T#572lFe9zF^ZJhi4R^q@1G$q*m}BB&IIc!bn;wMMUg!hP;TYn_NF|Tw zjEdwo!p$J`b{~yt;~F%hn}Al>k1@S6X;d(ztb>$gh#!3-lW7mgej=ruC8xHjtyx>I zc>z0g3%UHL@?Ii^?^)nCG{@@i5@Sd!sMB7#2Ho&a=~Xw1 zkSw+qXx$!mL-KSW)g0k?&-PjvF8%Xwy5#Q-E*MFvTIA%2rW^VmQ~B3JUU2+8S;N*= zbC9vedlb?ffs{abfcTI|70cWQGg|RPP_{>#6tS=y9D&R~6|TJD+qh%XrFq;cMvU&n zk8~)>KXr4&7eeqnmq&u&NNc#^MEHvkYI7$h1`vQS1`773HJS$dY5^TGH>Mpci)Gbq z?(c46R%x%NY!=5NY*l_r4k`668b~9X*+hKn&B{+f+qZFEXPX?cWy~mmBs<@l^bBXk zE<9vWw*LS{veA%A1ZFz`YdKuuS}Y#q42no6lb4^_&QDFnZVgz<+`d~b8<#z@I@Bx^ z4aL`e(YcKB8~P<8%6Sx(KnV36YMtWP<&RvMWl*FdY;qjkj5T3wi=W(tFTRSa03 zgK{tjdaE@{*|kkt=HNr-##u%iX4ywVGq!pS>u093CDQ!EXpDC>%ktkPouoMw-XRt^q(ikt9Y6S9H1gn$W8LR4X%%*6iynCJDO0nBln z15EK;f3v4IUPb&xD2m_#ws2`S2LhSWvE9;(P-{fJ znlAKboKA2z&e^MsYqnKfS_z~9gq@U(tDx=uQ~v;Z+hIlqK0=eoThEA|;nZWX*#4Av zD>nG*D#dK8SSMweQzT{2L&&H90IBZd<(h8QU}0;`*-i~BxvS_=;Vs z!X?sK&}S?de2(;*)4!lj=WSG=*3F)1&fMKT2D)SRdS?Fs@y>0(^8Wz!S1*!Pl;<0b z>!`d1=8o@NQZgPpcMLjiTWZkhB)ch|ma}?`bi(TH6}jSS2{;p67#a3P!9BMd=DEj% zI1=*JZMFFfhu9{T;!vR;-bf*gwiZQZ<}ODmTy(Cv)NE}vODSyb;#r`Xd1Q^cGM>j2 z!KCn?59lj$nst&v9m?{}7-nQ~@m3^PpyFqoY-hyVw>tLnT%7R-y`=C0q}zZvTEg## zuhp&KhWk;5cv4q+WtnBeEx3yuysA#^o|Sy++69)Y4Ww@J!R(TUgu>ogQU(S#>?t0l z!umF?b*0?gTmJwPOK{eltWYK~fq{TWx;CfVh!${xi3Le2M`A`Q9Gr(_wVIscrupow zVo4?(;#i4e#^8?11t$pGTWdNMvcqvToGEnjNX&M3A%9Un0+iphNd-YH;pTxQrd_$JmBa!X#9LU_w z&pMAM)immyHkbPDk*cJN5wP?5kS0u?YI5#&#yZq4ZUEEt?hJTuEt65au(rE+S$xFj zE=++4LJKK9LF-m4SlzLSh2(*w=lM2zWPB(sW2pdfenCA6j2u;_WJwrk@iuLH?768L z9`fxQlYezr_+5TAJ$F^P8dMes*liKKm32Z!axlR_BfbaLroJQUk?8y_cX=dDD#yu` zSqx<5fa*F_n$j!CoxJ(Pp#7XLDHUD#%Gls7OCGU*&MF+agwi@dD{Z&5CO_Ogr?@Md z=kXW_ZUC~Fmn6c?aDRpmW40R=487tBZM8`+v`D10HxU6k7ZL_x{KFt)G{oGjxFaHh zp5Op%F^>Gv73FvFLZC+k^0-qmVjLiX((TrHJbpY~X@AAB|9aYY2y4 zlN}uuze>EFiwspK#-ZC%SsT!A^m7T7~=3LPBA2GRfoiEYqq>H;C>o| zgLIpzwA)*oo0t~jNv4TpY{|X>U~m*|TzABa3UMZ|EuCH=s9gC>rz*?l91wjmU9;g1 zqS}Xt`cp7DfJq1c0IOmL;Z?C3(<{LM(AiBnIvdDUAMFXD>9$Lu-rCy31d@62KbC<5 z1m$JO80nK-%uYMkUjES#Jh}#q{G{?DN1K*R=A|G_N7Ciz}lu^x>3Hu*ugchH=^@~`Ova@RH`ru zL#*#b@1B*JIW+d4K}Y8UtppwSGz^-|;F@bqy`hFUHLhbo2L`q`G?BNxp?9HYdJZ?O zW}3oJ=VWMajcmRJ6`WRuIuTvbs^g~gAiz;$mm_)+AW|hO0S7rXm8@3iTzr(CO9{m& zv-fVT-_lHd;*y@Urr!afJAdXQ{OU8oPSZtOdO#~0ob{KBC@V`4 zgAFYFk^9AAa9eqr8B_eX60SZOu0_2=74^yHUon)qjg@BXs#&LZgq`Ku4X3(-9-MX1F-)9 zUyT{VvUxg+C~eC0`BNsTAdW>O=L$aj(D-V0ms>_XJhmT|bCI=?wTuFQ04+yI=g3@5 zl5W>hXit<(RgV0u%;c)%j8 za1~;HWT2h4s+Yx2cT2Nwn7&N^0F}DcvsHJBiJl%;Cmgp>ocavl)jZGs+D~PB2#>@x zpEb+8J;Bqb5Z>zZpDGJ`$&wVtOswGUJ_DMrD|D9UhxLneIC(5*RU6|a4k?x+HOgAT z2*Ez+9RY5+{{Y`geBq0@FS(7pqFAKn3gaL+2N@p?tC+`;`ko!$*HG3mp}Ib$QNA3) zbtJro>LbXqMK3TO;RFy+@0_s%>6*AoB&U}f9gliy()6F)h}OJ;7&CK$*@oEqV;j@L z!7Nc18v%lM>6-K2r!V3%<(D-0j!7_?nPPvbcG=B7%s0T>YXxLvOyL8q|+#XXRracTwmCM*|5Vm$@o= zAEl+ouuv=Mnn~uAu{kBT^q^Tr(Z&lY=4`S0?@8_p7D&RMeZS!wntNHJ$Jpq*S6zz6 z#?j~(DU|0(Y$V;ZR36HO6ECzPd^cFFx~ zN;iS_S#OQRY*2YzkTOLC#!QF_$;l__O28|*6gZQbZN_mQ{Kx*(Ma>~Z7~oNAqybpq zqO)V7llW7YmVpKa;L>}L76&-rl#F~&{puaOl%S9nl@F4mBVa!PM#dX$$Q8C2EGX4X z?Mjq^)QPv+OOC&7N7s=}E&#UJq_)faYs{Uz)c*kbVw@0l!RTqgNVy`JLeFcFx1Ik0 zNgu5(2#4WGZ$Mai^Sp9KLHRh(;hJ577>{1nC0!_iqC(q5O0f7HseX?d+-YeWjn!Tw z{sL5f6rFN8M`9>?O9(D+W61!zNC&~kFXpv8EgHp+c}d4>@>RB_X7+cIz}xb<13kg% zT|eL_DYw0Gzces{as5)m6;kmYizc9nEG(gb>5jen)y3ePPi}Q69|~hgmjL8!NYB=- zbm(0cbsx({l|1){;@_(1Qg-V_72dNuQEecNS>1xFf=MR;0o?p6ssVFHlwklG!dJP* zDj2$!t;9o{Oq1Aj{E#nM1Isw|fg50lv$k{CQXNZ3;e9IK+I3+y^D_lcYInPmS3MRu zn32qT1p=KF0H^6JG9FcRZTlS1$l9PbT2};WRxfuRm#4!VeBNs`&)A2?*o_Y+!qUJRVmd$D}&~&nLJLwm{{``t3?TadUuTm=z!pTLPPG z? z(;sd#_*I6a9mQ3;EP_2!+~@5aef4M!yVX_?lq>C`0x%P{XvNz!pKw7P=|FHsNTQ@v zhKyB%4T$MgzlajWb!ig?PH5%9AYhz|vGeGDH522_F4pHs_QV)?hI{Xxxv63KWMTD9 zAh=#V7d~o9&1Wye2BP59!tHtOt1dit& zPsY6JhF68v)Rko*sRslR-n|3i3(2((7t$`Jm8F(jD4FDLtlYbkkBw?z(bcz-qnBW} zu(e-tw~Q7V6WwXrTx~X?1io9eh(s}veeU3~9X%?D*F00>J#N-}N%aF96De5|7}h>z z?lJ~&esytipM&=tL&Q>QRyUAaM{~;4qpK1eY*}zO&tIKOcyq!25YZK6xVAc#$lS?u zx`X|g$GeZ7YQu&@+(4iZHPJ8!8z;$fzX|X+5pk8rm#12vB~B!{lPd~*+Z&&N-n(mn zvcIm0t7)N!b+}qs7Y#~`BgoaZhvkl1V zaf+t*^rQXaD7}|qSrWTj%c`wkV{|k$6khZO>6#wIoYs$Of!iYp^clq{9mNqA;CkYY z81F{ike=uaPp^6&^jxpY*XKqd%IDUl)R?x~5RM1kS_js!ng@TaA-?Hd4>V@PeQOVF zP;-r|Wb~)1L3Xp<&1?}t+pTY<2|FVI@=6gotsUz-?^#W0`9kfzXm|9jR>9ljO43^$ zYkL|FPg>5MDfJ;BS{F*!#;|v-6HHP0EzyeDkDL0EA^d2H6F)36E;G!(l?mXaISSs= z*_uZ5J?d14_+p|OP~}9=^C%$v#Y&LjH>=o25^$Hk8tDIZ1l zK?v;U)nc}`S5*e}j?x0$)yhb~*+v`ho2+SAoxjVK;;YHpkYl3mNGhlslMrm^^ zYEc9~Wrk}Yn{an+m4-Be0qkjXpAWg@P4}x?OgR921yp=I`AF*5($2$r-GZolD$@RE zDYdcKQ`B3EVzoUf@)iYZ%B#WMDjh1c@lb#JEhz(WG)Mj+R!a1$Y<^KTo@_Q?ohxhIGT;asp!)W{?bu>hqn}zmRh(Bk}&pQwBf(OLXFAVN4<;d=+DhWYV%zS`sGv1qKyt#t>8+9xq_e*k}o3`)wk;J2!VgxB8?H;U8#GbzztMzAVtF}2L4XVJ^CVwE8Ae;aIs71<%W0F-+&IS>E zUA9s6CZ)vzuhrd0k-I4{*xU0>B;^&rK3ZpS?w!xyx6+M!R&HUpymEdYDtH!9S-}({ zT*!(60CQyLatQT1(Sp^Tuoz@|j0)9mNgOPb2BE@<-B||^!~yr*Z=S<*M?I{3-7(so zn$i8Uo0tzI4!!xm`x-E=2KYOgnYm8ebs5BH#_V&euu5vRbK0!u5Jk*`y zh$$pv877ijKw8!VxGbE<=HBuA>eDhVm1kmsdnW$?XTdn6^T41gk+G3K<{78YXDUI* zQfVFJe2r`0nsp!Wmi;QjX0=@7hK>>wZ|@(S4P)h9{vV|*7d4^bG$ zVwx?Gtk+)|6aGOg)pTkxyd3ta_@__tnZwv=LuI?62V~bek z*2P?W+f+MnEv9MjH)X{n~8tKQ#16b*MI9$H5!muQoel1i^r@TFSimBrlpLqvg=-%^fg zcLNBh!#nlsNb(Tfo_J6P)GQJUTPBY3<43+rhl~|IexBB@6^O=9A~D+=uga&qJE>1| z9QIdkuXkeVk~r8*jx!vf4$eOiY9DE9eWK5!+)rh5B18MxWDuvC$?X$|LPDN|4DC+V zSIK$B(9dmcc#+Gd%9kxIw6LgXolHY6pcC&mN^!VMcim3;j%vU0FGZ7I;d$(1kIi`` zjD+(9dF46#M{2ML#t1bP;=739)48PO1I%Bvp@-bSim#Ps2har8)}_Y)$lX_0y)Hl2 zI8R#8VQFRI$&4|nEh0=N3J0$v914ot+%q9zr$Y$O`@lgzAZwyHn~LqeGWmYpy*w#ARyi~xQ#%nGAvIX>7lAm4ohBRD^eZE@68 zl#MCe4Ca`%_@YBrJxKB=57r_?THW!R5UMM96d z%smOI{p$I5GOj+$kx+ZIinXs?Q_Q+Q&J|=hP3C2*b(PQqFHzTtZR@y zXEn~Syh$n-9Lg9L9;4E|3en)w*2W2R=wOZsV@5#=s;LBjX0OL9=dcKGp31b1Y$EGX zTwf;!aqhJ&w{vMaobt-t&n(EnoSyl7RO5nQ#7_@i@oo5C;^f|WeBq;Z1Ip&c40#{T zT|RZ45(%Y(T}IA1VF1Y+&Wg#NoWPx_3-PB1MC%)CdU0kT3{H)?_=0L-16pi6+7A`S zmWot&9BW=9ajuQ~zyAOUUD?|0B>7V8=0A92A#ewv-npED304J2I3V^umFbvYcz3Tm z_}UX|#ya#x)$ys^o@F^3$WLzLJJnp)8f(j}@TbOkB#Hq?F@v=Q_N|kgZ9pV+tm{_- z2YtI%8r=lcZbX#AebMtYc{G{>?tN(N?@~8_gsnK{#SJjH9ffG;J666_>0Z=?-6$hH z>v`U@Klh>zq~1tF<5&e~XCP3C>+zyHgcZ12+*Zc;p!BWhdW{+vTF z#7R$h)EkFC@=!kcE04Qsn@9EqT*0bv^;L35%siBzgQQf~E|(k0Xg+~k{`FP(r5OJJ z#nQGu+z}tSaaKxYy;HtLhO1bV{p17yf)m^z1QeC1vhGU1xQ3b_WAfx+7#B&%>uf} zC27VObU8Q~qy{A=naCvXnl{v`-9sR3;zjN8sXRbU4`8S^GB+!yczBgmt8+_jm*Z6i zfc(LJhOM0}-~;Jh9yzuTWtT7Jce}Jvs1y!hBW2$kE2-YBPr#IqZQTp$5u;4ai-FbDp%j zQ@X^wpp)+Mo&DUN_^&U|o5z^f1BK~W5e#@hcjoSjl2wIek)4Q*3v%OTJpdmPcBd^C zCT%xhLmQolaE-7*)Q{y(gezJ<;?VpO~k2y^hmIg=3TWjHGgnuq!H7 z+iShtK>13y}3HipRLB8RF;K8Y3tkvTJ8*Ns;tB5?*6qalHWMM`qM?sCOtt*9OB)MKfFdiDz}dzYKR0Am7uFVw_4UosM?t zNi7Ps_M#N$-iyEfm=xg3axv@q)u_(FRFHCra0vO(H1$@9rbr1avE$GykSNAG9-h1X z)Spjb&v6zyOix~+g175do48fL-8d?q$JUYR5Q*)iL%vmj_#A$e=jwfb_Gp>FF_GNT zCW0*|eb(*o7G#2QHl8Tu!1Z;>&(^MQ46YVytHlTG#JT#Kp|tkJn2clnp5l1A^iq7p z{2H#m34r#UKzhd+{7q_f=?Rsi&1Yw~_bxQAAHuNxp^D#8MYk|hf-{Y?xXpA|Yo9lM z>J?{erd|6)I$o~JFrG;#@|&5lBa?!y(;Wd6Jqw0g^E4Fbi;Ch$_c>S zb@eq4ejnDfn^QgQ%jz&&+AJaqUuc3>%-r5!@?AO_gcdF(99NeUR6YAkCl)}ss={l zoU|=FP_vIgMD~v+39p61y7@Q~<&)el{^&a{=AXT7UZ_iI=!?HkCJ_N;7f)&QLHi20du%z3a#!Nv~tHnEwf zw6~SB%V$c5K@_FvAbW|s_UH1nlf#NK9K7P*d8wR@XsZB}UHW*p{O{Okki z?u-g>or>iZ)yQ*`xz0W#8&-QUl^#n=+e@hA<-|!Ua}R)5A*m$#cA0auG&3iOw)89F~&L8Hyxk z+Zzsoi-StkipOsvn~3eD<`Hw?Z|heJn$uP-WyKjIRT>I^pk7{TF}?N43M6brA7x*M zsrb{5t*qE+@Oif_yM2UR*^k1RC6XOaPLk6C-H;D?7!ex|m|@@HOe02??^0PcKQi~o zfaHQ-B&L{(} zX_O>UL*9h65tBj(r8rE6Fn6N?^`b)%aYF=S=~A@`lM;*KI8QlHXFhh79M+ zNtstaAVo2PJ{7#+cBvZT-VIt30pwaSrjgm0u`I_dNy#VFlU4_YHkP`d8|b#zNF*;U6bPrzoUjzg`sdxR1+7Mc`S zp#ieSyxrnhysjhGBg+t)h020XNyLY8dz$nVaW4-94%(%PsTl;^ARnE1^~AErKN0HE z#Om?A{lhD%$YnAT2tC28JwS~NqCYaNiU@J`O;|YFdMuxYFDXlfz*7c zdr%3WD3P%pj(urHX)Hu!kA)vnH-se*dd%!=J62=vqD-)6w?VDul1O8(%Cmabaao3PHSy)J{6p~x5R*nU1Qb}jdv`uW0Mdp%7R3W$& zSUI6mNm!gV`FrRDzsFvV-dNV$%b*#3Ex{mN^5 z0))&bg`Y4!6O~xgt*xVyag`#Xmhcrp&#~H%lI5=D$1iN{*w`mRGK%$3dK zQC%NTiP2*;6S)BZ#HXt4D6pYrPEq{AjxI1jJD!4v6l$x?NGGoKnh6D6HA|s5UP90& zPIeV<>5h3#b?lO zPq5$tS6fxOtl|@r9Dz|@HU+p}RRHd7B?J7Xr7A!fsNWSSmqfilahN2@`c-VPc+&p> zu>Sx>V+(AUzuXrsO{?n`a4M`wxj;i49mmR=thw8o=JD<(esQwpMoGZ*^{FJV+s^)4 zl|%rJg^owdG#x|PwCLiAcR3{Iu6upi`~`V)%{1%_H)})sA4K`iN5Ox{u zpSqkdY5Jir-8eJJ$QS{R;Pl_6H9Lm8Z?rZYwx(Nm z&$P-;dE7>);JciCPvKF$m%=tZ7tiKM<!i<3@nEKBkLrb-H}9P*&>EJ0>4F z!=;3d7z=(SOQM=bDsCk(E$=G6zlSIFaJ| z^qjZ8tN#GMTAvuvKFTbBbdPkMkP(r%&w39pD;$h$X@8a%AZG`)0iy*^LA7ZzL9)(s z4&_4h-SrJgK_d?t$M|thvAj|)5=3U^FiQf<4xE&d0{EZbfeRnV)-eZrY zg(a~`R^w4pj53f;GN&HtF}L7FTwWAiMFsw#vdE|mG2@wl&gZ6TrO~`^@dHA%hSJjh z1%f!K>m(?+3#UX-E5#OY@Z@TW~og3`Bk=q9}GwEJ>rxV>F*fRR^$jeUF{BNni zzr(q_k3G`q$K_oca5ZrwS3c~oHo13)T0^L5wtA(px4Vc-5oLU2f*B4}f-pe`xUMma z#J(bn9J;QeG3zmZ`Lj+@__f6f3jX%E{{R#*KjtX^0A|Pr&tdwe8Lhv{;q+Z|YXmkZ zma#`F#xhZz+DwviM>Cc`eJsZH$o76PaV4od*KkTR(o1vraabco|m&WUwdUPxkUpVQR@VzI=){8Nkn` zYU3;r2mn^gE<%4aPt@Xf2~L&m(Z(ab3SCYWfzEMDX3_0#rV|7LU^a2rKN?G;UcRFf z%<+X^Fsg5y=7B1_rdE1Mtd>(m2g!M-J7Q-)hD*8i^z@XjtBWq*ng` z?MNhsMnwovMF{5`eQHpcp>OofXjb>=XeVLQG?1eK9Ssa^xI6Wv!;~609sALT6q1iM zvG$KoT1C|7{`7G>V>zOZ2TD(IBXXUf3t3yw#)FL3R7jA|Lq(I;w_0xWB%~HZeg6QZ zE6AiMaP+sT)QsUXkoqVUneAHZ_g1_7Xwac&f2C@*-nU65zM{9&{o-YoV>yjU<+{KqiJLJ-x(>19jVx$A|r3NKo?)0Ks0^K+H(mu%-3Rg!5%(6if4f3m3&W$K4yXU2G zc8SC~j)y1_kt9mlF}LCY>MHi(uM~6_1utgyM&|beBV!*DIfZmMc@b$1CrJTiWJKUe z8?KtOZIqMJpJE{6CaQfmkN8ehTx%9TS=4?6ihn*KaC|G7HLCzV6QMtWHK(pHKQQ~M zMXoexs~eqEAB8Y$vnkWA%N|t_zU2HWxW4g|gRK0)70j1qK;>8voaB19DEw-#)x1i* z;>nCE1)Y+xK2SW&5Nm2=BSqz#6|8RfD=0wZ&ROzMb|7>eX*auyy53ltFrV4 ze4_iOJ6DyAp+RAd*zJlTZalI}jD!S{+=19pQ(eggvvRf=kUnCyqR7`*!^}|8!~~8= z{;3?J{Meuj6z6sbyi=*IyCkXYow&EQw^>OI7-=Qk46~kWAC_@S#ms9H%gitjx&izt zn&Rc=7#IMNpN=UZ&Q5v*P}t>K4JUG)4xp`Asdw}v66YQk+CChjRE)PBROd$$@w`0@}S17SvKm_o*8ojAM0~J z(b%`^QpPCkfJJCRnH?bSyO)IPwh znvS3V=_2j&QBJIcHZXEKclc5bE+U%7skz!*egdDQRxO_6rD|)ZH`o=HBh=D;N~A9E zFK#yf0Dk`f^Hq+BqTnZM?%K1?Iol^Y2{k?>?;U8h?8 z);=9ug-~hB5i_$)Ne{aIX;v!g!IP!E1VL%8`OU5 zY0xl=(m7EZ>v-XfrSjJ>y34wa#BIz+)C$YZKG82^Q4$sBI2@y)+*9SmDKYY&qXMVo zcBaNtHKmlya_s`6{{Vg>Q2teaA1X~iYCm;Kd}deW9HLuF)162AIs=ZQBl4*A&Yy1` z$0!ZR4@~y>RK_wnG3nIP75Wb}A6n3tFCsPq$s9han=xX0j-~|3abl5NJYcp42>64z zrhC&Rvw*GFeZ@;ILdcOxk_ZJ3J{yXTYAOuKH~T&6pz8U|BBp&QAJeg1(^0iH8>s z3@b(j%M5x`bNWy%Z;;LFzuKb>-Z0!^jEGFzZa@_8S`8ZgH9< zo%Zcnxp}hZOXA5|wARXaF`10bEhewJA2n|{qKRypz~36GrdF-LlXE9J%O1=2PgC%x zo14N)2;)cq3IpLo3~X}B21nAGEu(@dmT?jiH|1b(ay==k_A9xhX$c}DCoeEPGt+Lh zNz5YcY{e$92lZ187hKc@<3Q5+u&H3U1cKdwC)S=c%OCd1J*MnD(klmvI$^qwWBO1u zw$e0v5E|i7y61D3J9YPW%{9k=Z#Bs_cGuSg9^~!x!8A>60jP=z!*!Qv1Z`JJ&bLL5 zG(=FUqW~z_3R9iB)NfDJ!@`1iq=EWj!5^JG`$R;lh8bbD{c%>>1qxZRwatIb3XAc? zO(v92G8}TS1E|5@HA!8?&uKZx$Q>%e)pZMvPg1>wbLGU2q;vz6cleV~+i07gos^Xa zu&HC5GBPUuWX{3yBp)yq+ffL#%|dm|cG8jS%Ynbninz48v>;CtN6nmbZJboAP~u73 znm7TB4Y`i({{U)ZO*>S-j!TgnylM+HkFdb_w_l|LWF+rEA(I*~DUL62=7MV*;)FI7 zaJ0Gd%$`#OQIdKANzP6VYEVJos)ep^AdhrsOwhr|6k7GHQgf0qM|6b@iq_z5T4S2P zY3!u40=72#)`kzxx0-NDR2IR<%CMhG&^>moXVQ@+FjzLN=kf1B0<=v5DbV}kvATYA z4D_KhY-y8#iw6uobhHuEy&yXutt`krDn?f6I9fPvGxV(vpwKrRPkIn4dLHy=WE8O0 z`_NylVA%D|AW}nK--QXW(u33*7BlguOo5+`Z$0Y{{i{Icl1RWdt#qtb#sM|5HyzC+ zmIIyWVvAg6gfXAim4uMKm4_Q*fz6Zk>s!v$l3FCtNx-cPg&XFyz!8Jel6A6cN8?$_ z2Ev4@S+EEj6S>7C^b~`Kx4mupMhW^Fv7l^9185%U|=%fzKwcqZ|f;32ns{{Z?$AFV*9oJf)d=r%QAagHu{ z7WZwM$sCXFm1@y@n*4cy{sOB;2$nPcpt*nu*n6@rel@WKjkqd)qKX#w>;@(P`XAPW zEKV}Aq59V>2n%mdnMMe1NAjF}4GhV15y9sJG)lp80Vu~~*w$wGcP39yS}L@(j>Q`t z+pBXO$n_bcP1r5WRdRhcq@I1oPcQ`hR)!|$`%y>q1b$SmyP+|Xm5aE+-81#48(Wy9 zN9Bou3zj1X>r9-`5;GA41EYVf2u*IkWu;u2d)t)FX&sb~JxbUN2f_G)DaOkF2+1bl z0rV#yokGNrs|HDmk<%d76Xr8BO&b&6IM3lxNWmj?`Kj3>qaoG8vkwvJ*Cr(MLMkB1 zY>sC;vFI__Qu}M`X||4N-+qeVny9%PcTzFgfvhV30Mu`~sJo`HjhsTh-l*}*LHetW z*hv@!5=rPsU!6Ti6KS@{y902%!?7r&s6SJmrBQKR>K5b}rJZr;#C~+JaUQgx1Kdc# z0)-9(;4eTj4@$2mPLzrc72R5osl?N%&2T-bURLv-Zcb(=1cG~a>r2e4gk^HS1C5PR zFmbl9xzCd4`$><;ie7l`^~$`qaJgLL1()?TP5mz__5hD{p&wVo4W~K4`zzVs%Cn9v zVUN;=o`{_;dD?y;zD}g1(t0l{?q;@fR zfS;QhuUC)smN9~|pizUA&iaN6#V)Z8lg@ys`;-rRHqyo`bCmu(FGq zT^qKue?;dy4@EX+Z$hutSV?)xNn#IiN)lL#eV~2PYQKkEu$|Y+y?}4sz&~-tIVHeW z1WFto$pjh$h~efwicyruZU{eBB`m5LiN_+deZw@vVy>{l2*)faKj9UQ?Dp3#4s!$G z`WD;ur&9=yRs$TWNcipRPSN3l3Ql&jW3muJjK1;cDMJ(FoM5+Xj`T+|^JMf2a(@|@x)8+K(C+x$rChXd9>>=z@@T1?r8{eRr0rz4@;0)#R>de+r>l~1Vc>qdx) zTICFjq|tl?-*mq4Bd#~5zC~Cr;{g8v3h&Hc?oOe<<_4c8k0bIlf#M?Rmm~eA&6niR zH!%Dd)X>TVjo-SjJOr?sO|g-WPg6*)V=gk?slqko$Y4PosU(U?ShAb5 zsDy>14FO*G2kxleqM%I>>M>H!EpQurDa}UpbqhQyI}$#JrDnNWXs@bnDlyl8THXZ= zZ_>6v?NNe@-6mi;$oLJZp7oQ>1JG|y%=nz-XWbOo_SYA)u!1IhZb;}pWb7(t-QS|F z`qN|0Htm9b^F*-(Y;#r~muYLIPYPdJx=P!VA_rC<+3ZDI(>DiAp^5biJ2r&jNmK;x zdX8UsZ`O=RK_ZoM8|JxowXyislf;}CZxXHd4@z&X9N@;T9!Sr~V3GKWuO)_P7^IQB zY!2a+gZCPlt`6Zwb}Gd4gGwVo&5rrl3MyNLw1n9ckBx85c|s zzRcXi88q2Fy}uCaP(PO%67fcFQRLMY(p)>7H~iflkxPb%KreG(sC^&W-2iM00KJI zwQqeC7RCtM&3M$QZP;hflibxiG*>q-JC*mAPH70(E=>_|t%yR<;!8-fHU$SvScJ_i z@x;$3Lh2hIAa>0kscO=|o?Bb9Mh+L=!k?ZgWQ%7#sq<1UXvTTe;NqkAm-h2OVo4c> z-s=iYI?cOriqggl9u*fu~T z`B;2uCYz_*BrkC!eq-CneAt_OD)+|O`BdUqz%&lZgRv)(&D2NCIkgzh4R1a1Q<8XY z^`1uLiJzz{SMKXf`lg?x#H}rr=y8$!CL51j8YauA(P;=}zss&At!$Cd?N4ctPsX%J6{EjO57vP4 zoGtST-bN@JR_T!-u_Bfx;8G^XN>YUKiguL69!@bu9nV_APQ#^OH6V7>g&0mo4Q6`$ zs2K)?Flh%>B#cwHed{^!4*vlCs6EHZvl~-`e3aCN8zUmKIO=Gv`9S#A*FEX%o)c0( zY;V}sb9#y_vCmDbeYV_FU8O|`5-?~*hc{X;IQdrlov}nIDnrQXKKkA^6di|OoeTYG zCRh#zF|`!Oui_}x&U#Q8aK@U`t#{9;tj_y)t&jle(y(ocM50P;GA?8INT#g&SvJS5 zRn}zrtO4IE`PGSUGnrE@&~1~}p=_Em8a&jlfIb52+-{u~C5XR%ZOvFWkL?^ADv$pF z#=qW){{U*Q%Vd1&Z)rM>0xNU6$!jWS)te&~uGWCZk2V#V`kH-0=lC?mzqn=hRhXPH z_g5fi6q;=+Kv>3dpk!xbijrDe$0{ifR1L@nZrP(|wh7D>lkSc2)SlJKmu|OPz)f04 zh}xWO6e%~fLlJogT!7g3M^n^NYppWo-baZfK4f_2iI2Q8Gt!=|()QkWc$uLO6C(gf z=2jRYiI+{D^6g#YQZ_hZMt-7@aq~#hinNzVyu>RF`ikF}{JCg5b;V5|Pn>iA0JFkW z4T8Qf52i&jPj7nyNH-~sw+HO>#W{8M3BhfCWY(OMrg;DW;Qiq`{>lVxy}n`=AhHBk~y|hjQ8Ia zh9&4$ksyvjd-P52(`PLj9E^fC$of%UY-})NIUR7+(k*$p46hZHu%OcGeM0NunFZJq-{b-9E8nnkwqwI!B!w(0g;~n04gbF zl05Reu0079qxW^t_kkGZz~31@f|Jb!<+BccVV;LHKe|1FoQWDN5}e`I@8FGsT+T8E z+~i`Mq2n$fjPncUIqS|9zcEn}B%uB~ir<>u(NEJ9osW+GV`^cOlEbvFA5}X}I@cHN zG%|YSG5HZnQ;)R(4>hzcpF+d^YP$0`-9F<&6GlIkho^do;9{Th!kN8CHNWP$Om4WI zOY51Xk`Sgr7{G7p4qwKJP9cs6iYiDt?l5VUEN5g6&B>FnAksUSC51_B74;Ntf+0-` zDKfGhZY0?ol=~cm%t;B`m^ag{SWm=ST;v41jG;_6K^Zvs)oh>9C-(>CO(=cd-92lj z_=*7}SXM~W9^c7ibezY){DJ^F-My>RPt|Pwk{nMNV5$fXGt&oe&ZKck8%987Bj9VA z6y#v!W8p&%ROKXKe(K|$hT=^F>7GZ||K}NcnxTW>QDGU(%F#&uf7sDIe5hdq~nkxmgdG*<52_ zeS6mYu*juA%XQmot777PawQp;oqx2T{xrHSG{06MpoEX^mHlerGU%#RTKF98S6<;w zu8O8tmjteM8)BgPCOs=|v$0g-msQURi9RiMQlsDo<>BP%Wml)L?Tx z!l~bxLT+jiQ=@?8rovO79mJD zIsX8?P3}&Z(i1UO3<2aMHVE54jaAY!nZvkMcJwso8!~;gN86~OAnF7rzapKPJoCyU z$0*<8el*c6uNBXhR2(0TNRnA^=0sTlm4Rl?!)^MW=7DXdMXB6I?J`?NSgTx08I&@w zHV9BoPBz;VCE=r$yw^3(r!;SA_lKu{CTN1bRe{@JIlgq*+UBKke=WL^5Xn%$dV1%z zBx~o=3#3vklDWeXxBz$f(~gwUUEGPCkjebrj{g9a3#8Zpq{WSe?k)pi!f27TtC{(l zMwO#Ih#fr!)a?ZKEgQ!o6q9u%9=^MZaPs4t>SpHU!Q~j}0@JmHs!EGEWq8g&Bz5?M zQGjJ}8~dy8m9WRCv}vt^Y>igJ&M8CkmTps@vZvJMqPo-ECG*>b1tbC8P+&1V&N_;+ z*520g-gwbOs6Nm;kEK@{#pDTdBE$%EQ5bK6)s|zBN6l*{T*kN>U=_*klWDqzg@Z4( z6e`;=BRTnshU-?aTIzC$3YeVviObnrpsnf)D>AyP5CP^OY$>IrE`8!o1~Ppr+ab_w z9!CnK`65;TTSoRN?@89C(_~!b;pWRAKa~qny^S>s$FwKOxCa^P19b=EQT*iN?yTm( z#Tblp_fQ;%h6a~i9gxcd@}P5XzVr}IcIjKqOR}zCWeAZ4VuU_jt3O)M>UZt6W;e|`WIgk_tlv1Sz{wfT+1j_93LtGV z%;JUepa4T|fA(lw<6-fmPPdWiLpaR?28>*eVYYFKYeH5H&h?ud&~i4%%kH7|z@|)t z+O%+f>KhNUj+h(J4&ZN0cSH&{+nHPu-N4OG?ILA#W^Dfe-l32TDL#@R{{V!ZMM{UzAcBu+Clq6lq85(*RQ1@)-*XRSQzG6Ik&+WVe!E2R%Z|K%&lc>=BkMy zm^87J%Cacw)MS!=T_~<4<4CUNk~Yy6K>q+{X%R%6q;=SL>yFiBvj;Y`8}m`Ugl(O%)5zbF)VY|7Msa83_`>N5_X0pDwFK=d$N(N33ySJdKo_9x)#F;IV(2jL7YC&nB znc+e=W?YaDtqx8bx(rkX=~1Loc>=e}nhuWq@5;Yp0Fmp~iL=7)2?$*r ztsoYo1KT#jLG=Vy1w-~(Pu7z*og`9;I z3Bg4^{{T+7Bd5lZ&2FnBq<-)OfPHb^k87ZZ)P%|c$s#9~36X-1*d*elr$M!~Y^=)8 z20=YG?M=+2kWL8z52Xwq*rZx~(E{HjIbFak2QED~q*vrEncJ@4eJExud*kOp3_%A9 z-v&^_?m49#WId$t3Q{;}KFFmYLILZ^`co1|A;t#B^{4q+nE=9!WDE>#NY>Dt`@nz> zGx}E7QOj;iAOmd;A!Xvl;W}I1&8F!P#(mZ&ZqyLcsOo;Sx$Wd(wgKCr*w73zW9*EM znD1FcQCG!MOV0V+51uOwgC{C6N}4%)j@<`JRUaggG;SB2#s|CU@t`R5+G_Iw9S`3| zi5L4+7E}QHr`_v{1`zaOD3FUC(f)8fAMX{eeDBPs=|rjn(WpF!BjHS160#D7K$+-9 zJ64Q|+!`yDvD2jm7jg;hL!}@|DBg0+Fn0OTj3rPCl07j=6oA{)g}j(-Fy>My3uvZu z^n`u2*@?f1GoFpc^=x z;xFWlnE{qhB&N}616r-Hkd-n9d>pYJg!)vX;qC3LxfPZrE7wBB0z&XC1BS=eg&SK+dXq zsLy;=jM{aq^CYD)A`nB4yHq!fbo5qBgksLbDb6x|I#ldwv3n}AO27`AI)xih>ucA7 zIS_lu-Bk2Fses%2#DE5A$}q_(R~YpMq`EboocB?AzYLtl?0HgXb(?O@HFShhHONo^`B37HCtx`T-ANi{V}qZT&yVEf&^a{Iuz|)t=35 zoUCj2Qds3|9An`}d8~J)J}5t!{n8JJ@1T8_-on|2@gVt72AOPmaT4PPb3zg~PmOFd zG2HapoEiTBi2c!OhxiBC1nIV9?-1UAG`kWoW2FU&OcF_~_p^Yz_ognN_|M%dhObCS z{{VJa=LRja){~t!(=CN0cHW$Sj1GI_=~~0*J+PK~s!UGafd^=BAG$ zQ*Nn5=tw-G!ZH$e1AOmV7$0Sa-YD>&16vVf>?%(j1R^p~W0VtzU%s(f27UGDd-v^1 zJ(QdrZhO}Kmz4TYel4hk1f)ht_V>Z{_)yD4Pum#Bp`%T!9N~7LHM;@mO)tf?_D}eK zG&m7%Bv|8O?&k`i9Fl45@b;i&SkX|H?py`i)b^_nfp|%*?2fH;gU+2l*_7;6f35y5 z-wKx|g0R5Es4pqYE>7g^K2=ss`2&b!MR}DYF<3w)#?>k~Us7Z*%DZDe_s1VvH8@97 zGl+1!#GSK&l^MoPH^HlPXv=GFDU?jbi6%Z`+y4M$4XG8*jUC;x%I`jNlx8F_C+AUq zK7aK6l zoQ}UiQ#+0h(gn&}iTE4`Jt-9TwVY71A&{GFW}0dz103 zV;-j$6S+3DXjNUR=TEzMuOwMv^5jo+XCnuu)bVwwUPsL;PF2bf8An0*)aK%Q5MJU) z3b!~?Onl5oHa5md%{J>+b}*o1wUS16*;6MZ`uYm69@ev!QP8-a6=<;rIpz(`*S}wl zD3adFIAmvv5&|6M0qOYFnPsEcG%>5%N0M`ZNelI+jx*BqohyfKCiZ?w=8$J@T9M&PN!*phkdEt80C*O=3)Y^#OEnv)nUUZp z8}oLi^}U#MEIzrdl*w#+!xU(<$}3>*D4U_Jttk|(e%RO)YO{J#yRaGo4FhO z*J^jl*nlWQT;o6_i**UxC+aBAIudquqn}IkIqyiP)1*`^p!=imp>9k^x@SiI;V2Co z90nhK8|AO9HTw+QppC(z#8(J*{4-ODTJGThj1M&F<)2QKo?qupO)b(5*}nYIvCViv zAQO*(qSOjo4(Y>?P`Ot*#%TiIOgflyU(Bs2%=PnrN9&FvBmXJt@~vkseie z@IxpK^Av?yl^IlI6OWAu)QYyWg-n2Vqr^@DW1iUC^P{|^?VS2ju>SzVWFQ4UjS)x- zO!5QGN5t%kM_s=v3+&&OVrL&3M})*|k7*rO903l;)+xTA-B97{l=6kVS2CMQrJ-%?woEC1&kyP(>L=TTx9$O5dbLU zO1z-1Mn?4SXKfyxsgo-gjv`J6^JmtRUCftv3_|jP-stodL_OE1kymSF&;T{oo$F7s zQwxng1)U;1@6oZasdcZPaU@~n%7M>}?Y%;jw5!SqDh@N-K9w%ByoSo!FyKn(u|2+2 zKySH4tN~4K>HhZVZ0w|U-GckL+-9=ZR}ouV$2zf{lx@)b%||Y^8Ls6;`(A4%w+S zlU(wvjV;)X{M2N5lg;NyrN({j`qQLnf=Jfjym7G{+^d%5K7iD2JBI~NTpfqToxQPH zm&|@=Ab02mJdSgL9$^%62;2zf?Md#VgGW;?oqHUhk+UusRCiF+FSP(xc}s$J9lq*C zE$K2KjR8`6llaoMkDUW#1v?Lq#;fQcjYib+<(DwAw$`4(G88Iz7~Zx9Dba!)T(F`deUME`I>QPnTgwaFUW8=28yi@1tnK?*b~26HX`KX z(vKF$e2P-A5!0vT!rQ8GoOK@qOvWGy3+^HOT)66R@rYWwl0xF0qqB@- zvBg6q&Kp{pk+d2iM}34Y+_?FVT5z|~qi9-5l!Xj4p7X# z@EPAV8@QS~hW9t+{Hk^b6W`rL{Q;+OYp5=5n*n(_RdxUkfE|aW5e<+eF~&Q6E1DzK zb$b{80A|0sgk)@zupf4DPEhgR7F!XGMc)mOBt&ub$jv*WH)=M$wM(I8v%PsigEv0p0fw7!+?Np_=iyTV}VpuGv9~jwB{4Gz`{xFa+bEE_6W1Am?DWNPX zM##WxR|Z4wHN%@nbwZCkZW)u29Qw z2}MxxvjAMUB#;Ng8Kd1My1Pe7ytG$Uc=-k&Bh(!ICQ8OPIfGD`^WJ~dIis)J}xG#m}9;!RT`{;L9N$nm;9K?@wGR>sE`X zD&Sd4gAy`vy$NGxJp~OHf2}V>1AKh`l>whhnXu|910ihtqa;!p6vq6eNZWm>{{YGZ zeqlpU3CI~e=zka+$h2n+yMwxom`h`qe9%0yr{39Eb;nwim|@0zv7F~3lgVKNfO(xs z_~#UD&W!V61F&TSVhWDBj+-3xtrho(>Dr`cND9QqBIB@O{{Y^SOQl?nZd47;j+kOd z^v3mJnNT~2i%`23cJ5eH5kSlVI|GW;k<1YD9IkfXr74mpOb1q6^vK6b3dUJU*q+^u zSQ1|L6=4&B+!V__y0Wf%oMW{ico+sM2n(@3l_0veZz;Kog&z@36PM&pZ?toqdQ$^u zkdHvF5F#ya9H5oVk&)D7W~Ekk%Qcm`*yb<~!lO_ucXLV@ga_UpnLVj9#_(r-gAh9J zj`alWd)f#!y0Z)8h?{P&MJKw`LcuF2+#x?vQIT^lJ?!Vc)FqnXNA!(@*WNuT&f-Q9 zkrM}oOg0Y3Bi4c@NYHO|)5#miEE;_|O-&?@xdS79)S}+*XyXcwc|qwycQ(bc;rAnB zo>Tst(lYAJfHCl?z`jPxyN}&De(|{*a}T(aN9HuN5}#x{8c7N=h& zE?q+D08rRab{GdAg$U|*1mJ`};ikcpzbjCJkVZlI9`uB4J%TXj54u|=>$;v~PM(z` zvaztZwT0eXJ1EHXsDO>!F#v!MdU8pEMF<6hARypmQZWjkNC}?cM+yGpNVJS)CtUXj z(vm%mw8@p3GB(CWNTw@`fZH^TTev$?Q*b>qZ8n)#*J%cGY!Q70Flv7%`J;!Rx zeM(58<-(DYPIKOm{pjZzjcE@P%p@M)R1~&mMg)`b^rS4F^9VUgzRz6HHVb=VR+bKI$pvBC+D-3YcKb zLFx!UN;bQjQ&8C?IAe^~F2v+giLH!81B~aOtx0bDp^;pn#^hjToT$$HB{orcw-F)S zW~41>yx!^@Z;icbFos(xfaV0L1Ta17Wov%Ag5Z@B<8}4;iiy{IDBKe$w?M}r{HW1y zZV3#ZjXTL|Lz9f)@3j#wBR^wf(3)*TD2QoVX;`C3_!&6(pT3)bSqlUSnCgFF2xG@SA-Kp{{bhx4V7TSp{8 zk`W1c)w#4N3O;^-RZ`A87n*a|Aa0y$?3#mVXX1 z7Cbr5If(1>&q`2MDEXB{Zp4Gk4=~(k1LaZ|jj2K4IFqt(x3jWE=9itx8w}&}qGYs$ zupn}hPCz{cF9_Vs*vSJpqM?duSSp>{pfp;?bS{jL142$L?fG&6$nHs{A(*xYMOu?u zCXE)HWttgekY|~T1pxK~H5GZ0oU#r@&ciwT>H#o$G!Dv1abE*iUR(1E03Fcs2gHu_ zVx9NvL>ZBC6lc(y(Vb|*t5lU1J!oOJ!0IUpxb(>0hv#G0dT@~?E)r+fj8|Os0QyoE zlPU;3M^5xw$}(8(wl}A=+o!idA0g&e=0M)*&NJBjYeh*L{V5z%4Yw3}%&b7p^onp% zyt`2Fry1?F60#}D>PK%%5pkZFp-BjV)E<-)pO0Kt8A(4QM)Lr2Y3V(!Dk7YW)`IVo z(uK|m#xe~FLFLECtspl_(R_;8+pS{7%-bCNJ!s_sA4)hbH|TrfpM>Ej*Z^ z^r(Od$5TfDpa2JI7ZQjh2^b&_gFQ_vmPiuc%L-0$mfy7t1F0KO;sh}FN5D`T?uZgN z2oOMKOq})D^ruLy*S>S`p+cVF1a$PLSddpl?mU4AReiewC5zALQdUZr69S{F7lefw0Q*e|_+ z*x!DJk?Y#DR}ra#)Igk}d2(0+J}0d>F1?eztfRT%R<|&s7hSnY$QY*SWf2lEG6%hi zkWPW~(|z}*%ex{JsLnaFzpgi{ZE>yD4I{}Q6Qd~vgGl5!Z;dQAGAGzP<8Ii+YuN*m zM1Xw8DEUKFoA5U2(zHf;Qi&iaN4z?L@ZOcch~Dc)q#lGF#Xf+AHU(ftXnd#BG_a>B zEFmlbAIv-at4#PA_D}<7p)}e8Y92`w4uY{6kmXpZ_#9H7HZTITECzB&KlY;=*(54N zjEASZHpkMNKnTh8O0D(na?kn=PVzH>vdqA3@Xbgqd_?0rOa;{>U_beYl71`=Mn#yE z0|bj9>4DaYYiSeh9@L9L?2V6bJgW{L7Pzf28EmEBt3i&x6(XFW@q+&V0WS1wIag!+ zH+YUme*4u!fXA=;(Y%nk{+MUbj8N!c?3~K*Iaa2t;u`AuMctjYnr&L+-Ih-Rz@8I1D)~GlU+EtxoTdtW8F8U;*jKWQ+geL&4rPIh zqv>ia^-rrRL>XvUd1lwI?L2zbghFox0Vrn(Z`NtDGj@&QM5WjytsT zQIZ2g)m)PJ-pnmxFLwh`zI9sBEPqMfUI%3Q@;NI zbvIqbb1bOlC&0&1x6Ym-!98`prhkEzP<_+}>jI z5Jn20O!`vvkVa+qhB+|f(B~jh0W6YB7-BN5?w`tt>J>^oEZ@}?6}*v3B9t^`cVX%C zrB89~3(8Sjmu#uuYRkmBNrdh1Go0nO1pR3*v>=g+qM-BwjfCCMOlSfch0TTtP!&CY zDor!SrxAiwd}-E5{r4vUlNldBg(q;Shh@rxj+Hg4#B7k5W065T*&{SdSxTTgDF}P| z{Hem@%6R}m$^jdE4IMK)ktixaPjv_Vseryy5G#b)6`az@;w{y8B$2SB2E6Q%L3}IT_<5;YVN6mUAmvo_&}R zjQnZ2m^e7tj?^_yyV*)=kWt=78P0uAdU{!;SWH2^(lAttXINimQVs`NSqnRYr2ET5 zB|EbzRjBIIK(U1x4NHPsLAu;ZxmU`^ULe7EI;B$01r^xPf zxp!A9o$z+3BxGl`Dg|30;0h+y?i79-dm2u69_6AH*yA*w)B_Mv<86MW84u$^!O3KQK$~S&@dn2NDjRz^mFd+A(HgihW7ZDe3Mo`3OsjRH1 z&m~GYYD+vZjW*gqzVkZ*eMJ`#0X7{8#bsqkI0|0HCyEZ*#kNv?BcPx@gmtuE6Pn96)ipt71fl8)t_=nvH9nA~*u~}JCb_+Q2vcv|g4Q-a zDpwdB%e7@?3E@c8z7kBlr>1{ObOQ{dv8=4Bk5Ys#ViitzEJxi*rcpi zPUST%<AGo=l(|0F&%F3QK6Zk1Sayc0+dsE$vF-xiG@jCM)vqrAIqnHd< zR#CT=6Zk&KCmBH&pRDSZw!p^>8l}uppd|95z5w6Sm}H3+9D$5-<8$2BR#e4D`djRX zeVvBiYLr9=C_bjLvYa4Vn2;O)0DiQUoso*EAZD_%o4OK?y;UC0K*uugjk8Hc>5uJx zwUv}zl02tvEClCu7-9e?>qOlug##b&9DN2WD=CT=esq;1MkgvZqNIv4t+!8&Wo1TG z%Pe=0WCAcw2*{#LXp?)R9_T-PWo0wF`yyut-8nDWQ|f74eO9uvt2^?QJbaI$UO?u? zHpKx(RkQK@>nkcItB9!fGJM4>fkcx9VUe23%4hPWYF8Il9fBNvDMhL*ixFY=mGj%D z%CfSlyMnDVvK7HGj4r^oJ$A(@Xd`yP2LLt)G3|_2R#ZooWuMt1LR`iU{M^L)oD<%b zNQk*m1_wdcs~px=Qal9R(^H~(iZC#F_W1)zW_FB6%6iBF&ifyoWo1sz6cTqybIi^T z^f9z~9eIB`%F3BUc|%>*Pp>1K%UzSy@POo&Nxr=!=j6_ttbc9+j1qY<^IvNx@om z3Qh(xH~Lg%h9oDxde&A{@$jo3?4+776T@>1fHY<@N}o`6H5}BUjbtP!2QD_+va+OS z=PEP#Lfwn8B$J%R;OBjS+K-hK+W<#Z{{ULb%972fhY7yPi4qcWQ~(Lz1OEVGo-|pc zmg$3#-s$QEWo0M+VeY1A3pIsU#AQYa2PfCPMS(ov`jJ^#QaAFTf9F%#i6Dc%1_d%| zilWsdz~&4$tgNcPty^#&5c(u{+caQ*Iw^0C)YO1;=i+}V%F3{RFV$2(nENHMG4@<` zW+47Fo)30q#@p6bR0s080PXCY(c8M;GL43q8tDL0RTXF8-UkUfHVN{{}R$0AtS#r3d;W` zI_m!j9UBb;?TxXqa4<13aj*#SaB%PlNeJ)>NXSV^$?0h6*w}>srv%~uw~}4}K03k` z;t3K0Jpd6O0SO=BbpSvG03aeE0N(ij5h@xo3OW)15#xVi({}(w1SBNHH@8tyP_WSu z@emM^kWugf1azoeXoU2VM4Fb|9^pyE3{v@Zedr`Wt!W-B&*b{|jMCcH5e0<}Guvmp zGB#e`ktx5=`E*D>$m)J$D(ctsNo|~cQ%{NTKkIMw|BM5WQ4o<((GURWZ&F44|Iauw zA{q(`D(c&ph)4ird=vsYE=g2EdQEOik8q+SwEt^+nwUq+bDIQc6_LyE}sWM z{IAJo$U*B+4J}JQjVe=iV4X_gozoSbzGd|`#?2znfxzuzeOTw?V;p=xh7^(#d$@Z$ z)Rjzt_vd*f9ys93BnUMd1$M}(3o$V-ktYzD&uG-O>A;RM^>0oyOj(6MKWj85Bm|(V zhb4=$sL9oxxsK8aL$Wickm$qRo|yAlQQlX8KZ;$G$Dv73>~%@Z^y*>R2Zl)+P?6T) zx4B>RPmM&w*D;53yYO|}wex7U-}f2!j^|6`G|*~Xyq3cxaDZ+uoZ z(CKtHlCDKs-6=46dH(dI_)UI})|#fwd_(P5H_brRjHtyD%?m<;ctBZ<&=hwD2I!$R`?}mIQe>7uUSm(D9EO4O?)&E)NCECd?!JMDgCbyFy4c z>SkQDtr&|}`YY`jsU0m0EO|QQaazM%-Naj5keQRSGj_HXfyYGCVJu(*b(3QKWp4Dh z)y4T}>oIAy%7Cw=Skz3pW!8Q2MBw@16i48fp@ss`%!ntk|4eMtRH5aXNOj*I*!S4v z-jwPULCyT_zcGO!{fqfZlbKQngjL$5Aj+#pjT%jv|(mj%x9MK_37J)8AG$vUIF-({oZGwKZ}`5);;Kqgmxo=dRG{t zj-OHcwr*$riiE~uVZM+eJb1D=x5%zdsmJ6Wnsvx};42{iL`UBiFvuGs(`h#cE@nC< zqlu1;MIzcTM0Tart=%v)mivppN@w=Xr>~glF;?&6v$@7>M9>#O{mUVr=*R zzYbJp@f>M26otI=xkR++oEl9yS@;|}=)KVC-J`YWudnX-EAM@|R6J2cKG#EwfS4sM zp5*QHRfUuRXQ|fGkR%z|&1r?u$Ac5^`DU0FJvb*ZqBoB7WANmp#Gi{=Y{f0moDzIy z5@Z`U*WGpPeNBoRc;=XBo41JXD~niER?&F8>v#L2W4- z>J#V_RK~lNIP}lBPHz(@H3((5 zH|uVl*YdtDsZS5E3I#^+RkgqIm@Hl81ra4 zK3dCx6T9Sy_ngp!ho;%gp8*-@P*&141HwA5rAMd`QM*na+&CV;q}bn*E9#Rv#pjP0 z>Q2F4mr-TtM?MzZZP2(-fne5hfv3)SAeL&tbdZLCqhX| z%4xwue)AZ*Bc@2`*}?HGPLTF0TkLrIs>}fX2L4lBLAo$>J~hGFOIma|Izd@5^)aT} zM~rbb0&lL}7C;8OcU&!X+G92FqMs zB=I1BAKGf#@XN4UZkWM)-_fAl2uWy zZ}3-Z*pN{ojaS(Tmw#C)5%Y<}Jbm?s>D9w6{=sCXyuVr;zfG3+1s zQm!<2%kca|w5)TLzB6i4PJ^MVA5V|WoE zj?ut6YJLJArxW6}93ATcX8ug3zo-Ksa-wprWKnZy&Mx}+tdONJ!yvR@pPDGC*j#Rf zz=>s$=q)ox484y9RVP-@jsk?ioL$$G6<@#9n%B%Xov)t6ru^;F-I9AG0HB&V{qF{b?BLAk(pkjPM=`O8)O7YdgK-P@r9FIej=8)YhdQfVM~#Pp#MJ zLdBY|6}PNsCW-7WNi|ef_LHxq0(7DC3Rr1|I2|uiC#4J8-_9+oM1kWjfylR9DeEDb z%?&z|rq<~OKe>f<@Q>tdtVeDHZf3~nnBCfp14&5T4pp%`N6x`- zV$9D0o;tQ@Y|1ja5}KpHT+3?y?zBoUOLTcsnI-s3&Q|HOPI5zhPvys8R?vvxeU5zW zGBJ&|MqAoH$lXdB&seZ*$UCtO0Kf*!I}?t)VeWjQ5lUFGo4PviJtjHtD`Lj`{RwI93*udzR#Lc1K$fFC2{;bVOZ5_v0|v{(V_o2ejgwj;Qu$4js`eJM(P#W z_bP^dNT^Jux$~dgohi?h8M9uulc=Qg8WH$w!NL`Q+PY7)dm> zfL9J$coe#etoZj7O6J8iuj(=^JG2O_xCwxyTO>mvA)6uX{qs~z57E!e0D=bE(}N*V z_3+;Lc%cHAW5T%Zx`go+%H%5`0`dy5*w+mw3)}pF0q_(rHfy<2z@p%VX1lq$hi06X z!{E5T{Qo7ISYM62|3aER+1h)=RbB83nDzLT0rg9jc=>MYvWBO$9UubtQrJBU4xh{P z`)bFus$p+6N>Mc2y#36&H^=T9!3L!aYMF#xmMhc*3+gzG=_*W*j<;(ot#T?Q%56ZY znkKKF%Rl;|SJ=2e`c@IGcYm!eyn+hW%U@hNqCGn~jx@CPF}1h^i8f-eemX=)qj?7d zcd_8ZlR7O2D{1TB4v|M9TF>UG3AAgO#gUanz!jTbSR+<$)RmKzfd9;^OkRpbt1-vZQP^%!V5P1xMNB%TlYoesp)8X>34@XuEDWMTT;Ww;SlSp zi;*HAlzuHRp>+I+G}}|%EKSqYr;u>A??J3$hqB|?niSCtNbt%?~u6j^DE%LxlrQyBTiYC?x4reU8hmKF`|U$zZ8M4j5&|s z?9XFe|LKGEQv=*T>aB1QTw%rS-kx4p>-uGxvV*Gr<>%OEje+toG+LAT5Wi0 z1SU#X#Mho?2I8*&eo*v;6pGezhM2&>-c)nPpzj?V==9aOxvemhN|U0{{qu6y!WO5G zK!Y?aVWbF;;khUH_6}=`A3Z61n}*~?wA{&N`>#uJ33+w1X;F_1>qfxuJUTKuMQl&e z9}E&i?n3u;rxC*)ZHa@fcPQDtv#$i`-F7zXC+4?9hK$ED844 zK0kPD9}}!^1HnK6?wuSETKlJ6pijKFC?If1HQh9M+T3doevG&%N6ZT^^7 zFWS?aatn;6*1&@9`KZ1T>M?f=x0j-HZ zao#T)a;aH{-do(HDDBm-g6QX^sx<`VpQb#%?H6}*R1$V}Vxy?$;5Z3rh z@-RI}t1wJAUJcQzt;+?5KGx6-Z?Gr*a8V1@gyDdS2xs?M&U{2K)J6YVu4{SG;mhA{ z1%_lEtIzu_Inrf8O&V$0tQ`S>`*(SumlZO~JQ~TGsn+31jhDe$d77vMs=IrO7x;hv zr-Q}OKE~ORNrxho=`T#YXZxXKC!&nfXEUqpEqIH+zNMwUIC-b3FnEh?3M3J2+IxeIsz_c!!v8WbLDU=g))b$rSV`>wXJPO!(ATK>t>9-;qRp-L1#|9g4~?tV01o?>>4 zx41;c!~`vbZ9e7A*t^ixwRc6JTx@|j3HX4Y7(}_9^32t41Jz?VKF})`vA0cN^rn;o z^r@==K78Y^fFFr3c0#~|PjN5R8{{OW73@5zz__&axKNl7%^~0F{O317!V&6E-nze1 zQc_Zh^N)?44fB*{WfYeyWeFb~+-UPFm|L`UVktq~aTFfLQR*)oP>;7M?;@-1SPdim>DCt0Ra@8`d4l%B|CLb_p~K_uTWp3!t^&f%!69lY;_$6ZM^A zM~@^$Vo3yMbZ`>YI74K-D{oPnNy>GT<$f4OFW3%kXWJb><`d z&RCZnF?xrgWwgilwg|s$KtxGVZFtN-JY&#X!X8%xzgtKoK;UDl^gRIRX1d+C^ z4{EFosCDea1R>L>Qh5O<$TZJ}5>F;yUyeE4rfFtVg3+NWFJZEl-WG!Ie)C+hsfqh$ ze9m3iC=ZeBr3^-xesK7c9IIH4op!r!T9%_?wh5zAmCN$>9WdUXsD)e>3LhZCWGGtm5}r$haPq%B5lapQdw3=M65{EJGiC0Z zB=Yb$J}q003(w67c2{J+fk56bhe4Y?O2nh>p_LFdfmO{8Fm%j?olf*Z_|YME`>V`# z6f3r+C4}ibF5Z-dSP!k5bu~1mV7A@t8#*0hoGqm&puGXZ!~e%34~# z`IWC(v~E?j_yI9Y8}&W0I@^Jb!?}0p3FouY{SVwipDNL*ldS){og2(ECrS-9`2s!a zLm%GG5&6p9{NpSC;VAmhINzt!vIOICD}oI)*KakamECy>Jj&#_I$Td}MLy}}M&w25 zJWW$C)@w99Mxmwc{9+X?RejY2Y@UfEwB`DD!5inBW`(BJ>=V27J1q1m^mL5(JYh;}kd&jIeKuso2Y^sLW+ z3FJOFiEK52GenaUT#T&h0?3$l0YbVCK|Wr1)oOB{>clv5Gecur0h)-_a%kGQ7R-3s z(^qD4Bip*c{Y>_h)E@DA>Xtfz--!_ZX^zt{Bp7N=h&I(dMD~Ho>!zAaWxLfGb}0VVXX$}sT9hmv%L z1K>NJVbQKD!CB5H@=n+Mk}p?bo{Eo6`->ky^e6bSNsAy>MVD<=j-8S5t^xRxxt^@$ znDVzX6;YY+>sgNFpd@R`IOtkZLC?Dfelj<&0d}5Q{gE2Zau9cFb+Gz!Jx4h9Gr*5j`4>Y(zoY1@3A>90roD;)`ov#4Uk4jNR z@(l-R!9OwMC+e$PcH*XX(sO)@H;|&o%NGVyYxqK`kB2gSJEuj63}r%kA)C9VKHEh5yZ}{G=1RM+_IE|CIg#VRBcI{L}NNaClm6h;-dktmhjH~I#PX|(!L{lK$!vX)pT2J` zL zgC(WJk&SD&Wly!c7NXRHyFM3Tk@;cLb=D%}-#lYG9GOKK>40i<>Pi2OBL^oi95{mc zrzmorzgyfl;`muxE_I*W9T(LT@6Hi|DG!AFJpdAmLWXBuZR_Lp__<|{DmlGIP_wnx z<}=#2oevIkEH`N)7 zkrkKi3vet+79U`+!Jnd>6*eX-jNTEABONNj_Bz-6HqT6{;=8ZpS{ad9G^7a=oeAn_FH=DZ?M<0&wpM5ty00`Na_)pMsDI z@*i}hKT~<9jGdUP<4PI_6DT& z8RMjE`dv2w45w;4>qOf@@0QW>1&O7D>h!&jwTdchh#;z>I_&Mtg$&0GxKGrQyFvTV z0u~__=-$l2Gt;h#cYoPwE#>-MPz%JZf*8 z`E@MOC=?f>R{)v4FCELAWr6rwj{K5a(ot~J?my<7yE5v!A&$cSpHC!snOu}BaBukLKx(g18B~0=)!7977&E9?tjs3)$^f{ z=PTmSpl27;ZTM#=HmqDRm|PP6ucm$*$nYpjCIGU$8vb%mg)aVI(qB>nW2ZCR(9wkR z`KX2g|LO!bO=I|gV^3wKtc=3&-{qeOPuEABo5nUMW4S-nrR7W}?K}en7$}Te#f|C? z4)+*OA(~sb$^8;q1@BFGU4hgoWx=ZMg~cuUGk;EiX)Wkb)e|DlYy6@2A~xsc?RAQN zIjj)G*|~dEfx|Pu5mM`!a(U9Dzmu~%TxR<_2TEfs-$Tfo6`=-2G~`8)WRSa7m~00t_3yMAeruzzTP_f5bUErV^Vm&nxzKA7lhHF3v?I* zjjFNn2nhU;XQ>BcLJE)n&dCM2#cYiqTc({ropOTWmM!zu-vf>$ww9o7jJmZ?-j7Ms6vidPpU8?<{4sKS3Ib5 z1uOfQ<%ig9l3V&4q3}^9@t1?PJGSGyt!Lxa(|LVBNa<7L-Q0HQ{QB3HP)r@~Oe8eJ zgiv1m;n7?jJ-P-6b3&`#|1f$*p^k#kvd5!KLN&Q`xv>bsC-2>}&-@|al=71-g3HTd zlC}@x1+%UoiN02t#zVMb-CEo3^c>y;nyGzplwr6J84`dhWW$KRelbFxx8d;>@Y9>z zgBw~R>zIYgaK(pD$Pz;}?{OEe8fHytbR#ez50`3 zxHiAS0n581F7)^BQ20>Qman3~i%?;{K-c=B=nLtKL&9Fg09DWU8kQeYMtkM6EYC0*7kN39OX{bE1Vam}3o_gQ>vC-sbLR9-X^ z9UNR8lRY-++>x7>y#nrSUJ%Qq)bg2Lj6wGZ86G!1+c74-5IG)nZ9$ENxHn&Ru++}0G=^mm&Lb=Ys&Dh z%PRF^6tZmc?b^rNm1d3E`t%PUjP?mw@s`ADpycnmGSzPOu(%eqhP#R@Ro+W*fmv zX0QhFq$9~n2NPB5BU6>$eaTQRHtCf{#ce}cEgLi=jqYKPphAB+dl9mpzH|H9vBF%f zH_8kzD@_QD|M&hhf=fVR_?f_)$=I&Vh~SegH`}SsA5tMUZDb5QIg}K&(`!t3#yCR>g9fP9`ad;3rEO zXdCJy2y5`@>RTWOvd-Qt*_z^u5xp|R62Y`~iBcEeXl<>5NJ^gx98n!{A^uiQIHn3J z*sB|PY&wv{IXP!T+;qw;+o1iEbfM3&M$Id030EGD309a{tE9G-?^mP}AxMq_ent2w zAOhM1Wx&b*He%6B=^5vBq~r7w-d~mKk)vGyNm6EM)Qekk7)#CrwGPj;Uj5x6|9LVk zuMOmkRRxEsXZj%`3~}~^q}S$jDXN6%ewSbWXD63~a{lfGEc1?z=s1Z}t3S7%XX$xu z9|b60l5f4H^LBEID<@Q1Ze!w7O`z19Eb!Yf`RyK@V_=j+0PPjQ*U{&B@oG7t`n^{` z7tK+;!Ii8_bM}I?DSn{CH_O<#cH%W@gwt#CA3K<-@JCSa3eSDsT=joVlir{mx}U?m zTty?kBq%8&l)iJ{6CSBWVOV?eDaW&5R<81Bp}$K=Op_@IU4~}tgvBG;zjotPM|U8YA;HB+f`V-3M{7+1nPYY&&hc@D!CZjM zQ*;IWBza5R7Xm?sO=X%LBF_ufL>-IJ^bYh?3%u$!xnEm0Fl~ltefET9vfg_;`Mj}& zVlAgxYrGIN7vFdja1hOA&3vpx$X2Lt(V%(+cR=6s3Zu>$>zK=(wKE@Y1`H5rU5s|l z5t^RrhpGQ8Xq<9mXL;{Y^?56;Q`rfQI^=2J2W=Z@SJzt}H>*}bpjovWreR{xTUBs@ zr7!`)V~xEd>;OL6f3XME9_7hz13ky%?2A@cIC1k-5fYfl=C!C!)Vwk|cv*-rt4oUq zyT9V9Od;Iv?njos;4n>~Rfnhw5|Rex~MfnveN39Y)r_ul3GS2IS3O0lL$89gj+((GBvkv7t3S z<8j-TG*<{WkJm*{{Fd({yXlA-=4IW~CyJ=trb1hn6MPfyVkb!u|Lwz&#xm}-sMCJ` z-P|<#^joZo1Z&NGY)f+i;VsKzbbg>Y6QRjpa4(GuSU#Qjxd7ad+Cn(-X=-gz{%*v- z-+#ME3-)bli`Kb|L`p~t#wy7kri;t17X>~wHHa5J7yRXG4@%+g8noeZ5#31u?BZQ^ zO?3Nv+g@G`#=Z~utUF^x9=TRKj2$|Ilna@K<+a0mid^e-XZht34SsAd?#k5?E~~R? zud+I)1c~+(Kk958!C*@o_W=z zcR495x*p=xhSd$5gz9gkz*VPsm`c$PU+5U9VPG}Sh{M{w}^=_;sQ@ZmM zS5hQbL+pV@ZnpY}-Bsi~e%HkWRvKuxljEhlP*b@wm4RP)n&Ci0!YNpaUt@^IrucaI zO7A;!|S>)lH1CcQoCM~1W> zhTbWmFn^tB`w`I=FO69nkbW-@o>${ek^i)P;7e+{l7GfzF?~K~MeFzeKu>uqPCv4ZHPij!bi3E!oE)p9_bcEarRw=v1wOY|(xmdT z_a*(E$JM*q#h8-z`gh{>nxiL5YnaenmosemfrvRXlUuU@pHP>A+T!xX z9VfQ`G~KEbtRmaWY}jDCoTWN5#!nV{?k>cx2+-g*iUe0Br+vY?YcXzikMsw9sZbHf zV#_{9r4`~T!%)bqZvXJEH^W`~UhBmUwEKaBon(S7Cvtw(V$cc{d-e*b2`t!6TrUJ| zDra|$y2TsQ#DvIrP#ZL9UIEUMPdvr99$%={9!>BMmeRPCE*CVl??uN>SuL2I}H_AsJFQaarjJv_(u7}jf>46i^GcGV) zzLtQ>hDtwj<){xwfw1sqi^Lv#8$Sl+McoBJZ?50-hZ_ELQQx%3B&Aq!fRG-jZ~_F= z0U@E#^NHTUfN;uJz%;a!)zKEL{Aa@^PEkx_5<1byB6T@H$=vr`RauyO6}IT_qN^2{ zNJpdi?iD}?33YQEKX8~t6X@M~(cPat`izD&CqdCdoeJJh0N6V}J6M$$v^V^$C}3~r zF2aV+#_hhr<|^RX7g_Z=v-bdt%Er}U{wUC%cijuCOATB~TTko3JA}8l$0nHBhuY5VMzqG~0sp-S{x)>d| zFmAvDd@s|)0{gjQ@;K<*t^$gMp$J>`;Y%%iRj9p6m-m|Rcki~D!kT;(vPERF;825| zmO;gF2IhCTrOgLJspKNmr9BLj+di7;mYx_t0qwz)e1{M5y3lIO!Csuq*0 zmFUjrn6rLef?_RQldt7X=32S28GxkY$D!Q8P#|Z{TFL%{@7Ch)8#;f6)bInK_}{KW zj5{~gx%t%j^bS6H-APTFpJQJPHl1ZI!V(QGN60^y?dQI8xt#fN6ky1-R7>*3ur_Xx z6c-A}LB1ZA_xTj9zhAao3@S+amZUqFI&|}aAGhnribq0vBVJ6mkotTE7E1Ta0dX*6 zU~SD6Tf{dNjXZB9edOVZGdZ+b+ej(m5d=*GTxE9pXn zDwyn?sf@$Tl#i<<+&(X_GTO1Ncy%u`3e((G@hXx3jN2#UgqK%Wv+f|2KK)piR`bK4 zEX17sKa?-Pp+EA=TU;WCfE=`l^=mO)QV*afemM4Ra?Vv>8W15ieWWlN(H|Af3 zW5-sW11TF-X<42P7X!Hpq-JPJJfec$h2Q9n9Q6dCm^^9&ERbPJ-=Q*!V#fC6!q|d& z-4p_%G>fkZ3jIi+70#lU6cUQ$uR`AIN*KYIqm;7Renp;Ky%U8quK-2YoT9vvsCKJr zX>6|H&SBDtd8EiqG$mpmg=b}qOC(tI3oirw{b^K?{mti=Zu{X09F zRlZ+vZd9HH!^ea5c2+&S(Qrm5RpRsltMfI33&o7_ZhIp*L!Y#TcYCRr%}=4$bH{ZmG!5_HLk7`SMakR-3b~(p zB$a(t(jg30+ztQP`(%@ z`>pdD4)1N3CIi7|mB^PLbL9fl|M?vWEH?fAbVN)U+Se@3E*rx45F65et$M|$>LxWu z)H->O-m^?z55gH16mcZ3Bx#;b486ARSt4(V@j{)WL|_PgvrV4NVQqrz3ksQ|v(mDM zVI3Rmi67$D;Hzy{87YnSqw{3TQ7s zOnk{|Ob&G{3Y|}>2tY^-3<|FZcQ|{&%21uxGvAP8YZ5QY;|@O?kQn%gA3uf_7;su` z>Vi@YQ>M5I#@Ry=dj*K;MP-s%BW0}p8E|=wAvY8&#janGVMwL>(ZItohs;IFSf_g2 z=&-=r_I2dfw~Fs+ErKYLBS?pmT@o*D3Ttz>*gYBKFd};NH2GTc@7>NhRC-PFJfp(c zi9B(igcdmc{bu!Q&-LZywNlS99LsZTqpYO35m@fNz`}T`+sgV%4sJ#sbK>fcb;y_y zLe}Ad{QrrS1$$~HAd`VD&?*nJ(2|(|=us5v(T%LQ ztFsRaE%?jARK)^pq6(#fc5`wegh#4ho>W~Z1LN?46%6RRWD*{U`fbH#Gr^7W?r}}& zvzG(?7cLIC5ibch;D(03x(`MMwxALPr2vNdu(6Qo6H>zJCNscaZU2foZPPTfWn>-< z#&3x`rA*W*L;U;m=eaTYnKvuSdC9$DBbdzqY{7%e^36Um#!L!|@5j=^B0u9|OtQcZ90gqJCY?N8y06^zOu8O0T4g;eG2!c4Z*j|C}CAx2M?`!zUa z4%TelNh1Fs1(zz!K4!|7Jb;@}b!Jz-9%ufsBQ^qY|kVVuA2llg+2S`69semI^~ zoWECUC99e$bd5#v8TFKZqJM;~nyvPg-1%S?G-hOYM*C{Q8MAyj0}&+0_}t#FaVs1W z$7jpXS|1?j)A$PH%rsB`FR^d6tNrxr&@XDS_lT6QzK^2?9CRNY3aqIdy~`rbymzbw$NdQVfZ$kS*V z)o+7ejC$`@HRsrkC?J$|0Z+}Cih#)3SojO#4DagCYIcqSbOHqW_Zk@3+(wBT1Z-Cs zL5=8nibOWw?C|rJPW#{CqMgkwmYrNJZgf_z(0d@u1SF-~IB;|8G;|0T!@t>J5XDVnPd*7xbN7Z5Rc7eG%dpE|I1}mBH*0`ZA zo%vHp2r~T>(ifk*F8gryU_W)1H0eI10t&VxEkTo(yZ-F7!bqXhAOcVjjRNvN6= zeGYewT;QXR5BXsU*Qoj4wkH(CUmMz8ts=*Tl~H^Ik+*ieAmxoKEG!T!OAWM@hKFJJ zlccX=FJayD)eGt`2SY|fP2v#^Dy2`roQ|;FrynrgY47WcN#ib^`PfwJCZ&o5_dKNl ztjL^i@fdxJ-nywg!zMtUbUZ8x)R{kk<+$@z+86R9hjUaP-KhPY*bIlY%T}8q0Y)2S zu6yg0Rl~;F>yOY>^ts)Kv~B{f)h_PF&Y88E%p>vNV}fWfc>)tREhJT?`q(8#Mf#Eo zsp5Hw4+3p8>!c?^);jMw+M3wL8BOtWdC+k6ibWwVF z3Q4I{sY(_&E>QNN_&7p|(~9;_@`bz!uOjx&r%HK?4?T$SC}~`$w@qwYx9-WiC&+4) zQ6)>gy4?5pGVx$~3!CD>_n)D=s$+!sbX+JX;^07MCVF^u7bV1aFT<5TQyqSIp2|I6C_8kNF`kzg5`7oC%uz~* zT?nd@8qXa_Ii_OVX^>OnKQBBSt z?hD1oWsPM-`jV7B{rl450p>E)u8cOfJWUyj*w4dZIZw)kmY{w2{)hPo8b3gVVPw52 zCRV7|ZT%xWuk!4IL&(Ema?taAjjM2|O`bU1?*8CUI8m2nWmj<*CNU#MG|>VoBm!4t4>tc-Lr z4@^PBC-S`JWF)WQFfqvB=1sf%E<}ElyjO=$;-kr-`kli(O)1+@wESP&9((hw-~Q&E zpw09|ryGAPFVa3U8XAu1|IUuL6{#oGbh1lA{Y%jFt`S;hr%#;Sl7@HNwRNv;1=9-x zh?LbSjf>(^q7kAchbK+HT2*mstdJRZUVuf1ro7_{Dw6}TP80=7w!XGaMAkJcR*}d9 zQ~D+s;(9v#-LMt%CCCnp1BZ27`Gs9f#=zcli3+Rwm{@tvA8#nn_^eEDG?u9>YKGy259=FEslO!h*gr?eElubMZ*^x(IP=fnUZs$UOXrB(Xiu8UC z5p4t=gqR-uA+XV}%W|Mi@XGBmG1+~5=KCFhe<1;bLFmg;)11$jo`zq@&FSMb^E>{P zlG&0WG)+$U^u0mlRz9WL$MD%KPYR`$VkwATyQ}vvI)>VDw%0V0gqb+)L-mokI4dB=%hh zQGu$;-N?mSQj6H0Lf`a}XPbmUgjk{Yu=Ia>DXn>HL5Zk7PKqD4TLfuD-_toLST7<* z0OS+#$abo?OA9?-Nf*hWnO?w z3q>k1vR&P*=km6>P8UkM0?R%ux=X&@^3bF;2(qS$NU14$bE5HUIm3ls@ zs}h7zOXBkinBc8AyB(ldl$s;X_yb;57aF@#@lEr^!MB-Qwje!UdOR4Yx_gvxA;YTZ z){PnQko`Wh{>)PBTP@CWyz%S3I0oEJ=W~E-K0yg6-}*i22wVJ~oCjOb&(4s#u?ykL z%E$Q|)?DQ^i{>?Y3{7MdN~AX9>$t7R(?rRI!@_Q3p_IaQ@V3HzbU~S|RKF97J*~Nh z2uSj&u>p=Hnl)fnUBTy`QRJaBcM@MWCqwtcga$0w2hG8ADOYvnh@Tqpi0h%^0;TOb z+wvdQBBhg^o+_EeRPK+Trl~UGFfva2TD0%kuC5J(CqiVNS8gloR%nZVbmP))XpyjE zUU;k#@bb->QEmuv+)Fe3D_CXJks==;rLhkLA{`0b`--ikP334iSM;nx0;AnH!X1e^ zVFDkszok(B4Z{k;2^MX5^THYC7oX*U@B>QKQ%p?9`e9MB^;3(PlgypREYS@MtFG$j zEOk-Y<<6xM4WeSo)~#w!?%?M~hv~1b#do$wN{OZMdtCoGPkfU(F&^R^P=e0C%-i%V zXvr(H8*8rHRry5?q5m=>mU(-PlZqzVbhJ6cy%91W4LukZRO797V%Ji%$d>NGN~Abc ztY#h{qR&?Q2y*ZqoqplTkewn+mn6>7G8(4o6pCs zRF2QCv^Ku`tW9^;z3meX4!m{7i45_^^9RVDL61|7UdKpo+rurvA$oe9sSO-*zWn|V zjw&P>Nu5>arx#z>$TR}^1Agr$xVgTpU*9z^?I!c_@#g*UrRCEA1$m`Id%P-0UY59X zp3x_Xr0+frAow4H+as4$hfl+mt!$P3tC3ATktI9r1+q@>! zNaye3F`AKReUjv@7jx5)Rvb+jJ-4i(a9plS+P5Uf7_(Fln=sLbC3e!S)LmRr6G@-v zPg_o~Fo<($LfGzPuDP)JN&F`Vum6ZiK$|mEoMR1YZVJcm{G%hb7DrW@8C4U`cXvF; z`w<;Edn`vl>}4oY&-eXUuEJ<(%qhbA*ZkcUipt>x3<0HC)F1o&_8cq8) z-lR|p3Qo}|$!ZhxTE`CzF;vk6_~SXm)Ld>Nu6#GZA*J>jlZAf+eW75CTZXL20xdIV zmHJxqljc>6Dpv5{gbP*i%Kie z5gvU~l2_L691NCG3HM|`<+RXz&rmGrf`DI=|HI}(33jIr%L%@&K+PvdjA zF?D64fc(=$329B?0o33gV#W45c6R-k_gJb8c>#h4gs1!WI%VD47(X=Q(1`P=md9NH#vvoMV!R0KgrB4 zyP1=D7q-smn22HIBfZqocH07cE|Su!P> z(N?C3&6qdzJ#Cz-WAw9g8tHzJ@qTZp>An8&Ym1LiZz6f7(ML+ima7dH!_OT7#h*#e zRC-78K&-a1L*LNJ;x3lAq?Ca8Vx1wiy)B8mD=Rzb;6rHvJVR*yv7an-VCkELJBGUs zHQs&TYz3j6U5UdX`(CTDQ`O0Dl_;&E8Iagb9_{)2p?o8PnJ9%h>f_WQ3>d?z@f+kF-)Yz7z&PYplj(43v-P)A&U1q%uEcj3lT`0 z|Jo<72#h{7Bzc{izz1@y6`d06QqxArbT=$O!UmbG(1EeL$JD^|A+nT(A#k|>q*JI! zF52WcQ2-AN^AYAaI# znJMI`Y|sg`aBu#!j%5h;4#~UN91bqPsPZjio8tHg`7J?m=nN~>qD%s7YU+!sOyw!gwe0?*XRj>|EG5(*ZQW7Wgr^Dxh=#Gq~e2g*P-za%OL znA~HIk z02C2*j(WMR)YS$!rr$G3Bx56a0B-dB@t!^P%G*vO>S>^?**ZFGnX|iaJ5J6wq^?wS6*kDtdP(O;G;$KGkLf@&js^+UeK%NJXS~%KJ46DerCA|DT$F5sv2spM z1_pDTJUXS_%5O_n*wK1hZ~)`D`Bq!~lkn^f>+uD);KM2-kdcv+I(zX{eG44+?yIYW zR;4*XEM}t&Mg~-ov=h#Ox`2UqsKMMrR&eKBc!)eQ_n!M86;@g)yZwSag&T^ zjPa#y;yI(Z&ayt|2Q0v2B#i3YG?q)ZmDC|<)NRgscjMlM*KhROZ4S#ywYdC2f_InA z3d*=}I03zn6k+0u6;+ppr-_JpDViaS42ESGKR*8eeyz20Z=<0&^hMw0NHvBRTHV7h zA>_#U=A>P^TIEN&ph+B%6^utZFe{Ll3fL!WeGfVw6w=906s{Ilg|@U?4oZ`pk~{OK z#nYtgspyuK=8=@dtXe`4EP&-yjAWCJG$&`HqpD*`QyiXSHXcx*mk2UZj(GdVm)mO# zBrPUGg*=t)1$;EgR&|eQMr>d=OwY0WjB-7&PTe!_mil`=x*BLJ@R6BSn5cJ9Mh0>?2R!3Cu;}ibpqMn53WSb1BitPo zJl(*ID~?78b=0k*ic69X8My2GDXZArJ1h)GpkcTNpRGewUu{f{eZ93Ec=yz} z{f@Fy5^A*oRM>#kf*~8gjT~W^uNhVYKB36SKH3Z%%%j}V z0A@2#0>0pY0!rsU&sLHwN*P8#8?X}_&M%={WKPyN;nc`1V$NA*phP0dB@xj z8V9XBzWjhW)YVx)Ij?YQWq1OcdRDFf z0BP%;o3=m6q2nIf4yB82zMmtXEq{iO{11g8=o*HNKpzu1&#@~Kf=Av)gkpq>8gcLC zC-52@RpDXzf@yxA{{U*b_S`5+;~oJz4XRO+2;)b$81R1a^3Y{s66^*z`e}4*K_2wp zi~KmI&r?}|Q9{uPisNw*0aY>vd8EP8cA%tyX) zr{{xF_ zQ~6eQMGt4Gw_r{W-jLFqllbbwk(5RL=s$yjq9@=dA5OH+ z<`=mhcGH(pkFQGDcI!%|p5CmZD@g!9f(>|5}p-MMj}Csf0{KJ>=lYJ zv=OB3q3L%-vQCU!k~eoWsOx?svB;9rWl`T@=}TFyam5?Rzyw7s>`wp=N!R0ARhO0i zT0N56RTFZbmbiQ|1C_>wpTWxC4hXAlymvYrNC-bZC=OdvEK)w)gi_6co)l#2I$Ei! zB1sTs7zS1z;QNgq7!-_ai&K;HCt2&C3zTeQ82MJ3&&I0YZo$dxK&@np*nR+O)AS;d z$NoAuH2D7j?$@u7Gsx0O^cF+V){@u6@Jo+Y2iAbz%0bBE@Yg@la*pFn2BlMjj&;P+ zjFXRTESF4lY;#W_)!~(L7*hIMQ}@BtSuKp}ROIQ7X;p_Kztd1;qg>}27}>hfLh&49 zAkx^|ojBLIx9EQ6V|){{W7my(nHs=dXpdndwzL;0g`>9?9v!Be>4J;(|!| z#&k&09AFJ_Xqab>6&&a7m0JY!WipZ@>{Ob2oX2i!saTJvG+gHVs+=CfZx z+bAl$RO%BXM6x|p?VqyJd{I?Da)1c>>GRT)&n1++jLzQ~a2uH9;8jQf=j1rjhr{T% zc&*jIa*u@9Zl z5B~s%msFA$QG|}76#oF(Q&_VLoc`ZG^;Ao`FZB|kfd2sWGw1&Rp`}NNJ{4Q~s@X?T zK&el4saWG@$EHn@G^2Js{TR=-oA(q?>IDA)GiGo54Ru(z(%5i&%D%(@0L7%x@ZHU7 z3&z_>mGkUu4I%>!RdR$|(4#(yXww*p6 z+o}4trj9y$&21Z-Wkix7+rKL;YIy(x7=!h~jXL^|plsc99paj`F*;VSkx;xk6HN~w z{Jvwc)<)|qCHKSH`)ms{$5lzVLsb@6Cwo3Y`QgS#*ILMKpw%L~h_a;qSkD0Gr%cfD zFP1GG2<6Bl+k;wK_2JC6`)QtTp}5w>CZ>$jPbT zYDsD>QX?6V;L8I>O1b0hC#N~?2YotvSHj zMY{81iR}SrSonGmt`IopE0i9Bdyq-_01Z>wgBWQr~RT|{yr05Y6m z!R$xw(b|;u^1&Q}R*jbhafMtJ}vaJN#Pm8X(;{x&+VIcfJ3BLxaT0CVbK z04I%SJJ(UzdS1&P!a4r{dv0_xJkiv~Wi=u;^CXQ(ZOU=!e#5Z`R99aadTXk#)`+eB zIW0X?UErRozDksmS(%tFT&gb|@CE?(8cQlqt2_>4kV7170|EmQc?X`<^HA{Q9u2#S zS*{?O_)ER)_U=Sp>f|20bf%X?buDaNN7N8P=A9OzwpDGYC5~2#Vn~n;%5tOZk)Rvx z{M1%E)KxuIRI+;JnaqyGjy*-PPN+KK=~>g&{aH~-GeYL~EJeWNBed#A;trAZFjqXQ zG$jJ$GCDDSM3_-R^P5x)?;HezovDv!(qHNOfGtZ|FgRL`(>Hf- zb1V~|;G;|CTPX9JsK!2Gi;n94Vg1ac9=?|TRe3cPTx-1xu=ms`l3n04p8o*(#;vKm zHS3gMQ>7~Lo>{4;J+sCchKj9y3Dwln<+?_o3@|(tZgGxVBaVB6q|<5|TxTNgB7KaC zKb;!3xAG87GLQKhvn}jOdWQVKIbE>@1CV)5Q43ApcUabrsf%Fk5Vn4NeD%7m-7nWP zvw3jz*ouZlVKN$(5*8qU*>a;RoQ^*IOQh+Zzonj1wul`WR3V;NT&V+=!n%x}{{T%N zCyp#OA}d?wGys0Rd7#t6*KaJ2#&f;02bOsHX0V(#OUzClI!e@$dosfyBk{(p=qwlZ zfD>=3P!7`GOM=9l@<`U)JrUN<^1tYsDGNJo{?Q6B2iqmju=d8GN6}s*$5>>Ff|fM} zSy85i#z60ukmP+dBlyl&2PL%LVOB1Y; zkf6L$Hw2&BDvJP}9b=1|rv?3EBT!A8$I2&+& zqP4NlttOEAZ{V4uV8d}!xM!Xz2X~;q?TRTa4=9RAEbB**vND8V`CO5LTv zK+7ZDG}uT$#x@eiZauNvTDkli z>UmLwomCSd1oCBZp4iD!bqb%sdzCVO_)*_X_oXCw|tVZm(cmA>87Hj0?z6v0%k3Pgmv zKEodVLFWf2>#bu`;N8WyGj$vc$0t7s3m?R=C-2n<`-@8)$j7Oj>H!HLk};nB^;JwMt@Y54Z?t zTUc0+Q4bpP+x{%*V&UNb07la*W~RBOQ;?q#67L`8=05ti+r^q8Rf;)ZW-+uzcoj_E z4DkX2?-~QwCB{xE8$)%T8@^m_`VwStqvYI9h-)TNi&rUNd)FLLal+3_YD%h zD$)x!$scw$gR|O&e+FvctGdUIq=U{n(x1ipH=w)P>D_}gR@kC0GlnsQ_u2I{m9XejXh{U8I7IT6@Fppt*HtO;yxf6&yt= zg%J=C00Dtu+0WWMlgJwHFG^9=Le)~kOl1X@CX7o9`i6HAxPadxpo5?<3@d*{Tk4iq zuBMWrtOZyA3d$5APFh4NE~7o}H?eBgIbR7Y8Jl0}GM|Aa~b2)MB2;Q=M&B zYCDW7@qh<7&lS^jB(=QL;g;dINF(PXcRxH(m2HO2)D~G5+ffOrRVd3KX!2W}7C72* z+?`QQ*ItgRSkjOQ=ckRNNoqDJ+BW4$Tyfij&wUoXs?_933W|R@)>AW1Btoa%71&!z+TEFyV3h~lWb>;n?piRYch3Q4EQET7eq*mRMEX<{ zM8x@U&xH#hBWe2{b3=(vAMB8S5D(;Vb=_f_BkEQkcq36$ABLwxEUES+WgY!2NAS>2 zMPX`8K;yQrX*P0La1`&-1^mR29ffxdsxm`hgX-19v@K4aWjjX8y9`ThCm9?u0Dq31#J~f|$?9l+I`yb^ zF;*o!f(Z7=$MueTfH}rKo%LfW6w$;NEgWhUTil$I%zJ&JN&06R_khh(tjr|XJ|-!3(1VVd(CX12eA>;C}mwn>N?{@VP1nh5?{ z4|sM{pdQKwnI03eyg)9A*9?gW({Rsnd-;Ze z?osf0?0EdN5muzP*Gww)&iwPBy11COG4#^dK5>8xv*VLt5C z3yi(c_6tkOc(QmJ&|U{XTBoSjvb8lZ{KUFNK^R#v+-pd94Ho%tt&EIQChwU2XCJ>z zjusu?F-tAuEp!KMtUobXU&K0nwY3A}>@>BtQSDsgzdCVvp-<)As}~>ejr??+vh_u- zS>~o_oJ|Cc6oVjgyaGP)$kCdR!|y#Q29QSM9{}W!xZ=Kec%2(d;vL!jjmgj-s<7bx z15AXgS-dX0(}rJ(lId@MC?8o>NkL^^t2|+`wWF@mWlYo8*2hqd{&DoWpPn0^ z$3@?yEq0EVtE;c3rjCETV4 zZ1>7jE58eVAM|~#YR@x?V!XGBVhh80&4ZKLk`;X?)W#+v-98A&!uJ}DP1Bu1l;jI- zSvyF;g}=jA9Z3!Ar!Ean^(I7hS!w43D>N_4NSlUm!`s`j(I;Nky`aaKs4Po)j}M-qP%0b_IWY+<5rZt zHPrx?Hk!~e+|#)JTC?!J_jA8>#g>M)Z#tH0*aWdUDGa;DLF2L2Ed5>7i&Hu!YXnzd zpa3ud`?Y*dG68ebKL`5P*DEtf=p&2}0XcJyf90c&o3~u3;HwkSR415IVKFy5bDnYa z)4#%?BfLu_>d+|ij%8CAI9WRu!1vNyqAr&^y)ARrR5Yy{#HdfOAm{jL=UaPb{LjBnC0dgTd#wW2~O5aT&X~PIlv*4tjf2=m&M6QKtjWMJ#`Qd7zHW{Ljh2S1j9r0{RTua1=$rzk{gBPxK07zgjrrOUyO z3?%FBoTgr%rxept-3-wy%Btou7Q#S(+1z!_;*U>xSS<6d6`O<~v(LSCi@9}ZEzrql zXzI*}0g(RD3O{C>Gh1nJbBz1rRJ9gZ9385E0Cjl3(WAl%p~`gaI5_R+PyC-seyi{Y z!)s?%^qm|wB#kR8YgTkxiNJJmjS{g?yBoas93FiEj5E*pYy=rMuMy<_}I;PZb8 zc{Iy7*p*$;%t6Z>57?_Z`xC_EqQBD$f5TK#P|p^3M)(K5)BYMJpZY#{V5&mcLh;+< zDu;jmZj?Q5;HN@c?j1Q#OKy@Mi@e7Kn`-I~=$aW^uc|}tgIhg6U9i=YXeW5&sQ{1(><_+$r|?svDc{v?bBqI;nT`qL z``QocuL}AinJw=fw1+nuDEE2N6ShfJSY)vv5Ph^&-kk}?Nx|*~XRL2FN>n-aAc}05 zz{mJ^*QbcnXb`emGidfXrKf30b(byr*kf6SV4`2>!~^3+Lb&O2xq{l)qjIa+F-fA+b5 z?`UVMd@AWXe@@&gDdDMEql+lt6)C|4bIH<)G@BxE=RSY($Mvlpwzk;=8TUE=07_^) z2R*pdSt-XnXj)GQIutSf!yzC1M4#iKUb67Bqv*O`?NJ3Ji#$|Qylg5Z;n4{P?R>_B zI%R-3^X2FN0OKFlnn$b6DZz~Z{{THPO+Og}QQDjzZ3)fb{{TZ|pM#KKp3^t;&Z%!c z6?APiroLFIB@!hp?2YF?3=oibBiw2yPt$S$xsy4@Jg@bu1@+5g^$U;u&-A0$rEraf zKTTFVE}0-4W45U&JTmChK>;)@S)x+S=Sj)Of3>J}9vbvgdueUrk5|(4Pfo{IQxnLO&a~hrG7AFa z@<+0t$5xiV4SGmgD2$YCB#loAXKAD)u~13-UiuyCeuc6}aOrDx98FIR%cv-*YOv-& zVVE}T33n(waB;5|&rV0nPbmYF`mx*ZR!4Dm@3cg@Bmj5!{HZn5J!@>~PQB_ojlvmB zHBvgn6KErGSq66z>@?4__`A|ps#m3`imT1|nz;_q9srtWm3z4MVVxa#Z~Y(oTf{EC z>lEqL%(8HlRqLLb;c&kY#thvNg)5Q2nI*A}w zI9}&q82O);hMwn4ni+Q^mdba=Km-bZain;d-Kn)`RSLEX5O78_SqjnOXGv4_Ur^V| zXB72|ZxG-iIf^z`&#Vp!)cfCv{UdRxvzmG2A{&CqAY@(_%5?T)?!#I_oBA7cT~APT zRSCY!6jpfcOeA_}&i1Z^$+dvS+z(95QJexlg1bpp-tHwfv;T7KS_lOqf> zjhH^%>Zv5s{{R&mY?NX(8SDEvp_0SJ>WqI-W88Dd&OyQb^`EBe-j=E9Sttcr_=9a| z0`1_xm9rn7rNh@fC@3t)z(|<%uL_IeZ^j*}i!YxkEg<@HZ zB66UKeY1?{TmJybUWz+yo>6p&rO(R7DW5C)hn$o8-f#!Dmd|seMH}uig%U9*A1br( z{x4R+jvdhc&m0ibDlw9GETNWX*0?9BzeJSFUjxeV#}Q;K+uWuU zs{l&pcgSnK>%-fP%Hh=ZNG{RCQ4-M9MGHx_C20}8IgsV{b_{vOm0bbjefOd6(?wX# zTWXSaH4qc)RtE-1*!FHY2ZN&T8*cXAsp<);scnlqG_(}6Gsz^7$liF3LJ+)VcdkM0 z&Z2EE4dL^jaK>Yks8+~0!N(b=m!39lC0@%#0@l&842J?~MlqIU>BnJNBdM*oixti3 zZc#E#fXkD)U45BI;De&xh`89R?$)@PnmB7xwgd0AzgRh6k@{-slcmIAYV9X?x0i5r z`}I#;ED!NrzkidGYOPB1|{9{&I?+J_SEnxi9?IbXc{{v%VWfHId~@|a!-!(-b& zF8z+H!#u2naM>ZUIri*-9(2kz&PW)_j=uCebs6Udxz1#b8;?sKN4Uw)A3a8O%z>Dn zQ6%%+o^z>bD%3>T2ZNAUVDtCujIm}Z5HZ@g*}%?zzcHVdiAEspJQ2fHETEm;MOD;! zY^pc|VBMdXB>w=0fv-q6iHIIy+J(0BwMGE@v~4UyI9?7Y#byM;&nWO4rh-Pd2z$bCB39FOQtalKGyQM&j40QF6;3!;jy&2m|( zz9Ay0g`;A2qC1Vf{%4I8Tl%iSM^!x>)Pe{nbyV8b4dq6C-&pO$f|p9Q70)X-e* zl^v#*DG|cvL}dfi$OzpYcs}F4th%40hfdv=dFiEi5;9?7mx};k;eg;{+qgVyFLu__ zYgcyj77jo$sB8nk>=+D&XCPpldVu-U<9l%P z?`YEm?b@gb$Q@MkQGf&GsYn3;>NsFX)RZ|L^tp{;O--j(?fGivol81rKR^dLI;*GT z>6O!#?>^H#TEihR&au3Ml-k2^Qa)ge{#qI}-*BU+J!rJX!(QG^8py0A4JKVtf?>9t z0*AhGduq;AWG^> zV!PC{DcZUnWmrpp5^R~~AubSi!+;jn2fG^Yy zFV?*>Lyz!K8d{uAPyQjL-FrS*G;E;$)&1Ch?2eOq3&H=4#LYy3=w z!5G12?c9&UJZWG3A1EnmJVm62Xk(T$Pfi&mP|87)LxLM4M}1Rnri#9Bh+|cm_N+|N zsO0-bK+|}K>ft%y=ZY3g6}SKn2+8-TP#v;>+52-? z58{;d;PLjPSBzBNP4=`O_}2aW>koBwFVme*4dEGuHCD)K04D-O7*m1$;m6^v^W#)C z3wf$(;*DIkPn98%e7|i|@8eketgTSp?R6BdA}^S}mSRTMA7!#e0SBJ?eLf6v?&LD4 zZ=tM02af7&5xHb-xIV^|{wmPJf3eb4N6fIuv&Q)Sq~(m+rQIJMjLM&Xx{@tBz`fpgq(y)cJtWRRo5q3e?ppzoC5ltkR!hw)mo41 zbTxKanlzG`VtZ`tcI}mwL4}WCk{;RNTb|j`e^&T?TYb4&yvH$7C8mlxxiQRPDUwbz z+_rE&T2xlZBbM%+1q_dfd3R2H_k{{TojaMQseJx7|pTZ6Ge6S2p2WyilKzdFv$OJw8U zQqpe*p{Ls1jQ+M1d>@$Rm|QDGeKMY)DE>6!@Ua+MZbiAw@d5ZL){yX~M27s%+yh;1 zjO2gDNXh>I+SYaOz=gBd_x}LWV;}T2q&z5&Id6!r11nvvK!Q7kkg?WRQj2|#VF1>zjUq@r8-BBU;E=l|Is!EE5ZxZ@%{M&ul{$>HLkkleDF5nV<&NHfs zOaB169g$q1jU{|Ql1Z<<7lb1h!pDRAG<6ND^iwn!Xu~6h?d<62S%Dkuoq+ z30~v70arKLIN1X#^PYacEhM_$9kJTZ20u$sXYcbyH1WCA7S2@T*!^^#>)8SQ6NUc( z^u53C;!OVlEp@FMQC&jGcV~ZaYx56^d^;wKtG>`YoSYHOUldkR$>4A_8P?F^%MiyV z=W6^1#>4(PC~A=8DoBLm4eA}+*nQo!J=KUF%M&+qbhPq){{Xi`z}2@Y5O6ZNKRV6W z350{t_!;V^h$f5xIpB>2b;1woy})C-ApG2EgCu2_0CqTEu7Ud2HXS!u7!WfE{N+)l zPZVK+$UO9?7Lv>xki(y9x0L{6?sK5dw@`XU@;~+(kM<6jQ&Sbm!3RNoZ3}-?ZzQQ7 z*s2fx0(7*%Rly^S{{T951;bD!N4t# zyE)L`QNl+}UH+66L?8ZH&|ilpQGxqk&YZ_|PBMPg`Ar@u>Bk2Vukh7vLf{dNUO<~^ zp&uxe6ZmSTp>dLRT#*3hkJ_Vc=Poltw!N=spd+!SfRDung!-sai}yu*NK;S!XrM9& zI8q9@IX=Tg{X3aDYSKr&6*2z+s|QLS9cvQXXR%bt6U!V|%4r%jIA#eOu>j!XIMpAA z-t4*SkwqlTj;uQne=2%^N9t=$<3jPf08Y;Nbmq1a=K2gpD1vY~W>F zz6orS7rkii{8J8*t)kpXFPF2F3A=_~4{rTyaP&+b9Nqj#>xpKgN$sf>fW;V{#BYcl zvP!qFBmIIoxSvivwSRX0k=-e9p4Lq*dM!1=Dv3W-gzO5+LjJV#>g}e>pOP zV~*Mk7V8qx^pvwJWzrDDNaXGKDKG&ikGo08zoa)vo|#K($5tdZ<)+D}2i4?=@^L2v zI;N@do2KOHJ0$eUG}RO<3W|9b%HBmgLQe6x0Ib96M{Ow9EhG>a;j@9G+(9KnA5i0( zzr)up;w?}Cbu!8onBq?^HB}plIpY8h^z^h*^u;w-Q`I$Dg(0~NNi?BQMetPlE=~qH z=Q>qMS6hASiBqTLF+}u}h;EXrJv@;E0!q*?9$`|T1D&ToO)jn7chVOMn}uciqM}hz zQ54YIk|t^>$b}R+Q_POI##@XG<5$b#?@ZG5B^^XFGo*If*!N2WgACHZLg9U|4{c!e zUk_fumrreA4a-4<9Bs%@aDDn#`qRa}7SQG~9YrrDP}}4q^+-L_{9fSGg5%R&Inwr8 z>%7h8*F3b6*IcSFWhk?wHb?*}0sATd8qYt{BdR(o_g!RbRodMoae!DyQk)+%Jmm4K zFB1G+r@!qteZDOQPtGWl|Km1lE{F3GcH0g0RE~} z7PkqgYcA2<#Uz_!&hfFp9lB#2Q+-QShsF9#vD-_&8Or{?8G3||?I-}}b7LA_JknRie5;;#9;&h+`xZqc$n|kM z1q0Y>y?iLJRE0#Qlt|0S5zDvl1k@cbrK9Q2le?=@!yMIg#7V!*a;U?dqz7P6u^!s$ zaEoabg4{_a(ntk5XSRK+iM09g9`;gJFreqJ9qK*Co#1lrN+NT(;{#Fb-AhyYYKAx@ zV+g5-)Z-Z&$6@WE>&@2X)Kx-SsSAwyBLfPfwg4Pw_vo{xI$%Y1r~M@{rj|8IkxjIj zj9`Wg!?G)6V?3W>qZSC`gqQUYIr&i0TD*DZB>q&=@sT5Ik6H&{pkLjG9{y~<$4CAY z)BIG3Zpi1&soVbm z)H=g>!Mv{yBQI;n$oz<|lln8nn(T^u*|ej0MC&R8G$+5Z3y71XKnhIlG@*CD)TOQ6}|xvuYQ5W$aOURZ+@D-(>cMIU!3 z`0D0mRAbvGlaBhUw_-FxPDm#Q9_0Ie8lPB8v-cp5M*{$X^U{gHdy+xMNARPe%ESlG zr_lqlPWTE3KICYEom`MW=a1vtjZ)Amw5t(0Ugzu1bY`)rU==_dbNA^j^r0M#b>^>T z0c*5M`#>X8Dd8cr*bR1yGF5Sm?c*alwt_E8f;sMWotkU|)2~WNb#=56*w>Wwg~-U& z%r??MBw&5opFvCr+GNao*vx`T#t4iu0py)ZukgkO$)=Do$Il1%>sb$gyj?A*xE90$G7z>K z@}y0z+bo+*-23&c*)_SaPBc4LNXhs8+Hqd26?R#QN|+x}pnIGM6t@6l-0L_E-Idvb z;xb!U87t{WiqrOc_c{{S3no~=M1zeLrFs7m0UsL=H4LY>4NXzg6!8rE95 zag#!|p^Oe&*mHrC-y8vB0jnO{{S(l zHIll(6#;4nLP5J?&K)`g?I+3yjtqNgtXW|Vu=BVn>4Vob zTUB7Arl=q^dxbN!Gc;jvv#B}fkO(;=Jq4&cs-zQ0e_aug2Rz}9eb{sL)2gP| z@$^Ni8lYAfqg3+b3fL`>2=gS5+c`g;gFmV${{ZA_J}ujZX`ygN!h7Hx>VWt-By+X&~dD%Cy>snLE1q5us6*!C($eBxA|@^)W-^fvC#3JRE$Ery(aC>FkEM zuo-%rOvEtbPELclM{lM8%eAU1%xtHXXu_`GzcH!mxa0rvWHrfInd#~{=( zoYL|MgbX5(6(O<-4V+`Pamf1WRC{D^GFj=!cl}xgZRiIaF#{m`=%zU-rgEi52+S|D zzIYqI9P_GLsyb(=f#N@_VY80P;P62m!O<#njMNDEiuzyDF$#YJAyzpe-%K-~??}Ht zze`Hh#^I*-PtyhPHk>f^Ew1#?P~(%7ybc4X+EeOz1;r*8UwfjOK3u& zGWquBMt23sYa29bNT3w{xcyUqh}{7N&NB#oJWALeFXx38=sp2K`_)RN~$r2 z#y{}Z#{Q0r=Je&(QlJrW^3FZVM5jOWwTz~O23A~WAmH$F4l&5q(f*CmW23I*oRfH$ z2kG$e=&8TEG(Dbw5D&0F!jrx^#f#-g{{Tn$4P%@1LDARfb+bHZ%Ur4(>VF_{tb=(> zGXg$()JV93ERJ>x=FI!9ZbGl zW61yzr3o8;SmRE-7aK|Adol;ZZ6R;9bnRiBeuE{zKD}z+C!Wep4%Si4J#Eq$Q+$nC z62^lWCoO<8?sWRRh^lW^iiO@!!_uS0!QHkrj|v7d7%nh%mimVCc(>iFDJ4p0-7sfx zgl@t6`0uN^d|2w3>tT(eqLw;WA{CM&`y>I9tTWqMZ_;&*--+xXwzI;tQyu&LKe9&{ z&%JT44v4KUQsRBB5s%Zip142Co}F)FdLI?2Z`8E$#X(z6>VQLaKGAsFb1&QQ0 zxYkWFtIxCDcsIbyjFp?o4EF*>F^=@;LNaXj>J@3PMw}{lx#T*7T zQCmwa>YhtKF}gIQZjMlWCpiQWue3`^^!*!7vy%;T93fmUKu5NE((B8`n^(M=Od`7i zgrC_2e@*0kk>k6{-QH$JM?9qy2WUnDuiLBoJxfy zNdZv1d&W<=)`jp|dMbXeqNu8#IAKb;8KjYdBJHO!0BGK+Q@ag?$9z`7 zS|-x0AIwo0nj&9303V#z(Cbc#wsp0jLsLZ!O-(BqsTNcZmc|(df4)0?aj%{*(RFQQ z{<1r1x5kFLstQP^Rz*~bP^DX7$s;2lKy~##gUgv?mKhRAoC6$@uw`XDhEll%9enlb z9-2$N!NIC{TC=F`Pzexv<1*Z$hs;Btw7JOA?+iFAcMPC>!s~4{a-~wQ;+W*>_^}Gv=w&nHv4btn+**8b#jgCBDk_v$x9m~ z9zvmQg&&al!xsyI&WpCc)1;At`A5+Gn>{|1s`E(k3^5~0TmvL{^rvf2JAs zk1QRn(|GMy-s!#}7Nox89`x%PcVIo~R@UDfQv}*1E$+*FZhteKL9Krr7D`iFLtKN; z0-XMvd2>;v_UA=u(?L9&q6$FjLpQZ8)uOw#ix*oLc0MSV`16WXEgy{g*_)>; znTry|ZxNiH`8oGGpq~5J)O|y5wqB@f=p(2w%%Q86Rw|RAECP-S=Z|o8duqD)t#azQ zY;kpDYb9=+9hV2tIp4UMXlp?7f zs#=z0ktAh}$Cu@n1$L2;an8Rky-{}YE2gbi+S*9zUH7CA!tB9t(96Fp0m<_*_-RF~ zq_TRGJF$!${{R}c>cTHm8*&B--MC|~Tw;=Pb+3zY!m@u?(9F^}cviVRDgY|mgJ9&7 z$F?==UDp02%NtWqV3Xk{j3o1k_iRU8NybkIaz70>tR5uvn%dx!v#Ty`T$3bqwI2~U z4v6eo3CCquTw~ulnRn}Mg`Ue_OG(sox1CRPV@_vdx#f0fNesWX53A~Q$}h$Oxk$?K z&J8G<4INy7ju}bD8j{x^6?{mbrmU;1>FU~OAS`z=eZBHdbH)cJS}&(>6_?)#8oH~Q zrMB0S*(BrjmKZ!a#jn;w8YOEy#kG&zeOL(r6%M1esJe>5$^`ofA>SGw}gCCZuYV)(VvG>s$ zCdiZh5vn@SJhP9H(mB+I`_l_B3l4p#PQ;#Fg4lq4nmTYl`eRFf6s&2~v-F*^RYs1d zsVL)gb>5{}A0e0AeLeKivHGkw(tYUZ^ZuaFpH$2t>b`~f4xoYg`Jy&Ij)J-^p1JEztD>#8Q&&SvB<&P)4S`9YZsoz_k71{8PIv>- zwYF!ds<2T!pQNslZZbCQl=X5#7l!Pia6Xz8{*L#^ZN4ORgGe7_(#!}zGm}tA*0AW> zk2|BPDx@kFJGJ?wk%#~RaGi-K*bMS@&AdgR%Qlxa!rop)UE<<7ih;8uBONoIYpiJ( z8g1^g9g{-?yl}G<<&DHPF_LTJ?};`j>{qU(prB788f*E6G(vp|=1RLkKEMxsQPJ5h zQ^ZUyD}<5}Bk{2}9yd1ubA#Vbj}fV@@?UzMrm4Y7oB5iI!09KNjWnekklZ6~;DOGx zw^7(3w_GS|=6Ne`4|b*!+-Fc+0l(1_ucj#T*%$FATWujPHF<4BQnI8_M66$u_&_uM zv<|sz;NQ`{n{hU`XASM;^!E*K1RxiP<14)510Ba)Rtck^k~u+^vL|(77C7cp9zBaN z!6*FHl5|P|ogPN6y$c?KuaJPw&&sS3uO{wPjnCjx}=o6?$9Qv`I2%NZkuLX+}4K|gk} z(%q790eMKl`Hq#@Veo&3*|$A}D5MuSE z7{}g!EidTpw_Ejk)6u~5%y_O2P{Jx$7u}vm zz#1m5=<6>;(8n!xWhKh|%%oeQV=X)iMoF3DATtl{1Htd8{ZZBZQPwLJJxe7$vJ?H5 z*-D;OG)K3hF`T#g&6fJ;vmylx5DLH3sgpwJ&nCHJZNndWMlC$5?4;0jMNmvE^c$N{uqb{cNk z{0Y9#Xcx|)Ce>p{jL2jGY8@Dilt%5xZ1?ul6T)7Yx6xMBbp;g{mrX{^6%PLZQF@0) z0ojk*F#{uwg^HwxL(xhc@2_|EH(KYVwW@xddYv#)P7{$4^s99Gikp!2^Nm1&9N2`jf_}{7dl;KMkoPo>&s1 zp`-$6eB5jV;aHKMwT=POc(k2EP`HlX-aXRF4#A$d;PtGAt8o>oxsk%C86?x@js;~z z9{SK78ET@Wp%oi)`M@N5{PpuL-Tft`lqpLi zCoJ)jY_SJ8+rC#Iec%E7b?tTjk#|E%%SmjdigVe*$oTt#Y<_y~DXUq@0g($IWyT5o z>n3ccR>J|0eCD4%CERTZZ;9FR`^;?WrIlC^FywGM`|CZ{&kXUziQY%pnLg(QN%;oO z0r`WZCsp|K*7Z^lZ81+0l2R`r#9@!xa07j&?oZE3`hw=ym_C7|?BJP&g`lrz1Eg1A+PJ2Y2yP#j5H2`g<+CjEEjXR_L05YE%#>} z51`{-v)pPb6L!)D2km_^^44x&5W1s!q?J=UJYk4fRk5FOw;Jf(V|B->zUIF85UP*% z^`QR%W3QQmGemk|jG9E>q$>@i2&Vr4(kbU~6?O6hGdA^A3y)$snE8VC(*tqC6^ri3P zn*vy^yxDJy)V$V#5zi3?Sdqrz{o#yY>)igba{Yl~b^++Y`F+~VN2_j%2wK|Cd*)-P zZ-2Q;8x=Jq4*8j}^3iMIJED1=K=~*7&~4*Lae-?lI`ZSKIs8x+4bYa8DD9Zr81<`#U|!ra8VC$zkfQd>C%2Z zht4znLDr(yAHr#jfq~n&?gJg`BXxQ&?|kJ_yRa}$dQ-!uswknhOHkC{O-~e|hpA(yw@D0OW_g)dk_b?*f^(mC_SN;mPl4!@OHa(TwGsKb&Q){mpJFrH z+?{$^Ar}hCqhJ;|i1RWwmymKJ1orKg`2n3~k&AiL9F=Jg1om7H;%j)J@o55;5-dQL z1Atqf;Z_nQPw9wbTKa&MQc1|a_cbmu=WZ8k2wM_UAO((QqxOci&Gvu?+$ zI0W;@ItI2?OAS3F^rdBWll2m~!jCPB`Nup3UQRuRrzKo{NF|<<2pTBnX#D!AL`uYS zg~k}3az|nLX)WAeiizO3oZ(o_-4(*{Wsa{N?^4n4>mX*~~N{B->2kYA-?rH$9m zlB#JEJm9fhE(URv#~9UcITK`iQHjlUODs@NSG8Aa1;OB8<#-%(g*niT?%ME%jdtvj zhSCWh#OEEj_tTXv)sXoqJQ9YKK3U;lNy#}N@Nt}HP-p2%%Gg_EE?GAfMn(=YHswdi zj{0D;`nk<~(Tq~Mp1G~{2#ml8-+1qmfB*`ddw1hjcerTgucfJ^8G@>1mQ@@Ce0sj` zpWb!ero>{cf*D5AWK<&<+vX6ZyK#VXuf?|4QqK}PF+sVI;QOaJ{IqH^ZUi1^SrZCR z%D$V^Czs&Tj9_^dwEP1n_-P?r0)wBfpS7v*{u2boH%&r=@aG@9NLzr;?E$PE*PwsE zC|wXA!F|mE+=1sD9SO_Kz4MIds^-LJLT=cU5zo&{2PYKNb6QjSI>t{^-kaTElzvoT z{{TH*-=bBJ?U1exF`ZTa07vM^uIhX{nV1n%b<843dRsW;cGjip;E6|A^0TC1 zCgxF=18@Y6+R1%eEG>2k43bL;sgaT806PY3Zg2^~IOm-={U4A#a)9Ul#U>9uaz54D zbt_Ld^bd0?mHk$)12%EfVd?qM$5;n$qLk;nj1T4!IrEi+wtQkJcWaF<+nT!!^8T9Bc#gr*DEZ(^U17 zD8@~)=mGltE9u$d*HE>mqpkNEIQ|ayk~OZibCM!4mLms-Qb1&5+eyy?9!2XJSa%ky zq5P?zMjz5*sL5H=u&<;WTFW3Gw8hy$KQaI~)_(7a;_Jsx^`%=LO<7Zn1<9eFg}B^r z7Fw#R+L>x5HH8C6#fVjnaHBnd&j4#h_(Nr_>IrVv`aq_#rrUOkm@(SEY_P=wWsh!T z9Q$iD_++GXtwAS~aFZWCBTZ}H= zMy|zB%TILMkGbN6@e`Hs_Jo^>V*&uc{Fb8C{{Tx56>6es z7D{Sha&r|3aKA&iHa{Ifw*LS~uN3Pm67wZoHFb8lu5AWl2E_s9P$d9OQdz zNBC>tABVkN(vsgA&a`q|>uY7FnJNm3XbjAeMHEWdAU zrlRR^qqx)Dq^c9t?HQ%=o-q(r8y7Fg2j!#1{{V;Lo#6a5d%$qZ<&J=JOJvggO)a!n zKZ}&a&ko2g-p16TeCc*95HyfvQ{Z<5`2rd5(jr~|r84;#F+4q1m84j2sRldh-h zD7wd_#B>onD{-j!c`7y}>{^ac*^MRG*iuL(qdDUPzJ&h(qC}PoZjZX9Exw)#`das= zsj5W+YKU@LFENiNZzCPJ9{O^1)l$#ZofV9FZZ&O>pre$3J!i}jrnf9`+W`<#FnPzP zwQ0W_De%-XTwU&zx{yG|KyHWWS<}UD=?P2G7kcYMQA<@<2ODRV;E#R=;HgTaI*j8E z>@}P!KcvT0UuT9WEw-p)pl7av7?ttn)5gVAsA0h;oNGdLeVe5^j+@0UqP^Qvx=UTo zYI+^*A~FhUXu=}2Or$Ax$sbdpS^NX&`dTiXh`i9;YbS<^uBtt_{?P=Cg~T1JF@Q~MtwL2vZqV0Ij-Gp4CZ78r9e-cEpVom}-i{D#Y#& zERhg|xy}X-g}MmS0HbNaEyX;s{5&h>#<^09fIoFfkx#|fD4DWqR4?lZZedQxpK^Zf z9XdK%dVZb>S}0x$3Fe7fW3;rW8;`OCg9DH5^QS$>rFtH&$@)qzkEBP2TG^UqrlJlb zjLe7z$J`8lkOyD~8iC@cOr#?G}BL4UHr<&haeeLi2lPd)h4Kf}6oo};P$ zAS3xUWMz~=5->hkAOeaw`F+~db}tS38ryE5vDDdUUg0HFK6t05M}^g@Wk(^Uj1Wqy zudQ%!5?D*JsMJv32CbAqBML{Q=?Vs-}DtL6|h_jc3ezmLmQ5uEx)cYgZH zTv^ETyLq@7CmVmAU3k??G+imwjw)uA0SM7Z6Kj5~0tpBk@ds9xH7(%OSx~sMP5=iZ zh}#;e@rsfk>J{p#kDe-79-g8_Q6|;{k4Ri#=e~&T(U?3XNR>$c0C{FS{Msfux*{Ib zjDOy#6rWKZRQBg~eJ`K=G+sPKlzxiVlCf&-iG5YcZRnj7imC#P+H{1rDR{{VJ03D+R6R&*gfh4wBzxl^VOO>@(ho} zZ~HNzZxEH2syY`P#ql%v4J(|LMpMUDI;a-)f~cuhQ2hho{w-;nHu5cXLr90B0e|+7G85 z$60@%dV+_euDxG$xD`qiYPn>VFdjfYC1Jw_IRia`1Lva-lKzxF7FharN-3@tD?l?(ngyqJLQ(Q4|2Gt5-MyK~=W_#q7ah8dOVrq$H1mm&8jx@vZ2gP2C@e8cK z-m96Pbu=(jgA=ZHIhC`#3}Yu+_&*hE4YP${MWi9{IuN5E{#C}btu?g^`M(WSHOWLBE=~As*AS{&85Yn=ff$8IDKQqRWH_orGyq1b3@+iqWVOHlD$E}77 zecisAqSsv2uUbv6=>Rwdfx-G@^INy@r-v;>d#o+YoDsD~LHGF@A))FyI!2DJN$04# zRXJaTYLE~i8@F&7i3fwmG_<;1ZoN%e=GIEmIX|n37YMobMIZg=N7fF3zx8ASp+t0+ zv~9CoYM94PzvhF2UA{`7lk(Fhf%Hx zayE`}t~HnUS~)HD+IZ+~tVZaf`%kwxGRS>QdHLf+^qn)+U2SoxlAbxL=i2jDRm#lD zilcK$E1aGH$@e<7r?A+p^tBQU)>gvsD%47#My5i*`EeZf+ru|ML80Ni7neH>!JL%> zFn%2TzpV?e%VFWY8sg^WJ@CdC%v^3HlYj+ObT@>ZRo7A@QPTNTK#lda8CZb-05{!_ z-L13X{{VuWA<*j`L5Jh6Y6fcO8QOp3)3W{j^whM)8M9mVt{359!hwJ?gRmO6ia$<; zxt@P9qs{;%5pkpvenF_3}6w5 z1bunuLtZLL@ZCw)Y7lK%qH?5h{#q{o0G^5b50D=X4guohQ=iE@YdzwYZ}wj*fA8V@ z@n53<07lV-*U=6#w(|a9ifl;_!~j=;=_6K_sPLYllafC@Q&Y~a6?21(bNA<0G!+Tv z>~0vIGyedeeR0cyAdHN3uh38wE~MhFBaEvy4-LW9<*c(PB>N2h9BQD{qGOTYzwg&I zzEV;0TNnrYbedSEoiM0LrmHMbaKBG{L#z!ZEsWsQDb+$7s^C~DCvQNwZ0KZ8K zw}~)PF<4l$4!|8MZyif>zsP*~7)72CALF8Iyd`yeBE7-#;_vQ$l&1dx#5PvyRx)Ih zpaZAgo84RE6VFrG2GWR@fGF8 z#+`7^NB3-SJ5is;Rzn&p$s+nx3=Rh$cE1hM;DiQ}Q^58<{{V)X6!AEtfRJ)yPvABC zB|DzkJY(Ob(;D6ZE!nM&eQkMmFX zX_*}dnjayD2ONEMVMl5)5?khZBU*hr$>e3kAR+nmpzahVcT7p8f?KQW`Don@(o}tcqWA9jPf5bK#RAk&ujGQX)Sf7yZ zS(Mmm?>%ffWekzi(NM)y@!*qC#Z;=3?5Y?NJ>R_=0>tBI1Qa)yZVR1WzgBRWsh z+vla~8VFe*%6f%Y;G8LMf1vl)ds5QbHW=dpTLy)$xnr$?n_jp2|IS$N8k^V74+aYqmgTM4y^?nv%+M^ENSGNBnR zN&)p@jc2B`p4$G|c8nPm=cjQ@g_W~f%F66WL&w^_R@B)(Hj1)UidT9{7-l6GDvRcb z*uOjvPy_3(Ru2z4o2h6dt+&z%X`_?McWI)J4~*^oV=3*YzlIj2xmbk$UA z7#Ssm$W#II-Hd3X`YY8$_gmeXXWFwQQ?7lQCMthD{{XvPiY-n;ZXy6~gdxf97-qT1 zv_Q73<+jXSc;MwuJJxV-3A)KaCW!z90)8eO0&{?Ue@#_Ycz@IssO>axqOaN}c+Ni~ zudR0;i)o={ilFjA4e!QAGvD7zyQhYCS^U_Uk)ewb%iq${fF z=1}r0{;vbl2hX1RQ{L(KTcMbDM`Ulgxf(Vbw|Rm#I^(56Cs|@wQ^BfNnWVP`CpeH} z^2Vg}=08dxIptfnxQB`Cy8`~PYDs3t?3Dm>_#H{Y#AlacmNT}`Dm>zb$w5Eo|1{gRIr9M^D+K+)=!0}u9Aw=P7E=Wiysgajw8kiu0gj+GrxG@{g73MOv8(H|ucVupN#U zAa}vl{WXiHgIgh-%M~bwvRI`QzHSsQ_jk)K0pkbTU87!?x>Y{niyv@`Tx&aA03nCAh1JP7qaBn` zI#TVl8179hu7?EvIuP1?;r^D6?r=5wtklK`IN=b#y^Z;37%*2oY!X4_T0by6xB$Rj6qKp$WHHJLB*;zk(Ohw5@# zNimFLAHPU0pikDf*E-PMr~nUY#A)ngC*F~LX2u&;M2jlK!QsTMoGJ5EWZ)CW-K<~L zl~UDpBFij`Bgs{g>JA$&c^Lz~wtt8&DSB?Qa|%o&YIZR`b~qCu+SnlA{SLE~og-qs zRsN9k>Jo;TV`;WQ%yY;|2oy2OZyR@$?lt#@wR>F?#fx=3QoMhJWz2E!Ad~XuzfX8W zLjM43zeC!VlMbP2Z*+Ai+%3er0aaQ{UkgifL*MnXf48Bjfs#_#&Rvdw9XY47^j_L| zKTVgBrhhYSI~7roK?R5>CpqKWRnOD?7^_jX@Npb~MVJq%Nh3Y@6(m zB@fj$*oXWLnw1aG?sooqxbU`Se zx^JlZiaM(6%y!y?1W7d{@w2)ro(M5y9D|$#r4#tB*5U+^ML1l_u78b0N6#s^MV26uYR&TOr5%#MYSbW|3=d(nx&I?3C5DK8#=; z^s$Zk{hoQol6D(4n%ioUDoeZ-F^ZByq*8@Dm!5IKTn;|Ec6e7a+Gf5jG&5JM)_S#8 zr;H&|3==tFGban><0J3VeJ5G8n_66~fwyPiJ@Hm}$Mk8d+xSXmS?t_L7(84rJ$>=* zThqh(rljaDn+uGkvXl2lHS^B)=6;Xp2*^9-o;L$L9oM>$e?4p7pX$2mPLZ-f{a(G{ zE!4`=D$+6ls26wsk+_06?VM{NUG24%ogL7%Q7uF;LeWDFN|Zq?t6fo8e1hA(UZ4iy z+#PJP$Xma(Io8RwLTD=9}UDd&Cy@F+7&Z96KTfu44ZH4(>Vj6{Ku_CB@;V zfqf}oB_EyU(_wPOBTddHq*aCrGN#=|j~Ox0JiJuF(wkh~$c%DH?5zE1ooC zC#W3Z2Ha}eDoYhzi=r*J3QnY}pq3vpNTYg}rmG82>G&w4lL`TC-IoihD`!e{HGfiE zqmF~AQrRSu(>yRzNmDI0!55aV=d8Z6cQXN;DP08t(c+#-3`EHxVo65sH-8G$zlD5J zJ+O^t-4r<5vC5lpl6hQU@^U!&P|t)uI9z-=Ym_kBp{WHRV zb(`WHS{a>Ch1j9N0kEVHRO?K1&G5u6G;mt3Qd0E&b;^mJo`4{c6EH=UO`u9thL8|B z$9fdX5xTi0cNo}o!2Wcf#a;*T7LebDiQ#Y%J1?Ie)eaek2|aSXDRY#@!`XxcW3ilLEJmkYZGIOerfUK4mPG_p$8ilHGOqj_gSJBiZph>UU+ z{{YnyTqDu^ApAmgoj_#YL;a|OM`Xr63^6D*h~ zI5|1v6&AO_PKmFlnv$yZ)G{N>xG$JqH5msRBzNuY&WkVfl(znjucoDUXrQ&!My%)& zj@U}%s4b7rT;%HNTssS8=r@{IV_T&Jj{CUC#-U!XF;`lyw9!%A*`AhY;yLpJ90DqNUQpBxI12cD2{DAB= zQ!4I^fInwZ==zEX){Zx#x#UE6o_k)uZR|G~f1PLEU#x zOx;J)W>yi1tBkP_K;0m8P`LNVVo%+qyLf@uw#Js<4^i1-6nkNb8jfPcBRdA|(UY7G zbE<2XQ}wO-<3%+6Nokd+L8*&vEQ$n*ySAUzjFXIfv#hqEs#>%%u3d5uB@ecLfv(}A zeu6w^*N{kB$>TiXXAS(Q@u_@<>k!oM9_o0(SIORFtw!FU_6!(cX)$EzD|PNB{baF} zRA+aVVpzUT2FFk|S=P5Ms%Gtwz*4j{xHbzCE<0kH!jKoVL9^ zB_qvpV1b0AY*Ce59FTI{_8e;`WOW(zrWO(bIgo%s#sED{bRQX5jXPhH@#;LW93e=? z(pEKGEbUT0QTlZAg`IYq&R7}l;jCNf9$|CST4IlKch1C@Y;;(G<&tmZ(>J92C%*MW3pG?m-$F{V%Uc4qa5u$3HIlyrPXz1Rg}lm%@FSXsP1;A69loxEb=>zs&vm`Mp$1CC@+pGfY3}KE9)ML&yH-_aHr}s~73Q zxX13-%ZkFM^qORE6VtIDP0y;ET}BleQd_)ScqK zk96Z1I(phpIi!cT`Xg7E3NST6(-}Q8Y;0pRv2phdYTCN88+8=blLj$C6G-7kScMtD z9Auq!iPW{siUwG_06z7K(pg54X2kFyjQ;@X6`Xu)>cexblcHp$SYWKDM{4N-ea)Tf zv8XGzk&VQh@-eK5S4&?65zxq4;I>IUJv4=~%vtfsA3eFzhf!QE5XWBfnPp48X|1!@ zGXpP>$Muo1C)17q8OoAzqb~+}YNM#S!Wn8JSt#fmF|QBi)gMxvjE_%$%SFw)%^7p) zAG7oK{#C2etVu`1#ve0$|gO^@BFo(R;kbOBA9LAccc^}!uuT+tJ4WJHRG3MRNL1i~?rWm>CrXwPCaxG5<9Q${-!0$iRYtKRl~`~F ze(dL5rM!q(5Zq@!c9(B@I3Q!|kAJSBJyg?n&pJXhk5J#!6|`+|^Rut;qx#;lU

| z8VakwR@JffkTQRMs!BN|ok)%VPDYP{#?shjR1-_4)NgKx4CD`L>k>0$o=MfLC;;PJ zVTZP?qEEX}o+D6aV9^rbS`Cj$We{O4NxEj+4cavXaaOLHkC@Y(uNL{u?+EQBvS;DPkhGr;RTlBcTV7c|8= zhD95W0o|1 zvJ&eXZH__^$GO1Zw$fK|=LC&sE~D`SqiXucp?XHm=KhF=;S$x+L%u)OtL%yiR02tf z!DmzQIo6iw=xMB-7fO=J`lyyo&QBm24l|#Yb%=a&YF`b!OtkgI1u8w7NGdLsZ2Uc@HX{zQfwN?VZK@_@3fm z8artR!=4Ep=_OqQER3oKz)lDl(6u#vJ*xF=nspwVg)i#+@{7+Zc{p75@ON6VK&Y%tjU_#~SviNaXo`I!m{X9uz&X59#Venn4@5+a}?TLYyh>olsYJ z@8Nil0{;LD9P{X$@%Tn`#v3`FV0JM3Q5W}dGzCK|@tgzus-MSxfc+(D7Z?+BM82}T zk_Wjy`oUKUcM!`*oP!LGr|TIH{023%{{Y?F!}{79+DhxJDCL=Bk|^p~9Y1A&DUfl& z8pyp@aOsr3#Z_&%twk_=l@Um|Q{7JW9mcc~!!Wp3IUsk(Q}0=eGRY1$l?41g*`+eb z%NwV&5KrDUZPV?x@k&R1`25B-S3b`*wj8G8gY?wPJDBdYj6J1KwNQRn&n;=HIk`e-3=yV7zzo* zukH!p1FCzB5k+C7FsxM5RYSF;!S$m^;oXSsjt9>J<))8@RPj?<=9|q~;HQ^qcgO}} zp<{^v9q^#H$ZMb9UX-*ihbp6DM1-khz~zU(wRKGb%|z)QV^(z%G}0(wgBjpAe0Qpw z?V3t%kx8VgXepx~+78k2bGtE<%V0e!0VgD!WDk8@af})k`oY2ErF7#DVB-;-pXMpD&hqj6O8>4FapQT>!a`Wpb#bKtV zq=bl?GOM_|Y$^9({#qi&bERqKY2-O+a&Sl>Hz0K6(oYe~2C1oqj1Z|9MfN3lB$Lvr z;s9W3TA#yQ(012O2j8s3hbD(#=Te~@>rGo}Kb zBZl2W4tPpBWo-Rp9mnIUq9<{qAReRis@NC`f}{*~@7Rv{*R95r610e<qYd{{ZCzmg$E!i}f@MawE%=AKf}%+wj%UsrPjszeg7~#4?gQD}N0D+dup%2mbLt zj;KM@(S&8|Sa>QE{m(jq$o~K-xM%$;v7u}13SEdKpj(cEREThKR!n~fApv^boIXnAW}n-pYukw8We=i{jj32elUyu$}jxG{3;#z@6LPj zG?VHG@W)Q8)=4Ky3+nDU$GOw{k(ly&)+0|Ckgv+K$B8SRldm1}U?26Xq{l~HZI%dY z%~f16PHI6^k;YjH^XYH2r#K++bmj3%jE;oOHp>bS)~}UTI-`!h}r3;Nz&rG!No^ zzS~21j!OXZXl09gEGNv47c4&$xf_n&y{W~WoYr>93QTsOz{^!Pf%jT_ zZ(UPObCqb|NGHsd1V(_ADgkG}$EeLsI$u)d!&kn4+SJB-` zkrKEkj((Lbdd_WQMwY=O#F9tXuTOgVV^4XZUY4drsfneI+MbZ$kWwIV$G;lOHGM-v zCx*QRLU*NQHE*3XOot&_8J%2Ub}V-N4wNb3?Lw}`u|mN68tC{Rgu0I>g*EazvUL0^ zoASfsP!c|1`M%oJ%i`S;oRxPOLb1ftEZ>wpFH%ti*9d?{xfsFq8)HW`&=_*0t zqEC0Ej9aYpEm(I0$(5-hj4S7}XCv^@H%Iu9&{XxkOw#ogvOkIH8RdvQTx-5F3@RLC zjDl42tdmXQrF181SilFd7Z5*$+VJ>w)W05~Yys%ZM|LhmKbQ{$A3w1g7yYl%^4vB+ zJm7y?Do@eQr0KKqBnBe`cTRUve}z3=(^gKTrjoklO-&l#WO8MdPzd~rwB5-ZWPzWV z8qu8-;txbcCI0|-P+JsD)OFHEOw#~ziqX&gW~3*Bb-RXaRjdf^)oJ;1`k{PfpeZ9PN$56nR_fjX*Y#N3mzHiX=*_D*}!Px`uFFO76XauiHJI4$Mz z{As*@qCXWfDKgt~0RYR*X)x*oNZhgcdu#X2X`>hioaaAwvs71a7z-$pmaR^CWAJPT z;f;Gue({h>V_IsEfc>DfgCp|L@_5HbCkiGfulIeZ$iGFNC|1VclNU0)fh5=%OVz~tKxaWn_m#Ta#zx9p6dyT@`T-B0n49iypK!s3)h{ywh z&(Br%{{R3DJu5UeYUGzCy;YEsT=U;N=UBa0SkkUyb=yBJzzL6^T=cKfz6UpYeeRlW zrd_f5Vamyqo(FoQ@pP>v4Xx5v*i;~o-aIcT-jxRjkVbgNI?MLniN1AR#z~<=6&Y-r znE?y+3;pBwYiV`-2BM0~Ep%~JR0tw;cUI*2KyGDneM|Omc)%QLw#8+>^<8qoMNK7C z&5ug2r9eH{_5gg(8qH~*B05HxN-FOg!${}Spc?9aHSqnOyKx-%GX=Mai69(q;~h;b z`fs8vy*8ntK_yl&^-=&^?iu?d=rqZ*bcNRV_<>d^NgJwWJ5YU8cRz-xI@U{()A*xf5Jx87V@$I5zf_Yvk z^*iK=rvaf?ak+v200_w9xnzDc(O%YjZw^MX2qt(WlpzSRCkHwBh^?d2og?ATNNuQ| zLvXn+Gf^~tls*3dR)-*c=bawcb+=DcQ#4V`%OL}ug!_Fp^ZL)ySNp9Dm2`BqQ^2K> zr4pb!hB7^56O4^rQglCEK!}FhR1WjbNhcWe@O$&A%XMiQJYH-|jtDFP`{dU@)I2A9 zt6qLC>r#1TJdML3e1Pp+XQiqs<+wocvq(N8mfA-+A2F+{kY`5vZ$s>S!09cQp8rCqc(XK@)(o^g#2^`BQkZ(6I2lB9O(MJIa<$z$79 z$s)+E><;4Ig&ySRHMF&qU3pQ)n`2*(=sQ*f@fx|T{dae{0&@+y_Wk=oobTdT=y-?D$rB-+X`kgpvkmqucKG4QDcgBxt;~PNwX>O^u z4Y(w>TW~$O?M-|>@?1+Yw>wJU{c1A6G04|dflj7~$oAu1RDC$oBQs-zTBU#k(xb;1 zD0kFJE0T=%9B!W0fF4MbU`asB3vf7Won&rM#nAb1BO5%yz4 z`BV)qCr#1BKfO^8?rq=8OrEuk<^GQ~gaeg_gZ_-*=!-Vpb*GR20JNt+aY?*HplNq_ z9Qj8B{!>p`>nyOrK#w!8>SGuRPa#L=tJSZvqzKJCnA?ziv#gcYb@kELP?+T^tdaV& z{op(OF{6=jsfyI9&PiBhBOczOKbE@0-Vt9h<@`^^#DG4v&8+-q9FWBq;hQRoGDjUN zM@Mq7w`!&s&VN?lElP^#XGY?roS*o%AIn+LU*$@(9`lAWgZJzNXoA&qYP!K5;8%Ns ze&Tg(ItsxVZ#B*bImh&?ZahTI!or`GXu2EK5~_nY4EuA29>?2FevZ1*$t15N{#+5m zB%#M6(lfv(S=QaPBa47QmyzGG_R$>;YnmexBd{t))yeeW6Tljom|CG!Afw0%Bc0Q1vE`7c=QXi9H>sZU;crn?7u@knQMG=GiufNs4zb@~bv&I-V5sQ|>Ukol zsiKm56w4;~s-}rtJvJFe*-Ezy&u~G`n!XhEKg0BQQCnn!P4YaL45T-z9i6}C<3Lwl zj<4%JnueNtb#x#UmX@*@9c8DTAN6v^*x}IfK4Xn$Z|*FhxnwM=Smj1Xw`zG~WqU1> z79_HbtPgWZ&kTA(vei{R>h|J!>L?bD-x(o=Ed*=i#-QZ-om7*LZ@)(Kbxj{oU22xv z%{@Ilals>_0T%S&sy92Cdp0|E&XpA})OW_K>1I`A0bhX z?1S&33QOGuuHzR^*=Pks)bPM2Nc|8}L{I_dz7MG5gdU^cPN9||Y#kdY6l9aukTs)0 zcoBxuNx-Yx#f=V3e`xS`X>oOyA_BAwM)=$9_QL`_w9mOl=gT+)w&FW?=NZz{lAsN4eR99svAx<;?mt*GqTjPL~L( zq2mM)GEW>IdIwIo)*_AV(%#xgoUtn}Amrz<9@LYrw0}p$vQO}}w`ndQx0DP=X&GE+ z(eLX0+FsP#{4)_UujzgM%&>#pe25y=H!lVHNv4r$`kL-a!y#EEsEG@@A!QpxX90-7 z87E7B_cpf0eWs(RzSPWOD>U@7$Vim~XK3`ValsmK7OQV6Z&@x>Am=-VPro9U+}U1f zptR6ho$Zw!aq<+6mXDwneKa?g#xlk=8T>RA)G^swXvL zg)N38@CI{=8T{$vRS?9ak%Fs(Ln~~c{;SVe5d2ha0+LSvvq%pgPzHsl2^EmA_K`o1 znEgj;hR!;Mil1%$nS;E*Iw4Xs_6>KN=rp0Eo`wRSn>pK%AOxb@Qz&NeWFQrNIC&XE*~n&pyW=c8R(}tm=Lyrb{bIm2Db)O3ffuea9t< z0Fugh83%*kLd{D=^HlzmxJoIv%F)n<-tUPB0Q^7$zw+QtLgfC@(3qNnm^@R6sfU`( zAP3AS2n22??HnHZWVV*q5S1~O;eITTN6_`Gh5XXB$!*vLkE9%b3TsCzE~N&}KJ7z6 zsb~lzSeFCZokVg6)}}__3=!K}My=(J7?sqdixMXXu~h>D=nk`VdBNazI@Fh>jpp1v zILIUCpTFE{sP=+*=8uD^6-ctnlwjVj7~tb4SG(F~MrC8j2ktr+T&(K3BZ7ZEHD-&R z?m#%f`i{p};|7Wx)#cKSRUmaj%ebxvdH2y@g)iszy_O~e2DT>zd+j^_0G5TLnS~Hn z0hxK=?$5~M+e}{wQaQXqvuyx=v6+V4av^rkJ-cdga_T$hiW=*Sc@O+1wpWRggs^n1 zUq6q0eZnF9^oh8(LCNP%&lK2-ZkI#*G_{TXv!MQ3M%K7xZ>Fi#IlCv@AHsmsS8bYo z{{W2u-xwt6f=)a4+^D#q-gk&5%il=q04q&XgtPdaQ=g3*(n z$AP8I?NDw5kMY)y;!LjE!`i{NLVc+-cma1{d+RfGmrs6&s*<*rFxKhGS>WUZEPHXt zQ`~=a>rh@(DIxb7R9_WJ$r~tW*bvHj1QEzOSv+D$&$#Gmg{Ab?H=B^1t?>_f&z01V zBPC2uS%^>=oCXWQ3j^ys(=s86#oD*rj2247n0*W_R?k5Zy4cK4m$d&qfF5=$kBxX*q=)61nmHv zei~+6?Xk(>b%n8(div5h?}-Ta_tKN6ZIIfn@Y6*jI!C_@!)ZAr_6JPfyR4qk;U7rV zp^${HxiiNahw~Il;I0^t&$!lVcubd3#=rQSXTAZgXq+XVn&Tg<8?b3mvR2a0(aNxu z7{(F7{ltwB!&^^}vPU1?$o=C$_hzB%OLZk=H4;Y>2i(fLoUz7L!6OB6&VfZ0ww>B0 zuB;3X{8Hl|PhOuzrme(a9ETl16_}e>dr3$bWIU-S6#oE9>RrPGk74Qm0K-DJYm~hs z)G&1=K3b6C3#0%M`nKRqqvpQ)UBd;nK+V>y50Hot{{WbEHR-Kxj*?v}B#Fk?Mu-qW z_CKuEiK8kp^%4ld8+%o9Yt1SFumT7m?;K*aO>KQO)`e?fb#~hu2SPn+K_P|+;Er`m zPj`&|(c|WS@fuEaZ&TWAawUo?xul4Ol9WoJS7&yOPUD<+1KU&XGt<-57MkNKGv$WW zZKQYOY2axpXr*P6HqJBXIPFfP)|AAOE)GW{IK??4yvCq<@$}#S0FI`u+B|1}KP}(* z=@%8!)5&Y4PI>m1{B+~;( zDY^duvEFICy`<$VwwKBQ@Zbh^DYYmYI6Yy&P&vG(untlMy|w$?=(y~WmA zX;PvYHps;#i0)P#bB~v}<4j5VqTP76Q`Mzd6zv+6n+^6`oE&qZuXOnXLxpaeSb^=( z(Uy9YY_bjGu17xf$cE~Dn?3un)Q{4|J2A)lME?LCCld2!ByPE>$I?&xx{{Y$7rn+Y zkDPD(aiPDnXJ6TTf0Wh#0NRnC`^EnNs+-2_;AeRHa(}?<&Xc+Mm&?U8guYgiWCxHp ztHyDk{n*l@^v#PLT%pIztN#Gq)Q+6KTB&-5Sz)e{Uad-Os$T2BPSo0y!h`bJY>K8+-LUlhk44&)G40!*p!Dm}XzHPgFkEtW^rKStHgKWTu^<7sWRpzsR?C(S zM?B;KkKL|NT_iP>${Z6U(WXW{*bkPKl3d}1@NSgqMsgZ3xFhH2)GzBzuGwD%m6w_{ z0oCx*qT~*E$X!A>pq!A7u5p|WwC3+m)in4-w^oxw5jYO&RdRXYn$n4Pfp2vV>^4J5 z7jco6cV<75jc1Fc#`SrYNg8QG%vqK=vb?$W3xUZxZuoj=`ri2kEj3g|8q*QNYFJ@f>;g3-NPV-a5ktNNhDOeuT0YQCDx9TshSk0rjA*}dw*H_v;%2S z0LVP|InK2&hc=5i{%BR>3}<66HM>KB(9<3!RQAV!QM z2h)~Zn!tV`s+-!Jas6n;2ERW3iJfE9_2Nhw)-P}g{{W7beheU!q3OhIrOm>rxgZ5( z3PwrK8f#EoWT}>D-j(DVjHvO+i4?{HiADidQ;tU(Lij0PK)nX3Ep;?g{8d{Ol4Mrf zpOHD|8g^T!wMfEQt6-VbENi;4Olu1-3aAO&gWQjOWPD3!Gvsx-qD_}dR z*h?GjJJ=UpC5npn_UC+D7RLZx`1?L4>BnX2*~H&xzFip-WmKGc+3uC z5whdoaId317zybMN7j))aM4N)3V43re?wT@9D_(X9{6HEmW<<0HP>%=zMtRBZ{u9g zMj^C|6Yp;y@D*oej6GwfG7UW7jQ;@1on`K}v(Q|v)bUlIG*4AZwOoV(H(?t&Z*9A? zpKWTso?W+9&u=bY_71bhi}uK5>06~dO0glJE^wornQR}w9rXy%w${!tYh$BHw<(W{ zJk}xcp389lx!h_4(+Vmoc)Y07dohk!BSiI*LvW)@sF9?zPBZKnegqvkJYn;LTpd5j zn^mAO`m9l*8cxzPevX-Nc~hKwWMf9%JG2(vJuCqG8q{eqh4X*nR?T|YUaqd$Q$ZB0 zyQ6ka+$d6C8Tsj(O%VWaKLP$40qD^3MOuvNutfvZK29^`4D25*!-J09^wy#)TOXPk zTYsoBjjD6*1_lSy8bRU-HUZNcj(GPKr|`Tg)6NIQwR6ox@{S0`y;c?uvLirWYP;|9A>TdM0(+9=tAqY^;R*j>bN?~dB`mYJZHqc|l`Ctmb(R8qDWd_C$uo>@HVzamPU!hk~`nBifBeO#`8 z9RNrfDkCWgk>jVRm0}D5W(8C(PtPY(D6av0J-tU`ppeO35EDZf@}{I}Tr)hZc?9GH zPI7x`j++BYVPLEoN|4zY1hMPwz^vDcvl!kb;n9Ikc^i8U=O(^^^u>?D`^Q93*3B9k zifRfYTF)aVlI8?rBm{av2X=d7p4u1d{*US5(-q4`g(eU;CnPA|tN#GnIuq&cn~$ry za>rc__DVanc32hQky1!%>AoM#cqeHwxp_E7CmocIG!YVYe@py*G}Tj8^xa((!leGP zqT11vb!0A2of3dSEAq)1*HqRtd%Zr}@kJ$$Pc<;X{{U8Z9R2fLW5d2Chf&nywGu@v zURz}V#Di}fj@UF9{XFe;5e6Zcxl(<$!n~Yn{)*hz`-DKqJx&Ha{d|8ta_Osxy4TPx zTf-gBI4Tyhoe2AC1YTr$?;B$(M+6-Xb@jsMZ@F3LrSlp%>mX`@7~EPt;1EH^Gwj~p z`la=2k`^+<)TAG+ZJx^1+etDhJ9`e@`KLV%eC1VPU`kE2gYzJbTiP$$@1+&i}@(A|_kaTHJ6(dBm6kjk25D+=eNIK2mT}|Xl zp}ku_Ds87l9>^OU9DVXLO)n2_@ul8qh~d(m+?;!}kKv{VjMe@(cymt`*QEN1u6B5k ze`7FHyT$_Y86!cxKBJMW`_r;I-KtpenpleG9BpU){OH1}?|Gf!h8mb5g&Bd8NZM9o zyRxdX05R{A_iLE=pHRNBI&l%Bw6QQU7b%U6(|~i3dRCIc)Jrtw0__CuMo@SojAx-0 znQr}4))!i* zMNLH5?e8S6$NvB$Kt46}mB*=RDr;&kl?DniEYC|x8HBbNGq}u*3j_yf*QbXz4vw(f zDf+6e_-n(dXf9RL{;mkIvt(P&6^1a)+~ei0pJOXFksG!_{{X{KexPL6J=MXFSWvr0 zas-S=VaWhfq|{W;PZX2Wv{E(*jhk~Sos;MC`k{pgm0RDQ&>RN*%l_V+8E8d((7-)xZd(Vf$~){{T#yG!dChZuJtPgbyQnnBaSJ zf%Mjr>Q=T5>IIk}RqhD*vMEDa4Q6yL84$)Fb9P{Hw+68l=69CkR?ZYNOy>iDIqWs< z)2th-?4_Pubr!|FI-1DG{{Y5{{{XC{X~tEpCC5_?pZjTB zBF7@A7z*o;pfw|{qW=JX`l)%rr%5sQOsDzjA~<}G+2dLl#Ar=FQS~3Nduo5R3x7Rl zjDknDv^pDa)8TCOiah@S&?!~W+jS_%?VsaXwaiDui*$e>n7wQHil;t;i~;(Bzm}O^ z9a(IhPtsQjB%_EV0!dzUh6E{98wLrIyU!fww>Z+imQy!`^oK9 zO{N9mWVVDb_sA4W)zqCkPium;>nLHZluoT2aZ5E;#Fw_fqBS|=cHl_*YJ#uByEH2V z_bFw1dYG14S43o$l=G6L94-&PAn3a9(Y-@OS8kG)15&05C97zP`Xy85I+Awr>cZsn zr7hm+TYRsntgM{NSZX9jjVInCRlo;yY(Xva9C4-=5;e`NZv@ytIdF1)um@_z>v2h? z>X%0L(bho2VC+M4o;uSSG~jz`La!rVfp{9|6cgWA_H6g92t$!mDN&@A6c4n(ekAKu z-Vwa{#_hpa4hXj+Kn4-$#r?qPCon?!|Iwj{j;l>BbKY!0a)z0imE608` zX>TSjfw!RSWd8tWG5$IMtC*J~8UFy!zL+88{U|10Dx#s)B4eHaKlp1%P>(7I6@8;Y z`3!3_)f2Sf@$%N0i2HjDIntP`w>?0t&c7b$;~2=~)v8lZSfwI~keOc(lj+4{`>@=yeSgPFyWC7m525}Vao(urq-KsmgWMltK4VJ@ zyndsR^Zc=+WSxACz=Atsv*yjs$VLTN91)7l-Bu-rsiaOBGDja@f2O$DZ_issWucr! zG;M|rmRR51I2@SU9R6dGq7JR5-6WiQH@AFiHnrNfrSD%A52<$*nltufPjG*c_Bxux zE?_Lb5WyMfX`);;ozkm+cEbjn7a?Z8`LT&2w_Tu+d`%p(tYasiGACjKDb7@m4ufK= z>R2}-)I}nL!7Po(&(hi@z1S^YBH19Tqme~WTvJNN7{_{feq5dpvHEK`R8dr0>ScnW zHc6slu8c5Lj^K?OWpWIA2=y;iJ*pawiX-`pkQ_4DErFx&g0t| z(fp2v{2S>SS3j(p zYPl7AWh0V6#N*}W56?*88}*n!^PBh@Vd5*XrubIoeWiqOf=A0DzJF3LP+BVFt*3>B zJf{=G<+7p2IZ}88YHh|ba$`CZ8{i&BGtM{%8qhSBsu+GDL@GSwC|CiU9^;(kAFiru zI(m_rHmV(`fre4|`E0t|M;pf@9e`IAZyjlq#~KkJAajw^@~r%6>sKJTIM28KI`I~v zG6Up)qo?Cp8GRx|^4Md`@`?O%TRP^p%GzPFC}~+w%(@@nzeX&h0ASSz#WsvRI|=sO zSN{NTtp5O2Pg63+@yrrvTs%@>f~-H5isQLSd!&vj^Bqc_;A8@R);?q0X__eKS1mOl zjOT(RVm~!gkH=ON^vUJ0NRP>CdG3FML#G00UI;18C#du>^)R9?~ z79byN3I|aA|zz}tT#M= zo2HD^6a~FBuWn6o({{TuD zoo+R9%REI&NbJMcjtS1WNkw;&I3w;3G)gIG-~>SwjM)1;{{Z)EjPzA5%2o}BgUpBD z*y9?Jje=o7I2;Uh`BCxsn%U)0>c|P@nUrJa){D9)sOE!hzVfJHKA0+4f>-2^k8hFo z(-*0_I*$EsFcnmg48bs5g(ujLbw1-u2|SCFMgDJLH8=Tz66YtMxB{e0gQBX+uNR z=UbaO6h{Ql&-|^PnCxiF`Zigqx+3d*s<>7xA}Upa6p-wNW~pubbBt|MjT-ox>05c} zH=?bktE8l=o#l92agAM(_eyimxZ{pAIdrtvy(2Xof;pLgS0P=?^bP?TAHPT{?z!u0 zMb2s)g|-;Vk^>{ia;LKcoDg(1uZWYxdSvJoR^X`;Cg2ZDWCKPI0F4vGwv#OG*8XCM zy*V9t1pC(R>X|L}tBe&@6)PN5Q3OYDpp&<^qu(RnoN1%sox+m4rDtk+mPGjZM&<4H z5bHGf-Fu_9T4|=Mnt0j@nAK#4HE%$M57o$zw>aEJK^^_{?C{2_+ivMt;-Rah+a*g& zD5{xKLA?~=L`B9&ZvNWgzAW(TN#QsqjFz3QHU!AV6OwV(wc6t$))+j1Ka_`&fsTL! z+}0}bY6g=twlv*#CndY zqmmdScP`RO$AcgndB8d3Yht~|dP`kYvLsDS6)e(|&zM~!ELU%Bx%&3!U3*>DH7iK8 z*kFlPU&AVul}RM3ufu{kIj&>i{{Rd@qv^M{-3|{?Sfx{{UI7+|brEvSN~l%ksyS zx~2DT$L;>C;dAom8uXy4yGw8sCf#l_Lku$2GSx^1*`3q~kCl=@PIHcQvgcayLPpGy zS~95IbG%@G)kj3J=N@Dr{{WbCSaz$y-w}l?y4e_PUB!h&7{ZL6JkO?<#SAfBBPs(R zr{I0$Yw3l?E~iUvRw%8($}j`tr6XZepZEdl`gYa@ikqdKudO__g+wu|d*eXc)!BVT z7>@bp?$d7tYnrXx(#d&k2=Zk>1-ULx?#Gi!d~Kp8wc!0uA$@BDd253+gcuACbM0G; z!se`G<<*d<*50HZUF8=?{IrB6;@E|yM;verdI1oqYuBO07Jh2Guc;0p1Dc z8PC&4UVmBqHxyQ%KYt(FX4$hJKO;HM;jPu&&n?Wd7@b4AbzYp;F4KHCZ8Wbr3fpzc}BTW#vv zh~v3OM>H``Sht+JNCBAt0Kxs$KBey>MY7t$* za}uJqe7OexD_Z(h)|Da|)F_%Q@$2N@aXOrD;U zlp|nKyM-CR=djL}mJ5Zl$wwtsU+Zb*jiZ(mpHqh6JvcZc2ThA~N6iuxDdvFtNX85L zvB%3wJVV57kam;7Jq`zIY2jeacKBsGRd^k${h|yB$9+O*uyuD7c?Es->m@kJ;A;xA zZ8)xuVBLZRQf%6F>}Y9f(c_jSVE6^Gh6HvYhait*s}mPGv4VnQOYs{=lqB-={&qKN z;d0U8m5Q+FMGZBjyo<7BRz@IUfFmdCN{Y*s>!RZbWfvKd;}p@bZ#}8xknUbS)2;>x z{It{Q$z!hR9<03@dWdS}w;EQabp|5JUQdV;3;`0a+C9Ep>LH<{uB@5ng&InE5JN7} zy$_ZjDskT}u6;Yz*1K(ot@?IRJQ7q}YTA(;5(LV!vxwQd2FP^hj30e#>~3MbAKd={ zyr_)K$^hK0gV1)abK+}Ds|d#V$KY9+VMCHtfFqK7_NR}BT~|d@Peo(6d<0cA_NZza zx~57Y-M7Ca9Y3Uxr$4Iok;itm&m{EBriz|I=Wv-BN)m9~DLt|dvsI6w zqq}%*(VbC5msX>4sdw@gEye_IEy-aZEUL+pvSV;K2Z60q)7}wUF7~=RrKa!aQB*>* zK`O?$WNeUmkdS%g9zpM|Mxm+S-&-sbPdP=#*!JWNr-Rn8ng)@h*j$^K;e}>llOV?8 z7;-vR9=qFUx_ajIP*r*KR!L-@E^${&hZ0Fl!M@r^r0iqeN#~6VQT6Teu9opzb+gW& z10eGt5f(7X8!Vq?{YDuV)G`TPdyH#K_~GG=!=-Lk+m#Zn#(5!@3hEgEMVgg%TgX{sSBpEi$>6RHI*!(F_m)Yv zB4q6YA@ZlDeZ8qO(Y_^%C7$71c7iBjqX}6_6ix)v!&Qa=qaI4LV4t3ItsgbklG__F z1)NITPy!FFxXycPD)pB{+IoHCu}>7@vM4H^-zzzl7>uwB<_w6!@IsNafJ*i{yr8)C zjV&dv-19>P&RP;Hnr7W49Fr+!k#qgr;0zEO038!Hp9Io*hzFek2ja+6h&>@L-?b^9NK6&|_5MM3R-yw!C(lu02iCLs-NAjj} z0K)IVD!%6&pPqy|PNI}oNl3z>E2$y!>LQ=i`w3qzK;V$-!G6|xAm^P&@e8gZ=}Qw; zB(eF1phA60T0PNZwhJywj2vWZF|J!Q_d0nxg?a7*b6c1 znxR-aP+Kk&(cbP;+fqN*JhRDF7RiZFPTa&!^U6`l{!P}-xeG)-`~(zp*c z=7s{YoUCSFPWLBx$0T#xNy~LlR$sb~cIn%)(@-TWl}{7~O|>fy6`C{)>EFo!t^v+Q zG}rK&hS3a_Qp&ce6=j}Asi+C@O|ihH_l>JHZMD}-q`0qEmcQZZ@EB|!6MBB zo~YOz!M2^6D{}s>SG;!xjW>jFRG=Yn8Muvr_ZZ{8y=mdTT6%ddGSsWxDX8fXJ4UaW z6oh(@)&fJZCvUog>`t`0CF)0S70bvsx$?wK!-l{)=j+y>cTaodu0n82jzJmeQG6ok zX0h6ZZDqOaw3SmCX&&V#_POv>3`C%?3;xyo2IUwiS172eIR}t1f+AcarZ+ zYAU384MZiGxhK>QB|Y%K_eL2an6}u&vzWnEUvz=Fc&8PeQEWzyb(Ym zKzJOIG0kHe>X>g;p^qY0&&$5KTjoA`B(D-Qo0P>4oa(syM`BHsDi|L1L=Cp52%U^Tw`r$umT4i_ssj*CG41o!e?{JUXQpm%J<1;`>7oHhh^}NDcIVayxz)FXw8px@ zRaH_QD5#`qCy_|rP()*0yo@j`N}pqm2l#WmbC*0~yHIA0WPaM}83c7}zdKDpMUci&Nh7a5{F=nY0cRC%)Wr<~t znlPE;a3l|(8gac%=+-<>Pfc1KMMSGR9kH1|$%P<-JtHK2dDD3#j?H6&G*o~uW4Act ztzb1BQtImQrMP|U`6ZZ|Cc(zLMl#sfF6WMQ+AdDHi)0GuG)>cht@7N!WQwRxKIaP4tmu5Wuzx8U3OFIp>+NF_N9AFM}jC}QHGSn_WQroga6YbmFdulYxE64Q&5Pq7t92&iO zugD~Lijp|U=rr{ug~yzNsJvWTH8?y>mv>aE=j>al*Yhsl&q`X}&89zyGH>e&(f!CN zlm4hT^U~I|`dj6pW&ZKc&b@&`#DnEaeywnp_WAjXrS&szq_6(~;iVs#+x+xz)@%j5 zeP&Vnj+T&DLkiW!Cgt4+3{>qqoMWEak^)wy-RokUr$<|pKer(~eHTl*rsVq)aDKWs zmg#PnrtPsL>%6qMQ^Cmq`~3mXC2(NJjt-59OCAjh>O$3911&^poNjeee)EsrtuUkl zK3r=wQ=od=H|a@4Yg$R~2pRtXoDP$I zKi!^-qm|ZE85PvUTpSQX5(p#i(^scmh^iy(gdfLA-y7}J*FKamR7WI`wB)dhmt01` zGLCXooa0nn`tFNo*j4s`MPR&lG_bPuO%GU7r8P{kt;tseg1@Z5&gBE&`^)&~O8Y}4 zJmnk!z;_*p`H!L2P>Qdq`ai2}^m0>84P8YfGC*Wj%SeONtjcm7PvzL_VRZ~QC{~s` zhR=^mI6fz0;Y5r#u>1+f*F?CU-YuoQ1Y}b87MIfp35gWpt2y;N8F@ZrH~8x-^_3|T zzCHQ;^{;w{Fl2M=Gy8_K4_ZNq9N=e6G|PwBLFtNFtXYG#fTjNcNOgSuD|BG_l7eCd zL?HeF*Zkr8^w;qNrs?{c)-M+FvehIz_a{FS2p#_b(@cIN>NJ6SZA|jHQIV6Te?#>R zM@=!Ku6F$$BlkVwbH?%X`HeKV3K?aMhnfJ&{{V=4SC-j$%rcCj93Nv&j)EWlY1#+= z%D?R$X}+$f$A^6j--j;B-5 zsFdw_lm$4%tVhrGv#H4f%gO$ zgnFgX+m~>>WDY-t3CU%pP}q!(%oy@Vu=#2X)@X5&7|#G_B>w#wN(*l7pO&M6??G2A5-nm&sOhe^EgsFk^cak zYQNxQr(q;)5tV^c^&O6u-^Ud3?i@J%^}O(Ril)*oRU8(9$jJ8jie>c7)7Ys61zz`~ zfFeAOOEepXxUrAak3u|<*+20vv9 z;CBdl!N(kC{{X|b&}wG%GeSn@nN#+UT-WZO3V7Cg{Wcg-Ex`174*ZZkkJ5;Lqz_C< zQBQBBmYPOcDpE#>;Y^OS^vuCYJ&p%IezJ#JFI!dxqPBGHN>fIIb4410#~c7b?XBhG zjR~3xHlmlws#?kXsUP)#Kf%+FP;Pdd`+ge37jCfe7Rhpw38^6=0_1KXn}L$KZd9Jw z8VkagP^=9L6_L_O8AG1L_RT2q&xYGszqiz;o@miyRSO?L!>Ks$RrOYz7bda(6Vg{j&?k;5%+bvx^Rpf>U5_8SnQK#;Xox(NTzva#mh)K* z6*e;Nss+qtn1BvxrXK$Qe!Y^U2qPK)0E1uQrRRxpEq6_-8H{W3F%sW_BN@**?0viI z9RVwPP6->BeEH(EmkTH0^UwuT{0%(m>mro;T@DzjDnY|3!3Q4W-%)L~TYAFfjAQh5 zzv=$~2|kj(9(C;;_R4xH(6rS^;x!JyiCMYar9jT(lbi+QbE4~yR9kv?sj8-{kSLm# z+Y;n~g7Z$Bj(=nlGJd-GtR-*7L9mixAx=8_g+=aowUZ!zv}fhPJkx6XcA%q#M^P}1 zr%6O*i3&=gax>Uq0(sZXxZ+7Ay(wkfx zmA5Kd!%)b`&XnpR*h(_+6|g&uU=G?dz0>%qd|sTQtAark5~-`E1{Cs%pJE>>Fwf*F zFj5NThI89m`jqb|DZ%WU2zMM|?6&ABCc zYpEtRUR(}PWWq^If(Vd)(h>;OcUgGG_uhq~tfJa$r;bFLo-_;!`qj$g87a_6j|`IrS9cBw^sX_FZ7FXZCDXQ=I^?0a%+SqP z)bgc5#|(+(w)qoukrmtqHh_NY>ZwVB6%1Dd0ru}&y(Qw2kjCe7H#rBbdUY>V+3Ktl zO-MFXQB%_<_mDEN@=TjNyd3gyPI1PTPjH~Py)9I9#6>jm`gfAcQl~1d*s`-9pML%I zf8rGLL2RXZ3O_X-f(m)2F~+Q(b2wyi7(y~eP>sO$JdFoiZ58x%b+SVwZlW-ORrfkO z07HO*vy6}k`DuI>a9WQvAC2>!-*5i_RnRqUX6shBwMlk^Z4gB&F^~^>ucEWlQq|m| zm@Pv^N^|^<2py#p6PU|sH2(QB`+TADv420lZ1B0 z%zj#8^p(%6u9cOv)wFb`j*Pq>8b~9PI_Mp8Y!e*GSRtCccJA zB~7EuD;VQA9gYdAwuOUp+g7&nG9Z<)Pa~;wjN>1*_-oRv(bG{0i?NxfNR|;F1U~_{ z=KurWIOATiO-l6t01}P905=B&5XwJj5$tq7mpF+e+vsDoH&LHzzE`rknp;L-WJTUr zp&rCkdF|H}hIoXF1yPa8$PhZg@6P$c+X>v40TsjRP^{2mdPw7m8mD-W;g=gFTxSPAYqoS};VRW! zJTb4gP`gt>R{m8Pk$lBK%ZcNim1HWrbA!Pn1Rna;>2O@b3tTsp5X==@0ggXtWF9(n zu3h47W;=%(e6U;zQiGI{RYP%V@hmX|8r@>1Uc5C@P=J z_}Vb8Jm-apEUAWG{{TE|U+C9xxJwUFM@v#<=}KzIX>9S3*o~r${6ePuwl|PTKWOCZ z26We7j)a!cHDp&PsBF?ytYQfc*rzd^h>MR(?kXHGi?~SdRjMU| zpUaF}swxRpnm;>mb!~%s;DNY%jcx|{l(NP`D-aHIk=LA8DX_b@Ns&unjN}uHXWQy) zN&f&zm}|u~zNXtWzod5tjsZDeiBJf7R8#3DL{qgea@x%u338*qS?+g_(eqNxS97Qj zEa!C7Dyo&w18S!2p+^gi9{&JHdvA#K-9EGxRTLLuY9f1N@jz+oR$b?8Z5VP7Cjpcn zt~HxH8ouB9pQx`-Usz-jQOWVXd}WL!Wa1QZR3=!GMmgt=4GdmnQl19cGEc~y;+{6A z-BA;t0>n6{0%+3ti`^4WjK!6Win}VUgt8#(w1^#u;SV2~xcG)@$io z7gAX~MS8n6u1cypFvzn{Qdi>MMLuALN62jCus=TMT9dB&Uf<#p*4pPmvEDg022oI? zXKR2#F@Q2ga8J-_KVzl8cx4?+^%e0Yqqa#bG?7gaY3k>c`H0|vS&0q?0X_M~G~V6U z%PKi-xY_){q;~3wX=t)!ZHyhjjEsBys@*PiGbHrz)KyU2>bIq`Tq+iI9&f_RnF_NZ zEIhM?lNtBYgRd_=K}__J(Z>XWYO{Q&mmAilWO9;4Qmj1$AJvuYSBCATFH?AtZkkG8 z($>beR67{zqLL=~x@wrgnibjxB@MUJoNYYhX#>=~O&?Kpr47tHG}M#S$vK7Gx}u;m z%?FmjN%I_n6B*s9M+uRa5sj<3;PNs*jeT=_35k^_W1ch9j`^?Nqoa?e=xHl$l{FMI z)CnGGVRH;mDyey6jH&dmr)VP?<0DkfeWdCRn~s{YmN8#(sohOb+hS;`1fE(5 zF4Co2YJdkPRX5r+ma=~~x#=yEF`gJCja)|lNZRbNWq(=eQb#%N1~kU$Wa+ED4J~`! zprZ`G4w9OD&kNH*<{*Wn8&za-Ng(d*2Yp`QZLO5BG9QSyJa+?%Sm7p>R2`!{4#$jB zm!f(f!>Qp5(FMZoWUT4>!(CIp3ZoPnGcW9mzM`&rePcahetq)SvMiQb`;s+%O7&Nd2FDYx0hmx|Qs9$tGN&5krLsL*#rVdKIgWMF2>PEYPT}F z#Zd8sG;Pd)OQS-p&5%?{?xB|;DSYq8C6~=K)KZ{ zb0AMDLK(M5v>my}bjTg_2B|frswC3B0AuMLPtujWgttr#Xjzxy8SVG0jY)udk2;FE z9{QV3xhI}A&SW@K&2)jw3ODH7e^_Vj~iQMP0{5|ynZPLbZ>c+2Ak&#ycT}3d+Dszs0z4fNQqp)w&w^NMDw04uMF8=`L zyea;yN;C^t30)ucY*^~M(eM4JkH`U_TD8E`9~;~2Umze1ds3UO1}(AYjMOjtEv3~I zVnvu^JA_M*^rcQT#_2Pa7TEE})Z@(*gL$@+kEr;Xffr)&WhSn=a;h|@s&3=bKRoF_<5m8m(P56N2pVrBPcuNL4JVd_s)7L{CmpoM>Bc{z z=OA)Q>09E3RWNHsGf1m6vdGY9A888m0pQ~~$2s|H$pVX)$jBUGsg2%EK0F)~j(+*2 zZHuRRPpbStx7UhzWv-@@DP+lg$>t+CJ4wJVu}*$NRy}_Ex`w|V&V%w%uip)NeA_zy z8C1Kh@MKI*LnJieBN!O>1GBem`r3t6G zn&LoI4Wte`@D6J|b!4-{O(c=R^0x7mMJ#svoDY_>msLp}O0$E(&mQCGbFH(|Tbk`u z{^Ald_ps7q$LOeMy;DG9D^c+ApEYnjEL`Egz1vc=n``+&GI8-{h}A7v#$@v_sy-Zl z3db>AsHo=JWhmg`y(ELr&>eKU-R%_=?y*dz*^@X{Q}ymNUHwO)m7U&pJG&i&x%u;` z{{ZfJO6`GCS2)HY&;I~xS{07iIAR}i^PKTX)>hgSW14>SiveV}5!lhdN8+ICKzNBP z6t+(e!_26|r(|uUHpjOJo1Skm@&ea1yyG(x{I(|FVhoGVOwx*N% zu|ig5P3$tDo;NRjC9|0#)Z>unXm&L(5$Q5(o*uffR@!BaS9iA{&}D6HGoe2cnaTaJ z`D&S}>Gy-@r~2c+*PSUp+`@Ts8>puPzy6Lr{{Z=#mHy-7%)@mhQ5hVHLGsVMn%Ny@ z)BIn?xdp%IiuD&Ci68U|ZNphi8y-Jlf7$f^sTZzZp8dQI{yhj=8D#MYS z{4oCj{+jjw0CBo0N~ynA5;z#8KzsZCvr+!pwH?pfKhmxL0O0l0K3ePl06_k<+n)ab zZ>FW5LsJ`VLcj+ZI2p#QDf)_p(`Bk5E$7If7XtxRN6)b&<4L)E4!4K{o8@C<41*Gm zsL0t~`uwMHwgM&ZGUYY)*OnjeGw9!FFhh8-u)@?%F>twCQ{Oy^%qw zfNdE604P4X{1?k#B-TPd`Gfp)s*AwO15(K=UaJGFks?Qh%Lfcg4tp-qpTAzo;5C)G zH)_B?(OiT1>IYi29na-e572za{{Z@%{*nD@sJDAb&-Tba`iuTLn@w`IGZqz4ZXgfx zgR+y4f3B6$cmrd`Mdq-5$fx=0O8)>y`zUo^)0L&0n)EU9~(|T`KmvjmJ$B|N831Do8@8u0OgPS z+O@a;07w3wk<>lvxj|qVwyy&{@tr{Un!$NHzav8b0Pq)5ImPepAJ&gPHqHi3Y#;qa z{zp0E+-dR={}K`p$w+*qmS9qXrf zH^VnN74^7#muqBUxqXMdYEK@nR5r`C0?w-xQdiZ)jynJZaVc;0F`sQ_Zo27ipX-Z6 zl(JPqwNa}zH9|;*<6ts<`Cpjrt?yW|Q}rVPsA7^CW>nj>>%YqEC@Vc@7=C#;k$1--7gWEIlSp{jDLvruBWK$LKS-_g=K+|btE59uafKG#l~tX zx@x9oe}=b2tq3ofBHRZo0NUOA=UTGAs43dZTM|b;<4rhpDe8%tN|lsnDnafv{Ihk3 zN!HNZC{pq%ohm9LV5umQGrJj68B#lBV_j>ypQUVlJ$ItE)Tn}58iD1`r*&Q7_kCfO+k*Ni0*$_f?VJRFZjeDWzQQ zlrvypa1Jz<3G5c?Pxr{l%!fD`9e#A;=u0J>YSvDpVgt#+&OTL$sd{UrDQ6JPSx_nr z3h_D}?+Z7nQZFYtMLV(x%MRxNYSyJBz0FzY+oYjujajBKOvaARgNaF*X^PFqvmyc80{{Y<%@A^Kk`zfhr zjz~$^cL3y!W4R|45llTmR~QB7&b6RwP!V*O2bDs;_e^A!e##PvIj#==CR*y z_FCG@MO76YM6o1qPJ%>NNOxzLjmlaVBO!rdUmUR7(JWI!1OEd=7VG14k7;IoV@b1uYd!vjf1B5hvV8 zEPr;G+{11m4vb7@R{)d80c)RHc)HVK8=0aK2!`W>o~I+dG3;GFZ~b@E5#8-Hs?~5@ zqNt=5Oliw3CAXnO2X;O14`HF(&qhOMro2HFPRdB0Syq?HiO@|4*pqQx+kjkrh}Ulj zyg;t&uNL}lHl&7@8efiV2^vOYB`kpVRpX5jb!78TZoADIBTB+~b~6-TR!JEFv5fq* z7N;647NtNXqd7S1>NV4R0jR~Q$2`%nc$RRZA3^U~+V9hWyg#S9Lpq68*XKB7EL(fa zCKr1WHV`=-xYmA(x6TyBa~*1&d_+XX@-}j%z&JVVPa4ov6#Z*2hKW3hO*N(M_(u{v za>EudRf6Rh5(ybO=SZ5m2+}%P=BlQqq?Loi=47{_v$;fIoMe5YfOU_yxRBl4MqCwH z2Hardj+hnSFLc{g(XAvA0?v$EY2;w{&2Xo= zV-g z=OFqVVY%)H85%0TbcNn}R!cE@gsU>okW|AArNb5uIXj5$fwvzcqOLUv5>La-LM)07 zTRSj$AcMtY#*=g-7k05o?HhmH<8V3Sr!m&t2zDEk$~A1WdbE0Jhd1 zgUA2^JL!DN=WRlk)j!#PnZMS?g(5vN|6rouqh* zyiQ7{;<1^_26jKPy^e9;LUn(luJcVYq0Epo(T7-OHa!PEHL zPrr;PM4Bc{Ga%;;&~ealS!qADblZU_o@gaW3!<|g89+JbsiW?r>N;!Pwrg}WI9bGT z%F8hCeb!o}E_}^0p|_ z%~MXUtp05^L`fw*Qey@%?4*7nw4$%Sb$3cEu~65~Ms885cxkf@GBiv{8+imWlDr&( zG{&P_l^s+x_UU3&rHxwQY>`XGu*^Kgkt7+z44yJ`+fMG2>E4@@qD{u-Zh|Ma)=5xg z@<1M?3epgu5Z|=Gj^GTPE7NYH(iB^|M0j5~U3+?p%G*`aS{r-T z`~^isOdVQfjTa}CD;Ul^#3w$(QT#UEJk0jW(}%l>tl}ae#&W&LKUzTE>8nK3ino*E z#$De&qbdUfBCMGTQwMM-fvyxi6<5^Pdoo!esE#vGkwX;XCTOK6le-%LC4SRn@CKz^ zXNvB#Q&iQUTf*AP&HDtL}n};%${s)50lws-jA{>;)o#Q$lH9%y`ooB3VM<`w{fe z?D5<>M&TVz4SW8TthiQNzeBtVVV<4QX~Ra+oD^P$5utCQe`TVojy?-vNx?lo{Nk9M zZx2d!A642Cth3w_1(xKLYzc;;U_63O-!TU}Pb4oIy71qis^RNPmHnfUe8qTn#{_W1 z<~Ja?eauuz-MqYyZP?>U{+he=<%QWRZ1XHKByu%k$>vrKlD5fYRwv7M4Y!jw8Dx?{ zxkCI$82o^(4Yl2?-A3<&BS_rZ-$#Y*#C0E;iY!<3fEfA$j8`f>5ChKD$n^ ze^J4Bu-$5{@YGymvrQzD(o0<%LgYxGv^f~aZZZx5z}ED;*W2zgy|Np^MRAm$DI%x~ zF(49t$YvaOIOACN#2EZTvq4#JzFe+?*HlDJQ8b?yN=EGDl066He$djN(Y%sD3AdU- zmTasNu^3bPQL7Gq)$fSeW?=EDBaqIR;QKKZ8^TVgxb#K--*<@~NhhJHc#>fh$fh|k z%&93OD}kH>bmy$SQuQZV&2f%+s-~!dl1cCZQ9DzikUj>`L+8`1 zxbY63Z*v^7s+4mc6pn`!e}!-Ep>?;|q5#Ih_{rIvM)CCQ0PfcfQ4+>PHcq1zR|suq?= z($iZHkWxb|Zt=EvZ3ASatMYTV<)>OizDAR6xS(}K$SsUg-FD~8y`Rg$^`0|V9c4!y z<{L$2Jwzkn=+B%9$0XxseVf(5J@uUWo22UcWup}{!qPY&t3#Fto!z~cwoiX;XvU@L zOJ~K&U37|l${1w(1sO=V7*rltk4B!jLF9Xe!i0Dy*u|WA|EWv$u%okpK=!5PY4EEj=X%R zh@4CmuO){A+v`*qrKql?hAI|Xnvep=G@;a)NOhPdHh@Q`IXUl*H9CIL*ZpNlEt(58 zRI|`XB|i?)Q^tzmp#_-poD6)Y@e@`}GA*Myy~Sl^H*tu<{>IHMT>ZDWBnmFrTT=5J*~im|*tC27i8^ zQ&T|Om5u-)gU)h3{U>}PiBC{eNJe&1NCEj4bsBp}u|EeN{og%CAR0b>=*Y=YkDXGO z6e+@ve*ksqH8UJxdCAAuQ^`QA0l{Bwax%Zqwx$Lu-NvDxJVBzUaCj>5vl(G?P_o?CC|v!b2jL)^A%6kEx)NR zP4lm)ACr-wYRqV=_b-`uxyhfkT~x#Ik&c7w7##fdK;_!40EoxXQlG?j0^Lf#I)Z;B zKjWaDkxlnnar3FC{v`hZEf#o(r_MyjGw6Kg{ zXh*S>{^c$FwB)-VGM+#VK>%m*(rc%EciLQz-f8du04CaP)Hj$mgOBmiu$`ukpk>y$0IG+j@Z_eqK-)I zL)FxERO6o=jacZy5P{as0KN?iczlpSFt1u;MI4gJ9fp%bwa} z_?Om;)-_g-(bQ^Vqqb90N@`uBCE+YGo>@6lo-@v~{!@t&$RHMOPs+4t>QJwI3JZ%K zV-^P(PzP_?16Sg2*D|tzqAkN5l5h{d9{L-nTG&*BOHAfO0oc?&Rh5f=ueL@p-&PcG z?r5c~sE^`YurPy!Sk-uK+ww{I0r=|XxQ-!`!yj5E7-esTbDEa5MaV31=>&uKduqa# zbjJLA`S!@pGx=-9wZ$S99}X98-?sg+p4r!0TU(ac8Yuz&g6-V<;B)Vxj;&w@8ey6> zY_9tGM;}VjTevPQmq|#S0zyP4zqIo(>s;v<>Q-d1dDorThlH7t1x$m!P zeviB(tdPq>-kf3Pd}A5@=Bt}q((QmUPKli0nz}nnsZJ6i*y;sPyo!kzzpn?}gO1#4 zZ6$nd7#ZLn-}q|SbQS(N7s{I3=P}#}mQr~g{Xh*(hr=$clBKrP+S@Ek57%>(liRoD zpx?zB206Wtr@a)KW~GvU4EX;5Emn%CcAcjO+dA&`K3R;CM;ZPD8k^JoEnRu|kg(In z)UK;5N@u4GPI0%)M+`kYk)oyW{_k*!QaPxEY-1v_|wv?pTaj5_j z8NK>ZcKU9iJVE1u%IByQD;;Xd5yN}u9{RGRu3VA393Q52aZTYTRnN>a&^I6P>^uJe z%{sD&!alT+VOoH;52Q|Wk@VZ3-^BhJVa5D8Jv~)#_Ex423=RnE#d=dz5^@I^8nuF~ zs8jUSwWq?~x^-j^L+SQ2l1JgUIxV2^SHx=BVvaFDT0(XYJc4oU$QliG{TfHx9o%ew zO`qXbwx4*5mWhC&YFg}&bWcSwn1Q2eU+ClFpPsO^R`6J4e`*9^ec92ixB5GHjSH^k zw{eXB0BCRIx?>f@Q)H`TbmD`NNWec{y{m^!_*vE6Pj3};R7L5|LdeXh2_5mgjN?Mx zVbWJ#lVL}6q>`RTK45W%-k@z5=NJb(=U+g&O4n6l>6>k~eV%nRJ7n_CRIwzI2>_n@ zTzJLd&Hn(e;t`$0km7ib5Na!JmItX20Ki~N;v3V0)o87DYcqC_W?lh34OfEhe-tx0nJivA|n zWGuG46Yo&p_cX7*_)~J|IjHDst`@!XJwjHKIViHSm5Xnr;Kl>hUK5!`OInp@;Ha2IGPFd;iG2bPYqnXA&y?Nx4d!^lX;fPu*!t(Cm}oF{o1nYPYe3G z@zj?}nn>x*Elp)quM0+~Uc2NBiexJ(c?L@7XNI?Q-%wm4_|Cbs$t=~9Nj@O1 z4Ble{gx^j8$F_8O{S(x6ib}$OFvl{e@A&8%AL#FVW{sNrK@{9GMpj}6xdD|D z{4JxT!rtx(WRfo|xH&i+*X3CB-_mc2W&Z%?{vNrKC?ygkOst^$j-*&C!@Xw=a#V~HRwyQL180@Lfpkt5KeKfO!z>g4Q0pPh>%0DZa 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 U&3Ugi^?hDz&3Ugi^?hIe*=mOZhX4Qo literal 0 HcmV?d00001 diff --git a/image/2025-12-26/0694e25d-4e96-766f-8000-b8c29eb12843/darak-1_000.jpg b/image/2025-12-26/0694e25d-4e96-766f-8000-b8c29eb12843/darak-1_000.jpg new file mode 100644 index 0000000000000000000000000000000000000000..05462d6f14cc6cf89c60a81f5dfc22b83e0034ec GIT binary patch literal 195312 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%0DF1Y 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 z z*VMJgM@J-z#hez7G+ryr1^~C;xzmO554<4SJ4)ZRsA`gydypwpQU3suq>OT!R>yn+ z?c|K(zJ(tN_6mlQw&_|kS3N|4x$l*LlwLn!`D&Zh2EO%EtSx7?ud3BGX>39lA~;}W zGc)8IAZGfHk_HBsx@siVI=VM<*`F3Os9bue&KKEzsU} z^7>a=P;OSragoBV+{|hzf7y{+9De<^uhl)xXxS9->}{h~Y3;NUi1!83ow&_kQ19J+ zML8_QV2^BIb{h4wwa0F;T&J!K+S{w4J_q{enqj%YEQdU$|)?3zU zxMX0|i76As6oCHiWMITMapY&)PA#jb_d4yFV%ic^%l=ZdQdL(rBR-Wp3_zM}HxM1M zfu8;ShJ)7ajWz(pKs&#{_+Zgj%gCH0dP#O zju_4cbgy3yQeFB4MKMjATmiRDJ9hM_PFGIJ>B&Ib@jjA`=UvQ}-4fhZBr z9bWCd&336?Jk2c$EGXiTWOrrme>2}ohtAy6D}^*^9ci9Op@K?3GaD%cjTDyn(ul?p#MS(LJc2M0aD_RfVc zO<#R!BU*UcrkV)x6e!WFpi-rWGI+Kz%eeQ|d#!Z?bv=x6$!zwkWX%vs7_*h&hRFku zy;U7auEnfrdVRt`_V+Q(A$v(OWC%vySbz^ArV{5_N|2;$1gQ&yO2ZG8^#k&7xj#`J z8{1LASbCH)#~_v1vhz3y;1iG=IL>2ab|EUSZ)p7{Lgs+o&Cs?YdO3VpGRSGczg z7wkw@YLPA{o8=*q3YeA9D`bI^SmB4aW1l+5S1l#NRrI(dc#S1U!w~!zjxb3il0Ceg zS1Oj3=%#`wovJ3}kt{>D6!RpKe2ffWeeH{=52KHAuA z(THTo%XakV?O4iWx$v8^w$=CHdwz9s{h*VW)Y8);(<6Fn!MX7VfD#PnAb0$aooG*2 zZF(xpSjS++$?fmXdG@VsZ84HS;2sYroO=;hIPTLLc~OXEYITKM zIKcH4k8gh%{Ppds{b-Fj#|Ln-NL#-F;eUb751mp)&S;}mG6Ym&e#gIT91I`huQdCD z1gV{5E$B{+lJHP)>-ZQB*de_BS=5Bno%;*{&TBZV=b4leb|~-t)p|6)DJ(kM!*Im*+}n`t355k<5Ni|rOuu%Q8%JaJx5^NrUwJD$G(J-S4guYhCwShG7_qL zpExiMQSQ1*N--d!ig|f)kjO!E*kPBKFQ>7{$785>HuFML2pzuMew0H`klRjo z$Rk`5IL>+PRXJ|M2durOc(r)Y_@ugN#kOoFFO@5TxUqf>y#9)0+Db7?rh$93MkO#l<(hc!#aE9U3 z4ZCV@Q{<)jPa4zM1u z?Fv<8W{!p?01(U+%;XG@AEuZ(7_0Rp3VF)EAC)fk$v@)V(NpFdNIzp-*uHeOTRcW} zm{0Yxs+7RMz#oM7C%^L3ThdR2ovpq$J(F@h*1Cq_Qj;{XM5!z)%Oge#hQkiS?tAJV zbW!mIaI8mk80>#8-gBexO*)BHwsu{j!%T*bNMX%Y#&~3v6v|AbC#I~SmzREIewu0c zk8`YOwo$g1IgW8Q;zEYP0CT~he-6#RP^_Ol5Op!*o(4(4=7-zE;VPotYg(vxHJPbn z989-9RH|{?w-82ipL`tvYQ7csrP`_`w!utbbu229T*Bx5L*$RK#x>AuNBKKEpUYxqDSPz>ZzO6aKbqnH$rio8PB(_O>=@>uI2&F|6^ZkqhOVpQDyB z%L6_1vsYVgaZJK`IU{1k;Gtc2%9`Wz3PM!I*ucWef-!^N2U^wEEwy|hYwZ*@f1Hp< zCNb;@8ZQs{OH5-}Z}boqd-xLLkF$gQY9jm~jv>0&RuVY?7LhZY5`TpKeXD@e(t0ch zaoA@g2RQCEg+7Pzk*?To4~KqKYwjF=wBQ~XcndL`(M+ecTpY2 z7dvAoar*;Y=S61$yaGpj3~OP%XC4@wj2{C{^-sd~{SdoBXojLRc3jid#;wVF6UIUb z)dstveM7RdiT34jjCpi{rN`z<0x_$)!>syF^9dHOX79#SOrZXR)q6dzt!|~J({7Ls z#iDF~DjV$&N;%d_&QDIx6Me69JV3{M1 zT)1Q^NAPTS)n4mGTGOy@XuX1ipBiS0dwHV*IThDE)q(z$xCuALQ6Wvkl_MMvq4lkr zNab;lor#yeLo1Ho#dV=kNepuWxE=CYd@$CGH1(9@kJQL>-v{~XdY0Q+mMWa1EC6HQ zAN;lMN%gI>GQ!2YQGz=P`YBmhFj0>Ei0$9<)*qajn6P-3L}A2o&(d*#-H7q_@v8u~ zO$hD@8P0LrUy{-n7~z%nKKjL|V%|aPa$9QAOHH`wWQq|hnF=Bo;sZ!HawiAIbFR5;C~K*< zWw_75S?MUk#~Pj}0uJ5ts*|m*@1yFCA{E?i+r?ryz&P*4Sz1lDl|Mx4bEe;$6Gpko z&ffUPYCCOV{{Vv&YyDU2$pIqpJ} zp99}Vn>|mZw&@)5!p7f9jFLGYZ7JUr5cNr}TYBNO<7cL~rAV;nIX81aI!eaUEW;t>+MyIu87*D=!7Xd%U}-q9O8~U18rNWmKc+T zB@`f*Y!9Q4?>QE4u^Bn@u77+??e^W2;$doeT0rvfkkk5$0t7w7GGu;04ST(H zudNjuPN#0&ERRbiV#prnM5X@#aOhjp?nv$Zq7HC0PJ?RH?yG%GiW#VdbxdgL(nyj; zC!(IIZaK`DAm@*qoh3=D#c37H^UNilVm#U2PEJ{g9@NjK^j^4{{*+Q96}(c&W?|?8 zU<03Wc%*Y}?>d@#xaOj`(#ttKrH190iF1%bN`wL1-y^<`G+WPb)2OMdvd(D?WV=Pi z;~O9KWrK?-Bm3O7J3h>z+!b$2UDG%(Q9|n+*G;!0(n^^;OEgTjeuUX} zoUxm3=DTfsgt(HPmiGjZMJk`dQmPg7&PVsL`Hc&jZ93_fE47H=<9G8zk@S^n zsye2lmPYm-jHtnwNiE9M`LLy7z8!Jqq+_s!{#ZHQ}ftdnhkDtDo>jmF>Q_)mX-YEY7Xwoy3S_usXc>uhOQnKWbG4u^hZO@2}^?U>B~2luj5 z`c)iBIB_H^#m8?fhxO3}pH@^k+q*d0Mi1qh5ZZp4SaFf=t&#kzrPofb^#gMcLepxB zgVa)0=3rlrGn6hyPvyfp99L6ZX<`sucXc!pKX#>$F8%xDsOACl+kiR+SiT^-e}1+q zS64j@T=2~-MreWa#I-0d-yZnU-)Ud=U0Ovon*RWAEh>T{rD)+|tTG8%0FaUoe4Poq zmf};HiQwQ2QENycw^Ace0UiD7QYbDIF|9qWnyRWlQC;e1FHI9E9@*j?W7q&k-&2q+ z9GY0mw{LDu$o3xD8rpS=SxZc^JYZzGE!Yo#e>%b|C$9n;3w)Bq0L+ob zN+}-AAzmZ%&NT#{*dLus?apd8t{SZ%9PVO zE<;LX0QUAED?ji$w_3I)3uYlNAtHiI5mdWs{jdgsjBpBpgCCg(NjFY^X3_jcP&C*yaPA7$Jk-iKqew=365ch`8@Eub z6g)x+PT~YoKe~_158_U( zmp-ajM2{scq2h>xim9-2JRC7C{u&xwdXI3p@bzSNj|VFoXFq&4O8)>YQ#x+H)Vf{` zo}qCEKfxg%-%l5MK8Jok%5346KiWZ`)`J~c=q}vYn`-NOwC)C-=phn*&X^>!zE~y% zkd@<%`>vGhcT^{#kpQT;Q#5~4^ImEQ`(U^DY0cl4`75@)#*l|mG)f!PD(t|x`vHwE zb`7UPdE9pDDN%hYnuwy4myRyLHh#kzc(wTX);a`c-u6hZ;@C-9;tY0y$jHGttSvqS z^jA}8_m|!rw$eb(aSLP+7k6gQKGkyDo13ZI%1Q|+p`@y_%P0BWWnBWv60aZ&;rMbR zzv1tzt?IX@cB{#vnuZ6c!eXL3a1lu7xem{Kzw+B-M|h;$H22$Zs?2afN{%Ef z?b$#Ph6DKa172_2cWqR_>2s|JRI_H1FIr?_p6KqlNBr<{_th7z^(L>^+T3?i^xRq{ zr-T|OwMMoqgq%4)#!t8vL0a@Z-P=99R{kBNQaO9M!4d$YmHYlwxo*9caipL!$X1ex z`ArotP>xKBFwRv8Q}zV;^Ql^GhqP)ojgZrB`&1W-cs)s;TJ(lwcVhnlR!DA1oM%Su z#l5y=ZqKAvw^hjeQks^UM_DJU905t>kN_0pyoCNAI!LZN0Xl_qr1aROx>+U$XnWvC zo?XwsYz*mhOP>D#Q;Gh1;!9X9rfgg&54}_nG8?$XA>7;P_7`lkUHIB?T&(C$`1a@Z zson8)fS-9+XiuHuFKeOd8Q7<29S|C&PV}tkCzMfz2cB>p4inl1RQf2tAOR&H! zbAg=;H-}9r?RUF<6|$b9CWyrGncO535OKksLX~nnHgI%Uq1YEIg@4Q2zWL z+BV|_zSXuqATM1)s;ahBZHr}GG{sCaSJMgI6cPg?4m<{ZvPN|aAE!)2wT0S7z={M; zPa}IIQLlDCVXIYs(4pG3R|ULOQc+iW3q0G|V+8x^$+D!P=>F@9 zvP&~uw)Msc+xEItiKm$X1W6Au^tyKrneUwlne>S5S+wXKQ^Va91-6L@#zMQCbM&k( z8pBn1&iSFXjRNhE5y&_`c0RN}uiIOZ=*8CaZoX~$SY!2S%m07lYNzYt@0J&14D&YX?0dFe*`waFIW zo*SHU!pl=lJxW733@}zodDIpMI5^1HEjJC~)6*`t-RO4Zv*#^sUeF@U(sQVYkgXCp zJ=2*goZ7u0~rT+j{Eyby^lEVJL31d}nBPlo`w_~4UPJglN^!OsUh6`(z5y+9I z?4p7{5huAG^v2o}*Hf^rHoM&*FiSLbG~TqY7I1#DOrR8WW$wQI+P_+^yCU_sWwqQ5 zx@c|6WQr!4V`v=*V7MTzd=c9^(A`@O)444F0JACW64TFc$bzOx5@n}uL6l&&N|W^G z&O7LBZjQfkT6T`%krt}wEE7{pGCXp~-!CgEGpw;UKEx>GPmL@+y{4~iE!WLW0T%@9 zM+6}&-#NesZVgxV_LmX2jAT|tMu^0Vxd>z3vN`WeMFkx$;o7x!>uiEJW`~N?w7lv0 z{{UpG{ag-y`2=>*dwW-IZMA5cIVg+GNjk?;B1uA-M4=3z#&9HLaC76_XqRicQ&C&1 zt#tMpnSaUw9X(wwG%!IF5-M`_aL0%Z$Co840m#+vv!<8bi?Dun`BfD-o#TkYv?5s@ zL~qIuMkiiu%Y&Z8@%w59i(_?aB)C*-i#41!(wQgRmR$b;Iy(9l&Y@=niyIj2)x>C;REiX83bkiO_p?5MO!0ZPX!6dJdk)zFJTWy=2L(;to zs8x;TfvQ#JFvvYVCL*L4kS{Me`|5{11r4^x6=jB^wxY6@S-D$fK@S+60!Hzn{{Ti) zlM|n)<0R?|O9t$=-smf8g-og=NmRO2Nf0sj?9pcj-_K^wh~C=1vvm9)4lw&5!7rSG zLl314FkD%>q*hWFI6LEDewi2)#93swRaxSKo=jEJ%+b_BWGzmxkhuCzSQg5T$0Us7 zTbJ#n7Us1}3g$|<+F0n!Y|zv}6QLes%f`iA;NakR^Q!Hp*-v!1Lv%7*sO{A-=0|s# zB#fMc9Bf+|A9q&PTgLwY*5IqwRIBQ zk~+Fo^&}A(;|!&dPa=M%azkW{>4fQhfUPCkstW2V>UkOx%}pa0j~s{ZW06tN9QHWD z`{+5;{n2sjHLq|~&q*&Edo9pWIu)pmBjW?XA@7`$k^+0E$ktznjmLgV_12(HTb(K- zRE;SReQkoJNyi*^KbEZ?v|F40mT^4cq_-|SpamH#fIWMA)=jKIE!-dmc$wXIlZ+la zd(b6WW|9s(spG&$h~P7K!C*(_s!sTh#bKzRv8+TJp564+^`4HlZTPhG@WmA!K+1;1rfQiX3cQSDl_|k+2*+Ya zZ0KdUHsp7@)Q0H{MoLZsBvvY{(>o-J7=LCrL60Ekwwp8^crJ^ke8ZNFEf9bYm~g9~ zV?yrr-vU=zn6wGFs9qa6033Sup?!U=rMXjPs+?R(K_H2+(n$+|gs}h>3{Pbzznp25 zv?kl#L2bK+AShypkC<$Z0#F?CIR^o;oPRAvQuO`_s144B(3Mw_RH2D!IWNf^m+*rS{)RXzJ>xxKJ7zN;Wd)qgPNG!GUcS>h;EILIGBCph-eI+n+@qP5f0 zJ-gJYnw_SmtDsQ}qrA!CiDYb}5>>xW+M-FeDrq@eYb$A^wXH-e1gPdl5_TNp;uwN` z$Bbh-P>)x;xwYGeG8AVR&Y~@sn(E^5FoINp8bvL^*+KkABsLcVxH#@Lxj|EI zq}-QF)dW)1&hZ!`9)w|}o4kIi_dEv>a@o#%>IS;Cq@cJ}y)a7Z$f9UvCy5c4=1ULl zm+}ewcJr;wjUgbhafDSQ0kxQ9@%hjT{5*lyVjBfOAA}RlTdVh7ed3~)=WtmiRV75R zlNT>f0fHZC21m9v9eBO8^)Cx!lcTJyAj1=!uhcRL><`=9LwdMtXy%z6@f<3Q5=P-6 z^$1_W-N`rywyiYVhB>ThZ9&AlJhRE4soWf041i76^)|{^*`e7e)_Mj>#W;7 zEjRmJ64CBW((<(}(dvPCqj_F8h#n(@7AwV%9z=G@7}YCcb>`P$w=UPDpsJ|47=0#? zs7M#o`b35K5^>~=1E@Z*byA0>^j7P16pbxa1-{n=F~<{3@v~EzWb{f9ROh*GV1D{D z&{kUF-s@L4_Tna(#FmCNRV6)GW8S+9p!BPad#0?TxQs%tXc9L7CNQLK2hh}ox1yV- zvI-iD-9;sy$4fkQDOp%?En2WVrS#a0D<8mEjE?%4+4Z|ZzOLb7+BH`Siu$_6RFbYU z=mN3HMy^5y`bRD#5AJtoHXOL^`dFkoq!VPY^s zA;HhwinFxehCMOT7V+K1GfAijz&o3B68sL{m^9&U{n1A^SuXo>f}lnILv1yRkzNAO ze9O|wD!j6W0z5LP3PxD?BN|vXM^MF9&Avpl%GXNG&m{y?#@&{pvKW`LMx;89+G%mR18JzL&0w^&W?B@A~L2 z(8Et|xK>ivK#Ke#Y3P8CNR_4Mz`7!^X6=whd+DC$XrAijpsVc|LS3-sq^h?u0>7;DWmms>a1HJ|h zG!JP?dbKq$$s$D^IJUTAeMpexAG7`(FeHrU8o|}hpf6H)8q`rLt+I*~rnklkz>OW8 zxzBT!W8C{=RM@1ikk3X?s?$cEoMiqSDRZC9`;WQRf2# zH&Ca#g`l&A}y|fp}vI1bj%q$O8bMbKGhlR8I@tM=32S@KiHn0g8+t(x7}r z)|aTY7%vp<4GJrPz${pkjQbNAY(ng^;=vOHw6_{wq@Dzk4{1S>N9Wd3!SUYf40!h%wc06Y9@k4lRZkn&QYL4tR$MYlg*ZQuJw6~P z^R3g|+Qx=h$jLZhr=C4XG|y?LeBH7p{9$~k!y|X5G1$<8`j`IzP6nuVo+ot_;aG)7 zW?|{5Cjp6Uk?u})2_w#uLazP9EYdb}pRIr(`+>8q+*eGIFHgTt<;8 zPD3ZRAHUyF$7GvCvrk0x2TF{omOorPD$UI!emt_IfWd&qLCy}O+v>KGMUBcN3JDk> zW4EnOZkM{2Hg!@!z+;^7268A@UuwA0uxaTF6jbKUa7U@#2qVZK=UCFgQ%OS|!f4bZ zPSJ(~A&RIadwZ`SMu^uMo_A`rx>LpT5ys4f@@UR^G9fWAQT7B6w!PEOXuDV*nzpdg zOY#RWD6C7L+ozzW-Ua7hQT&jN;O zUND1*T%qJ!BbY6WH-8{_)V&o|Y#3^J-Xp__DsX)F2fyX7HStEh!}BRAhnVcF3C|=9ef6*0xYs)NZp9C^k+Elg4TjX1GMy4O3j6`b5};P$&m`mL&W375b%P zrNwE#%recK1;8Ilh_`i5bW>1C9qVm}nmFVURKm~dGlBH9jLg{l{+ww{>OJXtiPft; z`sG7$wArojMM*i5hNhs%!QNJA+6dS&B20HZ&%T}-W`w#*(1A2<$~GU37!N9ak9}oT zqXd$ix#TiR?BIfa%ymCQ*X7f0O#3q~-Jq*rfOz!=vA@ynZy_+qsL?S5s|^p$OpXM>3bM#)2--6f!>cnUCsnOl*F)|d?rP@2I;Dbu-X7IGp&w^a0 z1d;?&c(IIf=a2697}buJp>7mV)ziox2?kZwh#2_8p9lygez z9ZnhcT?n4n92FRFPpv>nBGx0vQw(xOdvTI5>co5Dv)fe*rpnouGT%93x48O1BApex zf3gON^HEmAg)fHCvB(-Y2aw#3!b7j+%fuU#p8ouEb>Iv31YeR)&MEd`q`-vGo}es)ON6 zCyY7tB!kbbAnKYoK;FwNQfUB$+qt3!JQI_~(kq|Weu35Joh@}KK%jAQ%i{ywYJ+v? z?eg55ovCr058o)y=ieQ*{Q=lIWwLG5$x~&bx5$I=)kDT-{t~w%{dKQ=>D7kmky&b_ zs%GRrdjb|D`;QsN@jA1tI`iTkoN6xSvbp}(?uwj!!T#z?y7+z2_fivXFD=G6#JL~% zfv@L|&9H8;T_LGej!0pCY|+TFV~>CA6RwQetNk6XLWJP0ELlII4Kx?;g`Smemf=^o z>7wP8K9c%p#(aa^{+fWV_-DK&9I#q0(K^OBEH#icMR@on(6&eC#A_W#t91=-^4@u^ zL~jZ>8%{yZ6SnDXFG|wowYRyFK`e^TybO$cVyM>o_$jRPv8#O|CBP>>Mt|S06qcLb z?YQuu3?qaOQS-zD-1lG!AHzkxvGCJ%dUzwPxzf`FMN=I-Pa`s@;xO_A;y%ZT8f5lQ zN_PIrrl?vdq?M&0v6Y052Mnqh zE`QSdQj2W(c7~zksj8%;6U+`>IjH)xp5u;u`;A;}pADNr1kda!8gr6mRb}p1)9r#z zG1xDFJ+$3^#)OoXq9zQZDvHPHIQy=@3scf7yk#PU47*6miJw1HV>$%}i)$Dqi#A3N zG~Yh6a_0(h&!r=~gQWF)8r5`~)h!hyGSd1L9=x8Cl_19$EsIo(?f8ROrKzd4mL+SbYNGW^u_Uai8!EXT08-ieX;$&& zhEQ$o+`tIR?g5D(as?fX&d_Bjd7-GuuzEHF44eyTdH8^K@C7ltVZJ zu}4N&%8-4|zNzWwMS8I$^@z~X+~w^&(7B36VmwNF2mKrz>NU2pVrF5Mjlnrm0ChgZ z9`&Kkz)&1<>+D5y{{VLUFYQ{UIHUO~h=1O|%@E`}jHBfT+a0tWs_2JUHe`eRoW9gN zSS*yyA&iwB$>PPM#yp(stTlZd-kWNNjjpDO<4lW%iagOv!~yjY#z-W8{aSvy58Udd zw$zw!6fb9ouxV_l5{cNc0QWTQmJ;k z(nC>AIyA5kN?@fvkc|jZaz8JBZEjs^%Hwi;s^Nwo!^!9DPZcRG83{YNw= z+r35FsZMF^+n()8{;YDvG*cmk8FP+GN&q|IvPOQ|DO3DaZo5X{n$2~d)pIoFIK_Nt z&~nGR_JcljgMW@?cYW7 z6x+1N8UW2KS2dCqU-jXUm;w9&*8?kerRJKTt@s5G;JaR-SN+UJJ9=!*p?}Y zEE!Opq+s^;IHR{t?@MUvT@An$lZ9ndp>xGpv~Coiw{xa~>(uMC{-ZTQwtw#14u!-Tqv#-f`BQgF3riI6RO5C3lt#aetz0NZ7!owTjK`hwWzL2rxM9cGs7Tk zekaFeJHVAD9$LUD>5c5!w51vaforr3&b3p zXF6!Bx16-{UZSm|h6);rY|u|tN&!cWN-QywaGCmWFn;>3`kPv|g7y|uxyl{B*%bNH z+Wq#GrA-C0uZZ#%c43?ipbQFLtiJ|!x+~q6c-lAJB=zewb#YTkOTq$?FVq=>xmE|Z z3i<8ZT6^Zc3NM)#i=9v_G_=ncfPk|1Qn)}cJ9o+c8fkVl_Q`Fw+ij-P5v`=8Sn6si z<%yl8DqR3Uh9r}Q&VBo7K5N#M92rJ>aKYq@sB;U za@VXcI+MbJ>UBRa0$ajVa*>Y10A%;1KBE^OBdEv-@g);T#fJr$a&Rh%TX@=ZbhQ-p z*VKxgVR+`LlL{6V99SWk0pCB_$<#GZOgA;5=yx{QuPJY-ri!9EsMvZXB~VW_lj;3I z8WPlB?X?vA4JB1YD+3#qgs5d8!JsqK|(itBNk(Rh(! zSZNEyvBsZ^>4=Oo9FzI#BiZUg<|q*%{h0AEcuah5VT^_C%^d##6Li~q<&rH$;AkKHR;(2bS2XQ4WR(od^8x#bIgs7K@Ntc1vF!e{?OGY( zb2VBt(n$1e6+6OkIH?}7!XL3*U}%*a?&?`RIPMqXIGlP_l_wuz*}(1g8j+Hlcu)JO zuD8O3llIdbFl*6i@mozA%>rj=FoVaob6c$9>8P~ju({NY$%wErIt|As zIOjjDY4pa`x~ZN?X)CHIDyit?l4vA};zo(wk(z+qk7is29@!^U?a5zc*teLfZr96o zRO(}?NL!5aAdKWI2mv8L7$>%``>w#0Hu^fYkv(|nB41i(GLY!*fPZU0N{-rEDeYT3 zb#KkbO(6EgRKK9BUg@F=-i9iUWo0i~ZA`M}t9mrMbGjXO7ok-mylZjyUcz zam^OD>CT(#3$vzL5H}!h4$uh6EuV8%&7biDxoSG$S5I43D&sR6OMEoc%jpP)a~TbW z10GIJ2+prtbEP})_RJR@vAdzAmN){k+zF@k8JUkHFornKVx)U$D=jBWHm_E8wM7m7 zD%!7>crKH}5ftK~Au%NA`N5IM`jiqg@2A713^%^hq`3(riiywpoj|2Pq{T2m(*Rig zUrUwZ0RZ7p65t2K(=SR+XUunn!Wl>=)5_of&+Ha#-!mJa}xWLW}`z=42q zjy|XBQr#ilo3p2sj~7xaC@(NiJkiuwEi6U|Vtgv2IwWnw0FvN#&wkoz`mwz$2TW}B z`)xjKwM;E;Xjvw~P|1a9TZa`wa>U>c`tfDycFMZ#l9FyHC9kfJg&_4J`Ee>YGQyn) zA{Y;=>L3jZc5cvJpL@UT3%quysVXW>T`iube^Q#RDZvj>M9xn^>Sy-`DOg&g>XSb75 zu~Z=(OqCF#s6}Eq@g+byUa#F)>h9y5Q_-oUXr(+QV=AjeKqD#1Ky^Kd#u#XmTGtJ^ zSyyYNuX;Famx`(Fu7Ig=E+PpVMgTyu#G@V#Pv2F#Y3XWifEgt`U7Zn*BrlQ+0qi^X zKKdk=Hr6*2PaU*UK3J>mC9vN4@0?Xvy5C2*cbjyQAY@PhF5LD5oYd)usCP?N-HzkA zDwK%Cbqh-W04!MNdW)=XYHbPG(u?Qwzw2>M!rJC7Yf4%mKgWe!&@x2t-x!AJgXdv##&h-D6!2MDngu+ z6qW7d1KT>X+G{qwuIWzJhFGXgJIyRozpWpqQW_#SsAp2HxITM;Mu+Nm{{TC0aLpS$ zj|dGY7zgjzXFp1=t@UfLjpN9N!*$Aq$KvC61M6EAR+=094@p-^{&2}8FwQVT88W#9 z09Vruk~5z9_tdQ?O?Ks)#c!pSdTC8OQZ(kOLag#JGA}PofH->}ZGKh5cC=H{-B7Tm zg`3up(lWL()8B42lg}A=mUtbb04PLPVfcW^?t2lBI#8P9 zQi32MyJ2e{41rE^!^?r5-Sb1{)s-&|ys5dSa7OMF3}mk>a=0EE0)bSBUvnDgh32ft69%pVvh@_UNb; zpCFL(G5U=fL7>~Wg(QwJaT151_nqu?}4dS z7x(wFG?xmce-;_CKnH>{F_A%U?`>A$(g_`kpA4{HUAQAZdfqWpTq)+Bss3G_B@pnC zW;tKz^*FC?*vD^SjB8f?LnX$Zg;Uu*5(vBf-)ucpz>>Ijl03&{psj};tO9mkzSRMk|pROO>e zTBn+xDV5)maHL3}{h5gRvE+>FX74M|OoHT1Q~dX)suU~96J@yx4}Ls*W7rX`&_zA8 z;k;&cIW3ZT$7Ah*ipge@OJ;xo3Y5!Zk1yXeFBH?qM)HV@O0oo!Tq`mZCj$+feZd|4 zGAX(ibCz+;Yco@(vV>r@Y4F|C*@ z#WJ&Gv2G3A6(HmT+atEJZ&@Oi=*FqNYm~K>u@>SKBr$#f&n7_n6mlg$4}X0P`g4Dh zy7^T+QOhI|$jcdZ=41Dj@h^EXl_HO7g?Z!-vl+*iYOeGS?69(V=Sb4 zs!>Z100XESrLwAv)3w{-k>r(}Mx!K4P|P{I41jpCDnCs!HZ6^@sy79KE#4{;(`4GT zm31l|qAxvDOC&28Q}g69iCQis1QQ&ErIxQ2W@2A`)ZzQc8Uoe zRZ}ahvOrC0Wj)O)q-RD`G?dat$$$%-a0Cy2&7S`N zZ9)FadMRg)pn#LI#SD%8i5g5`z+gVy_N!erC4I)<1z)7HdQ*BPcWjWX0|o7a;2!74w{1zoI=xh| zy)Xht{mJj19mWAT?fU(-`L?dC&s$6AqQO^B##m6CEXu*7UsQI&*gP~3#O8DcI z{SH9ysmdC|NgTBaR41pzjV&q0F#iBcAFJ??Phtjr^;Y#Nr}e4UAh}q$%Ez*(<)8V? zGy3cHnh06UXr28>j7y&kqmc(5GmgW__S7b|QaBud2^h%6JJ9&zmM7kXvjLNjYLO-5*fxHpWjvX??7 zimC|N+m%~$XyoO9>&uoA2XzBE^V>Mol=asuy_fZyG@)jfrC{SCarnLX>ZD z=R&82W|3J@gDCSeX8@1x{*>2ct50cfacm?79D@)+&miP_)mv~>s@-YTnI(!kdRZoq zISl0js;grQjCWsuG~;Hv_8D*^ln(Q9esxr>4Vk%nW80zbZ?T)@yW$r_l5IRp&wXwma+ zEN21J`_g4bGCLEI{{YKV`I;EPl^-V(Wk4ezf4((CmcbOUgjgn(fb#ObJ9y7==f<+p z(0r%U@<@(5dWSg~_iTbc$4-AG5%eVbSLrC8T>4eY8|^EV430(#z{2A`27cO+hj52( zF;b~;3BxvfkG2TaPM+0roazC@2d*>s@G3Q$n z+ACa#rnpr^K}-QQQ~-GpQNwxgLH0ehW1_5jvRUcOPxP|5BxjCs$c`kA{l|~jQlBF? zqzQ>%1eHbd1HLnWpebDAu|IuDi2!ko<28$%4#PjKXA(1v#~T)7oMb5cy!aa4i7P~T zZXxmY1p2UZ_wB9wbZI?0&CGBL3osy$>)#*4Q?Nr7R6*dL(B^VFa0`Q|@b$Z$L;7(erfIXnV7t^Z3Nu6tFb^d{ zIdG%9x?}4lBP5N1> zV>IOg9CMgN)d7B?lqiH@v7Y3BJAL#ex^B9)yGLrHYSlF@iJ_WesyhNDjihM`E>Ca? z7|;z;=F-wXz}{j8N4ewHzLNIhATn^Ifs@C2sO~Cj7T=PNqTxp*5SZnVz@cPzAS#Ap zr?>&U54hC|!@2ELl(M)E(3-O{cKU>Q0dk|?9@@3;n`O@JcBqAArjyZ$BdL*Dos`b% z1WM8Y^%0Yt;PKFySnTO|lGjsJRcV?f;S|+yNbrUOm>#0J<$>7pAD(@*v!=;$^K*qo z;qnf7JY%2Iu(pxf;^kdIjhRZgJd=zZ{ix|la*B#kS!}76DvzWwfJwi?RL?Z9{VdJ_^tpyi^0&l`Z`HPDWIZx=9X9>FjYKKyP@K}stH!fJ(PV%I%r)>!Icm*Ze?OI$nxVO`PP#? zyE=j94Z8(@(eL@wZD#An&8(zozH@L*c)sxx8r|uGIHf+&#Huf{aBd2{dkF^{~nt3d%P_KQLa zikac2LHOPMIK%!$m=Ecp*5KiE{)qD#@6wMqe zJG)BK%u9D9F&IJi0~pus6@Zeh6?~55{Yxu)`6Jsd3;zIJN4)DL8CxhpKJD8y#c!cA z^E8+q!kLQy0EsKCqm8c7^7Od;KyseWR{HGMlPQh@_FZ&1q|+{@=Bk8(ecoe4J=N%p0}wp!)2 zNl91$=T$<@Nip^xTzC!SWE}pQv?aCeD$Ph9B1dNKM{md;`jLruJwo!WtBv8~!B>a` z0h|D=a54I8DDI_J$S#kLNHslSTzVDuG`HRQZ+y2blG9fF!hzkVPnW2`_7l?u4gUZw z8$n9#!Mk>yYuC$Qu1a?pTZB!LICf&pfmZ_^$tX|TPlaWL>f#EkGO-w7%6_kZJ~8=w z>M5uVo^ayQ&rUgojo9Ebjy##rH*ELDwLut2{` z91uy*+xTh@@6#QJxxIC+v{D&3=1HO^oz4d$$A$}I>_O1<^lNTdKzL{+zR`ex%_{LD z#C(AdCyq7$0FtVIJ!W9jcW;Vm<6L9HAU=M_iiB+(kO))t?MDr}eE4|XpEUH8b-Qxv zoTZpjw2??i`b!3<4!!}w`)g7@&Tvv(CzQ(Nn&xFpglTrPs5XiIStJE}sD9soHx zP(aZOZ1iRTo&P1>#|_3F$bqPrn@7eSJ-R`AA_zwqoCv&qD#%z9_?3arjcwFRahkR(jLSz^H8(e< zdYOKRLm`Z+lH7uTPZh|)@v1$K;nScuDw~hLZ03hlv@}0i(DHiPtvA~2=$uUvx>o2Bqe!;&QGC7TdDu(AHo<(6T)DEtX z!m^M_8Q}3i=>8x2le%tELrMh_#PY>0dFECbBIN2=Mhozh9h?FOzBLt7(Js3frJwd~ zE%{)YX!#dLm68G3)r&_V2ibF<%S?5LsQY_(Lnx=Gx;GHW;y7BW954We^h-B!_gz}) zZ`O+(6GuxuDn_IvSjrna}KIp(z0aU`$kh6RctR$`z4nJ3>wJ4WqJp#eiu@vXAk zQ5=l1Mnon~EDHyaWVQ!zau4aP>dutew{GxDT}`f8ZFd;vT9qS{zX<+dEAheR3gvhX zDtqWOdV<{$?+`@B3XXX9=C)4>ie*)kc^JVU59vVFJ-t_Jn%6WFq`aZ1hI-TzNbSU_S7VUv#PS`pp(n$C zOszd9zitXjS~;MOwcwg49dqbM3_N%@5?BD)BN;vNPIPHvN<30tV!o`_>WL^|Sj0qB zG-OEfeMbd93gBnHm-<2_)3ua_SU_ONBt}+N7(bZ)b*ovBNo>y>WED6fxy!Y8DYnPx zMGZ`qQe~xOb|>|~_5zul-%Gl{Q_b_M2Knon4j1Xzqv)X66O;24_GzCm6&E%&mCRKkMmE?2V2fjYq zveNBoovIb-sh(3K6D$(EXUMfX(Kb8eO%heo z%O9rfsl@$3WGphJfjy3UYs;-C!nin%La4wvz{h_|tyf*~Y?09RBMv)xI7%Gk^d2U72{B^{xsRLiX zHyuqn=9-$YKwCK=AoPJb`|;Ohdab-EDQISjo>2J7l!KHZz#%i-7H@Cku14NArsRs@ z6*r?5Qtm3Ws*0{6$2pLxjDi;gGxr~T4!1DL;y@JCQ1 zRYhQUVlqw$_Qy4oY}pNcir;NzSsu1Ys$zE_a9AN`;sFGZTljX@VLE9ge@D7|M`?-} zZ#H5i6UNG^^||gOP%^Q|2NiSmDeiJKi0sX}wOv}Pv|H_PR7YsEr5sYoz()kIm1$~U zkx(O%!wlyqmbx)_t=|^?sTCayQM^?2v(wa4R?UOoJ>^vzDnmExU0iMme%Gy!v)A(0&qYhkIdKR+uYk?j_A*3nrmeo(xj48)nrK= z*bnKnk^lmOj0M3Uj^t|1){dadSJAmI^cLqg`$cJ`q^;uc7|lvzM_xQwqc5=fNg$7H z1uFNo2F|Qn4yJ9!prrtM$^4WK?W=ST;P5JTgbl zS2tFkBuN=rWK}XB#g@Ur9x{9AC804&hFthlNEZX}06w|&_N{$StJ-MVYsI=h~JEI@+7Ok@C7wDMqoR^HY9Wr=XHQ#@R&i3fBy$9g zSUuCWtv8$B&C*#@ipvafObRtH5^{pBNRmW$0LH;^e0ds;s$4C_#9kRu8l;{iYW%A) zAzO@$99J~nYm;8j^FfDJf+)wetzz7@8>IvQEjf_W0An#ssm)=-eh^u( z0XZ7bs=wIWP|qvZLnV6ps~%EFnn>^%8~{}E2R?QC2J5s%YpWAPB(YrntAwfvV;qAV zmn-zhj^L;r!w82VIThev47o<2`~R+mymEJ3b> zi6LhQG06mD8TSVqR8FJS2CogYFiDXTekNbzJuoJO)|yJ?ibyyEPWwTLoPnN4(G`lwZ&aWd0I+KWmIc)0%)LFfC|V+kpOo*atI&>*Q@^D zhFfK2$_Of?kC)5J4M(ZP-I8JH00T?M83(ys_tid+W!<2sTI)@|uAqlu=_45=iHZjV zmCAt1-I(}2v}{9fbc-O6hg{$sZ7h8beJORUH49mSq+Tp#GTTt(sXvGxek&!`L>19I z!dILNl0Esc_gXMT`>F@x%y6j2tM9*v0Y8N zBaWWoav-&-7K4em9sO)Ys3BLdONcu4bSkyZZGYF8gY{?C5? zbDesmsv#Q+Ai=|KT>UZaTO!k>f>{KMBCC;;f(|=!PrX;@>^1jmkIUU^rb8wwBS$>t z3ml)=T(6OmIbh?)b?>NQV!u+xs=njeYq%qdN<$h`nv#`NpI6g6xI$wopWVI*1ojy7 zt*NOgzK}2I61~~idzQjo2C%Ka+F2;Efr#sWQnDg zc5#%BAPxaOOB?~)$;O$RO~%R93tg9U(#-)B)D^y@N`Ypcq^o*yx;8n0NJ5K@;AmsK zHavT}I+|%IJ$gwVN-DV8BCd{{ip&Vd9xd5h!65q`P;47&>C+lllvSGQ3i$;RQ_;v| zV=Rrs=1Emo4oi39xEcIfd$yL#QPPydCe1}$ZeCA_zQ^h+>*+3{({4I(G|fyq2$-~C z0WJ=A3}e$h=;zZ;i*DV?yDiC6I;?6q$s+SdfclJNmZB#la9GX(9k~(TPoG)r`(`UD z-fhVA_jqXO>`}=I#)fC$%Oe3OC4B{R>BupR`8m?v)Bdl^wzjo>g{(2jU0Y0oTg+jk z=dZ4JRD3oGXTKRf_|~urb(V>L~3CG_?`DcNS^w&XBzvoPlV=cOii)3miAx=UaQJ z>M5)g^nw`LnrfcHG7U&0IV-`L8<4{=R>pf{wy4$B7rPx*MLo?~=2*)5+_`dI@u(*w z#y>VoRgb7yesEtp3ljl}wH81L&=Ylhld+83UtP_Zs0 zQb001@sad`pa5Tx&)>eZB&1qMrMbN{^);U;ghm($;|zsY)sdGZf3N_~Fxt6n^ETl1 zsgNVogoA=RU{6r$SqgIg(c)M0<)1p%sHitet2Bup85WW?sEM12ki#s$QZ&-0SN8= z@3{j9S8HXCYH6=YEii_q;G>meL}xC++9IGH$Ag?O&un+mUgft!St6?a^VArcp(f;w z62v}%!B7?ea!}mQld6r+Zb-Csbdj}Ol@mwmMy~9w3!&ug8BzF&!EBtLIMBb^>vo$Z zZHEDKjDHsFQ(@2q4#UGGygkafQ(ywaBihp1GO#q)b|t`d;EwACp{&VUn<7bp<@ zUHh=ggYSW>ox^W#`q*f0R|r{5?iryuV0jFfNhObNIOE&LZ8!VAp0=WvDq7orrq3Ir zD!K)911%Ja2vAt$5J#tYU%pyMo0UNYS)J614vSNFqQ# z6Gl#Pk_iXTZAjDAM^PDgJyfem;y}S%OsY7Rc}N)G81^mWIMnsmVeXrQB-J#&g!EN4 zGF#=Sc*0KyK1CQIz+~)3JdF0#yHQqVIZ_EhKCH6I9A#Z+LzBsZWT6rb6t5W2IFBGd9F7bCU&~wcJvz0`0!Z)}q@BwK znmi|fSDrvPBoXwJ+g6G#ss2yf;5C(S$ZF~8QlI4^c3x`3gi<8H0pqX)k~8ixuOK>o z!3l4$$^i_lLK07?&UvHyFGK4(iEXT?t%5hVn0>$DRVoVVxgw`pxe{w^wMpp84r7)= z0486jiZ^T!c;~n4s>GXyn#k=>TMZ>h=H$mvrZTOZcF9xQ1a|GBbxzx^wcNtdR{XqG zurzhH`-G%J>8=Wd;uv!TkV_Co4{cGm4$`KLDCU};I?2&wiOTV)3^F*#OAM|;_EX$< z*58-3j#J}0cyEksV0j+q2i3dch4UqKV#qW)vARYWE|IE#XK|q2MzW)s)T!M(q#;>yW_hv z5uE+Pon@!nVSmyrB;~Qe2qAwyM3bwmYfmC42+w@rwrT*DWll1<6eg6RL)Xfc`sayaP9n0ho9x%V*t6Wea zlanVNU71MYF@kb@5<7O+?=Ce#14^#s00$F+oMZ!@{{WUX_V~M;550S}f#>q9l<-a! zm614wAdt%4zu7s?e@%SNG!nOEaNW3+0G9oJ`rn2pG6Gs8TxFSu)^Xfpk6?9{c35MU zY2sx_k0z5V*?W>l4qtBh16hKY$m8o+v+V?*PW9%Q>7^yA#oFmPtiLQ@F94C?Qd&Zsj!KT;gN$Rj%CXYyMnF?;s3|3-(DP9Ef!} z_Wn8n-2NKxQ`GvkRm~Lh!HL+*Pah^H>UDQ47d~;G+3!wfV2xQbg8saEQs$*{ z?-M%N`^r&yYwu@ac z>+b5`2ljNkao)Y-sFsR(Du!lQ`1X=DSi<@5C(;H-Z7du2r#8)jH9}l#=*=$Yn52>=Qvn0>w=1Wp7atm64AmC75>@Z#}WwS|z<~yDC25 z*gkIKAHoe$3)R}ji?5NZPU{Be-V+a%^Z*L!T{QJ}>S{_Fim7>tJvgMB6H7DwO~5Q| z|Fzt6mXP^3p|1RVpcBlBAU`1~N~l8jzXCk~PjdcUQMHWoVZ1a=67EJn}s& zVn?TTF}r$P)bds!`y3IbRt~o9s!gXwM{(RVi*c-__34E?Bhp8bFv2RJ$jYBtAd%dG zp4y1ol=yJbFabj*ImpNJs|!Z>fu!HXBglr?1YzUxhy|4PJ^fE=W<`97YiW!v>8yE# zBMt?;C;)}yli2(FYCfj3Xzep!T~zATuu?*`bpT_6NWmgmS&w4uN9V+6#+Hijh$}YJ zvPnk`U(Z07nnt5jFQ{UKD$enqMTkU`0TqsMkWXz;`h)QkW}eKub8gba(bd&KC4Ir< zWtyP5Sqq%6()_^WPp|+CYCBv#$7Eu`cLGNM`+e&zL*f>L4YM-O5t$Sp4;#+ooB@x2 zdSI_RlcKj_bE2xPwW~*UNGNLHbXDTf#C?8L=j%}J%-pgv4z;ZtUYhIDrc^|xsjj#! zOrmMcH8P`0K?ur5P$qEL@9Z(80=s!r+^R0ZiiR3WD}-@FR)vlS%7x=0X8?vQ2?c$Q zF@dY4zo^^lq*dD}R+2g-WR98ANge4TEy-!&Zhuf8gkG?##3QPMLSmE6vIdApxMO)lA_>HUhy>aDrtyVE8IqO#?pi;(7_)U>=v z`fvw-!}rxr^L*NSM&V}MH8wtVa#!b-OhxLU!OyC~KxG-mPh`h##Asc%_so_XF{Gxn zQ-_M0NuE^-5!J~GCQ=WmsgIBF0&jj~tLxI0ppxz$aD84yRGkWZtSOEz0vcMvVuq^2Zq{U4ouU zgB{NwIo8h9>4p0FaA=x2T9%@!3PCWLDbXefA1u-F!hzey4~=VYABPRj`<_euce)v3 zGseXM1&|NXchp(qLG9A!PS=2e%w}sf@(X< zRMSX(NU82nG>!qr2i8_)$G!;dsM2Yc(Gbzgm1E^O45!z+{XUg!N33b__(?42l1O~0 z!~$v3iuoEw(#s;eOvr(k1G``VRkA;>wPUQb$ivo$ikAU7Mio~-kT~z9vWuuma;9{- zS}GxtCW(Z!Zf1>)ax8?1=ER+`gY_I}&1KvcJH&|vCH95tnFNVRK542Om-l0-3dhfo z2-Xd6E)Lb*kL>gLnjsCuFEb|fK7*f8+TK_H{g16Ql*j`bl)R{Pwf+dSGgdLP>@ngu{4d_zH&$Ruts&dly?dU23=}p zBP_AE5(xWXoal4@P^?a~y)+WWLBy2&u%6&Z3CIUNNF!Smd*Z&KWNK?<(?b-cALW`E znGP~Oo@(Abl}^5nNab!jp4GbtU?cF=nt5%@fl+RqBtP+jB7U#qhR^4XXw}x;mKdY8 z-6Nt@o7HIQA`?e2!BVcR@Af^&)}(z^po&=`5*XY9B!a3pq>v2%0CuTk<@yZj4(Yvi zJxL955iSNs20PXYiponb6{Wbhk5*x@x#Gce zEVgMqGGYVjE+s7BkM5w!@sXiDcTYAJ=Afjl-PZd1t>!67rl5|QqLtm_Sr4W}jGrX9h;3BR(eIxSDt`yrFf72GK zqOwxg)1s@1s4GP7JO2P-UO4lS?~$f@{{Yj<8^g{ktR}gViKeTN)4)~}$D6A>&a6~% z@sI;|I;GlrO&-BCRhBKyQAI%2anv*(w6z|&a5z#kFkem;##xx0sXle>#+jx}OSEBf zGVOvp_c>B1yoNoDSb_IEPzLAM4ykQ2(AueQHFby;7SmADh~17kVC1L@31UZKjbn%6 zM|xi`3k`n7sHcKi>7Yrf=LdMk_%(19qCJ5nQfg>Q5xN=!+3DqaIPByY}UeBme>T@vf)s{o!-lk;n2CGDQ(8(!|UeT!4IxV4MN` zJ@hW_=EJ463qdZS^VatzmwFao4`>7u3H8lIn^I+H(cMq^2<%OxeMt@C~8HXdp zg3E%Q-r)ArT)jb~L2hI>VG(~8K_q^agzxhEo>lxk$TdvcQ*E!>Q_W$bRI82J8D40n zg(P1?+ntbK_LmF1sGr!lu)=D50y8F7o;zIP&j>WF7wiF`Y(j zQ%smECDIVe83^?ioEI_N?c0*B0aKiU57xG4xC`w!%H9%LDB_9p3xOiEdE~&c`jv(Q zBX_~=;On117JGuSTFXr(m0?=SYHF%@K3#(FXDG4fA$SECBe!n)Y&R9>aPFfWj*+8* ztK|?PAoTg9m{Lg@Bmi^c&$hGQ_MXP0+ZRj4F2xo12-WE$p|71}aTly1>9O<(yO^r@iOI@ejq&$&{S)+jU+Jmp?7y(-HtQ**BWTLJ=AC}6!pSI~6EC2|<2(mr1cD3|MV(U_2e)kLuSn|_p7l(nW4F&P2eJ1!rHyMww`~&fqw{Ww z$D4q1JM&e|r%fHc@UIlH%(2A6QX3_NigA(&9@zW%)_R@a4TMWXWml$Xl2JFLQG|+n z2EaKgef)nNd!X4D+F7M|QQ)UEs~oZ^SM;4g01_}jB^|tdOEkH&RQ%GZ#m}R`2;|JRsF>Xt(4UcHrt`rKjV!kJdsw!9sQdMu>pb9_I zF(ec1f_?P4(_0pT%SAI(Gt)>CSj=Phusoh)Y!&+Fd4lH@y#n)PbI9kHl!JM zlCa1WWqBR3-;VWA+|?4^DQ?gtW*U};N|>|8L|IqC4xvFu&Ijj#t1nLaVOtdh-?tJf zX17+je3W|O`SRAd~FLOm!!TX)=hGM*|Oq_nc$f;GnR zB}9CLl<>sPupb{t@Ywt%v}EZYSEcK{P01#pn%i)tskg~q8gE@{)+ppv^T!~C!i)i& zXF8SJ{Vlk?RYlG^np%prnpK@8M*?=4PauHyZd{I6vBsiyF5ib_+_z0lnt>&%k~&nP zqo;WNK=GLv7gEF2bY>-#cQ_u}UXxqWuk@R{Xd_doC{rE4I6KQ=@9n@Hy@g&-^)8a>aJ^gP`%2G&im1QIm?T*@|byD*|c&OU&(^^Fg(9;@Bq>n1fBMPYGp1`;{ z01O=GSXo`%K{Tk-ZjvDJmBHFrFDwD}2bxXmexVZBT`$cm-oj(>mAu=^jjVBw`0r9X zdu!Tby#S364>`58+(!KtnvU$t9&QFFSWa9&ZRBiR-)o)_g zazc)hDjkem5$H#*f0a?J)Yf|IV^!QIr<@rhbbEM`r1EU#0!USx7*eH}l{vx2uU6fy z73KuIP=tF`NTY&ENsNyuXt~A7h7J!U`bafDjA4ms)=ptmkV#Nb0zI?mI*+VJd*I1D zGMP5N?+AY~<}yg9m#6ao09pkIJA>TdW8WIk-PaADW4+c? zwen6)AeCrhj68wLfg&`3VMCn$FTaghEH&_5_O&%VDooMLS>+srlc%JnG(#$52Z_!= z@8iyZGR&HMa;nH8cSDj0+Ht$r8OAs@sib3hFg^%$jznFjA%=0=oMcvC@)p@tv^6&R zv`QC<5N1^|sCOY_Ws?NqyWsg41HXMnT*zJ2wpc(~QpP#zFE)#7;Mkkk5r z2=OWznGa%ljwJhnH6jSF&A<{q>@HD=AH)drW4|5EYZqEcict-^tb+zs!2pqt+3n3< zZ#Usjx0<$^hACE8a&~W~22dALi3EK_!WD z$W;l+Ckja!_tuu(+%UZzRU!1#)uj>CM65F;r~r zD6AT37G7LgqyS-<_EXsS`|EAJo9WU>sSf$0eaOcrgZcZ{&#DW<33=HgDyry*10a*0 z-qn)ZwznSWPItOl5dsF5jvOmT9BOzXuhoH`z~ea7vste(TG^zhs1e5Th~tKz(P$A{ z=|ZiO8W4TYBj?{l{hL)qbESFOu^y60oNyooB}vcHPH?~sX9vG?qMZd@ro&%RM;vb= zOB_>FR>2SaI>)+sr-apHz7 zBLf)Dn6%qPyOsQVXK3~=7^ol-p5CWE_3ih< z{-k)3Y~+nfvle`jyc}cgOLcSA&lcFah-7Knc|z2ek>ehdiKFMheGGBj3}Aa5OWP>z zujn<(gbUR~GDRdwClr}MW*8C@%)s|JI6blBN60#DKGc?;iLR5@)5#-7l1Wg^0Y%E0 z%K*Ptdx5XFH61id^3p{YqXbOHiCE-~(5Wg<00=q2J;~G^LhbAfmfjgfjfeysXLd** zZh5VT;nmHZw31CP?^G^hDjRcP41@2*1ugV9TB_*2c8)masE_>G8l&?NtHQ<-#dwAK z!vm5&r#;5AQS6PKa;lcTmKYN3>VbIQ`)huZVM`r6c?GAH{dS#!>|E!GkOeFTd=ru2>I}EKjA&$q z%xpkX5suP3^PWh>VWjCxZmK*v7&h(sUtdBEVuI6bl6YzBmBoB6V)T`kMVE@4aS6aF z86fccJMpzi!(ghTLJno7A33 zgQGtd{Bg2_^(g~5@2KCC-VJz4O891)H4=e6JZn)B@dWImJnGs1TB&r7@V#&gnX6?lI@=mHXl;*yr>fV2uhN1;o9#F_zJ-|3P<@x9M z`)hr+qj6-Li;&Fwfgr9A94|OOS{c=LmUqQkNQk)pB_sjJ-~coCrQ7x;veO03)5}{O zeIz_#`G^Ys?jlpviHl{!XOgfO@vB8uUgg|1lpB)Tp0#`o{{TN6Bbu6^FeF^z(Pi!= zQZdUveHlN=t5xoTm^9MEBoasxE(4Pg7b+ba90)njfN*pxxKmBEDyWSl4;88wRGlW| zeQ8|(0AshY#s_}>+F-ZVK5(!IerE)QkYr;R+7BK5DGyTV+4Rd}CxYv4+fS5dX#*gR z{{WxTw<+%#vD1pm2P%>`r#(N@93`8R2g_ zc@T5R@9HS}n~{?FdTVVHvfR=?ot|hglqp21h_r?>+;5je|3xlX{K1Hj<$ef!hqhpDu4TbX25 zW_B_nsR#i(h#1HB(^($dywcFCHNt|bnb>-<#|Vvye=3-9>N|M$AbHdsMV_W;-DZWO zcJz@XCNzp(L$(4rC|k)Pj-vX1)HyG=is+m}6ULX1 z=3JR@=&26a`3p^F?SSrqkjCDgW1o4;Cq3M5pPwr)K?fOD>$`Tm6euKrZIp*zwSGd2*@0> zone~Ux9)XDDQ}c;o&sf-7`|>c3`i|B?XAfcNoF)HFQ`KoQ0#ML<-!P z1ONc19KN3&y@sR>6txWDJw#SkP^}&Tq-OTaw}b@d#2ZW))k zZa^IJ0ZHV4OzN_g8;#Bs4XM<0)Du!WS(&wn4&I6V0^#K(K6+^HuWVdHB8b9ZXo)J z1d}EYlHQnXU<@8WV?gT8r)({y3RN4lbyq3XO)M`gFvAKs$|ExXBU~`&pM3Z2tY_hx z*Lk9(TI;pKdD>9ba~gs z-yr4ByBwDLjc)LgLaiq551_{%od%co{nL382yg}&iDQ%Y#Y0-U%5PA~EuLFs&?^*q z2QX#9A5KRqk%J-6@hYV{=OIn7(Psq@I%G5@cf1GB?{9C%&5BQqNOR0@G5@Sr}J6 zqiGO#3fUe2?~PWkTbK5HGYDwwsw!1ZQl6Se7#_s&;&J{O(;~@+V=94<;m8F0pRGns z1~|M&Yne8&%WS~OHOzg@(w*mZnyIQ#Q+-^cQ4oq5m}G&1asrRb&%VEGJsIB3Vr!k& zrk!YIr)Hw3G0yUz9+NPHaaBG@b^v|Oti3^psr$EfyH(UBHL@0(Dp6d;aEuEDB~D8W zf%Nw|{ItOAioM%os+Z7~YV%U6)iu?$#s#GayjSInq`ateg#-Y5Wb4TRU--r9 zh&-{T3uLwe<37~Ato$^%RGRbVQcpNx08klJ^MG^d>?s3_{`^+WM{%i17DPeyelpqd z9}jQL_Rh2>+t%m`+$q|kMW~n{a26$2OoCWtfj&Px4Ia1cC9a;Vo0Uux&ebYtrHYWn zg-`)ZuhBAt-;l?A_t4YUxo!HGX|0jG)T`=+Ur*CX2}6L&to~SeKWz}Tym?~{4pVRk zVLMRq&Itmli`@?6O`dq7VpR?w1O-1*Dz$T4e9KOKNadB0M;7|<`N78%#~Ib41G?^) z6K)RL((`Z&p(Qt{avCkY$3#^`` zi!^N!P>zxXJjft@E;2wIj-~GN+^A^jX1Gz7j(FANh(xN3k;S+qj0}<-9_)oidmUYN zCC+86b+bcNGs#r2&T8Dq1gM-?q-)$4Rmzir+d4YXZ3`vR25Xh1NmPv-jWqE~DU*rf zFx){PW3rCQJ-zfDEhN+>8%`N=a#Vl`^x~ZK-3nQ>#D*)`OQ_l%m&&~440`d!P-yne z6-~9M>f@)LkF=r|rIZ&^Fpkg6zp3YtJ&rsbPgm?6n|`XrU5cJ?zq?TJa#ad>7ErkF z+sMHhFq&#|u&jXbY?Ua5P!H-K#T4jdPHB*EGCZHc zdz||MPN%PzHoDQrOd?2JDP=0D^fH{DBOU($J#K?dAzoFwXrvv2k1_uMYq+hp(?h4C zLlv^RWRUDh*h$I8YnK)MIo7<`1^g1x^Y>yW2dHciDj!R3P%dOyiN!TLlqbb z1`p?<+32Riu+~)9(_5fPS{E{Ngh(Vz5ZR1|C(qN4{rhSkgCvBd+Pul!Fv7?i-*cR6JvAKE8GE4N1|7Jf7~N`4PdERfX3g_fDSGJ_jOmkfIq z$iNyC)^r-()apNwxlvVH=_06#pi`-n(PvgFRw9eUsROwn5u9sGR<_M>pqV3px0sQ+ zlv59gk-`GDcCQ)ruiGEQcHFwsNkwYL;;V^TKSk)7lbInD1CX);$GQ7=@v6k#4Y>6t z>?=2gOctm`JaWxxp@n?`>Ns!sz9_APIV+L}*yzt`=>3Og88-Ei#l9e_QfRWxP?+ZZ zh;IzUVD<-EF>USlP9#{Wt7Z`>S7_sIa=JES4i%Il{aFXTM}w*IT?+|6$g&Uu!bdrA z{X5XuBe=|lS;ML1akP)8)}ilRG})ak+R)Qk<&vsc<&1hWD3Q;o$B(UrQI0Nn=eKWt z5-4fzQ(NGQ+#bgp#)~kinTbXX$)bt=rHKje^m6a^)n@0iYp*pe9Ua1YrGaGi)>>wz z^w~gTmOPQvmLn$_9tMdQUG=x^uu{QNAqS2nmO{Z=U;rzI;uS#{P*33=bQa;S<+*uF z10lf-Nj?2BLnG4}HJNUKS1%ff$sdFaf)C#`N8EdkdtTZQ!~_%*Q@TvTq?DMPDR5k5 zXV~{Yu7j7Fd!^p#NU#dI>Oa#;)iWw7gcF7lFgXPG?~l3F`)l5hr4MhN1y1C* zywS*BS!Ic;Oil|1B|scoixZ6GkOq8eQ>UFTux(G2tgF6KEHO%xyb2?YW^n$Zhl!oJ z44i?2K{)ZKv0lb**iDc@Dv6PhM{}QQSGv5heL>iTw!R_vca#yjKfg-3ZcHe+(2M;yf!)mJ4(S3FWau-Df%^UWm4qB$_6sPh5F zbKaq%-qg{4&#vJiYDi{^amRxzFak663=rAv`r}(y8vC`<30|6>QAE*%`CMbwjYp{Y zXvq59_rN1K_t1XdStSiK(x_!?kKD2z)Z2m2V>l7 zm3Q3nnuw;BiJehaHd$i>)XZ`>8GTHGynCLj^?h)PRvvNCie^ zB!md4SBU@;20_u?Epsc#WGu*_#}Oos3CUo6`%+AOORP(OYjbpFmhB`A0LT*X01N@- z(}THsfm*cnRrhLIc&RCpIVHD5M9As@kb1}u7Cp%%fseM7{-JMsUs3ON`uYl|N@~Lt zl<7u&3Rd}c2#D-XSxW*qsK+e!z|j&1+cv^lq)j8d4-&kxNU}#fL-0tleMn;@5D(Hp z$F{s}%cZAg?Yo7JUKKIBF^Za4mZ7Rk{_!}fsp9_tQNaVYJ8EW~s5B;dq-%*TB%64Q z3@8kxNdxF<>Q14TUbeVN?;hUerepGemJ5YAAe?ibPfFU_8?L`?ZCm?Sfk$4Zj+T<4 z$Ek#snnoa;lAL27PJ3u>`|9mOahlp5h+E`n-D%{B5hZB{Z%#x|LypB;IX(3wZr+tq z)J(Lo%S|#=zzj7K0^~`|l#l2`k&J!Lah*{&Elr1UR@KW@N|e&m#n$O>6&hDr!w1v;^B)gm;;3X;QeZ)l3UBq1SpU)BS(eF198qyeSIjgU2(Kt zY)}+Fq{2szrNT!XsZQg(a;gE$q576gWc~FIWT#6S8_grMlR-3TJP@`SQ5c6tNALA7 zf)9LWRj!%YBit3WH*(^Vl7c1`buv2^M>$VTl#p5bc2nEI{IpxLTVA5eUtKNI*F{Mz z$?|m7&*`x-k|S@RA5C9A4mA%@@U-`u*ho*938Q@XbCSJ|XbjqI^If4UiGrUaVMr_7 z^Yx*<;?-Myx_$GcJrjL`}bnMQ|3O+>Kp;Yf%ZC{q`B>g zsppw!<9fQ5lZ8C!>+?+`!PCRsAXhhP~Q~?$BvjHflC#Mk zBU~u{%N``F9^Q2wyLKHVfLQ@0GTO~ydRPT*1m3Gr8CqE7SjRKy$xulLmOu=|0Ci8E z`9p2r_R6v(hMGH#IrPepQ}=SIEg=9FKXz?x?+&5XRMg&Xf~9>KC6y?hk1#3aKC$2l z^TdFD+Vx=6{Ci^?7LAY@1_%zsZ3pkqHM#YjHcKm|c*&65{_h!VgXSmD_pANWZr0y_ zX4|e1)KgPQPGqQ*b_jB6Bsn9C2JD@Vdv?@w-EAAj(kC=&9R$rBbn4<(bcPl&A|gi0 zta$hbBatT^v#4t}^>w6slr?Ph2^fZ=nV3o>B||Z8Ss`O5u^q;I>UVF@S}SZ6l~7d* zsqOVC6&x@lg;j}Ji+~T;$S4^gE>FIPyi?nvnKG`90+rq6W68+(JXSE>MRGB0n31uUm^mk{JAmWrHcHY4azahKQ6=%Y-`oU>=V<*_14-~H1#q=43%;sL|!%kzo3}n34YEy4{@)5YF{L{ zo-~+bgMvR2Dx)6kAoD9t0Qh)930>hJ!omOsAQ$AlA^w^5hP>Mn*{#s zucs(D#?z-6eYVo(wP-UCew%R%gHf_7zQ~ zN~XCPX|1Ht(p1AF(mb#9$P{F&Hb4yD*S@r>w%x`p#-P(lQ5{OR`N)%$PPhe?n0ECC zZ{wn^dt2{&W@?wD5WmZ*YDZScm~oHljy@nh4&ZiHd`cSinD5oqaB?J+est23!V=$K3fxeCD9(eHAt3>RY(XOanBa5rg)}wMK0_ zRnF5-=utr&2`uPp9#VZ4%CevZLo%l!++)r&qV0-H%u>k(Le)u0O-<@F;Y*}qVf7wI zxe7cn#yp<-v)e4T_*}80SZYM?#ute}Wh8)c7;KUUf3eXPgLVs?lTcJDM@2fas!tO< zl1GAH0Z8OX?Z>$ubT-1)(^t7Gb19BV50OIdCA;~FJONz|)BP5 zD;C(e+V3cN#IUSKk2xipFy7%I%uQDQCJ?o4q%zlMYP+B%D1#+mH;|@T0enIw8+yxN?@DL>^*3kaE%I$Rh=DoMh@@ zrn-7O{$4To1iw$!jCMJ|$sYdzW9_epP1#K|NplwRBoZhiJ-u5sC7_B=#;DxnXWoZ% zbmM4LymP@p>6m0mqH?Vfu37d?Ppy_%lS7pKITDiIXC!~p!CFPw}J zqsDYvr?0IrOC%AWNFl=_SQJJKVGr)eURUkyQWhAMlx4r$ zRCTjN*Nbg2qiIqqS^YTLrQ~7>LCghSSjpl~k2)MdPtuRubrjSV`=oME)bgp0oh6ze z4{*+6W5IiN0OKCoWv(q1_B2|$NNQF-LNQSqmO|@>3J!exkUSk%?b{=6*(9lwjT(+g z$$8QxDjAV@a^koc9z1?p33Z{(b1@;-L?gV4GnyZJq^;Db_<&)v=ZHvgk4*h)vuNGB zCcYWshS^;sz~E0J!U~e(JUM z1|O%kwpnSnaLo_RLvHGXg$o#6pz*jL?yY~a=9)AYBHndVjh-J0J-{_XsQ7)`ws=}Q zB>1EOgtU@};KiSoJxIWjd;Rh=}(TQ>+&s#VUG_Bw)r*0L#cLga-w& z^?Ama@n0P>#=>=0W*nqtDUYWlkbUw$F5R`|Y0^rUm8UHjSi+!HWJUHTBk+&Ee?D|_ zZk^JkoXR5eupzK`^LqX3T4>r@IB%7Q12`TS$3COlfOMS@w@+=JH>+=6cS9M9B~MF- zVxTcNQ}2yIMbL^^3qeyatpSv(Ldu8JR$Togu1;~2{WN&4sG?cmdZc)abqL{+g2%&& zToRv|?hlt5ZtMvLcep>Lj5!oP&dm{%1}tMW)|TC?+t)`C;5Eh`=5FHW|hV@G+sL=IMsp zz6n|yIE8R@=PIK5z@{9K(T4jE%;Qimx?6ZuM?_tAc3$UYa$KvrbW1caJz_50l*fU!5ay^wRxoMtQDPvc~a<72}z`ITe+%vPbnU zLX2Y_`)DD$EnP&hLrW!+%W`=sWcBKvZ%HL_zz1*}496dUW5;o=>lO9H3ut$Xf%x~i zJbGs}I_FW#Oh5Emfj^a~WZpN$Icywigb~ z?!5RK+~A$0XE`9AJe(oH$e5IR_a%@$PjIVJtE+Qw+gR zBbt%mST0Xx-ei*9Cz*qzhW`%q1NZ> z4&B>M*6V`Q8E1r*byB8BkmJ(@SC?Vru794ccL%vqFhNSs$(OP^hgHv#tj9PfzhT&o zN6QVgRm)h^(X8>O2B`GaWKe#f74e*R{QK%0``5~>6#C?PR(LLit|@KYmg>EYbBgtB znx$=|tfrnvsP!Zfj%gn$1LNxc&H-VOgPj9w`j6Fp*IP`--9;|wmX_SM zsbkxwogn#^lr1|Xsuz?|!ovjQcVnNj<3Sc;X z+s2HN(!EtW)l@@J%#0J|;;D32_n#{AfLZ&1n>7vzZDJI#)f)o z@lPdUN9$sofN>H8<@9BMA#wapG!FTKLgE%&Mt^qf-d)3<-qg3P>2cm#&Lc%Y;GNi9 zI}yf729nE_pU{Sm%6%Fd`Z}lOI!z(SU?M9aEiWc4nK;7d+fAQLwk@*PXDM{Nda+eW z>$I}MiakLoBAz5?Vih;Z`|3AtbbM~QitB|1&Lni23W;6-6_M~i<6IR~$YudM zs|Z`u?1!5L$OGI1^>^>6Pkk-K2=5^9h%VuijE;E6 z)|NU~Mg5+Sd3zjDh9t%6aqWeoG`0#5g09PCq>`n`m8)tc%u<1n(MVj%%rJ5W00+Oe zusjr(mZ+kwyHUl!FgD6ZMg>VK#g<@S>Ie9Z3~bjMrMj-RS&TK5RiC|%ia5P_spn-J zjEWvn={R2f`Q+pcS!l0YimDkUr>3K@(n!2kQ%an{4U8hOKWyQX8s8P-Jcxv483TEF zTz*w$z|sbcC9{CQuvP3p^#ovZSEFXIS?y^xy@JHtpVWDTZzmu@Ws$M&U={URA8X98$syC#y1%eg^NgYTdzh+#99yPVKq_|sUrKGAf)s$?Xyt#3U)RIA! z9=a7%o}Q#aC%|*@m!6k#caskkqosL-8Y$@CpV&KH1fR7lwuijZH#F>M+T02Xl<} z_xl5#Y!+IYfEgu33z1Mt7~PL$Soq|q1mnh_tFD%cLk%gNC9Gdeya_Wa1t&RvCyI~H z$sROC11qvZ%!pN7PzBm7ScT^9P7V1GyxEPi$(vMAdU#Bxxs6O2`^GqgUpvgn~h1#gz8P(mv-?W(8?E z6yn{=lk@;s`;{NhUwDqgwQK{{vaM*AIi4zYJP16!P^!*6j^Oql-MgJtEACsWqN0vU zY8rT`(oR+Wq{Zb^8s%dikOP)*NICsAZ7U>HY)lhW0#pd%C>W?6^UaiZ$KTGY^p&*I zT%@C&UYe+Kk_3@h8Dl-mqhyC5_8=UO%`dhtnC_e1A|~#tp^Wi$Xl?5wum>D}c~O9+aqOo*eGzTFCD~T`R7z?t(Y8`b zk}61WIEMmmKz2UZAC|7ST1n)inm#hQXxTuG%tV$L7*hC&caFgOG6 zS1T6atg=?#sV<_1Dr!j~G@=Ydivy{_@s8{dVtak{Ro;8zipeyW`(gEEo{CF&Ms$i1 zByuY(hH}C%fI0euXeo7yg{@U}7HF#;TE$6(^8E<>2<|w^mf}xif_wgYuUIYpORb}- zTXRwxm#TV-iV9-LWfL_sf;T{GD=-kK1py7jAI8w>&H$v4Zga%nv#O1mabK4 z9+*an89=4g&Ps;xOBEz!d+M!h>Hh1f=Wn5{X)DMJRRj*?Op>1II_ zcJdpbufOoJmm`l+=swj^+&5HS>vLPYY*+?TF_H#29Amy{zf-?nvO0L`t`xG?(^3j{ zfntz6!?*$7ZV1Xd@oru;KbA@E63A>;#?W%z3zURI> z+pYG>!5nJw%RF$*(Fa*MGAp=IpWYP*?Vj2sZB2`~jeWw*zO_YM5rg|SmDLgA;-$G6 z00gftB#(b>eA+@=?vf@gG=vfveAv!7{{YUV+w|{RYOCQ3Sr8(rd1Mp8yFoz$+fuRyLe&R_OluOb3}Zf_BLsa)NXBq=A8y+F zp01{rjyY+jilJtbGSIn!;zQgz$r<9LAEk4ggRLynK+NVmZO9}aJ_sD=pVFaS^lwyY z%49J+-H_fSgAe6%gN}2aeJEpS-W2y5nz~AOB=jPq%t7YKkCI|Zoq-^^B!xK0&IUDk zy;!z<_NYEWt!X8epVoNgXykb3mGX!OEOxJCWw6jzExc1vWtr-$5gC>l zGua!NSM=EDI1EROY6hx`<49?xy~^)SCQ~(JDVk`&9h8>t%Gf`IWPP;++($dCmc`OA z#G;nul^M=Eb3=5^D^k-G$1Gknj0=;rVL9wDe_YnPRl~P-^<5OLKdCTimFe*jNRQOZ z>Pp39X}|-y`d7A~V55ev=S@XDlA1WyDJL?Dss45kO*!*Pi@GrFjHt$Z<3*e9&$M16 zqn7KHr=h5)nl=%SMpDbdC5dvX*;AaIN?mR{XZEcv1kkciEU`&CtVSscIZ&9EB1U8Xlibxo?C7*H1;n|}3J+5J74FV%zA zX0;h5t*ff63?+shD)LCPL^!jLE7Q!O%@*o`NR&?05ON|Nnipd2j z<%tC}u_~ZERn&lg5k5Z%#x))-X71YQ+0aWMAxo=__U^+JLr&=@MGmp4xGc>nbI2`& z!2GFY+uJ%D&8ia>EqwJYBs9^(Q70J-N%g%;u~CHqdmLbXda_x%d1BsCRZ~x8L2O#4 z6QPVSuc%1)XD#%QrMm!ep8901eJHll%^jke>sJi|(Ta+xE1TMHqXUS5C7|e^A@e@YbWyT3O z1aLj+hfV1#Xs)DUf;jv@Sq3oMMn@-}DIeUw4n~`9)I&v3)b!M_DT)+xDN>jQ6>J`E z-O8>&Uce0scMnUqePx*>TUA3tNeoh$s^^X$S(%%ZYxN^WK=0qN81P2A(|fc%d=+Um zX^zTDD!=yC1=UqeONla~()wbb@;oH`gjll#h zwD!B)DNUxjDw@Tbco`~^F_m=n8zj2FAQT?tp7_)){_96UxK=W%@kv6G(bYn{sj30Y ztQlD4MFhUWw7YPh}V z(|#UHe+hpGjS!X~fq~n;ao(ugqMkRWpubx2>%4xO&K#`$0l53Bz7QsomaN? zQpta#sivNJ>11P1a7bfe1YVjBC1aF~5uZ&Vumo%IZp{qcxIG2dO1YE|Cz0 zT}yhWz*Z^`AUk*Qq8fd^uiLwcgQRolZw zB~0=fo^KSaY1M!y)8pW%1a`-RtRtFKxVlD!y9EV<9?l0C{S9RfodQ}cw{i^3m=1r3 zaq}?S>&8YxwztX*I5~RqS zXGUL3va*jzg3P_~$a@`5?p?)e-ImH5V5e$Ydg^qNcBhRNX=O%c5uVGBs1jS>RE@)W zvRmt=OLaTFbu~<}Qq?QDS)oJ-K?IOoHhY1L91j|e0^Cm&ffiU~khv;wKp%(l2il~| zYj0xaXy=M}VO0Q-$i(--$8*nmV7G;2JF?#IEkKHbFtOK|rj0lxp<5-1z~rYb*q?6Q z^$%Usc-qkoeGO!jvoh8!Jc7sReiE5*_)-`!0F#m1OU;Vx)YiAJu2UrPO~g}ApF}DE zs^=#RzzlcspE@?dyG_c#eHWSP5XtF8j2H33P)3|HfXo2kd>?HHlGjkupo%+ba~jCN zl9>dbOyqvGVdy z9OJlBJ;$98?kzxSX=-5oP8fnl4tZ0KJ%w1UyEAXqTxu)m;)*%ssaaTXX#4t^CBrcVn6619 zBx<3!tWQfvJd|=4risx(j&$T%NF0g8e~5O@Nc^>@Zo6AzqIoN4sAdqeQ3#?ADkN1T zk5J(iMls2V2iWMDv}3hH1j2e#BvQYs@x>Ym%9RI$i5MbwIU#a;_BuUgFRrJyX-skN zEEZNd4Yz;@9ExeNy^{6_o56}5!0m7V2OM%eD;=k1?DY~<-uE2wy-^hkw6n9Yh0m&r z=mY*C__9Av+A{38cAU>pw%Q3Pk|}sYFbcU4f1?Pa&qyG2!6Y7rSn;J{MSWA3U>KId01onr=>YaQ#u zY0roFL1!+c%9A;Ye737BvS1gWDfZ>DyaS*e!Nwj{>nVT(r(|?fJ95OLzO~sZ&u)QB^5|Pf>#o z93&WK1D**7xIPFz+IO{z<|M?5fO;a5arDXWSt;>3Bz{%DTXM0}&r3^F#7OcVN01m& zp4lLU?0)_A9~Dee2_%gqG~)^*QQ1_v8Nu<7zM*G{B&G{hA1aPW{39U#@Sf_b%y3RI z-?7&7Q_WLCl<5hLM5UO_p#2#P0QS#s(_0CVkET6^NC7~{din0MM*fuy}U}`SuNl!@ts31oOPGQxDkcqJBIKjZirAHdD zCD)UVYZr330RBR?C}>bFBgZg#!|E`TgEk2vev^PlZ}HZ|_E_aqX(AHL7#~gDSGdU~ zhI^d(1IBfZl9skPWRf(9BFr75^_Dc zP|t58wl$lwBu5Gf_N)|0WCJG^;(BPOu3Bb=;ygiST$uYe6;aC>BiQ}5B}YdzQnJjE zkm^I36au*e1F-s!ZvFdetqm=F*hQLXq72HMT&T};^&ZRyJoxdcxaF1_g1{a~IG1ir zpHR*-k@xO>^{r^&B>GIFbE)V^o@bm0dyV zM^S!%P|EF2(W58{B6@sWD`XMmH@1mW&m@qT=-nfzV2aM_&V*<15D3BV*!yc@2dJEr zQA%Z#xOPxGj@^JcKgUt0(=0Eg5=fbFF_1{(z78u>DFY4%>CIIjwbex$O(drSn2fO` zfKEb#+W>g`A8mTAhN6}VgGEfOP~nV`@?s=)L4tBH4}p`b1MT`KL6)kSsg>M zJ%J=)i!bY~1B*l}Eq!15NgS}`R5vczR`cVqAAfyF3mv!vZUXWfIlv!!@U}qq9+gos z1XydT9DL%L7==-k58Kmxc2a;2_#Qt!PRBqeM_D6TTu#AR)tA%u1q*V)?0f$JO;oOZ zMccN@=Y&?q^GhibdVFRPf$Tuf629Gm)HRcIS5nnS1pAIDqm>vWe=e&m<|Qs%g>nf=H)>Dyx7LNVqu3 z@81XQt*NXZClVzhbCeD&tV;mAK*K9%iTbmTKdz*zZ?r8^kp~U)A4Gprx|s%Yze&i? z9Ax(JJ@qUkJgJh!OO}+h8T8a;gB5Z3RlHzedF`vDR1J=3WRD{fN5M>?ynuUgDhG^fe!41` zsa{l!*o}R!w7uRu`qLwJKVw>3S8&|7EhMs3xJ+>fv1BS1iDbwOPkgt&d}zlFKdBVx z(#S%L9FTc;$JLSFIoI0zQf>bL0sN{wpMZVq1QgLlB=UVsODd39;{|zm81MP(dWy$K zHFp=@`Jyd;9C{eW@SC`c{*{HMpBf#WmO0dSGf7iV45B#fC`F+qaJz znYvi0DCvVnB+ht@xxnq5f#W0ZueJ8Dk~s1BSM;x=ciKG1)7F*C_fT)N+mR_sQ%fB! z38{?B8Fn%@2X-eT8STd(o~Grw&vAy;SXMZyYH8X@rHuzBXoz(DT)ZFg*V_9^(v#!J zJvV=SM`vQq$^3rwMB01C>$okF%~Fslj(S+QB9N>mK+Ic_B%c2Orizr+Q%6%z06$9s z$oB;2m)o~&cGuebMKtziQb{E9-lW7yizMXcuvfa$Q8bZ77?3RFFkBE$$qby}5P+v2r*MBU-(PF(6oC-fLzM^1?NU}W{ovX$u#98V6=T|4M$vAy3w(aF z(?cj&!^&B>;C&^$k=w?u5ycHDiDQjIhAOL$zyrsy_VM2y`uksNew2u?E))*_pIXfo zV}>MByompKN3^|ps^fB5IYTNvHt)(bAT9yb}RJduue`fpBnpL zXv+Wq$Gv>K_xGU|`>3q6(!JuAs#xa}!yJ%u1_@W6{9+O3{b7TTeGm3!RZM%TD1A;* z$}6SrtCVY+gjBXwF+ou4TqK6mvTpF&u|ZIeXq3Uf6XuZKh~OM?tj*+1+tPl^oiWE zmlW)F~6xg4qNK_8~5*9$$jcnZ3EoCzdr1X3O&1&L5FPuubxj=tC00jznv zr1gzxx#ep<3uLr+UbRdHBj z`J|wb1_%*OV$N765O7azeXq4$ENSDh+AOx$AUiAXEH+D*^}|$i{nubFF>pRVcB=RUa7sUY=Q2BvHV(GagQI-=AVKeCzFf ztvAZMZ#W-;eJCu<%`&MZuN-=MQrSaoirHgGo!+r4D_y5rt}+5;B@O@zFb9F-zKc6w zZP{)RQ&Z1L6H|nr_ay<33g-*Jf}njq0LH%8+N-UJI@F+^JXYiL6hEh7g>F=YP)rY! z0RGXc&f&FMs5ZU1qoakt&;3BIyp>O^P84_pu${l8Zrhr2BP=Hu9}m0 zQcDqa6V#2G6Pl%ahT)P9DFb5~TzSr7av|^T)rAY+Nxg(7Fb4cA; z3@@Ta%!){wd=dd8f!cyevTZesLv>kdY3e7MN|#D$eF%h+fC*HL00Z&M4;k@|L3JM2 zLANbxD5>E@ud~%jI(jjvQdFwA;q{S9Unh;_vT3w9p>XV8b9Q;2v?!RQ8Q?TWr>Q zg2f!QrW`EN@?wD0zhnS_HE_REQo(kmwk#3+u@6wVP^^r}A0<+l`blC=d*q#cue3i> zC-#(__KsYAFnF!x57@88QEWTMbzJuy9Wc7o(^C4AkC&!@P9h^Y8D8M$J@e;Qnd%iP zuMHG2N5(2PMOFG$o=0NJ2{lHEdpz7m{ckH#o&lPs+Q0_<@zgM2`rdQjXV{yhksj#+e>op$Nin=j3 zttBZ9&Qjw5#(09+AROR;dyd+NxkTG}r>ufUl4u1#qw0}_{mRHOz$yAq;rnA>YwZKo z5f<7K6ar-jIQrGwu_Cm9B834{u*av;o2xCR)%!UlG;kRU;iPE8J7jXpG44*h)mkm} zdy+3+FHk{4m;(}hGc)mGpJRm>BgVeh+P>ZhMw4hfHNj|!8%HE$(@KD18TwU1!CzN% z+mzB($kRxY$p zGwBwL#FAl5l5$TKxjPTFZdcSANNeg+G&9qY!PpXT-N^IUAAD-N`$|`!w^W$p=T%Ei z(uL%s_xu9|DnSG4?cZN(?GzoBvOk5s^>dA7lA0G;o;J*p{ULBdj@b+d&O2xAs#NHe zF~wHk`m+UTKxPQvPjFW_?hZ5O8v9>sQS3kU?OzTnUd3{&m|V*_;{=tlBIMwR=VS%4 zdz=gt@2}f+(yP*^nMheAf)K=K!0p>UGmiMz+WSzSx_zo(0EVx07g~z+nm1KcN|&br z3lH6_X&~>M=PX8k+MB5LYN|x-GpvR=BPDTy6b8uz9_Qa*Ywck}$r}dFSHckNpJ^bXJ{{XJGE$FqEI;t1#2q?g>X3H?of8(#U_PuYy zpPhQ3Wxp!fOMEo1B0^agAb>H2B=YPrk2=~j%MI8-j6#HPPrG3d_xA6e`uksMMYjq* z=CGf?=~6FQEeuo17*fjQFCmL#r}>1qS3+$lYH4GNRYdihFU|O_ zNd#mZ`6pj%?I7xq!kV~cMGQg700MaRp&FEN_;Yzzvif~RUahuEPW7_VM|P!2enBOy zfud%oKCVjShzbl~{j;Ms+Ok1oqU0(ns=Z!QFU`zmF_NmqV{?WJl1>Rd&c4^$XV5@0 zLP#0e-`2d^qGccqpI^$al$Ddz$mq-hsB)n|82Y&2e*vtulglM#I1ErVD09S+a$CQD TI{RN~)q4-P{`!!=j935JmEGzb literal 0 HcmV?d00001 diff --git a/image/2025-12-26/0694e25d-4e96-766f-8000-b8c29eb12843/darak-2_000.jpg b/image/2025-12-26/0694e25d-4e96-766f-8000-b8c29eb12843/darak-2_000.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7ba93ea22b944f2f57d6dcd323af6d9daa0822f9 GIT binary patch literal 96737 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%0DZa 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 U&3Ugi^?hDz&3Ugi^?hIe*=mOZhX4Qo literal 0 HcmV?d00001 diff --git a/image/2025-12-26/0694e264-b742-7662-8000-a54ed4fd45a6/darak-1_000.jpg b/image/2025-12-26/0694e264-b742-7662-8000-a54ed4fd45a6/darak-1_000.jpg new file mode 100644 index 0000000000000000000000000000000000000000..05462d6f14cc6cf89c60a81f5dfc22b83e0034ec GIT binary patch literal 195312 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%0DF1Y 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 z z*VMJgM@J-z#hez7G+ryr1^~C;xzmO554<4SJ4)ZRsA`gydypwpQU3suq>OT!R>yn+ z?c|K(zJ(tN_6mlQw&_|kS3N|4x$l*LlwLn!`D&Zh2EO%EtSx7?ud3BGX>39lA~;}W zGc)8IAZGfHk_HBsx@siVI=VM<*`F3Os9bue&KKEzsU} z^7>a=P;OSragoBV+{|hzf7y{+9De<^uhl)xXxS9->}{h~Y3;NUi1!83ow&_kQ19J+ zML8_QV2^BIb{h4wwa0F;T&J!K+S{w4J_q{enqj%YEQdU$|)?3zU zxMX0|i76As6oCHiWMITMapY&)PA#jb_d4yFV%ic^%l=ZdQdL(rBR-Wp3_zM}HxM1M zfu8;ShJ)7ajWz(pKs&#{_+Zgj%gCH0dP#O zju_4cbgy3yQeFB4MKMjATmiRDJ9hM_PFGIJ>B&Ib@jjA`=UvQ}-4fhZBr z9bWCd&336?Jk2c$EGXiTWOrrme>2}ohtAy6D}^*^9ci9Op@K?3GaD%cjTDyn(ul?p#MS(LJc2M0aD_RfVc zO<#R!BU*UcrkV)x6e!WFpi-rWGI+Kz%eeQ|d#!Z?bv=x6$!zwkWX%vs7_*h&hRFku zy;U7auEnfrdVRt`_V+Q(A$v(OWC%vySbz^ArV{5_N|2;$1gQ&yO2ZG8^#k&7xj#`J z8{1LASbCH)#~_v1vhz3y;1iG=IL>2ab|EUSZ)p7{Lgs+o&Cs?YdO3VpGRSGczg z7wkw@YLPA{o8=*q3YeA9D`bI^SmB4aW1l+5S1l#NRrI(dc#S1U!w~!zjxb3il0Ceg zS1Oj3=%#`wovJ3}kt{>D6!RpKe2ffWeeH{=52KHAuA z(THTo%XakV?O4iWx$v8^w$=CHdwz9s{h*VW)Y8);(<6Fn!MX7VfD#PnAb0$aooG*2 zZF(xpSjS++$?fmXdG@VsZ84HS;2sYroO=;hIPTLLc~OXEYITKM zIKcH4k8gh%{Ppds{b-Fj#|Ln-NL#-F;eUb751mp)&S;}mG6Ym&e#gIT91I`huQdCD z1gV{5E$B{+lJHP)>-ZQB*de_BS=5Bno%;*{&TBZV=b4leb|~-t)p|6)DJ(kM!*Im*+}n`t355k<5Ni|rOuu%Q8%JaJx5^NrUwJD$G(J-S4guYhCwShG7_qL zpExiMQSQ1*N--d!ig|f)kjO!E*kPBKFQ>7{$785>HuFML2pzuMew0H`klRjo z$Rk`5IL>+PRXJ|M2durOc(r)Y_@ugN#kOoFFO@5TxUqf>y#9)0+Db7?rh$93MkO#l<(hc!#aE9U3 z4ZCV@Q{<)jPa4zM1u z?Fv<8W{!p?01(U+%;XG@AEuZ(7_0Rp3VF)EAC)fk$v@)V(NpFdNIzp-*uHeOTRcW} zm{0Yxs+7RMz#oM7C%^L3ThdR2ovpq$J(F@h*1Cq_Qj;{XM5!z)%Oge#hQkiS?tAJV zbW!mIaI8mk80>#8-gBexO*)BHwsu{j!%T*bNMX%Y#&~3v6v|AbC#I~SmzREIewu0c zk8`YOwo$g1IgW8Q;zEYP0CT~he-6#RP^_Ol5Op!*o(4(4=7-zE;VPotYg(vxHJPbn z989-9RH|{?w-82ipL`tvYQ7csrP`_`w!utbbu229T*Bx5L*$RK#x>AuNBKKEpUYxqDSPz>ZzO6aKbqnH$rio8PB(_O>=@>uI2&F|6^ZkqhOVpQDyB z%L6_1vsYVgaZJK`IU{1k;Gtc2%9`Wz3PM!I*ucWef-!^N2U^wEEwy|hYwZ*@f1Hp< zCNb;@8ZQs{OH5-}Z}boqd-xLLkF$gQY9jm~jv>0&RuVY?7LhZY5`TpKeXD@e(t0ch zaoA@g2RQCEg+7Pzk*?To4~KqKYwjF=wBQ~XcndL`(M+ecTpY2 z7dvAoar*;Y=S61$yaGpj3~OP%XC4@wj2{C{^-sd~{SdoBXojLRc3jid#;wVF6UIUb z)dstveM7RdiT34jjCpi{rN`z<0x_$)!>syF^9dHOX79#SOrZXR)q6dzt!|~J({7Ls z#iDF~DjV$&N;%d_&QDIx6Me69JV3{M1 zT)1Q^NAPTS)n4mGTGOy@XuX1ipBiS0dwHV*IThDE)q(z$xCuALQ6Wvkl_MMvq4lkr zNab;lor#yeLo1Ho#dV=kNepuWxE=CYd@$CGH1(9@kJQL>-v{~XdY0Q+mMWa1EC6HQ zAN;lMN%gI>GQ!2YQGz=P`YBmhFj0>Ei0$9<)*qajn6P-3L}A2o&(d*#-H7q_@v8u~ zO$hD@8P0LrUy{-n7~z%nKKjL|V%|aPa$9QAOHH`wWQq|hnF=Bo;sZ!HawiAIbFR5;C~K*< zWw_75S?MUk#~Pj}0uJ5ts*|m*@1yFCA{E?i+r?ryz&P*4Sz1lDl|Mx4bEe;$6Gpko z&ffUPYCCOV{{Vv&YyDU2$pIqpJ} zp99}Vn>|mZw&@)5!p7f9jFLGYZ7JUr5cNr}TYBNO<7cL~rAV;nIX81aI!eaUEW;t>+MyIu87*D=!7Xd%U}-q9O8~U18rNWmKc+T zB@`f*Y!9Q4?>QE4u^Bn@u77+??e^W2;$doeT0rvfkkk5$0t7w7GGu;04ST(H zudNjuPN#0&ERRbiV#prnM5X@#aOhjp?nv$Zq7HC0PJ?RH?yG%GiW#VdbxdgL(nyj; zC!(IIZaK`DAm@*qoh3=D#c37H^UNilVm#U2PEJ{g9@NjK^j^4{{*+Q96}(c&W?|?8 zU<03Wc%*Y}?>d@#xaOj`(#ttKrH190iF1%bN`wL1-y^<`G+WPb)2OMdvd(D?WV=Pi z;~O9KWrK?-Bm3O7J3h>z+!b$2UDG%(Q9|n+*G;!0(n^^;OEgTjeuUX} zoUxm3=DTfsgt(HPmiGjZMJk`dQmPg7&PVsL`Hc&jZ93_fE47H=<9G8zk@S^n zsye2lmPYm-jHtnwNiE9M`LLy7z8!Jqq+_s!{#ZHQ}ftdnhkDtDo>jmF>Q_)mX-YEY7Xwoy3S_usXc>uhOQnKWbG4u^hZO@2}^?U>B~2luj5 z`c)iBIB_H^#m8?fhxO3}pH@^k+q*d0Mi1qh5ZZp4SaFf=t&#kzrPofb^#gMcLepxB zgVa)0=3rlrGn6hyPvyfp99L6ZX<`sucXc!pKX#>$F8%xDsOACl+kiR+SiT^-e}1+q zS64j@T=2~-MreWa#I-0d-yZnU-)Ud=U0Ovon*RWAEh>T{rD)+|tTG8%0FaUoe4Poq zmf};HiQwQ2QENycw^Ace0UiD7QYbDIF|9qWnyRWlQC;e1FHI9E9@*j?W7q&k-&2q+ z9GY0mw{LDu$o3xD8rpS=SxZc^JYZzGE!Yo#e>%b|C$9n;3w)Bq0L+ob zN+}-AAzmZ%&NT#{*dLus?apd8t{SZ%9PVO zE<;LX0QUAED?ji$w_3I)3uYlNAtHiI5mdWs{jdgsjBpBpgCCg(NjFY^X3_jcP&C*yaPA7$Jk-iKqew=365ch`8@Eub z6g)x+PT~YoKe~_158_U( zmp-ajM2{scq2h>xim9-2JRC7C{u&xwdXI3p@bzSNj|VFoXFq&4O8)>YQ#x+H)Vf{` zo}qCEKfxg%-%l5MK8Jok%5346KiWZ`)`J~c=q}vYn`-NOwC)C-=phn*&X^>!zE~y% zkd@<%`>vGhcT^{#kpQT;Q#5~4^ImEQ`(U^DY0cl4`75@)#*l|mG)f!PD(t|x`vHwE zb`7UPdE9pDDN%hYnuwy4myRyLHh#kzc(wTX);a`c-u6hZ;@C-9;tY0y$jHGttSvqS z^jA}8_m|!rw$eb(aSLP+7k6gQKGkyDo13ZI%1Q|+p`@y_%P0BWWnBWv60aZ&;rMbR zzv1tzt?IX@cB{#vnuZ6c!eXL3a1lu7xem{Kzw+B-M|h;$H22$Zs?2afN{%Ef z?b$#Ph6DKa172_2cWqR_>2s|JRI_H1FIr?_p6KqlNBr<{_th7z^(L>^+T3?i^xRq{ zr-T|OwMMoqgq%4)#!t8vL0a@Z-P=99R{kBNQaO9M!4d$YmHYlwxo*9caipL!$X1ex z`ArotP>xKBFwRv8Q}zV;^Ql^GhqP)ojgZrB`&1W-cs)s;TJ(lwcVhnlR!DA1oM%Su z#l5y=ZqKAvw^hjeQks^UM_DJU905t>kN_0pyoCNAI!LZN0Xl_qr1aROx>+U$XnWvC zo?XwsYz*mhOP>D#Q;Gh1;!9X9rfgg&54}_nG8?$XA>7;P_7`lkUHIB?T&(C$`1a@Z zson8)fS-9+XiuHuFKeOd8Q7<29S|C&PV}tkCzMfz2cB>p4inl1RQf2tAOR&H! zbAg=;H-}9r?RUF<6|$b9CWyrGncO535OKksLX~nnHgI%Uq1YEIg@4Q2zWL z+BV|_zSXuqATM1)s;ahBZHr}GG{sCaSJMgI6cPg?4m<{ZvPN|aAE!)2wT0S7z={M; zPa}IIQLlDCVXIYs(4pG3R|ULOQc+iW3q0G|V+8x^$+D!P=>F@9 zvP&~uw)Msc+xEItiKm$X1W6Au^tyKrneUwlne>S5S+wXKQ^Va91-6L@#zMQCbM&k( z8pBn1&iSFXjRNhE5y&_`c0RN}uiIOZ=*8CaZoX~$SY!2S%m07lYNzYt@0J&14D&YX?0dFe*`waFIW zo*SHU!pl=lJxW733@}zodDIpMI5^1HEjJC~)6*`t-RO4Zv*#^sUeF@U(sQVYkgXCp zJ=2*goZ7u0~rT+j{Eyby^lEVJL31d}nBPlo`w_~4UPJglN^!OsUh6`(z5y+9I z?4p7{5huAG^v2o}*Hf^rHoM&*FiSLbG~TqY7I1#DOrR8WW$wQI+P_+^yCU_sWwqQ5 zx@c|6WQr!4V`v=*V7MTzd=c9^(A`@O)444F0JACW64TFc$bzOx5@n}uL6l&&N|W^G z&O7LBZjQfkT6T`%krt}wEE7{pGCXp~-!CgEGpw;UKEx>GPmL@+y{4~iE!WLW0T%@9 zM+6}&-#NesZVgxV_LmX2jAT|tMu^0Vxd>z3vN`WeMFkx$;o7x!>uiEJW`~N?w7lv0 z{{UpG{ag-y`2=>*dwW-IZMA5cIVg+GNjk?;B1uA-M4=3z#&9HLaC76_XqRicQ&C&1 zt#tMpnSaUw9X(wwG%!IF5-M`_aL0%Z$Co840m#+vv!<8bi?Dun`BfD-o#TkYv?5s@ zL~qIuMkiiu%Y&Z8@%w59i(_?aB)C*-i#41!(wQgRmR$b;Iy(9l&Y@=niyIj2)x>C;REiX83bkiO_p?5MO!0ZPX!6dJdk)zFJTWy=2L(;to zs8x;TfvQ#JFvvYVCL*L4kS{Me`|5{11r4^x6=jB^wxY6@S-D$fK@S+60!Hzn{{Ti) zlM|n)<0R?|O9t$=-smf8g-og=NmRO2Nf0sj?9pcj-_K^wh~C=1vvm9)4lw&5!7rSG zLl314FkD%>q*hWFI6LEDewi2)#93swRaxSKo=jEJ%+b_BWGzmxkhuCzSQg5T$0Us7 zTbJ#n7Us1}3g$|<+F0n!Y|zv}6QLes%f`iA;NakR^Q!Hp*-v!1Lv%7*sO{A-=0|s# zB#fMc9Bf+|A9q&PTgLwY*5IqwRIBQ zk~+Fo^&}A(;|!&dPa=M%azkW{>4fQhfUPCkstW2V>UkOx%}pa0j~s{ZW06tN9QHWD z`{+5;{n2sjHLq|~&q*&Edo9pWIu)pmBjW?XA@7`$k^+0E$ktznjmLgV_12(HTb(K- zRE;SReQkoJNyi*^KbEZ?v|F40mT^4cq_-|SpamH#fIWMA)=jKIE!-dmc$wXIlZ+la zd(b6WW|9s(spG&$h~P7K!C*(_s!sTh#bKzRv8+TJp564+^`4HlZTPhG@WmA!K+1;1rfQiX3cQSDl_|k+2*+Ya zZ0KdUHsp7@)Q0H{MoLZsBvvY{(>o-J7=LCrL60Ekwwp8^crJ^ke8ZNFEf9bYm~g9~ zV?yrr-vU=zn6wGFs9qa6033Sup?!U=rMXjPs+?R(K_H2+(n$+|gs}h>3{Pbzznp25 zv?kl#L2bK+AShypkC<$Z0#F?CIR^o;oPRAvQuO`_s144B(3Mw_RH2D!IWNf^m+*rS{)RXzJ>xxKJ7zN;Wd)qgPNG!GUcS>h;EILIGBCph-eI+n+@qP5f0 zJ-gJYnw_SmtDsQ}qrA!CiDYb}5>>xW+M-FeDrq@eYb$A^wXH-e1gPdl5_TNp;uwN` z$Bbh-P>)x;xwYGeG8AVR&Y~@sn(E^5FoINp8bvL^*+KkABsLcVxH#@Lxj|EI zq}-QF)dW)1&hZ!`9)w|}o4kIi_dEv>a@o#%>IS;Cq@cJ}y)a7Z$f9UvCy5c4=1ULl zm+}ewcJr;wjUgbhafDSQ0kxQ9@%hjT{5*lyVjBfOAA}RlTdVh7ed3~)=WtmiRV75R zlNT>f0fHZC21m9v9eBO8^)Cx!lcTJyAj1=!uhcRL><`=9LwdMtXy%z6@f<3Q5=P-6 z^$1_W-N`rywyiYVhB>ThZ9&AlJhRE4soWf041i76^)|{^*`e7e)_Mj>#W;7 zEjRmJ64CBW((<(}(dvPCqj_F8h#n(@7AwV%9z=G@7}YCcb>`P$w=UPDpsJ|47=0#? zs7M#o`b35K5^>~=1E@Z*byA0>^j7P16pbxa1-{n=F~<{3@v~EzWb{f9ROh*GV1D{D z&{kUF-s@L4_Tna(#FmCNRV6)GW8S+9p!BPad#0?TxQs%tXc9L7CNQLK2hh}ox1yV- zvI-iD-9;sy$4fkQDOp%?En2WVrS#a0D<8mEjE?%4+4Z|ZzOLb7+BH`Siu$_6RFbYU z=mN3HMy^5y`bRD#5AJtoHXOL^`dFkoq!VPY^s zA;HhwinFxehCMOT7V+K1GfAijz&o3B68sL{m^9&U{n1A^SuXo>f}lnILv1yRkzNAO ze9O|wD!j6W0z5LP3PxD?BN|vXM^MF9&Avpl%GXNG&m{y?#@&{pvKW`LMx;89+G%mR18JzL&0w^&W?B@A~L2 z(8Et|xK>ivK#Ke#Y3P8CNR_4Mz`7!^X6=whd+DC$XrAijpsVc|LS3-sq^h?u0>7;DWmms>a1HJ|h zG!JP?dbKq$$s$D^IJUTAeMpexAG7`(FeHrU8o|}hpf6H)8q`rLt+I*~rnklkz>OW8 zxzBT!W8C{=RM@1ikk3X?s?$cEoMiqSDRZC9`;WQRf2# zH&Ca#g`l&A}y|fp}vI1bj%q$O8bMbKGhlR8I@tM=32S@KiHn0g8+t(x7}r z)|aTY7%vp<4GJrPz${pkjQbNAY(ng^;=vOHw6_{wq@Dzk4{1S>N9Wd3!SUYf40!h%wc06Y9@k4lRZkn&QYL4tR$MYlg*ZQuJw6~P z^R3g|+Qx=h$jLZhr=C4XG|y?LeBH7p{9$~k!y|X5G1$<8`j`IzP6nuVo+ot_;aG)7 zW?|{5Cjp6Uk?u})2_w#uLazP9EYdb}pRIr(`+>8q+*eGIFHgTt<;8 zPD3ZRAHUyF$7GvCvrk0x2TF{omOorPD$UI!emt_IfWd&qLCy}O+v>KGMUBcN3JDk> zW4EnOZkM{2Hg!@!z+;^7268A@UuwA0uxaTF6jbKUa7U@#2qVZK=UCFgQ%OS|!f4bZ zPSJ(~A&RIadwZ`SMu^uMo_A`rx>LpT5ys4f@@UR^G9fWAQT7B6w!PEOXuDV*nzpdg zOY#RWD6C7L+ozzW-Ua7hQT&jN;O zUND1*T%qJ!BbY6WH-8{_)V&o|Y#3^J-Xp__DsX)F2fyX7HStEh!}BRAhnVcF3C|=9ef6*0xYs)NZp9C^k+Elg4TjX1GMy4O3j6`b5};P$&m`mL&W375b%P zrNwE#%recK1;8Ilh_`i5bW>1C9qVm}nmFVURKm~dGlBH9jLg{l{+ww{>OJXtiPft; z`sG7$wArojMM*i5hNhs%!QNJA+6dS&B20HZ&%T}-W`w#*(1A2<$~GU37!N9ak9}oT zqXd$ix#TiR?BIfa%ymCQ*X7f0O#3q~-Jq*rfOz!=vA@ynZy_+qsL?S5s|^p$OpXM>3bM#)2--6f!>cnUCsnOl*F)|d?rP@2I;Dbu-X7IGp&w^a0 z1d;?&c(IIf=a2697}buJp>7mV)ziox2?kZwh#2_8p9lygez z9ZnhcT?n4n92FRFPpv>nBGx0vQw(xOdvTI5>co5Dv)fe*rpnouGT%93x48O1BApex zf3gON^HEmAg)fHCvB(-Y2aw#3!b7j+%fuU#p8ouEb>Iv31YeR)&MEd`q`-vGo}es)ON6 zCyY7tB!kbbAnKYoK;FwNQfUB$+qt3!JQI_~(kq|Weu35Joh@}KK%jAQ%i{ywYJ+v? z?eg55ovCr058o)y=ieQ*{Q=lIWwLG5$x~&bx5$I=)kDT-{t~w%{dKQ=>D7kmky&b_ zs%GRrdjb|D`;QsN@jA1tI`iTkoN6xSvbp}(?uwj!!T#z?y7+z2_fivXFD=G6#JL~% zfv@L|&9H8;T_LGej!0pCY|+TFV~>CA6RwQetNk6XLWJP0ELlII4Kx?;g`Smemf=^o z>7wP8K9c%p#(aa^{+fWV_-DK&9I#q0(K^OBEH#icMR@on(6&eC#A_W#t91=-^4@u^ zL~jZ>8%{yZ6SnDXFG|wowYRyFK`e^TybO$cVyM>o_$jRPv8#O|CBP>>Mt|S06qcLb z?YQuu3?qaOQS-zD-1lG!AHzkxvGCJ%dUzwPxzf`FMN=I-Pa`s@;xO_A;y%ZT8f5lQ zN_PIrrl?vdq?M&0v6Y052Mnqh zE`QSdQj2W(c7~zksj8%;6U+`>IjH)xp5u;u`;A;}pADNr1kda!8gr6mRb}p1)9r#z zG1xDFJ+$3^#)OoXq9zQZDvHPHIQy=@3scf7yk#PU47*6miJw1HV>$%}i)$Dqi#A3N zG~Yh6a_0(h&!r=~gQWF)8r5`~)h!hyGSd1L9=x8Cl_19$EsIo(?f8ROrKzd4mL+SbYNGW^u_Uai8!EXT08-ieX;$&& zhEQ$o+`tIR?g5D(as?fX&d_Bjd7-GuuzEHF44eyTdH8^K@C7ltVZJ zu}4N&%8-4|zNzWwMS8I$^@z~X+~w^&(7B36VmwNF2mKrz>NU2pVrF5Mjlnrm0ChgZ z9`&Kkz)&1<>+D5y{{VLUFYQ{UIHUO~h=1O|%@E`}jHBfT+a0tWs_2JUHe`eRoW9gN zSS*yyA&iwB$>PPM#yp(stTlZd-kWNNjjpDO<4lW%iagOv!~yjY#z-W8{aSvy58Udd zw$zw!6fb9ouxV_l5{cNc0QWTQmJ;k z(nC>AIyA5kN?@fvkc|jZaz8JBZEjs^%Hwi;s^Nwo!^!9DPZcRG83{YNw= z+r35FsZMF^+n()8{;YDvG*cmk8FP+GN&q|IvPOQ|DO3DaZo5X{n$2~d)pIoFIK_Nt z&~nGR_JcljgMW@?cYW7 z6x+1N8UW2KS2dCqU-jXUm;w9&*8?kerRJKTt@s5G;JaR-SN+UJJ9=!*p?}Y zEE!Opq+s^;IHR{t?@MUvT@An$lZ9ndp>xGpv~Coiw{xa~>(uMC{-ZTQwtw#14u!-Tqv#-f`BQgF3riI6RO5C3lt#aetz0NZ7!owTjK`hwWzL2rxM9cGs7Tk zekaFeJHVAD9$LUD>5c5!w51vaforr3&b3p zXF6!Bx16-{UZSm|h6);rY|u|tN&!cWN-QywaGCmWFn;>3`kPv|g7y|uxyl{B*%bNH z+Wq#GrA-C0uZZ#%c43?ipbQFLtiJ|!x+~q6c-lAJB=zewb#YTkOTq$?FVq=>xmE|Z z3i<8ZT6^Zc3NM)#i=9v_G_=ncfPk|1Qn)}cJ9o+c8fkVl_Q`Fw+ij-P5v`=8Sn6si z<%yl8DqR3Uh9r}Q&VBo7K5N#M92rJ>aKYq@sB;U za@VXcI+MbJ>UBRa0$ajVa*>Y10A%;1KBE^OBdEv-@g);T#fJr$a&Rh%TX@=ZbhQ-p z*VKxgVR+`LlL{6V99SWk0pCB_$<#GZOgA;5=yx{QuPJY-ri!9EsMvZXB~VW_lj;3I z8WPlB?X?vA4JB1YD+3#qgs5d8!JsqK|(itBNk(Rh(! zSZNEyvBsZ^>4=Oo9FzI#BiZUg<|q*%{h0AEcuah5VT^_C%^d##6Li~q<&rH$;AkKHR;(2bS2XQ4WR(od^8x#bIgs7K@Ntc1vF!e{?OGY( zb2VBt(n$1e6+6OkIH?}7!XL3*U}%*a?&?`RIPMqXIGlP_l_wuz*}(1g8j+Hlcu)JO zuD8O3llIdbFl*6i@mozA%>rj=FoVaob6c$9>8P~ju({NY$%wErIt|As zIOjjDY4pa`x~ZN?X)CHIDyit?l4vA};zo(wk(z+qk7is29@!^U?a5zc*teLfZr96o zRO(}?NL!5aAdKWI2mv8L7$>%``>w#0Hu^fYkv(|nB41i(GLY!*fPZU0N{-rEDeYT3 zb#KkbO(6EgRKK9BUg@F=-i9iUWo0i~ZA`M}t9mrMbGjXO7ok-mylZjyUcz zam^OD>CT(#3$vzL5H}!h4$uh6EuV8%&7biDxoSG$S5I43D&sR6OMEoc%jpP)a~TbW z10GIJ2+prtbEP})_RJR@vAdzAmN){k+zF@k8JUkHFornKVx)U$D=jBWHm_E8wM7m7 zD%!7>crKH}5ftK~Au%NA`N5IM`jiqg@2A713^%^hq`3(riiywpoj|2Pq{T2m(*Rig zUrUwZ0RZ7p65t2K(=SR+XUunn!Wl>=)5_of&+Ha#-!mJa}xWLW}`z=42q zjy|XBQr#ilo3p2sj~7xaC@(NiJkiuwEi6U|Vtgv2IwWnw0FvN#&wkoz`mwz$2TW}B z`)xjKwM;E;Xjvw~P|1a9TZa`wa>U>c`tfDycFMZ#l9FyHC9kfJg&_4J`Ee>YGQyn) zA{Y;=>L3jZc5cvJpL@UT3%quysVXW>T`iube^Q#RDZvj>M9xn^>Sy-`DOg&g>XSb75 zu~Z=(OqCF#s6}Eq@g+byUa#F)>h9y5Q_-oUXr(+QV=AjeKqD#1Ky^Kd#u#XmTGtJ^ zSyyYNuX;Famx`(Fu7Ig=E+PpVMgTyu#G@V#Pv2F#Y3XWifEgt`U7Zn*BrlQ+0qi^X zKKdk=Hr6*2PaU*UK3J>mC9vN4@0?Xvy5C2*cbjyQAY@PhF5LD5oYd)usCP?N-HzkA zDwK%Cbqh-W04!MNdW)=XYHbPG(u?Qwzw2>M!rJC7Yf4%mKgWe!&@x2t-x!AJgXdv##&h-D6!2MDngu+ z6qW7d1KT>X+G{qwuIWzJhFGXgJIyRozpWpqQW_#SsAp2HxITM;Mu+Nm{{TC0aLpS$ zj|dGY7zgjzXFp1=t@UfLjpN9N!*$Aq$KvC61M6EAR+=094@p-^{&2}8FwQVT88W#9 z09Vruk~5z9_tdQ?O?Ks)#c!pSdTC8OQZ(kOLag#JGA}PofH->}ZGKh5cC=H{-B7Tm zg`3up(lWL()8B42lg}A=mUtbb04PLPVfcW^?t2lBI#8P9 zQi32MyJ2e{41rE^!^?r5-Sb1{)s-&|ys5dSa7OMF3}mk>a=0EE0)bSBUvnDgh32ft69%pVvh@_UNb; zpCFL(G5U=fL7>~Wg(QwJaT151_nqu?}4dS z7x(wFG?xmce-;_CKnH>{F_A%U?`>A$(g_`kpA4{HUAQAZdfqWpTq)+Bss3G_B@pnC zW;tKz^*FC?*vD^SjB8f?LnX$Zg;Uu*5(vBf-)ucpz>>Ijl03&{psj};tO9mkzSRMk|pROO>e zTBn+xDV5)maHL3}{h5gRvE+>FX74M|OoHT1Q~dX)suU~96J@yx4}Ls*W7rX`&_zA8 z;k;&cIW3ZT$7Ah*ipge@OJ;xo3Y5!Zk1yXeFBH?qM)HV@O0oo!Tq`mZCj$+feZd|4 zGAX(ibCz+;Yco@(vV>r@Y4F|C*@ z#WJ&Gv2G3A6(HmT+atEJZ&@Oi=*FqNYm~K>u@>SKBr$#f&n7_n6mlg$4}X0P`g4Dh zy7^T+QOhI|$jcdZ=41Dj@h^EXl_HO7g?Z!-vl+*iYOeGS?69(V=Sb4 zs!>Z100XESrLwAv)3w{-k>r(}Mx!K4P|P{I41jpCDnCs!HZ6^@sy79KE#4{;(`4GT zm31l|qAxvDOC&28Q}g69iCQis1QQ&ErIxQ2W@2A`)ZzQc8Uoe zRZ}ahvOrC0Wj)O)q-RD`G?dat$$$%-a0Cy2&7S`N zZ9)FadMRg)pn#LI#SD%8i5g5`z+gVy_N!erC4I)<1z)7HdQ*BPcWjWX0|o7a;2!74w{1zoI=xh| zy)Xht{mJj19mWAT?fU(-`L?dC&s$6AqQO^B##m6CEXu*7UsQI&*gP~3#O8DcI z{SH9ysmdC|NgTBaR41pzjV&q0F#iBcAFJ??Phtjr^;Y#Nr}e4UAh}q$%Ez*(<)8V? zGy3cHnh06UXr28>j7y&kqmc(5GmgW__S7b|QaBud2^h%6JJ9&zmM7kXvjLNjYLO-5*fxHpWjvX??7 zimC|N+m%~$XyoO9>&uoA2XzBE^V>Mol=asuy_fZyG@)jfrC{SCarnLX>ZD z=R&82W|3J@gDCSeX8@1x{*>2ct50cfacm?79D@)+&miP_)mv~>s@-YTnI(!kdRZoq zISl0js;grQjCWsuG~;Hv_8D*^ln(Q9esxr>4Vk%nW80zbZ?T)@yW$r_l5IRp&wXwma+ zEN21J`_g4bGCLEI{{YKV`I;EPl^-V(Wk4ezf4((CmcbOUgjgn(fb#ObJ9y7==f<+p z(0r%U@<@(5dWSg~_iTbc$4-AG5%eVbSLrC8T>4eY8|^EV430(#z{2A`27cO+hj52( zF;b~;3BxvfkG2TaPM+0roazC@2d*>s@G3Q$n z+ACa#rnpr^K}-QQQ~-GpQNwxgLH0ehW1_5jvRUcOPxP|5BxjCs$c`kA{l|~jQlBF? zqzQ>%1eHbd1HLnWpebDAu|IuDi2!ko<28$%4#PjKXA(1v#~T)7oMb5cy!aa4i7P~T zZXxmY1p2UZ_wB9wbZI?0&CGBL3osy$>)#*4Q?Nr7R6*dL(B^VFa0`Q|@b$Z$L;7(erfIXnV7t^Z3Nu6tFb^d{ zIdG%9x?}4lBP5N1> zV>IOg9CMgN)d7B?lqiH@v7Y3BJAL#ex^B9)yGLrHYSlF@iJ_WesyhNDjihM`E>Ca? z7|;z;=F-wXz}{j8N4ewHzLNIhATn^Ifs@C2sO~Cj7T=PNqTxp*5SZnVz@cPzAS#Ap zr?>&U54hC|!@2ELl(M)E(3-O{cKU>Q0dk|?9@@3;n`O@JcBqAArjyZ$BdL*Dos`b% z1WM8Y^%0Yt;PKFySnTO|lGjsJRcV?f;S|+yNbrUOm>#0J<$>7pAD(@*v!=;$^K*qo z;qnf7JY%2Iu(pxf;^kdIjhRZgJd=zZ{ix|la*B#kS!}76DvzWwfJwi?RL?Z9{VdJ_^tpyi^0&l`Z`HPDWIZx=9X9>FjYKKyP@K}stH!fJ(PV%I%r)>!Icm*Ze?OI$nxVO`PP#? zyE=j94Z8(@(eL@wZD#An&8(zozH@L*c)sxx8r|uGIHf+&#Huf{aBd2{dkF^{~nt3d%P_KQLa zikac2LHOPMIK%!$m=Ecp*5KiE{)qD#@6wMqe zJG)BK%u9D9F&IJi0~pus6@Zeh6?~55{Yxu)`6Jsd3;zIJN4)DL8CxhpKJD8y#c!cA z^E8+q!kLQy0EsKCqm8c7^7Od;KyseWR{HGMlPQh@_FZ&1q|+{@=Bk8(ecoe4J=N%p0}wp!)2 zNl91$=T$<@Nip^xTzC!SWE}pQv?aCeD$Ph9B1dNKM{md;`jLruJwo!WtBv8~!B>a` z0h|D=a54I8DDI_J$S#kLNHslSTzVDuG`HRQZ+y2blG9fF!hzkVPnW2`_7l?u4gUZw z8$n9#!Mk>yYuC$Qu1a?pTZB!LICf&pfmZ_^$tX|TPlaWL>f#EkGO-w7%6_kZJ~8=w z>M5uVo^ayQ&rUgojo9Ebjy##rH*ELDwLut2{` z91uy*+xTh@@6#QJxxIC+v{D&3=1HO^oz4d$$A$}I>_O1<^lNTdKzL{+zR`ex%_{LD z#C(AdCyq7$0FtVIJ!W9jcW;Vm<6L9HAU=M_iiB+(kO))t?MDr}eE4|XpEUH8b-Qxv zoTZpjw2??i`b!3<4!!}w`)g7@&Tvv(CzQ(Nn&xFpglTrPs5XiIStJE}sD9soHx zP(aZOZ1iRTo&P1>#|_3F$bqPrn@7eSJ-R`AA_zwqoCv&qD#%z9_?3arjcwFRahkR(jLSz^H8(e< zdYOKRLm`Z+lH7uTPZh|)@v1$K;nScuDw~hLZ03hlv@}0i(DHiPtvA~2=$uUvx>o2Bqe!;&QGC7TdDu(AHo<(6T)DEtX z!m^M_8Q}3i=>8x2le%tELrMh_#PY>0dFECbBIN2=Mhozh9h?FOzBLt7(Js3frJwd~ zE%{)YX!#dLm68G3)r&_V2ibF<%S?5LsQY_(Lnx=Gx;GHW;y7BW954We^h-B!_gz}) zZ`O+(6GuxuDn_IvSjrna}KIp(z0aU`$kh6RctR$`z4nJ3>wJ4WqJp#eiu@vXAk zQ5=l1Mnon~EDHyaWVQ!zau4aP>dutew{GxDT}`f8ZFd;vT9qS{zX<+dEAheR3gvhX zDtqWOdV<{$?+`@B3XXX9=C)4>ie*)kc^JVU59vVFJ-t_Jn%6WFq`aZ1hI-TzNbSU_S7VUv#PS`pp(n$C zOszd9zitXjS~;MOwcwg49dqbM3_N%@5?BD)BN;vNPIPHvN<30tV!o`_>WL^|Sj0qB zG-OEfeMbd93gBnHm-<2_)3ua_SU_ONBt}+N7(bZ)b*ovBNo>y>WED6fxy!Y8DYnPx zMGZ`qQe~xOb|>|~_5zul-%Gl{Q_b_M2Knon4j1Xzqv)X66O;24_GzCm6&E%&mCRKkMmE?2V2fjYq zveNBoovIb-sh(3K6D$(EXUMfX(Kb8eO%heo z%O9rfsl@$3WGphJfjy3UYs;-C!nin%La4wvz{h_|tyf*~Y?09RBMv)xI7%Gk^d2U72{B^{xsRLiX zHyuqn=9-$YKwCK=AoPJb`|;Ohdab-EDQISjo>2J7l!KHZz#%i-7H@Cku14NArsRs@ z6*r?5Qtm3Ws*0{6$2pLxjDi;gGxr~T4!1DL;y@JCQ1 zRYhQUVlqw$_Qy4oY}pNcir;NzSsu1Ys$zE_a9AN`;sFGZTljX@VLE9ge@D7|M`?-} zZ#H5i6UNG^^||gOP%^Q|2NiSmDeiJKi0sX}wOv}Pv|H_PR7YsEr5sYoz()kIm1$~U zkx(O%!wlyqmbx)_t=|^?sTCayQM^?2v(wa4R?UOoJ>^vzDnmExU0iMme%Gy!v)A(0&qYhkIdKR+uYk?j_A*3nrmeo(xj48)nrK= z*bnKnk^lmOj0M3Uj^t|1){dadSJAmI^cLqg`$cJ`q^;uc7|lvzM_xQwqc5=fNg$7H z1uFNo2F|Qn4yJ9!prrtM$^4WK?W=ST;P5JTgbl zS2tFkBuN=rWK}XB#g@Ur9x{9AC804&hFthlNEZX}06w|&_N{$StJ-MVYsI=h~JEI@+7Ok@C7wDMqoR^HY9Wr=XHQ#@R&i3fBy$9g zSUuCWtv8$B&C*#@ipvafObRtH5^{pBNRmW$0LH;^e0ds;s$4C_#9kRu8l;{iYW%A) zAzO@$99J~nYm;8j^FfDJf+)wetzz7@8>IvQEjf_W0An#ssm)=-eh^u( z0XZ7bs=wIWP|qvZLnV6ps~%EFnn>^%8~{}E2R?QC2J5s%YpWAPB(YrntAwfvV;qAV zmn-zhj^L;r!w82VIThev47o<2`~R+mymEJ3b> zi6LhQG06mD8TSVqR8FJS2CogYFiDXTekNbzJuoJO)|yJ?ibyyEPWwTLoPnN4(G`lwZ&aWd0I+KWmIc)0%)LFfC|V+kpOo*atI&>*Q@^D zhFfK2$_Of?kC)5J4M(ZP-I8JH00T?M83(ys_tid+W!<2sTI)@|uAqlu=_45=iHZjV zmCAt1-I(}2v}{9fbc-O6hg{$sZ7h8beJORUH49mSq+Tp#GTTt(sXvGxek&!`L>19I z!dILNl0Esc_gXMT`>F@x%y6j2tM9*v0Y8N zBaWWoav-&-7K4em9sO)Ys3BLdONcu4bSkyZZGYF8gY{?C5? zbDesmsv#Q+Ai=|KT>UZaTO!k>f>{KMBCC;;f(|=!PrX;@>^1jmkIUU^rb8wwBS$>t z3ml)=T(6OmIbh?)b?>NQV!u+xs=njeYq%qdN<$h`nv#`NpI6g6xI$wopWVI*1ojy7 zt*NOgzK}2I61~~idzQjo2C%Ka+F2;Efr#sWQnDg zc5#%BAPxaOOB?~)$;O$RO~%R93tg9U(#-)B)D^y@N`Ypcq^o*yx;8n0NJ5K@;AmsK zHavT}I+|%IJ$gwVN-DV8BCd{{ip&Vd9xd5h!65q`P;47&>C+lllvSGQ3i$;RQ_;v| zV=Rrs=1Emo4oi39xEcIfd$yL#QPPydCe1}$ZeCA_zQ^h+>*+3{({4I(G|fyq2$-~C z0WJ=A3}e$h=;zZ;i*DV?yDiC6I;?6q$s+SdfclJNmZB#la9GX(9k~(TPoG)r`(`UD z-fhVA_jqXO>`}=I#)fC$%Oe3OC4B{R>BupR`8m?v)Bdl^wzjo>g{(2jU0Y0oTg+jk z=dZ4JRD3oGXTKRf_|~urb(V>L~3CG_?`DcNS^w&XBzvoPlV=cOii)3miAx=UaQJ z>M5)g^nw`LnrfcHG7U&0IV-`L8<4{=R>pf{wy4$B7rPx*MLo?~=2*)5+_`dI@u(*w z#y>VoRgb7yesEtp3ljl}wH81L&=Ylhld+83UtP_Zs0 zQb001@sad`pa5Tx&)>eZB&1qMrMbN{^);U;ghm($;|zsY)sdGZf3N_~Fxt6n^ETl1 zsgNVogoA=RU{6r$SqgIg(c)M0<)1p%sHitet2Bup85WW?sEM12ki#s$QZ&-0SN8= z@3{j9S8HXCYH6=YEii_q;G>meL}xC++9IGH$Ag?O&un+mUgft!St6?a^VArcp(f;w z62v}%!B7?ea!}mQld6r+Zb-Csbdj}Ol@mwmMy~9w3!&ug8BzF&!EBtLIMBb^>vo$Z zZHEDKjDHsFQ(@2q4#UGGygkafQ(ywaBihp1GO#q)b|t`d;EwACp{&VUn<7bp<@ zUHh=ggYSW>ox^W#`q*f0R|r{5?iryuV0jFfNhObNIOE&LZ8!VAp0=WvDq7orrq3Ir zD!K)911%Ja2vAt$5J#tYU%pyMo0UNYS)J614vSNFqQ# z6Gl#Pk_iXTZAjDAM^PDgJyfem;y}S%OsY7Rc}N)G81^mWIMnsmVeXrQB-J#&g!EN4 zGF#=Sc*0KyK1CQIz+~)3JdF0#yHQqVIZ_EhKCH6I9A#Z+LzBsZWT6rb6t5W2IFBGd9F7bCU&~wcJvz0`0!Z)}q@BwK znmi|fSDrvPBoXwJ+g6G#ss2yf;5C(S$ZF~8QlI4^c3x`3gi<8H0pqX)k~8ixuOK>o z!3l4$$^i_lLK07?&UvHyFGK4(iEXT?t%5hVn0>$DRVoVVxgw`pxe{w^wMpp84r7)= z0486jiZ^T!c;~n4s>GXyn#k=>TMZ>h=H$mvrZTOZcF9xQ1a|GBbxzx^wcNtdR{XqG zurzhH`-G%J>8=Wd;uv!TkV_Co4{cGm4$`KLDCU};I?2&wiOTV)3^F*#OAM|;_EX$< z*58-3j#J}0cyEksV0j+q2i3dch4UqKV#qW)vARYWE|IE#XK|q2MzW)s)T!M(q#;>yW_hv z5uE+Pon@!nVSmyrB;~Qe2qAwyM3bwmYfmC42+w@rwrT*DWll1<6eg6RL)Xfc`sayaP9n0ho9x%V*t6Wea zlanVNU71MYF@kb@5<7O+?=Ce#14^#s00$F+oMZ!@{{WUX_V~M;550S}f#>q9l<-a! zm614wAdt%4zu7s?e@%SNG!nOEaNW3+0G9oJ`rn2pG6Gs8TxFSu)^Xfpk6?9{c35MU zY2sx_k0z5V*?W>l4qtBh16hKY$m8o+v+V?*PW9%Q>7^yA#oFmPtiLQ@F94C?Qd&Zsj!KT;gN$Rj%CXYyMnF?;s3|3-(DP9Ef!} z_Wn8n-2NKxQ`GvkRm~Lh!HL+*Pah^H>UDQ47d~;G+3!wfV2xQbg8saEQs$*{ z?-M%N`^r&yYwu@ac z>+b5`2ljNkao)Y-sFsR(Du!lQ`1X=DSi<@5C(;H-Z7du2r#8)jH9}l#=*=$Yn52>=Qvn0>w=1Wp7atm64AmC75>@Z#}WwS|z<~yDC25 z*gkIKAHoe$3)R}ji?5NZPU{Be-V+a%^Z*L!T{QJ}>S{_Fim7>tJvgMB6H7DwO~5Q| z|Fzt6mXP^3p|1RVpcBlBAU`1~N~l8jzXCk~PjdcUQMHWoVZ1a=67EJn}s& zVn?TTF}r$P)bds!`y3IbRt~o9s!gXwM{(RVi*c-__34E?Bhp8bFv2RJ$jYBtAd%dG zp4y1ol=yJbFabj*ImpNJs|!Z>fu!HXBglr?1YzUxhy|4PJ^fE=W<`97YiW!v>8yE# zBMt?;C;)}yli2(FYCfj3Xzep!T~zATuu?*`bpT_6NWmgmS&w4uN9V+6#+Hijh$}YJ zvPnk`U(Z07nnt5jFQ{UKD$enqMTkU`0TqsMkWXz;`h)QkW}eKub8gba(bd&KC4Ir< zWtyP5Sqq%6()_^WPp|+CYCBv#$7Eu`cLGNM`+e&zL*f>L4YM-O5t$Sp4;#+ooB@x2 zdSI_RlcKj_bE2xPwW~*UNGNLHbXDTf#C?8L=j%}J%-pgv4z;ZtUYhIDrc^|xsjj#! zOrmMcH8P`0K?ur5P$qEL@9Z(80=s!r+^R0ZiiR3WD}-@FR)vlS%7x=0X8?vQ2?c$Q zF@dY4zo^^lq*dD}R+2g-WR98ANge4TEy-!&Zhuf8gkG?##3QPMLSmE6vIdApxMO)lA_>HUhy>aDrtyVE8IqO#?pi;(7_)U>=v z`fvw-!}rxr^L*NSM&V}MH8wtVa#!b-OhxLU!OyC~KxG-mPh`h##Asc%_so_XF{Gxn zQ-_M0NuE^-5!J~GCQ=WmsgIBF0&jj~tLxI0ppxz$aD84yRGkWZtSOEz0vcMvVuq^2Zq{U4ouU zgB{NwIo8h9>4p0FaA=x2T9%@!3PCWLDbXefA1u-F!hzey4~=VYABPRj`<_euce)v3 zGseXM1&|NXchp(qLG9A!PS=2e%w}sf@(X< zRMSX(NU82nG>!qr2i8_)$G!;dsM2Yc(Gbzgm1E^O45!z+{XUg!N33b__(?42l1O~0 z!~$v3iuoEw(#s;eOvr(k1G``VRkA;>wPUQb$ivo$ikAU7Mio~-kT~z9vWuuma;9{- zS}GxtCW(Z!Zf1>)ax8?1=ER+`gY_I}&1KvcJH&|vCH95tnFNVRK542Om-l0-3dhfo z2-Xd6E)Lb*kL>gLnjsCuFEb|fK7*f8+TK_H{g16Ql*j`bl)R{Pwf+dSGgdLP>@ngu{4d_zH&$Ruts&dly?dU23=}p zBP_AE5(xWXoal4@P^?a~y)+WWLBy2&u%6&Z3CIUNNF!Smd*Z&KWNK?<(?b-cALW`E znGP~Oo@(Abl}^5nNab!jp4GbtU?cF=nt5%@fl+RqBtP+jB7U#qhR^4XXw}x;mKdY8 z-6Nt@o7HIQA`?e2!BVcR@Af^&)}(z^po&=`5*XY9B!a3pq>v2%0CuTk<@yZj4(Yvi zJxL955iSNs20PXYiponb6{Wbhk5*x@x#Gce zEVgMqGGYVjE+s7BkM5w!@sXiDcTYAJ=Afjl-PZd1t>!67rl5|QqLtm_Sr4W}jGrX9h;3BR(eIxSDt`yrFf72GK zqOwxg)1s@1s4GP7JO2P-UO4lS?~$f@{{Yj<8^g{ktR}gViKeTN)4)~}$D6A>&a6~% z@sI;|I;GlrO&-BCRhBKyQAI%2anv*(w6z|&a5z#kFkem;##xx0sXle>#+jx}OSEBf zGVOvp_c>B1yoNoDSb_IEPzLAM4ykQ2(AueQHFby;7SmADh~17kVC1L@31UZKjbn%6 zM|xi`3k`n7sHcKi>7Yrf=LdMk_%(19qCJ5nQfg>Q5xN=!+3DqaIPByY}UeBme>T@vf)s{o!-lk;n2CGDQ(8(!|UeT!4IxV4MN` zJ@hW_=EJ463qdZS^VatzmwFao4`>7u3H8lIn^I+H(cMq^2<%OxeMt@C~8HXdp zg3E%Q-r)ArT)jb~L2hI>VG(~8K_q^agzxhEo>lxk$TdvcQ*E!>Q_W$bRI82J8D40n zg(P1?+ntbK_LmF1sGr!lu)=D50y8F7o;zIP&j>WF7wiF`Y(j zQ%smECDIVe83^?ioEI_N?c0*B0aKiU57xG4xC`w!%H9%LDB_9p3xOiEdE~&c`jv(Q zBX_~=;On117JGuSTFXr(m0?=SYHF%@K3#(FXDG4fA$SECBe!n)Y&R9>aPFfWj*+8* ztK|?PAoTg9m{Lg@Bmi^c&$hGQ_MXP0+ZRj4F2xo12-WE$p|71}aTly1>9O<(yO^r@iOI@ejq&$&{S)+jU+Jmp?7y(-HtQ**BWTLJ=AC}6!pSI~6EC2|<2(mr1cD3|MV(U_2e)kLuSn|_p7l(nW4F&P2eJ1!rHyMww`~&fqw{Ww z$D4q1JM&e|r%fHc@UIlH%(2A6QX3_NigA(&9@zW%)_R@a4TMWXWml$Xl2JFLQG|+n z2EaKgef)nNd!X4D+F7M|QQ)UEs~oZ^SM;4g01_}jB^|tdOEkH&RQ%GZ#m}R`2;|JRsF>Xt(4UcHrt`rKjV!kJdsw!9sQdMu>pb9_I zF(ec1f_?P4(_0pT%SAI(Gt)>CSj=Phusoh)Y!&+Fd4lH@y#n)PbI9kHl!JM zlCa1WWqBR3-;VWA+|?4^DQ?gtW*U};N|>|8L|IqC4xvFu&Ijj#t1nLaVOtdh-?tJf zX17+je3W|O`SRAd~FLOm!!TX)=hGM*|Oq_nc$f;GnR zB}9CLl<>sPupb{t@Ywt%v}EZYSEcK{P01#pn%i)tskg~q8gE@{)+ppv^T!~C!i)i& zXF8SJ{Vlk?RYlG^np%prnpK@8M*?=4PauHyZd{I6vBsiyF5ib_+_z0lnt>&%k~&nP zqo;WNK=GLv7gEF2bY>-#cQ_u}UXxqWuk@R{Xd_doC{rE4I6KQ=@9n@Hy@g&-^)8a>aJ^gP`%2G&im1QIm?T*@|byD*|c&OU&(^^Fg(9;@Bq>n1fBMPYGp1`;{ z01O=GSXo`%K{Tk-ZjvDJmBHFrFDwD}2bxXmexVZBT`$cm-oj(>mAu=^jjVBw`0r9X zdu!Tby#S364>`58+(!KtnvU$t9&QFFSWa9&ZRBiR-)o)_g zazc)hDjkem5$H#*f0a?J)Yf|IV^!QIr<@rhbbEM`r1EU#0!USx7*eH}l{vx2uU6fy z73KuIP=tF`NTY&ENsNyuXt~A7h7J!U`bafDjA4ms)=ptmkV#Nb0zI?mI*+VJd*I1D zGMP5N?+AY~<}yg9m#6ao09pkIJA>TdW8WIk-PaADW4+c? zwen6)AeCrhj68wLfg&`3VMCn$FTaghEH&_5_O&%VDooMLS>+srlc%JnG(#$52Z_!= z@8iyZGR&HMa;nH8cSDj0+Ht$r8OAs@sib3hFg^%$jznFjA%=0=oMcvC@)p@tv^6&R zv`QC<5N1^|sCOY_Ws?NqyWsg41HXMnT*zJ2wpc(~QpP#zFE)#7;Mkkk5r z2=OWznGa%ljwJhnH6jSF&A<{q>@HD=AH)drW4|5EYZqEcict-^tb+zs!2pqt+3n3< zZ#Usjx0<$^hACE8a&~W~22dALi3EK_!WD z$W;l+Ckja!_tuu(+%UZzRU!1#)uj>CM65F;r~r zD6AT37G7LgqyS-<_EXsS`|EAJo9WU>sSf$0eaOcrgZcZ{&#DW<33=HgDyry*10a*0 z-qn)ZwznSWPItOl5dsF5jvOmT9BOzXuhoH`z~ea7vste(TG^zhs1e5Th~tKz(P$A{ z=|ZiO8W4TYBj?{l{hL)qbESFOu^y60oNyooB}vcHPH?~sX9vG?qMZd@ro&%RM;vb= zOB_>FR>2SaI>)+sr-apHz7 zBLf)Dn6%qPyOsQVXK3~=7^ol-p5CWE_3ih< z{-k)3Y~+nfvle`jyc}cgOLcSA&lcFah-7Knc|z2ek>ehdiKFMheGGBj3}Aa5OWP>z zujn<(gbUR~GDRdwClr}MW*8C@%)s|JI6blBN60#DKGc?;iLR5@)5#-7l1Wg^0Y%E0 z%K*Ptdx5XFH61id^3p{YqXbOHiCE-~(5Wg<00=q2J;~G^LhbAfmfjgfjfeysXLd** zZh5VT;nmHZw31CP?^G^hDjRcP41@2*1ugV9TB_*2c8)masE_>G8l&?NtHQ<-#dwAK z!vm5&r#;5AQS6PKa;lcTmKYN3>VbIQ`)huZVM`r6c?GAH{dS#!>|E!GkOeFTd=ru2>I}EKjA&$q z%xpkX5suP3^PWh>VWjCxZmK*v7&h(sUtdBEVuI6bl6YzBmBoB6V)T`kMVE@4aS6aF z86fccJMpzi!(ghTLJno7A33 zgQGtd{Bg2_^(g~5@2KCC-VJz4O891)H4=e6JZn)B@dWImJnGs1TB&r7@V#&gnX6?lI@=mHXl;*yr>fV2uhN1;o9#F_zJ-|3P<@x9M z`)hr+qj6-Li;&Fwfgr9A94|OOS{c=LmUqQkNQk)pB_sjJ-~coCrQ7x;veO03)5}{O zeIz_#`G^Ys?jlpviHl{!XOgfO@vB8uUgg|1lpB)Tp0#`o{{TN6Bbu6^FeF^z(Pi!= zQZdUveHlN=t5xoTm^9MEBoasxE(4Pg7b+ba90)njfN*pxxKmBEDyWSl4;88wRGlW| zeQ8|(0AshY#s_}>+F-ZVK5(!IerE)QkYr;R+7BK5DGyTV+4Rd}CxYv4+fS5dX#*gR z{{WxTw<+%#vD1pm2P%>`r#(N@93`8R2g_ zc@T5R@9HS}n~{?FdTVVHvfR=?ot|hglqp21h_r?>+;5je|3xlX{K1Hj<$ef!hqhpDu4TbX25 zW_B_nsR#i(h#1HB(^($dywcFCHNt|bnb>-<#|Vvye=3-9>N|M$AbHdsMV_W;-DZWO zcJz@XCNzp(L$(4rC|k)Pj-vX1)HyG=is+m}6ULX1 z=3JR@=&26a`3p^F?SSrqkjCDgW1o4;Cq3M5pPwr)K?fOD>$`Tm6euKrZIp*zwSGd2*@0> zone~Ux9)XDDQ}c;o&sf-7`|>c3`i|B?XAfcNoF)HFQ`KoQ0#ML<-!P z1ONc19KN3&y@sR>6txWDJw#SkP^}&Tq-OTaw}b@d#2ZW))k zZa^IJ0ZHV4OzN_g8;#Bs4XM<0)Du!WS(&wn4&I6V0^#K(K6+^HuWVdHB8b9ZXo)J z1d}EYlHQnXU<@8WV?gT8r)({y3RN4lbyq3XO)M`gFvAKs$|ExXBU~`&pM3Z2tY_hx z*Lk9(TI;pKdD>9ba~gs z-yr4ByBwDLjc)LgLaiq551_{%od%co{nL382yg}&iDQ%Y#Y0-U%5PA~EuLFs&?^*q z2QX#9A5KRqk%J-6@hYV{=OIn7(Psq@I%G5@cf1GB?{9C%&5BQqNOR0@G5@Sr}J6 zqiGO#3fUe2?~PWkTbK5HGYDwwsw!1ZQl6Se7#_s&;&J{O(;~@+V=94<;m8F0pRGns z1~|M&Yne8&%WS~OHOzg@(w*mZnyIQ#Q+-^cQ4oq5m}G&1asrRb&%VEGJsIB3Vr!k& zrk!YIr)Hw3G0yUz9+NPHaaBG@b^v|Oti3^psr$EfyH(UBHL@0(Dp6d;aEuEDB~D8W zf%Nw|{ItOAioM%os+Z7~YV%U6)iu?$#s#GayjSInq`ateg#-Y5Wb4TRU--r9 zh&-{T3uLwe<37~Ato$^%RGRbVQcpNx08klJ^MG^d>?s3_{`^+WM{%i17DPeyelpqd z9}jQL_Rh2>+t%m`+$q|kMW~n{a26$2OoCWtfj&Px4Ia1cC9a;Vo0Uux&ebYtrHYWn zg-`)ZuhBAt-;l?A_t4YUxo!HGX|0jG)T`=+Ur*CX2}6L&to~SeKWz}Tym?~{4pVRk zVLMRq&Itmli`@?6O`dq7VpR?w1O-1*Dz$T4e9KOKNadB0M;7|<`N78%#~Ib41G?^) z6K)RL((`Z&p(Qt{avCkY$3#^`` zi!^N!P>zxXJjft@E;2wIj-~GN+^A^jX1Gz7j(FANh(xN3k;S+qj0}<-9_)oidmUYN zCC+86b+bcNGs#r2&T8Dq1gM-?q-)$4Rmzir+d4YXZ3`vR25Xh1NmPv-jWqE~DU*rf zFx){PW3rCQJ-zfDEhN+>8%`N=a#Vl`^x~ZK-3nQ>#D*)`OQ_l%m&&~440`d!P-yne z6-~9M>f@)LkF=r|rIZ&^Fpkg6zp3YtJ&rsbPgm?6n|`XrU5cJ?zq?TJa#ad>7ErkF z+sMHhFq&#|u&jXbY?Ua5P!H-K#T4jdPHB*EGCZHc zdz||MPN%PzHoDQrOd?2JDP=0D^fH{DBOU($J#K?dAzoFwXrvv2k1_uMYq+hp(?h4C zLlv^RWRUDh*h$I8YnK)MIo7<`1^g1x^Y>yW2dHciDj!R3P%dOyiN!TLlqbb z1`p?<+32Riu+~)9(_5fPS{E{Ngh(Vz5ZR1|C(qN4{rhSkgCvBd+Pul!Fv7?i-*cR6JvAKE8GE4N1|7Jf7~N`4PdERfX3g_fDSGJ_jOmkfIq z$iNyC)^r-()apNwxlvVH=_06#pi`-n(PvgFRw9eUsROwn5u9sGR<_M>pqV3px0sQ+ zlv59gk-`GDcCQ)ruiGEQcHFwsNkwYL;;V^TKSk)7lbInD1CX);$GQ7=@v6k#4Y>6t z>?=2gOctm`JaWxxp@n?`>Ns!sz9_APIV+L}*yzt`=>3Og88-Ei#l9e_QfRWxP?+ZZ zh;IzUVD<-EF>USlP9#{Wt7Z`>S7_sIa=JES4i%Il{aFXTM}w*IT?+|6$g&Uu!bdrA z{X5XuBe=|lS;ML1akP)8)}ilRG})ak+R)Qk<&vsc<&1hWD3Q;o$B(UrQI0Nn=eKWt z5-4fzQ(NGQ+#bgp#)~kinTbXX$)bt=rHKje^m6a^)n@0iYp*pe9Ua1YrGaGi)>>wz z^w~gTmOPQvmLn$_9tMdQUG=x^uu{QNAqS2nmO{Z=U;rzI;uS#{P*33=bQa;S<+*uF z10lf-Nj?2BLnG4}HJNUKS1%ff$sdFaf)C#`N8EdkdtTZQ!~_%*Q@TvTq?DMPDR5k5 zXV~{Yu7j7Fd!^p#NU#dI>Oa#;)iWw7gcF7lFgXPG?~l3F`)l5hr4MhN1y1C* zywS*BS!Ic;Oil|1B|scoixZ6GkOq8eQ>UFTux(G2tgF6KEHO%xyb2?YW^n$Zhl!oJ z44i?2K{)ZKv0lb**iDc@Dv6PhM{}QQSGv5heL>iTw!R_vca#yjKfg-3ZcHe+(2M;yf!)mJ4(S3FWau-Df%^UWm4qB$_6sPh5F zbKaq%-qg{4&#vJiYDi{^amRxzFak663=rAv`r}(y8vC`<30|6>QAE*%`CMbwjYp{Y zXvq59_rN1K_t1XdStSiK(x_!?kKD2z)Z2m2V>l7 zm3Q3nnuw;BiJehaHd$i>)XZ`>8GTHGynCLj^?h)PRvvNCie^ zB!md4SBU@;20_u?Epsc#WGu*_#}Oos3CUo6`%+AOORP(OYjbpFmhB`A0LT*X01N@- z(}THsfm*cnRrhLIc&RCpIVHD5M9As@kb1}u7Cp%%fseM7{-JMsUs3ON`uYl|N@~Lt zl<7u&3Rd}c2#D-XSxW*qsK+e!z|j&1+cv^lq)j8d4-&kxNU}#fL-0tleMn;@5D(Hp z$F{s}%cZAg?Yo7JUKKIBF^Za4mZ7Rk{_!}fsp9_tQNaVYJ8EW~s5B;dq-%*TB%64Q z3@8kxNdxF<>Q14TUbeVN?;hUerepGemJ5YAAe?ibPfFU_8?L`?ZCm?Sfk$4Zj+T<4 z$Ek#snnoa;lAL27PJ3u>`|9mOahlp5h+E`n-D%{B5hZB{Z%#x|LypB;IX(3wZr+tq z)J(Lo%S|#=zzj7K0^~`|l#l2`k&J!Lah*{&Elr1UR@KW@N|e&m#n$O>6&hDr!w1v;^B)gm;;3X;QeZ)l3UBq1SpU)BS(eF198qyeSIjgU2(Kt zY)}+Fq{2szrNT!XsZQg(a;gE$q576gWc~FIWT#6S8_grMlR-3TJP@`SQ5c6tNALA7 zf)9LWRj!%YBit3WH*(^Vl7c1`buv2^M>$VTl#p5bc2nEI{IpxLTVA5eUtKNI*F{Mz z$?|m7&*`x-k|S@RA5C9A4mA%@@U-`u*ho*938Q@XbCSJ|XbjqI^If4UiGrUaVMr_7 z^Yx*<;?-Myx_$GcJrjL`}bnMQ|3O+>Kp;Yf%ZC{q`B>g zsppw!<9fQ5lZ8C!>+?+`!PCRsAXhhP~Q~?$BvjHflC#Mk zBU~u{%N``F9^Q2wyLKHVfLQ@0GTO~ydRPT*1m3Gr8CqE7SjRKy$xulLmOu=|0Ci8E z`9p2r_R6v(hMGH#IrPepQ}=SIEg=9FKXz?x?+&5XRMg&Xf~9>KC6y?hk1#3aKC$2l z^TdFD+Vx=6{Ci^?7LAY@1_%zsZ3pkqHM#YjHcKm|c*&65{_h!VgXSmD_pANWZr0y_ zX4|e1)KgPQPGqQ*b_jB6Bsn9C2JD@Vdv?@w-EAAj(kC=&9R$rBbn4<(bcPl&A|gi0 zta$hbBatT^v#4t}^>w6slr?Ph2^fZ=nV3o>B||Z8Ss`O5u^q;I>UVF@S}SZ6l~7d* zsqOVC6&x@lg;j}Ji+~T;$S4^gE>FIPyi?nvnKG`90+rq6W68+(JXSE>MRGB0n31uUm^mk{JAmWrHcHY4azahKQ6=%Y-`oU>=V<*_14-~H1#q=43%;sL|!%kzo3}n34YEy4{@)5YF{L{ zo-~+bgMvR2Dx)6kAoD9t0Qh)930>hJ!omOsAQ$AlA^w^5hP>Mn*{#s zucs(D#?z-6eYVo(wP-UCew%R%gHf_7zQ~ zN~XCPX|1Ht(p1AF(mb#9$P{F&Hb4yD*S@r>w%x`p#-P(lQ5{OR`N)%$PPhe?n0ECC zZ{wn^dt2{&W@?wD5WmZ*YDZScm~oHljy@nh4&ZiHd`cSinD5oqaB?J+est23!V=$K3fxeCD9(eHAt3>RY(XOanBa5rg)}wMK0_ zRnF5-=utr&2`uPp9#VZ4%CevZLo%l!++)r&qV0-H%u>k(Le)u0O-<@F;Y*}qVf7wI zxe7cn#yp<-v)e4T_*}80SZYM?#ute}Wh8)c7;KUUf3eXPgLVs?lTcJDM@2fas!tO< zl1GAH0Z8OX?Z>$ubT-1)(^t7Gb19BV50OIdCA;~FJONz|)BP5 zD;C(e+V3cN#IUSKk2xipFy7%I%uQDQCJ?o4q%zlMYP+B%D1#+mH;|@T0enIw8+yxN?@DL>^*3kaE%I$Rh=DoMh@@ zrn-7O{$4To1iw$!jCMJ|$sYdzW9_epP1#K|NplwRBoZhiJ-u5sC7_B=#;DxnXWoZ% zbmM4LymP@p>6m0mqH?Vfu37d?Ppy_%lS7pKITDiIXC!~p!CFPw}J zqsDYvr?0IrOC%AWNFl=_SQJJKVGr)eURUkyQWhAMlx4r$ zRCTjN*Nbg2qiIqqS^YTLrQ~7>LCghSSjpl~k2)MdPtuRubrjSV`=oME)bgp0oh6ze z4{*+6W5IiN0OKCoWv(q1_B2|$NNQF-LNQSqmO|@>3J!exkUSk%?b{=6*(9lwjT(+g z$$8QxDjAV@a^koc9z1?p33Z{(b1@;-L?gV4GnyZJq^;Db_<&)v=ZHvgk4*h)vuNGB zCcYWshS^;sz~E0J!U~e(JUM z1|O%kwpnSnaLo_RLvHGXg$o#6pz*jL?yY~a=9)AYBHndVjh-J0J-{_XsQ7)`ws=}Q zB>1EOgtU@};KiSoJxIWjd;Rh=}(TQ>+&s#VUG_Bw)r*0L#cLga-w& z^?Ama@n0P>#=>=0W*nqtDUYWlkbUw$F5R`|Y0^rUm8UHjSi+!HWJUHTBk+&Ee?D|_ zZk^JkoXR5eupzK`^LqX3T4>r@IB%7Q12`TS$3COlfOMS@w@+=JH>+=6cS9M9B~MF- zVxTcNQ}2yIMbL^^3qeyatpSv(Ldu8JR$Togu1;~2{WN&4sG?cmdZc)abqL{+g2%&& zToRv|?hlt5ZtMvLcep>Lj5!oP&dm{%1}tMW)|TC?+t)`C;5Eh`=5FHW|hV@G+sL=IMsp zz6n|yIE8R@=PIK5z@{9K(T4jE%;Qimx?6ZuM?_tAc3$UYa$KvrbW1caJz_50l*fU!5ay^wRxoMtQDPvc~a<72}z`ITe+%vPbnU zLX2Y_`)DD$EnP&hLrW!+%W`=sWcBKvZ%HL_zz1*}496dUW5;o=>lO9H3ut$Xf%x~i zJbGs}I_FW#Oh5Emfj^a~WZpN$Icywigb~ z?!5RK+~A$0XE`9AJe(oH$e5IR_a%@$PjIVJtE+Qw+gR zBbt%mST0Xx-ei*9Cz*qzhW`%q1NZ> z4&B>M*6V`Q8E1r*byB8BkmJ(@SC?Vru794ccL%vqFhNSs$(OP^hgHv#tj9PfzhT&o zN6QVgRm)h^(X8>O2B`GaWKe#f74e*R{QK%0``5~>6#C?PR(LLit|@KYmg>EYbBgtB znx$=|tfrnvsP!Zfj%gn$1LNxc&H-VOgPj9w`j6Fp*IP`--9;|wmX_SM zsbkxwogn#^lr1|Xsuz?|!ovjQcVnNj<3Sc;X z+s2HN(!EtW)l@@J%#0J|;;D32_n#{AfLZ&1n>7vzZDJI#)f)o z@lPdUN9$sofN>H8<@9BMA#wapG!FTKLgE%&Mt^qf-d)3<-qg3P>2cm#&Lc%Y;GNi9 zI}yf729nE_pU{Sm%6%Fd`Z}lOI!z(SU?M9aEiWc4nK;7d+fAQLwk@*PXDM{Nda+eW z>$I}MiakLoBAz5?Vih;Z`|3AtbbM~QitB|1&Lni23W;6-6_M~i<6IR~$YudM zs|Z`u?1!5L$OGI1^>^>6Pkk-K2=5^9h%VuijE;E6 z)|NU~Mg5+Sd3zjDh9t%6aqWeoG`0#5g09PCq>`n`m8)tc%u<1n(MVj%%rJ5W00+Oe zusjr(mZ+kwyHUl!FgD6ZMg>VK#g<@S>Ie9Z3~bjMrMj-RS&TK5RiC|%ia5P_spn-J zjEWvn={R2f`Q+pcS!l0YimDkUr>3K@(n!2kQ%an{4U8hOKWyQX8s8P-Jcxv483TEF zTz*w$z|sbcC9{CQuvP3p^#ovZSEFXIS?y^xy@JHtpVWDTZzmu@Ws$M&U={URA8X98$syC#y1%eg^NgYTdzh+#99yPVKq_|sUrKGAf)s$?Xyt#3U)RIA! z9=a7%o}Q#aC%|*@m!6k#caskkqosL-8Y$@CpV&KH1fR7lwuijZH#F>M+T02Xl<} z_xl5#Y!+IYfEgu33z1Mt7~PL$Soq|q1mnh_tFD%cLk%gNC9Gdeya_Wa1t&RvCyI~H z$sROC11qvZ%!pN7PzBm7ScT^9P7V1GyxEPi$(vMAdU#Bxxs6O2`^GqgUpvgn~h1#gz8P(mv-?W(8?E z6yn{=lk@;s`;{NhUwDqgwQK{{vaM*AIi4zYJP16!P^!*6j^Oql-MgJtEACsWqN0vU zY8rT`(oR+Wq{Zb^8s%dikOP)*NICsAZ7U>HY)lhW0#pd%C>W?6^UaiZ$KTGY^p&*I zT%@C&UYe+Kk_3@h8Dl-mqhyC5_8=UO%`dhtnC_e1A|~#tp^Wi$Xl?5wum>D}c~O9+aqOo*eGzTFCD~T`R7z?t(Y8`b zk}61WIEMmmKz2UZAC|7ST1n)inm#hQXxTuG%tV$L7*hC&caFgOG6 zS1T6atg=?#sV<_1Dr!j~G@=Ydivy{_@s8{dVtak{Ro;8zipeyW`(gEEo{CF&Ms$i1 zByuY(hH}C%fI0euXeo7yg{@U}7HF#;TE$6(^8E<>2<|w^mf}xif_wgYuUIYpORb}- zTXRwxm#TV-iV9-LWfL_sf;T{GD=-kK1py7jAI8w>&H$v4Zga%nv#O1mabK4 z9+*an89=4g&Ps;xOBEz!d+M!h>Hh1f=Wn5{X)DMJRRj*?Op>1II_ zcJdpbufOoJmm`l+=swj^+&5HS>vLPYY*+?TF_H#29Amy{zf-?nvO0L`t`xG?(^3j{ zfntz6!?*$7ZV1Xd@oru;KbA@E63A>;#?W%z3zURI> z+pYG>!5nJw%RF$*(Fa*MGAp=IpWYP*?Vj2sZB2`~jeWw*zO_YM5rg|SmDLgA;-$G6 z00gftB#(b>eA+@=?vf@gG=vfveAv!7{{YUV+w|{RYOCQ3Sr8(rd1Mp8yFoz$+fuRyLe&R_OluOb3}Zf_BLsa)NXBq=A8y+F zp01{rjyY+jilJtbGSIn!;zQgz$r<9LAEk4ggRLynK+NVmZO9}aJ_sD=pVFaS^lwyY z%49J+-H_fSgAe6%gN}2aeJEpS-W2y5nz~AOB=jPq%t7YKkCI|Zoq-^^B!xK0&IUDk zy;!z<_NYEWt!X8epVoNgXykb3mGX!OEOxJCWw6jzExc1vWtr-$5gC>l zGua!NSM=EDI1EROY6hx`<49?xy~^)SCQ~(JDVk`&9h8>t%Gf`IWPP;++($dCmc`OA z#G;nul^M=Eb3=5^D^k-G$1Gknj0=;rVL9wDe_YnPRl~P-^<5OLKdCTimFe*jNRQOZ z>Pp39X}|-y`d7A~V55ev=S@XDlA1WyDJL?Dss45kO*!*Pi@GrFjHt$Z<3*e9&$M16 zqn7KHr=h5)nl=%SMpDbdC5dvX*;AaIN?mR{XZEcv1kkciEU`&CtVSscIZ&9EB1U8Xlibxo?C7*H1;n|}3J+5J74FV%zA zX0;h5t*ff63?+shD)LCPL^!jLE7Q!O%@*o`NR&?05ON|Nnipd2j z<%tC}u_~ZERn&lg5k5Z%#x))-X71YQ+0aWMAxo=__U^+JLr&=@MGmp4xGc>nbI2`& z!2GFY+uJ%D&8ia>EqwJYBs9^(Q70J-N%g%;u~CHqdmLbXda_x%d1BsCRZ~x8L2O#4 z6QPVSuc%1)XD#%QrMm!ep8901eJHll%^jke>sJi|(Ta+xE1TMHqXUS5C7|e^A@e@YbWyT3O z1aLj+hfV1#Xs)DUf;jv@Sq3oMMn@-}DIeUw4n~`9)I&v3)b!M_DT)+xDN>jQ6>J`E z-O8>&Uce0scMnUqePx*>TUA3tNeoh$s^^X$S(%%ZYxN^WK=0qN81P2A(|fc%d=+Um zX^zTDD!=yC1=UqeONla~()wbb@;oH`gjll#h zwD!B)DNUxjDw@Tbco`~^F_m=n8zj2FAQT?tp7_)){_96UxK=W%@kv6G(bYn{sj30Y ztQlD4MFhUWw7YPh}V z(|#UHe+hpGjS!X~fq~n;ao(ugqMkRWpubx2>%4xO&K#`$0l53Bz7QsomaN? zQpta#sivNJ>11P1a7bfe1YVjBC1aF~5uZ&Vumo%IZp{qcxIG2dO1YE|Cz0 zT}yhWz*Z^`AUk*Qq8fd^uiLwcgQRolZw zB~0=fo^KSaY1M!y)8pW%1a`-RtRtFKxVlD!y9EV<9?l0C{S9RfodQ}cw{i^3m=1r3 zaq}?S>&8YxwztX*I5~RqS zXGUL3va*jzg3P_~$a@`5?p?)e-ImH5V5e$Ydg^qNcBhRNX=O%c5uVGBs1jS>RE@)W zvRmt=OLaTFbu~<}Qq?QDS)oJ-K?IOoHhY1L91j|e0^Cm&ffiU~khv;wKp%(l2il~| zYj0xaXy=M}VO0Q-$i(--$8*nmV7G;2JF?#IEkKHbFtOK|rj0lxp<5-1z~rYb*q?6Q z^$%Usc-qkoeGO!jvoh8!Jc7sReiE5*_)-`!0F#m1OU;Vx)YiAJu2UrPO~g}ApF}DE zs^=#RzzlcspE@?dyG_c#eHWSP5XtF8j2H33P)3|HfXo2kd>?HHlGjkupo%+ba~jCN zl9>dbOyqvGVdy z9OJlBJ;$98?kzxSX=-5oP8fnl4tZ0KJ%w1UyEAXqTxu)m;)*%ssaaTXX#4t^CBrcVn6619 zBx<3!tWQfvJd|=4risx(j&$T%NF0g8e~5O@Nc^>@Zo6AzqIoN4sAdqeQ3#?ADkN1T zk5J(iMls2V2iWMDv}3hH1j2e#BvQYs@x>Ym%9RI$i5MbwIU#a;_BuUgFRrJyX-skN zEEZNd4Yz;@9ExeNy^{6_o56}5!0m7V2OM%eD;=k1?DY~<-uE2wy-^hkw6n9Yh0m&r z=mY*C__9Av+A{38cAU>pw%Q3Pk|}sYFbcU4f1?Pa&qyG2!6Y7rSn;J{MSWA3U>KId01onr=>YaQ#u zY0roFL1!+c%9A;Ye737BvS1gWDfZ>DyaS*e!Nwj{>nVT(r(|?fJ95OLzO~sZ&u)QB^5|Pf>#o z93&WK1D**7xIPFz+IO{z<|M?5fO;a5arDXWSt;>3Bz{%DTXM0}&r3^F#7OcVN01m& zp4lLU?0)_A9~Dee2_%gqG~)^*QQ1_v8Nu<7zM*G{B&G{hA1aPW{39U#@Sf_b%y3RI z-?7&7Q_WLCl<5hLM5UO_p#2#P0QS#s(_0CVkET6^NC7~{din0MM*fuy}U}`SuNl!@ts31oOPGQxDkcqJBIKjZirAHdD zCD)UVYZr330RBR?C}>bFBgZg#!|E`TgEk2vev^PlZ}HZ|_E_aqX(AHL7#~gDSGdU~ zhI^d(1IBfZl9skPWRf(9BFr75^_Dc zP|t58wl$lwBu5Gf_N)|0WCJG^;(BPOu3Bb=;ygiST$uYe6;aC>BiQ}5B}YdzQnJjE zkm^I36au*e1F-s!ZvFdetqm=F*hQLXq72HMT&T};^&ZRyJoxdcxaF1_g1{a~IG1ir zpHR*-k@xO>^{r^&B>GIFbE)V^o@bm0dyV zM^S!%P|EF2(W58{B6@sWD`XMmH@1mW&m@qT=-nfzV2aM_&V*<15D3BV*!yc@2dJEr zQA%Z#xOPxGj@^JcKgUt0(=0Eg5=fbFF_1{(z78u>DFY4%>CIIjwbex$O(drSn2fO` zfKEb#+W>g`A8mTAhN6}VgGEfOP~nV`@?s=)L4tBH4}p`b1MT`KL6)kSsg>M zJ%J=)i!bY~1B*l}Eq!15NgS}`R5vczR`cVqAAfyF3mv!vZUXWfIlv!!@U}qq9+gos z1XydT9DL%L7==-k58Kmxc2a;2_#Qt!PRBqeM_D6TTu#AR)tA%u1q*V)?0f$JO;oOZ zMccN@=Y&?q^GhibdVFRPf$Tuf629Gm)HRcIS5nnS1pAIDqm>vWe=e&m<|Qs%g>nf=H)>Dyx7LNVqu3 z@81XQt*NXZClVzhbCeD&tV;mAK*K9%iTbmTKdz*zZ?r8^kp~U)A4Gprx|s%Yze&i? z9Ax(JJ@qUkJgJh!OO}+h8T8a;gB5Z3RlHzedF`vDR1J=3WRD{fN5M>?ynuUgDhG^fe!41` zsa{l!*o}R!w7uRu`qLwJKVw>3S8&|7EhMs3xJ+>fv1BS1iDbwOPkgt&d}zlFKdBVx z(#S%L9FTc;$JLSFIoI0zQf>bL0sN{wpMZVq1QgLlB=UVsODd39;{|zm81MP(dWy$K zHFp=@`Jyd;9C{eW@SC`c{*{HMpBf#WmO0dSGf7iV45B#fC`F+qaJz znYvi0DCvVnB+ht@xxnq5f#W0ZueJ8Dk~s1BSM;x=ciKG1)7F*C_fT)N+mR_sQ%fB! z38{?B8Fn%@2X-eT8STd(o~Grw&vAy;SXMZyYH8X@rHuzBXoz(DT)ZFg*V_9^(v#!J zJvV=SM`vQq$^3rwMB01C>$okF%~Fslj(S+QB9N>mK+Ic_B%c2Orizr+Q%6%z06$9s z$oB;2m)o~&cGuebMKtziQb{E9-lW7yizMXcuvfa$Q8bZ77?3RFFkBE$$qby}5P+v2r*MBU-(PF(6oC-fLzM^1?NU}W{ovX$u#98V6=T|4M$vAy3w(aF z(?cj&!^&B>;C&^$k=w?u5ycHDiDQjIhAOL$zyrsy_VM2y`uksNew2u?E))*_pIXfo zV}>MByompKN3^|ps^fB5IYTNvHt)(bAT9yb}RJduue`fpBnpL zXv+Wq$Gv>K_xGU|`>3q6(!JuAs#xa}!yJ%u1_@W6{9+O3{b7TTeGm3!RZM%TD1A;* z$}6SrtCVY+gjBXwF+ou4TqK6mvTpF&u|ZIeXq3Uf6XuZKh~OM?tj*+1+tPl^oiWE zmlW)F~6xg4qNK_8~5*9$$jcnZ3EoCzdr1X3O&1&L5FPuubxj=tC00jznv zr1gzxx#ep<3uLr+UbRdHBj z`J|wb1_%*OV$N765O7azeXq4$ENSDh+AOx$AUiAXEH+D*^}|$i{nubFF>pRVcB=RUa7sUY=Q2BvHV(GagQI-=AVKeCzFf ztvAZMZ#W-;eJCu<%`&MZuN-=MQrSaoirHgGo!+r4D_y5rt}+5;B@O@zFb9F-zKc6w zZP{)RQ&Z1L6H|nr_ay<33g-*Jf}njq0LH%8+N-UJI@F+^JXYiL6hEh7g>F=YP)rY! z0RGXc&f&FMs5ZU1qoakt&;3BIyp>O^P84_pu${l8Zrhr2BP=Hu9}m0 zQcDqa6V#2G6Pl%ahT)P9DFb5~TzSr7av|^T)rAY+Nxg(7Fb4cA; z3@@Ta%!){wd=dd8f!cyevTZesLv>kdY3e7MN|#D$eF%h+fC*HL00Z&M4;k@|L3JM2 zLANbxD5>E@ud~%jI(jjvQdFwA;q{S9Unh;_vT3w9p>XV8b9Q;2v?!RQ8Q?TWr>Q zg2f!QrW`EN@?wD0zhnS_HE_REQo(kmwk#3+u@6wVP^^r}A0<+l`blC=d*q#cue3i> zC-#(__KsYAFnF!x57@88QEWTMbzJuy9Wc7o(^C4AkC&!@P9h^Y8D8M$J@e;Qnd%iP zuMHG2N5(2PMOFG$o=0NJ2{lHEdpz7m{ckH#o&lPs+Q0_<@zgM2`rdQjXV{yhksj#+e>op$Nin=j3 zttBZ9&Qjw5#(09+AROR;dyd+NxkTG}r>ufUl4u1#qw0}_{mRHOz$yAq;rnA>YwZKo z5f<7K6ar-jIQrGwu_Cm9B834{u*av;o2xCR)%!UlG;kRU;iPE8J7jXpG44*h)mkm} zdy+3+FHk{4m;(}hGc)mGpJRm>BgVeh+P>ZhMw4hfHNj|!8%HE$(@KD18TwU1!CzN% z+mzB($kRxY$p zGwBwL#FAl5l5$TKxjPTFZdcSANNeg+G&9qY!PpXT-N^IUAAD-N`$|`!w^W$p=T%Ei z(uL%s_xu9|DnSG4?cZN(?GzoBvOk5s^>dA7lA0G;o;J*p{ULBdj@b+d&O2xAs#NHe zF~wHk`m+UTKxPQvPjFW_?hZ5O8v9>sQS3kU?OzTnUd3{&m|V*_;{=tlBIMwR=VS%4 zdz=gt@2}f+(yP*^nMheAf)K=K!0p>UGmiMz+WSzSx_zo(0EVx07g~z+nm1KcN|&br z3lH6_X&~>M=PX8k+MB5LYN|x-GpvR=BPDTy6b8uz9_Qa*Ywck}$r}dFSHckNpJ^bXJ{{XJGE$FqEI;t1#2q?g>X3H?of8(#U_PuYy zpPhQ3Wxp!fOMEo1B0^agAb>H2B=YPrk2=~j%MI8-j6#HPPrG3d_xA6e`uksMMYjq* z=CGf?=~6FQEeuo17*fjQFCmL#r}>1qS3+$lYH4GNRYdihFU|O_ zNd#mZ`6pj%?I7xq!kV~cMGQg700MaRp&FEN_;Yzzvif~RUahuEPW7_VM|P!2enBOy zfud%oKCVjShzbl~{j;Ms+Ok1oqU0(ns=Z!QFU`zmF_NmqV{?WJl1>Rd&c4^$XV5@0 zLP#0e-`2d^qGccqpI^$al$Ddz$mq-hsB)n|82Y&2e*vtulglM#I1ErVD09S+a$CQD TI{RN~)q4-P{`!!=j935JmEGzb literal 0 HcmV?d00001 diff --git a/image/2025-12-26/0694e264-b742-7662-8000-a54ed4fd45a6/darak-2_000.jpg b/image/2025-12-26/0694e264-b742-7662-8000-a54ed4fd45a6/darak-2_000.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7ba93ea22b944f2f57d6dcd323af6d9daa0822f9 GIT binary patch literal 96737 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%0DZa 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 U&3Ugi^?hDz&3Ugi^?hIe*=mOZhX4Qo literal 0 HcmV?d00001 diff --git a/image/2025-12-26/0694e26a-21aa-7eb1-8000-04a355390a04/darak-1_000.jpg b/image/2025-12-26/0694e26a-21aa-7eb1-8000-04a355390a04/darak-1_000.jpg new file mode 100644 index 0000000000000000000000000000000000000000..05462d6f14cc6cf89c60a81f5dfc22b83e0034ec GIT binary patch literal 195312 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%0DF1Y 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 z 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 TI{RN~)q4-P{`!!=j935JmEGzb literal 0 HcmV?d00001 diff --git a/image/2025-12-26/0694e26a-21aa-7eb1-8000-04a355390a04/darak-2_000.jpg b/image/2025-12-26/0694e26a-21aa-7eb1-8000-04a355390a04/darak-2_000.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7ba93ea22b944f2f57d6dcd323af6d9daa0822f9 GIT binary patch literal 96737 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%0DZa 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 U&3Ugi^?hDz&3Ugi^?hIe*=mOZhX4Qo literal 0 HcmV?d00001 diff --git a/main.py b/main.py index 828f60f..5a149e6 100644 --- a/main.py +++ b/main.py @@ -1,54 +1,54 @@ -from fastapi import FastAPI -from fastapi.middleware.cors import CORSMiddleware -from fastapi.staticfiles import StaticFiles -from scalar_fastapi import get_scalar_api_reference - -from app.admin_manager import init_admin -from app.core.common import lifespan -from app.database.session import engine -from app.home.api.routers.v1.home import router as home_router -from app.lyric.api.routers.v1.lyric import router as lyric_router -from app.song.api.routers.v1.song import router as song_router -from app.video.api.routers.v1.video import router as video_router -from app.utils.cors import CustomCORSMiddleware -from config import prj_settings - -app = FastAPI( - title=prj_settings.PROJECT_NAME, - version=prj_settings.VERSION, - description=prj_settings.DESCRIPTION, - lifespan=lifespan, - docs_url=None, # 기본 Swagger UI 비활성화 - redoc_url=None, # 기본 ReDoc 비활성화 -) - -init_admin(app, engine) - -custom_cors_middleware = CustomCORSMiddleware(app) -custom_cors_middleware.configure_cors() - -app.mount("/static", StaticFiles(directory="static"), name="static") -app.mount("/media", StaticFiles(directory="media"), name="media") - -app.add_middleware( - CORSMiddleware, - allow_origins=["*"], - allow_methods=["*"], - allow_headers=["*"], - allow_credentials=True, - max_age=-1, -) - - -@app.get("/docs", include_in_schema=False) -def get_scalar_docs(): - return get_scalar_api_reference( - openapi_url=app.openapi_url, - title="Scalar API", - ) - - -app.include_router(home_router) -app.include_router(lyric_router) # Lyric API 라우터 추가 -app.include_router(song_router) # Song API 라우터 추가 -app.include_router(video_router) # Video API 라우터 추가 +from fastapi import FastAPI +from fastapi.middleware.cors import CORSMiddleware +from fastapi.staticfiles import StaticFiles +from scalar_fastapi import get_scalar_api_reference + +from app.admin_manager import init_admin +from app.core.common import lifespan +from app.database.session import engine +from app.home.api.routers.v1.home import router as home_router +from app.lyric.api.routers.v1.lyric import router as lyric_router +from app.song.api.routers.v1.song import router as song_router +from app.video.api.routers.v1.video import router as video_router +from app.utils.cors import CustomCORSMiddleware +from config import prj_settings + +app = FastAPI( + title=prj_settings.PROJECT_NAME, + version=prj_settings.VERSION, + description=prj_settings.DESCRIPTION, + lifespan=lifespan, + docs_url=None, # 기본 Swagger UI 비활성화 + redoc_url=None, # 기본 ReDoc 비활성화 +) + +init_admin(app, engine) + +custom_cors_middleware = CustomCORSMiddleware(app) +custom_cors_middleware.configure_cors() + +app.mount("/static", StaticFiles(directory="static"), name="static") +app.mount("/media", StaticFiles(directory="media"), name="media") + +app.add_middleware( + CORSMiddleware, + allow_origins=["*"], + allow_methods=["*"], + allow_headers=["*"], + allow_credentials=True, + max_age=-1, +) + + +@app.get("/docs", include_in_schema=False) +def get_scalar_docs(): + return get_scalar_api_reference( + openapi_url=app.openapi_url, + title="Scalar API", + ) + + +app.include_router(home_router) +app.include_router(lyric_router) # Lyric API 라우터 추가 +app.include_router(song_router) # Song API 라우터 추가 +app.include_router(video_router) # Video API 라우터 추가 diff --git a/poc/creatomate/creatomate.py b/poc/creatomate/creatomate.py index f48f11b..efade26 100644 --- a/poc/creatomate/creatomate.py +++ b/poc/creatomate/creatomate.py @@ -1,226 +1,226 @@ -import copy - -import requests - -CREATOMATE_API_KEY = "df9e4382d7e84fe790bf8a2168152be195d5a3568524ceb66ed989a2dea809f7d3065d6803b2e3dd9d02b5e5ec1c9823" -# ACCOUNT_URL = "https://ado2mediastoragepublic.blob.core.windows.net/ado2-media-public-access/ado2-media-original/" -# Creatomate 템플릿 정보 전부 가져오기 - - -class Creatomate: - base_url: str = "https://api.creatomate.com" - - def __init__(self, api_key): - self.api_key = api_key - - def get_all_templates_data(self) -> dict: - url = Creatomate.base_url + "/v1/templates" - headers = { - "Content-Type": "application/json", - "Authorization": f"Bearer {self.api_key}", - } - response = requests.get(url, headers=headers) - return response.json() - - # Creatomate 템플릿 ID 로부터 해당 템플릿 정보 가져오기 - def get_one_template_data(self, template_id: str) -> dict: - url = Creatomate.base_url + f"/v1/templates/{template_id}" - headers = { - "Content-Type": "application/json", - "Authorization": f"Bearer {self.api_key}", - } - response = requests.get(url, headers=headers) - return response.json() - - # 템플릿 정보 파싱하여 리소스 이름 추출하기 - def parse_template_component_name(self, template_source: dict) -> dict: - def recursive_parse_component(element: dict) -> dict: - if "name" in element: - result_element_name_type = {element["name"]: element["type"]} - else: - result_element_name_type = {} - - if element["type"] == "composition": - minor_component_list = [ - recursive_parse_component(minor) for minor in element["elements"] - ] - for minor_component in minor_component_list: ## WARNING : Same name component should shroud other component. be aware - result_element_name_type.update(minor_component) - - return result_element_name_type - - result = {} - for result_element_dict in [ - recursive_parse_component(component) for component in template_source - ]: - result.update(result_element_dict) - - return result - - # 템플릿 정보 이미지/가사/음악 리소스와 매핑하기 - # 이미지는 순차적으로 집어넣기 - # 가사는 개행마다 한 텍스트 삽입 - # Template에 audio-music 항목이 있어야 함. (추가된 템플릿 Cafe뿐임) - def template_connect_resource_blackbox( - self, template_id: str, image_url_list: list[str], lyric: str, music_url: str - ) -> dict: - template_data = self.get_one_template_data(template_id) - template_component_data = self.parse_template_component_name( - template_data["source"]["elements"] - ) - - lyric.replace("\r", "") - lyric_splited = lyric.split("\n") - modifications = {} - for idx, (template_component_name, template_type) in enumerate( - template_component_data.items() - ): - match template_type: - case "image": - modifications[template_component_name] = image_url_list[ - idx % len(image_url_list) - ] - case "text": - modifications[template_component_name] = lyric_splited[ - idx % len(lyric_splited) - ] - - modifications["audio-music"] = music_url - - return modifications - - def elements_connect_resource_blackbox( - self, elements: list, image_url_list: list[str], lyric: str, music_url: str - ) -> dict: - template_component_data = self.parse_template_component_name(elements) - - lyric.replace("\r", "") - lyric_splited = lyric.split("\n") - modifications = {} - for idx, (template_component_name, template_type) in enumerate( - template_component_data.items() - ): - match template_type: - case "image": - modifications[template_component_name] = image_url_list[ - idx % len(image_url_list) - ] - case "text": - modifications[template_component_name] = lyric_splited[ - idx % len(lyric_splited) - ] - - modifications["audio-music"] = music_url - - return modifications - - def modify_element(self, elements: list, modification: dict): - def recursive_modify(element: dict) -> dict: - if "name" in element: - match element["type"]: - case "image": - element["source"] = modification[element["name"]] - case "audio": - element["source"] = modification.get(element["name"], "") - case "video": - element["source"] = modification[element["name"]] - case "text": - element["source"] = modification.get(element["name"], "") - case "composition": - for minor in element["elements"]: - recursive_modify(minor) - - for minor in elements: - recursive_modify(minor) - - return elements - - # Creatomate에 생성 요청 - # response에 요청 정보 있으니 풀링 필요 - def make_creatomate_call(self, template_id: str, modifications: dict): - url = Creatomate.base_url + "/v2/renders" - - data = {"template_id": template_id, "modifications": modifications} - headers = { - "Content-Type": "application/json", - "Authorization": f"Bearer {self.api_key}", - } - - response = requests.post(url, json=data, headers=headers) - return response - - # Creatomate에 생성 요청 without template - # response에 요청 정보 있으니 풀링 필요 - def make_creatomate_custom_call(self, source: str): - url = Creatomate.base_url + "/v2/renders" - data = source - headers = { - "Content-Type": "application/json", - "Authorization": f"Bearer {self.api_key}", - } - - response = requests.post(url, json=data, headers=headers) - return response - - def calc_scene_duration(self, template: dict): - total_template_duration = 0 - for elem in template["source"]["elements"]: - try: - if elem["type"] == "audio": - continue - total_template_duration += elem["duration"] - if "animations" not in elem: - continue - for animation in elem["animations"]: - assert animation["time"] == 0 # 0이 아닌 경우 확인 필요 - if animation["transition"]: - total_template_duration -= animation["duration"] - except: - print(elem) - return total_template_duration - - def extend_template_duration(self, template: dict, target_duration: float): - template["duration"] = target_duration - total_template_duration = self.calc_scene_duration(template) - extend_rate = target_duration / total_template_duration - new_template = copy.deepcopy(template) - for elem in new_template["source"]["elements"]: - try: - if elem["type"] == "audio": - continue - elem["duration"] = elem["duration"] * extend_rate - if "animations" not in elem: - continue - for animation in elem["animations"]: - assert animation["time"] == 0 # 0이 아닌 경우 확인 필요 - animation["duration"] = animation["duration"] * extend_rate - except: - print(elem) - return new_template - - -# Azure사용한 legacy 코드 원본 -# def template_connect_resource_blackbox(template_id, user_idx, task_idx): -# secret_client = get_keyvault_client() -# account_url = secret_client.get_secret(BLOB_ACCOUNT_URL_KEY).value -# media_folder_path = f"{user_idx}/{task_idx}" -# lyric_path = f"{media_folder_path}/lyric.txt" -# lyric = az_storage.az_storage_read_ado2_media(lyric_path).readall().decode('UTF-8') -# media_list = az_storage.az_storage_get_ado2_media_list(media_folder_path) -# image_list = [media.name for media in media_list if '/crawling-images/' in media.name] -# template_data = get_one_template_data(template_id) -# template_component_data = parse_template_component_name(template_data['source']['elements']) -# lyric.replace("\r", "") -# lyric_splited = lyric.split("\n") -# modifications = {} -# for idx, (template_component_name, template_type) in enumerate(template_component_data.items()): -# match template_type: -# case 'image': -# modifications[template_component_name] = f"{account_url}/{BLOB_CONTAINER_NAME}/{image_list[idx % len(image_list)]}" -# case 'text': -# modifications[template_component_name] = lyric_splited[idx % len(lyric_splited)] - -# modifications["audio-music"] = f"{account_url}/{BLOB_CONTAINER_NAME}/{BLOB_MEDIA_FOLDER}/{media_folder_path}/music_mureka.mp3" -# print(modifications) - -# return modifications +import copy + +import requests + +CREATOMATE_API_KEY = "df9e4382d7e84fe790bf8a2168152be195d5a3568524ceb66ed989a2dea809f7d3065d6803b2e3dd9d02b5e5ec1c9823" +# ACCOUNT_URL = "https://ado2mediastoragepublic.blob.core.windows.net/ado2-media-public-access/ado2-media-original/" +# Creatomate 템플릿 정보 전부 가져오기 + + +class Creatomate: + base_url: str = "https://api.creatomate.com" + + def __init__(self, api_key): + self.api_key = api_key + + def get_all_templates_data(self) -> dict: + url = Creatomate.base_url + "/v1/templates" + headers = { + "Content-Type": "application/json", + "Authorization": f"Bearer {self.api_key}", + } + response = requests.get(url, headers=headers) + return response.json() + + # Creatomate 템플릿 ID 로부터 해당 템플릿 정보 가져오기 + def get_one_template_data(self, template_id: str) -> dict: + url = Creatomate.base_url + f"/v1/templates/{template_id}" + headers = { + "Content-Type": "application/json", + "Authorization": f"Bearer {self.api_key}", + } + response = requests.get(url, headers=headers) + return response.json() + + # 템플릿 정보 파싱하여 리소스 이름 추출하기 + def parse_template_component_name(self, template_source: dict) -> dict: + def recursive_parse_component(element: dict) -> dict: + if "name" in element: + result_element_name_type = {element["name"]: element["type"]} + else: + result_element_name_type = {} + + if element["type"] == "composition": + minor_component_list = [ + recursive_parse_component(minor) for minor in element["elements"] + ] + for minor_component in minor_component_list: ## WARNING : Same name component should shroud other component. be aware + result_element_name_type.update(minor_component) + + return result_element_name_type + + result = {} + for result_element_dict in [ + recursive_parse_component(component) for component in template_source + ]: + result.update(result_element_dict) + + return result + + # 템플릿 정보 이미지/가사/음악 리소스와 매핑하기 + # 이미지는 순차적으로 집어넣기 + # 가사는 개행마다 한 텍스트 삽입 + # Template에 audio-music 항목이 있어야 함. (추가된 템플릿 Cafe뿐임) + def template_connect_resource_blackbox( + self, template_id: str, image_url_list: list[str], lyric: str, music_url: str + ) -> dict: + template_data = self.get_one_template_data(template_id) + template_component_data = self.parse_template_component_name( + template_data["source"]["elements"] + ) + + lyric.replace("\r", "") + lyric_splited = lyric.split("\n") + modifications = {} + for idx, (template_component_name, template_type) in enumerate( + template_component_data.items() + ): + match template_type: + case "image": + modifications[template_component_name] = image_url_list[ + idx % len(image_url_list) + ] + case "text": + modifications[template_component_name] = lyric_splited[ + idx % len(lyric_splited) + ] + + modifications["audio-music"] = music_url + + return modifications + + def elements_connect_resource_blackbox( + self, elements: list, image_url_list: list[str], lyric: str, music_url: str + ) -> dict: + template_component_data = self.parse_template_component_name(elements) + + lyric.replace("\r", "") + lyric_splited = lyric.split("\n") + modifications = {} + for idx, (template_component_name, template_type) in enumerate( + template_component_data.items() + ): + match template_type: + case "image": + modifications[template_component_name] = image_url_list[ + idx % len(image_url_list) + ] + case "text": + modifications[template_component_name] = lyric_splited[ + idx % len(lyric_splited) + ] + + modifications["audio-music"] = music_url + + return modifications + + def modify_element(self, elements: list, modification: dict): + def recursive_modify(element: dict) -> dict: + if "name" in element: + match element["type"]: + case "image": + element["source"] = modification[element["name"]] + case "audio": + element["source"] = modification.get(element["name"], "") + case "video": + element["source"] = modification[element["name"]] + case "text": + element["source"] = modification.get(element["name"], "") + case "composition": + for minor in element["elements"]: + recursive_modify(minor) + + for minor in elements: + recursive_modify(minor) + + return elements + + # Creatomate에 생성 요청 + # response에 요청 정보 있으니 풀링 필요 + def make_creatomate_call(self, template_id: str, modifications: dict): + url = Creatomate.base_url + "/v2/renders" + + data = {"template_id": template_id, "modifications": modifications} + headers = { + "Content-Type": "application/json", + "Authorization": f"Bearer {self.api_key}", + } + + response = requests.post(url, json=data, headers=headers) + return response + + # Creatomate에 생성 요청 without template + # response에 요청 정보 있으니 풀링 필요 + def make_creatomate_custom_call(self, source: str): + url = Creatomate.base_url + "/v2/renders" + data = source + headers = { + "Content-Type": "application/json", + "Authorization": f"Bearer {self.api_key}", + } + + response = requests.post(url, json=data, headers=headers) + return response + + def calc_scene_duration(self, template: dict): + total_template_duration = 0 + for elem in template["source"]["elements"]: + try: + if elem["type"] == "audio": + continue + total_template_duration += elem["duration"] + if "animations" not in elem: + continue + for animation in elem["animations"]: + assert animation["time"] == 0 # 0이 아닌 경우 확인 필요 + if animation["transition"]: + total_template_duration -= animation["duration"] + except: + print(elem) + return total_template_duration + + def extend_template_duration(self, template: dict, target_duration: float): + template["duration"] = target_duration + total_template_duration = self.calc_scene_duration(template) + extend_rate = target_duration / total_template_duration + new_template = copy.deepcopy(template) + for elem in new_template["source"]["elements"]: + try: + if elem["type"] == "audio": + continue + elem["duration"] = elem["duration"] * extend_rate + if "animations" not in elem: + continue + for animation in elem["animations"]: + assert animation["time"] == 0 # 0이 아닌 경우 확인 필요 + animation["duration"] = animation["duration"] * extend_rate + except: + print(elem) + return new_template + + +# Azure사용한 legacy 코드 원본 +# def template_connect_resource_blackbox(template_id, user_idx, task_idx): +# secret_client = get_keyvault_client() +# account_url = secret_client.get_secret(BLOB_ACCOUNT_URL_KEY).value +# media_folder_path = f"{user_idx}/{task_idx}" +# lyric_path = f"{media_folder_path}/lyric.txt" +# lyric = az_storage.az_storage_read_ado2_media(lyric_path).readall().decode('UTF-8') +# media_list = az_storage.az_storage_get_ado2_media_list(media_folder_path) +# image_list = [media.name for media in media_list if '/crawling-images/' in media.name] +# template_data = get_one_template_data(template_id) +# template_component_data = parse_template_component_name(template_data['source']['elements']) +# lyric.replace("\r", "") +# lyric_splited = lyric.split("\n") +# modifications = {} +# for idx, (template_component_name, template_type) in enumerate(template_component_data.items()): +# match template_type: +# case 'image': +# modifications[template_component_name] = f"{account_url}/{BLOB_CONTAINER_NAME}/{image_list[idx % len(image_list)]}" +# case 'text': +# modifications[template_component_name] = lyric_splited[idx % len(lyric_splited)] + +# modifications["audio-music"] = f"{account_url}/{BLOB_CONTAINER_NAME}/{BLOB_MEDIA_FOLDER}/{media_folder_path}/music_mureka.mp3" +# print(modifications) + +# return modifications diff --git a/poc/creatomate/test.py b/poc/creatomate/test.py index 63590b0..b22582d 100644 --- a/poc/creatomate/test.py +++ b/poc/creatomate/test.py @@ -1,55 +1,55 @@ -import creatomate - -CREATOMATE_API_KEY = "df9e4382d7e84fe790bf8a2168152be195d5a3568524ceb66ed989a2dea809f7d3065d6803b2e3dd9d02b5e5ec1c9823" -shortform_4_template_id = "e8c7b43f-de4b-4ba3-b8eb-5df688569193" -target_duration = 90.0 # s - -creato = creatomate.Creatomate(CREATOMATE_API_KEY) - -template = creato.get_one_template_data(shortform_4_template_id) - -uploaded_image_url_list = [ - "https://ado2mediastoragepublic.blob.core.windows.net/ado2-media-public-access/ado2-media-original/dev-user-idx/dev-task-idx/crawling-images/crawler4_img_1755818306_000_385523a5_99f2e8a8.jpg", - "https://ado2mediastoragepublic.blob.core.windows.net/ado2-media-public-access/ado2-media-original/dev-user-idx/dev-task-idx/crawling-images/crawler4_img_1755818306_001_d4cf6ec9_b81a1fdc.jpg", - "https://ado2mediastoragepublic.blob.core.windows.net/ado2-media-public-access/ado2-media-original/dev-user-idx/dev-task-idx/crawling-images/crawler4_img_1755818307_002_e4a0b276_680c5020.jpg", - "https://ado2mediastoragepublic.blob.core.windows.net/ado2-media-public-access/ado2-media-original/dev-user-idx/dev-task-idx/crawling-images/crawler4_img_1755818307_003_657f8c26_9f2c7168.jpg", - "https://ado2mediastoragepublic.blob.core.windows.net/ado2-media-public-access/ado2-media-original/dev-user-idx/dev-task-idx/crawling-images/crawler4_img_1755818307_004_9500e39d_24b9dad0.jpg", - "https://ado2mediastoragepublic.blob.core.windows.net/ado2-media-public-access/ado2-media-original/dev-user-idx/dev-task-idx/crawling-images/crawler4_img_1755818308_005_c3536641_9d490ccf.jpg", -] - -lyric = """ -진짜 맛있는 추어탕의 향연 -청담추어정 본점이야 말로 -온 가족이 함께 먹는 그 맛 -여수동 맛집으로 명성을 떨쳐 - -주차 가능, 단체 이용도 OK -내 입맛을 사로잡는 맛 -청담추어정, 그 진정한 맛 -말복을 지나고 느껴보세요 - -한산한 분위기, 편안한 식사 -상황 추어탕으로 더욱 완벽 -톡톡 튀는 맛, 한 입에 느껴 -청담추어정에서 즐겨보세요 - -성남 출신의 맛집으로 -여수대로에서 빛나는 그곳 -청담추어정, 진짜 맛의 꿈 -여러분을 초대합니다 여기에 - -#청담추어정 #여수동맛집 -성남에서 만나는 진짜 맛 -""" - -song_url = "https://ado2mediastoragepublic.blob.core.windows.net/ado2-media-public-access/ado2-media-original/dev-user-idx/dev-task-idx/stay.mp3" - -modifications = creato.elements_connect_resource_blackbox( - template["source"]["elements"], uploaded_image_url_list, lyric, song_url -) - - -new_elements = creato.modify_element(template["source"]["elements"], modifications) -template["source"]["elements"] = new_elements -last_template = creato.extend_template_duration(template, target_duration) -creato.make_creatomate_custom_call(last_template["source"]) +import creatomate + +CREATOMATE_API_KEY = "df9e4382d7e84fe790bf8a2168152be195d5a3568524ceb66ed989a2dea809f7d3065d6803b2e3dd9d02b5e5ec1c9823" +shortform_4_template_id = "e8c7b43f-de4b-4ba3-b8eb-5df688569193" +target_duration = 90.0 # s + +creato = creatomate.Creatomate(CREATOMATE_API_KEY) + +template = creato.get_one_template_data(shortform_4_template_id) + +uploaded_image_url_list = [ + "https://ado2mediastoragepublic.blob.core.windows.net/ado2-media-public-access/ado2-media-original/dev-user-idx/dev-task-idx/crawling-images/crawler4_img_1755818306_000_385523a5_99f2e8a8.jpg", + "https://ado2mediastoragepublic.blob.core.windows.net/ado2-media-public-access/ado2-media-original/dev-user-idx/dev-task-idx/crawling-images/crawler4_img_1755818306_001_d4cf6ec9_b81a1fdc.jpg", + "https://ado2mediastoragepublic.blob.core.windows.net/ado2-media-public-access/ado2-media-original/dev-user-idx/dev-task-idx/crawling-images/crawler4_img_1755818307_002_e4a0b276_680c5020.jpg", + "https://ado2mediastoragepublic.blob.core.windows.net/ado2-media-public-access/ado2-media-original/dev-user-idx/dev-task-idx/crawling-images/crawler4_img_1755818307_003_657f8c26_9f2c7168.jpg", + "https://ado2mediastoragepublic.blob.core.windows.net/ado2-media-public-access/ado2-media-original/dev-user-idx/dev-task-idx/crawling-images/crawler4_img_1755818307_004_9500e39d_24b9dad0.jpg", + "https://ado2mediastoragepublic.blob.core.windows.net/ado2-media-public-access/ado2-media-original/dev-user-idx/dev-task-idx/crawling-images/crawler4_img_1755818308_005_c3536641_9d490ccf.jpg", +] + +lyric = """ +진짜 맛있는 추어탕의 향연 +청담추어정 본점이야 말로 +온 가족이 함께 먹는 그 맛 +여수동 맛집으로 명성을 떨쳐 + +주차 가능, 단체 이용도 OK +내 입맛을 사로잡는 맛 +청담추어정, 그 진정한 맛 +말복을 지나고 느껴보세요 + +한산한 분위기, 편안한 식사 +상황 추어탕으로 더욱 완벽 +톡톡 튀는 맛, 한 입에 느껴 +청담추어정에서 즐겨보세요 + +성남 출신의 맛집으로 +여수대로에서 빛나는 그곳 +청담추어정, 진짜 맛의 꿈 +여러분을 초대합니다 여기에 + +#청담추어정 #여수동맛집 +성남에서 만나는 진짜 맛 +""" + +song_url = "https://ado2mediastoragepublic.blob.core.windows.net/ado2-media-public-access/ado2-media-original/dev-user-idx/dev-task-idx/stay.mp3" + +modifications = creato.elements_connect_resource_blackbox( + template["source"]["elements"], uploaded_image_url_list, lyric, song_url +) + + +new_elements = creato.modify_element(template["source"]["elements"], modifications) +template["source"]["elements"] = new_elements +last_template = creato.extend_template_duration(template, target_duration) +creato.make_creatomate_custom_call(last_template["source"]) diff --git a/uv.lock b/uv.lock index b121e2b..6693df3 100644 --- a/uv.lock +++ b/uv.lock @@ -1,1592 +1,1592 @@ -version = 1 -revision = 3 -requires-python = ">=3.13" - -[[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, upload-time = "2025-10-09T20:51:04.358Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/bc/8a/340a1555ae33d7354dbca4faa54948d76d89a27ceef032c8c3bc661d003e/aiofiles-25.1.0-py3-none-any.whl", hash = "sha256:abe311e527c862958650f9438e859c1fa7568a141b22abcd015e120e86a85695", size = 14668, upload-time = "2025-10-09T20:51:03.174Z" }, -] - -[[package]] -name = "aiohappyeyeballs" -version = "2.6.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/26/30/f84a107a9c4331c14b2b586036f40965c128aa4fee4dda5d3d51cb14ad54/aiohappyeyeballs-2.6.1.tar.gz", hash = "sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558", size = 22760, upload-time = "2025-03-12T01:42:48.764Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl", hash = "sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8", size = 15265, upload-time = "2025-03-12T01:42:47.083Z" }, -] - -[[package]] -name = "aiohttp" -version = "3.13.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "aiohappyeyeballs" }, - { name = "aiosignal" }, - { name = "attrs" }, - { name = "frozenlist" }, - { name = "multidict" }, - { name = "propcache" }, - { name = "yarl" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/1c/ce/3b83ebba6b3207a7135e5fcaba49706f8a4b6008153b4e30540c982fae26/aiohttp-3.13.2.tar.gz", hash = "sha256:40176a52c186aefef6eb3cad2cdd30cd06e3afbe88fe8ab2af9c0b90f228daca", size = 7837994, upload-time = "2025-10-28T20:59:39.937Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/bf/78/7e90ca79e5aa39f9694dcfd74f4720782d3c6828113bb1f3197f7e7c4a56/aiohttp-3.13.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:7519bdc7dfc1940d201651b52bf5e03f5503bda45ad6eacf64dda98be5b2b6be", size = 732139, upload-time = "2025-10-28T20:57:02.455Z" }, - { url = "https://files.pythonhosted.org/packages/db/ed/1f59215ab6853fbaa5c8495fa6cbc39edfc93553426152b75d82a5f32b76/aiohttp-3.13.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:088912a78b4d4f547a1f19c099d5a506df17eacec3c6f4375e2831ec1d995742", size = 490082, upload-time = "2025-10-28T20:57:04.784Z" }, - { url = "https://files.pythonhosted.org/packages/68/7b/fe0fe0f5e05e13629d893c760465173a15ad0039c0a5b0d0040995c8075e/aiohttp-3.13.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5276807b9de9092af38ed23ce120539ab0ac955547b38563a9ba4f5b07b95293", size = 489035, upload-time = "2025-10-28T20:57:06.894Z" }, - { url = "https://files.pythonhosted.org/packages/d2/04/db5279e38471b7ac801d7d36a57d1230feeee130bbe2a74f72731b23c2b1/aiohttp-3.13.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1237c1375eaef0db4dcd7c2559f42e8af7b87ea7d295b118c60c36a6e61cb811", size = 1720387, upload-time = "2025-10-28T20:57:08.685Z" }, - { url = "https://files.pythonhosted.org/packages/31/07/8ea4326bd7dae2bd59828f69d7fdc6e04523caa55e4a70f4a8725a7e4ed2/aiohttp-3.13.2-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:96581619c57419c3d7d78703d5b78c1e5e5fc0172d60f555bdebaced82ded19a", size = 1688314, upload-time = "2025-10-28T20:57:10.693Z" }, - { url = "https://files.pythonhosted.org/packages/48/ab/3d98007b5b87ffd519d065225438cc3b668b2f245572a8cb53da5dd2b1bc/aiohttp-3.13.2-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a2713a95b47374169409d18103366de1050fe0ea73db358fc7a7acb2880422d4", size = 1756317, upload-time = "2025-10-28T20:57:12.563Z" }, - { url = "https://files.pythonhosted.org/packages/97/3d/801ca172b3d857fafb7b50c7c03f91b72b867a13abca982ed6b3081774ef/aiohttp-3.13.2-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:228a1cd556b3caca590e9511a89444925da87d35219a49ab5da0c36d2d943a6a", size = 1858539, upload-time = "2025-10-28T20:57:14.623Z" }, - { url = "https://files.pythonhosted.org/packages/f7/0d/4764669bdf47bd472899b3d3db91fffbe925c8e3038ec591a2fd2ad6a14d/aiohttp-3.13.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ac6cde5fba8d7d8c6ac963dbb0256a9854e9fafff52fbcc58fdf819357892c3e", size = 1739597, upload-time = "2025-10-28T20:57:16.399Z" }, - { url = "https://files.pythonhosted.org/packages/c4/52/7bd3c6693da58ba16e657eb904a5b6decfc48ecd06e9ac098591653b1566/aiohttp-3.13.2-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f2bef8237544f4e42878c61cef4e2839fee6346dc60f5739f876a9c50be7fcdb", size = 1555006, upload-time = "2025-10-28T20:57:18.288Z" }, - { url = "https://files.pythonhosted.org/packages/48/30/9586667acec5993b6f41d2ebcf96e97a1255a85f62f3c653110a5de4d346/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:16f15a4eac3bc2d76c45f7ebdd48a65d41b242eb6c31c2245463b40b34584ded", size = 1683220, upload-time = "2025-10-28T20:57:20.241Z" }, - { url = "https://files.pythonhosted.org/packages/71/01/3afe4c96854cfd7b30d78333852e8e851dceaec1c40fd00fec90c6402dd2/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:bb7fb776645af5cc58ab804c58d7eba545a97e047254a52ce89c157b5af6cd0b", size = 1712570, upload-time = "2025-10-28T20:57:22.253Z" }, - { url = "https://files.pythonhosted.org/packages/11/2c/22799d8e720f4697a9e66fd9c02479e40a49de3de2f0bbe7f9f78a987808/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:e1b4951125ec10c70802f2cb09736c895861cd39fd9dcb35107b4dc8ae6220b8", size = 1733407, upload-time = "2025-10-28T20:57:24.37Z" }, - { url = "https://files.pythonhosted.org/packages/34/cb/90f15dd029f07cebbd91f8238a8b363978b530cd128488085b5703683594/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:550bf765101ae721ee1d37d8095f47b1f220650f85fe1af37a90ce75bab89d04", size = 1550093, upload-time = "2025-10-28T20:57:26.257Z" }, - { url = "https://files.pythonhosted.org/packages/69/46/12dce9be9d3303ecbf4d30ad45a7683dc63d90733c2d9fe512be6716cd40/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:fe91b87fc295973096251e2d25a811388e7d8adf3bd2b97ef6ae78bc4ac6c476", size = 1758084, upload-time = "2025-10-28T20:57:28.349Z" }, - { url = "https://files.pythonhosted.org/packages/f9/c8/0932b558da0c302ffd639fc6362a313b98fdf235dc417bc2493da8394df7/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e0c8e31cfcc4592cb200160344b2fb6ae0f9e4effe06c644b5a125d4ae5ebe23", size = 1716987, upload-time = "2025-10-28T20:57:30.233Z" }, - { url = "https://files.pythonhosted.org/packages/5d/8b/f5bd1a75003daed099baec373aed678f2e9b34f2ad40d85baa1368556396/aiohttp-3.13.2-cp313-cp313-win32.whl", hash = "sha256:0740f31a60848d6edb296a0df827473eede90c689b8f9f2a4cdde74889eb2254", size = 425859, upload-time = "2025-10-28T20:57:32.105Z" }, - { url = "https://files.pythonhosted.org/packages/5d/28/a8a9fc6957b2cee8902414e41816b5ab5536ecf43c3b1843c10e82c559b2/aiohttp-3.13.2-cp313-cp313-win_amd64.whl", hash = "sha256:a88d13e7ca367394908f8a276b89d04a3652044612b9a408a0bb22a5ed976a1a", size = 452192, upload-time = "2025-10-28T20:57:34.166Z" }, - { url = "https://files.pythonhosted.org/packages/9b/36/e2abae1bd815f01c957cbf7be817b3043304e1c87bad526292a0410fdcf9/aiohttp-3.13.2-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:2475391c29230e063ef53a66669b7b691c9bfc3f1426a0f7bcdf1216bdbac38b", size = 735234, upload-time = "2025-10-28T20:57:36.415Z" }, - { url = "https://files.pythonhosted.org/packages/ca/e3/1ee62dde9b335e4ed41db6bba02613295a0d5b41f74a783c142745a12763/aiohttp-3.13.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:f33c8748abef4d8717bb20e8fb1b3e07c6adacb7fd6beaae971a764cf5f30d61", size = 490733, upload-time = "2025-10-28T20:57:38.205Z" }, - { url = "https://files.pythonhosted.org/packages/1a/aa/7a451b1d6a04e8d15a362af3e9b897de71d86feac3babf8894545d08d537/aiohttp-3.13.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ae32f24bbfb7dbb485a24b30b1149e2f200be94777232aeadba3eecece4d0aa4", size = 491303, upload-time = "2025-10-28T20:57:40.122Z" }, - { url = "https://files.pythonhosted.org/packages/57/1e/209958dbb9b01174870f6a7538cd1f3f28274fdbc88a750c238e2c456295/aiohttp-3.13.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d7f02042c1f009ffb70067326ef183a047425bb2ff3bc434ead4dd4a4a66a2b", size = 1717965, upload-time = "2025-10-28T20:57:42.28Z" }, - { url = "https://files.pythonhosted.org/packages/08/aa/6a01848d6432f241416bc4866cae8dc03f05a5a884d2311280f6a09c73d6/aiohttp-3.13.2-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:93655083005d71cd6c072cdab54c886e6570ad2c4592139c3fb967bfc19e4694", size = 1667221, upload-time = "2025-10-28T20:57:44.869Z" }, - { url = "https://files.pythonhosted.org/packages/87/4f/36c1992432d31bbc789fa0b93c768d2e9047ec8c7177e5cd84ea85155f36/aiohttp-3.13.2-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0db1e24b852f5f664cd728db140cf11ea0e82450471232a394b3d1a540b0f906", size = 1757178, upload-time = "2025-10-28T20:57:47.216Z" }, - { url = "https://files.pythonhosted.org/packages/ac/b4/8e940dfb03b7e0f68a82b88fd182b9be0a65cb3f35612fe38c038c3112cf/aiohttp-3.13.2-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b009194665bcd128e23eaddef362e745601afa4641930848af4c8559e88f18f9", size = 1838001, upload-time = "2025-10-28T20:57:49.337Z" }, - { url = "https://files.pythonhosted.org/packages/d7/ef/39f3448795499c440ab66084a9db7d20ca7662e94305f175a80f5b7e0072/aiohttp-3.13.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c038a8fdc8103cd51dbd986ecdce141473ffd9775a7a8057a6ed9c3653478011", size = 1716325, upload-time = "2025-10-28T20:57:51.327Z" }, - { url = "https://files.pythonhosted.org/packages/d7/51/b311500ffc860b181c05d91c59a1313bdd05c82960fdd4035a15740d431e/aiohttp-3.13.2-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:66bac29b95a00db411cd758fea0e4b9bdba6d549dfe333f9a945430f5f2cc5a6", size = 1547978, upload-time = "2025-10-28T20:57:53.554Z" }, - { url = "https://files.pythonhosted.org/packages/31/64/b9d733296ef79815226dab8c586ff9e3df41c6aff2e16c06697b2d2e6775/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4ebf9cfc9ba24a74cf0718f04aac2a3bbe745902cc7c5ebc55c0f3b5777ef213", size = 1682042, upload-time = "2025-10-28T20:57:55.617Z" }, - { url = "https://files.pythonhosted.org/packages/3f/30/43d3e0f9d6473a6db7d472104c4eff4417b1e9df01774cb930338806d36b/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:a4b88ebe35ce54205c7074f7302bd08a4cb83256a3e0870c72d6f68a3aaf8e49", size = 1680085, upload-time = "2025-10-28T20:57:57.59Z" }, - { url = "https://files.pythonhosted.org/packages/16/51/c709f352c911b1864cfd1087577760ced64b3e5bee2aa88b8c0c8e2e4972/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:98c4fb90bb82b70a4ed79ca35f656f4281885be076f3f970ce315402b53099ae", size = 1728238, upload-time = "2025-10-28T20:57:59.525Z" }, - { url = "https://files.pythonhosted.org/packages/19/e2/19bd4c547092b773caeb48ff5ae4b1ae86756a0ee76c16727fcfd281404b/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:ec7534e63ae0f3759df3a1ed4fa6bc8f75082a924b590619c0dd2f76d7043caa", size = 1544395, upload-time = "2025-10-28T20:58:01.914Z" }, - { url = "https://files.pythonhosted.org/packages/cf/87/860f2803b27dfc5ed7be532832a3498e4919da61299b4a1f8eb89b8ff44d/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:5b927cf9b935a13e33644cbed6c8c4b2d0f25b713d838743f8fe7191b33829c4", size = 1742965, upload-time = "2025-10-28T20:58:03.972Z" }, - { url = "https://files.pythonhosted.org/packages/67/7f/db2fc7618925e8c7a601094d5cbe539f732df4fb570740be88ed9e40e99a/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:88d6c017966a78c5265d996c19cdb79235be5e6412268d7e2ce7dee339471b7a", size = 1697585, upload-time = "2025-10-28T20:58:06.189Z" }, - { url = "https://files.pythonhosted.org/packages/0c/07/9127916cb09bb38284db5036036042b7b2c514c8ebaeee79da550c43a6d6/aiohttp-3.13.2-cp314-cp314-win32.whl", hash = "sha256:f7c183e786e299b5d6c49fb43a769f8eb8e04a2726a2bd5887b98b5cc2d67940", size = 431621, upload-time = "2025-10-28T20:58:08.636Z" }, - { url = "https://files.pythonhosted.org/packages/fb/41/554a8a380df6d3a2bba8a7726429a23f4ac62aaf38de43bb6d6cde7b4d4d/aiohttp-3.13.2-cp314-cp314-win_amd64.whl", hash = "sha256:fe242cd381e0fb65758faf5ad96c2e460df6ee5b2de1072fe97e4127927e00b4", size = 457627, upload-time = "2025-10-28T20:58:11Z" }, - { url = "https://files.pythonhosted.org/packages/c7/8e/3824ef98c039d3951cb65b9205a96dd2b20f22241ee17d89c5701557c826/aiohttp-3.13.2-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:f10d9c0b0188fe85398c61147bbd2a657d616c876863bfeff43376e0e3134673", size = 767360, upload-time = "2025-10-28T20:58:13.358Z" }, - { url = "https://files.pythonhosted.org/packages/a4/0f/6a03e3fc7595421274fa34122c973bde2d89344f8a881b728fa8c774e4f1/aiohttp-3.13.2-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:e7c952aefdf2460f4ae55c5e9c3e80aa72f706a6317e06020f80e96253b1accd", size = 504616, upload-time = "2025-10-28T20:58:15.339Z" }, - { url = "https://files.pythonhosted.org/packages/c6/aa/ed341b670f1bc8a6f2c6a718353d13b9546e2cef3544f573c6a1ff0da711/aiohttp-3.13.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c20423ce14771d98353d2e25e83591fa75dfa90a3c1848f3d7c68243b4fbded3", size = 509131, upload-time = "2025-10-28T20:58:17.693Z" }, - { url = "https://files.pythonhosted.org/packages/7f/f0/c68dac234189dae5c4bbccc0f96ce0cc16b76632cfc3a08fff180045cfa4/aiohttp-3.13.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e96eb1a34396e9430c19d8338d2ec33015e4a87ef2b4449db94c22412e25ccdf", size = 1864168, upload-time = "2025-10-28T20:58:20.113Z" }, - { url = "https://files.pythonhosted.org/packages/8f/65/75a9a76db8364b5d0e52a0c20eabc5d52297385d9af9c35335b924fafdee/aiohttp-3.13.2-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:23fb0783bc1a33640036465019d3bba069942616a6a2353c6907d7fe1ccdaf4e", size = 1719200, upload-time = "2025-10-28T20:58:22.583Z" }, - { url = "https://files.pythonhosted.org/packages/f5/55/8df2ed78d7f41d232f6bd3ff866b6f617026551aa1d07e2f03458f964575/aiohttp-3.13.2-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2e1a9bea6244a1d05a4e57c295d69e159a5c50d8ef16aa390948ee873478d9a5", size = 1843497, upload-time = "2025-10-28T20:58:24.672Z" }, - { url = "https://files.pythonhosted.org/packages/e9/e0/94d7215e405c5a02ccb6a35c7a3a6cfff242f457a00196496935f700cde5/aiohttp-3.13.2-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0a3d54e822688b56e9f6b5816fb3de3a3a64660efac64e4c2dc435230ad23bad", size = 1935703, upload-time = "2025-10-28T20:58:26.758Z" }, - { url = "https://files.pythonhosted.org/packages/0b/78/1eeb63c3f9b2d1015a4c02788fb543141aad0a03ae3f7a7b669b2483f8d4/aiohttp-3.13.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7a653d872afe9f33497215745da7a943d1dc15b728a9c8da1c3ac423af35178e", size = 1792738, upload-time = "2025-10-28T20:58:29.787Z" }, - { url = "https://files.pythonhosted.org/packages/41/75/aaf1eea4c188e51538c04cc568040e3082db263a57086ea74a7d38c39e42/aiohttp-3.13.2-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:56d36e80d2003fa3fc0207fac644216d8532e9504a785ef9a8fd013f84a42c61", size = 1624061, upload-time = "2025-10-28T20:58:32.529Z" }, - { url = "https://files.pythonhosted.org/packages/9b/c2/3b6034de81fbcc43de8aeb209073a2286dfb50b86e927b4efd81cf848197/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:78cd586d8331fb8e241c2dd6b2f4061778cc69e150514b39a9e28dd050475661", size = 1789201, upload-time = "2025-10-28T20:58:34.618Z" }, - { url = "https://files.pythonhosted.org/packages/c9/38/c15dcf6d4d890217dae79d7213988f4e5fe6183d43893a9cf2fe9e84ca8d/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:20b10bbfbff766294fe99987f7bb3b74fdd2f1a2905f2562132641ad434dcf98", size = 1776868, upload-time = "2025-10-28T20:58:38.835Z" }, - { url = "https://files.pythonhosted.org/packages/04/75/f74fd178ac81adf4f283a74847807ade5150e48feda6aef024403716c30c/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:9ec49dff7e2b3c85cdeaa412e9d438f0ecd71676fde61ec57027dd392f00c693", size = 1790660, upload-time = "2025-10-28T20:58:41.507Z" }, - { url = "https://files.pythonhosted.org/packages/e7/80/7368bd0d06b16b3aba358c16b919e9c46cf11587dc572091031b0e9e3ef0/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:94f05348c4406450f9d73d38efb41d669ad6cd90c7ee194810d0eefbfa875a7a", size = 1617548, upload-time = "2025-10-28T20:58:43.674Z" }, - { url = "https://files.pythonhosted.org/packages/7d/4b/a6212790c50483cb3212e507378fbe26b5086d73941e1ec4b56a30439688/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:fa4dcb605c6f82a80c7f95713c2b11c3b8e9893b3ebd2bc9bde93165ed6107be", size = 1817240, upload-time = "2025-10-28T20:58:45.787Z" }, - { url = "https://files.pythonhosted.org/packages/ff/f7/ba5f0ba4ea8d8f3c32850912944532b933acbf0f3a75546b89269b9b7dde/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:cf00e5db968c3f67eccd2778574cf64d8b27d95b237770aa32400bd7a1ca4f6c", size = 1762334, upload-time = "2025-10-28T20:58:47.936Z" }, - { url = "https://files.pythonhosted.org/packages/7e/83/1a5a1856574588b1cad63609ea9ad75b32a8353ac995d830bf5da9357364/aiohttp-3.13.2-cp314-cp314t-win32.whl", hash = "sha256:d23b5fe492b0805a50d3371e8a728a9134d8de5447dce4c885f5587294750734", size = 464685, upload-time = "2025-10-28T20:58:50.642Z" }, - { url = "https://files.pythonhosted.org/packages/9f/4d/d22668674122c08f4d56972297c51a624e64b3ed1efaa40187607a7cb66e/aiohttp-3.13.2-cp314-cp314t-win_amd64.whl", hash = "sha256:ff0a7b0a82a7ab905cbda74006318d1b12e37c797eb1b0d4eb3e316cf47f658f", size = 498093, upload-time = "2025-10-28T20:58:52.782Z" }, -] - -[[package]] -name = "aiomysql" -version = "0.3.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pymysql" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/29/e0/302aeffe8d90853556f47f3106b89c16cc2ec2a4d269bdfd82e3f4ae12cc/aiomysql-0.3.2.tar.gz", hash = "sha256:72d15ef5cfc34c03468eb41e1b90adb9fd9347b0b589114bd23ead569a02ac1a", size = 108311, upload-time = "2025-10-22T00:15:21.278Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/4c/af/aae0153c3e28712adaf462328f6c7a3c196a1c1c27b491de4377dd3e6b52/aiomysql-0.3.2-py3-none-any.whl", hash = "sha256:c82c5ba04137d7afd5c693a258bea8ead2aad77101668044143a991e04632eb2", size = 71834, upload-time = "2025-10-22T00:15:15.905Z" }, -] - -[[package]] -name = "aiosignal" -version = "1.4.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "frozenlist" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/61/62/06741b579156360248d1ec624842ad0edf697050bbaf7c3e46394e106ad1/aiosignal-1.4.0.tar.gz", hash = "sha256:f47eecd9468083c2029cc99945502cb7708b082c232f9aca65da147157b251c7", size = 25007, upload-time = "2025-07-03T22:54:43.528Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl", hash = "sha256:053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e", size = 7490, upload-time = "2025-07-03T22:54:42.156Z" }, -] - -[[package]] -name = "annotated-doc" -version = "0.0.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/57/ba/046ceea27344560984e26a590f90bc7f4a75b06701f653222458922b558c/annotated_doc-0.0.4.tar.gz", hash = "sha256:fbcda96e87e9c92ad167c2e53839e57503ecfda18804ea28102353485033faa4", size = 7288, upload-time = "2025-11-10T22:07:42.062Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl", hash = "sha256:571ac1dc6991c450b25a9c2d84a3705e2ae7a53467b5d111c24fa8baabbed320", size = 5303, upload-time = "2025-11-10T22:07:40.673Z" }, -] - -[[package]] -name = "annotated-types" -version = "0.7.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, -] - -[[package]] -name = "anyio" -version = "4.12.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "idna" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/16/ce/8a777047513153587e5434fd752e89334ac33e379aa3497db860eeb60377/anyio-4.12.0.tar.gz", hash = "sha256:73c693b567b0c55130c104d0b43a9baf3aa6a31fc6110116509f27bf75e21ec0", size = 228266, upload-time = "2025-11-28T23:37:38.911Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7f/9c/36c5c37947ebfb8c7f22e0eb6e4d188ee2d53aa3880f3f2744fb894f0cb1/anyio-4.12.0-py3-none-any.whl", hash = "sha256:dad2376a628f98eeca4881fc56cd06affd18f659b17a747d3ff0307ced94b1bb", size = 113362, upload-time = "2025-11-28T23:36:57.897Z" }, -] - -[[package]] -name = "asyncmy" -version = "0.2.10" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b5/76/55cc0577f9e838c5a5213bf33159b9e484c9d9820a2bafd4d6bfa631bf86/asyncmy-0.2.10.tar.gz", hash = "sha256:f4b67edadf7caa56bdaf1c2e6cf451150c0a86f5353744deabe4426fe27aff4e", size = 63889, upload-time = "2024-12-12T14:45:09.2Z" } - -[[package]] -name = "attrs" -version = "25.4.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6b/5c/685e6633917e101e5dcb62b9dd76946cbb57c26e133bae9e0cd36033c0a9/attrs-25.4.0.tar.gz", hash = "sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11", size = 934251, upload-time = "2025-10-06T13:54:44.725Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl", hash = "sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373", size = 67615, upload-time = "2025-10-06T13:54:43.17Z" }, -] - -[[package]] -name = "certifi" -version = "2025.11.12" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a2/8c/58f469717fa48465e4a50c014a0400602d3c437d7c0c468e17ada824da3a/certifi-2025.11.12.tar.gz", hash = "sha256:d8ab5478f2ecd78af242878415affce761ca6bc54a22a27e026d7c25357c3316", size = 160538, upload-time = "2025-11-12T02:54:51.517Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/70/7d/9bc192684cea499815ff478dfcdc13835ddf401365057044fb721ec6bddb/certifi-2025.11.12-py3-none-any.whl", hash = "sha256:97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b", size = 159438, upload-time = "2025-11-12T02:54:49.735Z" }, -] - -[[package]] -name = "click" -version = "8.3.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/3d/fa/656b739db8587d7b5dfa22e22ed02566950fbfbcdc20311993483657a5c0/click-8.3.1.tar.gz", hash = "sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a", size = 295065, upload-time = "2025-11-15T20:45:42.706Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl", hash = "sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6", size = 108274, upload-time = "2025-11-15T20:45:41.139Z" }, -] - -[[package]] -name = "colorama" -version = "0.4.6" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, -] - -[[package]] -name = "distro" -version = "1.9.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/fc/f8/98eea607f65de6527f8a2e8885fc8015d3e6f5775df186e443e0964a11c3/distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed", size = 60722, upload-time = "2023-12-24T09:54:32.31Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/12/b3/231ffd4ab1fc9d679809f356cebee130ac7daa00d6d6f3206dd4fd137e9e/distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2", size = 20277, upload-time = "2023-12-24T09:54:30.421Z" }, -] - -[[package]] -name = "dnspython" -version = "2.8.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8c/8b/57666417c0f90f08bcafa776861060426765fdb422eb10212086fb811d26/dnspython-2.8.0.tar.gz", hash = "sha256:181d3c6996452cb1189c4046c61599b84a5a86e099562ffde77d26984ff26d0f", size = 368251, upload-time = "2025-09-07T18:58:00.022Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ba/5a/18ad964b0086c6e62e2e7500f7edc89e3faa45033c71c1893d34eed2b2de/dnspython-2.8.0-py3-none-any.whl", hash = "sha256:01d9bbc4a2d76bf0db7c1f729812ded6d912bd318d3b1cf81d30c0f845dbf3af", size = 331094, upload-time = "2025-09-07T18:57:58.071Z" }, -] - -[[package]] -name = "email-validator" -version = "2.3.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "dnspython" }, - { name = "idna" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/f5/22/900cb125c76b7aaa450ce02fd727f452243f2e91a61af068b40adba60ea9/email_validator-2.3.0.tar.gz", hash = "sha256:9fc05c37f2f6cf439ff414f8fc46d917929974a82244c20eb10231ba60c54426", size = 51238, upload-time = "2025-08-26T13:09:06.831Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/de/15/545e2b6cf2e3be84bc1ed85613edd75b8aea69807a71c26f4ca6a9258e82/email_validator-2.3.0-py3-none-any.whl", hash = "sha256:80f13f623413e6b197ae73bb10bf4eb0908faf509ad8362c5edeb0be7fd450b4", size = 35604, upload-time = "2025-08-26T13:09:05.858Z" }, -] - -[[package]] -name = "fastapi" -version = "0.125.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "annotated-doc" }, - { name = "pydantic" }, - { name = "starlette" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/17/71/2df15009fb4bdd522a069d2fbca6007c6c5487fce5cb965be00fc335f1d1/fastapi-0.125.0.tar.gz", hash = "sha256:16b532691a33e2c5dee1dac32feb31dc6eb41a3dd4ff29a95f9487cb21c054c0", size = 370550, upload-time = "2025-12-17T21:41:44.15Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/34/2f/ff2fcc98f500713368d8b650e1bbc4a0b3ebcdd3e050dcdaad5f5a13fd7e/fastapi-0.125.0-py3-none-any.whl", hash = "sha256:2570ec4f3aecf5cca8f0428aed2398b774fcdfee6c2116f86e80513f2f86a7a1", size = 112888, upload-time = "2025-12-17T21:41:41.286Z" }, -] - -[package.optional-dependencies] -standard = [ - { name = "email-validator" }, - { name = "fastapi-cli", extra = ["standard"] }, - { name = "httpx" }, - { name = "jinja2" }, - { name = "python-multipart" }, - { name = "uvicorn", extra = ["standard"] }, -] - -[[package]] -name = "fastapi-cli" -version = "0.0.16" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "rich-toolkit" }, - { name = "typer" }, - { name = "uvicorn", extra = ["standard"] }, -] -sdist = { url = "https://files.pythonhosted.org/packages/99/75/9407a6b452be4c988feacec9c9d2f58d8f315162a6c7258d5a649d933ebe/fastapi_cli-0.0.16.tar.gz", hash = "sha256:e8a2a1ecf7a4e062e3b2eec63ae34387d1e142d4849181d936b23c4bdfe29073", size = 19447, upload-time = "2025-11-10T19:01:07.856Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/55/43/678528c19318394320ee43757648d5e0a8070cf391b31f69d931e5c840d2/fastapi_cli-0.0.16-py3-none-any.whl", hash = "sha256:addcb6d130b5b9c91adbbf3f2947fe115991495fdb442fe3e51b5fc6327df9f4", size = 12312, upload-time = "2025-11-10T19:01:06.728Z" }, -] - -[package.optional-dependencies] -standard = [ - { name = "fastapi-cloud-cli" }, - { name = "uvicorn", extra = ["standard"] }, -] - -[[package]] -name = "fastapi-cloud-cli" -version = "0.7.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "fastar" }, - { name = "httpx" }, - { name = "pydantic", extra = ["email"] }, - { name = "rich-toolkit" }, - { name = "rignore" }, - { name = "sentry-sdk" }, - { name = "typer" }, - { name = "uvicorn", extra = ["standard"] }, -] -sdist = { url = "https://files.pythonhosted.org/packages/cf/0d/3b0d2991f481c122c552b4ae38a8b400a75ab0edbc85536f2a6224f72da2/fastapi_cloud_cli-0.7.0.tar.gz", hash = "sha256:8b025944475c3d53262105886dfe051f46383e4f287787a46892b524922ac0b6", size = 30906, upload-time = "2025-12-16T12:51:49.082Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2d/aa/a2319f008e123b178a5c4cba34935e8459e72d24d8c31214b244ab7266a6/fastapi_cloud_cli-0.7.0-py3-none-any.whl", hash = "sha256:9a152e80d08d465d4a6c4f5c75aa8871d1e8919f69ff131b0567f04e95d5f36c", size = 23376, upload-time = "2025-12-16T12:51:47.847Z" }, -] - -[[package]] -name = "fastar" -version = "0.8.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/69/e7/f89d54fb04104114dd0552836dc2b47914f416cc0e200b409dd04a33de5e/fastar-0.8.0.tar.gz", hash = "sha256:f4d4d68dbf1c4c2808f0e730fac5843493fc849f70fe3ad3af60dfbaf68b9a12", size = 68524, upload-time = "2025-11-26T02:36:00.72Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/a5/79ecba3646e22d03eef1a66fb7fc156567213e2e4ab9faab3bbd4489e483/fastar-0.8.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:a3253a06845462ca2196024c7a18f5c0ba4de1532ab1c4bad23a40b332a06a6a", size = 706112, upload-time = "2025-11-26T02:34:39.237Z" }, - { url = "https://files.pythonhosted.org/packages/0a/03/4f883bce878218a8676c2d7ca09b50c856a5470bb3b7f63baf9521ea6995/fastar-0.8.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5cbeb3ebfa0980c68ff8b126295cc6b208ccd81b638aebc5a723d810a7a0e5d2", size = 628954, upload-time = "2025-11-26T02:34:23.705Z" }, - { url = "https://files.pythonhosted.org/packages/4f/f1/892e471f156b03d10ba48ace9384f5a896702a54506137462545f38e40b8/fastar-0.8.0-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1c0d5956b917daac77d333d48b3f0f3ff927b8039d5b32d8125462782369f761", size = 868685, upload-time = "2025-11-26T02:33:53.077Z" }, - { url = "https://files.pythonhosted.org/packages/39/ba/e24915045852e30014ec6840446975c03f4234d1c9270394b51d3ad18394/fastar-0.8.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:27b404db2b786b65912927ce7f3790964a4bcbde42cdd13091b82a89cd655e1c", size = 765044, upload-time = "2025-11-26T02:32:48.187Z" }, - { url = "https://files.pythonhosted.org/packages/14/2c/1aa11ac21a99984864c2fca4994e094319ff3a2046e7a0343c39317bd5b9/fastar-0.8.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0902fc89dcf1e7f07b8563032a4159fe2b835e4c16942c76fd63451d0e5f76a3", size = 764322, upload-time = "2025-11-26T02:33:03.859Z" }, - { url = "https://files.pythonhosted.org/packages/ba/f0/4b91902af39fe2d3bae7c85c6d789586b9fbcf618d7fdb3d37323915906d/fastar-0.8.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:069347e2f0f7a8b99bbac8cd1bc0e06c7b4a31dc964fc60d84b95eab3d869dc1", size = 931016, upload-time = "2025-11-26T02:33:19.902Z" }, - { url = "https://files.pythonhosted.org/packages/c9/97/8fc43a5a9c0a2dc195730f6f7a0f367d171282cd8be2511d0e87c6d2dad0/fastar-0.8.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7fd135306f6bfe9a835918280e0eb440b70ab303e0187d90ab51ca86e143f70d", size = 821308, upload-time = "2025-11-26T02:33:34.664Z" }, - { url = "https://files.pythonhosted.org/packages/0c/e9/058615b63a7fd27965e8c5966f393ed0c169f7ff5012e1674f21684de3ba/fastar-0.8.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78d06d6897f43c27154b5f2d0eb930a43a81b7eec73f6f0b0114814d4a10ab38", size = 821171, upload-time = "2025-11-26T02:34:08.498Z" }, - { url = "https://files.pythonhosted.org/packages/ca/cf/69e16a17961570a755c37ffb5b5aa7610d2e77807625f537989da66f2a9d/fastar-0.8.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a922f8439231fa0c32b15e8d70ff6d415619b9d40492029dabbc14a0c53b5f18", size = 986227, upload-time = "2025-11-26T02:34:55.06Z" }, - { url = "https://files.pythonhosted.org/packages/fb/83/2100192372e59b56f4ace37d7d9cabda511afd71b5febad1643d1c334271/fastar-0.8.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:a739abd51eb766384b4caff83050888e80cd75bbcfec61e6d1e64875f94e4a40", size = 1039395, upload-time = "2025-11-26T02:35:12.166Z" }, - { url = "https://files.pythonhosted.org/packages/75/15/cdd03aca972f55872efbb7cf7540c3fa7b97a75d626303a3ea46932163dc/fastar-0.8.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:5a65f419d808b23ac89d5cd1b13a2f340f15bc5d1d9af79f39fdb77bba48ff1b", size = 1044766, upload-time = "2025-11-26T02:35:29.62Z" }, - { url = "https://files.pythonhosted.org/packages/3d/29/945e69e4e2652329ace545999334ec31f1431fbae3abb0105587e11af2ae/fastar-0.8.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7bb2ae6c0cce58f0db1c9f20495e7557cca2c1ee9c69bbd90eafd54f139171c5", size = 994740, upload-time = "2025-11-26T02:35:47.887Z" }, - { url = "https://files.pythonhosted.org/packages/4b/5d/dbfe28f8cd1eb484bba0c62e5259b2cf6fea229d6ef43e05c06b5a78c034/fastar-0.8.0-cp313-cp313-win32.whl", hash = "sha256:b28753e0d18a643272597cb16d39f1053842aa43131ad3e260c03a2417d38401", size = 455990, upload-time = "2025-11-26T02:36:28.502Z" }, - { url = "https://files.pythonhosted.org/packages/e1/01/e965740bd36e60ef4c5aa2cbe42b6c4eb1dc3551009238a97c2e5e96bd23/fastar-0.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:620e5d737dce8321d49a5ebb7997f1fd0047cde3512082c27dc66d6ac8c1927a", size = 490227, upload-time = "2025-11-26T02:36:14.363Z" }, - { url = "https://files.pythonhosted.org/packages/dd/10/c99202719b83e5249f26902ae53a05aea67d840eeb242019322f20fc171c/fastar-0.8.0-cp313-cp313-win_arm64.whl", hash = "sha256:c4c4bd08df563120cd33e854fe0a93b81579e8571b11f9b7da9e84c37da2d6b6", size = 461078, upload-time = "2025-11-26T02:36:04.94Z" }, - { url = "https://files.pythonhosted.org/packages/96/4a/9573b87a0ef07580ed111e7230259aec31bb33ca3667963ebee77022ec61/fastar-0.8.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:50b36ce654ba44b0e13fae607ae17ee6e1597b69f71df1bee64bb8328d881dfc", size = 706041, upload-time = "2025-11-26T02:34:40.638Z" }, - { url = "https://files.pythonhosted.org/packages/4a/19/f95444a1d4f375333af49300aa75ee93afa3335c0e40fda528e460ed859c/fastar-0.8.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:63a892762683d7ab00df0227d5ea9677c62ff2cde9b875e666c0be569ed940f3", size = 628617, upload-time = "2025-11-26T02:34:24.893Z" }, - { url = "https://files.pythonhosted.org/packages/b3/c9/b51481b38b7e3f16ef2b9e233b1a3623386c939d745d6e41bbd389eaae30/fastar-0.8.0-cp314-cp314-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4ae6a145c1bff592644bde13f2115e0239f4b7babaf506d14e7d208483cf01a5", size = 869299, upload-time = "2025-11-26T02:33:54.274Z" }, - { url = "https://files.pythonhosted.org/packages/bf/02/3ba1267ee5ba7314e29c431cf82eaa68586f2c40cdfa08be3632b7d07619/fastar-0.8.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ae0ff7c0a1c7e1428404b81faee8aebef466bfd0be25bfe4dabf5d535c68741", size = 764667, upload-time = "2025-11-26T02:32:49.606Z" }, - { url = "https://files.pythonhosted.org/packages/1b/84/bf33530fd015b5d7c2cc69e0bce4a38d736754a6955487005aab1af6adcd/fastar-0.8.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dbfd87dbd217b45c898b2dbcd0169aae534b2c1c5cbe3119510881f6a5ac8ef5", size = 763993, upload-time = "2025-11-26T02:33:05.782Z" }, - { url = "https://files.pythonhosted.org/packages/da/e0/9564d24e7cea6321a8d921c6d2a457044a476ef197aa4708e179d3d97f0d/fastar-0.8.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9a5abd99fcba83ef28c8fe6ae2927edc79053db43a0457a962ed85c9bf150d37", size = 930153, upload-time = "2025-11-26T02:33:21.53Z" }, - { url = "https://files.pythonhosted.org/packages/35/b1/6f57fcd8d6e192cfebf97e58eb27751640ad93784c857b79039e84387b51/fastar-0.8.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:91d4c685620c3a9d6b5ae091dbabab4f98b20049b7ecc7976e19cc9016c0d5d6", size = 821177, upload-time = "2025-11-26T02:33:35.839Z" }, - { url = "https://files.pythonhosted.org/packages/b3/78/9e004ea9f3aa7466f5ddb6f9518780e1d2f0ed3ca55f093632982598bace/fastar-0.8.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f77c2f2cad76e9dc7b6701297adb1eba87d0485944b416fc2ccf5516c01219a3", size = 820652, upload-time = "2025-11-26T02:34:09.776Z" }, - { url = "https://files.pythonhosted.org/packages/42/95/b604ed536544005c9f1aee7c4c74b00150db3d8d535cd8232dc20f947063/fastar-0.8.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e7f07c4a3dada7757a8fc430a5b4a29e6ef696d2212747213f57086ffd970316", size = 985961, upload-time = "2025-11-26T02:34:56.401Z" }, - { url = "https://files.pythonhosted.org/packages/f2/7b/fa9d4d96a5d494bdb8699363bb9de8178c0c21a02e1d89cd6f913d127018/fastar-0.8.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:90c0c3fe55105c0aed8a83135dbdeb31e683455dbd326a1c48fa44c378b85616", size = 1039316, upload-time = "2025-11-26T02:35:13.807Z" }, - { url = "https://files.pythonhosted.org/packages/4e/f9/8462789243bc3f33e8401378ec6d54de4e20cfa60c96a0e15e3e9d1389bb/fastar-0.8.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:fb9ee51e5bffe0dab3d3126d3a4fac8d8f7235cedcb4b8e74936087ce1c157f3", size = 1045028, upload-time = "2025-11-26T02:35:31.079Z" }, - { url = "https://files.pythonhosted.org/packages/a5/71/9abb128777e616127194b509e98fcda3db797d76288c1a8c23dd22afc14f/fastar-0.8.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e380b1e8d30317f52406c43b11e98d11e1d68723bbd031e18049ea3497b59a6d", size = 994677, upload-time = "2025-11-26T02:35:49.391Z" }, - { url = "https://files.pythonhosted.org/packages/de/c1/b81b3f194853d7ad232a67a1d768f5f51a016f165cfb56cb31b31bbc6177/fastar-0.8.0-cp314-cp314-win32.whl", hash = "sha256:1c4ffc06e9c4a8ca498c07e094670d8d8c0d25b17ca6465b9774da44ea997ab1", size = 456687, upload-time = "2025-11-26T02:36:30.205Z" }, - { url = "https://files.pythonhosted.org/packages/cb/87/9e0cd4768a98181d56f0cdbab2363404cc15deb93f4aad3b99cd2761bbaa/fastar-0.8.0-cp314-cp314-win_amd64.whl", hash = "sha256:5517a8ad4726267c57a3e0e2a44430b782e00b230bf51c55b5728e758bb3a692", size = 490578, upload-time = "2025-11-26T02:36:16.218Z" }, - { url = "https://files.pythonhosted.org/packages/aa/1e/580a76cf91847654f2ad6520e956e93218f778540975bc4190d363f709e2/fastar-0.8.0-cp314-cp314-win_arm64.whl", hash = "sha256:58030551046ff4a8616931e52a36c83545ff05996db5beb6e0cd2b7e748aa309", size = 461473, upload-time = "2025-11-26T02:36:06.373Z" }, - { url = "https://files.pythonhosted.org/packages/58/4c/bdb5c6efe934f68708529c8c9d4055ebef5c4be370621966438f658b29bd/fastar-0.8.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:1e7d29b6bfecb29db126a08baf3c04a5ab667f6cea2b7067d3e623a67729c4a6", size = 705570, upload-time = "2025-11-26T02:34:42.01Z" }, - { url = "https://files.pythonhosted.org/packages/6d/78/f01ac7e71d5a37621bd13598a26e948a12b85ca8042f7ee1a0a8c9f59cda/fastar-0.8.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:05eb7b96940f9526b485f1d0b02393839f0f61cac4b1f60024984f8b326d2640", size = 627761, upload-time = "2025-11-26T02:34:26.152Z" }, - { url = "https://files.pythonhosted.org/packages/06/45/6df0ecda86ea9d2e95053c1a655d153dee55fc121b6e13ea6d1e246a50b6/fastar-0.8.0-cp314-cp314t-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:619352d8ac011794e2345c462189dc02ba634750d23cd9d86a9267dd71b1f278", size = 869414, upload-time = "2025-11-26T02:33:55.618Z" }, - { url = "https://files.pythonhosted.org/packages/b2/72/486421f5a8c0c377cc82e7a50c8a8ea899a6ec2aa72bde8f09fb667a2dc8/fastar-0.8.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74ebfecef3fe6d7a90355fac1402fd30636988332a1d33f3e80019a10782bb24", size = 763863, upload-time = "2025-11-26T02:32:51.051Z" }, - { url = "https://files.pythonhosted.org/packages/d4/64/39f654dbb41a3867fb1f2c8081c014d8f1d32ea10585d84cacbef0b32995/fastar-0.8.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2975aca5a639e26a3ab0d23b4b0628d6dd6d521146c3c11486d782be621a35aa", size = 763065, upload-time = "2025-11-26T02:33:07.274Z" }, - { url = "https://files.pythonhosted.org/packages/4e/bd/c011a34fb3534c4c3301f7c87c4ffd7e47f6113c904c092ddc8a59a303ea/fastar-0.8.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:afc438eaed8ff0dcdd9308268be5cb38c1db7e94c3ccca7c498ca13a4a4535a3", size = 930530, upload-time = "2025-11-26T02:33:23.117Z" }, - { url = "https://files.pythonhosted.org/packages/55/9d/aa6e887a7033c571b1064429222bbe09adc9a3c1e04f3d1788ba5838ebd5/fastar-0.8.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6ced0a5399cc0a84a858ef0a31ca2d0c24d3bbec4bcda506a9192d8119f3590a", size = 820572, upload-time = "2025-11-26T02:33:37.542Z" }, - { url = "https://files.pythonhosted.org/packages/ad/9c/7a3a2278a1052e1a5d98646de7c095a00cffd2492b3b84ce730e2f1cd93a/fastar-0.8.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec9b23da8c4c039da3fe2e358973c66976a0c8508aa06d6626b4403cb5666c19", size = 820649, upload-time = "2025-11-26T02:34:11.108Z" }, - { url = "https://files.pythonhosted.org/packages/02/9e/d38edc1f4438cd047e56137c26d94783ffade42e1b3bde620ccf17b771ef/fastar-0.8.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:dfba078fcd53478032fd0ceed56960ec6b7ff0511cfc013a8a3a4307e3a7bac4", size = 985653, upload-time = "2025-11-26T02:34:57.884Z" }, - { url = "https://files.pythonhosted.org/packages/69/d9/2147d0c19757e165cd62d41cec3f7b38fad2ad68ab784978b5f81716c7ea/fastar-0.8.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:ade56c94c14be356d295fecb47a3fcd473dd43a8803ead2e2b5b9e58feb6dcfa", size = 1038140, upload-time = "2025-11-26T02:35:15.778Z" }, - { url = "https://files.pythonhosted.org/packages/7f/1d/ec4c717ffb8a308871e9602ec3197d957e238dc0227127ac573ec9bca952/fastar-0.8.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:e48d938f9366db5e59441728f70b7f6c1ccfab7eff84f96f9b7e689b07786c52", size = 1045195, upload-time = "2025-11-26T02:35:32.865Z" }, - { url = "https://files.pythonhosted.org/packages/6a/9f/637334dc8c8f3bb391388b064ae13f0ad9402bc5a6c3e77b8887d0c31921/fastar-0.8.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:79c441dc1482ff51a54fb3f57ae6f7bb3d2cff88fa2cc5d196c519f8aab64a56", size = 994686, upload-time = "2025-11-26T02:35:51.392Z" }, - { url = "https://files.pythonhosted.org/packages/c9/e2/dfa19a4b260b8ab3581b7484dcb80c09b25324f4daa6b6ae1c7640d1607a/fastar-0.8.0-cp314-cp314t-win32.whl", hash = "sha256:187f61dc739afe45ac8e47ed7fd1adc45d52eac110cf27d579155720507d6fbe", size = 455767, upload-time = "2025-11-26T02:36:34.758Z" }, - { url = "https://files.pythonhosted.org/packages/51/47/df65c72afc1297797b255f90c4778b5d6f1f0f80282a134d5ab610310ed9/fastar-0.8.0-cp314-cp314t-win_amd64.whl", hash = "sha256:40e9d763cf8bf85ce2fa256e010aa795c0fe3d3bd1326d5c3084e6ce7857127e", size = 489971, upload-time = "2025-11-26T02:36:22.081Z" }, - { url = "https://files.pythonhosted.org/packages/85/11/0aa8455af26f0ae89e42be67f3a874255ee5d7f0f026fc86e8d56f76b428/fastar-0.8.0-cp314-cp314t-win_arm64.whl", hash = "sha256:e59673307b6a08210987059a2bdea2614fe26e3335d0e5d1a3d95f49a05b1418", size = 460467, upload-time = "2025-11-26T02:36:07.978Z" }, -] - -[[package]] -name = "frozenlist" -version = "1.8.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/2d/f5/c831fac6cc817d26fd54c7eaccd04ef7e0288806943f7cc5bbf69f3ac1f0/frozenlist-1.8.0.tar.gz", hash = "sha256:3ede829ed8d842f6cd48fc7081d7a41001a56f1f38603f9d49bf3020d59a31ad", size = 45875, upload-time = "2025-10-06T05:38:17.865Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2d/40/0832c31a37d60f60ed79e9dfb5a92e1e2af4f40a16a29abcc7992af9edff/frozenlist-1.8.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8d92f1a84bb12d9e56f818b3a746f3efba93c1b63c8387a73dde655e1e42282a", size = 85717, upload-time = "2025-10-06T05:36:27.341Z" }, - { url = "https://files.pythonhosted.org/packages/30/ba/b0b3de23f40bc55a7057bd38434e25c34fa48e17f20ee273bbde5e0650f3/frozenlist-1.8.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:96153e77a591c8adc2ee805756c61f59fef4cf4073a9275ee86fe8cba41241f7", size = 49651, upload-time = "2025-10-06T05:36:28.855Z" }, - { url = "https://files.pythonhosted.org/packages/0c/ab/6e5080ee374f875296c4243c381bbdef97a9ac39c6e3ce1d5f7d42cb78d6/frozenlist-1.8.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f21f00a91358803399890ab167098c131ec2ddd5f8f5fd5fe9c9f2c6fcd91e40", size = 49417, upload-time = "2025-10-06T05:36:29.877Z" }, - { url = "https://files.pythonhosted.org/packages/d5/4e/e4691508f9477ce67da2015d8c00acd751e6287739123113a9fca6f1604e/frozenlist-1.8.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fb30f9626572a76dfe4293c7194a09fb1fe93ba94c7d4f720dfae3b646b45027", size = 234391, upload-time = "2025-10-06T05:36:31.301Z" }, - { url = "https://files.pythonhosted.org/packages/40/76/c202df58e3acdf12969a7895fd6f3bc016c642e6726aa63bd3025e0fc71c/frozenlist-1.8.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eaa352d7047a31d87dafcacbabe89df0aa506abb5b1b85a2fb91bc3faa02d822", size = 233048, upload-time = "2025-10-06T05:36:32.531Z" }, - { url = "https://files.pythonhosted.org/packages/f9/c0/8746afb90f17b73ca5979c7a3958116e105ff796e718575175319b5bb4ce/frozenlist-1.8.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:03ae967b4e297f58f8c774c7eabcce57fe3c2434817d4385c50661845a058121", size = 226549, upload-time = "2025-10-06T05:36:33.706Z" }, - { url = "https://files.pythonhosted.org/packages/7e/eb/4c7eefc718ff72f9b6c4893291abaae5fbc0c82226a32dcd8ef4f7a5dbef/frozenlist-1.8.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f6292f1de555ffcc675941d65fffffb0a5bcd992905015f85d0592201793e0e5", size = 239833, upload-time = "2025-10-06T05:36:34.947Z" }, - { url = "https://files.pythonhosted.org/packages/c2/4e/e5c02187cf704224f8b21bee886f3d713ca379535f16893233b9d672ea71/frozenlist-1.8.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:29548f9b5b5e3460ce7378144c3010363d8035cea44bc0bf02d57f5a685e084e", size = 245363, upload-time = "2025-10-06T05:36:36.534Z" }, - { url = "https://files.pythonhosted.org/packages/1f/96/cb85ec608464472e82ad37a17f844889c36100eed57bea094518bf270692/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ec3cc8c5d4084591b4237c0a272cc4f50a5b03396a47d9caaf76f5d7b38a4f11", size = 229314, upload-time = "2025-10-06T05:36:38.582Z" }, - { url = "https://files.pythonhosted.org/packages/5d/6f/4ae69c550e4cee66b57887daeebe006fe985917c01d0fff9caab9883f6d0/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:517279f58009d0b1f2e7c1b130b377a349405da3f7621ed6bfae50b10adf20c1", size = 243365, upload-time = "2025-10-06T05:36:40.152Z" }, - { url = "https://files.pythonhosted.org/packages/7a/58/afd56de246cf11780a40a2c28dc7cbabbf06337cc8ddb1c780a2d97e88d8/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:db1e72ede2d0d7ccb213f218df6a078a9c09a7de257c2fe8fcef16d5925230b1", size = 237763, upload-time = "2025-10-06T05:36:41.355Z" }, - { url = "https://files.pythonhosted.org/packages/cb/36/cdfaf6ed42e2644740d4a10452d8e97fa1c062e2a8006e4b09f1b5fd7d63/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b4dec9482a65c54a5044486847b8a66bf10c9cb4926d42927ec4e8fd5db7fed8", size = 240110, upload-time = "2025-10-06T05:36:42.716Z" }, - { url = "https://files.pythonhosted.org/packages/03/a8/9ea226fbefad669f11b52e864c55f0bd57d3c8d7eb07e9f2e9a0b39502e1/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:21900c48ae04d13d416f0e1e0c4d81f7931f73a9dfa0b7a8746fb2fe7dd970ed", size = 233717, upload-time = "2025-10-06T05:36:44.251Z" }, - { url = "https://files.pythonhosted.org/packages/1e/0b/1b5531611e83ba7d13ccc9988967ea1b51186af64c42b7a7af465dcc9568/frozenlist-1.8.0-cp313-cp313-win32.whl", hash = "sha256:8b7b94a067d1c504ee0b16def57ad5738701e4ba10cec90529f13fa03c833496", size = 39628, upload-time = "2025-10-06T05:36:45.423Z" }, - { url = "https://files.pythonhosted.org/packages/d8/cf/174c91dbc9cc49bc7b7aab74d8b734e974d1faa8f191c74af9b7e80848e6/frozenlist-1.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:878be833caa6a3821caf85eb39c5ba92d28e85df26d57afb06b35b2efd937231", size = 43882, upload-time = "2025-10-06T05:36:46.796Z" }, - { url = "https://files.pythonhosted.org/packages/c1/17/502cd212cbfa96eb1388614fe39a3fc9ab87dbbe042b66f97acb57474834/frozenlist-1.8.0-cp313-cp313-win_arm64.whl", hash = "sha256:44389d135b3ff43ba8cc89ff7f51f5a0bb6b63d829c8300f79a2fe4fe61bcc62", size = 39676, upload-time = "2025-10-06T05:36:47.8Z" }, - { url = "https://files.pythonhosted.org/packages/d2/5c/3bbfaa920dfab09e76946a5d2833a7cbdf7b9b4a91c714666ac4855b88b4/frozenlist-1.8.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:e25ac20a2ef37e91c1b39938b591457666a0fa835c7783c3a8f33ea42870db94", size = 89235, upload-time = "2025-10-06T05:36:48.78Z" }, - { url = "https://files.pythonhosted.org/packages/d2/d6/f03961ef72166cec1687e84e8925838442b615bd0b8854b54923ce5b7b8a/frozenlist-1.8.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:07cdca25a91a4386d2e76ad992916a85038a9b97561bf7a3fd12d5d9ce31870c", size = 50742, upload-time = "2025-10-06T05:36:49.837Z" }, - { url = "https://files.pythonhosted.org/packages/1e/bb/a6d12b7ba4c3337667d0e421f7181c82dda448ce4e7ad7ecd249a16fa806/frozenlist-1.8.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4e0c11f2cc6717e0a741f84a527c52616140741cd812a50422f83dc31749fb52", size = 51725, upload-time = "2025-10-06T05:36:50.851Z" }, - { url = "https://files.pythonhosted.org/packages/bc/71/d1fed0ffe2c2ccd70b43714c6cab0f4188f09f8a67a7914a6b46ee30f274/frozenlist-1.8.0-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b3210649ee28062ea6099cfda39e147fa1bc039583c8ee4481cb7811e2448c51", size = 284533, upload-time = "2025-10-06T05:36:51.898Z" }, - { url = "https://files.pythonhosted.org/packages/c9/1f/fb1685a7b009d89f9bf78a42d94461bc06581f6e718c39344754a5d9bada/frozenlist-1.8.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:581ef5194c48035a7de2aefc72ac6539823bb71508189e5de01d60c9dcd5fa65", size = 292506, upload-time = "2025-10-06T05:36:53.101Z" }, - { url = "https://files.pythonhosted.org/packages/e6/3b/b991fe1612703f7e0d05c0cf734c1b77aaf7c7d321df4572e8d36e7048c8/frozenlist-1.8.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3ef2d026f16a2b1866e1d86fc4e1291e1ed8a387b2c333809419a2f8b3a77b82", size = 274161, upload-time = "2025-10-06T05:36:54.309Z" }, - { url = "https://files.pythonhosted.org/packages/ca/ec/c5c618767bcdf66e88945ec0157d7f6c4a1322f1473392319b7a2501ded7/frozenlist-1.8.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5500ef82073f599ac84d888e3a8c1f77ac831183244bfd7f11eaa0289fb30714", size = 294676, upload-time = "2025-10-06T05:36:55.566Z" }, - { url = "https://files.pythonhosted.org/packages/7c/ce/3934758637d8f8a88d11f0585d6495ef54b2044ed6ec84492a91fa3b27aa/frozenlist-1.8.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:50066c3997d0091c411a66e710f4e11752251e6d2d73d70d8d5d4c76442a199d", size = 300638, upload-time = "2025-10-06T05:36:56.758Z" }, - { url = "https://files.pythonhosted.org/packages/fc/4f/a7e4d0d467298f42de4b41cbc7ddaf19d3cfeabaf9ff97c20c6c7ee409f9/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:5c1c8e78426e59b3f8005e9b19f6ff46e5845895adbde20ece9218319eca6506", size = 283067, upload-time = "2025-10-06T05:36:57.965Z" }, - { url = "https://files.pythonhosted.org/packages/dc/48/c7b163063d55a83772b268e6d1affb960771b0e203b632cfe09522d67ea5/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:eefdba20de0d938cec6a89bd4d70f346a03108a19b9df4248d3cf0d88f1b0f51", size = 292101, upload-time = "2025-10-06T05:36:59.237Z" }, - { url = "https://files.pythonhosted.org/packages/9f/d0/2366d3c4ecdc2fd391e0afa6e11500bfba0ea772764d631bbf82f0136c9d/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:cf253e0e1c3ceb4aaff6df637ce033ff6535fb8c70a764a8f46aafd3d6ab798e", size = 289901, upload-time = "2025-10-06T05:37:00.811Z" }, - { url = "https://files.pythonhosted.org/packages/b8/94/daff920e82c1b70e3618a2ac39fbc01ae3e2ff6124e80739ce5d71c9b920/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:032efa2674356903cd0261c4317a561a6850f3ac864a63fc1583147fb05a79b0", size = 289395, upload-time = "2025-10-06T05:37:02.115Z" }, - { url = "https://files.pythonhosted.org/packages/e3/20/bba307ab4235a09fdcd3cc5508dbabd17c4634a1af4b96e0f69bfe551ebd/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6da155091429aeba16851ecb10a9104a108bcd32f6c1642867eadaee401c1c41", size = 283659, upload-time = "2025-10-06T05:37:03.711Z" }, - { url = "https://files.pythonhosted.org/packages/fd/00/04ca1c3a7a124b6de4f8a9a17cc2fcad138b4608e7a3fc5877804b8715d7/frozenlist-1.8.0-cp313-cp313t-win32.whl", hash = "sha256:0f96534f8bfebc1a394209427d0f8a63d343c9779cda6fc25e8e121b5fd8555b", size = 43492, upload-time = "2025-10-06T05:37:04.915Z" }, - { url = "https://files.pythonhosted.org/packages/59/5e/c69f733a86a94ab10f68e496dc6b7e8bc078ebb415281d5698313e3af3a1/frozenlist-1.8.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5d63a068f978fc69421fb0e6eb91a9603187527c86b7cd3f534a5b77a592b888", size = 48034, upload-time = "2025-10-06T05:37:06.343Z" }, - { url = "https://files.pythonhosted.org/packages/16/6c/be9d79775d8abe79b05fa6d23da99ad6e7763a1d080fbae7290b286093fd/frozenlist-1.8.0-cp313-cp313t-win_arm64.whl", hash = "sha256:bf0a7e10b077bf5fb9380ad3ae8ce20ef919a6ad93b4552896419ac7e1d8e042", size = 41749, upload-time = "2025-10-06T05:37:07.431Z" }, - { url = "https://files.pythonhosted.org/packages/f1/c8/85da824b7e7b9b6e7f7705b2ecaf9591ba6f79c1177f324c2735e41d36a2/frozenlist-1.8.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:cee686f1f4cadeb2136007ddedd0aaf928ab95216e7691c63e50a8ec066336d0", size = 86127, upload-time = "2025-10-06T05:37:08.438Z" }, - { url = "https://files.pythonhosted.org/packages/8e/e8/a1185e236ec66c20afd72399522f142c3724c785789255202d27ae992818/frozenlist-1.8.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:119fb2a1bd47307e899c2fac7f28e85b9a543864df47aa7ec9d3c1b4545f096f", size = 49698, upload-time = "2025-10-06T05:37:09.48Z" }, - { url = "https://files.pythonhosted.org/packages/a1/93/72b1736d68f03fda5fdf0f2180fb6caaae3894f1b854d006ac61ecc727ee/frozenlist-1.8.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4970ece02dbc8c3a92fcc5228e36a3e933a01a999f7094ff7c23fbd2beeaa67c", size = 49749, upload-time = "2025-10-06T05:37:10.569Z" }, - { url = "https://files.pythonhosted.org/packages/a7/b2/fabede9fafd976b991e9f1b9c8c873ed86f202889b864756f240ce6dd855/frozenlist-1.8.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:cba69cb73723c3f329622e34bdbf5ce1f80c21c290ff04256cff1cd3c2036ed2", size = 231298, upload-time = "2025-10-06T05:37:11.993Z" }, - { url = "https://files.pythonhosted.org/packages/3a/3b/d9b1e0b0eed36e70477ffb8360c49c85c8ca8ef9700a4e6711f39a6e8b45/frozenlist-1.8.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:778a11b15673f6f1df23d9586f83c4846c471a8af693a22e066508b77d201ec8", size = 232015, upload-time = "2025-10-06T05:37:13.194Z" }, - { url = "https://files.pythonhosted.org/packages/dc/94/be719d2766c1138148564a3960fc2c06eb688da592bdc25adcf856101be7/frozenlist-1.8.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0325024fe97f94c41c08872db482cf8ac4800d80e79222c6b0b7b162d5b13686", size = 225038, upload-time = "2025-10-06T05:37:14.577Z" }, - { url = "https://files.pythonhosted.org/packages/e4/09/6712b6c5465f083f52f50cf74167b92d4ea2f50e46a9eea0523d658454ae/frozenlist-1.8.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:97260ff46b207a82a7567b581ab4190bd4dfa09f4db8a8b49d1a958f6aa4940e", size = 240130, upload-time = "2025-10-06T05:37:15.781Z" }, - { url = "https://files.pythonhosted.org/packages/f8/d4/cd065cdcf21550b54f3ce6a22e143ac9e4836ca42a0de1022da8498eac89/frozenlist-1.8.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:54b2077180eb7f83dd52c40b2750d0a9f175e06a42e3213ce047219de902717a", size = 242845, upload-time = "2025-10-06T05:37:17.037Z" }, - { url = "https://files.pythonhosted.org/packages/62/c3/f57a5c8c70cd1ead3d5d5f776f89d33110b1addae0ab010ad774d9a44fb9/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2f05983daecab868a31e1da44462873306d3cbfd76d1f0b5b69c473d21dbb128", size = 229131, upload-time = "2025-10-06T05:37:18.221Z" }, - { url = "https://files.pythonhosted.org/packages/6c/52/232476fe9cb64f0742f3fde2b7d26c1dac18b6d62071c74d4ded55e0ef94/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:33f48f51a446114bc5d251fb2954ab0164d5be02ad3382abcbfe07e2531d650f", size = 240542, upload-time = "2025-10-06T05:37:19.771Z" }, - { url = "https://files.pythonhosted.org/packages/5f/85/07bf3f5d0fb5414aee5f47d33c6f5c77bfe49aac680bfece33d4fdf6a246/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:154e55ec0655291b5dd1b8731c637ecdb50975a2ae70c606d100750a540082f7", size = 237308, upload-time = "2025-10-06T05:37:20.969Z" }, - { url = "https://files.pythonhosted.org/packages/11/99/ae3a33d5befd41ac0ca2cc7fd3aa707c9c324de2e89db0e0f45db9a64c26/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:4314debad13beb564b708b4a496020e5306c7333fa9a3ab90374169a20ffab30", size = 238210, upload-time = "2025-10-06T05:37:22.252Z" }, - { url = "https://files.pythonhosted.org/packages/b2/60/b1d2da22f4970e7a155f0adde9b1435712ece01b3cd45ba63702aea33938/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:073f8bf8becba60aa931eb3bc420b217bb7d5b8f4750e6f8b3be7f3da85d38b7", size = 231972, upload-time = "2025-10-06T05:37:23.5Z" }, - { url = "https://files.pythonhosted.org/packages/3f/ab/945b2f32de889993b9c9133216c068b7fcf257d8595a0ac420ac8677cab0/frozenlist-1.8.0-cp314-cp314-win32.whl", hash = "sha256:bac9c42ba2ac65ddc115d930c78d24ab8d4f465fd3fc473cdedfccadb9429806", size = 40536, upload-time = "2025-10-06T05:37:25.581Z" }, - { url = "https://files.pythonhosted.org/packages/59/ad/9caa9b9c836d9ad6f067157a531ac48b7d36499f5036d4141ce78c230b1b/frozenlist-1.8.0-cp314-cp314-win_amd64.whl", hash = "sha256:3e0761f4d1a44f1d1a47996511752cf3dcec5bbdd9cc2b4fe595caf97754b7a0", size = 44330, upload-time = "2025-10-06T05:37:26.928Z" }, - { url = "https://files.pythonhosted.org/packages/82/13/e6950121764f2676f43534c555249f57030150260aee9dcf7d64efda11dd/frozenlist-1.8.0-cp314-cp314-win_arm64.whl", hash = "sha256:d1eaff1d00c7751b7c6662e9c5ba6eb2c17a2306ba5e2a37f24ddf3cc953402b", size = 40627, upload-time = "2025-10-06T05:37:28.075Z" }, - { url = "https://files.pythonhosted.org/packages/c0/c7/43200656ecc4e02d3f8bc248df68256cd9572b3f0017f0a0c4e93440ae23/frozenlist-1.8.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:d3bb933317c52d7ea5004a1c442eef86f426886fba134ef8cf4226ea6ee1821d", size = 89238, upload-time = "2025-10-06T05:37:29.373Z" }, - { url = "https://files.pythonhosted.org/packages/d1/29/55c5f0689b9c0fb765055629f472c0de484dcaf0acee2f7707266ae3583c/frozenlist-1.8.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:8009897cdef112072f93a0efdce29cd819e717fd2f649ee3016efd3cd885a7ed", size = 50738, upload-time = "2025-10-06T05:37:30.792Z" }, - { url = "https://files.pythonhosted.org/packages/ba/7d/b7282a445956506fa11da8c2db7d276adcbf2b17d8bb8407a47685263f90/frozenlist-1.8.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2c5dcbbc55383e5883246d11fd179782a9d07a986c40f49abe89ddf865913930", size = 51739, upload-time = "2025-10-06T05:37:32.127Z" }, - { url = "https://files.pythonhosted.org/packages/62/1c/3d8622e60d0b767a5510d1d3cf21065b9db874696a51ea6d7a43180a259c/frozenlist-1.8.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:39ecbc32f1390387d2aa4f5a995e465e9e2f79ba3adcac92d68e3e0afae6657c", size = 284186, upload-time = "2025-10-06T05:37:33.21Z" }, - { url = "https://files.pythonhosted.org/packages/2d/14/aa36d5f85a89679a85a1d44cd7a6657e0b1c75f61e7cad987b203d2daca8/frozenlist-1.8.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92db2bf818d5cc8d9c1f1fc56b897662e24ea5adb36ad1f1d82875bd64e03c24", size = 292196, upload-time = "2025-10-06T05:37:36.107Z" }, - { url = "https://files.pythonhosted.org/packages/05/23/6bde59eb55abd407d34f77d39a5126fb7b4f109a3f611d3929f14b700c66/frozenlist-1.8.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2dc43a022e555de94c3b68a4ef0b11c4f747d12c024a520c7101709a2144fb37", size = 273830, upload-time = "2025-10-06T05:37:37.663Z" }, - { url = "https://files.pythonhosted.org/packages/d2/3f/22cff331bfad7a8afa616289000ba793347fcd7bc275f3b28ecea2a27909/frozenlist-1.8.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cb89a7f2de3602cfed448095bab3f178399646ab7c61454315089787df07733a", size = 294289, upload-time = "2025-10-06T05:37:39.261Z" }, - { url = "https://files.pythonhosted.org/packages/a4/89/5b057c799de4838b6c69aa82b79705f2027615e01be996d2486a69ca99c4/frozenlist-1.8.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:33139dc858c580ea50e7e60a1b0ea003efa1fd42e6ec7fdbad78fff65fad2fd2", size = 300318, upload-time = "2025-10-06T05:37:43.213Z" }, - { url = "https://files.pythonhosted.org/packages/30/de/2c22ab3eb2a8af6d69dc799e48455813bab3690c760de58e1bf43b36da3e/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:168c0969a329b416119507ba30b9ea13688fafffac1b7822802537569a1cb0ef", size = 282814, upload-time = "2025-10-06T05:37:45.337Z" }, - { url = "https://files.pythonhosted.org/packages/59/f7/970141a6a8dbd7f556d94977858cfb36fa9b66e0892c6dd780d2219d8cd8/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:28bd570e8e189d7f7b001966435f9dac6718324b5be2990ac496cf1ea9ddb7fe", size = 291762, upload-time = "2025-10-06T05:37:46.657Z" }, - { url = "https://files.pythonhosted.org/packages/c1/15/ca1adae83a719f82df9116d66f5bb28bb95557b3951903d39135620ef157/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:b2a095d45c5d46e5e79ba1e5b9cb787f541a8dee0433836cea4b96a2c439dcd8", size = 289470, upload-time = "2025-10-06T05:37:47.946Z" }, - { url = "https://files.pythonhosted.org/packages/ac/83/dca6dc53bf657d371fbc88ddeb21b79891e747189c5de990b9dfff2ccba1/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:eab8145831a0d56ec9c4139b6c3e594c7a83c2c8be25d5bcf2d86136a532287a", size = 289042, upload-time = "2025-10-06T05:37:49.499Z" }, - { url = "https://files.pythonhosted.org/packages/96/52/abddd34ca99be142f354398700536c5bd315880ed0a213812bc491cff5e4/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:974b28cf63cc99dfb2188d8d222bc6843656188164848c4f679e63dae4b0708e", size = 283148, upload-time = "2025-10-06T05:37:50.745Z" }, - { url = "https://files.pythonhosted.org/packages/af/d3/76bd4ed4317e7119c2b7f57c3f6934aba26d277acc6309f873341640e21f/frozenlist-1.8.0-cp314-cp314t-win32.whl", hash = "sha256:342c97bf697ac5480c0a7ec73cd700ecfa5a8a40ac923bd035484616efecc2df", size = 44676, upload-time = "2025-10-06T05:37:52.222Z" }, - { url = "https://files.pythonhosted.org/packages/89/76/c615883b7b521ead2944bb3480398cbb07e12b7b4e4d073d3752eb721558/frozenlist-1.8.0-cp314-cp314t-win_amd64.whl", hash = "sha256:06be8f67f39c8b1dc671f5d83aaefd3358ae5cdcf8314552c57e7ed3e6475bdd", size = 49451, upload-time = "2025-10-06T05:37:53.425Z" }, - { url = "https://files.pythonhosted.org/packages/e0/a3/5982da14e113d07b325230f95060e2169f5311b1017ea8af2a29b374c289/frozenlist-1.8.0-cp314-cp314t-win_arm64.whl", hash = "sha256:102e6314ca4da683dca92e3b1355490fed5f313b768500084fbe6371fddfdb79", size = 42507, upload-time = "2025-10-06T05:37:54.513Z" }, - { url = "https://files.pythonhosted.org/packages/9a/9a/e35b4a917281c0b8419d4207f4334c8e8c5dbf4f3f5f9ada73958d937dcc/frozenlist-1.8.0-py3-none-any.whl", hash = "sha256:0c18a16eab41e82c295618a77502e17b195883241c563b00f0aa5106fc4eaa0d", size = 13409, upload-time = "2025-10-06T05:38:16.721Z" }, -] - -[[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, upload-time = "2025-12-04T14:49:44.05Z" } -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, upload-time = "2025-12-04T14:23:01.282Z" }, - { 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, upload-time = "2025-12-04T14:50:08.309Z" }, - { 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, upload-time = "2025-12-04T14:57:43.968Z" }, - { 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, upload-time = "2025-12-04T15:07:14.697Z" }, - { 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, upload-time = "2025-12-04T14:26:03.669Z" }, - { 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, upload-time = "2025-12-04T15:04:25.276Z" }, - { 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, upload-time = "2025-12-04T14:27:30.804Z" }, - { url = "https://files.pythonhosted.org/packages/7e/71/ba21c3fb8c5dce83b8c01f458a42e99ffdb1963aeec08fff5a18588d8fd7/greenlet-3.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:9ee1942ea19550094033c35d25d20726e4f1c40d59545815e1128ac58d416d38", size = 301833, upload-time = "2025-12-04T14:32:23.929Z" }, - { 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, upload-time = "2025-12-04T14:23:05.267Z" }, - { 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, upload-time = "2025-12-04T14:50:10.026Z" }, - { 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, upload-time = "2025-12-04T14:57:45.41Z" }, - { 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, upload-time = "2025-12-04T15:07:15.789Z" }, - { 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, upload-time = "2025-12-04T14:26:05.099Z" }, - { 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, upload-time = "2025-12-04T15:04:27.041Z" }, - { 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, upload-time = "2025-12-04T14:27:32.366Z" }, - { url = "https://files.pythonhosted.org/packages/7c/9a/9030e6f9aa8fd7808e9c31ba4c38f87c4f8ec324ee67431d181fe396d705/greenlet-3.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:73f51dd0e0bdb596fb0417e475fa3c5e32d4c83638296e560086b8d7da7c4170", size = 305387, upload-time = "2025-12-04T14:26:51.063Z" }, - { 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, upload-time = "2025-12-04T14:25:20.941Z" }, - { 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, upload-time = "2025-12-04T14:50:11.039Z" }, - { 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, upload-time = "2025-12-04T14:57:47.007Z" }, - { 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, upload-time = "2025-12-04T15:07:16.906Z" }, - { 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, upload-time = "2025-12-04T14:26:06.225Z" }, - { 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, upload-time = "2025-12-04T15:04:28.484Z" }, - { 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, upload-time = "2025-12-04T14:27:33.531Z" }, -] - -[[package]] -name = "h11" -version = "0.16.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, -] - -[[package]] -name = "httpcore" -version = "1.0.9" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "certifi" }, - { name = "h11" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" }, -] - -[[package]] -name = "httptools" -version = "0.7.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b5/46/120a669232c7bdedb9d52d4aeae7e6c7dfe151e99dc70802e2fc7a5e1993/httptools-0.7.1.tar.gz", hash = "sha256:abd72556974f8e7c74a259655924a717a2365b236c882c3f6f8a45fe94703ac9", size = 258961, upload-time = "2025-10-10T03:55:08.559Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/09/8f/c77b1fcbfd262d422f12da02feb0d218fa228d52485b77b953832105bb90/httptools-0.7.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6babce6cfa2a99545c60bfef8bee0cc0545413cb0018f617c8059a30ad985de3", size = 202889, upload-time = "2025-10-10T03:54:47.089Z" }, - { url = "https://files.pythonhosted.org/packages/0a/1a/22887f53602feaa066354867bc49a68fc295c2293433177ee90870a7d517/httptools-0.7.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:601b7628de7504077dd3dcb3791c6b8694bbd967148a6d1f01806509254fb1ca", size = 108180, upload-time = "2025-10-10T03:54:48.052Z" }, - { url = "https://files.pythonhosted.org/packages/32/6a/6aaa91937f0010d288d3d124ca2946d48d60c3a5ee7ca62afe870e3ea011/httptools-0.7.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:04c6c0e6c5fb0739c5b8a9eb046d298650a0ff38cf42537fc372b28dc7e4472c", size = 478596, upload-time = "2025-10-10T03:54:48.919Z" }, - { url = "https://files.pythonhosted.org/packages/6d/70/023d7ce117993107be88d2cbca566a7c1323ccbaf0af7eabf2064fe356f6/httptools-0.7.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:69d4f9705c405ae3ee83d6a12283dc9feba8cc6aaec671b412917e644ab4fa66", size = 473268, upload-time = "2025-10-10T03:54:49.993Z" }, - { url = "https://files.pythonhosted.org/packages/32/4d/9dd616c38da088e3f436e9a616e1d0cc66544b8cdac405cc4e81c8679fc7/httptools-0.7.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:44c8f4347d4b31269c8a9205d8a5ee2df5322b09bbbd30f8f862185bb6b05346", size = 455517, upload-time = "2025-10-10T03:54:51.066Z" }, - { url = "https://files.pythonhosted.org/packages/1d/3a/a6c595c310b7df958e739aae88724e24f9246a514d909547778d776799be/httptools-0.7.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:465275d76db4d554918aba40bf1cbebe324670f3dfc979eaffaa5d108e2ed650", size = 458337, upload-time = "2025-10-10T03:54:52.196Z" }, - { url = "https://files.pythonhosted.org/packages/fd/82/88e8d6d2c51edc1cc391b6e044c6c435b6aebe97b1abc33db1b0b24cd582/httptools-0.7.1-cp313-cp313-win_amd64.whl", hash = "sha256:322d00c2068d125bd570f7bf78b2d367dad02b919d8581d7476d8b75b294e3e6", size = 85743, upload-time = "2025-10-10T03:54:53.448Z" }, - { url = "https://files.pythonhosted.org/packages/34/50/9d095fcbb6de2d523e027a2f304d4551855c2f46e0b82befd718b8b20056/httptools-0.7.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:c08fe65728b8d70b6923ce31e3956f859d5e1e8548e6f22ec520a962c6757270", size = 203619, upload-time = "2025-10-10T03:54:54.321Z" }, - { url = "https://files.pythonhosted.org/packages/07/f0/89720dc5139ae54b03f861b5e2c55a37dba9a5da7d51e1e824a1f343627f/httptools-0.7.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:7aea2e3c3953521c3c51106ee11487a910d45586e351202474d45472db7d72d3", size = 108714, upload-time = "2025-10-10T03:54:55.163Z" }, - { url = "https://files.pythonhosted.org/packages/b3/cb/eea88506f191fb552c11787c23f9a405f4c7b0c5799bf73f2249cd4f5228/httptools-0.7.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0e68b8582f4ea9166be62926077a3334064d422cf08ab87d8b74664f8e9058e1", size = 472909, upload-time = "2025-10-10T03:54:56.056Z" }, - { url = "https://files.pythonhosted.org/packages/e0/4a/a548bdfae6369c0d078bab5769f7b66f17f1bfaa6fa28f81d6be6959066b/httptools-0.7.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:df091cf961a3be783d6aebae963cc9b71e00d57fa6f149025075217bc6a55a7b", size = 470831, upload-time = "2025-10-10T03:54:57.219Z" }, - { url = "https://files.pythonhosted.org/packages/4d/31/14df99e1c43bd132eec921c2e7e11cda7852f65619bc0fc5bdc2d0cb126c/httptools-0.7.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f084813239e1eb403ddacd06a30de3d3e09a9b76e7894dcda2b22f8a726e9c60", size = 452631, upload-time = "2025-10-10T03:54:58.219Z" }, - { url = "https://files.pythonhosted.org/packages/22/d2/b7e131f7be8d854d48cb6d048113c30f9a46dca0c9a8b08fcb3fcd588cdc/httptools-0.7.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7347714368fb2b335e9063bc2b96f2f87a9ceffcd9758ac295f8bbcd3ffbc0ca", size = 452910, upload-time = "2025-10-10T03:54:59.366Z" }, - { url = "https://files.pythonhosted.org/packages/53/cf/878f3b91e4e6e011eff6d1fa9ca39f7eb17d19c9d7971b04873734112f30/httptools-0.7.1-cp314-cp314-win_amd64.whl", hash = "sha256:cfabda2a5bb85aa2a904ce06d974a3f30fb36cc63d7feaddec05d2050acede96", size = 88205, upload-time = "2025-10-10T03:55:00.389Z" }, -] - -[[package]] -name = "httpx" -version = "0.28.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "anyio" }, - { name = "certifi" }, - { name = "httpcore" }, - { name = "idna" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" }, -] - -[[package]] -name = "idna" -version = "3.11" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902", size = 194582, upload-time = "2025-10-12T14:55:20.501Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" }, -] - -[[package]] -name = "iniconfig" -version = "2.3.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, -] - -[[package]] -name = "itsdangerous" -version = "2.2.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/9c/cb/8ac0172223afbccb63986cc25049b154ecfb5e85932587206f42317be31d/itsdangerous-2.2.0.tar.gz", hash = "sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173", size = 54410, upload-time = "2024-04-16T21:28:15.614Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/04/96/92447566d16df59b2a776c0fb82dbc4d9e07cd95062562af01e408583fc4/itsdangerous-2.2.0-py3-none-any.whl", hash = "sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef", size = 16234, upload-time = "2024-04-16T21:28:14.499Z" }, -] - -[[package]] -name = "jinja2" -version = "3.1.6" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "markupsafe" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, -] - -[[package]] -name = "jiter" -version = "0.12.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/45/9d/e0660989c1370e25848bb4c52d061c71837239738ad937e83edca174c273/jiter-0.12.0.tar.gz", hash = "sha256:64dfcd7d5c168b38d3f9f8bba7fc639edb3418abcc74f22fdbe6b8938293f30b", size = 168294, upload-time = "2025-11-09T20:49:23.302Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3d/a6/97209693b177716e22576ee1161674d1d58029eb178e01866a0422b69224/jiter-0.12.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:6cc49d5130a14b732e0612bc76ae8db3b49898732223ef8b7599aa8d9810683e", size = 313658, upload-time = "2025-11-09T20:47:44.424Z" }, - { url = "https://files.pythonhosted.org/packages/06/4d/125c5c1537c7d8ee73ad3d530a442d6c619714b95027143f1b61c0b4dfe0/jiter-0.12.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:37f27a32ce36364d2fa4f7fdc507279db604d27d239ea2e044c8f148410defe1", size = 318605, upload-time = "2025-11-09T20:47:45.973Z" }, - { url = "https://files.pythonhosted.org/packages/99/bf/a840b89847885064c41a5f52de6e312e91fa84a520848ee56c97e4fa0205/jiter-0.12.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bbc0944aa3d4b4773e348cda635252824a78f4ba44328e042ef1ff3f6080d1cf", size = 349803, upload-time = "2025-11-09T20:47:47.535Z" }, - { url = "https://files.pythonhosted.org/packages/8a/88/e63441c28e0db50e305ae23e19c1d8fae012d78ed55365da392c1f34b09c/jiter-0.12.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:da25c62d4ee1ffbacb97fac6dfe4dcd6759ebdc9015991e92a6eae5816287f44", size = 365120, upload-time = "2025-11-09T20:47:49.284Z" }, - { url = "https://files.pythonhosted.org/packages/0a/7c/49b02714af4343970eb8aca63396bc1c82fa01197dbb1e9b0d274b550d4e/jiter-0.12.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:048485c654b838140b007390b8182ba9774621103bd4d77c9c3f6f117474ba45", size = 479918, upload-time = "2025-11-09T20:47:50.807Z" }, - { url = "https://files.pythonhosted.org/packages/69/ba/0a809817fdd5a1db80490b9150645f3aae16afad166960bcd562be194f3b/jiter-0.12.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:635e737fbb7315bef0037c19b88b799143d2d7d3507e61a76751025226b3ac87", size = 379008, upload-time = "2025-11-09T20:47:52.211Z" }, - { url = "https://files.pythonhosted.org/packages/5f/c3/c9fc0232e736c8877d9e6d83d6eeb0ba4e90c6c073835cc2e8f73fdeef51/jiter-0.12.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e017c417b1ebda911bd13b1e40612704b1f5420e30695112efdbed8a4b389ed", size = 361785, upload-time = "2025-11-09T20:47:53.512Z" }, - { url = "https://files.pythonhosted.org/packages/96/61/61f69b7e442e97ca6cd53086ddc1cf59fb830549bc72c0a293713a60c525/jiter-0.12.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:89b0bfb8b2bf2351fba36bb211ef8bfceba73ef58e7f0c68fb67b5a2795ca2f9", size = 386108, upload-time = "2025-11-09T20:47:54.893Z" }, - { url = "https://files.pythonhosted.org/packages/e9/2e/76bb3332f28550c8f1eba3bf6e5efe211efda0ddbbaf24976bc7078d42a5/jiter-0.12.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:f5aa5427a629a824a543672778c9ce0c5e556550d1569bb6ea28a85015287626", size = 519937, upload-time = "2025-11-09T20:47:56.253Z" }, - { url = "https://files.pythonhosted.org/packages/84/d6/fa96efa87dc8bff2094fb947f51f66368fa56d8d4fc9e77b25d7fbb23375/jiter-0.12.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed53b3d6acbcb0fd0b90f20c7cb3b24c357fe82a3518934d4edfa8c6898e498c", size = 510853, upload-time = "2025-11-09T20:47:58.32Z" }, - { url = "https://files.pythonhosted.org/packages/8a/28/93f67fdb4d5904a708119a6ab58a8f1ec226ff10a94a282e0215402a8462/jiter-0.12.0-cp313-cp313-win32.whl", hash = "sha256:4747de73d6b8c78f2e253a2787930f4fffc68da7fa319739f57437f95963c4de", size = 204699, upload-time = "2025-11-09T20:47:59.686Z" }, - { url = "https://files.pythonhosted.org/packages/c4/1f/30b0eb087045a0abe2a5c9c0c0c8da110875a1d3be83afd4a9a4e548be3c/jiter-0.12.0-cp313-cp313-win_amd64.whl", hash = "sha256:e25012eb0c456fcc13354255d0338cd5397cce26c77b2832b3c4e2e255ea5d9a", size = 204258, upload-time = "2025-11-09T20:48:01.01Z" }, - { url = "https://files.pythonhosted.org/packages/2c/f4/2b4daf99b96bce6fc47971890b14b2a36aef88d7beb9f057fafa032c6141/jiter-0.12.0-cp313-cp313-win_arm64.whl", hash = "sha256:c97b92c54fe6110138c872add030a1f99aea2401ddcdaa21edf74705a646dd60", size = 185503, upload-time = "2025-11-09T20:48:02.35Z" }, - { url = "https://files.pythonhosted.org/packages/39/ca/67bb15a7061d6fe20b9b2a2fd783e296a1e0f93468252c093481a2f00efa/jiter-0.12.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:53839b35a38f56b8be26a7851a48b89bc47e5d88e900929df10ed93b95fea3d6", size = 317965, upload-time = "2025-11-09T20:48:03.783Z" }, - { url = "https://files.pythonhosted.org/packages/18/af/1788031cd22e29c3b14bc6ca80b16a39a0b10e611367ffd480c06a259831/jiter-0.12.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94f669548e55c91ab47fef8bddd9c954dab1938644e715ea49d7e117015110a4", size = 345831, upload-time = "2025-11-09T20:48:05.55Z" }, - { url = "https://files.pythonhosted.org/packages/05/17/710bf8472d1dff0d3caf4ced6031060091c1320f84ee7d5dcbed1f352417/jiter-0.12.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:351d54f2b09a41600ffea43d081522d792e81dcfb915f6d2d242744c1cc48beb", size = 361272, upload-time = "2025-11-09T20:48:06.951Z" }, - { url = "https://files.pythonhosted.org/packages/fb/f1/1dcc4618b59761fef92d10bcbb0b038b5160be653b003651566a185f1a5c/jiter-0.12.0-cp313-cp313t-win_amd64.whl", hash = "sha256:2a5e90604620f94bf62264e7c2c038704d38217b7465b863896c6d7c902b06c7", size = 204604, upload-time = "2025-11-09T20:48:08.328Z" }, - { url = "https://files.pythonhosted.org/packages/d9/32/63cb1d9f1c5c6632a783c0052cde9ef7ba82688f7065e2f0d5f10a7e3edb/jiter-0.12.0-cp313-cp313t-win_arm64.whl", hash = "sha256:88ef757017e78d2860f96250f9393b7b577b06a956ad102c29c8237554380db3", size = 185628, upload-time = "2025-11-09T20:48:09.572Z" }, - { url = "https://files.pythonhosted.org/packages/a8/99/45c9f0dbe4a1416b2b9a8a6d1236459540f43d7fb8883cff769a8db0612d/jiter-0.12.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:c46d927acd09c67a9fb1416df45c5a04c27e83aae969267e98fba35b74e99525", size = 312478, upload-time = "2025-11-09T20:48:10.898Z" }, - { url = "https://files.pythonhosted.org/packages/4c/a7/54ae75613ba9e0f55fcb0bc5d1f807823b5167cc944e9333ff322e9f07dd/jiter-0.12.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:774ff60b27a84a85b27b88cd5583899c59940bcc126caca97eb2a9df6aa00c49", size = 318706, upload-time = "2025-11-09T20:48:12.266Z" }, - { url = "https://files.pythonhosted.org/packages/59/31/2aa241ad2c10774baf6c37f8b8e1f39c07db358f1329f4eb40eba179c2a2/jiter-0.12.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5433fab222fb072237df3f637d01b81f040a07dcac1cb4a5c75c7aa9ed0bef1", size = 351894, upload-time = "2025-11-09T20:48:13.673Z" }, - { url = "https://files.pythonhosted.org/packages/54/4f/0f2759522719133a9042781b18cc94e335b6d290f5e2d3e6899d6af933e3/jiter-0.12.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f8c593c6e71c07866ec6bfb790e202a833eeec885022296aff6b9e0b92d6a70e", size = 365714, upload-time = "2025-11-09T20:48:15.083Z" }, - { url = "https://files.pythonhosted.org/packages/dc/6f/806b895f476582c62a2f52c453151edd8a0fde5411b0497baaa41018e878/jiter-0.12.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:90d32894d4c6877a87ae00c6b915b609406819dce8bc0d4e962e4de2784e567e", size = 478989, upload-time = "2025-11-09T20:48:16.706Z" }, - { url = "https://files.pythonhosted.org/packages/86/6c/012d894dc6e1033acd8db2b8346add33e413ec1c7c002598915278a37f79/jiter-0.12.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:798e46eed9eb10c3adbbacbd3bdb5ecd4cf7064e453d00dbef08802dae6937ff", size = 378615, upload-time = "2025-11-09T20:48:18.614Z" }, - { url = "https://files.pythonhosted.org/packages/87/30/d718d599f6700163e28e2c71c0bbaf6dace692e7df2592fd793ac9276717/jiter-0.12.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3f1368f0a6719ea80013a4eb90ba72e75d7ea67cfc7846db2ca504f3df0169a", size = 364745, upload-time = "2025-11-09T20:48:20.117Z" }, - { url = "https://files.pythonhosted.org/packages/8f/85/315b45ce4b6ddc7d7fceca24068543b02bdc8782942f4ee49d652e2cc89f/jiter-0.12.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:65f04a9d0b4406f7e51279710b27484af411896246200e461d80d3ba0caa901a", size = 386502, upload-time = "2025-11-09T20:48:21.543Z" }, - { url = "https://files.pythonhosted.org/packages/74/0b/ce0434fb40c5b24b368fe81b17074d2840748b4952256bab451b72290a49/jiter-0.12.0-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:fd990541982a24281d12b67a335e44f117e4c6cbad3c3b75c7dea68bf4ce3a67", size = 519845, upload-time = "2025-11-09T20:48:22.964Z" }, - { url = "https://files.pythonhosted.org/packages/e8/a3/7a7a4488ba052767846b9c916d208b3ed114e3eb670ee984e4c565b9cf0d/jiter-0.12.0-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:b111b0e9152fa7df870ecaebb0bd30240d9f7fff1f2003bcb4ed0f519941820b", size = 510701, upload-time = "2025-11-09T20:48:24.483Z" }, - { url = "https://files.pythonhosted.org/packages/c3/16/052ffbf9d0467b70af24e30f91e0579e13ded0c17bb4a8eb2aed3cb60131/jiter-0.12.0-cp314-cp314-win32.whl", hash = "sha256:a78befb9cc0a45b5a5a0d537b06f8544c2ebb60d19d02c41ff15da28a9e22d42", size = 205029, upload-time = "2025-11-09T20:48:25.749Z" }, - { url = "https://files.pythonhosted.org/packages/e4/18/3cf1f3f0ccc789f76b9a754bdb7a6977e5d1d671ee97a9e14f7eb728d80e/jiter-0.12.0-cp314-cp314-win_amd64.whl", hash = "sha256:e1fe01c082f6aafbe5c8faf0ff074f38dfb911d53f07ec333ca03f8f6226debf", size = 204960, upload-time = "2025-11-09T20:48:27.415Z" }, - { url = "https://files.pythonhosted.org/packages/02/68/736821e52ecfdeeb0f024b8ab01b5a229f6b9293bbdb444c27efade50b0f/jiter-0.12.0-cp314-cp314-win_arm64.whl", hash = "sha256:d72f3b5a432a4c546ea4bedc84cce0c3404874f1d1676260b9c7f048a9855451", size = 185529, upload-time = "2025-11-09T20:48:29.125Z" }, - { url = "https://files.pythonhosted.org/packages/30/61/12ed8ee7a643cce29ac97c2281f9ce3956eb76b037e88d290f4ed0d41480/jiter-0.12.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:e6ded41aeba3603f9728ed2b6196e4df875348ab97b28fc8afff115ed42ba7a7", size = 318974, upload-time = "2025-11-09T20:48:30.87Z" }, - { url = "https://files.pythonhosted.org/packages/2d/c6/f3041ede6d0ed5e0e79ff0de4c8f14f401bbf196f2ef3971cdbe5fd08d1d/jiter-0.12.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a947920902420a6ada6ad51892082521978e9dd44a802663b001436e4b771684", size = 345932, upload-time = "2025-11-09T20:48:32.658Z" }, - { url = "https://files.pythonhosted.org/packages/d5/5d/4d94835889edd01ad0e2dbfc05f7bdfaed46292e7b504a6ac7839aa00edb/jiter-0.12.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:add5e227e0554d3a52cf390a7635edaffdf4f8fce4fdbcef3cc2055bb396a30c", size = 367243, upload-time = "2025-11-09T20:48:34.093Z" }, - { url = "https://files.pythonhosted.org/packages/fd/76/0051b0ac2816253a99d27baf3dda198663aff882fa6ea7deeb94046da24e/jiter-0.12.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f9b1cda8fcb736250d7e8711d4580ebf004a46771432be0ae4796944b5dfa5d", size = 479315, upload-time = "2025-11-09T20:48:35.507Z" }, - { url = "https://files.pythonhosted.org/packages/70/ae/83f793acd68e5cb24e483f44f482a1a15601848b9b6f199dacb970098f77/jiter-0.12.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:deeb12a2223fe0135c7ff1356a143d57f95bbf1f4a66584f1fc74df21d86b993", size = 380714, upload-time = "2025-11-09T20:48:40.014Z" }, - { url = "https://files.pythonhosted.org/packages/b1/5e/4808a88338ad2c228b1126b93fcd8ba145e919e886fe910d578230dabe3b/jiter-0.12.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c596cc0f4cb574877550ce4ecd51f8037469146addd676d7c1a30ebe6391923f", size = 365168, upload-time = "2025-11-09T20:48:41.462Z" }, - { url = "https://files.pythonhosted.org/packages/0c/d4/04619a9e8095b42aef436b5aeb4c0282b4ff1b27d1db1508df9f5dc82750/jiter-0.12.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5ab4c823b216a4aeab3fdbf579c5843165756bd9ad87cc6b1c65919c4715f783", size = 387893, upload-time = "2025-11-09T20:48:42.921Z" }, - { url = "https://files.pythonhosted.org/packages/17/ea/d3c7e62e4546fdc39197fa4a4315a563a89b95b6d54c0d25373842a59cbe/jiter-0.12.0-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:e427eee51149edf962203ff8db75a7514ab89be5cb623fb9cea1f20b54f1107b", size = 520828, upload-time = "2025-11-09T20:48:44.278Z" }, - { url = "https://files.pythonhosted.org/packages/cc/0b/c6d3562a03fd767e31cb119d9041ea7958c3c80cb3d753eafb19b3b18349/jiter-0.12.0-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:edb868841f84c111255ba5e80339d386d937ec1fdce419518ce1bd9370fac5b6", size = 511009, upload-time = "2025-11-09T20:48:45.726Z" }, - { url = "https://files.pythonhosted.org/packages/aa/51/2cb4468b3448a8385ebcd15059d325c9ce67df4e2758d133ab9442b19834/jiter-0.12.0-cp314-cp314t-win32.whl", hash = "sha256:8bbcfe2791dfdb7c5e48baf646d37a6a3dcb5a97a032017741dea9f817dca183", size = 205110, upload-time = "2025-11-09T20:48:47.033Z" }, - { url = "https://files.pythonhosted.org/packages/b2/c5/ae5ec83dec9c2d1af805fd5fe8f74ebded9c8670c5210ec7820ce0dbeb1e/jiter-0.12.0-cp314-cp314t-win_amd64.whl", hash = "sha256:2fa940963bf02e1d8226027ef461e36af472dea85d36054ff835aeed944dd873", size = 205223, upload-time = "2025-11-09T20:48:49.076Z" }, - { url = "https://files.pythonhosted.org/packages/97/9a/3c5391907277f0e55195550cf3fa8e293ae9ee0c00fb402fec1e38c0c82f/jiter-0.12.0-cp314-cp314t-win_arm64.whl", hash = "sha256:506c9708dd29b27288f9f8f1140c3cb0e3d8ddb045956d7757b1fa0e0f39a473", size = 185564, upload-time = "2025-11-09T20:48:50.376Z" }, -] - -[[package]] -name = "markdown-it-py" -version = "4.0.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "mdurl" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3", size = 73070, upload-time = "2025-08-11T12:57:52.854Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", size = 87321, upload-time = "2025-08-11T12:57:51.923Z" }, -] - -[[package]] -name = "markupsafe" -version = "3.0.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313, upload-time = "2025-09-27T18:37:40.426Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622, upload-time = "2025-09-27T18:36:41.777Z" }, - { url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029, upload-time = "2025-09-27T18:36:43.257Z" }, - { url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374, upload-time = "2025-09-27T18:36:44.508Z" }, - { url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", size = 22980, upload-time = "2025-09-27T18:36:45.385Z" }, - { url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", size = 21990, upload-time = "2025-09-27T18:36:46.916Z" }, - { url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", size = 23784, upload-time = "2025-09-27T18:36:47.884Z" }, - { url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", size = 21588, upload-time = "2025-09-27T18:36:48.82Z" }, - { url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", size = 23041, upload-time = "2025-09-27T18:36:49.797Z" }, - { url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543, upload-time = "2025-09-27T18:36:51.584Z" }, - { url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113, upload-time = "2025-09-27T18:36:52.537Z" }, - { url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911, upload-time = "2025-09-27T18:36:53.513Z" }, - { url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", size = 11658, upload-time = "2025-09-27T18:36:54.819Z" }, - { url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", size = 12066, upload-time = "2025-09-27T18:36:55.714Z" }, - { url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", size = 25639, upload-time = "2025-09-27T18:36:56.908Z" }, - { url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", size = 23569, upload-time = "2025-09-27T18:36:57.913Z" }, - { url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", size = 23284, upload-time = "2025-09-27T18:36:58.833Z" }, - { url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", size = 24801, upload-time = "2025-09-27T18:36:59.739Z" }, - { url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", size = 22769, upload-time = "2025-09-27T18:37:00.719Z" }, - { url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", size = 23642, upload-time = "2025-09-27T18:37:01.673Z" }, - { url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612, upload-time = "2025-09-27T18:37:02.639Z" }, - { url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200, upload-time = "2025-09-27T18:37:03.582Z" }, - { url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973, upload-time = "2025-09-27T18:37:04.929Z" }, - { url = "https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe", size = 11619, upload-time = "2025-09-27T18:37:06.342Z" }, - { url = "https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026", size = 12029, upload-time = "2025-09-27T18:37:07.213Z" }, - { url = "https://files.pythonhosted.org/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737", size = 24408, upload-time = "2025-09-27T18:37:09.572Z" }, - { url = "https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97", size = 23005, upload-time = "2025-09-27T18:37:10.58Z" }, - { url = "https://files.pythonhosted.org/packages/bc/20/b7fdf89a8456b099837cd1dc21974632a02a999ec9bf7ca3e490aacd98e7/markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d", size = 22048, upload-time = "2025-09-27T18:37:11.547Z" }, - { url = "https://files.pythonhosted.org/packages/9a/a7/591f592afdc734f47db08a75793a55d7fbcc6902a723ae4cfbab61010cc5/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda", size = 23821, upload-time = "2025-09-27T18:37:12.48Z" }, - { url = "https://files.pythonhosted.org/packages/7d/33/45b24e4f44195b26521bc6f1a82197118f74df348556594bd2262bda1038/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf", size = 21606, upload-time = "2025-09-27T18:37:13.485Z" }, - { url = "https://files.pythonhosted.org/packages/ff/0e/53dfaca23a69fbfbbf17a4b64072090e70717344c52eaaaa9c5ddff1e5f0/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe", size = 23043, upload-time = "2025-09-27T18:37:14.408Z" }, - { url = "https://files.pythonhosted.org/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9", size = 14747, upload-time = "2025-09-27T18:37:15.36Z" }, - { url = "https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581", size = 15341, upload-time = "2025-09-27T18:37:16.496Z" }, - { url = "https://files.pythonhosted.org/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4", size = 14073, upload-time = "2025-09-27T18:37:17.476Z" }, - { url = "https://files.pythonhosted.org/packages/3c/f0/57689aa4076e1b43b15fdfa646b04653969d50cf30c32a102762be2485da/markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab", size = 11661, upload-time = "2025-09-27T18:37:18.453Z" }, - { url = "https://files.pythonhosted.org/packages/89/c3/2e67a7ca217c6912985ec766c6393b636fb0c2344443ff9d91404dc4c79f/markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175", size = 12069, upload-time = "2025-09-27T18:37:19.332Z" }, - { url = "https://files.pythonhosted.org/packages/f0/00/be561dce4e6ca66b15276e184ce4b8aec61fe83662cce2f7d72bd3249d28/markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634", size = 25670, upload-time = "2025-09-27T18:37:20.245Z" }, - { url = "https://files.pythonhosted.org/packages/50/09/c419f6f5a92e5fadde27efd190eca90f05e1261b10dbd8cbcb39cd8ea1dc/markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50", size = 23598, upload-time = "2025-09-27T18:37:21.177Z" }, - { url = "https://files.pythonhosted.org/packages/22/44/a0681611106e0b2921b3033fc19bc53323e0b50bc70cffdd19f7d679bb66/markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e", size = 23261, upload-time = "2025-09-27T18:37:22.167Z" }, - { url = "https://files.pythonhosted.org/packages/5f/57/1b0b3f100259dc9fffe780cfb60d4be71375510e435efec3d116b6436d43/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5", size = 24835, upload-time = "2025-09-27T18:37:23.296Z" }, - { url = "https://files.pythonhosted.org/packages/26/6a/4bf6d0c97c4920f1597cc14dd720705eca0bf7c787aebc6bb4d1bead5388/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523", size = 22733, upload-time = "2025-09-27T18:37:24.237Z" }, - { url = "https://files.pythonhosted.org/packages/14/c7/ca723101509b518797fedc2fdf79ba57f886b4aca8a7d31857ba3ee8281f/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc", size = 23672, upload-time = "2025-09-27T18:37:25.271Z" }, - { url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", size = 14819, upload-time = "2025-09-27T18:37:26.285Z" }, - { url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", size = 15426, upload-time = "2025-09-27T18:37:27.316Z" }, - { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" }, -] - -[[package]] -name = "mdurl" -version = "0.1.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, -] - -[[package]] -name = "multidict" -version = "6.7.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/80/1e/5492c365f222f907de1039b91f922b93fa4f764c713ee858d235495d8f50/multidict-6.7.0.tar.gz", hash = "sha256:c6e99d9a65ca282e578dfea819cfa9c0a62b2499d8677392e09feaf305e9e6f5", size = 101834, upload-time = "2025-10-06T14:52:30.657Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d2/86/33272a544eeb36d66e4d9a920602d1a2f57d4ebea4ef3cdfe5a912574c95/multidict-6.7.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:bee7c0588aa0076ce77c0ea5d19a68d76ad81fcd9fe8501003b9a24f9d4000f6", size = 76135, upload-time = "2025-10-06T14:49:54.26Z" }, - { url = "https://files.pythonhosted.org/packages/91/1c/eb97db117a1ebe46d457a3d235a7b9d2e6dcab174f42d1b67663dd9e5371/multidict-6.7.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7ef6b61cad77091056ce0e7ce69814ef72afacb150b7ac6a3e9470def2198159", size = 45117, upload-time = "2025-10-06T14:49:55.82Z" }, - { url = "https://files.pythonhosted.org/packages/f1/d8/6c3442322e41fb1dd4de8bd67bfd11cd72352ac131f6368315617de752f1/multidict-6.7.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9c0359b1ec12b1d6849c59f9d319610b7f20ef990a6d454ab151aa0e3b9f78ca", size = 43472, upload-time = "2025-10-06T14:49:57.048Z" }, - { url = "https://files.pythonhosted.org/packages/75/3f/e2639e80325af0b6c6febdf8e57cc07043ff15f57fa1ef808f4ccb5ac4cd/multidict-6.7.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:cd240939f71c64bd658f186330603aac1a9a81bf6273f523fca63673cb7378a8", size = 249342, upload-time = "2025-10-06T14:49:58.368Z" }, - { url = "https://files.pythonhosted.org/packages/5d/cc/84e0585f805cbeaa9cbdaa95f9a3d6aed745b9d25700623ac89a6ecff400/multidict-6.7.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a60a4d75718a5efa473ebd5ab685786ba0c67b8381f781d1be14da49f1a2dc60", size = 257082, upload-time = "2025-10-06T14:49:59.89Z" }, - { url = "https://files.pythonhosted.org/packages/b0/9c/ac851c107c92289acbbf5cfb485694084690c1b17e555f44952c26ddc5bd/multidict-6.7.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:53a42d364f323275126aff81fb67c5ca1b7a04fda0546245730a55c8c5f24bc4", size = 240704, upload-time = "2025-10-06T14:50:01.485Z" }, - { url = "https://files.pythonhosted.org/packages/50/cc/5f93e99427248c09da95b62d64b25748a5f5c98c7c2ab09825a1d6af0e15/multidict-6.7.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3b29b980d0ddbecb736735ee5bef69bb2ddca56eff603c86f3f29a1128299b4f", size = 266355, upload-time = "2025-10-06T14:50:02.955Z" }, - { url = "https://files.pythonhosted.org/packages/ec/0c/2ec1d883ceb79c6f7f6d7ad90c919c898f5d1c6ea96d322751420211e072/multidict-6.7.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f8a93b1c0ed2d04b97a5e9336fd2d33371b9a6e29ab7dd6503d63407c20ffbaf", size = 267259, upload-time = "2025-10-06T14:50:04.446Z" }, - { url = "https://files.pythonhosted.org/packages/c6/2d/f0b184fa88d6630aa267680bdb8623fb69cb0d024b8c6f0d23f9a0f406d3/multidict-6.7.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9ff96e8815eecacc6645da76c413eb3b3d34cfca256c70b16b286a687d013c32", size = 254903, upload-time = "2025-10-06T14:50:05.98Z" }, - { url = "https://files.pythonhosted.org/packages/06/c9/11ea263ad0df7dfabcad404feb3c0dd40b131bc7f232d5537f2fb1356951/multidict-6.7.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7516c579652f6a6be0e266aec0acd0db80829ca305c3d771ed898538804c2036", size = 252365, upload-time = "2025-10-06T14:50:07.511Z" }, - { url = "https://files.pythonhosted.org/packages/41/88/d714b86ee2c17d6e09850c70c9d310abac3d808ab49dfa16b43aba9d53fd/multidict-6.7.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:040f393368e63fb0f3330e70c26bfd336656bed925e5cbe17c9da839a6ab13ec", size = 250062, upload-time = "2025-10-06T14:50:09.074Z" }, - { url = "https://files.pythonhosted.org/packages/15/fe/ad407bb9e818c2b31383f6131ca19ea7e35ce93cf1310fce69f12e89de75/multidict-6.7.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b3bc26a951007b1057a1c543af845f1c7e3e71cc240ed1ace7bf4484aa99196e", size = 249683, upload-time = "2025-10-06T14:50:10.714Z" }, - { url = "https://files.pythonhosted.org/packages/8c/a4/a89abdb0229e533fb925e7c6e5c40201c2873efebc9abaf14046a4536ee6/multidict-6.7.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:7b022717c748dd1992a83e219587aabe45980d88969f01b316e78683e6285f64", size = 261254, upload-time = "2025-10-06T14:50:12.28Z" }, - { url = "https://files.pythonhosted.org/packages/8d/aa/0e2b27bd88b40a4fb8dc53dd74eecac70edaa4c1dd0707eb2164da3675b3/multidict-6.7.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:9600082733859f00d79dee64effc7aef1beb26adb297416a4ad2116fd61374bd", size = 257967, upload-time = "2025-10-06T14:50:14.16Z" }, - { url = "https://files.pythonhosted.org/packages/d0/8e/0c67b7120d5d5f6d874ed85a085f9dc770a7f9d8813e80f44a9fec820bb7/multidict-6.7.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:94218fcec4d72bc61df51c198d098ce2b378e0ccbac41ddbed5ef44092913288", size = 250085, upload-time = "2025-10-06T14:50:15.639Z" }, - { url = "https://files.pythonhosted.org/packages/ba/55/b73e1d624ea4b8fd4dd07a3bb70f6e4c7c6c5d9d640a41c6ffe5cdbd2a55/multidict-6.7.0-cp313-cp313-win32.whl", hash = "sha256:a37bd74c3fa9d00be2d7b8eca074dc56bd8077ddd2917a839bd989612671ed17", size = 41713, upload-time = "2025-10-06T14:50:17.066Z" }, - { url = "https://files.pythonhosted.org/packages/32/31/75c59e7d3b4205075b4c183fa4ca398a2daf2303ddf616b04ae6ef55cffe/multidict-6.7.0-cp313-cp313-win_amd64.whl", hash = "sha256:30d193c6cc6d559db42b6bcec8a5d395d34d60c9877a0b71ecd7c204fcf15390", size = 45915, upload-time = "2025-10-06T14:50:18.264Z" }, - { url = "https://files.pythonhosted.org/packages/31/2a/8987831e811f1184c22bc2e45844934385363ee61c0a2dcfa8f71b87e608/multidict-6.7.0-cp313-cp313-win_arm64.whl", hash = "sha256:ea3334cabe4d41b7ccd01e4d349828678794edbc2d3ae97fc162a3312095092e", size = 43077, upload-time = "2025-10-06T14:50:19.853Z" }, - { url = "https://files.pythonhosted.org/packages/e8/68/7b3a5170a382a340147337b300b9eb25a9ddb573bcdfff19c0fa3f31ffba/multidict-6.7.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:ad9ce259f50abd98a1ca0aa6e490b58c316a0fce0617f609723e40804add2c00", size = 83114, upload-time = "2025-10-06T14:50:21.223Z" }, - { url = "https://files.pythonhosted.org/packages/55/5c/3fa2d07c84df4e302060f555bbf539310980362236ad49f50eeb0a1c1eb9/multidict-6.7.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:07f5594ac6d084cbb5de2df218d78baf55ef150b91f0ff8a21cc7a2e3a5a58eb", size = 48442, upload-time = "2025-10-06T14:50:22.871Z" }, - { url = "https://files.pythonhosted.org/packages/fc/56/67212d33239797f9bd91962bb899d72bb0f4c35a8652dcdb8ed049bef878/multidict-6.7.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0591b48acf279821a579282444814a2d8d0af624ae0bc600aa4d1b920b6e924b", size = 46885, upload-time = "2025-10-06T14:50:24.258Z" }, - { url = "https://files.pythonhosted.org/packages/46/d1/908f896224290350721597a61a69cd19b89ad8ee0ae1f38b3f5cd12ea2ac/multidict-6.7.0-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:749a72584761531d2b9467cfbdfd29487ee21124c304c4b6cb760d8777b27f9c", size = 242588, upload-time = "2025-10-06T14:50:25.716Z" }, - { url = "https://files.pythonhosted.org/packages/ab/67/8604288bbd68680eee0ab568fdcb56171d8b23a01bcd5cb0c8fedf6e5d99/multidict-6.7.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b4c3d199f953acd5b446bf7c0de1fe25d94e09e79086f8dc2f48a11a129cdf1", size = 249966, upload-time = "2025-10-06T14:50:28.192Z" }, - { url = "https://files.pythonhosted.org/packages/20/33/9228d76339f1ba51e3efef7da3ebd91964d3006217aae13211653193c3ff/multidict-6.7.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:9fb0211dfc3b51efea2f349ec92c114d7754dd62c01f81c3e32b765b70c45c9b", size = 228618, upload-time = "2025-10-06T14:50:29.82Z" }, - { url = "https://files.pythonhosted.org/packages/f8/2d/25d9b566d10cab1c42b3b9e5b11ef79c9111eaf4463b8c257a3bd89e0ead/multidict-6.7.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a027ec240fe73a8d6281872690b988eed307cd7d91b23998ff35ff577ca688b5", size = 257539, upload-time = "2025-10-06T14:50:31.731Z" }, - { url = "https://files.pythonhosted.org/packages/b6/b1/8d1a965e6637fc33de3c0d8f414485c2b7e4af00f42cab3d84e7b955c222/multidict-6.7.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1d964afecdf3a8288789df2f5751dc0a8261138c3768d9af117ed384e538fad", size = 256345, upload-time = "2025-10-06T14:50:33.26Z" }, - { url = "https://files.pythonhosted.org/packages/ba/0c/06b5a8adbdeedada6f4fb8d8f193d44a347223b11939b42953eeb6530b6b/multidict-6.7.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:caf53b15b1b7df9fbd0709aa01409000a2b4dd03a5f6f5cc548183c7c8f8b63c", size = 247934, upload-time = "2025-10-06T14:50:34.808Z" }, - { url = "https://files.pythonhosted.org/packages/8f/31/b2491b5fe167ca044c6eb4b8f2c9f3b8a00b24c432c365358eadac5d7625/multidict-6.7.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:654030da3197d927f05a536a66186070e98765aa5142794c9904555d3a9d8fb5", size = 245243, upload-time = "2025-10-06T14:50:36.436Z" }, - { url = "https://files.pythonhosted.org/packages/61/1a/982913957cb90406c8c94f53001abd9eafc271cb3e70ff6371590bec478e/multidict-6.7.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:2090d3718829d1e484706a2f525e50c892237b2bf9b17a79b059cb98cddc2f10", size = 235878, upload-time = "2025-10-06T14:50:37.953Z" }, - { url = "https://files.pythonhosted.org/packages/be/c0/21435d804c1a1cf7a2608593f4d19bca5bcbd7a81a70b253fdd1c12af9c0/multidict-6.7.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:2d2cfeec3f6f45651b3d408c4acec0ebf3daa9bc8a112a084206f5db5d05b754", size = 243452, upload-time = "2025-10-06T14:50:39.574Z" }, - { url = "https://files.pythonhosted.org/packages/54/0a/4349d540d4a883863191be6eb9a928846d4ec0ea007d3dcd36323bb058ac/multidict-6.7.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:4ef089f985b8c194d341eb2c24ae6e7408c9a0e2e5658699c92f497437d88c3c", size = 252312, upload-time = "2025-10-06T14:50:41.612Z" }, - { url = "https://files.pythonhosted.org/packages/26/64/d5416038dbda1488daf16b676e4dbfd9674dde10a0cc8f4fc2b502d8125d/multidict-6.7.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:e93a0617cd16998784bf4414c7e40f17a35d2350e5c6f0bd900d3a8e02bd3762", size = 246935, upload-time = "2025-10-06T14:50:43.972Z" }, - { url = "https://files.pythonhosted.org/packages/9f/8c/8290c50d14e49f35e0bd4abc25e1bc7711149ca9588ab7d04f886cdf03d9/multidict-6.7.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f0feece2ef8ebc42ed9e2e8c78fc4aa3cf455733b507c09ef7406364c94376c6", size = 243385, upload-time = "2025-10-06T14:50:45.648Z" }, - { url = "https://files.pythonhosted.org/packages/ef/a0/f83ae75e42d694b3fbad3e047670e511c138be747bc713cf1b10d5096416/multidict-6.7.0-cp313-cp313t-win32.whl", hash = "sha256:19a1d55338ec1be74ef62440ca9e04a2f001a04d0cc49a4983dc320ff0f3212d", size = 47777, upload-time = "2025-10-06T14:50:47.154Z" }, - { url = "https://files.pythonhosted.org/packages/dc/80/9b174a92814a3830b7357307a792300f42c9e94664b01dee8e457551fa66/multidict-6.7.0-cp313-cp313t-win_amd64.whl", hash = "sha256:3da4fb467498df97e986af166b12d01f05d2e04f978a9c1c680ea1988e0bc4b6", size = 53104, upload-time = "2025-10-06T14:50:48.851Z" }, - { url = "https://files.pythonhosted.org/packages/cc/28/04baeaf0428d95bb7a7bea0e691ba2f31394338ba424fb0679a9ed0f4c09/multidict-6.7.0-cp313-cp313t-win_arm64.whl", hash = "sha256:b4121773c49a0776461f4a904cdf6264c88e42218aaa8407e803ca8025872792", size = 45503, upload-time = "2025-10-06T14:50:50.16Z" }, - { url = "https://files.pythonhosted.org/packages/e2/b1/3da6934455dd4b261d4c72f897e3a5728eba81db59959f3a639245891baa/multidict-6.7.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3bab1e4aff7adaa34410f93b1f8e57c4b36b9af0426a76003f441ee1d3c7e842", size = 75128, upload-time = "2025-10-06T14:50:51.92Z" }, - { url = "https://files.pythonhosted.org/packages/14/2c/f069cab5b51d175a1a2cb4ccdf7a2c2dabd58aa5bd933fa036a8d15e2404/multidict-6.7.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:b8512bac933afc3e45fb2b18da8e59b78d4f408399a960339598374d4ae3b56b", size = 44410, upload-time = "2025-10-06T14:50:53.275Z" }, - { url = "https://files.pythonhosted.org/packages/42/e2/64bb41266427af6642b6b128e8774ed84c11b80a90702c13ac0a86bb10cc/multidict-6.7.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:79dcf9e477bc65414ebfea98ffd013cb39552b5ecd62908752e0e413d6d06e38", size = 43205, upload-time = "2025-10-06T14:50:54.911Z" }, - { url = "https://files.pythonhosted.org/packages/02/68/6b086fef8a3f1a8541b9236c594f0c9245617c29841f2e0395d979485cde/multidict-6.7.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:31bae522710064b5cbeddaf2e9f32b1abab70ac6ac91d42572502299e9953128", size = 245084, upload-time = "2025-10-06T14:50:56.369Z" }, - { url = "https://files.pythonhosted.org/packages/15/ee/f524093232007cd7a75c1d132df70f235cfd590a7c9eaccd7ff422ef4ae8/multidict-6.7.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a0df7ff02397bb63e2fd22af2c87dfa39e8c7f12947bc524dbdc528282c7e34", size = 252667, upload-time = "2025-10-06T14:50:57.991Z" }, - { url = "https://files.pythonhosted.org/packages/02/a5/eeb3f43ab45878f1895118c3ef157a480db58ede3f248e29b5354139c2c9/multidict-6.7.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7a0222514e8e4c514660e182d5156a415c13ef0aabbd71682fc714e327b95e99", size = 233590, upload-time = "2025-10-06T14:50:59.589Z" }, - { url = "https://files.pythonhosted.org/packages/6a/1e/76d02f8270b97269d7e3dbd45644b1785bda457b474315f8cf999525a193/multidict-6.7.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2397ab4daaf2698eb51a76721e98db21ce4f52339e535725de03ea962b5a3202", size = 264112, upload-time = "2025-10-06T14:51:01.183Z" }, - { url = "https://files.pythonhosted.org/packages/76/0b/c28a70ecb58963847c2a8efe334904cd254812b10e535aefb3bcce513918/multidict-6.7.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8891681594162635948a636c9fe0ff21746aeb3dd5463f6e25d9bea3a8a39ca1", size = 261194, upload-time = "2025-10-06T14:51:02.794Z" }, - { url = "https://files.pythonhosted.org/packages/b4/63/2ab26e4209773223159b83aa32721b4021ffb08102f8ac7d689c943fded1/multidict-6.7.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18706cc31dbf402a7945916dd5cddf160251b6dab8a2c5f3d6d5a55949f676b3", size = 248510, upload-time = "2025-10-06T14:51:04.724Z" }, - { url = "https://files.pythonhosted.org/packages/93/cd/06c1fa8282af1d1c46fd55c10a7930af652afdce43999501d4d68664170c/multidict-6.7.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f844a1bbf1d207dd311a56f383f7eda2d0e134921d45751842d8235e7778965d", size = 248395, upload-time = "2025-10-06T14:51:06.306Z" }, - { url = "https://files.pythonhosted.org/packages/99/ac/82cb419dd6b04ccf9e7e61befc00c77614fc8134362488b553402ecd55ce/multidict-6.7.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:d4393e3581e84e5645506923816b9cc81f5609a778c7e7534054091acc64d1c6", size = 239520, upload-time = "2025-10-06T14:51:08.091Z" }, - { url = "https://files.pythonhosted.org/packages/fa/f3/a0f9bf09493421bd8716a362e0cd1d244f5a6550f5beffdd6b47e885b331/multidict-6.7.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:fbd18dc82d7bf274b37aa48d664534330af744e03bccf696d6f4c6042e7d19e7", size = 245479, upload-time = "2025-10-06T14:51:10.365Z" }, - { url = "https://files.pythonhosted.org/packages/8d/01/476d38fc73a212843f43c852b0eee266b6971f0e28329c2184a8df90c376/multidict-6.7.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:b6234e14f9314731ec45c42fc4554b88133ad53a09092cc48a88e771c125dadb", size = 258903, upload-time = "2025-10-06T14:51:12.466Z" }, - { url = "https://files.pythonhosted.org/packages/49/6d/23faeb0868adba613b817d0e69c5f15531b24d462af8012c4f6de4fa8dc3/multidict-6.7.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:08d4379f9744d8f78d98c8673c06e202ffa88296f009c71bbafe8a6bf847d01f", size = 252333, upload-time = "2025-10-06T14:51:14.48Z" }, - { url = "https://files.pythonhosted.org/packages/1e/cc/48d02ac22b30fa247f7dad82866e4b1015431092f4ba6ebc7e77596e0b18/multidict-6.7.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:9fe04da3f79387f450fd0061d4dd2e45a72749d31bf634aecc9e27f24fdc4b3f", size = 243411, upload-time = "2025-10-06T14:51:16.072Z" }, - { url = "https://files.pythonhosted.org/packages/4a/03/29a8bf5a18abf1fe34535c88adbdfa88c9fb869b5a3b120692c64abe8284/multidict-6.7.0-cp314-cp314-win32.whl", hash = "sha256:fbafe31d191dfa7c4c51f7a6149c9fb7e914dcf9ffead27dcfd9f1ae382b3885", size = 40940, upload-time = "2025-10-06T14:51:17.544Z" }, - { url = "https://files.pythonhosted.org/packages/82/16/7ed27b680791b939de138f906d5cf2b4657b0d45ca6f5dd6236fdddafb1a/multidict-6.7.0-cp314-cp314-win_amd64.whl", hash = "sha256:2f67396ec0310764b9222a1728ced1ab638f61aadc6226f17a71dd9324f9a99c", size = 45087, upload-time = "2025-10-06T14:51:18.875Z" }, - { url = "https://files.pythonhosted.org/packages/cd/3c/e3e62eb35a1950292fe39315d3c89941e30a9d07d5d2df42965ab041da43/multidict-6.7.0-cp314-cp314-win_arm64.whl", hash = "sha256:ba672b26069957ee369cfa7fc180dde1fc6f176eaf1e6beaf61fbebbd3d9c000", size = 42368, upload-time = "2025-10-06T14:51:20.225Z" }, - { url = "https://files.pythonhosted.org/packages/8b/40/cd499bd0dbc5f1136726db3153042a735fffd0d77268e2ee20d5f33c010f/multidict-6.7.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:c1dcc7524066fa918c6a27d61444d4ee7900ec635779058571f70d042d86ed63", size = 82326, upload-time = "2025-10-06T14:51:21.588Z" }, - { url = "https://files.pythonhosted.org/packages/13/8a/18e031eca251c8df76daf0288e6790561806e439f5ce99a170b4af30676b/multidict-6.7.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:27e0b36c2d388dc7b6ced3406671b401e84ad7eb0656b8f3a2f46ed0ce483718", size = 48065, upload-time = "2025-10-06T14:51:22.93Z" }, - { url = "https://files.pythonhosted.org/packages/40/71/5e6701277470a87d234e433fb0a3a7deaf3bcd92566e421e7ae9776319de/multidict-6.7.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2a7baa46a22e77f0988e3b23d4ede5513ebec1929e34ee9495be535662c0dfe2", size = 46475, upload-time = "2025-10-06T14:51:24.352Z" }, - { url = "https://files.pythonhosted.org/packages/fe/6a/bab00cbab6d9cfb57afe1663318f72ec28289ea03fd4e8236bb78429893a/multidict-6.7.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:7bf77f54997a9166a2f5675d1201520586439424c2511723a7312bdb4bcc034e", size = 239324, upload-time = "2025-10-06T14:51:25.822Z" }, - { url = "https://files.pythonhosted.org/packages/2a/5f/8de95f629fc22a7769ade8b41028e3e5a822c1f8904f618d175945a81ad3/multidict-6.7.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e011555abada53f1578d63389610ac8a5400fc70ce71156b0aa30d326f1a5064", size = 246877, upload-time = "2025-10-06T14:51:27.604Z" }, - { url = "https://files.pythonhosted.org/packages/23/b4/38881a960458f25b89e9f4a4fdcb02ac101cfa710190db6e5528841e67de/multidict-6.7.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:28b37063541b897fd6a318007373930a75ca6d6ac7c940dbe14731ffdd8d498e", size = 225824, upload-time = "2025-10-06T14:51:29.664Z" }, - { url = "https://files.pythonhosted.org/packages/1e/39/6566210c83f8a261575f18e7144736059f0c460b362e96e9cf797a24b8e7/multidict-6.7.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:05047ada7a2fde2631a0ed706f1fd68b169a681dfe5e4cf0f8e4cb6618bbc2cd", size = 253558, upload-time = "2025-10-06T14:51:31.684Z" }, - { url = "https://files.pythonhosted.org/packages/00/a3/67f18315100f64c269f46e6c0319fa87ba68f0f64f2b8e7fd7c72b913a0b/multidict-6.7.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:716133f7d1d946a4e1b91b1756b23c088881e70ff180c24e864c26192ad7534a", size = 252339, upload-time = "2025-10-06T14:51:33.699Z" }, - { url = "https://files.pythonhosted.org/packages/c8/2a/1cb77266afee2458d82f50da41beba02159b1d6b1f7973afc9a1cad1499b/multidict-6.7.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d1bed1b467ef657f2a0ae62844a607909ef1c6889562de5e1d505f74457d0b96", size = 244895, upload-time = "2025-10-06T14:51:36.189Z" }, - { url = "https://files.pythonhosted.org/packages/dd/72/09fa7dd487f119b2eb9524946ddd36e2067c08510576d43ff68469563b3b/multidict-6.7.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ca43bdfa5d37bd6aee89d85e1d0831fb86e25541be7e9d376ead1b28974f8e5e", size = 241862, upload-time = "2025-10-06T14:51:41.291Z" }, - { url = "https://files.pythonhosted.org/packages/65/92/bc1f8bd0853d8669300f732c801974dfc3702c3eeadae2f60cef54dc69d7/multidict-6.7.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:44b546bd3eb645fd26fb949e43c02a25a2e632e2ca21a35e2e132c8105dc8599", size = 232376, upload-time = "2025-10-06T14:51:43.55Z" }, - { url = "https://files.pythonhosted.org/packages/09/86/ac39399e5cb9d0c2ac8ef6e10a768e4d3bc933ac808d49c41f9dc23337eb/multidict-6.7.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:a6ef16328011d3f468e7ebc326f24c1445f001ca1dec335b2f8e66bed3006394", size = 240272, upload-time = "2025-10-06T14:51:45.265Z" }, - { url = "https://files.pythonhosted.org/packages/3d/b6/fed5ac6b8563ec72df6cb1ea8dac6d17f0a4a1f65045f66b6d3bf1497c02/multidict-6.7.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:5aa873cbc8e593d361ae65c68f85faadd755c3295ea2c12040ee146802f23b38", size = 248774, upload-time = "2025-10-06T14:51:46.836Z" }, - { url = "https://files.pythonhosted.org/packages/6b/8d/b954d8c0dc132b68f760aefd45870978deec6818897389dace00fcde32ff/multidict-6.7.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:3d7b6ccce016e29df4b7ca819659f516f0bc7a4b3efa3bb2012ba06431b044f9", size = 242731, upload-time = "2025-10-06T14:51:48.541Z" }, - { url = "https://files.pythonhosted.org/packages/16/9d/a2dac7009125d3540c2f54e194829ea18ac53716c61b655d8ed300120b0f/multidict-6.7.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:171b73bd4ee683d307599b66793ac80981b06f069b62eea1c9e29c9241aa66b0", size = 240193, upload-time = "2025-10-06T14:51:50.355Z" }, - { url = "https://files.pythonhosted.org/packages/39/ca/c05f144128ea232ae2178b008d5011d4e2cea86e4ee8c85c2631b1b94802/multidict-6.7.0-cp314-cp314t-win32.whl", hash = "sha256:b2d7f80c4e1fd010b07cb26820aae86b7e73b681ee4889684fb8d2d4537aab13", size = 48023, upload-time = "2025-10-06T14:51:51.883Z" }, - { url = "https://files.pythonhosted.org/packages/ba/8f/0a60e501584145588be1af5cc829265701ba3c35a64aec8e07cbb71d39bb/multidict-6.7.0-cp314-cp314t-win_amd64.whl", hash = "sha256:09929cab6fcb68122776d575e03c6cc64ee0b8fca48d17e135474b042ce515cd", size = 53507, upload-time = "2025-10-06T14:51:53.672Z" }, - { url = "https://files.pythonhosted.org/packages/7f/ae/3148b988a9c6239903e786eac19c889fab607c31d6efa7fb2147e5680f23/multidict-6.7.0-cp314-cp314t-win_arm64.whl", hash = "sha256:cc41db090ed742f32bd2d2c721861725e6109681eddf835d0a82bd3a5c382827", size = 44804, upload-time = "2025-10-06T14:51:55.415Z" }, - { url = "https://files.pythonhosted.org/packages/b7/da/7d22601b625e241d4f23ef1ebff8acfc60da633c9e7e7922e24d10f592b3/multidict-6.7.0-py3-none-any.whl", hash = "sha256:394fc5c42a333c9ffc3e421a4c85e08580d990e08b99f6bf35b4132114c5dcb3", size = 12317, upload-time = "2025-10-06T14:52:29.272Z" }, -] - -[[package]] -name = "o2o-castad-backend" -version = "0.1.0" -source = { editable = "." } -dependencies = [ - { name = "aiofiles" }, - { name = "aiohttp" }, - { name = "aiomysql" }, - { name = "asyncmy" }, - { name = "fastapi", extra = ["standard"] }, - { name = "fastapi-cli" }, - { name = "openai" }, - { name = "pydantic-settings" }, - { name = "redis" }, - { name = "ruff" }, - { name = "scalar-fastapi" }, - { name = "sqladmin", extra = ["full"] }, - { name = "sqlalchemy", extra = ["asyncio"] }, - { name = "uuid7" }, -] - -[package.dev-dependencies] -dev = [ - { name = "pytest" }, - { name = "pytest-asyncio" }, -] - -[package.metadata] -requires-dist = [ - { name = "aiofiles", specifier = ">=25.1.0" }, - { name = "aiohttp", specifier = ">=3.13.2" }, - { name = "aiomysql", specifier = ">=0.3.2" }, - { name = "asyncmy", specifier = ">=0.2.10" }, - { name = "fastapi", extras = ["standard"], specifier = ">=0.125.0" }, - { name = "fastapi-cli", specifier = ">=0.0.16" }, - { name = "openai", specifier = ">=2.13.0" }, - { name = "pydantic-settings", specifier = ">=2.12.0" }, - { name = "redis", specifier = ">=7.1.0" }, - { name = "ruff", specifier = ">=0.14.9" }, - { name = "scalar-fastapi", specifier = ">=1.5.0" }, - { name = "sqladmin", extras = ["full"], specifier = ">=0.22.0" }, - { name = "sqlalchemy", extras = ["asyncio"], specifier = ">=2.0.45" }, - { name = "uuid7", specifier = ">=0.1.0" }, -] - -[package.metadata.requires-dev] -dev = [ - { name = "pytest", specifier = ">=9.0.2" }, - { name = "pytest-asyncio", specifier = ">=1.3.0" }, -] - -[[package]] -name = "openai" -version = "2.14.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "anyio" }, - { name = "distro" }, - { name = "httpx" }, - { name = "jiter" }, - { name = "pydantic" }, - { name = "sniffio" }, - { name = "tqdm" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/d8/b1/12fe1c196bea326261718eb037307c1c1fe1dedc2d2d4de777df822e6238/openai-2.14.0.tar.gz", hash = "sha256:419357bedde9402d23bf8f2ee372fca1985a73348debba94bddff06f19459952", size = 626938, upload-time = "2025-12-19T03:28:45.742Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/27/4b/7c1a00c2c3fbd004253937f7520f692a9650767aa73894d7a34f0d65d3f4/openai-2.14.0-py3-none-any.whl", hash = "sha256:7ea40aca4ffc4c4a776e77679021b47eec1160e341f42ae086ba949c9dcc9183", size = 1067558, upload-time = "2025-12-19T03:28:43.727Z" }, -] - -[[package]] -name = "packaging" -version = "25.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, -] - -[[package]] -name = "pluggy" -version = "1.6.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, -] - -[[package]] -name = "propcache" -version = "0.4.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/9e/da/e9fc233cf63743258bff22b3dfa7ea5baef7b5bc324af47a0ad89b8ffc6f/propcache-0.4.1.tar.gz", hash = "sha256:f48107a8c637e80362555f37ecf49abe20370e557cc4ab374f04ec4423c97c3d", size = 46442, upload-time = "2025-10-08T19:49:02.291Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/bf/df/6d9c1b6ac12b003837dde8a10231a7344512186e87b36e855bef32241942/propcache-0.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:43eedf29202c08550aac1d14e0ee619b0430aaef78f85864c1a892294fbc28cf", size = 77750, upload-time = "2025-10-08T19:47:07.648Z" }, - { url = "https://files.pythonhosted.org/packages/8b/e8/677a0025e8a2acf07d3418a2e7ba529c9c33caf09d3c1f25513023c1db56/propcache-0.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d62cdfcfd89ccb8de04e0eda998535c406bf5e060ffd56be6c586cbcc05b3311", size = 44780, upload-time = "2025-10-08T19:47:08.851Z" }, - { url = "https://files.pythonhosted.org/packages/89/a4/92380f7ca60f99ebae761936bc48a72a639e8a47b29050615eef757cb2a7/propcache-0.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cae65ad55793da34db5f54e4029b89d3b9b9490d8abe1b4c7ab5d4b8ec7ebf74", size = 46308, upload-time = "2025-10-08T19:47:09.982Z" }, - { url = "https://files.pythonhosted.org/packages/2d/48/c5ac64dee5262044348d1d78a5f85dd1a57464a60d30daee946699963eb3/propcache-0.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:333ddb9031d2704a301ee3e506dc46b1fe5f294ec198ed6435ad5b6a085facfe", size = 208182, upload-time = "2025-10-08T19:47:11.319Z" }, - { url = "https://files.pythonhosted.org/packages/c6/0c/cd762dd011a9287389a6a3eb43aa30207bde253610cca06824aeabfe9653/propcache-0.4.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fd0858c20f078a32cf55f7e81473d96dcf3b93fd2ccdb3d40fdf54b8573df3af", size = 211215, upload-time = "2025-10-08T19:47:13.146Z" }, - { url = "https://files.pythonhosted.org/packages/30/3e/49861e90233ba36890ae0ca4c660e95df565b2cd15d4a68556ab5865974e/propcache-0.4.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:678ae89ebc632c5c204c794f8dab2837c5f159aeb59e6ed0539500400577298c", size = 218112, upload-time = "2025-10-08T19:47:14.913Z" }, - { url = "https://files.pythonhosted.org/packages/f1/8b/544bc867e24e1bd48f3118cecd3b05c694e160a168478fa28770f22fd094/propcache-0.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d472aeb4fbf9865e0c6d622d7f4d54a4e101a89715d8904282bb5f9a2f476c3f", size = 204442, upload-time = "2025-10-08T19:47:16.277Z" }, - { url = "https://files.pythonhosted.org/packages/50/a6/4282772fd016a76d3e5c0df58380a5ea64900afd836cec2c2f662d1b9bb3/propcache-0.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4d3df5fa7e36b3225954fba85589da77a0fe6a53e3976de39caf04a0db4c36f1", size = 199398, upload-time = "2025-10-08T19:47:17.962Z" }, - { url = "https://files.pythonhosted.org/packages/3e/ec/d8a7cd406ee1ddb705db2139f8a10a8a427100347bd698e7014351c7af09/propcache-0.4.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:ee17f18d2498f2673e432faaa71698032b0127ebf23ae5974eeaf806c279df24", size = 196920, upload-time = "2025-10-08T19:47:19.355Z" }, - { url = "https://files.pythonhosted.org/packages/f6/6c/f38ab64af3764f431e359f8baf9e0a21013e24329e8b85d2da32e8ed07ca/propcache-0.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:580e97762b950f993ae618e167e7be9256b8353c2dcd8b99ec100eb50f5286aa", size = 203748, upload-time = "2025-10-08T19:47:21.338Z" }, - { url = "https://files.pythonhosted.org/packages/d6/e3/fa846bd70f6534d647886621388f0a265254d30e3ce47e5c8e6e27dbf153/propcache-0.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:501d20b891688eb8e7aa903021f0b72d5a55db40ffaab27edefd1027caaafa61", size = 205877, upload-time = "2025-10-08T19:47:23.059Z" }, - { url = "https://files.pythonhosted.org/packages/e2/39/8163fc6f3133fea7b5f2827e8eba2029a0277ab2c5beee6c1db7b10fc23d/propcache-0.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a0bd56e5b100aef69bd8562b74b46254e7c8812918d3baa700c8a8009b0af66", size = 199437, upload-time = "2025-10-08T19:47:24.445Z" }, - { url = "https://files.pythonhosted.org/packages/93/89/caa9089970ca49c7c01662bd0eeedfe85494e863e8043565aeb6472ce8fe/propcache-0.4.1-cp313-cp313-win32.whl", hash = "sha256:bcc9aaa5d80322bc2fb24bb7accb4a30f81e90ab8d6ba187aec0744bc302ad81", size = 37586, upload-time = "2025-10-08T19:47:25.736Z" }, - { url = "https://files.pythonhosted.org/packages/f5/ab/f76ec3c3627c883215b5c8080debb4394ef5a7a29be811f786415fc1e6fd/propcache-0.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:381914df18634f5494334d201e98245c0596067504b9372d8cf93f4bb23e025e", size = 40790, upload-time = "2025-10-08T19:47:26.847Z" }, - { url = "https://files.pythonhosted.org/packages/59/1b/e71ae98235f8e2ba5004d8cb19765a74877abf189bc53fc0c80d799e56c3/propcache-0.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:8873eb4460fd55333ea49b7d189749ecf6e55bf85080f11b1c4530ed3034cba1", size = 37158, upload-time = "2025-10-08T19:47:27.961Z" }, - { url = "https://files.pythonhosted.org/packages/83/ce/a31bbdfc24ee0dcbba458c8175ed26089cf109a55bbe7b7640ed2470cfe9/propcache-0.4.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:92d1935ee1f8d7442da9c0c4fa7ac20d07e94064184811b685f5c4fada64553b", size = 81451, upload-time = "2025-10-08T19:47:29.445Z" }, - { url = "https://files.pythonhosted.org/packages/25/9c/442a45a470a68456e710d96cacd3573ef26a1d0a60067e6a7d5e655621ed/propcache-0.4.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:473c61b39e1460d386479b9b2f337da492042447c9b685f28be4f74d3529e566", size = 46374, upload-time = "2025-10-08T19:47:30.579Z" }, - { url = "https://files.pythonhosted.org/packages/f4/bf/b1d5e21dbc3b2e889ea4327044fb16312a736d97640fb8b6aa3f9c7b3b65/propcache-0.4.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:c0ef0aaafc66fbd87842a3fe3902fd889825646bc21149eafe47be6072725835", size = 48396, upload-time = "2025-10-08T19:47:31.79Z" }, - { url = "https://files.pythonhosted.org/packages/f4/04/5b4c54a103d480e978d3c8a76073502b18db0c4bc17ab91b3cb5092ad949/propcache-0.4.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f95393b4d66bfae908c3ca8d169d5f79cd65636ae15b5e7a4f6e67af675adb0e", size = 275950, upload-time = "2025-10-08T19:47:33.481Z" }, - { url = "https://files.pythonhosted.org/packages/b4/c1/86f846827fb969c4b78b0af79bba1d1ea2156492e1b83dea8b8a6ae27395/propcache-0.4.1-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c07fda85708bc48578467e85099645167a955ba093be0a2dcba962195676e859", size = 273856, upload-time = "2025-10-08T19:47:34.906Z" }, - { url = "https://files.pythonhosted.org/packages/36/1d/fc272a63c8d3bbad6878c336c7a7dea15e8f2d23a544bda43205dfa83ada/propcache-0.4.1-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:af223b406d6d000830c6f65f1e6431783fc3f713ba3e6cc8c024d5ee96170a4b", size = 280420, upload-time = "2025-10-08T19:47:36.338Z" }, - { url = "https://files.pythonhosted.org/packages/07/0c/01f2219d39f7e53d52e5173bcb09c976609ba30209912a0680adfb8c593a/propcache-0.4.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a78372c932c90ee474559c5ddfffd718238e8673c340dc21fe45c5b8b54559a0", size = 263254, upload-time = "2025-10-08T19:47:37.692Z" }, - { url = "https://files.pythonhosted.org/packages/2d/18/cd28081658ce597898f0c4d174d4d0f3c5b6d4dc27ffafeef835c95eb359/propcache-0.4.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:564d9f0d4d9509e1a870c920a89b2fec951b44bf5ba7d537a9e7c1ccec2c18af", size = 261205, upload-time = "2025-10-08T19:47:39.659Z" }, - { url = "https://files.pythonhosted.org/packages/7a/71/1f9e22eb8b8316701c2a19fa1f388c8a3185082607da8e406a803c9b954e/propcache-0.4.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:17612831fda0138059cc5546f4d12a2aacfb9e47068c06af35c400ba58ba7393", size = 247873, upload-time = "2025-10-08T19:47:41.084Z" }, - { url = "https://files.pythonhosted.org/packages/4a/65/3d4b61f36af2b4eddba9def857959f1016a51066b4f1ce348e0cf7881f58/propcache-0.4.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:41a89040cb10bd345b3c1a873b2bf36413d48da1def52f268a055f7398514874", size = 262739, upload-time = "2025-10-08T19:47:42.51Z" }, - { url = "https://files.pythonhosted.org/packages/2a/42/26746ab087faa77c1c68079b228810436ccd9a5ce9ac85e2b7307195fd06/propcache-0.4.1-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:e35b88984e7fa64aacecea39236cee32dd9bd8c55f57ba8a75cf2399553f9bd7", size = 263514, upload-time = "2025-10-08T19:47:43.927Z" }, - { url = "https://files.pythonhosted.org/packages/94/13/630690fe201f5502d2403dd3cfd451ed8858fe3c738ee88d095ad2ff407b/propcache-0.4.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f8b465489f927b0df505cbe26ffbeed4d6d8a2bbc61ce90eb074ff129ef0ab1", size = 257781, upload-time = "2025-10-08T19:47:45.448Z" }, - { url = "https://files.pythonhosted.org/packages/92/f7/1d4ec5841505f423469efbfc381d64b7b467438cd5a4bbcbb063f3b73d27/propcache-0.4.1-cp313-cp313t-win32.whl", hash = "sha256:2ad890caa1d928c7c2965b48f3a3815c853180831d0e5503d35cf00c472f4717", size = 41396, upload-time = "2025-10-08T19:47:47.202Z" }, - { url = "https://files.pythonhosted.org/packages/48/f0/615c30622316496d2cbbc29f5985f7777d3ada70f23370608c1d3e081c1f/propcache-0.4.1-cp313-cp313t-win_amd64.whl", hash = "sha256:f7ee0e597f495cf415bcbd3da3caa3bd7e816b74d0d52b8145954c5e6fd3ff37", size = 44897, upload-time = "2025-10-08T19:47:48.336Z" }, - { url = "https://files.pythonhosted.org/packages/fd/ca/6002e46eccbe0e33dcd4069ef32f7f1c9e243736e07adca37ae8c4830ec3/propcache-0.4.1-cp313-cp313t-win_arm64.whl", hash = "sha256:929d7cbe1f01bb7baffb33dc14eb5691c95831450a26354cd210a8155170c93a", size = 39789, upload-time = "2025-10-08T19:47:49.876Z" }, - { url = "https://files.pythonhosted.org/packages/8e/5c/bca52d654a896f831b8256683457ceddd490ec18d9ec50e97dfd8fc726a8/propcache-0.4.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3f7124c9d820ba5548d431afb4632301acf965db49e666aa21c305cbe8c6de12", size = 78152, upload-time = "2025-10-08T19:47:51.051Z" }, - { url = "https://files.pythonhosted.org/packages/65/9b/03b04e7d82a5f54fb16113d839f5ea1ede58a61e90edf515f6577c66fa8f/propcache-0.4.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:c0d4b719b7da33599dfe3b22d3db1ef789210a0597bc650b7cee9c77c2be8c5c", size = 44869, upload-time = "2025-10-08T19:47:52.594Z" }, - { url = "https://files.pythonhosted.org/packages/b2/fa/89a8ef0468d5833a23fff277b143d0573897cf75bd56670a6d28126c7d68/propcache-0.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:9f302f4783709a78240ebc311b793f123328716a60911d667e0c036bc5dcbded", size = 46596, upload-time = "2025-10-08T19:47:54.073Z" }, - { url = "https://files.pythonhosted.org/packages/86/bd/47816020d337f4a746edc42fe8d53669965138f39ee117414c7d7a340cfe/propcache-0.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c80ee5802e3fb9ea37938e7eecc307fb984837091d5fd262bb37238b1ae97641", size = 206981, upload-time = "2025-10-08T19:47:55.715Z" }, - { url = "https://files.pythonhosted.org/packages/df/f6/c5fa1357cc9748510ee55f37173eb31bfde6d94e98ccd9e6f033f2fc06e1/propcache-0.4.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ed5a841e8bb29a55fb8159ed526b26adc5bdd7e8bd7bf793ce647cb08656cdf4", size = 211490, upload-time = "2025-10-08T19:47:57.499Z" }, - { url = "https://files.pythonhosted.org/packages/80/1e/e5889652a7c4a3846683401a48f0f2e5083ce0ec1a8a5221d8058fbd1adf/propcache-0.4.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:55c72fd6ea2da4c318e74ffdf93c4fe4e926051133657459131a95c846d16d44", size = 215371, upload-time = "2025-10-08T19:47:59.317Z" }, - { url = "https://files.pythonhosted.org/packages/b2/f2/889ad4b2408f72fe1a4f6a19491177b30ea7bf1a0fd5f17050ca08cfc882/propcache-0.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8326e144341460402713f91df60ade3c999d601e7eb5ff8f6f7862d54de0610d", size = 201424, upload-time = "2025-10-08T19:48:00.67Z" }, - { url = "https://files.pythonhosted.org/packages/27/73/033d63069b57b0812c8bd19f311faebeceb6ba31b8f32b73432d12a0b826/propcache-0.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:060b16ae65bc098da7f6d25bf359f1f31f688384858204fe5d652979e0015e5b", size = 197566, upload-time = "2025-10-08T19:48:02.604Z" }, - { url = "https://files.pythonhosted.org/packages/dc/89/ce24f3dc182630b4e07aa6d15f0ff4b14ed4b9955fae95a0b54c58d66c05/propcache-0.4.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:89eb3fa9524f7bec9de6e83cf3faed9d79bffa560672c118a96a171a6f55831e", size = 193130, upload-time = "2025-10-08T19:48:04.499Z" }, - { url = "https://files.pythonhosted.org/packages/a9/24/ef0d5fd1a811fb5c609278d0209c9f10c35f20581fcc16f818da959fc5b4/propcache-0.4.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:dee69d7015dc235f526fe80a9c90d65eb0039103fe565776250881731f06349f", size = 202625, upload-time = "2025-10-08T19:48:06.213Z" }, - { url = "https://files.pythonhosted.org/packages/f5/02/98ec20ff5546f68d673df2f7a69e8c0d076b5abd05ca882dc7ee3a83653d/propcache-0.4.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:5558992a00dfd54ccbc64a32726a3357ec93825a418a401f5cc67df0ac5d9e49", size = 204209, upload-time = "2025-10-08T19:48:08.432Z" }, - { url = "https://files.pythonhosted.org/packages/a0/87/492694f76759b15f0467a2a93ab68d32859672b646aa8a04ce4864e7932d/propcache-0.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c9b822a577f560fbd9554812526831712c1436d2c046cedee4c3796d3543b144", size = 197797, upload-time = "2025-10-08T19:48:09.968Z" }, - { url = "https://files.pythonhosted.org/packages/ee/36/66367de3575db1d2d3f3d177432bd14ee577a39d3f5d1b3d5df8afe3b6e2/propcache-0.4.1-cp314-cp314-win32.whl", hash = "sha256:ab4c29b49d560fe48b696cdcb127dd36e0bc2472548f3bf56cc5cb3da2b2984f", size = 38140, upload-time = "2025-10-08T19:48:11.232Z" }, - { url = "https://files.pythonhosted.org/packages/0c/2a/a758b47de253636e1b8aef181c0b4f4f204bf0dd964914fb2af90a95b49b/propcache-0.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:5a103c3eb905fcea0ab98be99c3a9a5ab2de60228aa5aceedc614c0281cf6153", size = 41257, upload-time = "2025-10-08T19:48:12.707Z" }, - { url = "https://files.pythonhosted.org/packages/34/5e/63bd5896c3fec12edcbd6f12508d4890d23c265df28c74b175e1ef9f4f3b/propcache-0.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:74c1fb26515153e482e00177a1ad654721bf9207da8a494a0c05e797ad27b992", size = 38097, upload-time = "2025-10-08T19:48:13.923Z" }, - { url = "https://files.pythonhosted.org/packages/99/85/9ff785d787ccf9bbb3f3106f79884a130951436f58392000231b4c737c80/propcache-0.4.1-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:824e908bce90fb2743bd6b59db36eb4f45cd350a39637c9f73b1c1ea66f5b75f", size = 81455, upload-time = "2025-10-08T19:48:15.16Z" }, - { url = "https://files.pythonhosted.org/packages/90/85/2431c10c8e7ddb1445c1f7c4b54d886e8ad20e3c6307e7218f05922cad67/propcache-0.4.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:c2b5e7db5328427c57c8e8831abda175421b709672f6cfc3d630c3b7e2146393", size = 46372, upload-time = "2025-10-08T19:48:16.424Z" }, - { url = "https://files.pythonhosted.org/packages/01/20/b0972d902472da9bcb683fa595099911f4d2e86e5683bcc45de60dd05dc3/propcache-0.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6f6ff873ed40292cd4969ef5310179afd5db59fdf055897e282485043fc80ad0", size = 48411, upload-time = "2025-10-08T19:48:17.577Z" }, - { url = "https://files.pythonhosted.org/packages/e2/e3/7dc89f4f21e8f99bad3d5ddb3a3389afcf9da4ac69e3deb2dcdc96e74169/propcache-0.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:49a2dc67c154db2c1463013594c458881a069fcf98940e61a0569016a583020a", size = 275712, upload-time = "2025-10-08T19:48:18.901Z" }, - { url = "https://files.pythonhosted.org/packages/20/67/89800c8352489b21a8047c773067644e3897f02ecbbd610f4d46b7f08612/propcache-0.4.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:005f08e6a0529984491e37d8dbc3dd86f84bd78a8ceb5fa9a021f4c48d4984be", size = 273557, upload-time = "2025-10-08T19:48:20.762Z" }, - { url = "https://files.pythonhosted.org/packages/e2/a1/b52b055c766a54ce6d9c16d9aca0cad8059acd9637cdf8aa0222f4a026ef/propcache-0.4.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5c3310452e0d31390da9035c348633b43d7e7feb2e37be252be6da45abd1abcc", size = 280015, upload-time = "2025-10-08T19:48:22.592Z" }, - { url = "https://files.pythonhosted.org/packages/48/c8/33cee30bd890672c63743049f3c9e4be087e6780906bfc3ec58528be59c1/propcache-0.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c3c70630930447f9ef1caac7728c8ad1c56bc5015338b20fed0d08ea2480b3a", size = 262880, upload-time = "2025-10-08T19:48:23.947Z" }, - { url = "https://files.pythonhosted.org/packages/0c/b1/8f08a143b204b418285c88b83d00edbd61afbc2c6415ffafc8905da7038b/propcache-0.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8e57061305815dfc910a3634dcf584f08168a8836e6999983569f51a8544cd89", size = 260938, upload-time = "2025-10-08T19:48:25.656Z" }, - { url = "https://files.pythonhosted.org/packages/cf/12/96e4664c82ca2f31e1c8dff86afb867348979eb78d3cb8546a680287a1e9/propcache-0.4.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:521a463429ef54143092c11a77e04056dd00636f72e8c45b70aaa3140d639726", size = 247641, upload-time = "2025-10-08T19:48:27.207Z" }, - { url = "https://files.pythonhosted.org/packages/18/ed/e7a9cfca28133386ba52278136d42209d3125db08d0a6395f0cba0c0285c/propcache-0.4.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:120c964da3fdc75e3731aa392527136d4ad35868cc556fd09bb6d09172d9a367", size = 262510, upload-time = "2025-10-08T19:48:28.65Z" }, - { url = "https://files.pythonhosted.org/packages/f5/76/16d8bf65e8845dd62b4e2b57444ab81f07f40caa5652b8969b87ddcf2ef6/propcache-0.4.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:d8f353eb14ee3441ee844ade4277d560cdd68288838673273b978e3d6d2c8f36", size = 263161, upload-time = "2025-10-08T19:48:30.133Z" }, - { url = "https://files.pythonhosted.org/packages/e7/70/c99e9edb5d91d5ad8a49fa3c1e8285ba64f1476782fed10ab251ff413ba1/propcache-0.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ab2943be7c652f09638800905ee1bab2c544e537edb57d527997a24c13dc1455", size = 257393, upload-time = "2025-10-08T19:48:31.567Z" }, - { url = "https://files.pythonhosted.org/packages/08/02/87b25304249a35c0915d236575bc3574a323f60b47939a2262b77632a3ee/propcache-0.4.1-cp314-cp314t-win32.whl", hash = "sha256:05674a162469f31358c30bcaa8883cb7829fa3110bf9c0991fe27d7896c42d85", size = 42546, upload-time = "2025-10-08T19:48:32.872Z" }, - { url = "https://files.pythonhosted.org/packages/cb/ef/3c6ecf8b317aa982f309835e8f96987466123c6e596646d4e6a1dfcd080f/propcache-0.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:990f6b3e2a27d683cb7602ed6c86f15ee6b43b1194736f9baaeb93d0016633b1", size = 46259, upload-time = "2025-10-08T19:48:34.226Z" }, - { url = "https://files.pythonhosted.org/packages/c4/2d/346e946d4951f37eca1e4f55be0f0174c52cd70720f84029b02f296f4a38/propcache-0.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:ecef2343af4cc68e05131e45024ba34f6095821988a9d0a02aa7c73fcc448aa9", size = 40428, upload-time = "2025-10-08T19:48:35.441Z" }, - { url = "https://files.pythonhosted.org/packages/5b/5a/bc7b4a4ef808fa59a816c17b20c4bef6884daebbdf627ff2a161da67da19/propcache-0.4.1-py3-none-any.whl", hash = "sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237", size = 13305, upload-time = "2025-10-08T19:49:00.792Z" }, -] - -[[package]] -name = "pydantic" -version = "2.12.5" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "annotated-types" }, - { name = "pydantic-core" }, - { name = "typing-extensions" }, - { name = "typing-inspection" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/69/44/36f1a6e523abc58ae5f928898e4aca2e0ea509b5aa6f6f392a5d882be928/pydantic-2.12.5.tar.gz", hash = "sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49", size = 821591, upload-time = "2025-11-26T15:11:46.471Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl", hash = "sha256:e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d", size = 463580, upload-time = "2025-11-26T15:11:44.605Z" }, -] - -[package.optional-dependencies] -email = [ - { name = "email-validator" }, -] - -[[package]] -name = "pydantic-core" -version = "2.41.5" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/71/70/23b021c950c2addd24ec408e9ab05d59b035b39d97cdc1130e1bce647bb6/pydantic_core-2.41.5.tar.gz", hash = "sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e", size = 460952, upload-time = "2025-11-04T13:43:49.098Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/87/06/8806241ff1f70d9939f9af039c6c35f2360cf16e93c2ca76f184e76b1564/pydantic_core-2.41.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:941103c9be18ac8daf7b7adca8228f8ed6bb7a1849020f643b3a14d15b1924d9", size = 2120403, upload-time = "2025-11-04T13:40:25.248Z" }, - { url = "https://files.pythonhosted.org/packages/94/02/abfa0e0bda67faa65fef1c84971c7e45928e108fe24333c81f3bfe35d5f5/pydantic_core-2.41.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:112e305c3314f40c93998e567879e887a3160bb8689ef3d2c04b6cc62c33ac34", size = 1896206, upload-time = "2025-11-04T13:40:27.099Z" }, - { url = "https://files.pythonhosted.org/packages/15/df/a4c740c0943e93e6500f9eb23f4ca7ec9bf71b19e608ae5b579678c8d02f/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cbaad15cb0c90aa221d43c00e77bb33c93e8d36e0bf74760cd00e732d10a6a0", size = 1919307, upload-time = "2025-11-04T13:40:29.806Z" }, - { url = "https://files.pythonhosted.org/packages/9a/e3/6324802931ae1d123528988e0e86587c2072ac2e5394b4bc2bc34b61ff6e/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:03ca43e12fab6023fc79d28ca6b39b05f794ad08ec2feccc59a339b02f2b3d33", size = 2063258, upload-time = "2025-11-04T13:40:33.544Z" }, - { url = "https://files.pythonhosted.org/packages/c9/d4/2230d7151d4957dd79c3044ea26346c148c98fbf0ee6ebd41056f2d62ab5/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc799088c08fa04e43144b164feb0c13f9a0bc40503f8df3e9fde58a3c0c101e", size = 2214917, upload-time = "2025-11-04T13:40:35.479Z" }, - { url = "https://files.pythonhosted.org/packages/e6/9f/eaac5df17a3672fef0081b6c1bb0b82b33ee89aa5cec0d7b05f52fd4a1fa/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:97aeba56665b4c3235a0e52b2c2f5ae9cd071b8a8310ad27bddb3f7fb30e9aa2", size = 2332186, upload-time = "2025-11-04T13:40:37.436Z" }, - { url = "https://files.pythonhosted.org/packages/cf/4e/35a80cae583a37cf15604b44240e45c05e04e86f9cfd766623149297e971/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:406bf18d345822d6c21366031003612b9c77b3e29ffdb0f612367352aab7d586", size = 2073164, upload-time = "2025-11-04T13:40:40.289Z" }, - { url = "https://files.pythonhosted.org/packages/bf/e3/f6e262673c6140dd3305d144d032f7bd5f7497d3871c1428521f19f9efa2/pydantic_core-2.41.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b93590ae81f7010dbe380cdeab6f515902ebcbefe0b9327cc4804d74e93ae69d", size = 2179146, upload-time = "2025-11-04T13:40:42.809Z" }, - { url = "https://files.pythonhosted.org/packages/75/c7/20bd7fc05f0c6ea2056a4565c6f36f8968c0924f19b7d97bbfea55780e73/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:01a3d0ab748ee531f4ea6c3e48ad9dac84ddba4b0d82291f87248f2f9de8d740", size = 2137788, upload-time = "2025-11-04T13:40:44.752Z" }, - { url = "https://files.pythonhosted.org/packages/3a/8d/34318ef985c45196e004bc46c6eab2eda437e744c124ef0dbe1ff2c9d06b/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:6561e94ba9dacc9c61bce40e2d6bdc3bfaa0259d3ff36ace3b1e6901936d2e3e", size = 2340133, upload-time = "2025-11-04T13:40:46.66Z" }, - { url = "https://files.pythonhosted.org/packages/9c/59/013626bf8c78a5a5d9350d12e7697d3d4de951a75565496abd40ccd46bee/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:915c3d10f81bec3a74fbd4faebe8391013ba61e5a1a8d48c4455b923bdda7858", size = 2324852, upload-time = "2025-11-04T13:40:48.575Z" }, - { url = "https://files.pythonhosted.org/packages/1a/d9/c248c103856f807ef70c18a4f986693a46a8ffe1602e5d361485da502d20/pydantic_core-2.41.5-cp313-cp313-win32.whl", hash = "sha256:650ae77860b45cfa6e2cdafc42618ceafab3a2d9a3811fcfbd3bbf8ac3c40d36", size = 1994679, upload-time = "2025-11-04T13:40:50.619Z" }, - { url = "https://files.pythonhosted.org/packages/9e/8b/341991b158ddab181cff136acd2552c9f35bd30380422a639c0671e99a91/pydantic_core-2.41.5-cp313-cp313-win_amd64.whl", hash = "sha256:79ec52ec461e99e13791ec6508c722742ad745571f234ea6255bed38c6480f11", size = 2019766, upload-time = "2025-11-04T13:40:52.631Z" }, - { url = "https://files.pythonhosted.org/packages/73/7d/f2f9db34af103bea3e09735bb40b021788a5e834c81eedb541991badf8f5/pydantic_core-2.41.5-cp313-cp313-win_arm64.whl", hash = "sha256:3f84d5c1b4ab906093bdc1ff10484838aca54ef08de4afa9de0f5f14d69639cd", size = 1981005, upload-time = "2025-11-04T13:40:54.734Z" }, - { url = "https://files.pythonhosted.org/packages/ea/28/46b7c5c9635ae96ea0fbb779e271a38129df2550f763937659ee6c5dbc65/pydantic_core-2.41.5-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a", size = 2119622, upload-time = "2025-11-04T13:40:56.68Z" }, - { url = "https://files.pythonhosted.org/packages/74/1a/145646e5687e8d9a1e8d09acb278c8535ebe9e972e1f162ed338a622f193/pydantic_core-2.41.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14", size = 1891725, upload-time = "2025-11-04T13:40:58.807Z" }, - { url = "https://files.pythonhosted.org/packages/23/04/e89c29e267b8060b40dca97bfc64a19b2a3cf99018167ea1677d96368273/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25e1c2af0fce638d5f1988b686f3b3ea8cd7de5f244ca147c777769e798a9cd1", size = 1915040, upload-time = "2025-11-04T13:41:00.853Z" }, - { url = "https://files.pythonhosted.org/packages/84/a3/15a82ac7bd97992a82257f777b3583d3e84bdb06ba6858f745daa2ec8a85/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:506d766a8727beef16b7adaeb8ee6217c64fc813646b424d0804d67c16eddb66", size = 2063691, upload-time = "2025-11-04T13:41:03.504Z" }, - { url = "https://files.pythonhosted.org/packages/74/9b/0046701313c6ef08c0c1cf0e028c67c770a4e1275ca73131563c5f2a310a/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4819fa52133c9aa3c387b3328f25c1facc356491e6135b459f1de698ff64d869", size = 2213897, upload-time = "2025-11-04T13:41:05.804Z" }, - { url = "https://files.pythonhosted.org/packages/8a/cd/6bac76ecd1b27e75a95ca3a9a559c643b3afcd2dd62086d4b7a32a18b169/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b761d210c9ea91feda40d25b4efe82a1707da2ef62901466a42492c028553a2", size = 2333302, upload-time = "2025-11-04T13:41:07.809Z" }, - { url = "https://files.pythonhosted.org/packages/4c/d2/ef2074dc020dd6e109611a8be4449b98cd25e1b9b8a303c2f0fca2f2bcf7/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375", size = 2064877, upload-time = "2025-11-04T13:41:09.827Z" }, - { url = "https://files.pythonhosted.org/packages/18/66/e9db17a9a763d72f03de903883c057b2592c09509ccfe468187f2a2eef29/pydantic_core-2.41.5-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2782c870e99878c634505236d81e5443092fba820f0373997ff75f90f68cd553", size = 2180680, upload-time = "2025-11-04T13:41:12.379Z" }, - { url = "https://files.pythonhosted.org/packages/d3/9e/3ce66cebb929f3ced22be85d4c2399b8e85b622db77dad36b73c5387f8f8/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:0177272f88ab8312479336e1d777f6b124537d47f2123f89cb37e0accea97f90", size = 2138960, upload-time = "2025-11-04T13:41:14.627Z" }, - { url = "https://files.pythonhosted.org/packages/a6/62/205a998f4327d2079326b01abee48e502ea739d174f0a89295c481a2272e/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:63510af5e38f8955b8ee5687740d6ebf7c2a0886d15a6d65c32814613681bc07", size = 2339102, upload-time = "2025-11-04T13:41:16.868Z" }, - { url = "https://files.pythonhosted.org/packages/3c/0d/f05e79471e889d74d3d88f5bd20d0ed189ad94c2423d81ff8d0000aab4ff/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:e56ba91f47764cc14f1daacd723e3e82d1a89d783f0f5afe9c364b8bb491ccdb", size = 2326039, upload-time = "2025-11-04T13:41:18.934Z" }, - { url = "https://files.pythonhosted.org/packages/ec/e1/e08a6208bb100da7e0c4b288eed624a703f4d129bde2da475721a80cab32/pydantic_core-2.41.5-cp314-cp314-win32.whl", hash = "sha256:aec5cf2fd867b4ff45b9959f8b20ea3993fc93e63c7363fe6851424c8a7e7c23", size = 1995126, upload-time = "2025-11-04T13:41:21.418Z" }, - { url = "https://files.pythonhosted.org/packages/48/5d/56ba7b24e9557f99c9237e29f5c09913c81eeb2f3217e40e922353668092/pydantic_core-2.41.5-cp314-cp314-win_amd64.whl", hash = "sha256:8e7c86f27c585ef37c35e56a96363ab8de4e549a95512445b85c96d3e2f7c1bf", size = 2015489, upload-time = "2025-11-04T13:41:24.076Z" }, - { url = "https://files.pythonhosted.org/packages/4e/bb/f7a190991ec9e3e0ba22e4993d8755bbc4a32925c0b5b42775c03e8148f9/pydantic_core-2.41.5-cp314-cp314-win_arm64.whl", hash = "sha256:e672ba74fbc2dc8eea59fb6d4aed6845e6905fc2a8afe93175d94a83ba2a01a0", size = 1977288, upload-time = "2025-11-04T13:41:26.33Z" }, - { url = "https://files.pythonhosted.org/packages/92/ed/77542d0c51538e32e15afe7899d79efce4b81eee631d99850edc2f5e9349/pydantic_core-2.41.5-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:8566def80554c3faa0e65ac30ab0932b9e3a5cd7f8323764303d468e5c37595a", size = 2120255, upload-time = "2025-11-04T13:41:28.569Z" }, - { url = "https://files.pythonhosted.org/packages/bb/3d/6913dde84d5be21e284439676168b28d8bbba5600d838b9dca99de0fad71/pydantic_core-2.41.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b80aa5095cd3109962a298ce14110ae16b8c1aece8b72f9dafe81cf597ad80b3", size = 1863760, upload-time = "2025-11-04T13:41:31.055Z" }, - { url = "https://files.pythonhosted.org/packages/5a/f0/e5e6b99d4191da102f2b0eb9687aaa7f5bea5d9964071a84effc3e40f997/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3006c3dd9ba34b0c094c544c6006cc79e87d8612999f1a5d43b769b89181f23c", size = 1878092, upload-time = "2025-11-04T13:41:33.21Z" }, - { url = "https://files.pythonhosted.org/packages/71/48/36fb760642d568925953bcc8116455513d6e34c4beaa37544118c36aba6d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:72f6c8b11857a856bcfa48c86f5368439f74453563f951e473514579d44aa612", size = 2053385, upload-time = "2025-11-04T13:41:35.508Z" }, - { url = "https://files.pythonhosted.org/packages/20/25/92dc684dd8eb75a234bc1c764b4210cf2646479d54b47bf46061657292a8/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5cb1b2f9742240e4bb26b652a5aeb840aa4b417c7748b6f8387927bc6e45e40d", size = 2218832, upload-time = "2025-11-04T13:41:37.732Z" }, - { url = "https://files.pythonhosted.org/packages/e2/09/f53e0b05023d3e30357d82eb35835d0f6340ca344720a4599cd663dca599/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bd3d54f38609ff308209bd43acea66061494157703364ae40c951f83ba99a1a9", size = 2327585, upload-time = "2025-11-04T13:41:40Z" }, - { url = "https://files.pythonhosted.org/packages/aa/4e/2ae1aa85d6af35a39b236b1b1641de73f5a6ac4d5a7509f77b814885760c/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ff4321e56e879ee8d2a879501c8e469414d948f4aba74a2d4593184eb326660", size = 2041078, upload-time = "2025-11-04T13:41:42.323Z" }, - { url = "https://files.pythonhosted.org/packages/cd/13/2e215f17f0ef326fc72afe94776edb77525142c693767fc347ed6288728d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d0d2568a8c11bf8225044aa94409e21da0cb09dcdafe9ecd10250b2baad531a9", size = 2173914, upload-time = "2025-11-04T13:41:45.221Z" }, - { url = "https://files.pythonhosted.org/packages/02/7a/f999a6dcbcd0e5660bc348a3991c8915ce6599f4f2c6ac22f01d7a10816c/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:a39455728aabd58ceabb03c90e12f71fd30fa69615760a075b9fec596456ccc3", size = 2129560, upload-time = "2025-11-04T13:41:47.474Z" }, - { url = "https://files.pythonhosted.org/packages/3a/b1/6c990ac65e3b4c079a4fb9f5b05f5b013afa0f4ed6780a3dd236d2cbdc64/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:239edca560d05757817c13dc17c50766136d21f7cd0fac50295499ae24f90fdf", size = 2329244, upload-time = "2025-11-04T13:41:49.992Z" }, - { url = "https://files.pythonhosted.org/packages/d9/02/3c562f3a51afd4d88fff8dffb1771b30cfdfd79befd9883ee094f5b6c0d8/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:2a5e06546e19f24c6a96a129142a75cee553cc018ffee48a460059b1185f4470", size = 2331955, upload-time = "2025-11-04T13:41:54.079Z" }, - { url = "https://files.pythonhosted.org/packages/5c/96/5fb7d8c3c17bc8c62fdb031c47d77a1af698f1d7a406b0f79aaa1338f9ad/pydantic_core-2.41.5-cp314-cp314t-win32.whl", hash = "sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa", size = 1988906, upload-time = "2025-11-04T13:41:56.606Z" }, - { url = "https://files.pythonhosted.org/packages/22/ed/182129d83032702912c2e2d8bbe33c036f342cc735737064668585dac28f/pydantic_core-2.41.5-cp314-cp314t-win_amd64.whl", hash = "sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c", size = 1981607, upload-time = "2025-11-04T13:41:58.889Z" }, - { url = "https://files.pythonhosted.org/packages/9f/ed/068e41660b832bb0b1aa5b58011dea2a3fe0ba7861ff38c4d4904c1c1a99/pydantic_core-2.41.5-cp314-cp314t-win_arm64.whl", hash = "sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008", size = 1974769, upload-time = "2025-11-04T13:42:01.186Z" }, -] - -[[package]] -name = "pydantic-settings" -version = "2.12.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pydantic" }, - { name = "python-dotenv" }, - { name = "typing-inspection" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/43/4b/ac7e0aae12027748076d72a8764ff1c9d82ca75a7a52622e67ed3f765c54/pydantic_settings-2.12.0.tar.gz", hash = "sha256:005538ef951e3c2a68e1c08b292b5f2e71490def8589d4221b95dab00dafcfd0", size = 194184, upload-time = "2025-11-10T14:25:47.013Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c1/60/5d4751ba3f4a40a6891f24eec885f51afd78d208498268c734e256fb13c4/pydantic_settings-2.12.0-py3-none-any.whl", hash = "sha256:fddb9fd99a5b18da837b29710391e945b1e30c135477f484084ee513adb93809", size = 51880, upload-time = "2025-11-10T14:25:45.546Z" }, -] - -[[package]] -name = "pygments" -version = "2.19.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, -] - -[[package]] -name = "pymysql" -version = "1.1.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f5/ae/1fe3fcd9f959efa0ebe200b8de88b5a5ce3e767e38c7ac32fb179f16a388/pymysql-1.1.2.tar.gz", hash = "sha256:4961d3e165614ae65014e361811a724e2044ad3ea3739de9903ae7c21f539f03", size = 48258, upload-time = "2025-08-24T12:55:55.146Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7c/4c/ad33b92b9864cbde84f259d5df035a6447f91891f5be77788e2a3892bce3/pymysql-1.1.2-py3-none-any.whl", hash = "sha256:e6b1d89711dd51f8f74b1631fe08f039e7d76cf67a42a323d3178f0f25762ed9", size = 45300, upload-time = "2025-08-24T12:55:53.394Z" }, -] - -[[package]] -name = "pytest" -version = "9.0.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, - { name = "iniconfig" }, - { name = "packaging" }, - { name = "pluggy" }, - { name = "pygments" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/d1/db/7ef3487e0fb0049ddb5ce41d3a49c235bf9ad299b6a25d5780a89f19230f/pytest-9.0.2.tar.gz", hash = "sha256:75186651a92bd89611d1d9fc20f0b4345fd827c41ccd5c299a868a05d70edf11", size = 1568901, upload-time = "2025-12-06T21:30:51.014Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl", hash = "sha256:711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b", size = 374801, upload-time = "2025-12-06T21:30:49.154Z" }, -] - -[[package]] -name = "pytest-asyncio" -version = "1.3.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pytest" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/90/2c/8af215c0f776415f3590cac4f9086ccefd6fd463befeae41cd4d3f193e5a/pytest_asyncio-1.3.0.tar.gz", hash = "sha256:d7f52f36d231b80ee124cd216ffb19369aa168fc10095013c6b014a34d3ee9e5", size = 50087, upload-time = "2025-11-10T16:07:47.256Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e5/35/f8b19922b6a25bc0880171a2f1a003eaeb93657475193ab516fd87cac9da/pytest_asyncio-1.3.0-py3-none-any.whl", hash = "sha256:611e26147c7f77640e6d0a92a38ed17c3e9848063698d5c93d5aa7aa11cebff5", size = 15075, upload-time = "2025-11-10T16:07:45.537Z" }, -] - -[[package]] -name = "python-dotenv" -version = "1.2.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f0/26/19cadc79a718c5edbec86fd4919a6b6d3f681039a2f6d66d14be94e75fb9/python_dotenv-1.2.1.tar.gz", hash = "sha256:42667e897e16ab0d66954af0e60a9caa94f0fd4ecf3aaf6d2d260eec1aa36ad6", size = 44221, upload-time = "2025-10-26T15:12:10.434Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/14/1b/a298b06749107c305e1fe0f814c6c74aea7b2f1e10989cb30f544a1b3253/python_dotenv-1.2.1-py3-none-any.whl", hash = "sha256:b81ee9561e9ca4004139c6cbba3a238c32b03e4894671e181b671e8cb8425d61", size = 21230, upload-time = "2025-10-26T15:12:09.109Z" }, -] - -[[package]] -name = "python-multipart" -version = "0.0.21" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/78/96/804520d0850c7db98e5ccb70282e29208723f0964e88ffd9d0da2f52ea09/python_multipart-0.0.21.tar.gz", hash = "sha256:7137ebd4d3bbf70ea1622998f902b97a29434a9e8dc40eb203bbcf7c2a2cba92", size = 37196, upload-time = "2025-12-17T09:24:22.446Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/aa/76/03af049af4dcee5d27442f71b6924f01f3efb5d2bd34f23fcd563f2cc5f5/python_multipart-0.0.21-py3-none-any.whl", hash = "sha256:cf7a6713e01c87aa35387f4774e812c4361150938d20d232800f75ffcf266090", size = 24541, upload-time = "2025-12-17T09:24:21.153Z" }, -] - -[[package]] -name = "pyyaml" -version = "6.0.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, - { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, - { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, - { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, - { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, - { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, - { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, - { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, - { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, - { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, - { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, - { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, - { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, - { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" }, - { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" }, - { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" }, - { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" }, - { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" }, - { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" }, - { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" }, - { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" }, - { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" }, - { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" }, - { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" }, - { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" }, - { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, - { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, - { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, -] - -[[package]] -name = "redis" -version = "7.1.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/43/c8/983d5c6579a411d8a99bc5823cc5712768859b5ce2c8afe1a65b37832c81/redis-7.1.0.tar.gz", hash = "sha256:b1cc3cfa5a2cb9c2ab3ba700864fb0ad75617b41f01352ce5779dabf6d5f9c3c", size = 4796669, upload-time = "2025-11-19T15:54:39.961Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/89/f0/8956f8a86b20d7bb9d6ac0187cf4cd54d8065bc9a1a09eb8011d4d326596/redis-7.1.0-py3-none-any.whl", hash = "sha256:23c52b208f92b56103e17c5d06bdc1a6c2c0b3106583985a76a18f83b265de2b", size = 354159, upload-time = "2025-11-19T15:54:38.064Z" }, -] - -[[package]] -name = "rich" -version = "14.2.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "markdown-it-py" }, - { name = "pygments" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/fb/d2/8920e102050a0de7bfabeb4c4614a49248cf8d5d7a8d01885fbb24dc767a/rich-14.2.0.tar.gz", hash = "sha256:73ff50c7c0c1c77c8243079283f4edb376f0f6442433aecb8ce7e6d0b92d1fe4", size = 219990, upload-time = "2025-10-09T14:16:53.064Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/25/7a/b0178788f8dc6cafce37a212c99565fa1fe7872c70c6c9c1e1a372d9d88f/rich-14.2.0-py3-none-any.whl", hash = "sha256:76bc51fe2e57d2b1be1f96c524b890b816e334ab4c1e45888799bfaab0021edd", size = 243393, upload-time = "2025-10-09T14:16:51.245Z" }, -] - -[[package]] -name = "rich-toolkit" -version = "0.17.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "click" }, - { name = "rich" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/97/09/3f9b8d9daaf235195c626f21e03604c05b987404ee3bcacee0c1f67f2a8e/rich_toolkit-0.17.1.tar.gz", hash = "sha256:5af54df8d1dd9c8530e462e1bdcaed625c9b49f5a55b035aa0ba1c17bdb87c9a", size = 187925, upload-time = "2025-12-17T10:49:22.583Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7f/7b/15e55fa8a76d0d41bf34d965af78acdaf80a315907adb30de8b63c272694/rich_toolkit-0.17.1-py3-none-any.whl", hash = "sha256:96d24bb921ecd225ffce7c526a9149e74006410c05e6d405bd74ffd54d5631ed", size = 31412, upload-time = "2025-12-17T10:49:21.793Z" }, -] - -[[package]] -name = "rignore" -version = "0.7.6" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e5/f5/8bed2310abe4ae04b67a38374a4d311dd85220f5d8da56f47ae9361be0b0/rignore-0.7.6.tar.gz", hash = "sha256:00d3546cd793c30cb17921ce674d2c8f3a4b00501cb0e3dd0e82217dbeba2671", size = 57140, upload-time = "2025-11-05T21:41:21.968Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/8a/a4078f6e14932ac7edb171149c481de29969d96ddee3ece5dc4c26f9e0c3/rignore-0.7.6-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:2bdab1d31ec9b4fb1331980ee49ea051c0d7f7bb6baa28b3125ef03cdc48fdaf", size = 883057, upload-time = "2025-11-05T20:42:42.741Z" }, - { url = "https://files.pythonhosted.org/packages/f9/8f/f8daacd177db4bf7c2223bab41e630c52711f8af9ed279be2058d2fe4982/rignore-0.7.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:90f0a00ce0c866c275bf888271f1dc0d2140f29b82fcf33cdbda1e1a6af01010", size = 820150, upload-time = "2025-11-05T20:42:26.545Z" }, - { url = "https://files.pythonhosted.org/packages/36/31/b65b837e39c3f7064c426754714ac633b66b8c2290978af9d7f513e14aa9/rignore-0.7.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1ad295537041dc2ed4b540fb1a3906bd9ede6ccdad3fe79770cd89e04e3c73c", size = 897406, upload-time = "2025-11-05T20:40:53.854Z" }, - { url = "https://files.pythonhosted.org/packages/ca/58/1970ce006c427e202ac7c081435719a076c478f07b3a23f469227788dc23/rignore-0.7.6-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f782dbd3a65a5ac85adfff69e5c6b101285ef3f845c3a3cae56a54bebf9fe116", size = 874050, upload-time = "2025-11-05T20:41:08.922Z" }, - { url = "https://files.pythonhosted.org/packages/d4/00/eb45db9f90137329072a732273be0d383cb7d7f50ddc8e0bceea34c1dfdf/rignore-0.7.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:65cece3b36e5b0826d946494734c0e6aaf5a0337e18ff55b071438efe13d559e", size = 1167835, upload-time = "2025-11-05T20:41:24.997Z" }, - { url = "https://files.pythonhosted.org/packages/f3/f1/6f1d72ddca41a64eed569680587a1236633587cc9f78136477ae69e2c88a/rignore-0.7.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d7e4bb66c13cd7602dc8931822c02dfbbd5252015c750ac5d6152b186f0a8be0", size = 941945, upload-time = "2025-11-05T20:41:40.628Z" }, - { url = "https://files.pythonhosted.org/packages/48/6f/2f178af1c1a276a065f563ec1e11e7a9e23d4996fd0465516afce4b5c636/rignore-0.7.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:297e500c15766e196f68aaaa70e8b6db85fa23fdc075b880d8231fdfba738cd7", size = 959067, upload-time = "2025-11-05T20:42:11.09Z" }, - { url = "https://files.pythonhosted.org/packages/5b/db/423a81c4c1e173877c7f9b5767dcaf1ab50484a94f60a0b2ed78be3fa765/rignore-0.7.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a07084211a8d35e1a5b1d32b9661a5ed20669970b369df0cf77da3adea3405de", size = 984438, upload-time = "2025-11-05T20:41:55.443Z" }, - { url = "https://files.pythonhosted.org/packages/31/eb/c4f92cc3f2825d501d3c46a244a671eb737fc1bcf7b05a3ecd34abb3e0d7/rignore-0.7.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:181eb2a975a22256a1441a9d2f15eb1292839ea3f05606620bd9e1938302cf79", size = 1078365, upload-time = "2025-11-05T21:40:15.148Z" }, - { url = "https://files.pythonhosted.org/packages/26/09/99442f02794bd7441bfc8ed1c7319e890449b816a7493b2db0e30af39095/rignore-0.7.6-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:7bbcdc52b5bf9f054b34ce4af5269df5d863d9c2456243338bc193c28022bd7b", size = 1139066, upload-time = "2025-11-05T21:40:32.771Z" }, - { url = "https://files.pythonhosted.org/packages/2c/88/bcfc21e520bba975410e9419450f4b90a2ac8236b9a80fd8130e87d098af/rignore-0.7.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f2e027a6da21a7c8c0d87553c24ca5cc4364def18d146057862c23a96546238e", size = 1118036, upload-time = "2025-11-05T21:40:49.646Z" }, - { url = "https://files.pythonhosted.org/packages/e2/25/d37215e4562cda5c13312636393aea0bafe38d54d4e0517520a4cc0753ec/rignore-0.7.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ee4a18b82cbbc648e4aac1510066682fe62beb5dc88e2c67c53a83954e541360", size = 1127550, upload-time = "2025-11-05T21:41:07.648Z" }, - { url = "https://files.pythonhosted.org/packages/dc/76/a264ab38bfa1620ec12a8ff1c07778da89e16d8c0f3450b0333020d3d6dc/rignore-0.7.6-cp313-cp313-win32.whl", hash = "sha256:a7d7148b6e5e95035d4390396895adc384d37ff4e06781a36fe573bba7c283e5", size = 646097, upload-time = "2025-11-05T21:41:53.201Z" }, - { url = "https://files.pythonhosted.org/packages/62/44/3c31b8983c29ea8832b6082ddb1d07b90379c2d993bd20fce4487b71b4f4/rignore-0.7.6-cp313-cp313-win_amd64.whl", hash = "sha256:b037c4b15a64dced08fc12310ee844ec2284c4c5c1ca77bc37d0a04f7bff386e", size = 726170, upload-time = "2025-11-05T21:41:38.131Z" }, - { url = "https://files.pythonhosted.org/packages/aa/41/e26a075cab83debe41a42661262f606166157df84e0e02e2d904d134c0d8/rignore-0.7.6-cp313-cp313-win_arm64.whl", hash = "sha256:e47443de9b12fe569889bdbe020abe0e0b667516ee2ab435443f6d0869bd2804", size = 656184, upload-time = "2025-11-05T21:41:27.396Z" }, - { url = "https://files.pythonhosted.org/packages/9a/b9/1f5bd82b87e5550cd843ceb3768b4a8ef274eb63f29333cf2f29644b3d75/rignore-0.7.6-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:8e41be9fa8f2f47239ded8920cc283699a052ac4c371f77f5ac017ebeed75732", size = 882632, upload-time = "2025-11-05T20:42:44.063Z" }, - { url = "https://files.pythonhosted.org/packages/e9/6b/07714a3efe4a8048864e8a5b7db311ba51b921e15268b17defaebf56d3db/rignore-0.7.6-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:6dc1e171e52cefa6c20e60c05394a71165663b48bca6c7666dee4f778f2a7d90", size = 820760, upload-time = "2025-11-05T20:42:27.885Z" }, - { url = "https://files.pythonhosted.org/packages/ac/0f/348c829ea2d8d596e856371b14b9092f8a5dfbb62674ec9b3f67e4939a9d/rignore-0.7.6-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ce2268837c3600f82ab8db58f5834009dc638ee17103582960da668963bebc5", size = 899044, upload-time = "2025-11-05T20:40:55.336Z" }, - { url = "https://files.pythonhosted.org/packages/f0/30/2e1841a19b4dd23878d73edd5d82e998a83d5ed9570a89675f140ca8b2ad/rignore-0.7.6-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:690a3e1b54bfe77e89c4bacb13f046e642f8baadafc61d68f5a726f324a76ab6", size = 874144, upload-time = "2025-11-05T20:41:10.195Z" }, - { url = "https://files.pythonhosted.org/packages/c2/bf/0ce9beb2e5f64c30e3580bef09f5829236889f01511a125f98b83169b993/rignore-0.7.6-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09d12ac7a0b6210c07bcd145007117ebd8abe99c8eeb383e9e4673910c2754b2", size = 1168062, upload-time = "2025-11-05T20:41:26.511Z" }, - { url = "https://files.pythonhosted.org/packages/b9/8b/571c178414eb4014969865317da8a02ce4cf5241a41676ef91a59aab24de/rignore-0.7.6-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2a2b2b74a8c60203b08452479b90e5ce3dbe96a916214bc9eb2e5af0b6a9beb0", size = 942542, upload-time = "2025-11-05T20:41:41.838Z" }, - { url = "https://files.pythonhosted.org/packages/19/62/7a3cf601d5a45137a7e2b89d10c05b5b86499190c4b7ca5c3c47d79ee519/rignore-0.7.6-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8fc5a531ef02131e44359419a366bfac57f773ea58f5278c2cdd915f7d10ea94", size = 958739, upload-time = "2025-11-05T20:42:12.463Z" }, - { url = "https://files.pythonhosted.org/packages/5f/1f/4261f6a0d7caf2058a5cde2f5045f565ab91aa7badc972b57d19ce58b14e/rignore-0.7.6-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b7a1f77d9c4cd7e76229e252614d963442686bfe12c787a49f4fe481df49e7a9", size = 984138, upload-time = "2025-11-05T20:41:56.775Z" }, - { url = "https://files.pythonhosted.org/packages/2b/bf/628dfe19c75e8ce1f45f7c248f5148b17dfa89a817f8e3552ab74c3ae812/rignore-0.7.6-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ead81f728682ba72b5b1c3d5846b011d3e0174da978de87c61645f2ed36659a7", size = 1079299, upload-time = "2025-11-05T21:40:16.639Z" }, - { url = "https://files.pythonhosted.org/packages/af/a5/be29c50f5c0c25c637ed32db8758fdf5b901a99e08b608971cda8afb293b/rignore-0.7.6-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:12ffd50f520c22ffdabed8cd8bfb567d9ac165b2b854d3e679f4bcaef11a9441", size = 1139618, upload-time = "2025-11-05T21:40:34.507Z" }, - { url = "https://files.pythonhosted.org/packages/2a/40/3c46cd7ce4fa05c20b525fd60f599165e820af66e66f2c371cd50644558f/rignore-0.7.6-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:e5a16890fbe3c894f8ca34b0fcacc2c200398d4d46ae654e03bc9b3dbf2a0a72", size = 1117626, upload-time = "2025-11-05T21:40:51.494Z" }, - { url = "https://files.pythonhosted.org/packages/8c/b9/aea926f263b8a29a23c75c2e0d8447965eb1879d3feb53cfcf84db67ed58/rignore-0.7.6-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:3abab3bf99e8a77488ef6c7c9a799fac22224c28fe9f25cc21aa7cc2b72bfc0b", size = 1128144, upload-time = "2025-11-05T21:41:09.169Z" }, - { url = "https://files.pythonhosted.org/packages/a4/f6/0d6242f8d0df7f2ecbe91679fefc1f75e7cd2072cb4f497abaab3f0f8523/rignore-0.7.6-cp314-cp314-win32.whl", hash = "sha256:eeef421c1782953c4375aa32f06ecae470c1285c6381eee2a30d2e02a5633001", size = 646385, upload-time = "2025-11-05T21:41:55.105Z" }, - { url = "https://files.pythonhosted.org/packages/d5/38/c0dcd7b10064f084343d6af26fe9414e46e9619c5f3224b5272e8e5d9956/rignore-0.7.6-cp314-cp314-win_amd64.whl", hash = "sha256:6aeed503b3b3d5af939b21d72a82521701a4bd3b89cd761da1e7dc78621af304", size = 725738, upload-time = "2025-11-05T21:41:39.736Z" }, - { url = "https://files.pythonhosted.org/packages/d9/7a/290f868296c1ece914d565757ab363b04730a728b544beb567ceb3b2d96f/rignore-0.7.6-cp314-cp314-win_arm64.whl", hash = "sha256:104f215b60b3c984c386c3e747d6ab4376d5656478694e22c7bd2f788ddd8304", size = 656008, upload-time = "2025-11-05T21:41:29.028Z" }, - { url = "https://files.pythonhosted.org/packages/ca/d2/3c74e3cd81fe8ea08a8dcd2d755c09ac2e8ad8fe409508904557b58383d3/rignore-0.7.6-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:bb24a5b947656dd94cb9e41c4bc8b23cec0c435b58be0d74a874f63c259549e8", size = 882835, upload-time = "2025-11-05T20:42:45.443Z" }, - { url = "https://files.pythonhosted.org/packages/77/61/a772a34b6b63154877433ac2d048364815b24c2dd308f76b212c408101a2/rignore-0.7.6-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5b1e33c9501cefe24b70a1eafd9821acfd0ebf0b35c3a379430a14df089993e3", size = 820301, upload-time = "2025-11-05T20:42:29.226Z" }, - { url = "https://files.pythonhosted.org/packages/71/30/054880b09c0b1b61d17eeb15279d8bf729c0ba52b36c3ada52fb827cbb3c/rignore-0.7.6-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bec3994665a44454df86deb762061e05cd4b61e3772f5b07d1882a8a0d2748d5", size = 897611, upload-time = "2025-11-05T20:40:56.475Z" }, - { url = "https://files.pythonhosted.org/packages/1e/40/b2d1c169f833d69931bf232600eaa3c7998ba4f9a402e43a822dad2ea9f2/rignore-0.7.6-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:26cba2edfe3cff1dfa72bddf65d316ddebf182f011f2f61538705d6dbaf54986", size = 873875, upload-time = "2025-11-05T20:41:11.561Z" }, - { url = "https://files.pythonhosted.org/packages/55/59/ca5ae93d83a1a60e44b21d87deb48b177a8db1b85e82fc8a9abb24a8986d/rignore-0.7.6-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ffa86694fec604c613696cb91e43892aa22e1fec5f9870e48f111c603e5ec4e9", size = 1167245, upload-time = "2025-11-05T20:41:28.29Z" }, - { url = "https://files.pythonhosted.org/packages/a5/52/cf3dce392ba2af806cba265aad6bcd9c48bb2a6cb5eee448d3319f6e505b/rignore-0.7.6-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48efe2ed95aa8104145004afb15cdfa02bea5cdde8b0344afeb0434f0d989aa2", size = 941750, upload-time = "2025-11-05T20:41:43.111Z" }, - { url = "https://files.pythonhosted.org/packages/ec/be/3f344c6218d779395e785091d05396dfd8b625f6aafbe502746fcd880af2/rignore-0.7.6-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8dcae43eb44b7f2457fef7cc87f103f9a0013017a6f4e62182c565e924948f21", size = 958896, upload-time = "2025-11-05T20:42:13.784Z" }, - { url = "https://files.pythonhosted.org/packages/c9/34/d3fa71938aed7d00dcad87f0f9bcb02ad66c85d6ffc83ba31078ce53646a/rignore-0.7.6-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2cd649a7091c0dad2f11ef65630d30c698d505cbe8660dd395268e7c099cc99f", size = 983992, upload-time = "2025-11-05T20:41:58.022Z" }, - { url = "https://files.pythonhosted.org/packages/24/a4/52a697158e9920705bdbd0748d59fa63e0f3233fb92e9df9a71afbead6ca/rignore-0.7.6-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:42de84b0289d478d30ceb7ae59023f7b0527786a9a5b490830e080f0e4ea5aeb", size = 1078181, upload-time = "2025-11-05T21:40:18.151Z" }, - { url = "https://files.pythonhosted.org/packages/ac/65/aa76dbcdabf3787a6f0fd61b5cc8ed1e88580590556d6c0207960d2384bb/rignore-0.7.6-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:875a617e57b53b4acbc5a91de418233849711c02e29cc1f4f9febb2f928af013", size = 1139232, upload-time = "2025-11-05T21:40:35.966Z" }, - { url = "https://files.pythonhosted.org/packages/08/44/31b31a49b3233c6842acc1c0731aa1e7fb322a7170612acf30327f700b44/rignore-0.7.6-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:8703998902771e96e49968105207719f22926e4431b108450f3f430b4e268b7c", size = 1117349, upload-time = "2025-11-05T21:40:53.013Z" }, - { url = "https://files.pythonhosted.org/packages/e9/ae/1b199a2302c19c658cf74e5ee1427605234e8c91787cfba0015f2ace145b/rignore-0.7.6-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:602ef33f3e1b04c1e9a10a3c03f8bc3cef2d2383dcc250d309be42b49923cabc", size = 1127702, upload-time = "2025-11-05T21:41:10.881Z" }, - { url = "https://files.pythonhosted.org/packages/fc/d3/18210222b37e87e36357f7b300b7d98c6dd62b133771e71ae27acba83a4f/rignore-0.7.6-cp314-cp314t-win32.whl", hash = "sha256:c1d8f117f7da0a4a96a8daef3da75bc090e3792d30b8b12cfadc240c631353f9", size = 647033, upload-time = "2025-11-05T21:42:00.095Z" }, - { url = "https://files.pythonhosted.org/packages/3e/87/033eebfbee3ec7d92b3bb1717d8f68c88e6fc7de54537040f3b3a405726f/rignore-0.7.6-cp314-cp314t-win_amd64.whl", hash = "sha256:ca36e59408bec81de75d307c568c2d0d410fb880b1769be43611472c61e85c96", size = 725647, upload-time = "2025-11-05T21:41:44.449Z" }, - { url = "https://files.pythonhosted.org/packages/79/62/b88e5879512c55b8ee979c666ee6902adc4ed05007226de266410ae27965/rignore-0.7.6-cp314-cp314t-win_arm64.whl", hash = "sha256:b83adabeb3e8cf662cabe1931b83e165b88c526fa6af6b3aa90429686e474896", size = 656035, upload-time = "2025-11-05T21:41:31.13Z" }, -] - -[[package]] -name = "ruff" -version = "0.14.10" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/57/08/52232a877978dd8f9cf2aeddce3e611b40a63287dfca29b6b8da791f5e8d/ruff-0.14.10.tar.gz", hash = "sha256:9a2e830f075d1a42cd28420d7809ace390832a490ed0966fe373ba288e77aaf4", size = 5859763, upload-time = "2025-12-18T19:28:57.98Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/60/01/933704d69f3f05ee16ef11406b78881733c186fe14b6a46b05cfcaf6d3b2/ruff-0.14.10-py3-none-linux_armv6l.whl", hash = "sha256:7a3ce585f2ade3e1f29ec1b92df13e3da262178df8c8bdf876f48fa0e8316c49", size = 13527080, upload-time = "2025-12-18T19:29:25.642Z" }, - { url = "https://files.pythonhosted.org/packages/df/58/a0349197a7dfa603ffb7f5b0470391efa79ddc327c1e29c4851e85b09cc5/ruff-0.14.10-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:674f9be9372907f7257c51f1d4fc902cb7cf014b9980152b802794317941f08f", size = 13797320, upload-time = "2025-12-18T19:29:02.571Z" }, - { url = "https://files.pythonhosted.org/packages/7b/82/36be59f00a6082e38c23536df4e71cdbc6af8d7c707eade97fcad5c98235/ruff-0.14.10-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d85713d522348837ef9df8efca33ccb8bd6fcfc86a2cde3ccb4bc9d28a18003d", size = 12918434, upload-time = "2025-12-18T19:28:51.202Z" }, - { url = "https://files.pythonhosted.org/packages/a6/00/45c62a7f7e34da92a25804f813ebe05c88aa9e0c25e5cb5a7d23dd7450e3/ruff-0.14.10-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6987ebe0501ae4f4308d7d24e2d0fe3d7a98430f5adfd0f1fead050a740a3a77", size = 13371961, upload-time = "2025-12-18T19:29:04.991Z" }, - { url = "https://files.pythonhosted.org/packages/40/31/a5906d60f0405f7e57045a70f2d57084a93ca7425f22e1d66904769d1628/ruff-0.14.10-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:16a01dfb7b9e4eee556fbfd5392806b1b8550c9b4a9f6acd3dbe6812b193c70a", size = 13275629, upload-time = "2025-12-18T19:29:21.381Z" }, - { url = "https://files.pythonhosted.org/packages/3e/60/61c0087df21894cf9d928dc04bcd4fb10e8b2e8dca7b1a276ba2155b2002/ruff-0.14.10-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7165d31a925b7a294465fa81be8c12a0e9b60fb02bf177e79067c867e71f8b1f", size = 14029234, upload-time = "2025-12-18T19:29:00.132Z" }, - { url = "https://files.pythonhosted.org/packages/44/84/77d911bee3b92348b6e5dab5a0c898d87084ea03ac5dc708f46d88407def/ruff-0.14.10-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:c561695675b972effb0c0a45db233f2c816ff3da8dcfbe7dfc7eed625f218935", size = 15449890, upload-time = "2025-12-18T19:28:53.573Z" }, - { url = "https://files.pythonhosted.org/packages/e9/36/480206eaefa24a7ec321582dda580443a8f0671fdbf6b1c80e9c3e93a16a/ruff-0.14.10-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4bb98fcbbc61725968893682fd4df8966a34611239c9fd07a1f6a07e7103d08e", size = 15123172, upload-time = "2025-12-18T19:29:23.453Z" }, - { url = "https://files.pythonhosted.org/packages/5c/38/68e414156015ba80cef5473d57919d27dfb62ec804b96180bafdeaf0e090/ruff-0.14.10-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f24b47993a9d8cb858429e97bdf8544c78029f09b520af615c1d261bf827001d", size = 14460260, upload-time = "2025-12-18T19:29:27.808Z" }, - { url = "https://files.pythonhosted.org/packages/b3/19/9e050c0dca8aba824d67cc0db69fb459c28d8cd3f6855b1405b3f29cc91d/ruff-0.14.10-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59aabd2e2c4fd614d2862e7939c34a532c04f1084476d6833dddef4afab87e9f", size = 14229978, upload-time = "2025-12-18T19:29:11.32Z" }, - { url = "https://files.pythonhosted.org/packages/51/eb/e8dd1dd6e05b9e695aa9dd420f4577debdd0f87a5ff2fedda33c09e9be8c/ruff-0.14.10-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:213db2b2e44be8625002dbea33bb9c60c66ea2c07c084a00d55732689d697a7f", size = 14338036, upload-time = "2025-12-18T19:29:09.184Z" }, - { url = "https://files.pythonhosted.org/packages/6a/12/f3e3a505db7c19303b70af370d137795fcfec136d670d5de5391e295c134/ruff-0.14.10-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:b914c40ab64865a17a9a5b67911d14df72346a634527240039eb3bd650e5979d", size = 13264051, upload-time = "2025-12-18T19:29:13.431Z" }, - { url = "https://files.pythonhosted.org/packages/08/64/8c3a47eaccfef8ac20e0484e68e0772013eb85802f8a9f7603ca751eb166/ruff-0.14.10-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:1484983559f026788e3a5c07c81ef7d1e97c1c78ed03041a18f75df104c45405", size = 13283998, upload-time = "2025-12-18T19:29:06.994Z" }, - { url = "https://files.pythonhosted.org/packages/12/84/534a5506f4074e5cc0529e5cd96cfc01bb480e460c7edf5af70d2bcae55e/ruff-0.14.10-py3-none-musllinux_1_2_i686.whl", hash = "sha256:c70427132db492d25f982fffc8d6c7535cc2fd2c83fc8888f05caaa248521e60", size = 13601891, upload-time = "2025-12-18T19:28:55.811Z" }, - { url = "https://files.pythonhosted.org/packages/0d/1e/14c916087d8598917dbad9b2921d340f7884824ad6e9c55de948a93b106d/ruff-0.14.10-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5bcf45b681e9f1ee6445d317ce1fa9d6cba9a6049542d1c3d5b5958986be8830", size = 14336660, upload-time = "2025-12-18T19:29:16.531Z" }, - { url = "https://files.pythonhosted.org/packages/f2/1c/d7b67ab43f30013b47c12b42d1acd354c195351a3f7a1d67f59e54227ede/ruff-0.14.10-py3-none-win32.whl", hash = "sha256:104c49fc7ab73f3f3a758039adea978869a918f31b73280db175b43a2d9b51d6", size = 13196187, upload-time = "2025-12-18T19:29:19.006Z" }, - { url = "https://files.pythonhosted.org/packages/fb/9c/896c862e13886fae2af961bef3e6312db9ebc6adc2b156fe95e615dee8c1/ruff-0.14.10-py3-none-win_amd64.whl", hash = "sha256:466297bd73638c6bdf06485683e812db1c00c7ac96d4ddd0294a338c62fdc154", size = 14661283, upload-time = "2025-12-18T19:29:30.16Z" }, - { url = "https://files.pythonhosted.org/packages/74/31/b0e29d572670dca3674eeee78e418f20bdf97fa8aa9ea71380885e175ca0/ruff-0.14.10-py3-none-win_arm64.whl", hash = "sha256:e51d046cf6dda98a4633b8a8a771451107413b0f07183b2bef03f075599e44e6", size = 13729839, upload-time = "2025-12-18T19:28:48.636Z" }, -] - -[[package]] -name = "scalar-fastapi" -version = "1.5.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b2/1a/4897819ef5682f40cce1f9b552a1e002d394bf7e12e5d6fe62f843ffef51/scalar_fastapi-1.5.0.tar.gz", hash = "sha256:5ae887fcc0db63305dc41dc39d61f7be183256085872aa33b294e0d48e29901e", size = 7447, upload-time = "2025-12-04T19:44:12.04Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7a/cc/c0712ac83a31ae96785d9916d7be54595914aa93375ea5df3ba3eadab8af/scalar_fastapi-1.5.0-py3-none-any.whl", hash = "sha256:8e712599ccdfbb614bff5583fdbee1bef03e5fac1e06520287337ff232cb667a", size = 6828, upload-time = "2025-12-04T19:44:11.242Z" }, -] - -[[package]] -name = "sentry-sdk" -version = "2.48.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "certifi" }, - { name = "urllib3" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/40/f0/0e9dc590513d5e742d7799e2038df3a05167cba084c6ca4f3cdd75b55164/sentry_sdk-2.48.0.tar.gz", hash = "sha256:5213190977ff7fdff8a58b722fb807f8d5524a80488626ebeda1b5676c0c1473", size = 384828, upload-time = "2025-12-16T14:55:41.722Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/4d/19/8d77f9992e5cbfcaa9133c3bf63b4fbbb051248802e1e803fed5c552fbb2/sentry_sdk-2.48.0-py2.py3-none-any.whl", hash = "sha256:6b12ac256769d41825d9b7518444e57fa35b5642df4c7c5e322af4d2c8721172", size = 414555, upload-time = "2025-12-16T14:55:40.152Z" }, -] - -[[package]] -name = "shellingham" -version = "1.5.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310, upload-time = "2023-10-24T04:13:40.426Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, -] - -[[package]] -name = "sniffio" -version = "1.3.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372, upload-time = "2024-02-25T23:20:04.057Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" }, -] - -[[package]] -name = "sqladmin" -version = "0.22.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "jinja2" }, - { name = "python-multipart" }, - { name = "sqlalchemy" }, - { name = "starlette" }, - { name = "wtforms" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/2c/ac/526bb3ff2dd94fbf8442bccb49ef40aa360045add19d4fbffcb43995e67a/sqladmin-0.22.0.tar.gz", hash = "sha256:4ea904d97e4d030edb68fb0681330b4d963f422442a64bee487fdc46119b3729", size = 1429937, upload-time = "2025-11-24T12:52:59.285Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f2/b4/ab78c7d7b13bd3f90d6d8a106c5ad12bf7a738f89eb0241b24ad8efe5d1e/sqladmin-0.22.0-py3-none-any.whl", hash = "sha256:f2fb11165a70601a97f71956104b47da2c432db49b0d7966dc65e9e6343887d3", size = 1445514, upload-time = "2025-11-24T12:53:00.511Z" }, -] - -[package.optional-dependencies] -full = [ - { name = "itsdangerous" }, -] - -[[package]] -name = "sqlalchemy" -version = "2.0.45" -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/be/f9/5e4491e5ccf42f5d9cfc663741d261b3e6e1683ae7812114e7636409fcc6/sqlalchemy-2.0.45.tar.gz", hash = "sha256:1632a4bda8d2d25703fdad6363058d882541bdaaee0e5e3ddfa0cd3229efce88", size = 9869912, upload-time = "2025-12-09T21:05:16.737Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/6a/c8/7cc5221b47a54edc72a0140a1efa56e0a2730eefa4058d7ed0b4c4357ff8/sqlalchemy-2.0.45-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fe187fc31a54d7fd90352f34e8c008cf3ad5d064d08fedd3de2e8df83eb4a1cf", size = 3277082, upload-time = "2025-12-09T22:11:06.167Z" }, - { url = "https://files.pythonhosted.org/packages/0e/50/80a8d080ac7d3d321e5e5d420c9a522b0aa770ec7013ea91f9a8b7d36e4a/sqlalchemy-2.0.45-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:672c45cae53ba88e0dad74b9027dddd09ef6f441e927786b05bec75d949fbb2e", size = 3293131, upload-time = "2025-12-09T22:13:52.626Z" }, - { url = "https://files.pythonhosted.org/packages/da/4c/13dab31266fc9904f7609a5dc308a2432a066141d65b857760c3bef97e69/sqlalchemy-2.0.45-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:470daea2c1ce73910f08caf10575676a37159a6d16c4da33d0033546bddebc9b", size = 3225389, upload-time = "2025-12-09T22:11:08.093Z" }, - { url = "https://files.pythonhosted.org/packages/74/04/891b5c2e9f83589de202e7abaf24cd4e4fa59e1837d64d528829ad6cc107/sqlalchemy-2.0.45-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9c6378449e0940476577047150fd09e242529b761dc887c9808a9a937fe990c8", size = 3266054, upload-time = "2025-12-09T22:13:54.262Z" }, - { url = "https://files.pythonhosted.org/packages/f1/24/fc59e7f71b0948cdd4cff7a286210e86b0443ef1d18a23b0d83b87e4b1f7/sqlalchemy-2.0.45-cp313-cp313-win32.whl", hash = "sha256:4b6bec67ca45bc166c8729910bd2a87f1c0407ee955df110d78948f5b5827e8a", size = 2110299, upload-time = "2025-12-09T21:39:33.486Z" }, - { url = "https://files.pythonhosted.org/packages/c0/c5/d17113020b2d43073412aeca09b60d2009442420372123b8d49cc253f8b8/sqlalchemy-2.0.45-cp313-cp313-win_amd64.whl", hash = "sha256:afbf47dc4de31fa38fd491f3705cac5307d21d4bb828a4f020ee59af412744ee", size = 2136264, upload-time = "2025-12-09T21:39:36.801Z" }, - { url = "https://files.pythonhosted.org/packages/3d/8d/bb40a5d10e7a5f2195f235c0b2f2c79b0bf6e8f00c0c223130a4fbd2db09/sqlalchemy-2.0.45-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:83d7009f40ce619d483d26ac1b757dfe3167b39921379a8bd1b596cf02dab4a6", size = 3521998, upload-time = "2025-12-09T22:13:28.622Z" }, - { url = "https://files.pythonhosted.org/packages/75/a5/346128b0464886f036c039ea287b7332a410aa2d3fb0bb5d404cb8861635/sqlalchemy-2.0.45-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:d8a2ca754e5415cde2b656c27900b19d50ba076aa05ce66e2207623d3fe41f5a", size = 3473434, upload-time = "2025-12-09T22:13:30.188Z" }, - { url = "https://files.pythonhosted.org/packages/cc/64/4e1913772646b060b025d3fc52ce91a58967fe58957df32b455de5a12b4f/sqlalchemy-2.0.45-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7f46ec744e7f51275582e6a24326e10c49fbdd3fc99103e01376841213028774", size = 3272404, upload-time = "2025-12-09T22:11:09.662Z" }, - { url = "https://files.pythonhosted.org/packages/b3/27/caf606ee924282fe4747ee4fd454b335a72a6e018f97eab5ff7f28199e16/sqlalchemy-2.0.45-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:883c600c345123c033c2f6caca18def08f1f7f4c3ebeb591a63b6fceffc95cce", size = 3277057, upload-time = "2025-12-09T22:13:56.213Z" }, - { url = "https://files.pythonhosted.org/packages/85/d0/3d64218c9724e91f3d1574d12eb7ff8f19f937643815d8daf792046d88ab/sqlalchemy-2.0.45-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2c0b74aa79e2deade948fe8593654c8ef4228c44ba862bb7c9585c8e0db90f33", size = 3222279, upload-time = "2025-12-09T22:11:11.1Z" }, - { url = "https://files.pythonhosted.org/packages/24/10/dd7688a81c5bc7690c2a3764d55a238c524cd1a5a19487928844cb247695/sqlalchemy-2.0.45-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:8a420169cef179d4c9064365f42d779f1e5895ad26ca0c8b4c0233920973db74", size = 3244508, upload-time = "2025-12-09T22:13:57.932Z" }, - { url = "https://files.pythonhosted.org/packages/aa/41/db75756ca49f777e029968d9c9fee338c7907c563267740c6d310a8e3f60/sqlalchemy-2.0.45-cp314-cp314-win32.whl", hash = "sha256:e50dcb81a5dfe4b7b4a4aa8f338116d127cb209559124f3694c70d6cd072b68f", size = 2113204, upload-time = "2025-12-09T21:39:38.365Z" }, - { url = "https://files.pythonhosted.org/packages/89/a2/0e1590e9adb292b1d576dbcf67ff7df8cf55e56e78d2c927686d01080f4b/sqlalchemy-2.0.45-cp314-cp314-win_amd64.whl", hash = "sha256:4748601c8ea959e37e03d13dcda4a44837afcd1b21338e637f7c935b8da06177", size = 2138785, upload-time = "2025-12-09T21:39:39.503Z" }, - { url = "https://files.pythonhosted.org/packages/42/39/f05f0ed54d451156bbed0e23eb0516bcad7cbb9f18b3bf219c786371b3f0/sqlalchemy-2.0.45-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cd337d3526ec5298f67d6a30bbbe4ed7e5e68862f0bf6dd21d289f8d37b7d60b", size = 3522029, upload-time = "2025-12-09T22:13:32.09Z" }, - { url = "https://files.pythonhosted.org/packages/54/0f/d15398b98b65c2bce288d5ee3f7d0a81f77ab89d9456994d5c7cc8b2a9db/sqlalchemy-2.0.45-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9a62b446b7d86a3909abbcd1cd3cc550a832f99c2bc37c5b22e1925438b9367b", size = 3475142, upload-time = "2025-12-09T22:13:33.739Z" }, - { url = "https://files.pythonhosted.org/packages/bf/e1/3ccb13c643399d22289c6a9786c1a91e3dcbb68bce4beb44926ac2c557bf/sqlalchemy-2.0.45-py3-none-any.whl", hash = "sha256:5225a288e4c8cc2308dbdd874edad6e7d0fd38eac1e9e5f23503425c8eee20d0", size = 1936672, upload-time = "2025-12-09T21:54:52.608Z" }, -] - -[package.optional-dependencies] -asyncio = [ - { name = "greenlet" }, -] - -[[package]] -name = "starlette" -version = "0.50.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "anyio" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/ba/b8/73a0e6a6e079a9d9cfa64113d771e421640b6f679a52eeb9b32f72d871a1/starlette-0.50.0.tar.gz", hash = "sha256:a2a17b22203254bcbc2e1f926d2d55f3f9497f769416b3190768befe598fa3ca", size = 2646985, upload-time = "2025-11-01T15:25:27.516Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d9/52/1064f510b141bd54025f9b55105e26d1fa970b9be67ad766380a3c9b74b0/starlette-0.50.0-py3-none-any.whl", hash = "sha256:9e5391843ec9b6e472eed1365a78c8098cfceb7a74bfd4d6b1c0c0095efb3bca", size = 74033, upload-time = "2025-11-01T15:25:25.461Z" }, -] - -[[package]] -name = "tqdm" -version = "4.67.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/a8/4b/29b4ef32e036bb34e4ab51796dd745cdba7ed47ad142a9f4a1eb8e0c744d/tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2", size = 169737, upload-time = "2024-11-24T20:12:22.481Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2", size = 78540, upload-time = "2024-11-24T20:12:19.698Z" }, -] - -[[package]] -name = "typer" -version = "0.20.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "click" }, - { name = "rich" }, - { name = "shellingham" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/8f/28/7c85c8032b91dbe79725b6f17d2fffc595dff06a35c7a30a37bef73a1ab4/typer-0.20.0.tar.gz", hash = "sha256:1aaf6494031793e4876fb0bacfa6a912b551cf43c1e63c800df8b1a866720c37", size = 106492, upload-time = "2025-10-20T17:03:49.445Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/78/64/7713ffe4b5983314e9d436a90d5bd4f63b6054e2aca783a3cfc44cb95bbf/typer-0.20.0-py3-none-any.whl", hash = "sha256:5b463df6793ec1dca6213a3cf4c0f03bc6e322ac5e16e13ddd622a889489784a", size = 47028, upload-time = "2025-10-20T17:03:47.617Z" }, -] - -[[package]] -name = "typing-extensions" -version = "4.15.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, -] - -[[package]] -name = "typing-inspection" -version = "0.4.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload-time = "2025-10-01T02:14:41.687Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" }, -] - -[[package]] -name = "urllib3" -version = "2.6.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1e/24/a2a2ed9addd907787d7aa0355ba36a6cadf1768b934c652ea78acbd59dcd/urllib3-2.6.2.tar.gz", hash = "sha256:016f9c98bb7e98085cb2b4b17b87d2c702975664e4f060c6532e64d1c1a5e797", size = 432930, upload-time = "2025-12-11T15:56:40.252Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/6d/b9/4095b668ea3678bf6a0af005527f39de12fb026516fb3df17495a733b7f8/urllib3-2.6.2-py3-none-any.whl", hash = "sha256:ec21cddfe7724fc7cb4ba4bea7aa8e2ef36f607a4bab81aa6ce42a13dc3f03dd", size = 131182, upload-time = "2025-12-11T15:56:38.584Z" }, -] - -[[package]] -name = "uuid7" -version = "0.1.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5c/19/7472bd526591e2192926247109dbf78692e709d3e56775792fec877a7720/uuid7-0.1.0.tar.gz", hash = "sha256:8c57aa32ee7456d3cc68c95c4530bc571646defac01895cfc73545449894a63c", size = 14052, upload-time = "2021-12-29T01:38:21.897Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b5/77/8852f89a91453956582a85024d80ad96f30a41fed4c2b3dce0c9f12ecc7e/uuid7-0.1.0-py2.py3-none-any.whl", hash = "sha256:5e259bb63c8cb4aded5927ff41b444a80d0c7124e8a0ced7cf44efa1f5cccf61", size = 7477, upload-time = "2021-12-29T01:38:20.418Z" }, -] - -[[package]] -name = "uvicorn" -version = "0.38.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "click" }, - { name = "h11" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/cb/ce/f06b84e2697fef4688ca63bdb2fdf113ca0a3be33f94488f2cadb690b0cf/uvicorn-0.38.0.tar.gz", hash = "sha256:fd97093bdd120a2609fc0d3afe931d4d4ad688b6e75f0f929fde1bc36fe0e91d", size = 80605, upload-time = "2025-10-18T13:46:44.63Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ee/d9/d88e73ca598f4f6ff671fb5fde8a32925c2e08a637303a1d12883c7305fa/uvicorn-0.38.0-py3-none-any.whl", hash = "sha256:48c0afd214ceb59340075b4a052ea1ee91c16fbc2a9b1469cca0e54566977b02", size = 68109, upload-time = "2025-10-18T13:46:42.958Z" }, -] - -[package.optional-dependencies] -standard = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, - { name = "httptools" }, - { name = "python-dotenv" }, - { name = "pyyaml" }, - { name = "uvloop", marker = "platform_python_implementation != 'PyPy' and sys_platform != 'cygwin' and sys_platform != 'win32'" }, - { name = "watchfiles" }, - { name = "websockets" }, -] - -[[package]] -name = "uvloop" -version = "0.22.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/06/f0/18d39dbd1971d6d62c4629cc7fa67f74821b0dc1f5a77af43719de7936a7/uvloop-0.22.1.tar.gz", hash = "sha256:6c84bae345b9147082b17371e3dd5d42775bddce91f885499017f4607fdaf39f", size = 2443250, upload-time = "2025-10-16T22:17:19.342Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/89/8c/182a2a593195bfd39842ea68ebc084e20c850806117213f5a299dfc513d9/uvloop-0.22.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:561577354eb94200d75aca23fbde86ee11be36b00e52a4eaf8f50fb0c86b7705", size = 1358611, upload-time = "2025-10-16T22:16:36.833Z" }, - { url = "https://files.pythonhosted.org/packages/d2/14/e301ee96a6dc95224b6f1162cd3312f6d1217be3907b79173b06785f2fe7/uvloop-0.22.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1cdf5192ab3e674ca26da2eada35b288d2fa49fdd0f357a19f0e7c4e7d5077c8", size = 751811, upload-time = "2025-10-16T22:16:38.275Z" }, - { url = "https://files.pythonhosted.org/packages/b7/02/654426ce265ac19e2980bfd9ea6590ca96a56f10c76e63801a2df01c0486/uvloop-0.22.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6e2ea3d6190a2968f4a14a23019d3b16870dd2190cd69c8180f7c632d21de68d", size = 4288562, upload-time = "2025-10-16T22:16:39.375Z" }, - { url = "https://files.pythonhosted.org/packages/15/c0/0be24758891ef825f2065cd5db8741aaddabe3e248ee6acc5e8a80f04005/uvloop-0.22.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0530a5fbad9c9e4ee3f2b33b148c6a64d47bbad8000ea63704fa8260f4cf728e", size = 4366890, upload-time = "2025-10-16T22:16:40.547Z" }, - { url = "https://files.pythonhosted.org/packages/d2/53/8369e5219a5855869bcee5f4d317f6da0e2c669aecf0ef7d371e3d084449/uvloop-0.22.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bc5ef13bbc10b5335792360623cc378d52d7e62c2de64660616478c32cd0598e", size = 4119472, upload-time = "2025-10-16T22:16:41.694Z" }, - { url = "https://files.pythonhosted.org/packages/f8/ba/d69adbe699b768f6b29a5eec7b47dd610bd17a69de51b251126a801369ea/uvloop-0.22.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1f38ec5e3f18c8a10ded09742f7fb8de0108796eb673f30ce7762ce1b8550cad", size = 4239051, upload-time = "2025-10-16T22:16:43.224Z" }, - { url = "https://files.pythonhosted.org/packages/90/cd/b62bdeaa429758aee8de8b00ac0dd26593a9de93d302bff3d21439e9791d/uvloop-0.22.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3879b88423ec7e97cd4eba2a443aa26ed4e59b45e6b76aabf13fe2f27023a142", size = 1362067, upload-time = "2025-10-16T22:16:44.503Z" }, - { url = "https://files.pythonhosted.org/packages/0d/f8/a132124dfda0777e489ca86732e85e69afcd1ff7686647000050ba670689/uvloop-0.22.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:4baa86acedf1d62115c1dc6ad1e17134476688f08c6efd8a2ab076e815665c74", size = 752423, upload-time = "2025-10-16T22:16:45.968Z" }, - { url = "https://files.pythonhosted.org/packages/a3/94/94af78c156f88da4b3a733773ad5ba0b164393e357cc4bd0ab2e2677a7d6/uvloop-0.22.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:297c27d8003520596236bdb2335e6b3f649480bd09e00d1e3a99144b691d2a35", size = 4272437, upload-time = "2025-10-16T22:16:47.451Z" }, - { url = "https://files.pythonhosted.org/packages/b5/35/60249e9fd07b32c665192cec7af29e06c7cd96fa1d08b84f012a56a0b38e/uvloop-0.22.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c1955d5a1dd43198244d47664a5858082a3239766a839b2102a269aaff7a4e25", size = 4292101, upload-time = "2025-10-16T22:16:49.318Z" }, - { url = "https://files.pythonhosted.org/packages/02/62/67d382dfcb25d0a98ce73c11ed1a6fba5037a1a1d533dcbb7cab033a2636/uvloop-0.22.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b31dc2fccbd42adc73bc4e7cdbae4fc5086cf378979e53ca5d0301838c5682c6", size = 4114158, upload-time = "2025-10-16T22:16:50.517Z" }, - { url = "https://files.pythonhosted.org/packages/f0/7a/f1171b4a882a5d13c8b7576f348acfe6074d72eaf52cccef752f748d4a9f/uvloop-0.22.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:93f617675b2d03af4e72a5333ef89450dfaa5321303ede6e67ba9c9d26878079", size = 4177360, upload-time = "2025-10-16T22:16:52.646Z" }, - { url = "https://files.pythonhosted.org/packages/79/7b/b01414f31546caf0919da80ad57cbfe24c56b151d12af68cee1b04922ca8/uvloop-0.22.1-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:37554f70528f60cad66945b885eb01f1bb514f132d92b6eeed1c90fd54ed6289", size = 1454790, upload-time = "2025-10-16T22:16:54.355Z" }, - { url = "https://files.pythonhosted.org/packages/d4/31/0bb232318dd838cad3fa8fb0c68c8b40e1145b32025581975e18b11fab40/uvloop-0.22.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:b76324e2dc033a0b2f435f33eb88ff9913c156ef78e153fb210e03c13da746b3", size = 796783, upload-time = "2025-10-16T22:16:55.906Z" }, - { url = "https://files.pythonhosted.org/packages/42/38/c9b09f3271a7a723a5de69f8e237ab8e7803183131bc57c890db0b6bb872/uvloop-0.22.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:badb4d8e58ee08dad957002027830d5c3b06aea446a6a3744483c2b3b745345c", size = 4647548, upload-time = "2025-10-16T22:16:57.008Z" }, - { url = "https://files.pythonhosted.org/packages/c1/37/945b4ca0ac27e3dc4952642d4c900edd030b3da6c9634875af6e13ae80e5/uvloop-0.22.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b91328c72635f6f9e0282e4a57da7470c7350ab1c9f48546c0f2866205349d21", size = 4467065, upload-time = "2025-10-16T22:16:58.206Z" }, - { url = "https://files.pythonhosted.org/packages/97/cc/48d232f33d60e2e2e0b42f4e73455b146b76ebe216487e862700457fbf3c/uvloop-0.22.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:daf620c2995d193449393d6c62131b3fbd40a63bf7b307a1527856ace637fe88", size = 4328384, upload-time = "2025-10-16T22:16:59.36Z" }, - { url = "https://files.pythonhosted.org/packages/e4/16/c1fd27e9549f3c4baf1dc9c20c456cd2f822dbf8de9f463824b0c0357e06/uvloop-0.22.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6cde23eeda1a25c75b2e07d39970f3374105d5eafbaab2a4482be82f272d5a5e", size = 4296730, upload-time = "2025-10-16T22:17:00.744Z" }, -] - -[[package]] -name = "watchfiles" -version = "1.1.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "anyio" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/c2/c9/8869df9b2a2d6c59d79220a4db37679e74f807c559ffe5265e08b227a210/watchfiles-1.1.1.tar.gz", hash = "sha256:a173cb5c16c4f40ab19cecf48a534c409f7ea983ab8fed0741304a1c0a31b3f2", size = 94440, upload-time = "2025-10-14T15:06:21.08Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/bb/f4/f750b29225fe77139f7ae5de89d4949f5a99f934c65a1f1c0b248f26f747/watchfiles-1.1.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:130e4876309e8686a5e37dba7d5e9bc77e6ed908266996ca26572437a5271e18", size = 404321, upload-time = "2025-10-14T15:05:02.063Z" }, - { url = "https://files.pythonhosted.org/packages/2b/f9/f07a295cde762644aa4c4bb0f88921d2d141af45e735b965fb2e87858328/watchfiles-1.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5f3bde70f157f84ece3765b42b4a52c6ac1a50334903c6eaf765362f6ccca88a", size = 391783, upload-time = "2025-10-14T15:05:03.052Z" }, - { url = "https://files.pythonhosted.org/packages/bc/11/fc2502457e0bea39a5c958d86d2cb69e407a4d00b85735ca724bfa6e0d1a/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:14e0b1fe858430fc0251737ef3824c54027bedb8c37c38114488b8e131cf8219", size = 449279, upload-time = "2025-10-14T15:05:04.004Z" }, - { url = "https://files.pythonhosted.org/packages/e3/1f/d66bc15ea0b728df3ed96a539c777acfcad0eb78555ad9efcaa1274688f0/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f27db948078f3823a6bb3b465180db8ebecf26dd5dae6f6180bd87383b6b4428", size = 459405, upload-time = "2025-10-14T15:05:04.942Z" }, - { url = "https://files.pythonhosted.org/packages/be/90/9f4a65c0aec3ccf032703e6db02d89a157462fbb2cf20dd415128251cac0/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:059098c3a429f62fc98e8ec62b982230ef2c8df68c79e826e37b895bc359a9c0", size = 488976, upload-time = "2025-10-14T15:05:05.905Z" }, - { url = "https://files.pythonhosted.org/packages/37/57/ee347af605d867f712be7029bb94c8c071732a4b44792e3176fa3c612d39/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfb5862016acc9b869bb57284e6cb35fdf8e22fe59f7548858e2f971d045f150", size = 595506, upload-time = "2025-10-14T15:05:06.906Z" }, - { url = "https://files.pythonhosted.org/packages/a8/78/cc5ab0b86c122047f75e8fc471c67a04dee395daf847d3e59381996c8707/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:319b27255aacd9923b8a276bb14d21a5f7ff82564c744235fc5eae58d95422ae", size = 474936, upload-time = "2025-10-14T15:05:07.906Z" }, - { url = "https://files.pythonhosted.org/packages/62/da/def65b170a3815af7bd40a3e7010bf6ab53089ef1b75d05dd5385b87cf08/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c755367e51db90e75b19454b680903631d41f9e3607fbd941d296a020c2d752d", size = 456147, upload-time = "2025-10-14T15:05:09.138Z" }, - { url = "https://files.pythonhosted.org/packages/57/99/da6573ba71166e82d288d4df0839128004c67d2778d3b566c138695f5c0b/watchfiles-1.1.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c22c776292a23bfc7237a98f791b9ad3144b02116ff10d820829ce62dff46d0b", size = 630007, upload-time = "2025-10-14T15:05:10.117Z" }, - { url = "https://files.pythonhosted.org/packages/a8/51/7439c4dd39511368849eb1e53279cd3454b4a4dbace80bab88feeb83c6b5/watchfiles-1.1.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:3a476189be23c3686bc2f4321dd501cb329c0a0469e77b7b534ee10129ae6374", size = 622280, upload-time = "2025-10-14T15:05:11.146Z" }, - { url = "https://files.pythonhosted.org/packages/95/9c/8ed97d4bba5db6fdcdb2b298d3898f2dd5c20f6b73aee04eabe56c59677e/watchfiles-1.1.1-cp313-cp313-win32.whl", hash = "sha256:bf0a91bfb5574a2f7fc223cf95eeea79abfefa404bf1ea5e339c0c1560ae99a0", size = 272056, upload-time = "2025-10-14T15:05:12.156Z" }, - { url = "https://files.pythonhosted.org/packages/1f/f3/c14e28429f744a260d8ceae18bf58c1d5fa56b50d006a7a9f80e1882cb0d/watchfiles-1.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:52e06553899e11e8074503c8e716d574adeeb7e68913115c4b3653c53f9bae42", size = 288162, upload-time = "2025-10-14T15:05:13.208Z" }, - { url = "https://files.pythonhosted.org/packages/dc/61/fe0e56c40d5cd29523e398d31153218718c5786b5e636d9ae8ae79453d27/watchfiles-1.1.1-cp313-cp313-win_arm64.whl", hash = "sha256:ac3cc5759570cd02662b15fbcd9d917f7ecd47efe0d6b40474eafd246f91ea18", size = 277909, upload-time = "2025-10-14T15:05:14.49Z" }, - { url = "https://files.pythonhosted.org/packages/79/42/e0a7d749626f1e28c7108a99fb9bf524b501bbbeb9b261ceecde644d5a07/watchfiles-1.1.1-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:563b116874a9a7ce6f96f87cd0b94f7faf92d08d0021e837796f0a14318ef8da", size = 403389, upload-time = "2025-10-14T15:05:15.777Z" }, - { url = "https://files.pythonhosted.org/packages/15/49/08732f90ce0fbbc13913f9f215c689cfc9ced345fb1bcd8829a50007cc8d/watchfiles-1.1.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3ad9fe1dae4ab4212d8c91e80b832425e24f421703b5a42ef2e4a1e215aff051", size = 389964, upload-time = "2025-10-14T15:05:16.85Z" }, - { url = "https://files.pythonhosted.org/packages/27/0d/7c315d4bd5f2538910491a0393c56bf70d333d51bc5b34bee8e68e8cea19/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce70f96a46b894b36eba678f153f052967a0d06d5b5a19b336ab0dbbd029f73e", size = 448114, upload-time = "2025-10-14T15:05:17.876Z" }, - { url = "https://files.pythonhosted.org/packages/c3/24/9e096de47a4d11bc4df41e9d1e61776393eac4cb6eb11b3e23315b78b2cc/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cb467c999c2eff23a6417e58d75e5828716f42ed8289fe6b77a7e5a91036ca70", size = 460264, upload-time = "2025-10-14T15:05:18.962Z" }, - { url = "https://files.pythonhosted.org/packages/cc/0f/e8dea6375f1d3ba5fcb0b3583e2b493e77379834c74fd5a22d66d85d6540/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:836398932192dae4146c8f6f737d74baeac8b70ce14831a239bdb1ca882fc261", size = 487877, upload-time = "2025-10-14T15:05:20.094Z" }, - { url = "https://files.pythonhosted.org/packages/ac/5b/df24cfc6424a12deb41503b64d42fbea6b8cb357ec62ca84a5a3476f654a/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:743185e7372b7bc7c389e1badcc606931a827112fbbd37f14c537320fca08620", size = 595176, upload-time = "2025-10-14T15:05:21.134Z" }, - { url = "https://files.pythonhosted.org/packages/8f/b5/853b6757f7347de4e9b37e8cc3289283fb983cba1ab4d2d7144694871d9c/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:afaeff7696e0ad9f02cbb8f56365ff4686ab205fcf9c4c5b6fdfaaa16549dd04", size = 473577, upload-time = "2025-10-14T15:05:22.306Z" }, - { url = "https://files.pythonhosted.org/packages/e1/f7/0a4467be0a56e80447c8529c9fce5b38eab4f513cb3d9bf82e7392a5696b/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f7eb7da0eb23aa2ba036d4f616d46906013a68caf61b7fdbe42fc8b25132e77", size = 455425, upload-time = "2025-10-14T15:05:23.348Z" }, - { url = "https://files.pythonhosted.org/packages/8e/e0/82583485ea00137ddf69bc84a2db88bd92ab4a6e3c405e5fb878ead8d0e7/watchfiles-1.1.1-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:831a62658609f0e5c64178211c942ace999517f5770fe9436be4c2faeba0c0ef", size = 628826, upload-time = "2025-10-14T15:05:24.398Z" }, - { url = "https://files.pythonhosted.org/packages/28/9a/a785356fccf9fae84c0cc90570f11702ae9571036fb25932f1242c82191c/watchfiles-1.1.1-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:f9a2ae5c91cecc9edd47e041a930490c31c3afb1f5e6d71de3dc671bfaca02bf", size = 622208, upload-time = "2025-10-14T15:05:25.45Z" }, - { url = "https://files.pythonhosted.org/packages/c3/f4/0872229324ef69b2c3edec35e84bd57a1289e7d3fe74588048ed8947a323/watchfiles-1.1.1-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:d1715143123baeeaeadec0528bb7441103979a1d5f6fd0e1f915383fea7ea6d5", size = 404315, upload-time = "2025-10-14T15:05:26.501Z" }, - { url = "https://files.pythonhosted.org/packages/7b/22/16d5331eaed1cb107b873f6ae1b69e9ced582fcf0c59a50cd84f403b1c32/watchfiles-1.1.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:39574d6370c4579d7f5d0ad940ce5b20db0e4117444e39b6d8f99db5676c52fd", size = 390869, upload-time = "2025-10-14T15:05:27.649Z" }, - { url = "https://files.pythonhosted.org/packages/b2/7e/5643bfff5acb6539b18483128fdc0ef2cccc94a5b8fbda130c823e8ed636/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7365b92c2e69ee952902e8f70f3ba6360d0d596d9299d55d7d386df84b6941fb", size = 449919, upload-time = "2025-10-14T15:05:28.701Z" }, - { url = "https://files.pythonhosted.org/packages/51/2e/c410993ba5025a9f9357c376f48976ef0e1b1aefb73b97a5ae01a5972755/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bfff9740c69c0e4ed32416f013f3c45e2ae42ccedd1167ef2d805c000b6c71a5", size = 460845, upload-time = "2025-10-14T15:05:30.064Z" }, - { url = "https://files.pythonhosted.org/packages/8e/a4/2df3b404469122e8680f0fcd06079317e48db58a2da2950fb45020947734/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b27cf2eb1dda37b2089e3907d8ea92922b673c0c427886d4edc6b94d8dfe5db3", size = 489027, upload-time = "2025-10-14T15:05:31.064Z" }, - { url = "https://files.pythonhosted.org/packages/ea/84/4587ba5b1f267167ee715b7f66e6382cca6938e0a4b870adad93e44747e6/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:526e86aced14a65a5b0ec50827c745597c782ff46b571dbfe46192ab9e0b3c33", size = 595615, upload-time = "2025-10-14T15:05:32.074Z" }, - { url = "https://files.pythonhosted.org/packages/6a/0f/c6988c91d06e93cd0bb3d4a808bcf32375ca1904609835c3031799e3ecae/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:04e78dd0b6352db95507fd8cb46f39d185cf8c74e4cf1e4fbad1d3df96faf510", size = 474836, upload-time = "2025-10-14T15:05:33.209Z" }, - { url = "https://files.pythonhosted.org/packages/b4/36/ded8aebea91919485b7bbabbd14f5f359326cb5ec218cd67074d1e426d74/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c85794a4cfa094714fb9c08d4a218375b2b95b8ed1666e8677c349906246c05", size = 455099, upload-time = "2025-10-14T15:05:34.189Z" }, - { url = "https://files.pythonhosted.org/packages/98/e0/8c9bdba88af756a2fce230dd365fab2baf927ba42cd47521ee7498fd5211/watchfiles-1.1.1-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:74d5012b7630714b66be7b7b7a78855ef7ad58e8650c73afc4c076a1f480a8d6", size = 630626, upload-time = "2025-10-14T15:05:35.216Z" }, - { url = "https://files.pythonhosted.org/packages/2a/84/a95db05354bf2d19e438520d92a8ca475e578c647f78f53197f5a2f17aaf/watchfiles-1.1.1-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:8fbe85cb3201c7d380d3d0b90e63d520f15d6afe217165d7f98c9c649654db81", size = 622519, upload-time = "2025-10-14T15:05:36.259Z" }, - { url = "https://files.pythonhosted.org/packages/1d/ce/d8acdc8de545de995c339be67711e474c77d643555a9bb74a9334252bd55/watchfiles-1.1.1-cp314-cp314-win32.whl", hash = "sha256:3fa0b59c92278b5a7800d3ee7733da9d096d4aabcfabb9a928918bd276ef9b9b", size = 272078, upload-time = "2025-10-14T15:05:37.63Z" }, - { url = "https://files.pythonhosted.org/packages/c4/c9/a74487f72d0451524be827e8edec251da0cc1fcf111646a511ae752e1a3d/watchfiles-1.1.1-cp314-cp314-win_amd64.whl", hash = "sha256:c2047d0b6cea13b3316bdbafbfa0c4228ae593d995030fda39089d36e64fc03a", size = 287664, upload-time = "2025-10-14T15:05:38.95Z" }, - { url = "https://files.pythonhosted.org/packages/df/b8/8ac000702cdd496cdce998c6f4ee0ca1f15977bba51bdf07d872ebdfc34c/watchfiles-1.1.1-cp314-cp314-win_arm64.whl", hash = "sha256:842178b126593addc05acf6fce960d28bc5fae7afbaa2c6c1b3a7b9460e5be02", size = 277154, upload-time = "2025-10-14T15:05:39.954Z" }, - { url = "https://files.pythonhosted.org/packages/47/a8/e3af2184707c29f0f14b1963c0aace6529f9d1b8582d5b99f31bbf42f59e/watchfiles-1.1.1-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:88863fbbc1a7312972f1c511f202eb30866370ebb8493aef2812b9ff28156a21", size = 403820, upload-time = "2025-10-14T15:05:40.932Z" }, - { url = "https://files.pythonhosted.org/packages/c0/ec/e47e307c2f4bd75f9f9e8afbe3876679b18e1bcec449beca132a1c5ffb2d/watchfiles-1.1.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:55c7475190662e202c08c6c0f4d9e345a29367438cf8e8037f3155e10a88d5a5", size = 390510, upload-time = "2025-10-14T15:05:41.945Z" }, - { url = "https://files.pythonhosted.org/packages/d5/a0/ad235642118090f66e7b2f18fd5c42082418404a79205cdfca50b6309c13/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f53fa183d53a1d7a8852277c92b967ae99c2d4dcee2bfacff8868e6e30b15f7", size = 448408, upload-time = "2025-10-14T15:05:43.385Z" }, - { url = "https://files.pythonhosted.org/packages/df/85/97fa10fd5ff3332ae17e7e40e20784e419e28521549780869f1413742e9d/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6aae418a8b323732fa89721d86f39ec8f092fc2af67f4217a2b07fd3e93c6101", size = 458968, upload-time = "2025-10-14T15:05:44.404Z" }, - { url = "https://files.pythonhosted.org/packages/47/c2/9059c2e8966ea5ce678166617a7f75ecba6164375f3b288e50a40dc6d489/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f096076119da54a6080e8920cbdaac3dbee667eb91dcc5e5b78840b87415bd44", size = 488096, upload-time = "2025-10-14T15:05:45.398Z" }, - { url = "https://files.pythonhosted.org/packages/94/44/d90a9ec8ac309bc26db808a13e7bfc0e4e78b6fc051078a554e132e80160/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:00485f441d183717038ed2e887a7c868154f216877653121068107b227a2f64c", size = 596040, upload-time = "2025-10-14T15:05:46.502Z" }, - { url = "https://files.pythonhosted.org/packages/95/68/4e3479b20ca305cfc561db3ed207a8a1c745ee32bf24f2026a129d0ddb6e/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a55f3e9e493158d7bfdb60a1165035f1cf7d320914e7b7ea83fe22c6023b58fc", size = 473847, upload-time = "2025-10-14T15:05:47.484Z" }, - { url = "https://files.pythonhosted.org/packages/4f/55/2af26693fd15165c4ff7857e38330e1b61ab8c37d15dc79118cdba115b7a/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c91ed27800188c2ae96d16e3149f199d62f86c7af5f5f4d2c61a3ed8cd3666c", size = 455072, upload-time = "2025-10-14T15:05:48.928Z" }, - { url = "https://files.pythonhosted.org/packages/66/1d/d0d200b10c9311ec25d2273f8aad8c3ef7cc7ea11808022501811208a750/watchfiles-1.1.1-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:311ff15a0bae3714ffb603e6ba6dbfba4065ab60865d15a6ec544133bdb21099", size = 629104, upload-time = "2025-10-14T15:05:49.908Z" }, - { url = "https://files.pythonhosted.org/packages/e3/bd/fa9bb053192491b3867ba07d2343d9f2252e00811567d30ae8d0f78136fe/watchfiles-1.1.1-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:a916a2932da8f8ab582f242c065f5c81bed3462849ca79ee357dd9551b0e9b01", size = 622112, upload-time = "2025-10-14T15:05:50.941Z" }, -] - -[[package]] -name = "websockets" -version = "15.0.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/21/e6/26d09fab466b7ca9c7737474c52be4f76a40301b08362eb2dbc19dcc16c1/websockets-15.0.1.tar.gz", hash = "sha256:82544de02076bafba038ce055ee6412d68da13ab47f0c60cab827346de828dee", size = 177016, upload-time = "2025-03-05T20:03:41.606Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/cb/9f/51f0cf64471a9d2b4d0fc6c534f323b664e7095640c34562f5182e5a7195/websockets-15.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ee443ef070bb3b6ed74514f5efaa37a252af57c90eb33b956d35c8e9c10a1931", size = 175440, upload-time = "2025-03-05T20:02:36.695Z" }, - { url = "https://files.pythonhosted.org/packages/8a/05/aa116ec9943c718905997412c5989f7ed671bc0188ee2ba89520e8765d7b/websockets-15.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5a939de6b7b4e18ca683218320fc67ea886038265fd1ed30173f5ce3f8e85675", size = 173098, upload-time = "2025-03-05T20:02:37.985Z" }, - { url = "https://files.pythonhosted.org/packages/ff/0b/33cef55ff24f2d92924923c99926dcce78e7bd922d649467f0eda8368923/websockets-15.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:746ee8dba912cd6fc889a8147168991d50ed70447bf18bcda7039f7d2e3d9151", size = 173329, upload-time = "2025-03-05T20:02:39.298Z" }, - { url = "https://files.pythonhosted.org/packages/31/1d/063b25dcc01faa8fada1469bdf769de3768b7044eac9d41f734fd7b6ad6d/websockets-15.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:595b6c3969023ecf9041b2936ac3827e4623bfa3ccf007575f04c5a6aa318c22", size = 183111, upload-time = "2025-03-05T20:02:40.595Z" }, - { url = "https://files.pythonhosted.org/packages/93/53/9a87ee494a51bf63e4ec9241c1ccc4f7c2f45fff85d5bde2ff74fcb68b9e/websockets-15.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c714d2fc58b5ca3e285461a4cc0c9a66bd0e24c5da9911e30158286c9b5be7f", size = 182054, upload-time = "2025-03-05T20:02:41.926Z" }, - { url = "https://files.pythonhosted.org/packages/ff/b2/83a6ddf56cdcbad4e3d841fcc55d6ba7d19aeb89c50f24dd7e859ec0805f/websockets-15.0.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f3c1e2ab208db911594ae5b4f79addeb3501604a165019dd221c0bdcabe4db8", size = 182496, upload-time = "2025-03-05T20:02:43.304Z" }, - { url = "https://files.pythonhosted.org/packages/98/41/e7038944ed0abf34c45aa4635ba28136f06052e08fc2168520bb8b25149f/websockets-15.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:229cf1d3ca6c1804400b0a9790dc66528e08a6a1feec0d5040e8b9eb14422375", size = 182829, upload-time = "2025-03-05T20:02:48.812Z" }, - { url = "https://files.pythonhosted.org/packages/e0/17/de15b6158680c7623c6ef0db361da965ab25d813ae54fcfeae2e5b9ef910/websockets-15.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:756c56e867a90fb00177d530dca4b097dd753cde348448a1012ed6c5131f8b7d", size = 182217, upload-time = "2025-03-05T20:02:50.14Z" }, - { url = "https://files.pythonhosted.org/packages/33/2b/1f168cb6041853eef0362fb9554c3824367c5560cbdaad89ac40f8c2edfc/websockets-15.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:558d023b3df0bffe50a04e710bc87742de35060580a293c2a984299ed83bc4e4", size = 182195, upload-time = "2025-03-05T20:02:51.561Z" }, - { url = "https://files.pythonhosted.org/packages/86/eb/20b6cdf273913d0ad05a6a14aed4b9a85591c18a987a3d47f20fa13dcc47/websockets-15.0.1-cp313-cp313-win32.whl", hash = "sha256:ba9e56e8ceeeedb2e080147ba85ffcd5cd0711b89576b83784d8605a7df455fa", size = 176393, upload-time = "2025-03-05T20:02:53.814Z" }, - { url = "https://files.pythonhosted.org/packages/1b/6c/c65773d6cab416a64d191d6ee8a8b1c68a09970ea6909d16965d26bfed1e/websockets-15.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:e09473f095a819042ecb2ab9465aee615bd9c2028e4ef7d933600a8401c79561", size = 176837, upload-time = "2025-03-05T20:02:55.237Z" }, - { url = "https://files.pythonhosted.org/packages/fa/a8/5b41e0da817d64113292ab1f8247140aac61cbf6cfd085d6a0fa77f4984f/websockets-15.0.1-py3-none-any.whl", hash = "sha256:f7a866fbc1e97b5c617ee4116daaa09b722101d4a3c170c787450ba409f9736f", size = 169743, upload-time = "2025-03-05T20:03:39.41Z" }, -] - -[[package]] -name = "wtforms" -version = "3.1.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "markupsafe" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/6a/c7/96d10183c3470f1836846f7b9527d6cb0b6c2226ebca40f36fa29f23de60/wtforms-3.1.2.tar.gz", hash = "sha256:f8d76180d7239c94c6322f7990ae1216dae3659b7aa1cee94b6318bdffb474b9", size = 134705, upload-time = "2024-01-06T07:52:41.075Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/18/19/c3232f35e24dccfad372e9f341c4f3a1166ae7c66e4e1351a9467c921cc1/wtforms-3.1.2-py3-none-any.whl", hash = "sha256:bf831c042829c8cdbad74c27575098d541d039b1faa74c771545ecac916f2c07", size = 145961, upload-time = "2024-01-06T07:52:43.023Z" }, -] - -[[package]] -name = "yarl" -version = "1.22.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "idna" }, - { name = "multidict" }, - { name = "propcache" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/57/63/0c6ebca57330cd313f6102b16dd57ffaf3ec4c83403dcb45dbd15c6f3ea1/yarl-1.22.0.tar.gz", hash = "sha256:bebf8557577d4401ba8bd9ff33906f1376c877aa78d1fe216ad01b4d6745af71", size = 187169, upload-time = "2025-10-06T14:12:55.963Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ea/f3/d67de7260456ee105dc1d162d43a019ecad6b91e2f51809d6cddaa56690e/yarl-1.22.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8dee9c25c74997f6a750cd317b8ca63545169c098faee42c84aa5e506c819b53", size = 139980, upload-time = "2025-10-06T14:10:14.601Z" }, - { url = "https://files.pythonhosted.org/packages/01/88/04d98af0b47e0ef42597b9b28863b9060bb515524da0a65d5f4db160b2d5/yarl-1.22.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:01e73b85a5434f89fc4fe27dcda2aff08ddf35e4d47bbbea3bdcd25321af538a", size = 93424, upload-time = "2025-10-06T14:10:16.115Z" }, - { url = "https://files.pythonhosted.org/packages/18/91/3274b215fd8442a03975ce6bee5fe6aa57a8326b29b9d3d56234a1dca244/yarl-1.22.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:22965c2af250d20c873cdbee8ff958fb809940aeb2e74ba5f20aaf6b7ac8c70c", size = 93821, upload-time = "2025-10-06T14:10:17.993Z" }, - { url = "https://files.pythonhosted.org/packages/61/3a/caf4e25036db0f2da4ca22a353dfeb3c9d3c95d2761ebe9b14df8fc16eb0/yarl-1.22.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b4f15793aa49793ec8d1c708ab7f9eded1aa72edc5174cae703651555ed1b601", size = 373243, upload-time = "2025-10-06T14:10:19.44Z" }, - { url = "https://files.pythonhosted.org/packages/6e/9e/51a77ac7516e8e7803b06e01f74e78649c24ee1021eca3d6a739cb6ea49c/yarl-1.22.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e5542339dcf2747135c5c85f68680353d5cb9ffd741c0f2e8d832d054d41f35a", size = 342361, upload-time = "2025-10-06T14:10:21.124Z" }, - { url = "https://files.pythonhosted.org/packages/d4/f8/33b92454789dde8407f156c00303e9a891f1f51a0330b0fad7c909f87692/yarl-1.22.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5c401e05ad47a75869c3ab3e35137f8468b846770587e70d71e11de797d113df", size = 387036, upload-time = "2025-10-06T14:10:22.902Z" }, - { url = "https://files.pythonhosted.org/packages/d9/9a/c5db84ea024f76838220280f732970aa4ee154015d7f5c1bfb60a267af6f/yarl-1.22.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:243dda95d901c733f5b59214d28b0120893d91777cb8aa043e6ef059d3cddfe2", size = 397671, upload-time = "2025-10-06T14:10:24.523Z" }, - { url = "https://files.pythonhosted.org/packages/11/c9/cd8538dc2e7727095e0c1d867bad1e40c98f37763e6d995c1939f5fdc7b1/yarl-1.22.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bec03d0d388060058f5d291a813f21c011041938a441c593374da6077fe21b1b", size = 377059, upload-time = "2025-10-06T14:10:26.406Z" }, - { url = "https://files.pythonhosted.org/packages/a1/b9/ab437b261702ced75122ed78a876a6dec0a1b0f5e17a4ac7a9a2482d8abe/yarl-1.22.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b0748275abb8c1e1e09301ee3cf90c8a99678a4e92e4373705f2a2570d581273", size = 365356, upload-time = "2025-10-06T14:10:28.461Z" }, - { url = "https://files.pythonhosted.org/packages/b2/9d/8e1ae6d1d008a9567877b08f0ce4077a29974c04c062dabdb923ed98e6fe/yarl-1.22.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:47fdb18187e2a4e18fda2c25c05d8251a9e4a521edaed757fef033e7d8498d9a", size = 361331, upload-time = "2025-10-06T14:10:30.541Z" }, - { url = "https://files.pythonhosted.org/packages/ca/5a/09b7be3905962f145b73beb468cdd53db8aa171cf18c80400a54c5b82846/yarl-1.22.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c7044802eec4524fde550afc28edda0dd5784c4c45f0be151a2d3ba017daca7d", size = 382590, upload-time = "2025-10-06T14:10:33.352Z" }, - { url = "https://files.pythonhosted.org/packages/aa/7f/59ec509abf90eda5048b0bc3e2d7b5099dffdb3e6b127019895ab9d5ef44/yarl-1.22.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:139718f35149ff544caba20fce6e8a2f71f1e39b92c700d8438a0b1d2a631a02", size = 385316, upload-time = "2025-10-06T14:10:35.034Z" }, - { url = "https://files.pythonhosted.org/packages/e5/84/891158426bc8036bfdfd862fabd0e0fa25df4176ec793e447f4b85cf1be4/yarl-1.22.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e1b51bebd221006d3d2f95fbe124b22b247136647ae5dcc8c7acafba66e5ee67", size = 374431, upload-time = "2025-10-06T14:10:37.76Z" }, - { url = "https://files.pythonhosted.org/packages/bb/49/03da1580665baa8bef5e8ed34c6df2c2aca0a2f28bf397ed238cc1bbc6f2/yarl-1.22.0-cp313-cp313-win32.whl", hash = "sha256:d3e32536234a95f513bd374e93d717cf6b2231a791758de6c509e3653f234c95", size = 81555, upload-time = "2025-10-06T14:10:39.649Z" }, - { url = "https://files.pythonhosted.org/packages/9a/ee/450914ae11b419eadd067c6183ae08381cfdfcb9798b90b2b713bbebddda/yarl-1.22.0-cp313-cp313-win_amd64.whl", hash = "sha256:47743b82b76d89a1d20b83e60d5c20314cbd5ba2befc9cda8f28300c4a08ed4d", size = 86965, upload-time = "2025-10-06T14:10:41.313Z" }, - { url = "https://files.pythonhosted.org/packages/98/4d/264a01eae03b6cf629ad69bae94e3b0e5344741e929073678e84bf7a3e3b/yarl-1.22.0-cp313-cp313-win_arm64.whl", hash = "sha256:5d0fcda9608875f7d052eff120c7a5da474a6796fe4d83e152e0e4d42f6d1a9b", size = 81205, upload-time = "2025-10-06T14:10:43.167Z" }, - { url = "https://files.pythonhosted.org/packages/88/fc/6908f062a2f77b5f9f6d69cecb1747260831ff206adcbc5b510aff88df91/yarl-1.22.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:719ae08b6972befcba4310e49edb1161a88cdd331e3a694b84466bd938a6ab10", size = 146209, upload-time = "2025-10-06T14:10:44.643Z" }, - { url = "https://files.pythonhosted.org/packages/65/47/76594ae8eab26210b4867be6f49129861ad33da1f1ebdf7051e98492bf62/yarl-1.22.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:47d8a5c446df1c4db9d21b49619ffdba90e77c89ec6e283f453856c74b50b9e3", size = 95966, upload-time = "2025-10-06T14:10:46.554Z" }, - { url = "https://files.pythonhosted.org/packages/ab/ce/05e9828a49271ba6b5b038b15b3934e996980dd78abdfeb52a04cfb9467e/yarl-1.22.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:cfebc0ac8333520d2d0423cbbe43ae43c8838862ddb898f5ca68565e395516e9", size = 97312, upload-time = "2025-10-06T14:10:48.007Z" }, - { url = "https://files.pythonhosted.org/packages/d1/c5/7dffad5e4f2265b29c9d7ec869c369e4223166e4f9206fc2243ee9eea727/yarl-1.22.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4398557cbf484207df000309235979c79c4356518fd5c99158c7d38203c4da4f", size = 361967, upload-time = "2025-10-06T14:10:49.997Z" }, - { url = "https://files.pythonhosted.org/packages/50/b2/375b933c93a54bff7fc041e1a6ad2c0f6f733ffb0c6e642ce56ee3b39970/yarl-1.22.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2ca6fd72a8cd803be290d42f2dec5cdcd5299eeb93c2d929bf060ad9efaf5de0", size = 323949, upload-time = "2025-10-06T14:10:52.004Z" }, - { url = "https://files.pythonhosted.org/packages/66/50/bfc2a29a1d78644c5a7220ce2f304f38248dc94124a326794e677634b6cf/yarl-1.22.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ca1f59c4e1ab6e72f0a23c13fca5430f889634166be85dbf1013683e49e3278e", size = 361818, upload-time = "2025-10-06T14:10:54.078Z" }, - { url = "https://files.pythonhosted.org/packages/46/96/f3941a46af7d5d0f0498f86d71275696800ddcdd20426298e572b19b91ff/yarl-1.22.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6c5010a52015e7c70f86eb967db0f37f3c8bd503a695a49f8d45700144667708", size = 372626, upload-time = "2025-10-06T14:10:55.767Z" }, - { url = "https://files.pythonhosted.org/packages/c1/42/8b27c83bb875cd89448e42cd627e0fb971fa1675c9ec546393d18826cb50/yarl-1.22.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d7672ecf7557476642c88497c2f8d8542f8e36596e928e9bcba0e42e1e7d71f", size = 341129, upload-time = "2025-10-06T14:10:57.985Z" }, - { url = "https://files.pythonhosted.org/packages/49/36/99ca3122201b382a3cf7cc937b95235b0ac944f7e9f2d5331d50821ed352/yarl-1.22.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:3b7c88eeef021579d600e50363e0b6ee4f7f6f728cd3486b9d0f3ee7b946398d", size = 346776, upload-time = "2025-10-06T14:10:59.633Z" }, - { url = "https://files.pythonhosted.org/packages/85/b4/47328bf996acd01a4c16ef9dcd2f59c969f495073616586f78cd5f2efb99/yarl-1.22.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:f4afb5c34f2c6fecdcc182dfcfc6af6cccf1aa923eed4d6a12e9d96904e1a0d8", size = 334879, upload-time = "2025-10-06T14:11:01.454Z" }, - { url = "https://files.pythonhosted.org/packages/c2/ad/b77d7b3f14a4283bffb8e92c6026496f6de49751c2f97d4352242bba3990/yarl-1.22.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:59c189e3e99a59cf8d83cbb31d4db02d66cda5a1a4374e8a012b51255341abf5", size = 350996, upload-time = "2025-10-06T14:11:03.452Z" }, - { url = "https://files.pythonhosted.org/packages/81/c8/06e1d69295792ba54d556f06686cbd6a7ce39c22307100e3fb4a2c0b0a1d/yarl-1.22.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:5a3bf7f62a289fa90f1990422dc8dff5a458469ea71d1624585ec3a4c8d6960f", size = 356047, upload-time = "2025-10-06T14:11:05.115Z" }, - { url = "https://files.pythonhosted.org/packages/4b/b8/4c0e9e9f597074b208d18cef227d83aac36184bfbc6eab204ea55783dbc5/yarl-1.22.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:de6b9a04c606978fdfe72666fa216ffcf2d1a9f6a381058d4378f8d7b1e5de62", size = 342947, upload-time = "2025-10-06T14:11:08.137Z" }, - { url = "https://files.pythonhosted.org/packages/e0/e5/11f140a58bf4c6ad7aca69a892bff0ee638c31bea4206748fc0df4ebcb3a/yarl-1.22.0-cp313-cp313t-win32.whl", hash = "sha256:1834bb90991cc2999f10f97f5f01317f99b143284766d197e43cd5b45eb18d03", size = 86943, upload-time = "2025-10-06T14:11:10.284Z" }, - { url = "https://files.pythonhosted.org/packages/31/74/8b74bae38ed7fe6793d0c15a0c8207bbb819cf287788459e5ed230996cdd/yarl-1.22.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ff86011bd159a9d2dfc89c34cfd8aff12875980e3bd6a39ff097887520e60249", size = 93715, upload-time = "2025-10-06T14:11:11.739Z" }, - { url = "https://files.pythonhosted.org/packages/69/66/991858aa4b5892d57aef7ee1ba6b4d01ec3b7eb3060795d34090a3ca3278/yarl-1.22.0-cp313-cp313t-win_arm64.whl", hash = "sha256:7861058d0582b847bc4e3a4a4c46828a410bca738673f35a29ba3ca5db0b473b", size = 83857, upload-time = "2025-10-06T14:11:13.586Z" }, - { url = "https://files.pythonhosted.org/packages/46/b3/e20ef504049f1a1c54a814b4b9bed96d1ac0e0610c3b4da178f87209db05/yarl-1.22.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:34b36c2c57124530884d89d50ed2c1478697ad7473efd59cfd479945c95650e4", size = 140520, upload-time = "2025-10-06T14:11:15.465Z" }, - { url = "https://files.pythonhosted.org/packages/e4/04/3532d990fdbab02e5ede063676b5c4260e7f3abea2151099c2aa745acc4c/yarl-1.22.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:0dd9a702591ca2e543631c2a017e4a547e38a5c0f29eece37d9097e04a7ac683", size = 93504, upload-time = "2025-10-06T14:11:17.106Z" }, - { url = "https://files.pythonhosted.org/packages/11/63/ff458113c5c2dac9a9719ac68ee7c947cb621432bcf28c9972b1c0e83938/yarl-1.22.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:594fcab1032e2d2cc3321bb2e51271e7cd2b516c7d9aee780ece81b07ff8244b", size = 94282, upload-time = "2025-10-06T14:11:19.064Z" }, - { url = "https://files.pythonhosted.org/packages/a7/bc/315a56aca762d44a6aaaf7ad253f04d996cb6b27bad34410f82d76ea8038/yarl-1.22.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f3d7a87a78d46a2e3d5b72587ac14b4c16952dd0887dbb051451eceac774411e", size = 372080, upload-time = "2025-10-06T14:11:20.996Z" }, - { url = "https://files.pythonhosted.org/packages/3f/3f/08e9b826ec2e099ea6e7c69a61272f4f6da62cb5b1b63590bb80ca2e4a40/yarl-1.22.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:852863707010316c973162e703bddabec35e8757e67fcb8ad58829de1ebc8590", size = 338696, upload-time = "2025-10-06T14:11:22.847Z" }, - { url = "https://files.pythonhosted.org/packages/e3/9f/90360108e3b32bd76789088e99538febfea24a102380ae73827f62073543/yarl-1.22.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:131a085a53bfe839a477c0845acf21efc77457ba2bcf5899618136d64f3303a2", size = 387121, upload-time = "2025-10-06T14:11:24.889Z" }, - { url = "https://files.pythonhosted.org/packages/98/92/ab8d4657bd5b46a38094cfaea498f18bb70ce6b63508fd7e909bd1f93066/yarl-1.22.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:078a8aefd263f4d4f923a9677b942b445a2be970ca24548a8102689a3a8ab8da", size = 394080, upload-time = "2025-10-06T14:11:27.307Z" }, - { url = "https://files.pythonhosted.org/packages/f5/e7/d8c5a7752fef68205296201f8ec2bf718f5c805a7a7e9880576c67600658/yarl-1.22.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bca03b91c323036913993ff5c738d0842fc9c60c4648e5c8d98331526df89784", size = 372661, upload-time = "2025-10-06T14:11:29.387Z" }, - { url = "https://files.pythonhosted.org/packages/b6/2e/f4d26183c8db0bb82d491b072f3127fb8c381a6206a3a56332714b79b751/yarl-1.22.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:68986a61557d37bb90d3051a45b91fa3d5c516d177dfc6dd6f2f436a07ff2b6b", size = 364645, upload-time = "2025-10-06T14:11:31.423Z" }, - { url = "https://files.pythonhosted.org/packages/80/7c/428e5812e6b87cd00ee8e898328a62c95825bf37c7fa87f0b6bb2ad31304/yarl-1.22.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:4792b262d585ff0dff6bcb787f8492e40698443ec982a3568c2096433660c694", size = 355361, upload-time = "2025-10-06T14:11:33.055Z" }, - { url = "https://files.pythonhosted.org/packages/ec/2a/249405fd26776f8b13c067378ef4d7dd49c9098d1b6457cdd152a99e96a9/yarl-1.22.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:ebd4549b108d732dba1d4ace67614b9545b21ece30937a63a65dd34efa19732d", size = 381451, upload-time = "2025-10-06T14:11:35.136Z" }, - { url = "https://files.pythonhosted.org/packages/67/a8/fb6b1adbe98cf1e2dd9fad71003d3a63a1bc22459c6e15f5714eb9323b93/yarl-1.22.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:f87ac53513d22240c7d59203f25cc3beac1e574c6cd681bbfd321987b69f95fd", size = 383814, upload-time = "2025-10-06T14:11:37.094Z" }, - { url = "https://files.pythonhosted.org/packages/d9/f9/3aa2c0e480fb73e872ae2814c43bc1e734740bb0d54e8cb2a95925f98131/yarl-1.22.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:22b029f2881599e2f1b06f8f1db2ee63bd309e2293ba2d566e008ba12778b8da", size = 370799, upload-time = "2025-10-06T14:11:38.83Z" }, - { url = "https://files.pythonhosted.org/packages/50/3c/af9dba3b8b5eeb302f36f16f92791f3ea62e3f47763406abf6d5a4a3333b/yarl-1.22.0-cp314-cp314-win32.whl", hash = "sha256:6a635ea45ba4ea8238463b4f7d0e721bad669f80878b7bfd1f89266e2ae63da2", size = 82990, upload-time = "2025-10-06T14:11:40.624Z" }, - { url = "https://files.pythonhosted.org/packages/ac/30/ac3a0c5bdc1d6efd1b41fa24d4897a4329b3b1e98de9449679dd327af4f0/yarl-1.22.0-cp314-cp314-win_amd64.whl", hash = "sha256:0d6e6885777af0f110b0e5d7e5dda8b704efed3894da26220b7f3d887b839a79", size = 88292, upload-time = "2025-10-06T14:11:42.578Z" }, - { url = "https://files.pythonhosted.org/packages/df/0a/227ab4ff5b998a1b7410abc7b46c9b7a26b0ca9e86c34ba4b8d8bc7c63d5/yarl-1.22.0-cp314-cp314-win_arm64.whl", hash = "sha256:8218f4e98d3c10d683584cb40f0424f4b9fd6e95610232dd75e13743b070ee33", size = 82888, upload-time = "2025-10-06T14:11:44.863Z" }, - { url = "https://files.pythonhosted.org/packages/06/5e/a15eb13db90abd87dfbefb9760c0f3f257ac42a5cac7e75dbc23bed97a9f/yarl-1.22.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:45c2842ff0e0d1b35a6bf1cd6c690939dacb617a70827f715232b2e0494d55d1", size = 146223, upload-time = "2025-10-06T14:11:46.796Z" }, - { url = "https://files.pythonhosted.org/packages/18/82/9665c61910d4d84f41a5bf6837597c89e665fa88aa4941080704645932a9/yarl-1.22.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:d947071e6ebcf2e2bee8fce76e10faca8f7a14808ca36a910263acaacef08eca", size = 95981, upload-time = "2025-10-06T14:11:48.845Z" }, - { url = "https://files.pythonhosted.org/packages/5d/9a/2f65743589809af4d0a6d3aa749343c4b5f4c380cc24a8e94a3c6625a808/yarl-1.22.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:334b8721303e61b00019474cc103bdac3d7b1f65e91f0bfedeec2d56dfe74b53", size = 97303, upload-time = "2025-10-06T14:11:50.897Z" }, - { url = "https://files.pythonhosted.org/packages/b0/ab/5b13d3e157505c43c3b43b5a776cbf7b24a02bc4cccc40314771197e3508/yarl-1.22.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1e7ce67c34138a058fd092f67d07a72b8e31ff0c9236e751957465a24b28910c", size = 361820, upload-time = "2025-10-06T14:11:52.549Z" }, - { url = "https://files.pythonhosted.org/packages/fb/76/242a5ef4677615cf95330cfc1b4610e78184400699bdda0acb897ef5e49a/yarl-1.22.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d77e1b2c6d04711478cb1c4ab90db07f1609ccf06a287d5607fcd90dc9863acf", size = 323203, upload-time = "2025-10-06T14:11:54.225Z" }, - { url = "https://files.pythonhosted.org/packages/8c/96/475509110d3f0153b43d06164cf4195c64d16999e0c7e2d8a099adcd6907/yarl-1.22.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c4647674b6150d2cae088fc07de2738a84b8bcedebef29802cf0b0a82ab6face", size = 363173, upload-time = "2025-10-06T14:11:56.069Z" }, - { url = "https://files.pythonhosted.org/packages/c9/66/59db471aecfbd559a1fd48aedd954435558cd98c7d0da8b03cc6c140a32c/yarl-1.22.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:efb07073be061c8f79d03d04139a80ba33cbd390ca8f0297aae9cce6411e4c6b", size = 373562, upload-time = "2025-10-06T14:11:58.783Z" }, - { url = "https://files.pythonhosted.org/packages/03/1f/c5d94abc91557384719da10ff166b916107c1b45e4d0423a88457071dd88/yarl-1.22.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e51ac5435758ba97ad69617e13233da53908beccc6cfcd6c34bbed8dcbede486", size = 339828, upload-time = "2025-10-06T14:12:00.686Z" }, - { url = "https://files.pythonhosted.org/packages/5f/97/aa6a143d3afba17b6465733681c70cf175af89f76ec8d9286e08437a7454/yarl-1.22.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:33e32a0dd0c8205efa8e83d04fc9f19313772b78522d1bdc7d9aed706bfd6138", size = 347551, upload-time = "2025-10-06T14:12:02.628Z" }, - { url = "https://files.pythonhosted.org/packages/43/3c/45a2b6d80195959239a7b2a8810506d4eea5487dce61c2a3393e7fc3c52e/yarl-1.22.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:bf4a21e58b9cde0e401e683ebd00f6ed30a06d14e93f7c8fd059f8b6e8f87b6a", size = 334512, upload-time = "2025-10-06T14:12:04.871Z" }, - { url = "https://files.pythonhosted.org/packages/86/a0/c2ab48d74599c7c84cb104ebd799c5813de252bea0f360ffc29d270c2caa/yarl-1.22.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:e4b582bab49ac33c8deb97e058cd67c2c50dac0dd134874106d9c774fd272529", size = 352400, upload-time = "2025-10-06T14:12:06.624Z" }, - { url = "https://files.pythonhosted.org/packages/32/75/f8919b2eafc929567d3d8411f72bdb1a2109c01caaab4ebfa5f8ffadc15b/yarl-1.22.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:0b5bcc1a9c4839e7e30b7b30dd47fe5e7e44fb7054ec29b5bb8d526aa1041093", size = 357140, upload-time = "2025-10-06T14:12:08.362Z" }, - { url = "https://files.pythonhosted.org/packages/cf/72/6a85bba382f22cf78add705d8c3731748397d986e197e53ecc7835e76de7/yarl-1.22.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c0232bce2170103ec23c454e54a57008a9a72b5d1c3105dc2496750da8cfa47c", size = 341473, upload-time = "2025-10-06T14:12:10.994Z" }, - { url = "https://files.pythonhosted.org/packages/35/18/55e6011f7c044dc80b98893060773cefcfdbf60dfefb8cb2f58b9bacbd83/yarl-1.22.0-cp314-cp314t-win32.whl", hash = "sha256:8009b3173bcd637be650922ac455946197d858b3630b6d8787aa9e5c4564533e", size = 89056, upload-time = "2025-10-06T14:12:13.317Z" }, - { url = "https://files.pythonhosted.org/packages/f9/86/0f0dccb6e59a9e7f122c5afd43568b1d31b8ab7dda5f1b01fb5c7025c9a9/yarl-1.22.0-cp314-cp314t-win_amd64.whl", hash = "sha256:9fb17ea16e972c63d25d4a97f016d235c78dd2344820eb35bc034bc32012ee27", size = 96292, upload-time = "2025-10-06T14:12:15.398Z" }, - { url = "https://files.pythonhosted.org/packages/48/b7/503c98092fb3b344a179579f55814b613c1fbb1c23b3ec14a7b008a66a6e/yarl-1.22.0-cp314-cp314t-win_arm64.whl", hash = "sha256:9f6d73c1436b934e3f01df1e1b21ff765cd1d28c77dfb9ace207f746d4610ee1", size = 85171, upload-time = "2025-10-06T14:12:16.935Z" }, - { url = "https://files.pythonhosted.org/packages/73/ae/b48f95715333080afb75a4504487cbe142cae1268afc482d06692d605ae6/yarl-1.22.0-py3-none-any.whl", hash = "sha256:1380560bdba02b6b6c90de54133c81c9f2a453dee9912fe58c1dcced1edb7cff", size = 46814, upload-time = "2025-10-06T14:12:53.872Z" }, -] +version = 1 +revision = 3 +requires-python = ">=3.13" + +[[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, upload-time = "2025-10-09T20:51:04.358Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bc/8a/340a1555ae33d7354dbca4faa54948d76d89a27ceef032c8c3bc661d003e/aiofiles-25.1.0-py3-none-any.whl", hash = "sha256:abe311e527c862958650f9438e859c1fa7568a141b22abcd015e120e86a85695", size = 14668, upload-time = "2025-10-09T20:51:03.174Z" }, +] + +[[package]] +name = "aiohappyeyeballs" +version = "2.6.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/26/30/f84a107a9c4331c14b2b586036f40965c128aa4fee4dda5d3d51cb14ad54/aiohappyeyeballs-2.6.1.tar.gz", hash = "sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558", size = 22760, upload-time = "2025-03-12T01:42:48.764Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl", hash = "sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8", size = 15265, upload-time = "2025-03-12T01:42:47.083Z" }, +] + +[[package]] +name = "aiohttp" +version = "3.13.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiohappyeyeballs" }, + { name = "aiosignal" }, + { name = "attrs" }, + { name = "frozenlist" }, + { name = "multidict" }, + { name = "propcache" }, + { name = "yarl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1c/ce/3b83ebba6b3207a7135e5fcaba49706f8a4b6008153b4e30540c982fae26/aiohttp-3.13.2.tar.gz", hash = "sha256:40176a52c186aefef6eb3cad2cdd30cd06e3afbe88fe8ab2af9c0b90f228daca", size = 7837994, upload-time = "2025-10-28T20:59:39.937Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bf/78/7e90ca79e5aa39f9694dcfd74f4720782d3c6828113bb1f3197f7e7c4a56/aiohttp-3.13.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:7519bdc7dfc1940d201651b52bf5e03f5503bda45ad6eacf64dda98be5b2b6be", size = 732139, upload-time = "2025-10-28T20:57:02.455Z" }, + { url = "https://files.pythonhosted.org/packages/db/ed/1f59215ab6853fbaa5c8495fa6cbc39edfc93553426152b75d82a5f32b76/aiohttp-3.13.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:088912a78b4d4f547a1f19c099d5a506df17eacec3c6f4375e2831ec1d995742", size = 490082, upload-time = "2025-10-28T20:57:04.784Z" }, + { url = "https://files.pythonhosted.org/packages/68/7b/fe0fe0f5e05e13629d893c760465173a15ad0039c0a5b0d0040995c8075e/aiohttp-3.13.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5276807b9de9092af38ed23ce120539ab0ac955547b38563a9ba4f5b07b95293", size = 489035, upload-time = "2025-10-28T20:57:06.894Z" }, + { url = "https://files.pythonhosted.org/packages/d2/04/db5279e38471b7ac801d7d36a57d1230feeee130bbe2a74f72731b23c2b1/aiohttp-3.13.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1237c1375eaef0db4dcd7c2559f42e8af7b87ea7d295b118c60c36a6e61cb811", size = 1720387, upload-time = "2025-10-28T20:57:08.685Z" }, + { url = "https://files.pythonhosted.org/packages/31/07/8ea4326bd7dae2bd59828f69d7fdc6e04523caa55e4a70f4a8725a7e4ed2/aiohttp-3.13.2-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:96581619c57419c3d7d78703d5b78c1e5e5fc0172d60f555bdebaced82ded19a", size = 1688314, upload-time = "2025-10-28T20:57:10.693Z" }, + { url = "https://files.pythonhosted.org/packages/48/ab/3d98007b5b87ffd519d065225438cc3b668b2f245572a8cb53da5dd2b1bc/aiohttp-3.13.2-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a2713a95b47374169409d18103366de1050fe0ea73db358fc7a7acb2880422d4", size = 1756317, upload-time = "2025-10-28T20:57:12.563Z" }, + { url = "https://files.pythonhosted.org/packages/97/3d/801ca172b3d857fafb7b50c7c03f91b72b867a13abca982ed6b3081774ef/aiohttp-3.13.2-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:228a1cd556b3caca590e9511a89444925da87d35219a49ab5da0c36d2d943a6a", size = 1858539, upload-time = "2025-10-28T20:57:14.623Z" }, + { url = "https://files.pythonhosted.org/packages/f7/0d/4764669bdf47bd472899b3d3db91fffbe925c8e3038ec591a2fd2ad6a14d/aiohttp-3.13.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ac6cde5fba8d7d8c6ac963dbb0256a9854e9fafff52fbcc58fdf819357892c3e", size = 1739597, upload-time = "2025-10-28T20:57:16.399Z" }, + { url = "https://files.pythonhosted.org/packages/c4/52/7bd3c6693da58ba16e657eb904a5b6decfc48ecd06e9ac098591653b1566/aiohttp-3.13.2-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f2bef8237544f4e42878c61cef4e2839fee6346dc60f5739f876a9c50be7fcdb", size = 1555006, upload-time = "2025-10-28T20:57:18.288Z" }, + { url = "https://files.pythonhosted.org/packages/48/30/9586667acec5993b6f41d2ebcf96e97a1255a85f62f3c653110a5de4d346/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:16f15a4eac3bc2d76c45f7ebdd48a65d41b242eb6c31c2245463b40b34584ded", size = 1683220, upload-time = "2025-10-28T20:57:20.241Z" }, + { url = "https://files.pythonhosted.org/packages/71/01/3afe4c96854cfd7b30d78333852e8e851dceaec1c40fd00fec90c6402dd2/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:bb7fb776645af5cc58ab804c58d7eba545a97e047254a52ce89c157b5af6cd0b", size = 1712570, upload-time = "2025-10-28T20:57:22.253Z" }, + { url = "https://files.pythonhosted.org/packages/11/2c/22799d8e720f4697a9e66fd9c02479e40a49de3de2f0bbe7f9f78a987808/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:e1b4951125ec10c70802f2cb09736c895861cd39fd9dcb35107b4dc8ae6220b8", size = 1733407, upload-time = "2025-10-28T20:57:24.37Z" }, + { url = "https://files.pythonhosted.org/packages/34/cb/90f15dd029f07cebbd91f8238a8b363978b530cd128488085b5703683594/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:550bf765101ae721ee1d37d8095f47b1f220650f85fe1af37a90ce75bab89d04", size = 1550093, upload-time = "2025-10-28T20:57:26.257Z" }, + { url = "https://files.pythonhosted.org/packages/69/46/12dce9be9d3303ecbf4d30ad45a7683dc63d90733c2d9fe512be6716cd40/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:fe91b87fc295973096251e2d25a811388e7d8adf3bd2b97ef6ae78bc4ac6c476", size = 1758084, upload-time = "2025-10-28T20:57:28.349Z" }, + { url = "https://files.pythonhosted.org/packages/f9/c8/0932b558da0c302ffd639fc6362a313b98fdf235dc417bc2493da8394df7/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e0c8e31cfcc4592cb200160344b2fb6ae0f9e4effe06c644b5a125d4ae5ebe23", size = 1716987, upload-time = "2025-10-28T20:57:30.233Z" }, + { url = "https://files.pythonhosted.org/packages/5d/8b/f5bd1a75003daed099baec373aed678f2e9b34f2ad40d85baa1368556396/aiohttp-3.13.2-cp313-cp313-win32.whl", hash = "sha256:0740f31a60848d6edb296a0df827473eede90c689b8f9f2a4cdde74889eb2254", size = 425859, upload-time = "2025-10-28T20:57:32.105Z" }, + { url = "https://files.pythonhosted.org/packages/5d/28/a8a9fc6957b2cee8902414e41816b5ab5536ecf43c3b1843c10e82c559b2/aiohttp-3.13.2-cp313-cp313-win_amd64.whl", hash = "sha256:a88d13e7ca367394908f8a276b89d04a3652044612b9a408a0bb22a5ed976a1a", size = 452192, upload-time = "2025-10-28T20:57:34.166Z" }, + { url = "https://files.pythonhosted.org/packages/9b/36/e2abae1bd815f01c957cbf7be817b3043304e1c87bad526292a0410fdcf9/aiohttp-3.13.2-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:2475391c29230e063ef53a66669b7b691c9bfc3f1426a0f7bcdf1216bdbac38b", size = 735234, upload-time = "2025-10-28T20:57:36.415Z" }, + { url = "https://files.pythonhosted.org/packages/ca/e3/1ee62dde9b335e4ed41db6bba02613295a0d5b41f74a783c142745a12763/aiohttp-3.13.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:f33c8748abef4d8717bb20e8fb1b3e07c6adacb7fd6beaae971a764cf5f30d61", size = 490733, upload-time = "2025-10-28T20:57:38.205Z" }, + { url = "https://files.pythonhosted.org/packages/1a/aa/7a451b1d6a04e8d15a362af3e9b897de71d86feac3babf8894545d08d537/aiohttp-3.13.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ae32f24bbfb7dbb485a24b30b1149e2f200be94777232aeadba3eecece4d0aa4", size = 491303, upload-time = "2025-10-28T20:57:40.122Z" }, + { url = "https://files.pythonhosted.org/packages/57/1e/209958dbb9b01174870f6a7538cd1f3f28274fdbc88a750c238e2c456295/aiohttp-3.13.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d7f02042c1f009ffb70067326ef183a047425bb2ff3bc434ead4dd4a4a66a2b", size = 1717965, upload-time = "2025-10-28T20:57:42.28Z" }, + { url = "https://files.pythonhosted.org/packages/08/aa/6a01848d6432f241416bc4866cae8dc03f05a5a884d2311280f6a09c73d6/aiohttp-3.13.2-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:93655083005d71cd6c072cdab54c886e6570ad2c4592139c3fb967bfc19e4694", size = 1667221, upload-time = "2025-10-28T20:57:44.869Z" }, + { url = "https://files.pythonhosted.org/packages/87/4f/36c1992432d31bbc789fa0b93c768d2e9047ec8c7177e5cd84ea85155f36/aiohttp-3.13.2-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0db1e24b852f5f664cd728db140cf11ea0e82450471232a394b3d1a540b0f906", size = 1757178, upload-time = "2025-10-28T20:57:47.216Z" }, + { url = "https://files.pythonhosted.org/packages/ac/b4/8e940dfb03b7e0f68a82b88fd182b9be0a65cb3f35612fe38c038c3112cf/aiohttp-3.13.2-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b009194665bcd128e23eaddef362e745601afa4641930848af4c8559e88f18f9", size = 1838001, upload-time = "2025-10-28T20:57:49.337Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ef/39f3448795499c440ab66084a9db7d20ca7662e94305f175a80f5b7e0072/aiohttp-3.13.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c038a8fdc8103cd51dbd986ecdce141473ffd9775a7a8057a6ed9c3653478011", size = 1716325, upload-time = "2025-10-28T20:57:51.327Z" }, + { url = "https://files.pythonhosted.org/packages/d7/51/b311500ffc860b181c05d91c59a1313bdd05c82960fdd4035a15740d431e/aiohttp-3.13.2-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:66bac29b95a00db411cd758fea0e4b9bdba6d549dfe333f9a945430f5f2cc5a6", size = 1547978, upload-time = "2025-10-28T20:57:53.554Z" }, + { url = "https://files.pythonhosted.org/packages/31/64/b9d733296ef79815226dab8c586ff9e3df41c6aff2e16c06697b2d2e6775/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4ebf9cfc9ba24a74cf0718f04aac2a3bbe745902cc7c5ebc55c0f3b5777ef213", size = 1682042, upload-time = "2025-10-28T20:57:55.617Z" }, + { url = "https://files.pythonhosted.org/packages/3f/30/43d3e0f9d6473a6db7d472104c4eff4417b1e9df01774cb930338806d36b/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:a4b88ebe35ce54205c7074f7302bd08a4cb83256a3e0870c72d6f68a3aaf8e49", size = 1680085, upload-time = "2025-10-28T20:57:57.59Z" }, + { url = "https://files.pythonhosted.org/packages/16/51/c709f352c911b1864cfd1087577760ced64b3e5bee2aa88b8c0c8e2e4972/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:98c4fb90bb82b70a4ed79ca35f656f4281885be076f3f970ce315402b53099ae", size = 1728238, upload-time = "2025-10-28T20:57:59.525Z" }, + { url = "https://files.pythonhosted.org/packages/19/e2/19bd4c547092b773caeb48ff5ae4b1ae86756a0ee76c16727fcfd281404b/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:ec7534e63ae0f3759df3a1ed4fa6bc8f75082a924b590619c0dd2f76d7043caa", size = 1544395, upload-time = "2025-10-28T20:58:01.914Z" }, + { url = "https://files.pythonhosted.org/packages/cf/87/860f2803b27dfc5ed7be532832a3498e4919da61299b4a1f8eb89b8ff44d/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:5b927cf9b935a13e33644cbed6c8c4b2d0f25b713d838743f8fe7191b33829c4", size = 1742965, upload-time = "2025-10-28T20:58:03.972Z" }, + { url = "https://files.pythonhosted.org/packages/67/7f/db2fc7618925e8c7a601094d5cbe539f732df4fb570740be88ed9e40e99a/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:88d6c017966a78c5265d996c19cdb79235be5e6412268d7e2ce7dee339471b7a", size = 1697585, upload-time = "2025-10-28T20:58:06.189Z" }, + { url = "https://files.pythonhosted.org/packages/0c/07/9127916cb09bb38284db5036036042b7b2c514c8ebaeee79da550c43a6d6/aiohttp-3.13.2-cp314-cp314-win32.whl", hash = "sha256:f7c183e786e299b5d6c49fb43a769f8eb8e04a2726a2bd5887b98b5cc2d67940", size = 431621, upload-time = "2025-10-28T20:58:08.636Z" }, + { url = "https://files.pythonhosted.org/packages/fb/41/554a8a380df6d3a2bba8a7726429a23f4ac62aaf38de43bb6d6cde7b4d4d/aiohttp-3.13.2-cp314-cp314-win_amd64.whl", hash = "sha256:fe242cd381e0fb65758faf5ad96c2e460df6ee5b2de1072fe97e4127927e00b4", size = 457627, upload-time = "2025-10-28T20:58:11Z" }, + { url = "https://files.pythonhosted.org/packages/c7/8e/3824ef98c039d3951cb65b9205a96dd2b20f22241ee17d89c5701557c826/aiohttp-3.13.2-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:f10d9c0b0188fe85398c61147bbd2a657d616c876863bfeff43376e0e3134673", size = 767360, upload-time = "2025-10-28T20:58:13.358Z" }, + { url = "https://files.pythonhosted.org/packages/a4/0f/6a03e3fc7595421274fa34122c973bde2d89344f8a881b728fa8c774e4f1/aiohttp-3.13.2-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:e7c952aefdf2460f4ae55c5e9c3e80aa72f706a6317e06020f80e96253b1accd", size = 504616, upload-time = "2025-10-28T20:58:15.339Z" }, + { url = "https://files.pythonhosted.org/packages/c6/aa/ed341b670f1bc8a6f2c6a718353d13b9546e2cef3544f573c6a1ff0da711/aiohttp-3.13.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c20423ce14771d98353d2e25e83591fa75dfa90a3c1848f3d7c68243b4fbded3", size = 509131, upload-time = "2025-10-28T20:58:17.693Z" }, + { url = "https://files.pythonhosted.org/packages/7f/f0/c68dac234189dae5c4bbccc0f96ce0cc16b76632cfc3a08fff180045cfa4/aiohttp-3.13.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e96eb1a34396e9430c19d8338d2ec33015e4a87ef2b4449db94c22412e25ccdf", size = 1864168, upload-time = "2025-10-28T20:58:20.113Z" }, + { url = "https://files.pythonhosted.org/packages/8f/65/75a9a76db8364b5d0e52a0c20eabc5d52297385d9af9c35335b924fafdee/aiohttp-3.13.2-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:23fb0783bc1a33640036465019d3bba069942616a6a2353c6907d7fe1ccdaf4e", size = 1719200, upload-time = "2025-10-28T20:58:22.583Z" }, + { url = "https://files.pythonhosted.org/packages/f5/55/8df2ed78d7f41d232f6bd3ff866b6f617026551aa1d07e2f03458f964575/aiohttp-3.13.2-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2e1a9bea6244a1d05a4e57c295d69e159a5c50d8ef16aa390948ee873478d9a5", size = 1843497, upload-time = "2025-10-28T20:58:24.672Z" }, + { url = "https://files.pythonhosted.org/packages/e9/e0/94d7215e405c5a02ccb6a35c7a3a6cfff242f457a00196496935f700cde5/aiohttp-3.13.2-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0a3d54e822688b56e9f6b5816fb3de3a3a64660efac64e4c2dc435230ad23bad", size = 1935703, upload-time = "2025-10-28T20:58:26.758Z" }, + { url = "https://files.pythonhosted.org/packages/0b/78/1eeb63c3f9b2d1015a4c02788fb543141aad0a03ae3f7a7b669b2483f8d4/aiohttp-3.13.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7a653d872afe9f33497215745da7a943d1dc15b728a9c8da1c3ac423af35178e", size = 1792738, upload-time = "2025-10-28T20:58:29.787Z" }, + { url = "https://files.pythonhosted.org/packages/41/75/aaf1eea4c188e51538c04cc568040e3082db263a57086ea74a7d38c39e42/aiohttp-3.13.2-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:56d36e80d2003fa3fc0207fac644216d8532e9504a785ef9a8fd013f84a42c61", size = 1624061, upload-time = "2025-10-28T20:58:32.529Z" }, + { url = "https://files.pythonhosted.org/packages/9b/c2/3b6034de81fbcc43de8aeb209073a2286dfb50b86e927b4efd81cf848197/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:78cd586d8331fb8e241c2dd6b2f4061778cc69e150514b39a9e28dd050475661", size = 1789201, upload-time = "2025-10-28T20:58:34.618Z" }, + { url = "https://files.pythonhosted.org/packages/c9/38/c15dcf6d4d890217dae79d7213988f4e5fe6183d43893a9cf2fe9e84ca8d/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:20b10bbfbff766294fe99987f7bb3b74fdd2f1a2905f2562132641ad434dcf98", size = 1776868, upload-time = "2025-10-28T20:58:38.835Z" }, + { url = "https://files.pythonhosted.org/packages/04/75/f74fd178ac81adf4f283a74847807ade5150e48feda6aef024403716c30c/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:9ec49dff7e2b3c85cdeaa412e9d438f0ecd71676fde61ec57027dd392f00c693", size = 1790660, upload-time = "2025-10-28T20:58:41.507Z" }, + { url = "https://files.pythonhosted.org/packages/e7/80/7368bd0d06b16b3aba358c16b919e9c46cf11587dc572091031b0e9e3ef0/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:94f05348c4406450f9d73d38efb41d669ad6cd90c7ee194810d0eefbfa875a7a", size = 1617548, upload-time = "2025-10-28T20:58:43.674Z" }, + { url = "https://files.pythonhosted.org/packages/7d/4b/a6212790c50483cb3212e507378fbe26b5086d73941e1ec4b56a30439688/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:fa4dcb605c6f82a80c7f95713c2b11c3b8e9893b3ebd2bc9bde93165ed6107be", size = 1817240, upload-time = "2025-10-28T20:58:45.787Z" }, + { url = "https://files.pythonhosted.org/packages/ff/f7/ba5f0ba4ea8d8f3c32850912944532b933acbf0f3a75546b89269b9b7dde/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:cf00e5db968c3f67eccd2778574cf64d8b27d95b237770aa32400bd7a1ca4f6c", size = 1762334, upload-time = "2025-10-28T20:58:47.936Z" }, + { url = "https://files.pythonhosted.org/packages/7e/83/1a5a1856574588b1cad63609ea9ad75b32a8353ac995d830bf5da9357364/aiohttp-3.13.2-cp314-cp314t-win32.whl", hash = "sha256:d23b5fe492b0805a50d3371e8a728a9134d8de5447dce4c885f5587294750734", size = 464685, upload-time = "2025-10-28T20:58:50.642Z" }, + { url = "https://files.pythonhosted.org/packages/9f/4d/d22668674122c08f4d56972297c51a624e64b3ed1efaa40187607a7cb66e/aiohttp-3.13.2-cp314-cp314t-win_amd64.whl", hash = "sha256:ff0a7b0a82a7ab905cbda74006318d1b12e37c797eb1b0d4eb3e316cf47f658f", size = 498093, upload-time = "2025-10-28T20:58:52.782Z" }, +] + +[[package]] +name = "aiomysql" +version = "0.3.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pymysql" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/29/e0/302aeffe8d90853556f47f3106b89c16cc2ec2a4d269bdfd82e3f4ae12cc/aiomysql-0.3.2.tar.gz", hash = "sha256:72d15ef5cfc34c03468eb41e1b90adb9fd9347b0b589114bd23ead569a02ac1a", size = 108311, upload-time = "2025-10-22T00:15:21.278Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4c/af/aae0153c3e28712adaf462328f6c7a3c196a1c1c27b491de4377dd3e6b52/aiomysql-0.3.2-py3-none-any.whl", hash = "sha256:c82c5ba04137d7afd5c693a258bea8ead2aad77101668044143a991e04632eb2", size = 71834, upload-time = "2025-10-22T00:15:15.905Z" }, +] + +[[package]] +name = "aiosignal" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "frozenlist" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/61/62/06741b579156360248d1ec624842ad0edf697050bbaf7c3e46394e106ad1/aiosignal-1.4.0.tar.gz", hash = "sha256:f47eecd9468083c2029cc99945502cb7708b082c232f9aca65da147157b251c7", size = 25007, upload-time = "2025-07-03T22:54:43.528Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl", hash = "sha256:053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e", size = 7490, upload-time = "2025-07-03T22:54:42.156Z" }, +] + +[[package]] +name = "annotated-doc" +version = "0.0.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/57/ba/046ceea27344560984e26a590f90bc7f4a75b06701f653222458922b558c/annotated_doc-0.0.4.tar.gz", hash = "sha256:fbcda96e87e9c92ad167c2e53839e57503ecfda18804ea28102353485033faa4", size = 7288, upload-time = "2025-11-10T22:07:42.062Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl", hash = "sha256:571ac1dc6991c450b25a9c2d84a3705e2ae7a53467b5d111c24fa8baabbed320", size = 5303, upload-time = "2025-11-10T22:07:40.673Z" }, +] + +[[package]] +name = "annotated-types" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, +] + +[[package]] +name = "anyio" +version = "4.12.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "idna" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/16/ce/8a777047513153587e5434fd752e89334ac33e379aa3497db860eeb60377/anyio-4.12.0.tar.gz", hash = "sha256:73c693b567b0c55130c104d0b43a9baf3aa6a31fc6110116509f27bf75e21ec0", size = 228266, upload-time = "2025-11-28T23:37:38.911Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7f/9c/36c5c37947ebfb8c7f22e0eb6e4d188ee2d53aa3880f3f2744fb894f0cb1/anyio-4.12.0-py3-none-any.whl", hash = "sha256:dad2376a628f98eeca4881fc56cd06affd18f659b17a747d3ff0307ced94b1bb", size = 113362, upload-time = "2025-11-28T23:36:57.897Z" }, +] + +[[package]] +name = "asyncmy" +version = "0.2.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b5/76/55cc0577f9e838c5a5213bf33159b9e484c9d9820a2bafd4d6bfa631bf86/asyncmy-0.2.10.tar.gz", hash = "sha256:f4b67edadf7caa56bdaf1c2e6cf451150c0a86f5353744deabe4426fe27aff4e", size = 63889, upload-time = "2024-12-12T14:45:09.2Z" } + +[[package]] +name = "attrs" +version = "25.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6b/5c/685e6633917e101e5dcb62b9dd76946cbb57c26e133bae9e0cd36033c0a9/attrs-25.4.0.tar.gz", hash = "sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11", size = 934251, upload-time = "2025-10-06T13:54:44.725Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl", hash = "sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373", size = 67615, upload-time = "2025-10-06T13:54:43.17Z" }, +] + +[[package]] +name = "certifi" +version = "2025.11.12" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/8c/58f469717fa48465e4a50c014a0400602d3c437d7c0c468e17ada824da3a/certifi-2025.11.12.tar.gz", hash = "sha256:d8ab5478f2ecd78af242878415affce761ca6bc54a22a27e026d7c25357c3316", size = 160538, upload-time = "2025-11-12T02:54:51.517Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/70/7d/9bc192684cea499815ff478dfcdc13835ddf401365057044fb721ec6bddb/certifi-2025.11.12-py3-none-any.whl", hash = "sha256:97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b", size = 159438, upload-time = "2025-11-12T02:54:49.735Z" }, +] + +[[package]] +name = "click" +version = "8.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3d/fa/656b739db8587d7b5dfa22e22ed02566950fbfbcdc20311993483657a5c0/click-8.3.1.tar.gz", hash = "sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a", size = 295065, upload-time = "2025-11-15T20:45:42.706Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl", hash = "sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6", size = 108274, upload-time = "2025-11-15T20:45:41.139Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "distro" +version = "1.9.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/fc/f8/98eea607f65de6527f8a2e8885fc8015d3e6f5775df186e443e0964a11c3/distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed", size = 60722, upload-time = "2023-12-24T09:54:32.31Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/12/b3/231ffd4ab1fc9d679809f356cebee130ac7daa00d6d6f3206dd4fd137e9e/distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2", size = 20277, upload-time = "2023-12-24T09:54:30.421Z" }, +] + +[[package]] +name = "dnspython" +version = "2.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8c/8b/57666417c0f90f08bcafa776861060426765fdb422eb10212086fb811d26/dnspython-2.8.0.tar.gz", hash = "sha256:181d3c6996452cb1189c4046c61599b84a5a86e099562ffde77d26984ff26d0f", size = 368251, upload-time = "2025-09-07T18:58:00.022Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ba/5a/18ad964b0086c6e62e2e7500f7edc89e3faa45033c71c1893d34eed2b2de/dnspython-2.8.0-py3-none-any.whl", hash = "sha256:01d9bbc4a2d76bf0db7c1f729812ded6d912bd318d3b1cf81d30c0f845dbf3af", size = 331094, upload-time = "2025-09-07T18:57:58.071Z" }, +] + +[[package]] +name = "email-validator" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "dnspython" }, + { name = "idna" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f5/22/900cb125c76b7aaa450ce02fd727f452243f2e91a61af068b40adba60ea9/email_validator-2.3.0.tar.gz", hash = "sha256:9fc05c37f2f6cf439ff414f8fc46d917929974a82244c20eb10231ba60c54426", size = 51238, upload-time = "2025-08-26T13:09:06.831Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/de/15/545e2b6cf2e3be84bc1ed85613edd75b8aea69807a71c26f4ca6a9258e82/email_validator-2.3.0-py3-none-any.whl", hash = "sha256:80f13f623413e6b197ae73bb10bf4eb0908faf509ad8362c5edeb0be7fd450b4", size = 35604, upload-time = "2025-08-26T13:09:05.858Z" }, +] + +[[package]] +name = "fastapi" +version = "0.125.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-doc" }, + { name = "pydantic" }, + { name = "starlette" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/17/71/2df15009fb4bdd522a069d2fbca6007c6c5487fce5cb965be00fc335f1d1/fastapi-0.125.0.tar.gz", hash = "sha256:16b532691a33e2c5dee1dac32feb31dc6eb41a3dd4ff29a95f9487cb21c054c0", size = 370550, upload-time = "2025-12-17T21:41:44.15Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/34/2f/ff2fcc98f500713368d8b650e1bbc4a0b3ebcdd3e050dcdaad5f5a13fd7e/fastapi-0.125.0-py3-none-any.whl", hash = "sha256:2570ec4f3aecf5cca8f0428aed2398b774fcdfee6c2116f86e80513f2f86a7a1", size = 112888, upload-time = "2025-12-17T21:41:41.286Z" }, +] + +[package.optional-dependencies] +standard = [ + { name = "email-validator" }, + { name = "fastapi-cli", extra = ["standard"] }, + { name = "httpx" }, + { name = "jinja2" }, + { name = "python-multipart" }, + { name = "uvicorn", extra = ["standard"] }, +] + +[[package]] +name = "fastapi-cli" +version = "0.0.16" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "rich-toolkit" }, + { name = "typer" }, + { name = "uvicorn", extra = ["standard"] }, +] +sdist = { url = "https://files.pythonhosted.org/packages/99/75/9407a6b452be4c988feacec9c9d2f58d8f315162a6c7258d5a649d933ebe/fastapi_cli-0.0.16.tar.gz", hash = "sha256:e8a2a1ecf7a4e062e3b2eec63ae34387d1e142d4849181d936b23c4bdfe29073", size = 19447, upload-time = "2025-11-10T19:01:07.856Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/55/43/678528c19318394320ee43757648d5e0a8070cf391b31f69d931e5c840d2/fastapi_cli-0.0.16-py3-none-any.whl", hash = "sha256:addcb6d130b5b9c91adbbf3f2947fe115991495fdb442fe3e51b5fc6327df9f4", size = 12312, upload-time = "2025-11-10T19:01:06.728Z" }, +] + +[package.optional-dependencies] +standard = [ + { name = "fastapi-cloud-cli" }, + { name = "uvicorn", extra = ["standard"] }, +] + +[[package]] +name = "fastapi-cloud-cli" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "fastar" }, + { name = "httpx" }, + { name = "pydantic", extra = ["email"] }, + { name = "rich-toolkit" }, + { name = "rignore" }, + { name = "sentry-sdk" }, + { name = "typer" }, + { name = "uvicorn", extra = ["standard"] }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cf/0d/3b0d2991f481c122c552b4ae38a8b400a75ab0edbc85536f2a6224f72da2/fastapi_cloud_cli-0.7.0.tar.gz", hash = "sha256:8b025944475c3d53262105886dfe051f46383e4f287787a46892b524922ac0b6", size = 30906, upload-time = "2025-12-16T12:51:49.082Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2d/aa/a2319f008e123b178a5c4cba34935e8459e72d24d8c31214b244ab7266a6/fastapi_cloud_cli-0.7.0-py3-none-any.whl", hash = "sha256:9a152e80d08d465d4a6c4f5c75aa8871d1e8919f69ff131b0567f04e95d5f36c", size = 23376, upload-time = "2025-12-16T12:51:47.847Z" }, +] + +[[package]] +name = "fastar" +version = "0.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/69/e7/f89d54fb04104114dd0552836dc2b47914f416cc0e200b409dd04a33de5e/fastar-0.8.0.tar.gz", hash = "sha256:f4d4d68dbf1c4c2808f0e730fac5843493fc849f70fe3ad3af60dfbaf68b9a12", size = 68524, upload-time = "2025-11-26T02:36:00.72Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/a5/79ecba3646e22d03eef1a66fb7fc156567213e2e4ab9faab3bbd4489e483/fastar-0.8.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:a3253a06845462ca2196024c7a18f5c0ba4de1532ab1c4bad23a40b332a06a6a", size = 706112, upload-time = "2025-11-26T02:34:39.237Z" }, + { url = "https://files.pythonhosted.org/packages/0a/03/4f883bce878218a8676c2d7ca09b50c856a5470bb3b7f63baf9521ea6995/fastar-0.8.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5cbeb3ebfa0980c68ff8b126295cc6b208ccd81b638aebc5a723d810a7a0e5d2", size = 628954, upload-time = "2025-11-26T02:34:23.705Z" }, + { url = "https://files.pythonhosted.org/packages/4f/f1/892e471f156b03d10ba48ace9384f5a896702a54506137462545f38e40b8/fastar-0.8.0-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1c0d5956b917daac77d333d48b3f0f3ff927b8039d5b32d8125462782369f761", size = 868685, upload-time = "2025-11-26T02:33:53.077Z" }, + { url = "https://files.pythonhosted.org/packages/39/ba/e24915045852e30014ec6840446975c03f4234d1c9270394b51d3ad18394/fastar-0.8.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:27b404db2b786b65912927ce7f3790964a4bcbde42cdd13091b82a89cd655e1c", size = 765044, upload-time = "2025-11-26T02:32:48.187Z" }, + { url = "https://files.pythonhosted.org/packages/14/2c/1aa11ac21a99984864c2fca4994e094319ff3a2046e7a0343c39317bd5b9/fastar-0.8.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0902fc89dcf1e7f07b8563032a4159fe2b835e4c16942c76fd63451d0e5f76a3", size = 764322, upload-time = "2025-11-26T02:33:03.859Z" }, + { url = "https://files.pythonhosted.org/packages/ba/f0/4b91902af39fe2d3bae7c85c6d789586b9fbcf618d7fdb3d37323915906d/fastar-0.8.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:069347e2f0f7a8b99bbac8cd1bc0e06c7b4a31dc964fc60d84b95eab3d869dc1", size = 931016, upload-time = "2025-11-26T02:33:19.902Z" }, + { url = "https://files.pythonhosted.org/packages/c9/97/8fc43a5a9c0a2dc195730f6f7a0f367d171282cd8be2511d0e87c6d2dad0/fastar-0.8.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7fd135306f6bfe9a835918280e0eb440b70ab303e0187d90ab51ca86e143f70d", size = 821308, upload-time = "2025-11-26T02:33:34.664Z" }, + { url = "https://files.pythonhosted.org/packages/0c/e9/058615b63a7fd27965e8c5966f393ed0c169f7ff5012e1674f21684de3ba/fastar-0.8.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78d06d6897f43c27154b5f2d0eb930a43a81b7eec73f6f0b0114814d4a10ab38", size = 821171, upload-time = "2025-11-26T02:34:08.498Z" }, + { url = "https://files.pythonhosted.org/packages/ca/cf/69e16a17961570a755c37ffb5b5aa7610d2e77807625f537989da66f2a9d/fastar-0.8.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a922f8439231fa0c32b15e8d70ff6d415619b9d40492029dabbc14a0c53b5f18", size = 986227, upload-time = "2025-11-26T02:34:55.06Z" }, + { url = "https://files.pythonhosted.org/packages/fb/83/2100192372e59b56f4ace37d7d9cabda511afd71b5febad1643d1c334271/fastar-0.8.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:a739abd51eb766384b4caff83050888e80cd75bbcfec61e6d1e64875f94e4a40", size = 1039395, upload-time = "2025-11-26T02:35:12.166Z" }, + { url = "https://files.pythonhosted.org/packages/75/15/cdd03aca972f55872efbb7cf7540c3fa7b97a75d626303a3ea46932163dc/fastar-0.8.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:5a65f419d808b23ac89d5cd1b13a2f340f15bc5d1d9af79f39fdb77bba48ff1b", size = 1044766, upload-time = "2025-11-26T02:35:29.62Z" }, + { url = "https://files.pythonhosted.org/packages/3d/29/945e69e4e2652329ace545999334ec31f1431fbae3abb0105587e11af2ae/fastar-0.8.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7bb2ae6c0cce58f0db1c9f20495e7557cca2c1ee9c69bbd90eafd54f139171c5", size = 994740, upload-time = "2025-11-26T02:35:47.887Z" }, + { url = "https://files.pythonhosted.org/packages/4b/5d/dbfe28f8cd1eb484bba0c62e5259b2cf6fea229d6ef43e05c06b5a78c034/fastar-0.8.0-cp313-cp313-win32.whl", hash = "sha256:b28753e0d18a643272597cb16d39f1053842aa43131ad3e260c03a2417d38401", size = 455990, upload-time = "2025-11-26T02:36:28.502Z" }, + { url = "https://files.pythonhosted.org/packages/e1/01/e965740bd36e60ef4c5aa2cbe42b6c4eb1dc3551009238a97c2e5e96bd23/fastar-0.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:620e5d737dce8321d49a5ebb7997f1fd0047cde3512082c27dc66d6ac8c1927a", size = 490227, upload-time = "2025-11-26T02:36:14.363Z" }, + { url = "https://files.pythonhosted.org/packages/dd/10/c99202719b83e5249f26902ae53a05aea67d840eeb242019322f20fc171c/fastar-0.8.0-cp313-cp313-win_arm64.whl", hash = "sha256:c4c4bd08df563120cd33e854fe0a93b81579e8571b11f9b7da9e84c37da2d6b6", size = 461078, upload-time = "2025-11-26T02:36:04.94Z" }, + { url = "https://files.pythonhosted.org/packages/96/4a/9573b87a0ef07580ed111e7230259aec31bb33ca3667963ebee77022ec61/fastar-0.8.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:50b36ce654ba44b0e13fae607ae17ee6e1597b69f71df1bee64bb8328d881dfc", size = 706041, upload-time = "2025-11-26T02:34:40.638Z" }, + { url = "https://files.pythonhosted.org/packages/4a/19/f95444a1d4f375333af49300aa75ee93afa3335c0e40fda528e460ed859c/fastar-0.8.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:63a892762683d7ab00df0227d5ea9677c62ff2cde9b875e666c0be569ed940f3", size = 628617, upload-time = "2025-11-26T02:34:24.893Z" }, + { url = "https://files.pythonhosted.org/packages/b3/c9/b51481b38b7e3f16ef2b9e233b1a3623386c939d745d6e41bbd389eaae30/fastar-0.8.0-cp314-cp314-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4ae6a145c1bff592644bde13f2115e0239f4b7babaf506d14e7d208483cf01a5", size = 869299, upload-time = "2025-11-26T02:33:54.274Z" }, + { url = "https://files.pythonhosted.org/packages/bf/02/3ba1267ee5ba7314e29c431cf82eaa68586f2c40cdfa08be3632b7d07619/fastar-0.8.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ae0ff7c0a1c7e1428404b81faee8aebef466bfd0be25bfe4dabf5d535c68741", size = 764667, upload-time = "2025-11-26T02:32:49.606Z" }, + { url = "https://files.pythonhosted.org/packages/1b/84/bf33530fd015b5d7c2cc69e0bce4a38d736754a6955487005aab1af6adcd/fastar-0.8.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dbfd87dbd217b45c898b2dbcd0169aae534b2c1c5cbe3119510881f6a5ac8ef5", size = 763993, upload-time = "2025-11-26T02:33:05.782Z" }, + { url = "https://files.pythonhosted.org/packages/da/e0/9564d24e7cea6321a8d921c6d2a457044a476ef197aa4708e179d3d97f0d/fastar-0.8.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9a5abd99fcba83ef28c8fe6ae2927edc79053db43a0457a962ed85c9bf150d37", size = 930153, upload-time = "2025-11-26T02:33:21.53Z" }, + { url = "https://files.pythonhosted.org/packages/35/b1/6f57fcd8d6e192cfebf97e58eb27751640ad93784c857b79039e84387b51/fastar-0.8.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:91d4c685620c3a9d6b5ae091dbabab4f98b20049b7ecc7976e19cc9016c0d5d6", size = 821177, upload-time = "2025-11-26T02:33:35.839Z" }, + { url = "https://files.pythonhosted.org/packages/b3/78/9e004ea9f3aa7466f5ddb6f9518780e1d2f0ed3ca55f093632982598bace/fastar-0.8.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f77c2f2cad76e9dc7b6701297adb1eba87d0485944b416fc2ccf5516c01219a3", size = 820652, upload-time = "2025-11-26T02:34:09.776Z" }, + { url = "https://files.pythonhosted.org/packages/42/95/b604ed536544005c9f1aee7c4c74b00150db3d8d535cd8232dc20f947063/fastar-0.8.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e7f07c4a3dada7757a8fc430a5b4a29e6ef696d2212747213f57086ffd970316", size = 985961, upload-time = "2025-11-26T02:34:56.401Z" }, + { url = "https://files.pythonhosted.org/packages/f2/7b/fa9d4d96a5d494bdb8699363bb9de8178c0c21a02e1d89cd6f913d127018/fastar-0.8.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:90c0c3fe55105c0aed8a83135dbdeb31e683455dbd326a1c48fa44c378b85616", size = 1039316, upload-time = "2025-11-26T02:35:13.807Z" }, + { url = "https://files.pythonhosted.org/packages/4e/f9/8462789243bc3f33e8401378ec6d54de4e20cfa60c96a0e15e3e9d1389bb/fastar-0.8.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:fb9ee51e5bffe0dab3d3126d3a4fac8d8f7235cedcb4b8e74936087ce1c157f3", size = 1045028, upload-time = "2025-11-26T02:35:31.079Z" }, + { url = "https://files.pythonhosted.org/packages/a5/71/9abb128777e616127194b509e98fcda3db797d76288c1a8c23dd22afc14f/fastar-0.8.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e380b1e8d30317f52406c43b11e98d11e1d68723bbd031e18049ea3497b59a6d", size = 994677, upload-time = "2025-11-26T02:35:49.391Z" }, + { url = "https://files.pythonhosted.org/packages/de/c1/b81b3f194853d7ad232a67a1d768f5f51a016f165cfb56cb31b31bbc6177/fastar-0.8.0-cp314-cp314-win32.whl", hash = "sha256:1c4ffc06e9c4a8ca498c07e094670d8d8c0d25b17ca6465b9774da44ea997ab1", size = 456687, upload-time = "2025-11-26T02:36:30.205Z" }, + { url = "https://files.pythonhosted.org/packages/cb/87/9e0cd4768a98181d56f0cdbab2363404cc15deb93f4aad3b99cd2761bbaa/fastar-0.8.0-cp314-cp314-win_amd64.whl", hash = "sha256:5517a8ad4726267c57a3e0e2a44430b782e00b230bf51c55b5728e758bb3a692", size = 490578, upload-time = "2025-11-26T02:36:16.218Z" }, + { url = "https://files.pythonhosted.org/packages/aa/1e/580a76cf91847654f2ad6520e956e93218f778540975bc4190d363f709e2/fastar-0.8.0-cp314-cp314-win_arm64.whl", hash = "sha256:58030551046ff4a8616931e52a36c83545ff05996db5beb6e0cd2b7e748aa309", size = 461473, upload-time = "2025-11-26T02:36:06.373Z" }, + { url = "https://files.pythonhosted.org/packages/58/4c/bdb5c6efe934f68708529c8c9d4055ebef5c4be370621966438f658b29bd/fastar-0.8.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:1e7d29b6bfecb29db126a08baf3c04a5ab667f6cea2b7067d3e623a67729c4a6", size = 705570, upload-time = "2025-11-26T02:34:42.01Z" }, + { url = "https://files.pythonhosted.org/packages/6d/78/f01ac7e71d5a37621bd13598a26e948a12b85ca8042f7ee1a0a8c9f59cda/fastar-0.8.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:05eb7b96940f9526b485f1d0b02393839f0f61cac4b1f60024984f8b326d2640", size = 627761, upload-time = "2025-11-26T02:34:26.152Z" }, + { url = "https://files.pythonhosted.org/packages/06/45/6df0ecda86ea9d2e95053c1a655d153dee55fc121b6e13ea6d1e246a50b6/fastar-0.8.0-cp314-cp314t-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:619352d8ac011794e2345c462189dc02ba634750d23cd9d86a9267dd71b1f278", size = 869414, upload-time = "2025-11-26T02:33:55.618Z" }, + { url = "https://files.pythonhosted.org/packages/b2/72/486421f5a8c0c377cc82e7a50c8a8ea899a6ec2aa72bde8f09fb667a2dc8/fastar-0.8.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74ebfecef3fe6d7a90355fac1402fd30636988332a1d33f3e80019a10782bb24", size = 763863, upload-time = "2025-11-26T02:32:51.051Z" }, + { url = "https://files.pythonhosted.org/packages/d4/64/39f654dbb41a3867fb1f2c8081c014d8f1d32ea10585d84cacbef0b32995/fastar-0.8.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2975aca5a639e26a3ab0d23b4b0628d6dd6d521146c3c11486d782be621a35aa", size = 763065, upload-time = "2025-11-26T02:33:07.274Z" }, + { url = "https://files.pythonhosted.org/packages/4e/bd/c011a34fb3534c4c3301f7c87c4ffd7e47f6113c904c092ddc8a59a303ea/fastar-0.8.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:afc438eaed8ff0dcdd9308268be5cb38c1db7e94c3ccca7c498ca13a4a4535a3", size = 930530, upload-time = "2025-11-26T02:33:23.117Z" }, + { url = "https://files.pythonhosted.org/packages/55/9d/aa6e887a7033c571b1064429222bbe09adc9a3c1e04f3d1788ba5838ebd5/fastar-0.8.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6ced0a5399cc0a84a858ef0a31ca2d0c24d3bbec4bcda506a9192d8119f3590a", size = 820572, upload-time = "2025-11-26T02:33:37.542Z" }, + { url = "https://files.pythonhosted.org/packages/ad/9c/7a3a2278a1052e1a5d98646de7c095a00cffd2492b3b84ce730e2f1cd93a/fastar-0.8.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec9b23da8c4c039da3fe2e358973c66976a0c8508aa06d6626b4403cb5666c19", size = 820649, upload-time = "2025-11-26T02:34:11.108Z" }, + { url = "https://files.pythonhosted.org/packages/02/9e/d38edc1f4438cd047e56137c26d94783ffade42e1b3bde620ccf17b771ef/fastar-0.8.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:dfba078fcd53478032fd0ceed56960ec6b7ff0511cfc013a8a3a4307e3a7bac4", size = 985653, upload-time = "2025-11-26T02:34:57.884Z" }, + { url = "https://files.pythonhosted.org/packages/69/d9/2147d0c19757e165cd62d41cec3f7b38fad2ad68ab784978b5f81716c7ea/fastar-0.8.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:ade56c94c14be356d295fecb47a3fcd473dd43a8803ead2e2b5b9e58feb6dcfa", size = 1038140, upload-time = "2025-11-26T02:35:15.778Z" }, + { url = "https://files.pythonhosted.org/packages/7f/1d/ec4c717ffb8a308871e9602ec3197d957e238dc0227127ac573ec9bca952/fastar-0.8.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:e48d938f9366db5e59441728f70b7f6c1ccfab7eff84f96f9b7e689b07786c52", size = 1045195, upload-time = "2025-11-26T02:35:32.865Z" }, + { url = "https://files.pythonhosted.org/packages/6a/9f/637334dc8c8f3bb391388b064ae13f0ad9402bc5a6c3e77b8887d0c31921/fastar-0.8.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:79c441dc1482ff51a54fb3f57ae6f7bb3d2cff88fa2cc5d196c519f8aab64a56", size = 994686, upload-time = "2025-11-26T02:35:51.392Z" }, + { url = "https://files.pythonhosted.org/packages/c9/e2/dfa19a4b260b8ab3581b7484dcb80c09b25324f4daa6b6ae1c7640d1607a/fastar-0.8.0-cp314-cp314t-win32.whl", hash = "sha256:187f61dc739afe45ac8e47ed7fd1adc45d52eac110cf27d579155720507d6fbe", size = 455767, upload-time = "2025-11-26T02:36:34.758Z" }, + { url = "https://files.pythonhosted.org/packages/51/47/df65c72afc1297797b255f90c4778b5d6f1f0f80282a134d5ab610310ed9/fastar-0.8.0-cp314-cp314t-win_amd64.whl", hash = "sha256:40e9d763cf8bf85ce2fa256e010aa795c0fe3d3bd1326d5c3084e6ce7857127e", size = 489971, upload-time = "2025-11-26T02:36:22.081Z" }, + { url = "https://files.pythonhosted.org/packages/85/11/0aa8455af26f0ae89e42be67f3a874255ee5d7f0f026fc86e8d56f76b428/fastar-0.8.0-cp314-cp314t-win_arm64.whl", hash = "sha256:e59673307b6a08210987059a2bdea2614fe26e3335d0e5d1a3d95f49a05b1418", size = 460467, upload-time = "2025-11-26T02:36:07.978Z" }, +] + +[[package]] +name = "frozenlist" +version = "1.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2d/f5/c831fac6cc817d26fd54c7eaccd04ef7e0288806943f7cc5bbf69f3ac1f0/frozenlist-1.8.0.tar.gz", hash = "sha256:3ede829ed8d842f6cd48fc7081d7a41001a56f1f38603f9d49bf3020d59a31ad", size = 45875, upload-time = "2025-10-06T05:38:17.865Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2d/40/0832c31a37d60f60ed79e9dfb5a92e1e2af4f40a16a29abcc7992af9edff/frozenlist-1.8.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8d92f1a84bb12d9e56f818b3a746f3efba93c1b63c8387a73dde655e1e42282a", size = 85717, upload-time = "2025-10-06T05:36:27.341Z" }, + { url = "https://files.pythonhosted.org/packages/30/ba/b0b3de23f40bc55a7057bd38434e25c34fa48e17f20ee273bbde5e0650f3/frozenlist-1.8.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:96153e77a591c8adc2ee805756c61f59fef4cf4073a9275ee86fe8cba41241f7", size = 49651, upload-time = "2025-10-06T05:36:28.855Z" }, + { url = "https://files.pythonhosted.org/packages/0c/ab/6e5080ee374f875296c4243c381bbdef97a9ac39c6e3ce1d5f7d42cb78d6/frozenlist-1.8.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f21f00a91358803399890ab167098c131ec2ddd5f8f5fd5fe9c9f2c6fcd91e40", size = 49417, upload-time = "2025-10-06T05:36:29.877Z" }, + { url = "https://files.pythonhosted.org/packages/d5/4e/e4691508f9477ce67da2015d8c00acd751e6287739123113a9fca6f1604e/frozenlist-1.8.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fb30f9626572a76dfe4293c7194a09fb1fe93ba94c7d4f720dfae3b646b45027", size = 234391, upload-time = "2025-10-06T05:36:31.301Z" }, + { url = "https://files.pythonhosted.org/packages/40/76/c202df58e3acdf12969a7895fd6f3bc016c642e6726aa63bd3025e0fc71c/frozenlist-1.8.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eaa352d7047a31d87dafcacbabe89df0aa506abb5b1b85a2fb91bc3faa02d822", size = 233048, upload-time = "2025-10-06T05:36:32.531Z" }, + { url = "https://files.pythonhosted.org/packages/f9/c0/8746afb90f17b73ca5979c7a3958116e105ff796e718575175319b5bb4ce/frozenlist-1.8.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:03ae967b4e297f58f8c774c7eabcce57fe3c2434817d4385c50661845a058121", size = 226549, upload-time = "2025-10-06T05:36:33.706Z" }, + { url = "https://files.pythonhosted.org/packages/7e/eb/4c7eefc718ff72f9b6c4893291abaae5fbc0c82226a32dcd8ef4f7a5dbef/frozenlist-1.8.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f6292f1de555ffcc675941d65fffffb0a5bcd992905015f85d0592201793e0e5", size = 239833, upload-time = "2025-10-06T05:36:34.947Z" }, + { url = "https://files.pythonhosted.org/packages/c2/4e/e5c02187cf704224f8b21bee886f3d713ca379535f16893233b9d672ea71/frozenlist-1.8.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:29548f9b5b5e3460ce7378144c3010363d8035cea44bc0bf02d57f5a685e084e", size = 245363, upload-time = "2025-10-06T05:36:36.534Z" }, + { url = "https://files.pythonhosted.org/packages/1f/96/cb85ec608464472e82ad37a17f844889c36100eed57bea094518bf270692/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ec3cc8c5d4084591b4237c0a272cc4f50a5b03396a47d9caaf76f5d7b38a4f11", size = 229314, upload-time = "2025-10-06T05:36:38.582Z" }, + { url = "https://files.pythonhosted.org/packages/5d/6f/4ae69c550e4cee66b57887daeebe006fe985917c01d0fff9caab9883f6d0/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:517279f58009d0b1f2e7c1b130b377a349405da3f7621ed6bfae50b10adf20c1", size = 243365, upload-time = "2025-10-06T05:36:40.152Z" }, + { url = "https://files.pythonhosted.org/packages/7a/58/afd56de246cf11780a40a2c28dc7cbabbf06337cc8ddb1c780a2d97e88d8/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:db1e72ede2d0d7ccb213f218df6a078a9c09a7de257c2fe8fcef16d5925230b1", size = 237763, upload-time = "2025-10-06T05:36:41.355Z" }, + { url = "https://files.pythonhosted.org/packages/cb/36/cdfaf6ed42e2644740d4a10452d8e97fa1c062e2a8006e4b09f1b5fd7d63/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b4dec9482a65c54a5044486847b8a66bf10c9cb4926d42927ec4e8fd5db7fed8", size = 240110, upload-time = "2025-10-06T05:36:42.716Z" }, + { url = "https://files.pythonhosted.org/packages/03/a8/9ea226fbefad669f11b52e864c55f0bd57d3c8d7eb07e9f2e9a0b39502e1/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:21900c48ae04d13d416f0e1e0c4d81f7931f73a9dfa0b7a8746fb2fe7dd970ed", size = 233717, upload-time = "2025-10-06T05:36:44.251Z" }, + { url = "https://files.pythonhosted.org/packages/1e/0b/1b5531611e83ba7d13ccc9988967ea1b51186af64c42b7a7af465dcc9568/frozenlist-1.8.0-cp313-cp313-win32.whl", hash = "sha256:8b7b94a067d1c504ee0b16def57ad5738701e4ba10cec90529f13fa03c833496", size = 39628, upload-time = "2025-10-06T05:36:45.423Z" }, + { url = "https://files.pythonhosted.org/packages/d8/cf/174c91dbc9cc49bc7b7aab74d8b734e974d1faa8f191c74af9b7e80848e6/frozenlist-1.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:878be833caa6a3821caf85eb39c5ba92d28e85df26d57afb06b35b2efd937231", size = 43882, upload-time = "2025-10-06T05:36:46.796Z" }, + { url = "https://files.pythonhosted.org/packages/c1/17/502cd212cbfa96eb1388614fe39a3fc9ab87dbbe042b66f97acb57474834/frozenlist-1.8.0-cp313-cp313-win_arm64.whl", hash = "sha256:44389d135b3ff43ba8cc89ff7f51f5a0bb6b63d829c8300f79a2fe4fe61bcc62", size = 39676, upload-time = "2025-10-06T05:36:47.8Z" }, + { url = "https://files.pythonhosted.org/packages/d2/5c/3bbfaa920dfab09e76946a5d2833a7cbdf7b9b4a91c714666ac4855b88b4/frozenlist-1.8.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:e25ac20a2ef37e91c1b39938b591457666a0fa835c7783c3a8f33ea42870db94", size = 89235, upload-time = "2025-10-06T05:36:48.78Z" }, + { url = "https://files.pythonhosted.org/packages/d2/d6/f03961ef72166cec1687e84e8925838442b615bd0b8854b54923ce5b7b8a/frozenlist-1.8.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:07cdca25a91a4386d2e76ad992916a85038a9b97561bf7a3fd12d5d9ce31870c", size = 50742, upload-time = "2025-10-06T05:36:49.837Z" }, + { url = "https://files.pythonhosted.org/packages/1e/bb/a6d12b7ba4c3337667d0e421f7181c82dda448ce4e7ad7ecd249a16fa806/frozenlist-1.8.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4e0c11f2cc6717e0a741f84a527c52616140741cd812a50422f83dc31749fb52", size = 51725, upload-time = "2025-10-06T05:36:50.851Z" }, + { url = "https://files.pythonhosted.org/packages/bc/71/d1fed0ffe2c2ccd70b43714c6cab0f4188f09f8a67a7914a6b46ee30f274/frozenlist-1.8.0-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b3210649ee28062ea6099cfda39e147fa1bc039583c8ee4481cb7811e2448c51", size = 284533, upload-time = "2025-10-06T05:36:51.898Z" }, + { url = "https://files.pythonhosted.org/packages/c9/1f/fb1685a7b009d89f9bf78a42d94461bc06581f6e718c39344754a5d9bada/frozenlist-1.8.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:581ef5194c48035a7de2aefc72ac6539823bb71508189e5de01d60c9dcd5fa65", size = 292506, upload-time = "2025-10-06T05:36:53.101Z" }, + { url = "https://files.pythonhosted.org/packages/e6/3b/b991fe1612703f7e0d05c0cf734c1b77aaf7c7d321df4572e8d36e7048c8/frozenlist-1.8.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3ef2d026f16a2b1866e1d86fc4e1291e1ed8a387b2c333809419a2f8b3a77b82", size = 274161, upload-time = "2025-10-06T05:36:54.309Z" }, + { url = "https://files.pythonhosted.org/packages/ca/ec/c5c618767bcdf66e88945ec0157d7f6c4a1322f1473392319b7a2501ded7/frozenlist-1.8.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5500ef82073f599ac84d888e3a8c1f77ac831183244bfd7f11eaa0289fb30714", size = 294676, upload-time = "2025-10-06T05:36:55.566Z" }, + { url = "https://files.pythonhosted.org/packages/7c/ce/3934758637d8f8a88d11f0585d6495ef54b2044ed6ec84492a91fa3b27aa/frozenlist-1.8.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:50066c3997d0091c411a66e710f4e11752251e6d2d73d70d8d5d4c76442a199d", size = 300638, upload-time = "2025-10-06T05:36:56.758Z" }, + { url = "https://files.pythonhosted.org/packages/fc/4f/a7e4d0d467298f42de4b41cbc7ddaf19d3cfeabaf9ff97c20c6c7ee409f9/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:5c1c8e78426e59b3f8005e9b19f6ff46e5845895adbde20ece9218319eca6506", size = 283067, upload-time = "2025-10-06T05:36:57.965Z" }, + { url = "https://files.pythonhosted.org/packages/dc/48/c7b163063d55a83772b268e6d1affb960771b0e203b632cfe09522d67ea5/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:eefdba20de0d938cec6a89bd4d70f346a03108a19b9df4248d3cf0d88f1b0f51", size = 292101, upload-time = "2025-10-06T05:36:59.237Z" }, + { url = "https://files.pythonhosted.org/packages/9f/d0/2366d3c4ecdc2fd391e0afa6e11500bfba0ea772764d631bbf82f0136c9d/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:cf253e0e1c3ceb4aaff6df637ce033ff6535fb8c70a764a8f46aafd3d6ab798e", size = 289901, upload-time = "2025-10-06T05:37:00.811Z" }, + { url = "https://files.pythonhosted.org/packages/b8/94/daff920e82c1b70e3618a2ac39fbc01ae3e2ff6124e80739ce5d71c9b920/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:032efa2674356903cd0261c4317a561a6850f3ac864a63fc1583147fb05a79b0", size = 289395, upload-time = "2025-10-06T05:37:02.115Z" }, + { url = "https://files.pythonhosted.org/packages/e3/20/bba307ab4235a09fdcd3cc5508dbabd17c4634a1af4b96e0f69bfe551ebd/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6da155091429aeba16851ecb10a9104a108bcd32f6c1642867eadaee401c1c41", size = 283659, upload-time = "2025-10-06T05:37:03.711Z" }, + { url = "https://files.pythonhosted.org/packages/fd/00/04ca1c3a7a124b6de4f8a9a17cc2fcad138b4608e7a3fc5877804b8715d7/frozenlist-1.8.0-cp313-cp313t-win32.whl", hash = "sha256:0f96534f8bfebc1a394209427d0f8a63d343c9779cda6fc25e8e121b5fd8555b", size = 43492, upload-time = "2025-10-06T05:37:04.915Z" }, + { url = "https://files.pythonhosted.org/packages/59/5e/c69f733a86a94ab10f68e496dc6b7e8bc078ebb415281d5698313e3af3a1/frozenlist-1.8.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5d63a068f978fc69421fb0e6eb91a9603187527c86b7cd3f534a5b77a592b888", size = 48034, upload-time = "2025-10-06T05:37:06.343Z" }, + { url = "https://files.pythonhosted.org/packages/16/6c/be9d79775d8abe79b05fa6d23da99ad6e7763a1d080fbae7290b286093fd/frozenlist-1.8.0-cp313-cp313t-win_arm64.whl", hash = "sha256:bf0a7e10b077bf5fb9380ad3ae8ce20ef919a6ad93b4552896419ac7e1d8e042", size = 41749, upload-time = "2025-10-06T05:37:07.431Z" }, + { url = "https://files.pythonhosted.org/packages/f1/c8/85da824b7e7b9b6e7f7705b2ecaf9591ba6f79c1177f324c2735e41d36a2/frozenlist-1.8.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:cee686f1f4cadeb2136007ddedd0aaf928ab95216e7691c63e50a8ec066336d0", size = 86127, upload-time = "2025-10-06T05:37:08.438Z" }, + { url = "https://files.pythonhosted.org/packages/8e/e8/a1185e236ec66c20afd72399522f142c3724c785789255202d27ae992818/frozenlist-1.8.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:119fb2a1bd47307e899c2fac7f28e85b9a543864df47aa7ec9d3c1b4545f096f", size = 49698, upload-time = "2025-10-06T05:37:09.48Z" }, + { url = "https://files.pythonhosted.org/packages/a1/93/72b1736d68f03fda5fdf0f2180fb6caaae3894f1b854d006ac61ecc727ee/frozenlist-1.8.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4970ece02dbc8c3a92fcc5228e36a3e933a01a999f7094ff7c23fbd2beeaa67c", size = 49749, upload-time = "2025-10-06T05:37:10.569Z" }, + { url = "https://files.pythonhosted.org/packages/a7/b2/fabede9fafd976b991e9f1b9c8c873ed86f202889b864756f240ce6dd855/frozenlist-1.8.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:cba69cb73723c3f329622e34bdbf5ce1f80c21c290ff04256cff1cd3c2036ed2", size = 231298, upload-time = "2025-10-06T05:37:11.993Z" }, + { url = "https://files.pythonhosted.org/packages/3a/3b/d9b1e0b0eed36e70477ffb8360c49c85c8ca8ef9700a4e6711f39a6e8b45/frozenlist-1.8.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:778a11b15673f6f1df23d9586f83c4846c471a8af693a22e066508b77d201ec8", size = 232015, upload-time = "2025-10-06T05:37:13.194Z" }, + { url = "https://files.pythonhosted.org/packages/dc/94/be719d2766c1138148564a3960fc2c06eb688da592bdc25adcf856101be7/frozenlist-1.8.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0325024fe97f94c41c08872db482cf8ac4800d80e79222c6b0b7b162d5b13686", size = 225038, upload-time = "2025-10-06T05:37:14.577Z" }, + { url = "https://files.pythonhosted.org/packages/e4/09/6712b6c5465f083f52f50cf74167b92d4ea2f50e46a9eea0523d658454ae/frozenlist-1.8.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:97260ff46b207a82a7567b581ab4190bd4dfa09f4db8a8b49d1a958f6aa4940e", size = 240130, upload-time = "2025-10-06T05:37:15.781Z" }, + { url = "https://files.pythonhosted.org/packages/f8/d4/cd065cdcf21550b54f3ce6a22e143ac9e4836ca42a0de1022da8498eac89/frozenlist-1.8.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:54b2077180eb7f83dd52c40b2750d0a9f175e06a42e3213ce047219de902717a", size = 242845, upload-time = "2025-10-06T05:37:17.037Z" }, + { url = "https://files.pythonhosted.org/packages/62/c3/f57a5c8c70cd1ead3d5d5f776f89d33110b1addae0ab010ad774d9a44fb9/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2f05983daecab868a31e1da44462873306d3cbfd76d1f0b5b69c473d21dbb128", size = 229131, upload-time = "2025-10-06T05:37:18.221Z" }, + { url = "https://files.pythonhosted.org/packages/6c/52/232476fe9cb64f0742f3fde2b7d26c1dac18b6d62071c74d4ded55e0ef94/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:33f48f51a446114bc5d251fb2954ab0164d5be02ad3382abcbfe07e2531d650f", size = 240542, upload-time = "2025-10-06T05:37:19.771Z" }, + { url = "https://files.pythonhosted.org/packages/5f/85/07bf3f5d0fb5414aee5f47d33c6f5c77bfe49aac680bfece33d4fdf6a246/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:154e55ec0655291b5dd1b8731c637ecdb50975a2ae70c606d100750a540082f7", size = 237308, upload-time = "2025-10-06T05:37:20.969Z" }, + { url = "https://files.pythonhosted.org/packages/11/99/ae3a33d5befd41ac0ca2cc7fd3aa707c9c324de2e89db0e0f45db9a64c26/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:4314debad13beb564b708b4a496020e5306c7333fa9a3ab90374169a20ffab30", size = 238210, upload-time = "2025-10-06T05:37:22.252Z" }, + { url = "https://files.pythonhosted.org/packages/b2/60/b1d2da22f4970e7a155f0adde9b1435712ece01b3cd45ba63702aea33938/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:073f8bf8becba60aa931eb3bc420b217bb7d5b8f4750e6f8b3be7f3da85d38b7", size = 231972, upload-time = "2025-10-06T05:37:23.5Z" }, + { url = "https://files.pythonhosted.org/packages/3f/ab/945b2f32de889993b9c9133216c068b7fcf257d8595a0ac420ac8677cab0/frozenlist-1.8.0-cp314-cp314-win32.whl", hash = "sha256:bac9c42ba2ac65ddc115d930c78d24ab8d4f465fd3fc473cdedfccadb9429806", size = 40536, upload-time = "2025-10-06T05:37:25.581Z" }, + { url = "https://files.pythonhosted.org/packages/59/ad/9caa9b9c836d9ad6f067157a531ac48b7d36499f5036d4141ce78c230b1b/frozenlist-1.8.0-cp314-cp314-win_amd64.whl", hash = "sha256:3e0761f4d1a44f1d1a47996511752cf3dcec5bbdd9cc2b4fe595caf97754b7a0", size = 44330, upload-time = "2025-10-06T05:37:26.928Z" }, + { url = "https://files.pythonhosted.org/packages/82/13/e6950121764f2676f43534c555249f57030150260aee9dcf7d64efda11dd/frozenlist-1.8.0-cp314-cp314-win_arm64.whl", hash = "sha256:d1eaff1d00c7751b7c6662e9c5ba6eb2c17a2306ba5e2a37f24ddf3cc953402b", size = 40627, upload-time = "2025-10-06T05:37:28.075Z" }, + { url = "https://files.pythonhosted.org/packages/c0/c7/43200656ecc4e02d3f8bc248df68256cd9572b3f0017f0a0c4e93440ae23/frozenlist-1.8.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:d3bb933317c52d7ea5004a1c442eef86f426886fba134ef8cf4226ea6ee1821d", size = 89238, upload-time = "2025-10-06T05:37:29.373Z" }, + { url = "https://files.pythonhosted.org/packages/d1/29/55c5f0689b9c0fb765055629f472c0de484dcaf0acee2f7707266ae3583c/frozenlist-1.8.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:8009897cdef112072f93a0efdce29cd819e717fd2f649ee3016efd3cd885a7ed", size = 50738, upload-time = "2025-10-06T05:37:30.792Z" }, + { url = "https://files.pythonhosted.org/packages/ba/7d/b7282a445956506fa11da8c2db7d276adcbf2b17d8bb8407a47685263f90/frozenlist-1.8.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2c5dcbbc55383e5883246d11fd179782a9d07a986c40f49abe89ddf865913930", size = 51739, upload-time = "2025-10-06T05:37:32.127Z" }, + { url = "https://files.pythonhosted.org/packages/62/1c/3d8622e60d0b767a5510d1d3cf21065b9db874696a51ea6d7a43180a259c/frozenlist-1.8.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:39ecbc32f1390387d2aa4f5a995e465e9e2f79ba3adcac92d68e3e0afae6657c", size = 284186, upload-time = "2025-10-06T05:37:33.21Z" }, + { url = "https://files.pythonhosted.org/packages/2d/14/aa36d5f85a89679a85a1d44cd7a6657e0b1c75f61e7cad987b203d2daca8/frozenlist-1.8.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92db2bf818d5cc8d9c1f1fc56b897662e24ea5adb36ad1f1d82875bd64e03c24", size = 292196, upload-time = "2025-10-06T05:37:36.107Z" }, + { url = "https://files.pythonhosted.org/packages/05/23/6bde59eb55abd407d34f77d39a5126fb7b4f109a3f611d3929f14b700c66/frozenlist-1.8.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2dc43a022e555de94c3b68a4ef0b11c4f747d12c024a520c7101709a2144fb37", size = 273830, upload-time = "2025-10-06T05:37:37.663Z" }, + { url = "https://files.pythonhosted.org/packages/d2/3f/22cff331bfad7a8afa616289000ba793347fcd7bc275f3b28ecea2a27909/frozenlist-1.8.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cb89a7f2de3602cfed448095bab3f178399646ab7c61454315089787df07733a", size = 294289, upload-time = "2025-10-06T05:37:39.261Z" }, + { url = "https://files.pythonhosted.org/packages/a4/89/5b057c799de4838b6c69aa82b79705f2027615e01be996d2486a69ca99c4/frozenlist-1.8.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:33139dc858c580ea50e7e60a1b0ea003efa1fd42e6ec7fdbad78fff65fad2fd2", size = 300318, upload-time = "2025-10-06T05:37:43.213Z" }, + { url = "https://files.pythonhosted.org/packages/30/de/2c22ab3eb2a8af6d69dc799e48455813bab3690c760de58e1bf43b36da3e/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:168c0969a329b416119507ba30b9ea13688fafffac1b7822802537569a1cb0ef", size = 282814, upload-time = "2025-10-06T05:37:45.337Z" }, + { url = "https://files.pythonhosted.org/packages/59/f7/970141a6a8dbd7f556d94977858cfb36fa9b66e0892c6dd780d2219d8cd8/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:28bd570e8e189d7f7b001966435f9dac6718324b5be2990ac496cf1ea9ddb7fe", size = 291762, upload-time = "2025-10-06T05:37:46.657Z" }, + { url = "https://files.pythonhosted.org/packages/c1/15/ca1adae83a719f82df9116d66f5bb28bb95557b3951903d39135620ef157/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:b2a095d45c5d46e5e79ba1e5b9cb787f541a8dee0433836cea4b96a2c439dcd8", size = 289470, upload-time = "2025-10-06T05:37:47.946Z" }, + { url = "https://files.pythonhosted.org/packages/ac/83/dca6dc53bf657d371fbc88ddeb21b79891e747189c5de990b9dfff2ccba1/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:eab8145831a0d56ec9c4139b6c3e594c7a83c2c8be25d5bcf2d86136a532287a", size = 289042, upload-time = "2025-10-06T05:37:49.499Z" }, + { url = "https://files.pythonhosted.org/packages/96/52/abddd34ca99be142f354398700536c5bd315880ed0a213812bc491cff5e4/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:974b28cf63cc99dfb2188d8d222bc6843656188164848c4f679e63dae4b0708e", size = 283148, upload-time = "2025-10-06T05:37:50.745Z" }, + { url = "https://files.pythonhosted.org/packages/af/d3/76bd4ed4317e7119c2b7f57c3f6934aba26d277acc6309f873341640e21f/frozenlist-1.8.0-cp314-cp314t-win32.whl", hash = "sha256:342c97bf697ac5480c0a7ec73cd700ecfa5a8a40ac923bd035484616efecc2df", size = 44676, upload-time = "2025-10-06T05:37:52.222Z" }, + { url = "https://files.pythonhosted.org/packages/89/76/c615883b7b521ead2944bb3480398cbb07e12b7b4e4d073d3752eb721558/frozenlist-1.8.0-cp314-cp314t-win_amd64.whl", hash = "sha256:06be8f67f39c8b1dc671f5d83aaefd3358ae5cdcf8314552c57e7ed3e6475bdd", size = 49451, upload-time = "2025-10-06T05:37:53.425Z" }, + { url = "https://files.pythonhosted.org/packages/e0/a3/5982da14e113d07b325230f95060e2169f5311b1017ea8af2a29b374c289/frozenlist-1.8.0-cp314-cp314t-win_arm64.whl", hash = "sha256:102e6314ca4da683dca92e3b1355490fed5f313b768500084fbe6371fddfdb79", size = 42507, upload-time = "2025-10-06T05:37:54.513Z" }, + { url = "https://files.pythonhosted.org/packages/9a/9a/e35b4a917281c0b8419d4207f4334c8e8c5dbf4f3f5f9ada73958d937dcc/frozenlist-1.8.0-py3-none-any.whl", hash = "sha256:0c18a16eab41e82c295618a77502e17b195883241c563b00f0aa5106fc4eaa0d", size = 13409, upload-time = "2025-10-06T05:38:16.721Z" }, +] + +[[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, upload-time = "2025-12-04T14:49:44.05Z" } +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, upload-time = "2025-12-04T14:23:01.282Z" }, + { 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, upload-time = "2025-12-04T14:50:08.309Z" }, + { 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, upload-time = "2025-12-04T14:57:43.968Z" }, + { 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, upload-time = "2025-12-04T15:07:14.697Z" }, + { 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, upload-time = "2025-12-04T14:26:03.669Z" }, + { 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, upload-time = "2025-12-04T15:04:25.276Z" }, + { 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, upload-time = "2025-12-04T14:27:30.804Z" }, + { url = "https://files.pythonhosted.org/packages/7e/71/ba21c3fb8c5dce83b8c01f458a42e99ffdb1963aeec08fff5a18588d8fd7/greenlet-3.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:9ee1942ea19550094033c35d25d20726e4f1c40d59545815e1128ac58d416d38", size = 301833, upload-time = "2025-12-04T14:32:23.929Z" }, + { 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, upload-time = "2025-12-04T14:23:05.267Z" }, + { 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, upload-time = "2025-12-04T14:50:10.026Z" }, + { 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, upload-time = "2025-12-04T14:57:45.41Z" }, + { 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, upload-time = "2025-12-04T15:07:15.789Z" }, + { 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, upload-time = "2025-12-04T14:26:05.099Z" }, + { 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, upload-time = "2025-12-04T15:04:27.041Z" }, + { 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, upload-time = "2025-12-04T14:27:32.366Z" }, + { url = "https://files.pythonhosted.org/packages/7c/9a/9030e6f9aa8fd7808e9c31ba4c38f87c4f8ec324ee67431d181fe396d705/greenlet-3.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:73f51dd0e0bdb596fb0417e475fa3c5e32d4c83638296e560086b8d7da7c4170", size = 305387, upload-time = "2025-12-04T14:26:51.063Z" }, + { 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, upload-time = "2025-12-04T14:25:20.941Z" }, + { 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, upload-time = "2025-12-04T14:50:11.039Z" }, + { 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, upload-time = "2025-12-04T14:57:47.007Z" }, + { 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, upload-time = "2025-12-04T15:07:16.906Z" }, + { 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, upload-time = "2025-12-04T14:26:06.225Z" }, + { 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, upload-time = "2025-12-04T15:04:28.484Z" }, + { 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, upload-time = "2025-12-04T14:27:33.531Z" }, +] + +[[package]] +name = "h11" +version = "0.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, +] + +[[package]] +name = "httpcore" +version = "1.0.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "h11" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" }, +] + +[[package]] +name = "httptools" +version = "0.7.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b5/46/120a669232c7bdedb9d52d4aeae7e6c7dfe151e99dc70802e2fc7a5e1993/httptools-0.7.1.tar.gz", hash = "sha256:abd72556974f8e7c74a259655924a717a2365b236c882c3f6f8a45fe94703ac9", size = 258961, upload-time = "2025-10-10T03:55:08.559Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/09/8f/c77b1fcbfd262d422f12da02feb0d218fa228d52485b77b953832105bb90/httptools-0.7.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6babce6cfa2a99545c60bfef8bee0cc0545413cb0018f617c8059a30ad985de3", size = 202889, upload-time = "2025-10-10T03:54:47.089Z" }, + { url = "https://files.pythonhosted.org/packages/0a/1a/22887f53602feaa066354867bc49a68fc295c2293433177ee90870a7d517/httptools-0.7.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:601b7628de7504077dd3dcb3791c6b8694bbd967148a6d1f01806509254fb1ca", size = 108180, upload-time = "2025-10-10T03:54:48.052Z" }, + { url = "https://files.pythonhosted.org/packages/32/6a/6aaa91937f0010d288d3d124ca2946d48d60c3a5ee7ca62afe870e3ea011/httptools-0.7.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:04c6c0e6c5fb0739c5b8a9eb046d298650a0ff38cf42537fc372b28dc7e4472c", size = 478596, upload-time = "2025-10-10T03:54:48.919Z" }, + { url = "https://files.pythonhosted.org/packages/6d/70/023d7ce117993107be88d2cbca566a7c1323ccbaf0af7eabf2064fe356f6/httptools-0.7.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:69d4f9705c405ae3ee83d6a12283dc9feba8cc6aaec671b412917e644ab4fa66", size = 473268, upload-time = "2025-10-10T03:54:49.993Z" }, + { url = "https://files.pythonhosted.org/packages/32/4d/9dd616c38da088e3f436e9a616e1d0cc66544b8cdac405cc4e81c8679fc7/httptools-0.7.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:44c8f4347d4b31269c8a9205d8a5ee2df5322b09bbbd30f8f862185bb6b05346", size = 455517, upload-time = "2025-10-10T03:54:51.066Z" }, + { url = "https://files.pythonhosted.org/packages/1d/3a/a6c595c310b7df958e739aae88724e24f9246a514d909547778d776799be/httptools-0.7.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:465275d76db4d554918aba40bf1cbebe324670f3dfc979eaffaa5d108e2ed650", size = 458337, upload-time = "2025-10-10T03:54:52.196Z" }, + { url = "https://files.pythonhosted.org/packages/fd/82/88e8d6d2c51edc1cc391b6e044c6c435b6aebe97b1abc33db1b0b24cd582/httptools-0.7.1-cp313-cp313-win_amd64.whl", hash = "sha256:322d00c2068d125bd570f7bf78b2d367dad02b919d8581d7476d8b75b294e3e6", size = 85743, upload-time = "2025-10-10T03:54:53.448Z" }, + { url = "https://files.pythonhosted.org/packages/34/50/9d095fcbb6de2d523e027a2f304d4551855c2f46e0b82befd718b8b20056/httptools-0.7.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:c08fe65728b8d70b6923ce31e3956f859d5e1e8548e6f22ec520a962c6757270", size = 203619, upload-time = "2025-10-10T03:54:54.321Z" }, + { url = "https://files.pythonhosted.org/packages/07/f0/89720dc5139ae54b03f861b5e2c55a37dba9a5da7d51e1e824a1f343627f/httptools-0.7.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:7aea2e3c3953521c3c51106ee11487a910d45586e351202474d45472db7d72d3", size = 108714, upload-time = "2025-10-10T03:54:55.163Z" }, + { url = "https://files.pythonhosted.org/packages/b3/cb/eea88506f191fb552c11787c23f9a405f4c7b0c5799bf73f2249cd4f5228/httptools-0.7.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0e68b8582f4ea9166be62926077a3334064d422cf08ab87d8b74664f8e9058e1", size = 472909, upload-time = "2025-10-10T03:54:56.056Z" }, + { url = "https://files.pythonhosted.org/packages/e0/4a/a548bdfae6369c0d078bab5769f7b66f17f1bfaa6fa28f81d6be6959066b/httptools-0.7.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:df091cf961a3be783d6aebae963cc9b71e00d57fa6f149025075217bc6a55a7b", size = 470831, upload-time = "2025-10-10T03:54:57.219Z" }, + { url = "https://files.pythonhosted.org/packages/4d/31/14df99e1c43bd132eec921c2e7e11cda7852f65619bc0fc5bdc2d0cb126c/httptools-0.7.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f084813239e1eb403ddacd06a30de3d3e09a9b76e7894dcda2b22f8a726e9c60", size = 452631, upload-time = "2025-10-10T03:54:58.219Z" }, + { url = "https://files.pythonhosted.org/packages/22/d2/b7e131f7be8d854d48cb6d048113c30f9a46dca0c9a8b08fcb3fcd588cdc/httptools-0.7.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7347714368fb2b335e9063bc2b96f2f87a9ceffcd9758ac295f8bbcd3ffbc0ca", size = 452910, upload-time = "2025-10-10T03:54:59.366Z" }, + { url = "https://files.pythonhosted.org/packages/53/cf/878f3b91e4e6e011eff6d1fa9ca39f7eb17d19c9d7971b04873734112f30/httptools-0.7.1-cp314-cp314-win_amd64.whl", hash = "sha256:cfabda2a5bb85aa2a904ce06d974a3f30fb36cc63d7feaddec05d2050acede96", size = 88205, upload-time = "2025-10-10T03:55:00.389Z" }, +] + +[[package]] +name = "httpx" +version = "0.28.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "certifi" }, + { name = "httpcore" }, + { name = "idna" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" }, +] + +[[package]] +name = "idna" +version = "3.11" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902", size = 194582, upload-time = "2025-10-12T14:55:20.501Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, +] + +[[package]] +name = "itsdangerous" +version = "2.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9c/cb/8ac0172223afbccb63986cc25049b154ecfb5e85932587206f42317be31d/itsdangerous-2.2.0.tar.gz", hash = "sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173", size = 54410, upload-time = "2024-04-16T21:28:15.614Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/96/92447566d16df59b2a776c0fb82dbc4d9e07cd95062562af01e408583fc4/itsdangerous-2.2.0-py3-none-any.whl", hash = "sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef", size = 16234, upload-time = "2024-04-16T21:28:14.499Z" }, +] + +[[package]] +name = "jinja2" +version = "3.1.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, +] + +[[package]] +name = "jiter" +version = "0.12.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/45/9d/e0660989c1370e25848bb4c52d061c71837239738ad937e83edca174c273/jiter-0.12.0.tar.gz", hash = "sha256:64dfcd7d5c168b38d3f9f8bba7fc639edb3418abcc74f22fdbe6b8938293f30b", size = 168294, upload-time = "2025-11-09T20:49:23.302Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3d/a6/97209693b177716e22576ee1161674d1d58029eb178e01866a0422b69224/jiter-0.12.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:6cc49d5130a14b732e0612bc76ae8db3b49898732223ef8b7599aa8d9810683e", size = 313658, upload-time = "2025-11-09T20:47:44.424Z" }, + { url = "https://files.pythonhosted.org/packages/06/4d/125c5c1537c7d8ee73ad3d530a442d6c619714b95027143f1b61c0b4dfe0/jiter-0.12.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:37f27a32ce36364d2fa4f7fdc507279db604d27d239ea2e044c8f148410defe1", size = 318605, upload-time = "2025-11-09T20:47:45.973Z" }, + { url = "https://files.pythonhosted.org/packages/99/bf/a840b89847885064c41a5f52de6e312e91fa84a520848ee56c97e4fa0205/jiter-0.12.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bbc0944aa3d4b4773e348cda635252824a78f4ba44328e042ef1ff3f6080d1cf", size = 349803, upload-time = "2025-11-09T20:47:47.535Z" }, + { url = "https://files.pythonhosted.org/packages/8a/88/e63441c28e0db50e305ae23e19c1d8fae012d78ed55365da392c1f34b09c/jiter-0.12.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:da25c62d4ee1ffbacb97fac6dfe4dcd6759ebdc9015991e92a6eae5816287f44", size = 365120, upload-time = "2025-11-09T20:47:49.284Z" }, + { url = "https://files.pythonhosted.org/packages/0a/7c/49b02714af4343970eb8aca63396bc1c82fa01197dbb1e9b0d274b550d4e/jiter-0.12.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:048485c654b838140b007390b8182ba9774621103bd4d77c9c3f6f117474ba45", size = 479918, upload-time = "2025-11-09T20:47:50.807Z" }, + { url = "https://files.pythonhosted.org/packages/69/ba/0a809817fdd5a1db80490b9150645f3aae16afad166960bcd562be194f3b/jiter-0.12.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:635e737fbb7315bef0037c19b88b799143d2d7d3507e61a76751025226b3ac87", size = 379008, upload-time = "2025-11-09T20:47:52.211Z" }, + { url = "https://files.pythonhosted.org/packages/5f/c3/c9fc0232e736c8877d9e6d83d6eeb0ba4e90c6c073835cc2e8f73fdeef51/jiter-0.12.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e017c417b1ebda911bd13b1e40612704b1f5420e30695112efdbed8a4b389ed", size = 361785, upload-time = "2025-11-09T20:47:53.512Z" }, + { url = "https://files.pythonhosted.org/packages/96/61/61f69b7e442e97ca6cd53086ddc1cf59fb830549bc72c0a293713a60c525/jiter-0.12.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:89b0bfb8b2bf2351fba36bb211ef8bfceba73ef58e7f0c68fb67b5a2795ca2f9", size = 386108, upload-time = "2025-11-09T20:47:54.893Z" }, + { url = "https://files.pythonhosted.org/packages/e9/2e/76bb3332f28550c8f1eba3bf6e5efe211efda0ddbbaf24976bc7078d42a5/jiter-0.12.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:f5aa5427a629a824a543672778c9ce0c5e556550d1569bb6ea28a85015287626", size = 519937, upload-time = "2025-11-09T20:47:56.253Z" }, + { url = "https://files.pythonhosted.org/packages/84/d6/fa96efa87dc8bff2094fb947f51f66368fa56d8d4fc9e77b25d7fbb23375/jiter-0.12.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed53b3d6acbcb0fd0b90f20c7cb3b24c357fe82a3518934d4edfa8c6898e498c", size = 510853, upload-time = "2025-11-09T20:47:58.32Z" }, + { url = "https://files.pythonhosted.org/packages/8a/28/93f67fdb4d5904a708119a6ab58a8f1ec226ff10a94a282e0215402a8462/jiter-0.12.0-cp313-cp313-win32.whl", hash = "sha256:4747de73d6b8c78f2e253a2787930f4fffc68da7fa319739f57437f95963c4de", size = 204699, upload-time = "2025-11-09T20:47:59.686Z" }, + { url = "https://files.pythonhosted.org/packages/c4/1f/30b0eb087045a0abe2a5c9c0c0c8da110875a1d3be83afd4a9a4e548be3c/jiter-0.12.0-cp313-cp313-win_amd64.whl", hash = "sha256:e25012eb0c456fcc13354255d0338cd5397cce26c77b2832b3c4e2e255ea5d9a", size = 204258, upload-time = "2025-11-09T20:48:01.01Z" }, + { url = "https://files.pythonhosted.org/packages/2c/f4/2b4daf99b96bce6fc47971890b14b2a36aef88d7beb9f057fafa032c6141/jiter-0.12.0-cp313-cp313-win_arm64.whl", hash = "sha256:c97b92c54fe6110138c872add030a1f99aea2401ddcdaa21edf74705a646dd60", size = 185503, upload-time = "2025-11-09T20:48:02.35Z" }, + { url = "https://files.pythonhosted.org/packages/39/ca/67bb15a7061d6fe20b9b2a2fd783e296a1e0f93468252c093481a2f00efa/jiter-0.12.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:53839b35a38f56b8be26a7851a48b89bc47e5d88e900929df10ed93b95fea3d6", size = 317965, upload-time = "2025-11-09T20:48:03.783Z" }, + { url = "https://files.pythonhosted.org/packages/18/af/1788031cd22e29c3b14bc6ca80b16a39a0b10e611367ffd480c06a259831/jiter-0.12.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94f669548e55c91ab47fef8bddd9c954dab1938644e715ea49d7e117015110a4", size = 345831, upload-time = "2025-11-09T20:48:05.55Z" }, + { url = "https://files.pythonhosted.org/packages/05/17/710bf8472d1dff0d3caf4ced6031060091c1320f84ee7d5dcbed1f352417/jiter-0.12.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:351d54f2b09a41600ffea43d081522d792e81dcfb915f6d2d242744c1cc48beb", size = 361272, upload-time = "2025-11-09T20:48:06.951Z" }, + { url = "https://files.pythonhosted.org/packages/fb/f1/1dcc4618b59761fef92d10bcbb0b038b5160be653b003651566a185f1a5c/jiter-0.12.0-cp313-cp313t-win_amd64.whl", hash = "sha256:2a5e90604620f94bf62264e7c2c038704d38217b7465b863896c6d7c902b06c7", size = 204604, upload-time = "2025-11-09T20:48:08.328Z" }, + { url = "https://files.pythonhosted.org/packages/d9/32/63cb1d9f1c5c6632a783c0052cde9ef7ba82688f7065e2f0d5f10a7e3edb/jiter-0.12.0-cp313-cp313t-win_arm64.whl", hash = "sha256:88ef757017e78d2860f96250f9393b7b577b06a956ad102c29c8237554380db3", size = 185628, upload-time = "2025-11-09T20:48:09.572Z" }, + { url = "https://files.pythonhosted.org/packages/a8/99/45c9f0dbe4a1416b2b9a8a6d1236459540f43d7fb8883cff769a8db0612d/jiter-0.12.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:c46d927acd09c67a9fb1416df45c5a04c27e83aae969267e98fba35b74e99525", size = 312478, upload-time = "2025-11-09T20:48:10.898Z" }, + { url = "https://files.pythonhosted.org/packages/4c/a7/54ae75613ba9e0f55fcb0bc5d1f807823b5167cc944e9333ff322e9f07dd/jiter-0.12.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:774ff60b27a84a85b27b88cd5583899c59940bcc126caca97eb2a9df6aa00c49", size = 318706, upload-time = "2025-11-09T20:48:12.266Z" }, + { url = "https://files.pythonhosted.org/packages/59/31/2aa241ad2c10774baf6c37f8b8e1f39c07db358f1329f4eb40eba179c2a2/jiter-0.12.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5433fab222fb072237df3f637d01b81f040a07dcac1cb4a5c75c7aa9ed0bef1", size = 351894, upload-time = "2025-11-09T20:48:13.673Z" }, + { url = "https://files.pythonhosted.org/packages/54/4f/0f2759522719133a9042781b18cc94e335b6d290f5e2d3e6899d6af933e3/jiter-0.12.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f8c593c6e71c07866ec6bfb790e202a833eeec885022296aff6b9e0b92d6a70e", size = 365714, upload-time = "2025-11-09T20:48:15.083Z" }, + { url = "https://files.pythonhosted.org/packages/dc/6f/806b895f476582c62a2f52c453151edd8a0fde5411b0497baaa41018e878/jiter-0.12.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:90d32894d4c6877a87ae00c6b915b609406819dce8bc0d4e962e4de2784e567e", size = 478989, upload-time = "2025-11-09T20:48:16.706Z" }, + { url = "https://files.pythonhosted.org/packages/86/6c/012d894dc6e1033acd8db2b8346add33e413ec1c7c002598915278a37f79/jiter-0.12.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:798e46eed9eb10c3adbbacbd3bdb5ecd4cf7064e453d00dbef08802dae6937ff", size = 378615, upload-time = "2025-11-09T20:48:18.614Z" }, + { url = "https://files.pythonhosted.org/packages/87/30/d718d599f6700163e28e2c71c0bbaf6dace692e7df2592fd793ac9276717/jiter-0.12.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3f1368f0a6719ea80013a4eb90ba72e75d7ea67cfc7846db2ca504f3df0169a", size = 364745, upload-time = "2025-11-09T20:48:20.117Z" }, + { url = "https://files.pythonhosted.org/packages/8f/85/315b45ce4b6ddc7d7fceca24068543b02bdc8782942f4ee49d652e2cc89f/jiter-0.12.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:65f04a9d0b4406f7e51279710b27484af411896246200e461d80d3ba0caa901a", size = 386502, upload-time = "2025-11-09T20:48:21.543Z" }, + { url = "https://files.pythonhosted.org/packages/74/0b/ce0434fb40c5b24b368fe81b17074d2840748b4952256bab451b72290a49/jiter-0.12.0-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:fd990541982a24281d12b67a335e44f117e4c6cbad3c3b75c7dea68bf4ce3a67", size = 519845, upload-time = "2025-11-09T20:48:22.964Z" }, + { url = "https://files.pythonhosted.org/packages/e8/a3/7a7a4488ba052767846b9c916d208b3ed114e3eb670ee984e4c565b9cf0d/jiter-0.12.0-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:b111b0e9152fa7df870ecaebb0bd30240d9f7fff1f2003bcb4ed0f519941820b", size = 510701, upload-time = "2025-11-09T20:48:24.483Z" }, + { url = "https://files.pythonhosted.org/packages/c3/16/052ffbf9d0467b70af24e30f91e0579e13ded0c17bb4a8eb2aed3cb60131/jiter-0.12.0-cp314-cp314-win32.whl", hash = "sha256:a78befb9cc0a45b5a5a0d537b06f8544c2ebb60d19d02c41ff15da28a9e22d42", size = 205029, upload-time = "2025-11-09T20:48:25.749Z" }, + { url = "https://files.pythonhosted.org/packages/e4/18/3cf1f3f0ccc789f76b9a754bdb7a6977e5d1d671ee97a9e14f7eb728d80e/jiter-0.12.0-cp314-cp314-win_amd64.whl", hash = "sha256:e1fe01c082f6aafbe5c8faf0ff074f38dfb911d53f07ec333ca03f8f6226debf", size = 204960, upload-time = "2025-11-09T20:48:27.415Z" }, + { url = "https://files.pythonhosted.org/packages/02/68/736821e52ecfdeeb0f024b8ab01b5a229f6b9293bbdb444c27efade50b0f/jiter-0.12.0-cp314-cp314-win_arm64.whl", hash = "sha256:d72f3b5a432a4c546ea4bedc84cce0c3404874f1d1676260b9c7f048a9855451", size = 185529, upload-time = "2025-11-09T20:48:29.125Z" }, + { url = "https://files.pythonhosted.org/packages/30/61/12ed8ee7a643cce29ac97c2281f9ce3956eb76b037e88d290f4ed0d41480/jiter-0.12.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:e6ded41aeba3603f9728ed2b6196e4df875348ab97b28fc8afff115ed42ba7a7", size = 318974, upload-time = "2025-11-09T20:48:30.87Z" }, + { url = "https://files.pythonhosted.org/packages/2d/c6/f3041ede6d0ed5e0e79ff0de4c8f14f401bbf196f2ef3971cdbe5fd08d1d/jiter-0.12.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a947920902420a6ada6ad51892082521978e9dd44a802663b001436e4b771684", size = 345932, upload-time = "2025-11-09T20:48:32.658Z" }, + { url = "https://files.pythonhosted.org/packages/d5/5d/4d94835889edd01ad0e2dbfc05f7bdfaed46292e7b504a6ac7839aa00edb/jiter-0.12.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:add5e227e0554d3a52cf390a7635edaffdf4f8fce4fdbcef3cc2055bb396a30c", size = 367243, upload-time = "2025-11-09T20:48:34.093Z" }, + { url = "https://files.pythonhosted.org/packages/fd/76/0051b0ac2816253a99d27baf3dda198663aff882fa6ea7deeb94046da24e/jiter-0.12.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f9b1cda8fcb736250d7e8711d4580ebf004a46771432be0ae4796944b5dfa5d", size = 479315, upload-time = "2025-11-09T20:48:35.507Z" }, + { url = "https://files.pythonhosted.org/packages/70/ae/83f793acd68e5cb24e483f44f482a1a15601848b9b6f199dacb970098f77/jiter-0.12.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:deeb12a2223fe0135c7ff1356a143d57f95bbf1f4a66584f1fc74df21d86b993", size = 380714, upload-time = "2025-11-09T20:48:40.014Z" }, + { url = "https://files.pythonhosted.org/packages/b1/5e/4808a88338ad2c228b1126b93fcd8ba145e919e886fe910d578230dabe3b/jiter-0.12.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c596cc0f4cb574877550ce4ecd51f8037469146addd676d7c1a30ebe6391923f", size = 365168, upload-time = "2025-11-09T20:48:41.462Z" }, + { url = "https://files.pythonhosted.org/packages/0c/d4/04619a9e8095b42aef436b5aeb4c0282b4ff1b27d1db1508df9f5dc82750/jiter-0.12.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5ab4c823b216a4aeab3fdbf579c5843165756bd9ad87cc6b1c65919c4715f783", size = 387893, upload-time = "2025-11-09T20:48:42.921Z" }, + { url = "https://files.pythonhosted.org/packages/17/ea/d3c7e62e4546fdc39197fa4a4315a563a89b95b6d54c0d25373842a59cbe/jiter-0.12.0-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:e427eee51149edf962203ff8db75a7514ab89be5cb623fb9cea1f20b54f1107b", size = 520828, upload-time = "2025-11-09T20:48:44.278Z" }, + { url = "https://files.pythonhosted.org/packages/cc/0b/c6d3562a03fd767e31cb119d9041ea7958c3c80cb3d753eafb19b3b18349/jiter-0.12.0-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:edb868841f84c111255ba5e80339d386d937ec1fdce419518ce1bd9370fac5b6", size = 511009, upload-time = "2025-11-09T20:48:45.726Z" }, + { url = "https://files.pythonhosted.org/packages/aa/51/2cb4468b3448a8385ebcd15059d325c9ce67df4e2758d133ab9442b19834/jiter-0.12.0-cp314-cp314t-win32.whl", hash = "sha256:8bbcfe2791dfdb7c5e48baf646d37a6a3dcb5a97a032017741dea9f817dca183", size = 205110, upload-time = "2025-11-09T20:48:47.033Z" }, + { url = "https://files.pythonhosted.org/packages/b2/c5/ae5ec83dec9c2d1af805fd5fe8f74ebded9c8670c5210ec7820ce0dbeb1e/jiter-0.12.0-cp314-cp314t-win_amd64.whl", hash = "sha256:2fa940963bf02e1d8226027ef461e36af472dea85d36054ff835aeed944dd873", size = 205223, upload-time = "2025-11-09T20:48:49.076Z" }, + { url = "https://files.pythonhosted.org/packages/97/9a/3c5391907277f0e55195550cf3fa8e293ae9ee0c00fb402fec1e38c0c82f/jiter-0.12.0-cp314-cp314t-win_arm64.whl", hash = "sha256:506c9708dd29b27288f9f8f1140c3cb0e3d8ddb045956d7757b1fa0e0f39a473", size = 185564, upload-time = "2025-11-09T20:48:50.376Z" }, +] + +[[package]] +name = "markdown-it-py" +version = "4.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mdurl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3", size = 73070, upload-time = "2025-08-11T12:57:52.854Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", size = 87321, upload-time = "2025-08-11T12:57:51.923Z" }, +] + +[[package]] +name = "markupsafe" +version = "3.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313, upload-time = "2025-09-27T18:37:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622, upload-time = "2025-09-27T18:36:41.777Z" }, + { url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029, upload-time = "2025-09-27T18:36:43.257Z" }, + { url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374, upload-time = "2025-09-27T18:36:44.508Z" }, + { url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", size = 22980, upload-time = "2025-09-27T18:36:45.385Z" }, + { url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", size = 21990, upload-time = "2025-09-27T18:36:46.916Z" }, + { url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", size = 23784, upload-time = "2025-09-27T18:36:47.884Z" }, + { url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", size = 21588, upload-time = "2025-09-27T18:36:48.82Z" }, + { url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", size = 23041, upload-time = "2025-09-27T18:36:49.797Z" }, + { url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543, upload-time = "2025-09-27T18:36:51.584Z" }, + { url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113, upload-time = "2025-09-27T18:36:52.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911, upload-time = "2025-09-27T18:36:53.513Z" }, + { url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", size = 11658, upload-time = "2025-09-27T18:36:54.819Z" }, + { url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", size = 12066, upload-time = "2025-09-27T18:36:55.714Z" }, + { url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", size = 25639, upload-time = "2025-09-27T18:36:56.908Z" }, + { url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", size = 23569, upload-time = "2025-09-27T18:36:57.913Z" }, + { url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", size = 23284, upload-time = "2025-09-27T18:36:58.833Z" }, + { url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", size = 24801, upload-time = "2025-09-27T18:36:59.739Z" }, + { url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", size = 22769, upload-time = "2025-09-27T18:37:00.719Z" }, + { url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", size = 23642, upload-time = "2025-09-27T18:37:01.673Z" }, + { url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612, upload-time = "2025-09-27T18:37:02.639Z" }, + { url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200, upload-time = "2025-09-27T18:37:03.582Z" }, + { url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973, upload-time = "2025-09-27T18:37:04.929Z" }, + { url = "https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe", size = 11619, upload-time = "2025-09-27T18:37:06.342Z" }, + { url = "https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026", size = 12029, upload-time = "2025-09-27T18:37:07.213Z" }, + { url = "https://files.pythonhosted.org/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737", size = 24408, upload-time = "2025-09-27T18:37:09.572Z" }, + { url = "https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97", size = 23005, upload-time = "2025-09-27T18:37:10.58Z" }, + { url = "https://files.pythonhosted.org/packages/bc/20/b7fdf89a8456b099837cd1dc21974632a02a999ec9bf7ca3e490aacd98e7/markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d", size = 22048, upload-time = "2025-09-27T18:37:11.547Z" }, + { url = "https://files.pythonhosted.org/packages/9a/a7/591f592afdc734f47db08a75793a55d7fbcc6902a723ae4cfbab61010cc5/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda", size = 23821, upload-time = "2025-09-27T18:37:12.48Z" }, + { url = "https://files.pythonhosted.org/packages/7d/33/45b24e4f44195b26521bc6f1a82197118f74df348556594bd2262bda1038/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf", size = 21606, upload-time = "2025-09-27T18:37:13.485Z" }, + { url = "https://files.pythonhosted.org/packages/ff/0e/53dfaca23a69fbfbbf17a4b64072090e70717344c52eaaaa9c5ddff1e5f0/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe", size = 23043, upload-time = "2025-09-27T18:37:14.408Z" }, + { url = "https://files.pythonhosted.org/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9", size = 14747, upload-time = "2025-09-27T18:37:15.36Z" }, + { url = "https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581", size = 15341, upload-time = "2025-09-27T18:37:16.496Z" }, + { url = "https://files.pythonhosted.org/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4", size = 14073, upload-time = "2025-09-27T18:37:17.476Z" }, + { url = "https://files.pythonhosted.org/packages/3c/f0/57689aa4076e1b43b15fdfa646b04653969d50cf30c32a102762be2485da/markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab", size = 11661, upload-time = "2025-09-27T18:37:18.453Z" }, + { url = "https://files.pythonhosted.org/packages/89/c3/2e67a7ca217c6912985ec766c6393b636fb0c2344443ff9d91404dc4c79f/markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175", size = 12069, upload-time = "2025-09-27T18:37:19.332Z" }, + { url = "https://files.pythonhosted.org/packages/f0/00/be561dce4e6ca66b15276e184ce4b8aec61fe83662cce2f7d72bd3249d28/markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634", size = 25670, upload-time = "2025-09-27T18:37:20.245Z" }, + { url = "https://files.pythonhosted.org/packages/50/09/c419f6f5a92e5fadde27efd190eca90f05e1261b10dbd8cbcb39cd8ea1dc/markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50", size = 23598, upload-time = "2025-09-27T18:37:21.177Z" }, + { url = "https://files.pythonhosted.org/packages/22/44/a0681611106e0b2921b3033fc19bc53323e0b50bc70cffdd19f7d679bb66/markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e", size = 23261, upload-time = "2025-09-27T18:37:22.167Z" }, + { url = "https://files.pythonhosted.org/packages/5f/57/1b0b3f100259dc9fffe780cfb60d4be71375510e435efec3d116b6436d43/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5", size = 24835, upload-time = "2025-09-27T18:37:23.296Z" }, + { url = "https://files.pythonhosted.org/packages/26/6a/4bf6d0c97c4920f1597cc14dd720705eca0bf7c787aebc6bb4d1bead5388/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523", size = 22733, upload-time = "2025-09-27T18:37:24.237Z" }, + { url = "https://files.pythonhosted.org/packages/14/c7/ca723101509b518797fedc2fdf79ba57f886b4aca8a7d31857ba3ee8281f/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc", size = 23672, upload-time = "2025-09-27T18:37:25.271Z" }, + { url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", size = 14819, upload-time = "2025-09-27T18:37:26.285Z" }, + { url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", size = 15426, upload-time = "2025-09-27T18:37:27.316Z" }, + { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" }, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, +] + +[[package]] +name = "multidict" +version = "6.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/80/1e/5492c365f222f907de1039b91f922b93fa4f764c713ee858d235495d8f50/multidict-6.7.0.tar.gz", hash = "sha256:c6e99d9a65ca282e578dfea819cfa9c0a62b2499d8677392e09feaf305e9e6f5", size = 101834, upload-time = "2025-10-06T14:52:30.657Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/86/33272a544eeb36d66e4d9a920602d1a2f57d4ebea4ef3cdfe5a912574c95/multidict-6.7.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:bee7c0588aa0076ce77c0ea5d19a68d76ad81fcd9fe8501003b9a24f9d4000f6", size = 76135, upload-time = "2025-10-06T14:49:54.26Z" }, + { url = "https://files.pythonhosted.org/packages/91/1c/eb97db117a1ebe46d457a3d235a7b9d2e6dcab174f42d1b67663dd9e5371/multidict-6.7.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7ef6b61cad77091056ce0e7ce69814ef72afacb150b7ac6a3e9470def2198159", size = 45117, upload-time = "2025-10-06T14:49:55.82Z" }, + { url = "https://files.pythonhosted.org/packages/f1/d8/6c3442322e41fb1dd4de8bd67bfd11cd72352ac131f6368315617de752f1/multidict-6.7.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9c0359b1ec12b1d6849c59f9d319610b7f20ef990a6d454ab151aa0e3b9f78ca", size = 43472, upload-time = "2025-10-06T14:49:57.048Z" }, + { url = "https://files.pythonhosted.org/packages/75/3f/e2639e80325af0b6c6febdf8e57cc07043ff15f57fa1ef808f4ccb5ac4cd/multidict-6.7.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:cd240939f71c64bd658f186330603aac1a9a81bf6273f523fca63673cb7378a8", size = 249342, upload-time = "2025-10-06T14:49:58.368Z" }, + { url = "https://files.pythonhosted.org/packages/5d/cc/84e0585f805cbeaa9cbdaa95f9a3d6aed745b9d25700623ac89a6ecff400/multidict-6.7.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a60a4d75718a5efa473ebd5ab685786ba0c67b8381f781d1be14da49f1a2dc60", size = 257082, upload-time = "2025-10-06T14:49:59.89Z" }, + { url = "https://files.pythonhosted.org/packages/b0/9c/ac851c107c92289acbbf5cfb485694084690c1b17e555f44952c26ddc5bd/multidict-6.7.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:53a42d364f323275126aff81fb67c5ca1b7a04fda0546245730a55c8c5f24bc4", size = 240704, upload-time = "2025-10-06T14:50:01.485Z" }, + { url = "https://files.pythonhosted.org/packages/50/cc/5f93e99427248c09da95b62d64b25748a5f5c98c7c2ab09825a1d6af0e15/multidict-6.7.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3b29b980d0ddbecb736735ee5bef69bb2ddca56eff603c86f3f29a1128299b4f", size = 266355, upload-time = "2025-10-06T14:50:02.955Z" }, + { url = "https://files.pythonhosted.org/packages/ec/0c/2ec1d883ceb79c6f7f6d7ad90c919c898f5d1c6ea96d322751420211e072/multidict-6.7.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f8a93b1c0ed2d04b97a5e9336fd2d33371b9a6e29ab7dd6503d63407c20ffbaf", size = 267259, upload-time = "2025-10-06T14:50:04.446Z" }, + { url = "https://files.pythonhosted.org/packages/c6/2d/f0b184fa88d6630aa267680bdb8623fb69cb0d024b8c6f0d23f9a0f406d3/multidict-6.7.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9ff96e8815eecacc6645da76c413eb3b3d34cfca256c70b16b286a687d013c32", size = 254903, upload-time = "2025-10-06T14:50:05.98Z" }, + { url = "https://files.pythonhosted.org/packages/06/c9/11ea263ad0df7dfabcad404feb3c0dd40b131bc7f232d5537f2fb1356951/multidict-6.7.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7516c579652f6a6be0e266aec0acd0db80829ca305c3d771ed898538804c2036", size = 252365, upload-time = "2025-10-06T14:50:07.511Z" }, + { url = "https://files.pythonhosted.org/packages/41/88/d714b86ee2c17d6e09850c70c9d310abac3d808ab49dfa16b43aba9d53fd/multidict-6.7.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:040f393368e63fb0f3330e70c26bfd336656bed925e5cbe17c9da839a6ab13ec", size = 250062, upload-time = "2025-10-06T14:50:09.074Z" }, + { url = "https://files.pythonhosted.org/packages/15/fe/ad407bb9e818c2b31383f6131ca19ea7e35ce93cf1310fce69f12e89de75/multidict-6.7.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b3bc26a951007b1057a1c543af845f1c7e3e71cc240ed1ace7bf4484aa99196e", size = 249683, upload-time = "2025-10-06T14:50:10.714Z" }, + { url = "https://files.pythonhosted.org/packages/8c/a4/a89abdb0229e533fb925e7c6e5c40201c2873efebc9abaf14046a4536ee6/multidict-6.7.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:7b022717c748dd1992a83e219587aabe45980d88969f01b316e78683e6285f64", size = 261254, upload-time = "2025-10-06T14:50:12.28Z" }, + { url = "https://files.pythonhosted.org/packages/8d/aa/0e2b27bd88b40a4fb8dc53dd74eecac70edaa4c1dd0707eb2164da3675b3/multidict-6.7.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:9600082733859f00d79dee64effc7aef1beb26adb297416a4ad2116fd61374bd", size = 257967, upload-time = "2025-10-06T14:50:14.16Z" }, + { url = "https://files.pythonhosted.org/packages/d0/8e/0c67b7120d5d5f6d874ed85a085f9dc770a7f9d8813e80f44a9fec820bb7/multidict-6.7.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:94218fcec4d72bc61df51c198d098ce2b378e0ccbac41ddbed5ef44092913288", size = 250085, upload-time = "2025-10-06T14:50:15.639Z" }, + { url = "https://files.pythonhosted.org/packages/ba/55/b73e1d624ea4b8fd4dd07a3bb70f6e4c7c6c5d9d640a41c6ffe5cdbd2a55/multidict-6.7.0-cp313-cp313-win32.whl", hash = "sha256:a37bd74c3fa9d00be2d7b8eca074dc56bd8077ddd2917a839bd989612671ed17", size = 41713, upload-time = "2025-10-06T14:50:17.066Z" }, + { url = "https://files.pythonhosted.org/packages/32/31/75c59e7d3b4205075b4c183fa4ca398a2daf2303ddf616b04ae6ef55cffe/multidict-6.7.0-cp313-cp313-win_amd64.whl", hash = "sha256:30d193c6cc6d559db42b6bcec8a5d395d34d60c9877a0b71ecd7c204fcf15390", size = 45915, upload-time = "2025-10-06T14:50:18.264Z" }, + { url = "https://files.pythonhosted.org/packages/31/2a/8987831e811f1184c22bc2e45844934385363ee61c0a2dcfa8f71b87e608/multidict-6.7.0-cp313-cp313-win_arm64.whl", hash = "sha256:ea3334cabe4d41b7ccd01e4d349828678794edbc2d3ae97fc162a3312095092e", size = 43077, upload-time = "2025-10-06T14:50:19.853Z" }, + { url = "https://files.pythonhosted.org/packages/e8/68/7b3a5170a382a340147337b300b9eb25a9ddb573bcdfff19c0fa3f31ffba/multidict-6.7.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:ad9ce259f50abd98a1ca0aa6e490b58c316a0fce0617f609723e40804add2c00", size = 83114, upload-time = "2025-10-06T14:50:21.223Z" }, + { url = "https://files.pythonhosted.org/packages/55/5c/3fa2d07c84df4e302060f555bbf539310980362236ad49f50eeb0a1c1eb9/multidict-6.7.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:07f5594ac6d084cbb5de2df218d78baf55ef150b91f0ff8a21cc7a2e3a5a58eb", size = 48442, upload-time = "2025-10-06T14:50:22.871Z" }, + { url = "https://files.pythonhosted.org/packages/fc/56/67212d33239797f9bd91962bb899d72bb0f4c35a8652dcdb8ed049bef878/multidict-6.7.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0591b48acf279821a579282444814a2d8d0af624ae0bc600aa4d1b920b6e924b", size = 46885, upload-time = "2025-10-06T14:50:24.258Z" }, + { url = "https://files.pythonhosted.org/packages/46/d1/908f896224290350721597a61a69cd19b89ad8ee0ae1f38b3f5cd12ea2ac/multidict-6.7.0-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:749a72584761531d2b9467cfbdfd29487ee21124c304c4b6cb760d8777b27f9c", size = 242588, upload-time = "2025-10-06T14:50:25.716Z" }, + { url = "https://files.pythonhosted.org/packages/ab/67/8604288bbd68680eee0ab568fdcb56171d8b23a01bcd5cb0c8fedf6e5d99/multidict-6.7.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b4c3d199f953acd5b446bf7c0de1fe25d94e09e79086f8dc2f48a11a129cdf1", size = 249966, upload-time = "2025-10-06T14:50:28.192Z" }, + { url = "https://files.pythonhosted.org/packages/20/33/9228d76339f1ba51e3efef7da3ebd91964d3006217aae13211653193c3ff/multidict-6.7.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:9fb0211dfc3b51efea2f349ec92c114d7754dd62c01f81c3e32b765b70c45c9b", size = 228618, upload-time = "2025-10-06T14:50:29.82Z" }, + { url = "https://files.pythonhosted.org/packages/f8/2d/25d9b566d10cab1c42b3b9e5b11ef79c9111eaf4463b8c257a3bd89e0ead/multidict-6.7.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a027ec240fe73a8d6281872690b988eed307cd7d91b23998ff35ff577ca688b5", size = 257539, upload-time = "2025-10-06T14:50:31.731Z" }, + { url = "https://files.pythonhosted.org/packages/b6/b1/8d1a965e6637fc33de3c0d8f414485c2b7e4af00f42cab3d84e7b955c222/multidict-6.7.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1d964afecdf3a8288789df2f5751dc0a8261138c3768d9af117ed384e538fad", size = 256345, upload-time = "2025-10-06T14:50:33.26Z" }, + { url = "https://files.pythonhosted.org/packages/ba/0c/06b5a8adbdeedada6f4fb8d8f193d44a347223b11939b42953eeb6530b6b/multidict-6.7.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:caf53b15b1b7df9fbd0709aa01409000a2b4dd03a5f6f5cc548183c7c8f8b63c", size = 247934, upload-time = "2025-10-06T14:50:34.808Z" }, + { url = "https://files.pythonhosted.org/packages/8f/31/b2491b5fe167ca044c6eb4b8f2c9f3b8a00b24c432c365358eadac5d7625/multidict-6.7.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:654030da3197d927f05a536a66186070e98765aa5142794c9904555d3a9d8fb5", size = 245243, upload-time = "2025-10-06T14:50:36.436Z" }, + { url = "https://files.pythonhosted.org/packages/61/1a/982913957cb90406c8c94f53001abd9eafc271cb3e70ff6371590bec478e/multidict-6.7.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:2090d3718829d1e484706a2f525e50c892237b2bf9b17a79b059cb98cddc2f10", size = 235878, upload-time = "2025-10-06T14:50:37.953Z" }, + { url = "https://files.pythonhosted.org/packages/be/c0/21435d804c1a1cf7a2608593f4d19bca5bcbd7a81a70b253fdd1c12af9c0/multidict-6.7.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:2d2cfeec3f6f45651b3d408c4acec0ebf3daa9bc8a112a084206f5db5d05b754", size = 243452, upload-time = "2025-10-06T14:50:39.574Z" }, + { url = "https://files.pythonhosted.org/packages/54/0a/4349d540d4a883863191be6eb9a928846d4ec0ea007d3dcd36323bb058ac/multidict-6.7.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:4ef089f985b8c194d341eb2c24ae6e7408c9a0e2e5658699c92f497437d88c3c", size = 252312, upload-time = "2025-10-06T14:50:41.612Z" }, + { url = "https://files.pythonhosted.org/packages/26/64/d5416038dbda1488daf16b676e4dbfd9674dde10a0cc8f4fc2b502d8125d/multidict-6.7.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:e93a0617cd16998784bf4414c7e40f17a35d2350e5c6f0bd900d3a8e02bd3762", size = 246935, upload-time = "2025-10-06T14:50:43.972Z" }, + { url = "https://files.pythonhosted.org/packages/9f/8c/8290c50d14e49f35e0bd4abc25e1bc7711149ca9588ab7d04f886cdf03d9/multidict-6.7.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f0feece2ef8ebc42ed9e2e8c78fc4aa3cf455733b507c09ef7406364c94376c6", size = 243385, upload-time = "2025-10-06T14:50:45.648Z" }, + { url = "https://files.pythonhosted.org/packages/ef/a0/f83ae75e42d694b3fbad3e047670e511c138be747bc713cf1b10d5096416/multidict-6.7.0-cp313-cp313t-win32.whl", hash = "sha256:19a1d55338ec1be74ef62440ca9e04a2f001a04d0cc49a4983dc320ff0f3212d", size = 47777, upload-time = "2025-10-06T14:50:47.154Z" }, + { url = "https://files.pythonhosted.org/packages/dc/80/9b174a92814a3830b7357307a792300f42c9e94664b01dee8e457551fa66/multidict-6.7.0-cp313-cp313t-win_amd64.whl", hash = "sha256:3da4fb467498df97e986af166b12d01f05d2e04f978a9c1c680ea1988e0bc4b6", size = 53104, upload-time = "2025-10-06T14:50:48.851Z" }, + { url = "https://files.pythonhosted.org/packages/cc/28/04baeaf0428d95bb7a7bea0e691ba2f31394338ba424fb0679a9ed0f4c09/multidict-6.7.0-cp313-cp313t-win_arm64.whl", hash = "sha256:b4121773c49a0776461f4a904cdf6264c88e42218aaa8407e803ca8025872792", size = 45503, upload-time = "2025-10-06T14:50:50.16Z" }, + { url = "https://files.pythonhosted.org/packages/e2/b1/3da6934455dd4b261d4c72f897e3a5728eba81db59959f3a639245891baa/multidict-6.7.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3bab1e4aff7adaa34410f93b1f8e57c4b36b9af0426a76003f441ee1d3c7e842", size = 75128, upload-time = "2025-10-06T14:50:51.92Z" }, + { url = "https://files.pythonhosted.org/packages/14/2c/f069cab5b51d175a1a2cb4ccdf7a2c2dabd58aa5bd933fa036a8d15e2404/multidict-6.7.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:b8512bac933afc3e45fb2b18da8e59b78d4f408399a960339598374d4ae3b56b", size = 44410, upload-time = "2025-10-06T14:50:53.275Z" }, + { url = "https://files.pythonhosted.org/packages/42/e2/64bb41266427af6642b6b128e8774ed84c11b80a90702c13ac0a86bb10cc/multidict-6.7.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:79dcf9e477bc65414ebfea98ffd013cb39552b5ecd62908752e0e413d6d06e38", size = 43205, upload-time = "2025-10-06T14:50:54.911Z" }, + { url = "https://files.pythonhosted.org/packages/02/68/6b086fef8a3f1a8541b9236c594f0c9245617c29841f2e0395d979485cde/multidict-6.7.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:31bae522710064b5cbeddaf2e9f32b1abab70ac6ac91d42572502299e9953128", size = 245084, upload-time = "2025-10-06T14:50:56.369Z" }, + { url = "https://files.pythonhosted.org/packages/15/ee/f524093232007cd7a75c1d132df70f235cfd590a7c9eaccd7ff422ef4ae8/multidict-6.7.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a0df7ff02397bb63e2fd22af2c87dfa39e8c7f12947bc524dbdc528282c7e34", size = 252667, upload-time = "2025-10-06T14:50:57.991Z" }, + { url = "https://files.pythonhosted.org/packages/02/a5/eeb3f43ab45878f1895118c3ef157a480db58ede3f248e29b5354139c2c9/multidict-6.7.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7a0222514e8e4c514660e182d5156a415c13ef0aabbd71682fc714e327b95e99", size = 233590, upload-time = "2025-10-06T14:50:59.589Z" }, + { url = "https://files.pythonhosted.org/packages/6a/1e/76d02f8270b97269d7e3dbd45644b1785bda457b474315f8cf999525a193/multidict-6.7.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2397ab4daaf2698eb51a76721e98db21ce4f52339e535725de03ea962b5a3202", size = 264112, upload-time = "2025-10-06T14:51:01.183Z" }, + { url = "https://files.pythonhosted.org/packages/76/0b/c28a70ecb58963847c2a8efe334904cd254812b10e535aefb3bcce513918/multidict-6.7.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8891681594162635948a636c9fe0ff21746aeb3dd5463f6e25d9bea3a8a39ca1", size = 261194, upload-time = "2025-10-06T14:51:02.794Z" }, + { url = "https://files.pythonhosted.org/packages/b4/63/2ab26e4209773223159b83aa32721b4021ffb08102f8ac7d689c943fded1/multidict-6.7.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18706cc31dbf402a7945916dd5cddf160251b6dab8a2c5f3d6d5a55949f676b3", size = 248510, upload-time = "2025-10-06T14:51:04.724Z" }, + { url = "https://files.pythonhosted.org/packages/93/cd/06c1fa8282af1d1c46fd55c10a7930af652afdce43999501d4d68664170c/multidict-6.7.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f844a1bbf1d207dd311a56f383f7eda2d0e134921d45751842d8235e7778965d", size = 248395, upload-time = "2025-10-06T14:51:06.306Z" }, + { url = "https://files.pythonhosted.org/packages/99/ac/82cb419dd6b04ccf9e7e61befc00c77614fc8134362488b553402ecd55ce/multidict-6.7.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:d4393e3581e84e5645506923816b9cc81f5609a778c7e7534054091acc64d1c6", size = 239520, upload-time = "2025-10-06T14:51:08.091Z" }, + { url = "https://files.pythonhosted.org/packages/fa/f3/a0f9bf09493421bd8716a362e0cd1d244f5a6550f5beffdd6b47e885b331/multidict-6.7.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:fbd18dc82d7bf274b37aa48d664534330af744e03bccf696d6f4c6042e7d19e7", size = 245479, upload-time = "2025-10-06T14:51:10.365Z" }, + { url = "https://files.pythonhosted.org/packages/8d/01/476d38fc73a212843f43c852b0eee266b6971f0e28329c2184a8df90c376/multidict-6.7.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:b6234e14f9314731ec45c42fc4554b88133ad53a09092cc48a88e771c125dadb", size = 258903, upload-time = "2025-10-06T14:51:12.466Z" }, + { url = "https://files.pythonhosted.org/packages/49/6d/23faeb0868adba613b817d0e69c5f15531b24d462af8012c4f6de4fa8dc3/multidict-6.7.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:08d4379f9744d8f78d98c8673c06e202ffa88296f009c71bbafe8a6bf847d01f", size = 252333, upload-time = "2025-10-06T14:51:14.48Z" }, + { url = "https://files.pythonhosted.org/packages/1e/cc/48d02ac22b30fa247f7dad82866e4b1015431092f4ba6ebc7e77596e0b18/multidict-6.7.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:9fe04da3f79387f450fd0061d4dd2e45a72749d31bf634aecc9e27f24fdc4b3f", size = 243411, upload-time = "2025-10-06T14:51:16.072Z" }, + { url = "https://files.pythonhosted.org/packages/4a/03/29a8bf5a18abf1fe34535c88adbdfa88c9fb869b5a3b120692c64abe8284/multidict-6.7.0-cp314-cp314-win32.whl", hash = "sha256:fbafe31d191dfa7c4c51f7a6149c9fb7e914dcf9ffead27dcfd9f1ae382b3885", size = 40940, upload-time = "2025-10-06T14:51:17.544Z" }, + { url = "https://files.pythonhosted.org/packages/82/16/7ed27b680791b939de138f906d5cf2b4657b0d45ca6f5dd6236fdddafb1a/multidict-6.7.0-cp314-cp314-win_amd64.whl", hash = "sha256:2f67396ec0310764b9222a1728ced1ab638f61aadc6226f17a71dd9324f9a99c", size = 45087, upload-time = "2025-10-06T14:51:18.875Z" }, + { url = "https://files.pythonhosted.org/packages/cd/3c/e3e62eb35a1950292fe39315d3c89941e30a9d07d5d2df42965ab041da43/multidict-6.7.0-cp314-cp314-win_arm64.whl", hash = "sha256:ba672b26069957ee369cfa7fc180dde1fc6f176eaf1e6beaf61fbebbd3d9c000", size = 42368, upload-time = "2025-10-06T14:51:20.225Z" }, + { url = "https://files.pythonhosted.org/packages/8b/40/cd499bd0dbc5f1136726db3153042a735fffd0d77268e2ee20d5f33c010f/multidict-6.7.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:c1dcc7524066fa918c6a27d61444d4ee7900ec635779058571f70d042d86ed63", size = 82326, upload-time = "2025-10-06T14:51:21.588Z" }, + { url = "https://files.pythonhosted.org/packages/13/8a/18e031eca251c8df76daf0288e6790561806e439f5ce99a170b4af30676b/multidict-6.7.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:27e0b36c2d388dc7b6ced3406671b401e84ad7eb0656b8f3a2f46ed0ce483718", size = 48065, upload-time = "2025-10-06T14:51:22.93Z" }, + { url = "https://files.pythonhosted.org/packages/40/71/5e6701277470a87d234e433fb0a3a7deaf3bcd92566e421e7ae9776319de/multidict-6.7.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2a7baa46a22e77f0988e3b23d4ede5513ebec1929e34ee9495be535662c0dfe2", size = 46475, upload-time = "2025-10-06T14:51:24.352Z" }, + { url = "https://files.pythonhosted.org/packages/fe/6a/bab00cbab6d9cfb57afe1663318f72ec28289ea03fd4e8236bb78429893a/multidict-6.7.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:7bf77f54997a9166a2f5675d1201520586439424c2511723a7312bdb4bcc034e", size = 239324, upload-time = "2025-10-06T14:51:25.822Z" }, + { url = "https://files.pythonhosted.org/packages/2a/5f/8de95f629fc22a7769ade8b41028e3e5a822c1f8904f618d175945a81ad3/multidict-6.7.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e011555abada53f1578d63389610ac8a5400fc70ce71156b0aa30d326f1a5064", size = 246877, upload-time = "2025-10-06T14:51:27.604Z" }, + { url = "https://files.pythonhosted.org/packages/23/b4/38881a960458f25b89e9f4a4fdcb02ac101cfa710190db6e5528841e67de/multidict-6.7.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:28b37063541b897fd6a318007373930a75ca6d6ac7c940dbe14731ffdd8d498e", size = 225824, upload-time = "2025-10-06T14:51:29.664Z" }, + { url = "https://files.pythonhosted.org/packages/1e/39/6566210c83f8a261575f18e7144736059f0c460b362e96e9cf797a24b8e7/multidict-6.7.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:05047ada7a2fde2631a0ed706f1fd68b169a681dfe5e4cf0f8e4cb6618bbc2cd", size = 253558, upload-time = "2025-10-06T14:51:31.684Z" }, + { url = "https://files.pythonhosted.org/packages/00/a3/67f18315100f64c269f46e6c0319fa87ba68f0f64f2b8e7fd7c72b913a0b/multidict-6.7.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:716133f7d1d946a4e1b91b1756b23c088881e70ff180c24e864c26192ad7534a", size = 252339, upload-time = "2025-10-06T14:51:33.699Z" }, + { url = "https://files.pythonhosted.org/packages/c8/2a/1cb77266afee2458d82f50da41beba02159b1d6b1f7973afc9a1cad1499b/multidict-6.7.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d1bed1b467ef657f2a0ae62844a607909ef1c6889562de5e1d505f74457d0b96", size = 244895, upload-time = "2025-10-06T14:51:36.189Z" }, + { url = "https://files.pythonhosted.org/packages/dd/72/09fa7dd487f119b2eb9524946ddd36e2067c08510576d43ff68469563b3b/multidict-6.7.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ca43bdfa5d37bd6aee89d85e1d0831fb86e25541be7e9d376ead1b28974f8e5e", size = 241862, upload-time = "2025-10-06T14:51:41.291Z" }, + { url = "https://files.pythonhosted.org/packages/65/92/bc1f8bd0853d8669300f732c801974dfc3702c3eeadae2f60cef54dc69d7/multidict-6.7.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:44b546bd3eb645fd26fb949e43c02a25a2e632e2ca21a35e2e132c8105dc8599", size = 232376, upload-time = "2025-10-06T14:51:43.55Z" }, + { url = "https://files.pythonhosted.org/packages/09/86/ac39399e5cb9d0c2ac8ef6e10a768e4d3bc933ac808d49c41f9dc23337eb/multidict-6.7.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:a6ef16328011d3f468e7ebc326f24c1445f001ca1dec335b2f8e66bed3006394", size = 240272, upload-time = "2025-10-06T14:51:45.265Z" }, + { url = "https://files.pythonhosted.org/packages/3d/b6/fed5ac6b8563ec72df6cb1ea8dac6d17f0a4a1f65045f66b6d3bf1497c02/multidict-6.7.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:5aa873cbc8e593d361ae65c68f85faadd755c3295ea2c12040ee146802f23b38", size = 248774, upload-time = "2025-10-06T14:51:46.836Z" }, + { url = "https://files.pythonhosted.org/packages/6b/8d/b954d8c0dc132b68f760aefd45870978deec6818897389dace00fcde32ff/multidict-6.7.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:3d7b6ccce016e29df4b7ca819659f516f0bc7a4b3efa3bb2012ba06431b044f9", size = 242731, upload-time = "2025-10-06T14:51:48.541Z" }, + { url = "https://files.pythonhosted.org/packages/16/9d/a2dac7009125d3540c2f54e194829ea18ac53716c61b655d8ed300120b0f/multidict-6.7.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:171b73bd4ee683d307599b66793ac80981b06f069b62eea1c9e29c9241aa66b0", size = 240193, upload-time = "2025-10-06T14:51:50.355Z" }, + { url = "https://files.pythonhosted.org/packages/39/ca/c05f144128ea232ae2178b008d5011d4e2cea86e4ee8c85c2631b1b94802/multidict-6.7.0-cp314-cp314t-win32.whl", hash = "sha256:b2d7f80c4e1fd010b07cb26820aae86b7e73b681ee4889684fb8d2d4537aab13", size = 48023, upload-time = "2025-10-06T14:51:51.883Z" }, + { url = "https://files.pythonhosted.org/packages/ba/8f/0a60e501584145588be1af5cc829265701ba3c35a64aec8e07cbb71d39bb/multidict-6.7.0-cp314-cp314t-win_amd64.whl", hash = "sha256:09929cab6fcb68122776d575e03c6cc64ee0b8fca48d17e135474b042ce515cd", size = 53507, upload-time = "2025-10-06T14:51:53.672Z" }, + { url = "https://files.pythonhosted.org/packages/7f/ae/3148b988a9c6239903e786eac19c889fab607c31d6efa7fb2147e5680f23/multidict-6.7.0-cp314-cp314t-win_arm64.whl", hash = "sha256:cc41db090ed742f32bd2d2c721861725e6109681eddf835d0a82bd3a5c382827", size = 44804, upload-time = "2025-10-06T14:51:55.415Z" }, + { url = "https://files.pythonhosted.org/packages/b7/da/7d22601b625e241d4f23ef1ebff8acfc60da633c9e7e7922e24d10f592b3/multidict-6.7.0-py3-none-any.whl", hash = "sha256:394fc5c42a333c9ffc3e421a4c85e08580d990e08b99f6bf35b4132114c5dcb3", size = 12317, upload-time = "2025-10-06T14:52:29.272Z" }, +] + +[[package]] +name = "o2o-castad-backend" +version = "0.1.0" +source = { editable = "." } +dependencies = [ + { name = "aiofiles" }, + { name = "aiohttp" }, + { name = "aiomysql" }, + { name = "asyncmy" }, + { name = "fastapi", extra = ["standard"] }, + { name = "fastapi-cli" }, + { name = "openai" }, + { name = "pydantic-settings" }, + { name = "redis" }, + { name = "ruff" }, + { name = "scalar-fastapi" }, + { name = "sqladmin", extra = ["full"] }, + { name = "sqlalchemy", extra = ["asyncio"] }, + { name = "uuid7" }, +] + +[package.dev-dependencies] +dev = [ + { name = "pytest" }, + { name = "pytest-asyncio" }, +] + +[package.metadata] +requires-dist = [ + { name = "aiofiles", specifier = ">=25.1.0" }, + { name = "aiohttp", specifier = ">=3.13.2" }, + { name = "aiomysql", specifier = ">=0.3.2" }, + { name = "asyncmy", specifier = ">=0.2.10" }, + { name = "fastapi", extras = ["standard"], specifier = ">=0.125.0" }, + { name = "fastapi-cli", specifier = ">=0.0.16" }, + { name = "openai", specifier = ">=2.13.0" }, + { name = "pydantic-settings", specifier = ">=2.12.0" }, + { name = "redis", specifier = ">=7.1.0" }, + { name = "ruff", specifier = ">=0.14.9" }, + { name = "scalar-fastapi", specifier = ">=1.5.0" }, + { name = "sqladmin", extras = ["full"], specifier = ">=0.22.0" }, + { name = "sqlalchemy", extras = ["asyncio"], specifier = ">=2.0.45" }, + { name = "uuid7", specifier = ">=0.1.0" }, +] + +[package.metadata.requires-dev] +dev = [ + { name = "pytest", specifier = ">=9.0.2" }, + { name = "pytest-asyncio", specifier = ">=1.3.0" }, +] + +[[package]] +name = "openai" +version = "2.14.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "distro" }, + { name = "httpx" }, + { name = "jiter" }, + { name = "pydantic" }, + { name = "sniffio" }, + { name = "tqdm" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d8/b1/12fe1c196bea326261718eb037307c1c1fe1dedc2d2d4de777df822e6238/openai-2.14.0.tar.gz", hash = "sha256:419357bedde9402d23bf8f2ee372fca1985a73348debba94bddff06f19459952", size = 626938, upload-time = "2025-12-19T03:28:45.742Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/27/4b/7c1a00c2c3fbd004253937f7520f692a9650767aa73894d7a34f0d65d3f4/openai-2.14.0-py3-none-any.whl", hash = "sha256:7ea40aca4ffc4c4a776e77679021b47eec1160e341f42ae086ba949c9dcc9183", size = 1067558, upload-time = "2025-12-19T03:28:43.727Z" }, +] + +[[package]] +name = "packaging" +version = "25.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "propcache" +version = "0.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9e/da/e9fc233cf63743258bff22b3dfa7ea5baef7b5bc324af47a0ad89b8ffc6f/propcache-0.4.1.tar.gz", hash = "sha256:f48107a8c637e80362555f37ecf49abe20370e557cc4ab374f04ec4423c97c3d", size = 46442, upload-time = "2025-10-08T19:49:02.291Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bf/df/6d9c1b6ac12b003837dde8a10231a7344512186e87b36e855bef32241942/propcache-0.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:43eedf29202c08550aac1d14e0ee619b0430aaef78f85864c1a892294fbc28cf", size = 77750, upload-time = "2025-10-08T19:47:07.648Z" }, + { url = "https://files.pythonhosted.org/packages/8b/e8/677a0025e8a2acf07d3418a2e7ba529c9c33caf09d3c1f25513023c1db56/propcache-0.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d62cdfcfd89ccb8de04e0eda998535c406bf5e060ffd56be6c586cbcc05b3311", size = 44780, upload-time = "2025-10-08T19:47:08.851Z" }, + { url = "https://files.pythonhosted.org/packages/89/a4/92380f7ca60f99ebae761936bc48a72a639e8a47b29050615eef757cb2a7/propcache-0.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cae65ad55793da34db5f54e4029b89d3b9b9490d8abe1b4c7ab5d4b8ec7ebf74", size = 46308, upload-time = "2025-10-08T19:47:09.982Z" }, + { url = "https://files.pythonhosted.org/packages/2d/48/c5ac64dee5262044348d1d78a5f85dd1a57464a60d30daee946699963eb3/propcache-0.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:333ddb9031d2704a301ee3e506dc46b1fe5f294ec198ed6435ad5b6a085facfe", size = 208182, upload-time = "2025-10-08T19:47:11.319Z" }, + { url = "https://files.pythonhosted.org/packages/c6/0c/cd762dd011a9287389a6a3eb43aa30207bde253610cca06824aeabfe9653/propcache-0.4.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fd0858c20f078a32cf55f7e81473d96dcf3b93fd2ccdb3d40fdf54b8573df3af", size = 211215, upload-time = "2025-10-08T19:47:13.146Z" }, + { url = "https://files.pythonhosted.org/packages/30/3e/49861e90233ba36890ae0ca4c660e95df565b2cd15d4a68556ab5865974e/propcache-0.4.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:678ae89ebc632c5c204c794f8dab2837c5f159aeb59e6ed0539500400577298c", size = 218112, upload-time = "2025-10-08T19:47:14.913Z" }, + { url = "https://files.pythonhosted.org/packages/f1/8b/544bc867e24e1bd48f3118cecd3b05c694e160a168478fa28770f22fd094/propcache-0.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d472aeb4fbf9865e0c6d622d7f4d54a4e101a89715d8904282bb5f9a2f476c3f", size = 204442, upload-time = "2025-10-08T19:47:16.277Z" }, + { url = "https://files.pythonhosted.org/packages/50/a6/4282772fd016a76d3e5c0df58380a5ea64900afd836cec2c2f662d1b9bb3/propcache-0.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4d3df5fa7e36b3225954fba85589da77a0fe6a53e3976de39caf04a0db4c36f1", size = 199398, upload-time = "2025-10-08T19:47:17.962Z" }, + { url = "https://files.pythonhosted.org/packages/3e/ec/d8a7cd406ee1ddb705db2139f8a10a8a427100347bd698e7014351c7af09/propcache-0.4.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:ee17f18d2498f2673e432faaa71698032b0127ebf23ae5974eeaf806c279df24", size = 196920, upload-time = "2025-10-08T19:47:19.355Z" }, + { url = "https://files.pythonhosted.org/packages/f6/6c/f38ab64af3764f431e359f8baf9e0a21013e24329e8b85d2da32e8ed07ca/propcache-0.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:580e97762b950f993ae618e167e7be9256b8353c2dcd8b99ec100eb50f5286aa", size = 203748, upload-time = "2025-10-08T19:47:21.338Z" }, + { url = "https://files.pythonhosted.org/packages/d6/e3/fa846bd70f6534d647886621388f0a265254d30e3ce47e5c8e6e27dbf153/propcache-0.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:501d20b891688eb8e7aa903021f0b72d5a55db40ffaab27edefd1027caaafa61", size = 205877, upload-time = "2025-10-08T19:47:23.059Z" }, + { url = "https://files.pythonhosted.org/packages/e2/39/8163fc6f3133fea7b5f2827e8eba2029a0277ab2c5beee6c1db7b10fc23d/propcache-0.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a0bd56e5b100aef69bd8562b74b46254e7c8812918d3baa700c8a8009b0af66", size = 199437, upload-time = "2025-10-08T19:47:24.445Z" }, + { url = "https://files.pythonhosted.org/packages/93/89/caa9089970ca49c7c01662bd0eeedfe85494e863e8043565aeb6472ce8fe/propcache-0.4.1-cp313-cp313-win32.whl", hash = "sha256:bcc9aaa5d80322bc2fb24bb7accb4a30f81e90ab8d6ba187aec0744bc302ad81", size = 37586, upload-time = "2025-10-08T19:47:25.736Z" }, + { url = "https://files.pythonhosted.org/packages/f5/ab/f76ec3c3627c883215b5c8080debb4394ef5a7a29be811f786415fc1e6fd/propcache-0.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:381914df18634f5494334d201e98245c0596067504b9372d8cf93f4bb23e025e", size = 40790, upload-time = "2025-10-08T19:47:26.847Z" }, + { url = "https://files.pythonhosted.org/packages/59/1b/e71ae98235f8e2ba5004d8cb19765a74877abf189bc53fc0c80d799e56c3/propcache-0.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:8873eb4460fd55333ea49b7d189749ecf6e55bf85080f11b1c4530ed3034cba1", size = 37158, upload-time = "2025-10-08T19:47:27.961Z" }, + { url = "https://files.pythonhosted.org/packages/83/ce/a31bbdfc24ee0dcbba458c8175ed26089cf109a55bbe7b7640ed2470cfe9/propcache-0.4.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:92d1935ee1f8d7442da9c0c4fa7ac20d07e94064184811b685f5c4fada64553b", size = 81451, upload-time = "2025-10-08T19:47:29.445Z" }, + { url = "https://files.pythonhosted.org/packages/25/9c/442a45a470a68456e710d96cacd3573ef26a1d0a60067e6a7d5e655621ed/propcache-0.4.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:473c61b39e1460d386479b9b2f337da492042447c9b685f28be4f74d3529e566", size = 46374, upload-time = "2025-10-08T19:47:30.579Z" }, + { url = "https://files.pythonhosted.org/packages/f4/bf/b1d5e21dbc3b2e889ea4327044fb16312a736d97640fb8b6aa3f9c7b3b65/propcache-0.4.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:c0ef0aaafc66fbd87842a3fe3902fd889825646bc21149eafe47be6072725835", size = 48396, upload-time = "2025-10-08T19:47:31.79Z" }, + { url = "https://files.pythonhosted.org/packages/f4/04/5b4c54a103d480e978d3c8a76073502b18db0c4bc17ab91b3cb5092ad949/propcache-0.4.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f95393b4d66bfae908c3ca8d169d5f79cd65636ae15b5e7a4f6e67af675adb0e", size = 275950, upload-time = "2025-10-08T19:47:33.481Z" }, + { url = "https://files.pythonhosted.org/packages/b4/c1/86f846827fb969c4b78b0af79bba1d1ea2156492e1b83dea8b8a6ae27395/propcache-0.4.1-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c07fda85708bc48578467e85099645167a955ba093be0a2dcba962195676e859", size = 273856, upload-time = "2025-10-08T19:47:34.906Z" }, + { url = "https://files.pythonhosted.org/packages/36/1d/fc272a63c8d3bbad6878c336c7a7dea15e8f2d23a544bda43205dfa83ada/propcache-0.4.1-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:af223b406d6d000830c6f65f1e6431783fc3f713ba3e6cc8c024d5ee96170a4b", size = 280420, upload-time = "2025-10-08T19:47:36.338Z" }, + { url = "https://files.pythonhosted.org/packages/07/0c/01f2219d39f7e53d52e5173bcb09c976609ba30209912a0680adfb8c593a/propcache-0.4.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a78372c932c90ee474559c5ddfffd718238e8673c340dc21fe45c5b8b54559a0", size = 263254, upload-time = "2025-10-08T19:47:37.692Z" }, + { url = "https://files.pythonhosted.org/packages/2d/18/cd28081658ce597898f0c4d174d4d0f3c5b6d4dc27ffafeef835c95eb359/propcache-0.4.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:564d9f0d4d9509e1a870c920a89b2fec951b44bf5ba7d537a9e7c1ccec2c18af", size = 261205, upload-time = "2025-10-08T19:47:39.659Z" }, + { url = "https://files.pythonhosted.org/packages/7a/71/1f9e22eb8b8316701c2a19fa1f388c8a3185082607da8e406a803c9b954e/propcache-0.4.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:17612831fda0138059cc5546f4d12a2aacfb9e47068c06af35c400ba58ba7393", size = 247873, upload-time = "2025-10-08T19:47:41.084Z" }, + { url = "https://files.pythonhosted.org/packages/4a/65/3d4b61f36af2b4eddba9def857959f1016a51066b4f1ce348e0cf7881f58/propcache-0.4.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:41a89040cb10bd345b3c1a873b2bf36413d48da1def52f268a055f7398514874", size = 262739, upload-time = "2025-10-08T19:47:42.51Z" }, + { url = "https://files.pythonhosted.org/packages/2a/42/26746ab087faa77c1c68079b228810436ccd9a5ce9ac85e2b7307195fd06/propcache-0.4.1-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:e35b88984e7fa64aacecea39236cee32dd9bd8c55f57ba8a75cf2399553f9bd7", size = 263514, upload-time = "2025-10-08T19:47:43.927Z" }, + { url = "https://files.pythonhosted.org/packages/94/13/630690fe201f5502d2403dd3cfd451ed8858fe3c738ee88d095ad2ff407b/propcache-0.4.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f8b465489f927b0df505cbe26ffbeed4d6d8a2bbc61ce90eb074ff129ef0ab1", size = 257781, upload-time = "2025-10-08T19:47:45.448Z" }, + { url = "https://files.pythonhosted.org/packages/92/f7/1d4ec5841505f423469efbfc381d64b7b467438cd5a4bbcbb063f3b73d27/propcache-0.4.1-cp313-cp313t-win32.whl", hash = "sha256:2ad890caa1d928c7c2965b48f3a3815c853180831d0e5503d35cf00c472f4717", size = 41396, upload-time = "2025-10-08T19:47:47.202Z" }, + { url = "https://files.pythonhosted.org/packages/48/f0/615c30622316496d2cbbc29f5985f7777d3ada70f23370608c1d3e081c1f/propcache-0.4.1-cp313-cp313t-win_amd64.whl", hash = "sha256:f7ee0e597f495cf415bcbd3da3caa3bd7e816b74d0d52b8145954c5e6fd3ff37", size = 44897, upload-time = "2025-10-08T19:47:48.336Z" }, + { url = "https://files.pythonhosted.org/packages/fd/ca/6002e46eccbe0e33dcd4069ef32f7f1c9e243736e07adca37ae8c4830ec3/propcache-0.4.1-cp313-cp313t-win_arm64.whl", hash = "sha256:929d7cbe1f01bb7baffb33dc14eb5691c95831450a26354cd210a8155170c93a", size = 39789, upload-time = "2025-10-08T19:47:49.876Z" }, + { url = "https://files.pythonhosted.org/packages/8e/5c/bca52d654a896f831b8256683457ceddd490ec18d9ec50e97dfd8fc726a8/propcache-0.4.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3f7124c9d820ba5548d431afb4632301acf965db49e666aa21c305cbe8c6de12", size = 78152, upload-time = "2025-10-08T19:47:51.051Z" }, + { url = "https://files.pythonhosted.org/packages/65/9b/03b04e7d82a5f54fb16113d839f5ea1ede58a61e90edf515f6577c66fa8f/propcache-0.4.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:c0d4b719b7da33599dfe3b22d3db1ef789210a0597bc650b7cee9c77c2be8c5c", size = 44869, upload-time = "2025-10-08T19:47:52.594Z" }, + { url = "https://files.pythonhosted.org/packages/b2/fa/89a8ef0468d5833a23fff277b143d0573897cf75bd56670a6d28126c7d68/propcache-0.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:9f302f4783709a78240ebc311b793f123328716a60911d667e0c036bc5dcbded", size = 46596, upload-time = "2025-10-08T19:47:54.073Z" }, + { url = "https://files.pythonhosted.org/packages/86/bd/47816020d337f4a746edc42fe8d53669965138f39ee117414c7d7a340cfe/propcache-0.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c80ee5802e3fb9ea37938e7eecc307fb984837091d5fd262bb37238b1ae97641", size = 206981, upload-time = "2025-10-08T19:47:55.715Z" }, + { url = "https://files.pythonhosted.org/packages/df/f6/c5fa1357cc9748510ee55f37173eb31bfde6d94e98ccd9e6f033f2fc06e1/propcache-0.4.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ed5a841e8bb29a55fb8159ed526b26adc5bdd7e8bd7bf793ce647cb08656cdf4", size = 211490, upload-time = "2025-10-08T19:47:57.499Z" }, + { url = "https://files.pythonhosted.org/packages/80/1e/e5889652a7c4a3846683401a48f0f2e5083ce0ec1a8a5221d8058fbd1adf/propcache-0.4.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:55c72fd6ea2da4c318e74ffdf93c4fe4e926051133657459131a95c846d16d44", size = 215371, upload-time = "2025-10-08T19:47:59.317Z" }, + { url = "https://files.pythonhosted.org/packages/b2/f2/889ad4b2408f72fe1a4f6a19491177b30ea7bf1a0fd5f17050ca08cfc882/propcache-0.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8326e144341460402713f91df60ade3c999d601e7eb5ff8f6f7862d54de0610d", size = 201424, upload-time = "2025-10-08T19:48:00.67Z" }, + { url = "https://files.pythonhosted.org/packages/27/73/033d63069b57b0812c8bd19f311faebeceb6ba31b8f32b73432d12a0b826/propcache-0.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:060b16ae65bc098da7f6d25bf359f1f31f688384858204fe5d652979e0015e5b", size = 197566, upload-time = "2025-10-08T19:48:02.604Z" }, + { url = "https://files.pythonhosted.org/packages/dc/89/ce24f3dc182630b4e07aa6d15f0ff4b14ed4b9955fae95a0b54c58d66c05/propcache-0.4.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:89eb3fa9524f7bec9de6e83cf3faed9d79bffa560672c118a96a171a6f55831e", size = 193130, upload-time = "2025-10-08T19:48:04.499Z" }, + { url = "https://files.pythonhosted.org/packages/a9/24/ef0d5fd1a811fb5c609278d0209c9f10c35f20581fcc16f818da959fc5b4/propcache-0.4.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:dee69d7015dc235f526fe80a9c90d65eb0039103fe565776250881731f06349f", size = 202625, upload-time = "2025-10-08T19:48:06.213Z" }, + { url = "https://files.pythonhosted.org/packages/f5/02/98ec20ff5546f68d673df2f7a69e8c0d076b5abd05ca882dc7ee3a83653d/propcache-0.4.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:5558992a00dfd54ccbc64a32726a3357ec93825a418a401f5cc67df0ac5d9e49", size = 204209, upload-time = "2025-10-08T19:48:08.432Z" }, + { url = "https://files.pythonhosted.org/packages/a0/87/492694f76759b15f0467a2a93ab68d32859672b646aa8a04ce4864e7932d/propcache-0.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c9b822a577f560fbd9554812526831712c1436d2c046cedee4c3796d3543b144", size = 197797, upload-time = "2025-10-08T19:48:09.968Z" }, + { url = "https://files.pythonhosted.org/packages/ee/36/66367de3575db1d2d3f3d177432bd14ee577a39d3f5d1b3d5df8afe3b6e2/propcache-0.4.1-cp314-cp314-win32.whl", hash = "sha256:ab4c29b49d560fe48b696cdcb127dd36e0bc2472548f3bf56cc5cb3da2b2984f", size = 38140, upload-time = "2025-10-08T19:48:11.232Z" }, + { url = "https://files.pythonhosted.org/packages/0c/2a/a758b47de253636e1b8aef181c0b4f4f204bf0dd964914fb2af90a95b49b/propcache-0.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:5a103c3eb905fcea0ab98be99c3a9a5ab2de60228aa5aceedc614c0281cf6153", size = 41257, upload-time = "2025-10-08T19:48:12.707Z" }, + { url = "https://files.pythonhosted.org/packages/34/5e/63bd5896c3fec12edcbd6f12508d4890d23c265df28c74b175e1ef9f4f3b/propcache-0.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:74c1fb26515153e482e00177a1ad654721bf9207da8a494a0c05e797ad27b992", size = 38097, upload-time = "2025-10-08T19:48:13.923Z" }, + { url = "https://files.pythonhosted.org/packages/99/85/9ff785d787ccf9bbb3f3106f79884a130951436f58392000231b4c737c80/propcache-0.4.1-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:824e908bce90fb2743bd6b59db36eb4f45cd350a39637c9f73b1c1ea66f5b75f", size = 81455, upload-time = "2025-10-08T19:48:15.16Z" }, + { url = "https://files.pythonhosted.org/packages/90/85/2431c10c8e7ddb1445c1f7c4b54d886e8ad20e3c6307e7218f05922cad67/propcache-0.4.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:c2b5e7db5328427c57c8e8831abda175421b709672f6cfc3d630c3b7e2146393", size = 46372, upload-time = "2025-10-08T19:48:16.424Z" }, + { url = "https://files.pythonhosted.org/packages/01/20/b0972d902472da9bcb683fa595099911f4d2e86e5683bcc45de60dd05dc3/propcache-0.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6f6ff873ed40292cd4969ef5310179afd5db59fdf055897e282485043fc80ad0", size = 48411, upload-time = "2025-10-08T19:48:17.577Z" }, + { url = "https://files.pythonhosted.org/packages/e2/e3/7dc89f4f21e8f99bad3d5ddb3a3389afcf9da4ac69e3deb2dcdc96e74169/propcache-0.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:49a2dc67c154db2c1463013594c458881a069fcf98940e61a0569016a583020a", size = 275712, upload-time = "2025-10-08T19:48:18.901Z" }, + { url = "https://files.pythonhosted.org/packages/20/67/89800c8352489b21a8047c773067644e3897f02ecbbd610f4d46b7f08612/propcache-0.4.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:005f08e6a0529984491e37d8dbc3dd86f84bd78a8ceb5fa9a021f4c48d4984be", size = 273557, upload-time = "2025-10-08T19:48:20.762Z" }, + { url = "https://files.pythonhosted.org/packages/e2/a1/b52b055c766a54ce6d9c16d9aca0cad8059acd9637cdf8aa0222f4a026ef/propcache-0.4.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5c3310452e0d31390da9035c348633b43d7e7feb2e37be252be6da45abd1abcc", size = 280015, upload-time = "2025-10-08T19:48:22.592Z" }, + { url = "https://files.pythonhosted.org/packages/48/c8/33cee30bd890672c63743049f3c9e4be087e6780906bfc3ec58528be59c1/propcache-0.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c3c70630930447f9ef1caac7728c8ad1c56bc5015338b20fed0d08ea2480b3a", size = 262880, upload-time = "2025-10-08T19:48:23.947Z" }, + { url = "https://files.pythonhosted.org/packages/0c/b1/8f08a143b204b418285c88b83d00edbd61afbc2c6415ffafc8905da7038b/propcache-0.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8e57061305815dfc910a3634dcf584f08168a8836e6999983569f51a8544cd89", size = 260938, upload-time = "2025-10-08T19:48:25.656Z" }, + { url = "https://files.pythonhosted.org/packages/cf/12/96e4664c82ca2f31e1c8dff86afb867348979eb78d3cb8546a680287a1e9/propcache-0.4.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:521a463429ef54143092c11a77e04056dd00636f72e8c45b70aaa3140d639726", size = 247641, upload-time = "2025-10-08T19:48:27.207Z" }, + { url = "https://files.pythonhosted.org/packages/18/ed/e7a9cfca28133386ba52278136d42209d3125db08d0a6395f0cba0c0285c/propcache-0.4.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:120c964da3fdc75e3731aa392527136d4ad35868cc556fd09bb6d09172d9a367", size = 262510, upload-time = "2025-10-08T19:48:28.65Z" }, + { url = "https://files.pythonhosted.org/packages/f5/76/16d8bf65e8845dd62b4e2b57444ab81f07f40caa5652b8969b87ddcf2ef6/propcache-0.4.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:d8f353eb14ee3441ee844ade4277d560cdd68288838673273b978e3d6d2c8f36", size = 263161, upload-time = "2025-10-08T19:48:30.133Z" }, + { url = "https://files.pythonhosted.org/packages/e7/70/c99e9edb5d91d5ad8a49fa3c1e8285ba64f1476782fed10ab251ff413ba1/propcache-0.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ab2943be7c652f09638800905ee1bab2c544e537edb57d527997a24c13dc1455", size = 257393, upload-time = "2025-10-08T19:48:31.567Z" }, + { url = "https://files.pythonhosted.org/packages/08/02/87b25304249a35c0915d236575bc3574a323f60b47939a2262b77632a3ee/propcache-0.4.1-cp314-cp314t-win32.whl", hash = "sha256:05674a162469f31358c30bcaa8883cb7829fa3110bf9c0991fe27d7896c42d85", size = 42546, upload-time = "2025-10-08T19:48:32.872Z" }, + { url = "https://files.pythonhosted.org/packages/cb/ef/3c6ecf8b317aa982f309835e8f96987466123c6e596646d4e6a1dfcd080f/propcache-0.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:990f6b3e2a27d683cb7602ed6c86f15ee6b43b1194736f9baaeb93d0016633b1", size = 46259, upload-time = "2025-10-08T19:48:34.226Z" }, + { url = "https://files.pythonhosted.org/packages/c4/2d/346e946d4951f37eca1e4f55be0f0174c52cd70720f84029b02f296f4a38/propcache-0.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:ecef2343af4cc68e05131e45024ba34f6095821988a9d0a02aa7c73fcc448aa9", size = 40428, upload-time = "2025-10-08T19:48:35.441Z" }, + { url = "https://files.pythonhosted.org/packages/5b/5a/bc7b4a4ef808fa59a816c17b20c4bef6884daebbdf627ff2a161da67da19/propcache-0.4.1-py3-none-any.whl", hash = "sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237", size = 13305, upload-time = "2025-10-08T19:49:00.792Z" }, +] + +[[package]] +name = "pydantic" +version = "2.12.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-types" }, + { name = "pydantic-core" }, + { name = "typing-extensions" }, + { name = "typing-inspection" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/69/44/36f1a6e523abc58ae5f928898e4aca2e0ea509b5aa6f6f392a5d882be928/pydantic-2.12.5.tar.gz", hash = "sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49", size = 821591, upload-time = "2025-11-26T15:11:46.471Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl", hash = "sha256:e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d", size = 463580, upload-time = "2025-11-26T15:11:44.605Z" }, +] + +[package.optional-dependencies] +email = [ + { name = "email-validator" }, +] + +[[package]] +name = "pydantic-core" +version = "2.41.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/71/70/23b021c950c2addd24ec408e9ab05d59b035b39d97cdc1130e1bce647bb6/pydantic_core-2.41.5.tar.gz", hash = "sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e", size = 460952, upload-time = "2025-11-04T13:43:49.098Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/87/06/8806241ff1f70d9939f9af039c6c35f2360cf16e93c2ca76f184e76b1564/pydantic_core-2.41.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:941103c9be18ac8daf7b7adca8228f8ed6bb7a1849020f643b3a14d15b1924d9", size = 2120403, upload-time = "2025-11-04T13:40:25.248Z" }, + { url = "https://files.pythonhosted.org/packages/94/02/abfa0e0bda67faa65fef1c84971c7e45928e108fe24333c81f3bfe35d5f5/pydantic_core-2.41.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:112e305c3314f40c93998e567879e887a3160bb8689ef3d2c04b6cc62c33ac34", size = 1896206, upload-time = "2025-11-04T13:40:27.099Z" }, + { url = "https://files.pythonhosted.org/packages/15/df/a4c740c0943e93e6500f9eb23f4ca7ec9bf71b19e608ae5b579678c8d02f/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cbaad15cb0c90aa221d43c00e77bb33c93e8d36e0bf74760cd00e732d10a6a0", size = 1919307, upload-time = "2025-11-04T13:40:29.806Z" }, + { url = "https://files.pythonhosted.org/packages/9a/e3/6324802931ae1d123528988e0e86587c2072ac2e5394b4bc2bc34b61ff6e/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:03ca43e12fab6023fc79d28ca6b39b05f794ad08ec2feccc59a339b02f2b3d33", size = 2063258, upload-time = "2025-11-04T13:40:33.544Z" }, + { url = "https://files.pythonhosted.org/packages/c9/d4/2230d7151d4957dd79c3044ea26346c148c98fbf0ee6ebd41056f2d62ab5/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc799088c08fa04e43144b164feb0c13f9a0bc40503f8df3e9fde58a3c0c101e", size = 2214917, upload-time = "2025-11-04T13:40:35.479Z" }, + { url = "https://files.pythonhosted.org/packages/e6/9f/eaac5df17a3672fef0081b6c1bb0b82b33ee89aa5cec0d7b05f52fd4a1fa/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:97aeba56665b4c3235a0e52b2c2f5ae9cd071b8a8310ad27bddb3f7fb30e9aa2", size = 2332186, upload-time = "2025-11-04T13:40:37.436Z" }, + { url = "https://files.pythonhosted.org/packages/cf/4e/35a80cae583a37cf15604b44240e45c05e04e86f9cfd766623149297e971/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:406bf18d345822d6c21366031003612b9c77b3e29ffdb0f612367352aab7d586", size = 2073164, upload-time = "2025-11-04T13:40:40.289Z" }, + { url = "https://files.pythonhosted.org/packages/bf/e3/f6e262673c6140dd3305d144d032f7bd5f7497d3871c1428521f19f9efa2/pydantic_core-2.41.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b93590ae81f7010dbe380cdeab6f515902ebcbefe0b9327cc4804d74e93ae69d", size = 2179146, upload-time = "2025-11-04T13:40:42.809Z" }, + { url = "https://files.pythonhosted.org/packages/75/c7/20bd7fc05f0c6ea2056a4565c6f36f8968c0924f19b7d97bbfea55780e73/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:01a3d0ab748ee531f4ea6c3e48ad9dac84ddba4b0d82291f87248f2f9de8d740", size = 2137788, upload-time = "2025-11-04T13:40:44.752Z" }, + { url = "https://files.pythonhosted.org/packages/3a/8d/34318ef985c45196e004bc46c6eab2eda437e744c124ef0dbe1ff2c9d06b/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:6561e94ba9dacc9c61bce40e2d6bdc3bfaa0259d3ff36ace3b1e6901936d2e3e", size = 2340133, upload-time = "2025-11-04T13:40:46.66Z" }, + { url = "https://files.pythonhosted.org/packages/9c/59/013626bf8c78a5a5d9350d12e7697d3d4de951a75565496abd40ccd46bee/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:915c3d10f81bec3a74fbd4faebe8391013ba61e5a1a8d48c4455b923bdda7858", size = 2324852, upload-time = "2025-11-04T13:40:48.575Z" }, + { url = "https://files.pythonhosted.org/packages/1a/d9/c248c103856f807ef70c18a4f986693a46a8ffe1602e5d361485da502d20/pydantic_core-2.41.5-cp313-cp313-win32.whl", hash = "sha256:650ae77860b45cfa6e2cdafc42618ceafab3a2d9a3811fcfbd3bbf8ac3c40d36", size = 1994679, upload-time = "2025-11-04T13:40:50.619Z" }, + { url = "https://files.pythonhosted.org/packages/9e/8b/341991b158ddab181cff136acd2552c9f35bd30380422a639c0671e99a91/pydantic_core-2.41.5-cp313-cp313-win_amd64.whl", hash = "sha256:79ec52ec461e99e13791ec6508c722742ad745571f234ea6255bed38c6480f11", size = 2019766, upload-time = "2025-11-04T13:40:52.631Z" }, + { url = "https://files.pythonhosted.org/packages/73/7d/f2f9db34af103bea3e09735bb40b021788a5e834c81eedb541991badf8f5/pydantic_core-2.41.5-cp313-cp313-win_arm64.whl", hash = "sha256:3f84d5c1b4ab906093bdc1ff10484838aca54ef08de4afa9de0f5f14d69639cd", size = 1981005, upload-time = "2025-11-04T13:40:54.734Z" }, + { url = "https://files.pythonhosted.org/packages/ea/28/46b7c5c9635ae96ea0fbb779e271a38129df2550f763937659ee6c5dbc65/pydantic_core-2.41.5-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a", size = 2119622, upload-time = "2025-11-04T13:40:56.68Z" }, + { url = "https://files.pythonhosted.org/packages/74/1a/145646e5687e8d9a1e8d09acb278c8535ebe9e972e1f162ed338a622f193/pydantic_core-2.41.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14", size = 1891725, upload-time = "2025-11-04T13:40:58.807Z" }, + { url = "https://files.pythonhosted.org/packages/23/04/e89c29e267b8060b40dca97bfc64a19b2a3cf99018167ea1677d96368273/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25e1c2af0fce638d5f1988b686f3b3ea8cd7de5f244ca147c777769e798a9cd1", size = 1915040, upload-time = "2025-11-04T13:41:00.853Z" }, + { url = "https://files.pythonhosted.org/packages/84/a3/15a82ac7bd97992a82257f777b3583d3e84bdb06ba6858f745daa2ec8a85/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:506d766a8727beef16b7adaeb8ee6217c64fc813646b424d0804d67c16eddb66", size = 2063691, upload-time = "2025-11-04T13:41:03.504Z" }, + { url = "https://files.pythonhosted.org/packages/74/9b/0046701313c6ef08c0c1cf0e028c67c770a4e1275ca73131563c5f2a310a/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4819fa52133c9aa3c387b3328f25c1facc356491e6135b459f1de698ff64d869", size = 2213897, upload-time = "2025-11-04T13:41:05.804Z" }, + { url = "https://files.pythonhosted.org/packages/8a/cd/6bac76ecd1b27e75a95ca3a9a559c643b3afcd2dd62086d4b7a32a18b169/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b761d210c9ea91feda40d25b4efe82a1707da2ef62901466a42492c028553a2", size = 2333302, upload-time = "2025-11-04T13:41:07.809Z" }, + { url = "https://files.pythonhosted.org/packages/4c/d2/ef2074dc020dd6e109611a8be4449b98cd25e1b9b8a303c2f0fca2f2bcf7/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375", size = 2064877, upload-time = "2025-11-04T13:41:09.827Z" }, + { url = "https://files.pythonhosted.org/packages/18/66/e9db17a9a763d72f03de903883c057b2592c09509ccfe468187f2a2eef29/pydantic_core-2.41.5-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2782c870e99878c634505236d81e5443092fba820f0373997ff75f90f68cd553", size = 2180680, upload-time = "2025-11-04T13:41:12.379Z" }, + { url = "https://files.pythonhosted.org/packages/d3/9e/3ce66cebb929f3ced22be85d4c2399b8e85b622db77dad36b73c5387f8f8/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:0177272f88ab8312479336e1d777f6b124537d47f2123f89cb37e0accea97f90", size = 2138960, upload-time = "2025-11-04T13:41:14.627Z" }, + { url = "https://files.pythonhosted.org/packages/a6/62/205a998f4327d2079326b01abee48e502ea739d174f0a89295c481a2272e/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:63510af5e38f8955b8ee5687740d6ebf7c2a0886d15a6d65c32814613681bc07", size = 2339102, upload-time = "2025-11-04T13:41:16.868Z" }, + { url = "https://files.pythonhosted.org/packages/3c/0d/f05e79471e889d74d3d88f5bd20d0ed189ad94c2423d81ff8d0000aab4ff/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:e56ba91f47764cc14f1daacd723e3e82d1a89d783f0f5afe9c364b8bb491ccdb", size = 2326039, upload-time = "2025-11-04T13:41:18.934Z" }, + { url = "https://files.pythonhosted.org/packages/ec/e1/e08a6208bb100da7e0c4b288eed624a703f4d129bde2da475721a80cab32/pydantic_core-2.41.5-cp314-cp314-win32.whl", hash = "sha256:aec5cf2fd867b4ff45b9959f8b20ea3993fc93e63c7363fe6851424c8a7e7c23", size = 1995126, upload-time = "2025-11-04T13:41:21.418Z" }, + { url = "https://files.pythonhosted.org/packages/48/5d/56ba7b24e9557f99c9237e29f5c09913c81eeb2f3217e40e922353668092/pydantic_core-2.41.5-cp314-cp314-win_amd64.whl", hash = "sha256:8e7c86f27c585ef37c35e56a96363ab8de4e549a95512445b85c96d3e2f7c1bf", size = 2015489, upload-time = "2025-11-04T13:41:24.076Z" }, + { url = "https://files.pythonhosted.org/packages/4e/bb/f7a190991ec9e3e0ba22e4993d8755bbc4a32925c0b5b42775c03e8148f9/pydantic_core-2.41.5-cp314-cp314-win_arm64.whl", hash = "sha256:e672ba74fbc2dc8eea59fb6d4aed6845e6905fc2a8afe93175d94a83ba2a01a0", size = 1977288, upload-time = "2025-11-04T13:41:26.33Z" }, + { url = "https://files.pythonhosted.org/packages/92/ed/77542d0c51538e32e15afe7899d79efce4b81eee631d99850edc2f5e9349/pydantic_core-2.41.5-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:8566def80554c3faa0e65ac30ab0932b9e3a5cd7f8323764303d468e5c37595a", size = 2120255, upload-time = "2025-11-04T13:41:28.569Z" }, + { url = "https://files.pythonhosted.org/packages/bb/3d/6913dde84d5be21e284439676168b28d8bbba5600d838b9dca99de0fad71/pydantic_core-2.41.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b80aa5095cd3109962a298ce14110ae16b8c1aece8b72f9dafe81cf597ad80b3", size = 1863760, upload-time = "2025-11-04T13:41:31.055Z" }, + { url = "https://files.pythonhosted.org/packages/5a/f0/e5e6b99d4191da102f2b0eb9687aaa7f5bea5d9964071a84effc3e40f997/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3006c3dd9ba34b0c094c544c6006cc79e87d8612999f1a5d43b769b89181f23c", size = 1878092, upload-time = "2025-11-04T13:41:33.21Z" }, + { url = "https://files.pythonhosted.org/packages/71/48/36fb760642d568925953bcc8116455513d6e34c4beaa37544118c36aba6d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:72f6c8b11857a856bcfa48c86f5368439f74453563f951e473514579d44aa612", size = 2053385, upload-time = "2025-11-04T13:41:35.508Z" }, + { url = "https://files.pythonhosted.org/packages/20/25/92dc684dd8eb75a234bc1c764b4210cf2646479d54b47bf46061657292a8/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5cb1b2f9742240e4bb26b652a5aeb840aa4b417c7748b6f8387927bc6e45e40d", size = 2218832, upload-time = "2025-11-04T13:41:37.732Z" }, + { url = "https://files.pythonhosted.org/packages/e2/09/f53e0b05023d3e30357d82eb35835d0f6340ca344720a4599cd663dca599/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bd3d54f38609ff308209bd43acea66061494157703364ae40c951f83ba99a1a9", size = 2327585, upload-time = "2025-11-04T13:41:40Z" }, + { url = "https://files.pythonhosted.org/packages/aa/4e/2ae1aa85d6af35a39b236b1b1641de73f5a6ac4d5a7509f77b814885760c/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ff4321e56e879ee8d2a879501c8e469414d948f4aba74a2d4593184eb326660", size = 2041078, upload-time = "2025-11-04T13:41:42.323Z" }, + { url = "https://files.pythonhosted.org/packages/cd/13/2e215f17f0ef326fc72afe94776edb77525142c693767fc347ed6288728d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d0d2568a8c11bf8225044aa94409e21da0cb09dcdafe9ecd10250b2baad531a9", size = 2173914, upload-time = "2025-11-04T13:41:45.221Z" }, + { url = "https://files.pythonhosted.org/packages/02/7a/f999a6dcbcd0e5660bc348a3991c8915ce6599f4f2c6ac22f01d7a10816c/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:a39455728aabd58ceabb03c90e12f71fd30fa69615760a075b9fec596456ccc3", size = 2129560, upload-time = "2025-11-04T13:41:47.474Z" }, + { url = "https://files.pythonhosted.org/packages/3a/b1/6c990ac65e3b4c079a4fb9f5b05f5b013afa0f4ed6780a3dd236d2cbdc64/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:239edca560d05757817c13dc17c50766136d21f7cd0fac50295499ae24f90fdf", size = 2329244, upload-time = "2025-11-04T13:41:49.992Z" }, + { url = "https://files.pythonhosted.org/packages/d9/02/3c562f3a51afd4d88fff8dffb1771b30cfdfd79befd9883ee094f5b6c0d8/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:2a5e06546e19f24c6a96a129142a75cee553cc018ffee48a460059b1185f4470", size = 2331955, upload-time = "2025-11-04T13:41:54.079Z" }, + { url = "https://files.pythonhosted.org/packages/5c/96/5fb7d8c3c17bc8c62fdb031c47d77a1af698f1d7a406b0f79aaa1338f9ad/pydantic_core-2.41.5-cp314-cp314t-win32.whl", hash = "sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa", size = 1988906, upload-time = "2025-11-04T13:41:56.606Z" }, + { url = "https://files.pythonhosted.org/packages/22/ed/182129d83032702912c2e2d8bbe33c036f342cc735737064668585dac28f/pydantic_core-2.41.5-cp314-cp314t-win_amd64.whl", hash = "sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c", size = 1981607, upload-time = "2025-11-04T13:41:58.889Z" }, + { url = "https://files.pythonhosted.org/packages/9f/ed/068e41660b832bb0b1aa5b58011dea2a3fe0ba7861ff38c4d4904c1c1a99/pydantic_core-2.41.5-cp314-cp314t-win_arm64.whl", hash = "sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008", size = 1974769, upload-time = "2025-11-04T13:42:01.186Z" }, +] + +[[package]] +name = "pydantic-settings" +version = "2.12.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pydantic" }, + { name = "python-dotenv" }, + { name = "typing-inspection" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/43/4b/ac7e0aae12027748076d72a8764ff1c9d82ca75a7a52622e67ed3f765c54/pydantic_settings-2.12.0.tar.gz", hash = "sha256:005538ef951e3c2a68e1c08b292b5f2e71490def8589d4221b95dab00dafcfd0", size = 194184, upload-time = "2025-11-10T14:25:47.013Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c1/60/5d4751ba3f4a40a6891f24eec885f51afd78d208498268c734e256fb13c4/pydantic_settings-2.12.0-py3-none-any.whl", hash = "sha256:fddb9fd99a5b18da837b29710391e945b1e30c135477f484084ee513adb93809", size = 51880, upload-time = "2025-11-10T14:25:45.546Z" }, +] + +[[package]] +name = "pygments" +version = "2.19.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, +] + +[[package]] +name = "pymysql" +version = "1.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f5/ae/1fe3fcd9f959efa0ebe200b8de88b5a5ce3e767e38c7ac32fb179f16a388/pymysql-1.1.2.tar.gz", hash = "sha256:4961d3e165614ae65014e361811a724e2044ad3ea3739de9903ae7c21f539f03", size = 48258, upload-time = "2025-08-24T12:55:55.146Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7c/4c/ad33b92b9864cbde84f259d5df035a6447f91891f5be77788e2a3892bce3/pymysql-1.1.2-py3-none-any.whl", hash = "sha256:e6b1d89711dd51f8f74b1631fe08f039e7d76cf67a42a323d3178f0f25762ed9", size = 45300, upload-time = "2025-08-24T12:55:53.394Z" }, +] + +[[package]] +name = "pytest" +version = "9.0.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d1/db/7ef3487e0fb0049ddb5ce41d3a49c235bf9ad299b6a25d5780a89f19230f/pytest-9.0.2.tar.gz", hash = "sha256:75186651a92bd89611d1d9fc20f0b4345fd827c41ccd5c299a868a05d70edf11", size = 1568901, upload-time = "2025-12-06T21:30:51.014Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl", hash = "sha256:711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b", size = 374801, upload-time = "2025-12-06T21:30:49.154Z" }, +] + +[[package]] +name = "pytest-asyncio" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/90/2c/8af215c0f776415f3590cac4f9086ccefd6fd463befeae41cd4d3f193e5a/pytest_asyncio-1.3.0.tar.gz", hash = "sha256:d7f52f36d231b80ee124cd216ffb19369aa168fc10095013c6b014a34d3ee9e5", size = 50087, upload-time = "2025-11-10T16:07:47.256Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e5/35/f8b19922b6a25bc0880171a2f1a003eaeb93657475193ab516fd87cac9da/pytest_asyncio-1.3.0-py3-none-any.whl", hash = "sha256:611e26147c7f77640e6d0a92a38ed17c3e9848063698d5c93d5aa7aa11cebff5", size = 15075, upload-time = "2025-11-10T16:07:45.537Z" }, +] + +[[package]] +name = "python-dotenv" +version = "1.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f0/26/19cadc79a718c5edbec86fd4919a6b6d3f681039a2f6d66d14be94e75fb9/python_dotenv-1.2.1.tar.gz", hash = "sha256:42667e897e16ab0d66954af0e60a9caa94f0fd4ecf3aaf6d2d260eec1aa36ad6", size = 44221, upload-time = "2025-10-26T15:12:10.434Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/14/1b/a298b06749107c305e1fe0f814c6c74aea7b2f1e10989cb30f544a1b3253/python_dotenv-1.2.1-py3-none-any.whl", hash = "sha256:b81ee9561e9ca4004139c6cbba3a238c32b03e4894671e181b671e8cb8425d61", size = 21230, upload-time = "2025-10-26T15:12:09.109Z" }, +] + +[[package]] +name = "python-multipart" +version = "0.0.21" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/78/96/804520d0850c7db98e5ccb70282e29208723f0964e88ffd9d0da2f52ea09/python_multipart-0.0.21.tar.gz", hash = "sha256:7137ebd4d3bbf70ea1622998f902b97a29434a9e8dc40eb203bbcf7c2a2cba92", size = 37196, upload-time = "2025-12-17T09:24:22.446Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/aa/76/03af049af4dcee5d27442f71b6924f01f3efb5d2bd34f23fcd563f2cc5f5/python_multipart-0.0.21-py3-none-any.whl", hash = "sha256:cf7a6713e01c87aa35387f4774e812c4361150938d20d232800f75ffcf266090", size = 24541, upload-time = "2025-12-17T09:24:21.153Z" }, +] + +[[package]] +name = "pyyaml" +version = "6.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, + { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, + { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, + { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, + { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, + { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, + { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, + { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, + { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, + { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, + { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, + { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, + { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" }, + { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" }, + { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" }, + { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" }, + { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" }, + { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" }, + { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" }, + { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" }, + { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" }, + { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, + { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, +] + +[[package]] +name = "redis" +version = "7.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/c8/983d5c6579a411d8a99bc5823cc5712768859b5ce2c8afe1a65b37832c81/redis-7.1.0.tar.gz", hash = "sha256:b1cc3cfa5a2cb9c2ab3ba700864fb0ad75617b41f01352ce5779dabf6d5f9c3c", size = 4796669, upload-time = "2025-11-19T15:54:39.961Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/89/f0/8956f8a86b20d7bb9d6ac0187cf4cd54d8065bc9a1a09eb8011d4d326596/redis-7.1.0-py3-none-any.whl", hash = "sha256:23c52b208f92b56103e17c5d06bdc1a6c2c0b3106583985a76a18f83b265de2b", size = 354159, upload-time = "2025-11-19T15:54:38.064Z" }, +] + +[[package]] +name = "rich" +version = "14.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fb/d2/8920e102050a0de7bfabeb4c4614a49248cf8d5d7a8d01885fbb24dc767a/rich-14.2.0.tar.gz", hash = "sha256:73ff50c7c0c1c77c8243079283f4edb376f0f6442433aecb8ce7e6d0b92d1fe4", size = 219990, upload-time = "2025-10-09T14:16:53.064Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/25/7a/b0178788f8dc6cafce37a212c99565fa1fe7872c70c6c9c1e1a372d9d88f/rich-14.2.0-py3-none-any.whl", hash = "sha256:76bc51fe2e57d2b1be1f96c524b890b816e334ab4c1e45888799bfaab0021edd", size = 243393, upload-time = "2025-10-09T14:16:51.245Z" }, +] + +[[package]] +name = "rich-toolkit" +version = "0.17.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "rich" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/97/09/3f9b8d9daaf235195c626f21e03604c05b987404ee3bcacee0c1f67f2a8e/rich_toolkit-0.17.1.tar.gz", hash = "sha256:5af54df8d1dd9c8530e462e1bdcaed625c9b49f5a55b035aa0ba1c17bdb87c9a", size = 187925, upload-time = "2025-12-17T10:49:22.583Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7f/7b/15e55fa8a76d0d41bf34d965af78acdaf80a315907adb30de8b63c272694/rich_toolkit-0.17.1-py3-none-any.whl", hash = "sha256:96d24bb921ecd225ffce7c526a9149e74006410c05e6d405bd74ffd54d5631ed", size = 31412, upload-time = "2025-12-17T10:49:21.793Z" }, +] + +[[package]] +name = "rignore" +version = "0.7.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e5/f5/8bed2310abe4ae04b67a38374a4d311dd85220f5d8da56f47ae9361be0b0/rignore-0.7.6.tar.gz", hash = "sha256:00d3546cd793c30cb17921ce674d2c8f3a4b00501cb0e3dd0e82217dbeba2671", size = 57140, upload-time = "2025-11-05T21:41:21.968Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/8a/a4078f6e14932ac7edb171149c481de29969d96ddee3ece5dc4c26f9e0c3/rignore-0.7.6-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:2bdab1d31ec9b4fb1331980ee49ea051c0d7f7bb6baa28b3125ef03cdc48fdaf", size = 883057, upload-time = "2025-11-05T20:42:42.741Z" }, + { url = "https://files.pythonhosted.org/packages/f9/8f/f8daacd177db4bf7c2223bab41e630c52711f8af9ed279be2058d2fe4982/rignore-0.7.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:90f0a00ce0c866c275bf888271f1dc0d2140f29b82fcf33cdbda1e1a6af01010", size = 820150, upload-time = "2025-11-05T20:42:26.545Z" }, + { url = "https://files.pythonhosted.org/packages/36/31/b65b837e39c3f7064c426754714ac633b66b8c2290978af9d7f513e14aa9/rignore-0.7.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1ad295537041dc2ed4b540fb1a3906bd9ede6ccdad3fe79770cd89e04e3c73c", size = 897406, upload-time = "2025-11-05T20:40:53.854Z" }, + { url = "https://files.pythonhosted.org/packages/ca/58/1970ce006c427e202ac7c081435719a076c478f07b3a23f469227788dc23/rignore-0.7.6-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f782dbd3a65a5ac85adfff69e5c6b101285ef3f845c3a3cae56a54bebf9fe116", size = 874050, upload-time = "2025-11-05T20:41:08.922Z" }, + { url = "https://files.pythonhosted.org/packages/d4/00/eb45db9f90137329072a732273be0d383cb7d7f50ddc8e0bceea34c1dfdf/rignore-0.7.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:65cece3b36e5b0826d946494734c0e6aaf5a0337e18ff55b071438efe13d559e", size = 1167835, upload-time = "2025-11-05T20:41:24.997Z" }, + { url = "https://files.pythonhosted.org/packages/f3/f1/6f1d72ddca41a64eed569680587a1236633587cc9f78136477ae69e2c88a/rignore-0.7.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d7e4bb66c13cd7602dc8931822c02dfbbd5252015c750ac5d6152b186f0a8be0", size = 941945, upload-time = "2025-11-05T20:41:40.628Z" }, + { url = "https://files.pythonhosted.org/packages/48/6f/2f178af1c1a276a065f563ec1e11e7a9e23d4996fd0465516afce4b5c636/rignore-0.7.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:297e500c15766e196f68aaaa70e8b6db85fa23fdc075b880d8231fdfba738cd7", size = 959067, upload-time = "2025-11-05T20:42:11.09Z" }, + { url = "https://files.pythonhosted.org/packages/5b/db/423a81c4c1e173877c7f9b5767dcaf1ab50484a94f60a0b2ed78be3fa765/rignore-0.7.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a07084211a8d35e1a5b1d32b9661a5ed20669970b369df0cf77da3adea3405de", size = 984438, upload-time = "2025-11-05T20:41:55.443Z" }, + { url = "https://files.pythonhosted.org/packages/31/eb/c4f92cc3f2825d501d3c46a244a671eb737fc1bcf7b05a3ecd34abb3e0d7/rignore-0.7.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:181eb2a975a22256a1441a9d2f15eb1292839ea3f05606620bd9e1938302cf79", size = 1078365, upload-time = "2025-11-05T21:40:15.148Z" }, + { url = "https://files.pythonhosted.org/packages/26/09/99442f02794bd7441bfc8ed1c7319e890449b816a7493b2db0e30af39095/rignore-0.7.6-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:7bbcdc52b5bf9f054b34ce4af5269df5d863d9c2456243338bc193c28022bd7b", size = 1139066, upload-time = "2025-11-05T21:40:32.771Z" }, + { url = "https://files.pythonhosted.org/packages/2c/88/bcfc21e520bba975410e9419450f4b90a2ac8236b9a80fd8130e87d098af/rignore-0.7.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f2e027a6da21a7c8c0d87553c24ca5cc4364def18d146057862c23a96546238e", size = 1118036, upload-time = "2025-11-05T21:40:49.646Z" }, + { url = "https://files.pythonhosted.org/packages/e2/25/d37215e4562cda5c13312636393aea0bafe38d54d4e0517520a4cc0753ec/rignore-0.7.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ee4a18b82cbbc648e4aac1510066682fe62beb5dc88e2c67c53a83954e541360", size = 1127550, upload-time = "2025-11-05T21:41:07.648Z" }, + { url = "https://files.pythonhosted.org/packages/dc/76/a264ab38bfa1620ec12a8ff1c07778da89e16d8c0f3450b0333020d3d6dc/rignore-0.7.6-cp313-cp313-win32.whl", hash = "sha256:a7d7148b6e5e95035d4390396895adc384d37ff4e06781a36fe573bba7c283e5", size = 646097, upload-time = "2025-11-05T21:41:53.201Z" }, + { url = "https://files.pythonhosted.org/packages/62/44/3c31b8983c29ea8832b6082ddb1d07b90379c2d993bd20fce4487b71b4f4/rignore-0.7.6-cp313-cp313-win_amd64.whl", hash = "sha256:b037c4b15a64dced08fc12310ee844ec2284c4c5c1ca77bc37d0a04f7bff386e", size = 726170, upload-time = "2025-11-05T21:41:38.131Z" }, + { url = "https://files.pythonhosted.org/packages/aa/41/e26a075cab83debe41a42661262f606166157df84e0e02e2d904d134c0d8/rignore-0.7.6-cp313-cp313-win_arm64.whl", hash = "sha256:e47443de9b12fe569889bdbe020abe0e0b667516ee2ab435443f6d0869bd2804", size = 656184, upload-time = "2025-11-05T21:41:27.396Z" }, + { url = "https://files.pythonhosted.org/packages/9a/b9/1f5bd82b87e5550cd843ceb3768b4a8ef274eb63f29333cf2f29644b3d75/rignore-0.7.6-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:8e41be9fa8f2f47239ded8920cc283699a052ac4c371f77f5ac017ebeed75732", size = 882632, upload-time = "2025-11-05T20:42:44.063Z" }, + { url = "https://files.pythonhosted.org/packages/e9/6b/07714a3efe4a8048864e8a5b7db311ba51b921e15268b17defaebf56d3db/rignore-0.7.6-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:6dc1e171e52cefa6c20e60c05394a71165663b48bca6c7666dee4f778f2a7d90", size = 820760, upload-time = "2025-11-05T20:42:27.885Z" }, + { url = "https://files.pythonhosted.org/packages/ac/0f/348c829ea2d8d596e856371b14b9092f8a5dfbb62674ec9b3f67e4939a9d/rignore-0.7.6-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ce2268837c3600f82ab8db58f5834009dc638ee17103582960da668963bebc5", size = 899044, upload-time = "2025-11-05T20:40:55.336Z" }, + { url = "https://files.pythonhosted.org/packages/f0/30/2e1841a19b4dd23878d73edd5d82e998a83d5ed9570a89675f140ca8b2ad/rignore-0.7.6-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:690a3e1b54bfe77e89c4bacb13f046e642f8baadafc61d68f5a726f324a76ab6", size = 874144, upload-time = "2025-11-05T20:41:10.195Z" }, + { url = "https://files.pythonhosted.org/packages/c2/bf/0ce9beb2e5f64c30e3580bef09f5829236889f01511a125f98b83169b993/rignore-0.7.6-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09d12ac7a0b6210c07bcd145007117ebd8abe99c8eeb383e9e4673910c2754b2", size = 1168062, upload-time = "2025-11-05T20:41:26.511Z" }, + { url = "https://files.pythonhosted.org/packages/b9/8b/571c178414eb4014969865317da8a02ce4cf5241a41676ef91a59aab24de/rignore-0.7.6-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2a2b2b74a8c60203b08452479b90e5ce3dbe96a916214bc9eb2e5af0b6a9beb0", size = 942542, upload-time = "2025-11-05T20:41:41.838Z" }, + { url = "https://files.pythonhosted.org/packages/19/62/7a3cf601d5a45137a7e2b89d10c05b5b86499190c4b7ca5c3c47d79ee519/rignore-0.7.6-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8fc5a531ef02131e44359419a366bfac57f773ea58f5278c2cdd915f7d10ea94", size = 958739, upload-time = "2025-11-05T20:42:12.463Z" }, + { url = "https://files.pythonhosted.org/packages/5f/1f/4261f6a0d7caf2058a5cde2f5045f565ab91aa7badc972b57d19ce58b14e/rignore-0.7.6-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b7a1f77d9c4cd7e76229e252614d963442686bfe12c787a49f4fe481df49e7a9", size = 984138, upload-time = "2025-11-05T20:41:56.775Z" }, + { url = "https://files.pythonhosted.org/packages/2b/bf/628dfe19c75e8ce1f45f7c248f5148b17dfa89a817f8e3552ab74c3ae812/rignore-0.7.6-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ead81f728682ba72b5b1c3d5846b011d3e0174da978de87c61645f2ed36659a7", size = 1079299, upload-time = "2025-11-05T21:40:16.639Z" }, + { url = "https://files.pythonhosted.org/packages/af/a5/be29c50f5c0c25c637ed32db8758fdf5b901a99e08b608971cda8afb293b/rignore-0.7.6-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:12ffd50f520c22ffdabed8cd8bfb567d9ac165b2b854d3e679f4bcaef11a9441", size = 1139618, upload-time = "2025-11-05T21:40:34.507Z" }, + { url = "https://files.pythonhosted.org/packages/2a/40/3c46cd7ce4fa05c20b525fd60f599165e820af66e66f2c371cd50644558f/rignore-0.7.6-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:e5a16890fbe3c894f8ca34b0fcacc2c200398d4d46ae654e03bc9b3dbf2a0a72", size = 1117626, upload-time = "2025-11-05T21:40:51.494Z" }, + { url = "https://files.pythonhosted.org/packages/8c/b9/aea926f263b8a29a23c75c2e0d8447965eb1879d3feb53cfcf84db67ed58/rignore-0.7.6-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:3abab3bf99e8a77488ef6c7c9a799fac22224c28fe9f25cc21aa7cc2b72bfc0b", size = 1128144, upload-time = "2025-11-05T21:41:09.169Z" }, + { url = "https://files.pythonhosted.org/packages/a4/f6/0d6242f8d0df7f2ecbe91679fefc1f75e7cd2072cb4f497abaab3f0f8523/rignore-0.7.6-cp314-cp314-win32.whl", hash = "sha256:eeef421c1782953c4375aa32f06ecae470c1285c6381eee2a30d2e02a5633001", size = 646385, upload-time = "2025-11-05T21:41:55.105Z" }, + { url = "https://files.pythonhosted.org/packages/d5/38/c0dcd7b10064f084343d6af26fe9414e46e9619c5f3224b5272e8e5d9956/rignore-0.7.6-cp314-cp314-win_amd64.whl", hash = "sha256:6aeed503b3b3d5af939b21d72a82521701a4bd3b89cd761da1e7dc78621af304", size = 725738, upload-time = "2025-11-05T21:41:39.736Z" }, + { url = "https://files.pythonhosted.org/packages/d9/7a/290f868296c1ece914d565757ab363b04730a728b544beb567ceb3b2d96f/rignore-0.7.6-cp314-cp314-win_arm64.whl", hash = "sha256:104f215b60b3c984c386c3e747d6ab4376d5656478694e22c7bd2f788ddd8304", size = 656008, upload-time = "2025-11-05T21:41:29.028Z" }, + { url = "https://files.pythonhosted.org/packages/ca/d2/3c74e3cd81fe8ea08a8dcd2d755c09ac2e8ad8fe409508904557b58383d3/rignore-0.7.6-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:bb24a5b947656dd94cb9e41c4bc8b23cec0c435b58be0d74a874f63c259549e8", size = 882835, upload-time = "2025-11-05T20:42:45.443Z" }, + { url = "https://files.pythonhosted.org/packages/77/61/a772a34b6b63154877433ac2d048364815b24c2dd308f76b212c408101a2/rignore-0.7.6-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5b1e33c9501cefe24b70a1eafd9821acfd0ebf0b35c3a379430a14df089993e3", size = 820301, upload-time = "2025-11-05T20:42:29.226Z" }, + { url = "https://files.pythonhosted.org/packages/71/30/054880b09c0b1b61d17eeb15279d8bf729c0ba52b36c3ada52fb827cbb3c/rignore-0.7.6-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bec3994665a44454df86deb762061e05cd4b61e3772f5b07d1882a8a0d2748d5", size = 897611, upload-time = "2025-11-05T20:40:56.475Z" }, + { url = "https://files.pythonhosted.org/packages/1e/40/b2d1c169f833d69931bf232600eaa3c7998ba4f9a402e43a822dad2ea9f2/rignore-0.7.6-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:26cba2edfe3cff1dfa72bddf65d316ddebf182f011f2f61538705d6dbaf54986", size = 873875, upload-time = "2025-11-05T20:41:11.561Z" }, + { url = "https://files.pythonhosted.org/packages/55/59/ca5ae93d83a1a60e44b21d87deb48b177a8db1b85e82fc8a9abb24a8986d/rignore-0.7.6-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ffa86694fec604c613696cb91e43892aa22e1fec5f9870e48f111c603e5ec4e9", size = 1167245, upload-time = "2025-11-05T20:41:28.29Z" }, + { url = "https://files.pythonhosted.org/packages/a5/52/cf3dce392ba2af806cba265aad6bcd9c48bb2a6cb5eee448d3319f6e505b/rignore-0.7.6-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48efe2ed95aa8104145004afb15cdfa02bea5cdde8b0344afeb0434f0d989aa2", size = 941750, upload-time = "2025-11-05T20:41:43.111Z" }, + { url = "https://files.pythonhosted.org/packages/ec/be/3f344c6218d779395e785091d05396dfd8b625f6aafbe502746fcd880af2/rignore-0.7.6-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8dcae43eb44b7f2457fef7cc87f103f9a0013017a6f4e62182c565e924948f21", size = 958896, upload-time = "2025-11-05T20:42:13.784Z" }, + { url = "https://files.pythonhosted.org/packages/c9/34/d3fa71938aed7d00dcad87f0f9bcb02ad66c85d6ffc83ba31078ce53646a/rignore-0.7.6-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2cd649a7091c0dad2f11ef65630d30c698d505cbe8660dd395268e7c099cc99f", size = 983992, upload-time = "2025-11-05T20:41:58.022Z" }, + { url = "https://files.pythonhosted.org/packages/24/a4/52a697158e9920705bdbd0748d59fa63e0f3233fb92e9df9a71afbead6ca/rignore-0.7.6-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:42de84b0289d478d30ceb7ae59023f7b0527786a9a5b490830e080f0e4ea5aeb", size = 1078181, upload-time = "2025-11-05T21:40:18.151Z" }, + { url = "https://files.pythonhosted.org/packages/ac/65/aa76dbcdabf3787a6f0fd61b5cc8ed1e88580590556d6c0207960d2384bb/rignore-0.7.6-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:875a617e57b53b4acbc5a91de418233849711c02e29cc1f4f9febb2f928af013", size = 1139232, upload-time = "2025-11-05T21:40:35.966Z" }, + { url = "https://files.pythonhosted.org/packages/08/44/31b31a49b3233c6842acc1c0731aa1e7fb322a7170612acf30327f700b44/rignore-0.7.6-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:8703998902771e96e49968105207719f22926e4431b108450f3f430b4e268b7c", size = 1117349, upload-time = "2025-11-05T21:40:53.013Z" }, + { url = "https://files.pythonhosted.org/packages/e9/ae/1b199a2302c19c658cf74e5ee1427605234e8c91787cfba0015f2ace145b/rignore-0.7.6-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:602ef33f3e1b04c1e9a10a3c03f8bc3cef2d2383dcc250d309be42b49923cabc", size = 1127702, upload-time = "2025-11-05T21:41:10.881Z" }, + { url = "https://files.pythonhosted.org/packages/fc/d3/18210222b37e87e36357f7b300b7d98c6dd62b133771e71ae27acba83a4f/rignore-0.7.6-cp314-cp314t-win32.whl", hash = "sha256:c1d8f117f7da0a4a96a8daef3da75bc090e3792d30b8b12cfadc240c631353f9", size = 647033, upload-time = "2025-11-05T21:42:00.095Z" }, + { url = "https://files.pythonhosted.org/packages/3e/87/033eebfbee3ec7d92b3bb1717d8f68c88e6fc7de54537040f3b3a405726f/rignore-0.7.6-cp314-cp314t-win_amd64.whl", hash = "sha256:ca36e59408bec81de75d307c568c2d0d410fb880b1769be43611472c61e85c96", size = 725647, upload-time = "2025-11-05T21:41:44.449Z" }, + { url = "https://files.pythonhosted.org/packages/79/62/b88e5879512c55b8ee979c666ee6902adc4ed05007226de266410ae27965/rignore-0.7.6-cp314-cp314t-win_arm64.whl", hash = "sha256:b83adabeb3e8cf662cabe1931b83e165b88c526fa6af6b3aa90429686e474896", size = 656035, upload-time = "2025-11-05T21:41:31.13Z" }, +] + +[[package]] +name = "ruff" +version = "0.14.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/57/08/52232a877978dd8f9cf2aeddce3e611b40a63287dfca29b6b8da791f5e8d/ruff-0.14.10.tar.gz", hash = "sha256:9a2e830f075d1a42cd28420d7809ace390832a490ed0966fe373ba288e77aaf4", size = 5859763, upload-time = "2025-12-18T19:28:57.98Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/60/01/933704d69f3f05ee16ef11406b78881733c186fe14b6a46b05cfcaf6d3b2/ruff-0.14.10-py3-none-linux_armv6l.whl", hash = "sha256:7a3ce585f2ade3e1f29ec1b92df13e3da262178df8c8bdf876f48fa0e8316c49", size = 13527080, upload-time = "2025-12-18T19:29:25.642Z" }, + { url = "https://files.pythonhosted.org/packages/df/58/a0349197a7dfa603ffb7f5b0470391efa79ddc327c1e29c4851e85b09cc5/ruff-0.14.10-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:674f9be9372907f7257c51f1d4fc902cb7cf014b9980152b802794317941f08f", size = 13797320, upload-time = "2025-12-18T19:29:02.571Z" }, + { url = "https://files.pythonhosted.org/packages/7b/82/36be59f00a6082e38c23536df4e71cdbc6af8d7c707eade97fcad5c98235/ruff-0.14.10-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d85713d522348837ef9df8efca33ccb8bd6fcfc86a2cde3ccb4bc9d28a18003d", size = 12918434, upload-time = "2025-12-18T19:28:51.202Z" }, + { url = "https://files.pythonhosted.org/packages/a6/00/45c62a7f7e34da92a25804f813ebe05c88aa9e0c25e5cb5a7d23dd7450e3/ruff-0.14.10-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6987ebe0501ae4f4308d7d24e2d0fe3d7a98430f5adfd0f1fead050a740a3a77", size = 13371961, upload-time = "2025-12-18T19:29:04.991Z" }, + { url = "https://files.pythonhosted.org/packages/40/31/a5906d60f0405f7e57045a70f2d57084a93ca7425f22e1d66904769d1628/ruff-0.14.10-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:16a01dfb7b9e4eee556fbfd5392806b1b8550c9b4a9f6acd3dbe6812b193c70a", size = 13275629, upload-time = "2025-12-18T19:29:21.381Z" }, + { url = "https://files.pythonhosted.org/packages/3e/60/61c0087df21894cf9d928dc04bcd4fb10e8b2e8dca7b1a276ba2155b2002/ruff-0.14.10-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7165d31a925b7a294465fa81be8c12a0e9b60fb02bf177e79067c867e71f8b1f", size = 14029234, upload-time = "2025-12-18T19:29:00.132Z" }, + { url = "https://files.pythonhosted.org/packages/44/84/77d911bee3b92348b6e5dab5a0c898d87084ea03ac5dc708f46d88407def/ruff-0.14.10-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:c561695675b972effb0c0a45db233f2c816ff3da8dcfbe7dfc7eed625f218935", size = 15449890, upload-time = "2025-12-18T19:28:53.573Z" }, + { url = "https://files.pythonhosted.org/packages/e9/36/480206eaefa24a7ec321582dda580443a8f0671fdbf6b1c80e9c3e93a16a/ruff-0.14.10-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4bb98fcbbc61725968893682fd4df8966a34611239c9fd07a1f6a07e7103d08e", size = 15123172, upload-time = "2025-12-18T19:29:23.453Z" }, + { url = "https://files.pythonhosted.org/packages/5c/38/68e414156015ba80cef5473d57919d27dfb62ec804b96180bafdeaf0e090/ruff-0.14.10-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f24b47993a9d8cb858429e97bdf8544c78029f09b520af615c1d261bf827001d", size = 14460260, upload-time = "2025-12-18T19:29:27.808Z" }, + { url = "https://files.pythonhosted.org/packages/b3/19/9e050c0dca8aba824d67cc0db69fb459c28d8cd3f6855b1405b3f29cc91d/ruff-0.14.10-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59aabd2e2c4fd614d2862e7939c34a532c04f1084476d6833dddef4afab87e9f", size = 14229978, upload-time = "2025-12-18T19:29:11.32Z" }, + { url = "https://files.pythonhosted.org/packages/51/eb/e8dd1dd6e05b9e695aa9dd420f4577debdd0f87a5ff2fedda33c09e9be8c/ruff-0.14.10-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:213db2b2e44be8625002dbea33bb9c60c66ea2c07c084a00d55732689d697a7f", size = 14338036, upload-time = "2025-12-18T19:29:09.184Z" }, + { url = "https://files.pythonhosted.org/packages/6a/12/f3e3a505db7c19303b70af370d137795fcfec136d670d5de5391e295c134/ruff-0.14.10-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:b914c40ab64865a17a9a5b67911d14df72346a634527240039eb3bd650e5979d", size = 13264051, upload-time = "2025-12-18T19:29:13.431Z" }, + { url = "https://files.pythonhosted.org/packages/08/64/8c3a47eaccfef8ac20e0484e68e0772013eb85802f8a9f7603ca751eb166/ruff-0.14.10-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:1484983559f026788e3a5c07c81ef7d1e97c1c78ed03041a18f75df104c45405", size = 13283998, upload-time = "2025-12-18T19:29:06.994Z" }, + { url = "https://files.pythonhosted.org/packages/12/84/534a5506f4074e5cc0529e5cd96cfc01bb480e460c7edf5af70d2bcae55e/ruff-0.14.10-py3-none-musllinux_1_2_i686.whl", hash = "sha256:c70427132db492d25f982fffc8d6c7535cc2fd2c83fc8888f05caaa248521e60", size = 13601891, upload-time = "2025-12-18T19:28:55.811Z" }, + { url = "https://files.pythonhosted.org/packages/0d/1e/14c916087d8598917dbad9b2921d340f7884824ad6e9c55de948a93b106d/ruff-0.14.10-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5bcf45b681e9f1ee6445d317ce1fa9d6cba9a6049542d1c3d5b5958986be8830", size = 14336660, upload-time = "2025-12-18T19:29:16.531Z" }, + { url = "https://files.pythonhosted.org/packages/f2/1c/d7b67ab43f30013b47c12b42d1acd354c195351a3f7a1d67f59e54227ede/ruff-0.14.10-py3-none-win32.whl", hash = "sha256:104c49fc7ab73f3f3a758039adea978869a918f31b73280db175b43a2d9b51d6", size = 13196187, upload-time = "2025-12-18T19:29:19.006Z" }, + { url = "https://files.pythonhosted.org/packages/fb/9c/896c862e13886fae2af961bef3e6312db9ebc6adc2b156fe95e615dee8c1/ruff-0.14.10-py3-none-win_amd64.whl", hash = "sha256:466297bd73638c6bdf06485683e812db1c00c7ac96d4ddd0294a338c62fdc154", size = 14661283, upload-time = "2025-12-18T19:29:30.16Z" }, + { url = "https://files.pythonhosted.org/packages/74/31/b0e29d572670dca3674eeee78e418f20bdf97fa8aa9ea71380885e175ca0/ruff-0.14.10-py3-none-win_arm64.whl", hash = "sha256:e51d046cf6dda98a4633b8a8a771451107413b0f07183b2bef03f075599e44e6", size = 13729839, upload-time = "2025-12-18T19:28:48.636Z" }, +] + +[[package]] +name = "scalar-fastapi" +version = "1.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b2/1a/4897819ef5682f40cce1f9b552a1e002d394bf7e12e5d6fe62f843ffef51/scalar_fastapi-1.5.0.tar.gz", hash = "sha256:5ae887fcc0db63305dc41dc39d61f7be183256085872aa33b294e0d48e29901e", size = 7447, upload-time = "2025-12-04T19:44:12.04Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7a/cc/c0712ac83a31ae96785d9916d7be54595914aa93375ea5df3ba3eadab8af/scalar_fastapi-1.5.0-py3-none-any.whl", hash = "sha256:8e712599ccdfbb614bff5583fdbee1bef03e5fac1e06520287337ff232cb667a", size = 6828, upload-time = "2025-12-04T19:44:11.242Z" }, +] + +[[package]] +name = "sentry-sdk" +version = "2.48.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/40/f0/0e9dc590513d5e742d7799e2038df3a05167cba084c6ca4f3cdd75b55164/sentry_sdk-2.48.0.tar.gz", hash = "sha256:5213190977ff7fdff8a58b722fb807f8d5524a80488626ebeda1b5676c0c1473", size = 384828, upload-time = "2025-12-16T14:55:41.722Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4d/19/8d77f9992e5cbfcaa9133c3bf63b4fbbb051248802e1e803fed5c552fbb2/sentry_sdk-2.48.0-py2.py3-none-any.whl", hash = "sha256:6b12ac256769d41825d9b7518444e57fa35b5642df4c7c5e322af4d2c8721172", size = 414555, upload-time = "2025-12-16T14:55:40.152Z" }, +] + +[[package]] +name = "shellingham" +version = "1.5.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310, upload-time = "2023-10-24T04:13:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, +] + +[[package]] +name = "sniffio" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372, upload-time = "2024-02-25T23:20:04.057Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" }, +] + +[[package]] +name = "sqladmin" +version = "0.22.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jinja2" }, + { name = "python-multipart" }, + { name = "sqlalchemy" }, + { name = "starlette" }, + { name = "wtforms" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2c/ac/526bb3ff2dd94fbf8442bccb49ef40aa360045add19d4fbffcb43995e67a/sqladmin-0.22.0.tar.gz", hash = "sha256:4ea904d97e4d030edb68fb0681330b4d963f422442a64bee487fdc46119b3729", size = 1429937, upload-time = "2025-11-24T12:52:59.285Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f2/b4/ab78c7d7b13bd3f90d6d8a106c5ad12bf7a738f89eb0241b24ad8efe5d1e/sqladmin-0.22.0-py3-none-any.whl", hash = "sha256:f2fb11165a70601a97f71956104b47da2c432db49b0d7966dc65e9e6343887d3", size = 1445514, upload-time = "2025-11-24T12:53:00.511Z" }, +] + +[package.optional-dependencies] +full = [ + { name = "itsdangerous" }, +] + +[[package]] +name = "sqlalchemy" +version = "2.0.45" +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/be/f9/5e4491e5ccf42f5d9cfc663741d261b3e6e1683ae7812114e7636409fcc6/sqlalchemy-2.0.45.tar.gz", hash = "sha256:1632a4bda8d2d25703fdad6363058d882541bdaaee0e5e3ddfa0cd3229efce88", size = 9869912, upload-time = "2025-12-09T21:05:16.737Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6a/c8/7cc5221b47a54edc72a0140a1efa56e0a2730eefa4058d7ed0b4c4357ff8/sqlalchemy-2.0.45-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fe187fc31a54d7fd90352f34e8c008cf3ad5d064d08fedd3de2e8df83eb4a1cf", size = 3277082, upload-time = "2025-12-09T22:11:06.167Z" }, + { url = "https://files.pythonhosted.org/packages/0e/50/80a8d080ac7d3d321e5e5d420c9a522b0aa770ec7013ea91f9a8b7d36e4a/sqlalchemy-2.0.45-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:672c45cae53ba88e0dad74b9027dddd09ef6f441e927786b05bec75d949fbb2e", size = 3293131, upload-time = "2025-12-09T22:13:52.626Z" }, + { url = "https://files.pythonhosted.org/packages/da/4c/13dab31266fc9904f7609a5dc308a2432a066141d65b857760c3bef97e69/sqlalchemy-2.0.45-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:470daea2c1ce73910f08caf10575676a37159a6d16c4da33d0033546bddebc9b", size = 3225389, upload-time = "2025-12-09T22:11:08.093Z" }, + { url = "https://files.pythonhosted.org/packages/74/04/891b5c2e9f83589de202e7abaf24cd4e4fa59e1837d64d528829ad6cc107/sqlalchemy-2.0.45-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9c6378449e0940476577047150fd09e242529b761dc887c9808a9a937fe990c8", size = 3266054, upload-time = "2025-12-09T22:13:54.262Z" }, + { url = "https://files.pythonhosted.org/packages/f1/24/fc59e7f71b0948cdd4cff7a286210e86b0443ef1d18a23b0d83b87e4b1f7/sqlalchemy-2.0.45-cp313-cp313-win32.whl", hash = "sha256:4b6bec67ca45bc166c8729910bd2a87f1c0407ee955df110d78948f5b5827e8a", size = 2110299, upload-time = "2025-12-09T21:39:33.486Z" }, + { url = "https://files.pythonhosted.org/packages/c0/c5/d17113020b2d43073412aeca09b60d2009442420372123b8d49cc253f8b8/sqlalchemy-2.0.45-cp313-cp313-win_amd64.whl", hash = "sha256:afbf47dc4de31fa38fd491f3705cac5307d21d4bb828a4f020ee59af412744ee", size = 2136264, upload-time = "2025-12-09T21:39:36.801Z" }, + { url = "https://files.pythonhosted.org/packages/3d/8d/bb40a5d10e7a5f2195f235c0b2f2c79b0bf6e8f00c0c223130a4fbd2db09/sqlalchemy-2.0.45-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:83d7009f40ce619d483d26ac1b757dfe3167b39921379a8bd1b596cf02dab4a6", size = 3521998, upload-time = "2025-12-09T22:13:28.622Z" }, + { url = "https://files.pythonhosted.org/packages/75/a5/346128b0464886f036c039ea287b7332a410aa2d3fb0bb5d404cb8861635/sqlalchemy-2.0.45-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:d8a2ca754e5415cde2b656c27900b19d50ba076aa05ce66e2207623d3fe41f5a", size = 3473434, upload-time = "2025-12-09T22:13:30.188Z" }, + { url = "https://files.pythonhosted.org/packages/cc/64/4e1913772646b060b025d3fc52ce91a58967fe58957df32b455de5a12b4f/sqlalchemy-2.0.45-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7f46ec744e7f51275582e6a24326e10c49fbdd3fc99103e01376841213028774", size = 3272404, upload-time = "2025-12-09T22:11:09.662Z" }, + { url = "https://files.pythonhosted.org/packages/b3/27/caf606ee924282fe4747ee4fd454b335a72a6e018f97eab5ff7f28199e16/sqlalchemy-2.0.45-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:883c600c345123c033c2f6caca18def08f1f7f4c3ebeb591a63b6fceffc95cce", size = 3277057, upload-time = "2025-12-09T22:13:56.213Z" }, + { url = "https://files.pythonhosted.org/packages/85/d0/3d64218c9724e91f3d1574d12eb7ff8f19f937643815d8daf792046d88ab/sqlalchemy-2.0.45-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2c0b74aa79e2deade948fe8593654c8ef4228c44ba862bb7c9585c8e0db90f33", size = 3222279, upload-time = "2025-12-09T22:11:11.1Z" }, + { url = "https://files.pythonhosted.org/packages/24/10/dd7688a81c5bc7690c2a3764d55a238c524cd1a5a19487928844cb247695/sqlalchemy-2.0.45-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:8a420169cef179d4c9064365f42d779f1e5895ad26ca0c8b4c0233920973db74", size = 3244508, upload-time = "2025-12-09T22:13:57.932Z" }, + { url = "https://files.pythonhosted.org/packages/aa/41/db75756ca49f777e029968d9c9fee338c7907c563267740c6d310a8e3f60/sqlalchemy-2.0.45-cp314-cp314-win32.whl", hash = "sha256:e50dcb81a5dfe4b7b4a4aa8f338116d127cb209559124f3694c70d6cd072b68f", size = 2113204, upload-time = "2025-12-09T21:39:38.365Z" }, + { url = "https://files.pythonhosted.org/packages/89/a2/0e1590e9adb292b1d576dbcf67ff7df8cf55e56e78d2c927686d01080f4b/sqlalchemy-2.0.45-cp314-cp314-win_amd64.whl", hash = "sha256:4748601c8ea959e37e03d13dcda4a44837afcd1b21338e637f7c935b8da06177", size = 2138785, upload-time = "2025-12-09T21:39:39.503Z" }, + { url = "https://files.pythonhosted.org/packages/42/39/f05f0ed54d451156bbed0e23eb0516bcad7cbb9f18b3bf219c786371b3f0/sqlalchemy-2.0.45-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cd337d3526ec5298f67d6a30bbbe4ed7e5e68862f0bf6dd21d289f8d37b7d60b", size = 3522029, upload-time = "2025-12-09T22:13:32.09Z" }, + { url = "https://files.pythonhosted.org/packages/54/0f/d15398b98b65c2bce288d5ee3f7d0a81f77ab89d9456994d5c7cc8b2a9db/sqlalchemy-2.0.45-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9a62b446b7d86a3909abbcd1cd3cc550a832f99c2bc37c5b22e1925438b9367b", size = 3475142, upload-time = "2025-12-09T22:13:33.739Z" }, + { url = "https://files.pythonhosted.org/packages/bf/e1/3ccb13c643399d22289c6a9786c1a91e3dcbb68bce4beb44926ac2c557bf/sqlalchemy-2.0.45-py3-none-any.whl", hash = "sha256:5225a288e4c8cc2308dbdd874edad6e7d0fd38eac1e9e5f23503425c8eee20d0", size = 1936672, upload-time = "2025-12-09T21:54:52.608Z" }, +] + +[package.optional-dependencies] +asyncio = [ + { name = "greenlet" }, +] + +[[package]] +name = "starlette" +version = "0.50.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ba/b8/73a0e6a6e079a9d9cfa64113d771e421640b6f679a52eeb9b32f72d871a1/starlette-0.50.0.tar.gz", hash = "sha256:a2a17b22203254bcbc2e1f926d2d55f3f9497f769416b3190768befe598fa3ca", size = 2646985, upload-time = "2025-11-01T15:25:27.516Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d9/52/1064f510b141bd54025f9b55105e26d1fa970b9be67ad766380a3c9b74b0/starlette-0.50.0-py3-none-any.whl", hash = "sha256:9e5391843ec9b6e472eed1365a78c8098cfceb7a74bfd4d6b1c0c0095efb3bca", size = 74033, upload-time = "2025-11-01T15:25:25.461Z" }, +] + +[[package]] +name = "tqdm" +version = "4.67.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a8/4b/29b4ef32e036bb34e4ab51796dd745cdba7ed47ad142a9f4a1eb8e0c744d/tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2", size = 169737, upload-time = "2024-11-24T20:12:22.481Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2", size = 78540, upload-time = "2024-11-24T20:12:19.698Z" }, +] + +[[package]] +name = "typer" +version = "0.20.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "rich" }, + { name = "shellingham" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8f/28/7c85c8032b91dbe79725b6f17d2fffc595dff06a35c7a30a37bef73a1ab4/typer-0.20.0.tar.gz", hash = "sha256:1aaf6494031793e4876fb0bacfa6a912b551cf43c1e63c800df8b1a866720c37", size = 106492, upload-time = "2025-10-20T17:03:49.445Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/64/7713ffe4b5983314e9d436a90d5bd4f63b6054e2aca783a3cfc44cb95bbf/typer-0.20.0-py3-none-any.whl", hash = "sha256:5b463df6793ec1dca6213a3cf4c0f03bc6e322ac5e16e13ddd622a889489784a", size = 47028, upload-time = "2025-10-20T17:03:47.617Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.15.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, +] + +[[package]] +name = "typing-inspection" +version = "0.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload-time = "2025-10-01T02:14:41.687Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" }, +] + +[[package]] +name = "urllib3" +version = "2.6.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1e/24/a2a2ed9addd907787d7aa0355ba36a6cadf1768b934c652ea78acbd59dcd/urllib3-2.6.2.tar.gz", hash = "sha256:016f9c98bb7e98085cb2b4b17b87d2c702975664e4f060c6532e64d1c1a5e797", size = 432930, upload-time = "2025-12-11T15:56:40.252Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6d/b9/4095b668ea3678bf6a0af005527f39de12fb026516fb3df17495a733b7f8/urllib3-2.6.2-py3-none-any.whl", hash = "sha256:ec21cddfe7724fc7cb4ba4bea7aa8e2ef36f607a4bab81aa6ce42a13dc3f03dd", size = 131182, upload-time = "2025-12-11T15:56:38.584Z" }, +] + +[[package]] +name = "uuid7" +version = "0.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5c/19/7472bd526591e2192926247109dbf78692e709d3e56775792fec877a7720/uuid7-0.1.0.tar.gz", hash = "sha256:8c57aa32ee7456d3cc68c95c4530bc571646defac01895cfc73545449894a63c", size = 14052, upload-time = "2021-12-29T01:38:21.897Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b5/77/8852f89a91453956582a85024d80ad96f30a41fed4c2b3dce0c9f12ecc7e/uuid7-0.1.0-py2.py3-none-any.whl", hash = "sha256:5e259bb63c8cb4aded5927ff41b444a80d0c7124e8a0ced7cf44efa1f5cccf61", size = 7477, upload-time = "2021-12-29T01:38:20.418Z" }, +] + +[[package]] +name = "uvicorn" +version = "0.38.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "h11" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cb/ce/f06b84e2697fef4688ca63bdb2fdf113ca0a3be33f94488f2cadb690b0cf/uvicorn-0.38.0.tar.gz", hash = "sha256:fd97093bdd120a2609fc0d3afe931d4d4ad688b6e75f0f929fde1bc36fe0e91d", size = 80605, upload-time = "2025-10-18T13:46:44.63Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ee/d9/d88e73ca598f4f6ff671fb5fde8a32925c2e08a637303a1d12883c7305fa/uvicorn-0.38.0-py3-none-any.whl", hash = "sha256:48c0afd214ceb59340075b4a052ea1ee91c16fbc2a9b1469cca0e54566977b02", size = 68109, upload-time = "2025-10-18T13:46:42.958Z" }, +] + +[package.optional-dependencies] +standard = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "httptools" }, + { name = "python-dotenv" }, + { name = "pyyaml" }, + { name = "uvloop", marker = "platform_python_implementation != 'PyPy' and sys_platform != 'cygwin' and sys_platform != 'win32'" }, + { name = "watchfiles" }, + { name = "websockets" }, +] + +[[package]] +name = "uvloop" +version = "0.22.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/06/f0/18d39dbd1971d6d62c4629cc7fa67f74821b0dc1f5a77af43719de7936a7/uvloop-0.22.1.tar.gz", hash = "sha256:6c84bae345b9147082b17371e3dd5d42775bddce91f885499017f4607fdaf39f", size = 2443250, upload-time = "2025-10-16T22:17:19.342Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/89/8c/182a2a593195bfd39842ea68ebc084e20c850806117213f5a299dfc513d9/uvloop-0.22.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:561577354eb94200d75aca23fbde86ee11be36b00e52a4eaf8f50fb0c86b7705", size = 1358611, upload-time = "2025-10-16T22:16:36.833Z" }, + { url = "https://files.pythonhosted.org/packages/d2/14/e301ee96a6dc95224b6f1162cd3312f6d1217be3907b79173b06785f2fe7/uvloop-0.22.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1cdf5192ab3e674ca26da2eada35b288d2fa49fdd0f357a19f0e7c4e7d5077c8", size = 751811, upload-time = "2025-10-16T22:16:38.275Z" }, + { url = "https://files.pythonhosted.org/packages/b7/02/654426ce265ac19e2980bfd9ea6590ca96a56f10c76e63801a2df01c0486/uvloop-0.22.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6e2ea3d6190a2968f4a14a23019d3b16870dd2190cd69c8180f7c632d21de68d", size = 4288562, upload-time = "2025-10-16T22:16:39.375Z" }, + { url = "https://files.pythonhosted.org/packages/15/c0/0be24758891ef825f2065cd5db8741aaddabe3e248ee6acc5e8a80f04005/uvloop-0.22.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0530a5fbad9c9e4ee3f2b33b148c6a64d47bbad8000ea63704fa8260f4cf728e", size = 4366890, upload-time = "2025-10-16T22:16:40.547Z" }, + { url = "https://files.pythonhosted.org/packages/d2/53/8369e5219a5855869bcee5f4d317f6da0e2c669aecf0ef7d371e3d084449/uvloop-0.22.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bc5ef13bbc10b5335792360623cc378d52d7e62c2de64660616478c32cd0598e", size = 4119472, upload-time = "2025-10-16T22:16:41.694Z" }, + { url = "https://files.pythonhosted.org/packages/f8/ba/d69adbe699b768f6b29a5eec7b47dd610bd17a69de51b251126a801369ea/uvloop-0.22.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1f38ec5e3f18c8a10ded09742f7fb8de0108796eb673f30ce7762ce1b8550cad", size = 4239051, upload-time = "2025-10-16T22:16:43.224Z" }, + { url = "https://files.pythonhosted.org/packages/90/cd/b62bdeaa429758aee8de8b00ac0dd26593a9de93d302bff3d21439e9791d/uvloop-0.22.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3879b88423ec7e97cd4eba2a443aa26ed4e59b45e6b76aabf13fe2f27023a142", size = 1362067, upload-time = "2025-10-16T22:16:44.503Z" }, + { url = "https://files.pythonhosted.org/packages/0d/f8/a132124dfda0777e489ca86732e85e69afcd1ff7686647000050ba670689/uvloop-0.22.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:4baa86acedf1d62115c1dc6ad1e17134476688f08c6efd8a2ab076e815665c74", size = 752423, upload-time = "2025-10-16T22:16:45.968Z" }, + { url = "https://files.pythonhosted.org/packages/a3/94/94af78c156f88da4b3a733773ad5ba0b164393e357cc4bd0ab2e2677a7d6/uvloop-0.22.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:297c27d8003520596236bdb2335e6b3f649480bd09e00d1e3a99144b691d2a35", size = 4272437, upload-time = "2025-10-16T22:16:47.451Z" }, + { url = "https://files.pythonhosted.org/packages/b5/35/60249e9fd07b32c665192cec7af29e06c7cd96fa1d08b84f012a56a0b38e/uvloop-0.22.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c1955d5a1dd43198244d47664a5858082a3239766a839b2102a269aaff7a4e25", size = 4292101, upload-time = "2025-10-16T22:16:49.318Z" }, + { url = "https://files.pythonhosted.org/packages/02/62/67d382dfcb25d0a98ce73c11ed1a6fba5037a1a1d533dcbb7cab033a2636/uvloop-0.22.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b31dc2fccbd42adc73bc4e7cdbae4fc5086cf378979e53ca5d0301838c5682c6", size = 4114158, upload-time = "2025-10-16T22:16:50.517Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7a/f1171b4a882a5d13c8b7576f348acfe6074d72eaf52cccef752f748d4a9f/uvloop-0.22.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:93f617675b2d03af4e72a5333ef89450dfaa5321303ede6e67ba9c9d26878079", size = 4177360, upload-time = "2025-10-16T22:16:52.646Z" }, + { url = "https://files.pythonhosted.org/packages/79/7b/b01414f31546caf0919da80ad57cbfe24c56b151d12af68cee1b04922ca8/uvloop-0.22.1-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:37554f70528f60cad66945b885eb01f1bb514f132d92b6eeed1c90fd54ed6289", size = 1454790, upload-time = "2025-10-16T22:16:54.355Z" }, + { url = "https://files.pythonhosted.org/packages/d4/31/0bb232318dd838cad3fa8fb0c68c8b40e1145b32025581975e18b11fab40/uvloop-0.22.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:b76324e2dc033a0b2f435f33eb88ff9913c156ef78e153fb210e03c13da746b3", size = 796783, upload-time = "2025-10-16T22:16:55.906Z" }, + { url = "https://files.pythonhosted.org/packages/42/38/c9b09f3271a7a723a5de69f8e237ab8e7803183131bc57c890db0b6bb872/uvloop-0.22.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:badb4d8e58ee08dad957002027830d5c3b06aea446a6a3744483c2b3b745345c", size = 4647548, upload-time = "2025-10-16T22:16:57.008Z" }, + { url = "https://files.pythonhosted.org/packages/c1/37/945b4ca0ac27e3dc4952642d4c900edd030b3da6c9634875af6e13ae80e5/uvloop-0.22.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b91328c72635f6f9e0282e4a57da7470c7350ab1c9f48546c0f2866205349d21", size = 4467065, upload-time = "2025-10-16T22:16:58.206Z" }, + { url = "https://files.pythonhosted.org/packages/97/cc/48d232f33d60e2e2e0b42f4e73455b146b76ebe216487e862700457fbf3c/uvloop-0.22.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:daf620c2995d193449393d6c62131b3fbd40a63bf7b307a1527856ace637fe88", size = 4328384, upload-time = "2025-10-16T22:16:59.36Z" }, + { url = "https://files.pythonhosted.org/packages/e4/16/c1fd27e9549f3c4baf1dc9c20c456cd2f822dbf8de9f463824b0c0357e06/uvloop-0.22.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6cde23eeda1a25c75b2e07d39970f3374105d5eafbaab2a4482be82f272d5a5e", size = 4296730, upload-time = "2025-10-16T22:17:00.744Z" }, +] + +[[package]] +name = "watchfiles" +version = "1.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c2/c9/8869df9b2a2d6c59d79220a4db37679e74f807c559ffe5265e08b227a210/watchfiles-1.1.1.tar.gz", hash = "sha256:a173cb5c16c4f40ab19cecf48a534c409f7ea983ab8fed0741304a1c0a31b3f2", size = 94440, upload-time = "2025-10-14T15:06:21.08Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bb/f4/f750b29225fe77139f7ae5de89d4949f5a99f934c65a1f1c0b248f26f747/watchfiles-1.1.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:130e4876309e8686a5e37dba7d5e9bc77e6ed908266996ca26572437a5271e18", size = 404321, upload-time = "2025-10-14T15:05:02.063Z" }, + { url = "https://files.pythonhosted.org/packages/2b/f9/f07a295cde762644aa4c4bb0f88921d2d141af45e735b965fb2e87858328/watchfiles-1.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5f3bde70f157f84ece3765b42b4a52c6ac1a50334903c6eaf765362f6ccca88a", size = 391783, upload-time = "2025-10-14T15:05:03.052Z" }, + { url = "https://files.pythonhosted.org/packages/bc/11/fc2502457e0bea39a5c958d86d2cb69e407a4d00b85735ca724bfa6e0d1a/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:14e0b1fe858430fc0251737ef3824c54027bedb8c37c38114488b8e131cf8219", size = 449279, upload-time = "2025-10-14T15:05:04.004Z" }, + { url = "https://files.pythonhosted.org/packages/e3/1f/d66bc15ea0b728df3ed96a539c777acfcad0eb78555ad9efcaa1274688f0/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f27db948078f3823a6bb3b465180db8ebecf26dd5dae6f6180bd87383b6b4428", size = 459405, upload-time = "2025-10-14T15:05:04.942Z" }, + { url = "https://files.pythonhosted.org/packages/be/90/9f4a65c0aec3ccf032703e6db02d89a157462fbb2cf20dd415128251cac0/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:059098c3a429f62fc98e8ec62b982230ef2c8df68c79e826e37b895bc359a9c0", size = 488976, upload-time = "2025-10-14T15:05:05.905Z" }, + { url = "https://files.pythonhosted.org/packages/37/57/ee347af605d867f712be7029bb94c8c071732a4b44792e3176fa3c612d39/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfb5862016acc9b869bb57284e6cb35fdf8e22fe59f7548858e2f971d045f150", size = 595506, upload-time = "2025-10-14T15:05:06.906Z" }, + { url = "https://files.pythonhosted.org/packages/a8/78/cc5ab0b86c122047f75e8fc471c67a04dee395daf847d3e59381996c8707/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:319b27255aacd9923b8a276bb14d21a5f7ff82564c744235fc5eae58d95422ae", size = 474936, upload-time = "2025-10-14T15:05:07.906Z" }, + { url = "https://files.pythonhosted.org/packages/62/da/def65b170a3815af7bd40a3e7010bf6ab53089ef1b75d05dd5385b87cf08/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c755367e51db90e75b19454b680903631d41f9e3607fbd941d296a020c2d752d", size = 456147, upload-time = "2025-10-14T15:05:09.138Z" }, + { url = "https://files.pythonhosted.org/packages/57/99/da6573ba71166e82d288d4df0839128004c67d2778d3b566c138695f5c0b/watchfiles-1.1.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c22c776292a23bfc7237a98f791b9ad3144b02116ff10d820829ce62dff46d0b", size = 630007, upload-time = "2025-10-14T15:05:10.117Z" }, + { url = "https://files.pythonhosted.org/packages/a8/51/7439c4dd39511368849eb1e53279cd3454b4a4dbace80bab88feeb83c6b5/watchfiles-1.1.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:3a476189be23c3686bc2f4321dd501cb329c0a0469e77b7b534ee10129ae6374", size = 622280, upload-time = "2025-10-14T15:05:11.146Z" }, + { url = "https://files.pythonhosted.org/packages/95/9c/8ed97d4bba5db6fdcdb2b298d3898f2dd5c20f6b73aee04eabe56c59677e/watchfiles-1.1.1-cp313-cp313-win32.whl", hash = "sha256:bf0a91bfb5574a2f7fc223cf95eeea79abfefa404bf1ea5e339c0c1560ae99a0", size = 272056, upload-time = "2025-10-14T15:05:12.156Z" }, + { url = "https://files.pythonhosted.org/packages/1f/f3/c14e28429f744a260d8ceae18bf58c1d5fa56b50d006a7a9f80e1882cb0d/watchfiles-1.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:52e06553899e11e8074503c8e716d574adeeb7e68913115c4b3653c53f9bae42", size = 288162, upload-time = "2025-10-14T15:05:13.208Z" }, + { url = "https://files.pythonhosted.org/packages/dc/61/fe0e56c40d5cd29523e398d31153218718c5786b5e636d9ae8ae79453d27/watchfiles-1.1.1-cp313-cp313-win_arm64.whl", hash = "sha256:ac3cc5759570cd02662b15fbcd9d917f7ecd47efe0d6b40474eafd246f91ea18", size = 277909, upload-time = "2025-10-14T15:05:14.49Z" }, + { url = "https://files.pythonhosted.org/packages/79/42/e0a7d749626f1e28c7108a99fb9bf524b501bbbeb9b261ceecde644d5a07/watchfiles-1.1.1-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:563b116874a9a7ce6f96f87cd0b94f7faf92d08d0021e837796f0a14318ef8da", size = 403389, upload-time = "2025-10-14T15:05:15.777Z" }, + { url = "https://files.pythonhosted.org/packages/15/49/08732f90ce0fbbc13913f9f215c689cfc9ced345fb1bcd8829a50007cc8d/watchfiles-1.1.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3ad9fe1dae4ab4212d8c91e80b832425e24f421703b5a42ef2e4a1e215aff051", size = 389964, upload-time = "2025-10-14T15:05:16.85Z" }, + { url = "https://files.pythonhosted.org/packages/27/0d/7c315d4bd5f2538910491a0393c56bf70d333d51bc5b34bee8e68e8cea19/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce70f96a46b894b36eba678f153f052967a0d06d5b5a19b336ab0dbbd029f73e", size = 448114, upload-time = "2025-10-14T15:05:17.876Z" }, + { url = "https://files.pythonhosted.org/packages/c3/24/9e096de47a4d11bc4df41e9d1e61776393eac4cb6eb11b3e23315b78b2cc/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cb467c999c2eff23a6417e58d75e5828716f42ed8289fe6b77a7e5a91036ca70", size = 460264, upload-time = "2025-10-14T15:05:18.962Z" }, + { url = "https://files.pythonhosted.org/packages/cc/0f/e8dea6375f1d3ba5fcb0b3583e2b493e77379834c74fd5a22d66d85d6540/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:836398932192dae4146c8f6f737d74baeac8b70ce14831a239bdb1ca882fc261", size = 487877, upload-time = "2025-10-14T15:05:20.094Z" }, + { url = "https://files.pythonhosted.org/packages/ac/5b/df24cfc6424a12deb41503b64d42fbea6b8cb357ec62ca84a5a3476f654a/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:743185e7372b7bc7c389e1badcc606931a827112fbbd37f14c537320fca08620", size = 595176, upload-time = "2025-10-14T15:05:21.134Z" }, + { url = "https://files.pythonhosted.org/packages/8f/b5/853b6757f7347de4e9b37e8cc3289283fb983cba1ab4d2d7144694871d9c/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:afaeff7696e0ad9f02cbb8f56365ff4686ab205fcf9c4c5b6fdfaaa16549dd04", size = 473577, upload-time = "2025-10-14T15:05:22.306Z" }, + { url = "https://files.pythonhosted.org/packages/e1/f7/0a4467be0a56e80447c8529c9fce5b38eab4f513cb3d9bf82e7392a5696b/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f7eb7da0eb23aa2ba036d4f616d46906013a68caf61b7fdbe42fc8b25132e77", size = 455425, upload-time = "2025-10-14T15:05:23.348Z" }, + { url = "https://files.pythonhosted.org/packages/8e/e0/82583485ea00137ddf69bc84a2db88bd92ab4a6e3c405e5fb878ead8d0e7/watchfiles-1.1.1-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:831a62658609f0e5c64178211c942ace999517f5770fe9436be4c2faeba0c0ef", size = 628826, upload-time = "2025-10-14T15:05:24.398Z" }, + { url = "https://files.pythonhosted.org/packages/28/9a/a785356fccf9fae84c0cc90570f11702ae9571036fb25932f1242c82191c/watchfiles-1.1.1-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:f9a2ae5c91cecc9edd47e041a930490c31c3afb1f5e6d71de3dc671bfaca02bf", size = 622208, upload-time = "2025-10-14T15:05:25.45Z" }, + { url = "https://files.pythonhosted.org/packages/c3/f4/0872229324ef69b2c3edec35e84bd57a1289e7d3fe74588048ed8947a323/watchfiles-1.1.1-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:d1715143123baeeaeadec0528bb7441103979a1d5f6fd0e1f915383fea7ea6d5", size = 404315, upload-time = "2025-10-14T15:05:26.501Z" }, + { url = "https://files.pythonhosted.org/packages/7b/22/16d5331eaed1cb107b873f6ae1b69e9ced582fcf0c59a50cd84f403b1c32/watchfiles-1.1.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:39574d6370c4579d7f5d0ad940ce5b20db0e4117444e39b6d8f99db5676c52fd", size = 390869, upload-time = "2025-10-14T15:05:27.649Z" }, + { url = "https://files.pythonhosted.org/packages/b2/7e/5643bfff5acb6539b18483128fdc0ef2cccc94a5b8fbda130c823e8ed636/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7365b92c2e69ee952902e8f70f3ba6360d0d596d9299d55d7d386df84b6941fb", size = 449919, upload-time = "2025-10-14T15:05:28.701Z" }, + { url = "https://files.pythonhosted.org/packages/51/2e/c410993ba5025a9f9357c376f48976ef0e1b1aefb73b97a5ae01a5972755/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bfff9740c69c0e4ed32416f013f3c45e2ae42ccedd1167ef2d805c000b6c71a5", size = 460845, upload-time = "2025-10-14T15:05:30.064Z" }, + { url = "https://files.pythonhosted.org/packages/8e/a4/2df3b404469122e8680f0fcd06079317e48db58a2da2950fb45020947734/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b27cf2eb1dda37b2089e3907d8ea92922b673c0c427886d4edc6b94d8dfe5db3", size = 489027, upload-time = "2025-10-14T15:05:31.064Z" }, + { url = "https://files.pythonhosted.org/packages/ea/84/4587ba5b1f267167ee715b7f66e6382cca6938e0a4b870adad93e44747e6/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:526e86aced14a65a5b0ec50827c745597c782ff46b571dbfe46192ab9e0b3c33", size = 595615, upload-time = "2025-10-14T15:05:32.074Z" }, + { url = "https://files.pythonhosted.org/packages/6a/0f/c6988c91d06e93cd0bb3d4a808bcf32375ca1904609835c3031799e3ecae/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:04e78dd0b6352db95507fd8cb46f39d185cf8c74e4cf1e4fbad1d3df96faf510", size = 474836, upload-time = "2025-10-14T15:05:33.209Z" }, + { url = "https://files.pythonhosted.org/packages/b4/36/ded8aebea91919485b7bbabbd14f5f359326cb5ec218cd67074d1e426d74/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c85794a4cfa094714fb9c08d4a218375b2b95b8ed1666e8677c349906246c05", size = 455099, upload-time = "2025-10-14T15:05:34.189Z" }, + { url = "https://files.pythonhosted.org/packages/98/e0/8c9bdba88af756a2fce230dd365fab2baf927ba42cd47521ee7498fd5211/watchfiles-1.1.1-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:74d5012b7630714b66be7b7b7a78855ef7ad58e8650c73afc4c076a1f480a8d6", size = 630626, upload-time = "2025-10-14T15:05:35.216Z" }, + { url = "https://files.pythonhosted.org/packages/2a/84/a95db05354bf2d19e438520d92a8ca475e578c647f78f53197f5a2f17aaf/watchfiles-1.1.1-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:8fbe85cb3201c7d380d3d0b90e63d520f15d6afe217165d7f98c9c649654db81", size = 622519, upload-time = "2025-10-14T15:05:36.259Z" }, + { url = "https://files.pythonhosted.org/packages/1d/ce/d8acdc8de545de995c339be67711e474c77d643555a9bb74a9334252bd55/watchfiles-1.1.1-cp314-cp314-win32.whl", hash = "sha256:3fa0b59c92278b5a7800d3ee7733da9d096d4aabcfabb9a928918bd276ef9b9b", size = 272078, upload-time = "2025-10-14T15:05:37.63Z" }, + { url = "https://files.pythonhosted.org/packages/c4/c9/a74487f72d0451524be827e8edec251da0cc1fcf111646a511ae752e1a3d/watchfiles-1.1.1-cp314-cp314-win_amd64.whl", hash = "sha256:c2047d0b6cea13b3316bdbafbfa0c4228ae593d995030fda39089d36e64fc03a", size = 287664, upload-time = "2025-10-14T15:05:38.95Z" }, + { url = "https://files.pythonhosted.org/packages/df/b8/8ac000702cdd496cdce998c6f4ee0ca1f15977bba51bdf07d872ebdfc34c/watchfiles-1.1.1-cp314-cp314-win_arm64.whl", hash = "sha256:842178b126593addc05acf6fce960d28bc5fae7afbaa2c6c1b3a7b9460e5be02", size = 277154, upload-time = "2025-10-14T15:05:39.954Z" }, + { url = "https://files.pythonhosted.org/packages/47/a8/e3af2184707c29f0f14b1963c0aace6529f9d1b8582d5b99f31bbf42f59e/watchfiles-1.1.1-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:88863fbbc1a7312972f1c511f202eb30866370ebb8493aef2812b9ff28156a21", size = 403820, upload-time = "2025-10-14T15:05:40.932Z" }, + { url = "https://files.pythonhosted.org/packages/c0/ec/e47e307c2f4bd75f9f9e8afbe3876679b18e1bcec449beca132a1c5ffb2d/watchfiles-1.1.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:55c7475190662e202c08c6c0f4d9e345a29367438cf8e8037f3155e10a88d5a5", size = 390510, upload-time = "2025-10-14T15:05:41.945Z" }, + { url = "https://files.pythonhosted.org/packages/d5/a0/ad235642118090f66e7b2f18fd5c42082418404a79205cdfca50b6309c13/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f53fa183d53a1d7a8852277c92b967ae99c2d4dcee2bfacff8868e6e30b15f7", size = 448408, upload-time = "2025-10-14T15:05:43.385Z" }, + { url = "https://files.pythonhosted.org/packages/df/85/97fa10fd5ff3332ae17e7e40e20784e419e28521549780869f1413742e9d/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6aae418a8b323732fa89721d86f39ec8f092fc2af67f4217a2b07fd3e93c6101", size = 458968, upload-time = "2025-10-14T15:05:44.404Z" }, + { url = "https://files.pythonhosted.org/packages/47/c2/9059c2e8966ea5ce678166617a7f75ecba6164375f3b288e50a40dc6d489/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f096076119da54a6080e8920cbdaac3dbee667eb91dcc5e5b78840b87415bd44", size = 488096, upload-time = "2025-10-14T15:05:45.398Z" }, + { url = "https://files.pythonhosted.org/packages/94/44/d90a9ec8ac309bc26db808a13e7bfc0e4e78b6fc051078a554e132e80160/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:00485f441d183717038ed2e887a7c868154f216877653121068107b227a2f64c", size = 596040, upload-time = "2025-10-14T15:05:46.502Z" }, + { url = "https://files.pythonhosted.org/packages/95/68/4e3479b20ca305cfc561db3ed207a8a1c745ee32bf24f2026a129d0ddb6e/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a55f3e9e493158d7bfdb60a1165035f1cf7d320914e7b7ea83fe22c6023b58fc", size = 473847, upload-time = "2025-10-14T15:05:47.484Z" }, + { url = "https://files.pythonhosted.org/packages/4f/55/2af26693fd15165c4ff7857e38330e1b61ab8c37d15dc79118cdba115b7a/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c91ed27800188c2ae96d16e3149f199d62f86c7af5f5f4d2c61a3ed8cd3666c", size = 455072, upload-time = "2025-10-14T15:05:48.928Z" }, + { url = "https://files.pythonhosted.org/packages/66/1d/d0d200b10c9311ec25d2273f8aad8c3ef7cc7ea11808022501811208a750/watchfiles-1.1.1-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:311ff15a0bae3714ffb603e6ba6dbfba4065ab60865d15a6ec544133bdb21099", size = 629104, upload-time = "2025-10-14T15:05:49.908Z" }, + { url = "https://files.pythonhosted.org/packages/e3/bd/fa9bb053192491b3867ba07d2343d9f2252e00811567d30ae8d0f78136fe/watchfiles-1.1.1-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:a916a2932da8f8ab582f242c065f5c81bed3462849ca79ee357dd9551b0e9b01", size = 622112, upload-time = "2025-10-14T15:05:50.941Z" }, +] + +[[package]] +name = "websockets" +version = "15.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/21/e6/26d09fab466b7ca9c7737474c52be4f76a40301b08362eb2dbc19dcc16c1/websockets-15.0.1.tar.gz", hash = "sha256:82544de02076bafba038ce055ee6412d68da13ab47f0c60cab827346de828dee", size = 177016, upload-time = "2025-03-05T20:03:41.606Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/9f/51f0cf64471a9d2b4d0fc6c534f323b664e7095640c34562f5182e5a7195/websockets-15.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ee443ef070bb3b6ed74514f5efaa37a252af57c90eb33b956d35c8e9c10a1931", size = 175440, upload-time = "2025-03-05T20:02:36.695Z" }, + { url = "https://files.pythonhosted.org/packages/8a/05/aa116ec9943c718905997412c5989f7ed671bc0188ee2ba89520e8765d7b/websockets-15.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5a939de6b7b4e18ca683218320fc67ea886038265fd1ed30173f5ce3f8e85675", size = 173098, upload-time = "2025-03-05T20:02:37.985Z" }, + { url = "https://files.pythonhosted.org/packages/ff/0b/33cef55ff24f2d92924923c99926dcce78e7bd922d649467f0eda8368923/websockets-15.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:746ee8dba912cd6fc889a8147168991d50ed70447bf18bcda7039f7d2e3d9151", size = 173329, upload-time = "2025-03-05T20:02:39.298Z" }, + { url = "https://files.pythonhosted.org/packages/31/1d/063b25dcc01faa8fada1469bdf769de3768b7044eac9d41f734fd7b6ad6d/websockets-15.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:595b6c3969023ecf9041b2936ac3827e4623bfa3ccf007575f04c5a6aa318c22", size = 183111, upload-time = "2025-03-05T20:02:40.595Z" }, + { url = "https://files.pythonhosted.org/packages/93/53/9a87ee494a51bf63e4ec9241c1ccc4f7c2f45fff85d5bde2ff74fcb68b9e/websockets-15.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c714d2fc58b5ca3e285461a4cc0c9a66bd0e24c5da9911e30158286c9b5be7f", size = 182054, upload-time = "2025-03-05T20:02:41.926Z" }, + { url = "https://files.pythonhosted.org/packages/ff/b2/83a6ddf56cdcbad4e3d841fcc55d6ba7d19aeb89c50f24dd7e859ec0805f/websockets-15.0.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f3c1e2ab208db911594ae5b4f79addeb3501604a165019dd221c0bdcabe4db8", size = 182496, upload-time = "2025-03-05T20:02:43.304Z" }, + { url = "https://files.pythonhosted.org/packages/98/41/e7038944ed0abf34c45aa4635ba28136f06052e08fc2168520bb8b25149f/websockets-15.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:229cf1d3ca6c1804400b0a9790dc66528e08a6a1feec0d5040e8b9eb14422375", size = 182829, upload-time = "2025-03-05T20:02:48.812Z" }, + { url = "https://files.pythonhosted.org/packages/e0/17/de15b6158680c7623c6ef0db361da965ab25d813ae54fcfeae2e5b9ef910/websockets-15.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:756c56e867a90fb00177d530dca4b097dd753cde348448a1012ed6c5131f8b7d", size = 182217, upload-time = "2025-03-05T20:02:50.14Z" }, + { url = "https://files.pythonhosted.org/packages/33/2b/1f168cb6041853eef0362fb9554c3824367c5560cbdaad89ac40f8c2edfc/websockets-15.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:558d023b3df0bffe50a04e710bc87742de35060580a293c2a984299ed83bc4e4", size = 182195, upload-time = "2025-03-05T20:02:51.561Z" }, + { url = "https://files.pythonhosted.org/packages/86/eb/20b6cdf273913d0ad05a6a14aed4b9a85591c18a987a3d47f20fa13dcc47/websockets-15.0.1-cp313-cp313-win32.whl", hash = "sha256:ba9e56e8ceeeedb2e080147ba85ffcd5cd0711b89576b83784d8605a7df455fa", size = 176393, upload-time = "2025-03-05T20:02:53.814Z" }, + { url = "https://files.pythonhosted.org/packages/1b/6c/c65773d6cab416a64d191d6ee8a8b1c68a09970ea6909d16965d26bfed1e/websockets-15.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:e09473f095a819042ecb2ab9465aee615bd9c2028e4ef7d933600a8401c79561", size = 176837, upload-time = "2025-03-05T20:02:55.237Z" }, + { url = "https://files.pythonhosted.org/packages/fa/a8/5b41e0da817d64113292ab1f8247140aac61cbf6cfd085d6a0fa77f4984f/websockets-15.0.1-py3-none-any.whl", hash = "sha256:f7a866fbc1e97b5c617ee4116daaa09b722101d4a3c170c787450ba409f9736f", size = 169743, upload-time = "2025-03-05T20:03:39.41Z" }, +] + +[[package]] +name = "wtforms" +version = "3.1.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6a/c7/96d10183c3470f1836846f7b9527d6cb0b6c2226ebca40f36fa29f23de60/wtforms-3.1.2.tar.gz", hash = "sha256:f8d76180d7239c94c6322f7990ae1216dae3659b7aa1cee94b6318bdffb474b9", size = 134705, upload-time = "2024-01-06T07:52:41.075Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/19/c3232f35e24dccfad372e9f341c4f3a1166ae7c66e4e1351a9467c921cc1/wtforms-3.1.2-py3-none-any.whl", hash = "sha256:bf831c042829c8cdbad74c27575098d541d039b1faa74c771545ecac916f2c07", size = 145961, upload-time = "2024-01-06T07:52:43.023Z" }, +] + +[[package]] +name = "yarl" +version = "1.22.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "idna" }, + { name = "multidict" }, + { name = "propcache" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/57/63/0c6ebca57330cd313f6102b16dd57ffaf3ec4c83403dcb45dbd15c6f3ea1/yarl-1.22.0.tar.gz", hash = "sha256:bebf8557577d4401ba8bd9ff33906f1376c877aa78d1fe216ad01b4d6745af71", size = 187169, upload-time = "2025-10-06T14:12:55.963Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ea/f3/d67de7260456ee105dc1d162d43a019ecad6b91e2f51809d6cddaa56690e/yarl-1.22.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8dee9c25c74997f6a750cd317b8ca63545169c098faee42c84aa5e506c819b53", size = 139980, upload-time = "2025-10-06T14:10:14.601Z" }, + { url = "https://files.pythonhosted.org/packages/01/88/04d98af0b47e0ef42597b9b28863b9060bb515524da0a65d5f4db160b2d5/yarl-1.22.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:01e73b85a5434f89fc4fe27dcda2aff08ddf35e4d47bbbea3bdcd25321af538a", size = 93424, upload-time = "2025-10-06T14:10:16.115Z" }, + { url = "https://files.pythonhosted.org/packages/18/91/3274b215fd8442a03975ce6bee5fe6aa57a8326b29b9d3d56234a1dca244/yarl-1.22.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:22965c2af250d20c873cdbee8ff958fb809940aeb2e74ba5f20aaf6b7ac8c70c", size = 93821, upload-time = "2025-10-06T14:10:17.993Z" }, + { url = "https://files.pythonhosted.org/packages/61/3a/caf4e25036db0f2da4ca22a353dfeb3c9d3c95d2761ebe9b14df8fc16eb0/yarl-1.22.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b4f15793aa49793ec8d1c708ab7f9eded1aa72edc5174cae703651555ed1b601", size = 373243, upload-time = "2025-10-06T14:10:19.44Z" }, + { url = "https://files.pythonhosted.org/packages/6e/9e/51a77ac7516e8e7803b06e01f74e78649c24ee1021eca3d6a739cb6ea49c/yarl-1.22.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e5542339dcf2747135c5c85f68680353d5cb9ffd741c0f2e8d832d054d41f35a", size = 342361, upload-time = "2025-10-06T14:10:21.124Z" }, + { url = "https://files.pythonhosted.org/packages/d4/f8/33b92454789dde8407f156c00303e9a891f1f51a0330b0fad7c909f87692/yarl-1.22.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5c401e05ad47a75869c3ab3e35137f8468b846770587e70d71e11de797d113df", size = 387036, upload-time = "2025-10-06T14:10:22.902Z" }, + { url = "https://files.pythonhosted.org/packages/d9/9a/c5db84ea024f76838220280f732970aa4ee154015d7f5c1bfb60a267af6f/yarl-1.22.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:243dda95d901c733f5b59214d28b0120893d91777cb8aa043e6ef059d3cddfe2", size = 397671, upload-time = "2025-10-06T14:10:24.523Z" }, + { url = "https://files.pythonhosted.org/packages/11/c9/cd8538dc2e7727095e0c1d867bad1e40c98f37763e6d995c1939f5fdc7b1/yarl-1.22.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bec03d0d388060058f5d291a813f21c011041938a441c593374da6077fe21b1b", size = 377059, upload-time = "2025-10-06T14:10:26.406Z" }, + { url = "https://files.pythonhosted.org/packages/a1/b9/ab437b261702ced75122ed78a876a6dec0a1b0f5e17a4ac7a9a2482d8abe/yarl-1.22.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b0748275abb8c1e1e09301ee3cf90c8a99678a4e92e4373705f2a2570d581273", size = 365356, upload-time = "2025-10-06T14:10:28.461Z" }, + { url = "https://files.pythonhosted.org/packages/b2/9d/8e1ae6d1d008a9567877b08f0ce4077a29974c04c062dabdb923ed98e6fe/yarl-1.22.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:47fdb18187e2a4e18fda2c25c05d8251a9e4a521edaed757fef033e7d8498d9a", size = 361331, upload-time = "2025-10-06T14:10:30.541Z" }, + { url = "https://files.pythonhosted.org/packages/ca/5a/09b7be3905962f145b73beb468cdd53db8aa171cf18c80400a54c5b82846/yarl-1.22.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c7044802eec4524fde550afc28edda0dd5784c4c45f0be151a2d3ba017daca7d", size = 382590, upload-time = "2025-10-06T14:10:33.352Z" }, + { url = "https://files.pythonhosted.org/packages/aa/7f/59ec509abf90eda5048b0bc3e2d7b5099dffdb3e6b127019895ab9d5ef44/yarl-1.22.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:139718f35149ff544caba20fce6e8a2f71f1e39b92c700d8438a0b1d2a631a02", size = 385316, upload-time = "2025-10-06T14:10:35.034Z" }, + { url = "https://files.pythonhosted.org/packages/e5/84/891158426bc8036bfdfd862fabd0e0fa25df4176ec793e447f4b85cf1be4/yarl-1.22.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e1b51bebd221006d3d2f95fbe124b22b247136647ae5dcc8c7acafba66e5ee67", size = 374431, upload-time = "2025-10-06T14:10:37.76Z" }, + { url = "https://files.pythonhosted.org/packages/bb/49/03da1580665baa8bef5e8ed34c6df2c2aca0a2f28bf397ed238cc1bbc6f2/yarl-1.22.0-cp313-cp313-win32.whl", hash = "sha256:d3e32536234a95f513bd374e93d717cf6b2231a791758de6c509e3653f234c95", size = 81555, upload-time = "2025-10-06T14:10:39.649Z" }, + { url = "https://files.pythonhosted.org/packages/9a/ee/450914ae11b419eadd067c6183ae08381cfdfcb9798b90b2b713bbebddda/yarl-1.22.0-cp313-cp313-win_amd64.whl", hash = "sha256:47743b82b76d89a1d20b83e60d5c20314cbd5ba2befc9cda8f28300c4a08ed4d", size = 86965, upload-time = "2025-10-06T14:10:41.313Z" }, + { url = "https://files.pythonhosted.org/packages/98/4d/264a01eae03b6cf629ad69bae94e3b0e5344741e929073678e84bf7a3e3b/yarl-1.22.0-cp313-cp313-win_arm64.whl", hash = "sha256:5d0fcda9608875f7d052eff120c7a5da474a6796fe4d83e152e0e4d42f6d1a9b", size = 81205, upload-time = "2025-10-06T14:10:43.167Z" }, + { url = "https://files.pythonhosted.org/packages/88/fc/6908f062a2f77b5f9f6d69cecb1747260831ff206adcbc5b510aff88df91/yarl-1.22.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:719ae08b6972befcba4310e49edb1161a88cdd331e3a694b84466bd938a6ab10", size = 146209, upload-time = "2025-10-06T14:10:44.643Z" }, + { url = "https://files.pythonhosted.org/packages/65/47/76594ae8eab26210b4867be6f49129861ad33da1f1ebdf7051e98492bf62/yarl-1.22.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:47d8a5c446df1c4db9d21b49619ffdba90e77c89ec6e283f453856c74b50b9e3", size = 95966, upload-time = "2025-10-06T14:10:46.554Z" }, + { url = "https://files.pythonhosted.org/packages/ab/ce/05e9828a49271ba6b5b038b15b3934e996980dd78abdfeb52a04cfb9467e/yarl-1.22.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:cfebc0ac8333520d2d0423cbbe43ae43c8838862ddb898f5ca68565e395516e9", size = 97312, upload-time = "2025-10-06T14:10:48.007Z" }, + { url = "https://files.pythonhosted.org/packages/d1/c5/7dffad5e4f2265b29c9d7ec869c369e4223166e4f9206fc2243ee9eea727/yarl-1.22.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4398557cbf484207df000309235979c79c4356518fd5c99158c7d38203c4da4f", size = 361967, upload-time = "2025-10-06T14:10:49.997Z" }, + { url = "https://files.pythonhosted.org/packages/50/b2/375b933c93a54bff7fc041e1a6ad2c0f6f733ffb0c6e642ce56ee3b39970/yarl-1.22.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2ca6fd72a8cd803be290d42f2dec5cdcd5299eeb93c2d929bf060ad9efaf5de0", size = 323949, upload-time = "2025-10-06T14:10:52.004Z" }, + { url = "https://files.pythonhosted.org/packages/66/50/bfc2a29a1d78644c5a7220ce2f304f38248dc94124a326794e677634b6cf/yarl-1.22.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ca1f59c4e1ab6e72f0a23c13fca5430f889634166be85dbf1013683e49e3278e", size = 361818, upload-time = "2025-10-06T14:10:54.078Z" }, + { url = "https://files.pythonhosted.org/packages/46/96/f3941a46af7d5d0f0498f86d71275696800ddcdd20426298e572b19b91ff/yarl-1.22.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6c5010a52015e7c70f86eb967db0f37f3c8bd503a695a49f8d45700144667708", size = 372626, upload-time = "2025-10-06T14:10:55.767Z" }, + { url = "https://files.pythonhosted.org/packages/c1/42/8b27c83bb875cd89448e42cd627e0fb971fa1675c9ec546393d18826cb50/yarl-1.22.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d7672ecf7557476642c88497c2f8d8542f8e36596e928e9bcba0e42e1e7d71f", size = 341129, upload-time = "2025-10-06T14:10:57.985Z" }, + { url = "https://files.pythonhosted.org/packages/49/36/99ca3122201b382a3cf7cc937b95235b0ac944f7e9f2d5331d50821ed352/yarl-1.22.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:3b7c88eeef021579d600e50363e0b6ee4f7f6f728cd3486b9d0f3ee7b946398d", size = 346776, upload-time = "2025-10-06T14:10:59.633Z" }, + { url = "https://files.pythonhosted.org/packages/85/b4/47328bf996acd01a4c16ef9dcd2f59c969f495073616586f78cd5f2efb99/yarl-1.22.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:f4afb5c34f2c6fecdcc182dfcfc6af6cccf1aa923eed4d6a12e9d96904e1a0d8", size = 334879, upload-time = "2025-10-06T14:11:01.454Z" }, + { url = "https://files.pythonhosted.org/packages/c2/ad/b77d7b3f14a4283bffb8e92c6026496f6de49751c2f97d4352242bba3990/yarl-1.22.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:59c189e3e99a59cf8d83cbb31d4db02d66cda5a1a4374e8a012b51255341abf5", size = 350996, upload-time = "2025-10-06T14:11:03.452Z" }, + { url = "https://files.pythonhosted.org/packages/81/c8/06e1d69295792ba54d556f06686cbd6a7ce39c22307100e3fb4a2c0b0a1d/yarl-1.22.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:5a3bf7f62a289fa90f1990422dc8dff5a458469ea71d1624585ec3a4c8d6960f", size = 356047, upload-time = "2025-10-06T14:11:05.115Z" }, + { url = "https://files.pythonhosted.org/packages/4b/b8/4c0e9e9f597074b208d18cef227d83aac36184bfbc6eab204ea55783dbc5/yarl-1.22.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:de6b9a04c606978fdfe72666fa216ffcf2d1a9f6a381058d4378f8d7b1e5de62", size = 342947, upload-time = "2025-10-06T14:11:08.137Z" }, + { url = "https://files.pythonhosted.org/packages/e0/e5/11f140a58bf4c6ad7aca69a892bff0ee638c31bea4206748fc0df4ebcb3a/yarl-1.22.0-cp313-cp313t-win32.whl", hash = "sha256:1834bb90991cc2999f10f97f5f01317f99b143284766d197e43cd5b45eb18d03", size = 86943, upload-time = "2025-10-06T14:11:10.284Z" }, + { url = "https://files.pythonhosted.org/packages/31/74/8b74bae38ed7fe6793d0c15a0c8207bbb819cf287788459e5ed230996cdd/yarl-1.22.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ff86011bd159a9d2dfc89c34cfd8aff12875980e3bd6a39ff097887520e60249", size = 93715, upload-time = "2025-10-06T14:11:11.739Z" }, + { url = "https://files.pythonhosted.org/packages/69/66/991858aa4b5892d57aef7ee1ba6b4d01ec3b7eb3060795d34090a3ca3278/yarl-1.22.0-cp313-cp313t-win_arm64.whl", hash = "sha256:7861058d0582b847bc4e3a4a4c46828a410bca738673f35a29ba3ca5db0b473b", size = 83857, upload-time = "2025-10-06T14:11:13.586Z" }, + { url = "https://files.pythonhosted.org/packages/46/b3/e20ef504049f1a1c54a814b4b9bed96d1ac0e0610c3b4da178f87209db05/yarl-1.22.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:34b36c2c57124530884d89d50ed2c1478697ad7473efd59cfd479945c95650e4", size = 140520, upload-time = "2025-10-06T14:11:15.465Z" }, + { url = "https://files.pythonhosted.org/packages/e4/04/3532d990fdbab02e5ede063676b5c4260e7f3abea2151099c2aa745acc4c/yarl-1.22.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:0dd9a702591ca2e543631c2a017e4a547e38a5c0f29eece37d9097e04a7ac683", size = 93504, upload-time = "2025-10-06T14:11:17.106Z" }, + { url = "https://files.pythonhosted.org/packages/11/63/ff458113c5c2dac9a9719ac68ee7c947cb621432bcf28c9972b1c0e83938/yarl-1.22.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:594fcab1032e2d2cc3321bb2e51271e7cd2b516c7d9aee780ece81b07ff8244b", size = 94282, upload-time = "2025-10-06T14:11:19.064Z" }, + { url = "https://files.pythonhosted.org/packages/a7/bc/315a56aca762d44a6aaaf7ad253f04d996cb6b27bad34410f82d76ea8038/yarl-1.22.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f3d7a87a78d46a2e3d5b72587ac14b4c16952dd0887dbb051451eceac774411e", size = 372080, upload-time = "2025-10-06T14:11:20.996Z" }, + { url = "https://files.pythonhosted.org/packages/3f/3f/08e9b826ec2e099ea6e7c69a61272f4f6da62cb5b1b63590bb80ca2e4a40/yarl-1.22.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:852863707010316c973162e703bddabec35e8757e67fcb8ad58829de1ebc8590", size = 338696, upload-time = "2025-10-06T14:11:22.847Z" }, + { url = "https://files.pythonhosted.org/packages/e3/9f/90360108e3b32bd76789088e99538febfea24a102380ae73827f62073543/yarl-1.22.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:131a085a53bfe839a477c0845acf21efc77457ba2bcf5899618136d64f3303a2", size = 387121, upload-time = "2025-10-06T14:11:24.889Z" }, + { url = "https://files.pythonhosted.org/packages/98/92/ab8d4657bd5b46a38094cfaea498f18bb70ce6b63508fd7e909bd1f93066/yarl-1.22.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:078a8aefd263f4d4f923a9677b942b445a2be970ca24548a8102689a3a8ab8da", size = 394080, upload-time = "2025-10-06T14:11:27.307Z" }, + { url = "https://files.pythonhosted.org/packages/f5/e7/d8c5a7752fef68205296201f8ec2bf718f5c805a7a7e9880576c67600658/yarl-1.22.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bca03b91c323036913993ff5c738d0842fc9c60c4648e5c8d98331526df89784", size = 372661, upload-time = "2025-10-06T14:11:29.387Z" }, + { url = "https://files.pythonhosted.org/packages/b6/2e/f4d26183c8db0bb82d491b072f3127fb8c381a6206a3a56332714b79b751/yarl-1.22.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:68986a61557d37bb90d3051a45b91fa3d5c516d177dfc6dd6f2f436a07ff2b6b", size = 364645, upload-time = "2025-10-06T14:11:31.423Z" }, + { url = "https://files.pythonhosted.org/packages/80/7c/428e5812e6b87cd00ee8e898328a62c95825bf37c7fa87f0b6bb2ad31304/yarl-1.22.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:4792b262d585ff0dff6bcb787f8492e40698443ec982a3568c2096433660c694", size = 355361, upload-time = "2025-10-06T14:11:33.055Z" }, + { url = "https://files.pythonhosted.org/packages/ec/2a/249405fd26776f8b13c067378ef4d7dd49c9098d1b6457cdd152a99e96a9/yarl-1.22.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:ebd4549b108d732dba1d4ace67614b9545b21ece30937a63a65dd34efa19732d", size = 381451, upload-time = "2025-10-06T14:11:35.136Z" }, + { url = "https://files.pythonhosted.org/packages/67/a8/fb6b1adbe98cf1e2dd9fad71003d3a63a1bc22459c6e15f5714eb9323b93/yarl-1.22.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:f87ac53513d22240c7d59203f25cc3beac1e574c6cd681bbfd321987b69f95fd", size = 383814, upload-time = "2025-10-06T14:11:37.094Z" }, + { url = "https://files.pythonhosted.org/packages/d9/f9/3aa2c0e480fb73e872ae2814c43bc1e734740bb0d54e8cb2a95925f98131/yarl-1.22.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:22b029f2881599e2f1b06f8f1db2ee63bd309e2293ba2d566e008ba12778b8da", size = 370799, upload-time = "2025-10-06T14:11:38.83Z" }, + { url = "https://files.pythonhosted.org/packages/50/3c/af9dba3b8b5eeb302f36f16f92791f3ea62e3f47763406abf6d5a4a3333b/yarl-1.22.0-cp314-cp314-win32.whl", hash = "sha256:6a635ea45ba4ea8238463b4f7d0e721bad669f80878b7bfd1f89266e2ae63da2", size = 82990, upload-time = "2025-10-06T14:11:40.624Z" }, + { url = "https://files.pythonhosted.org/packages/ac/30/ac3a0c5bdc1d6efd1b41fa24d4897a4329b3b1e98de9449679dd327af4f0/yarl-1.22.0-cp314-cp314-win_amd64.whl", hash = "sha256:0d6e6885777af0f110b0e5d7e5dda8b704efed3894da26220b7f3d887b839a79", size = 88292, upload-time = "2025-10-06T14:11:42.578Z" }, + { url = "https://files.pythonhosted.org/packages/df/0a/227ab4ff5b998a1b7410abc7b46c9b7a26b0ca9e86c34ba4b8d8bc7c63d5/yarl-1.22.0-cp314-cp314-win_arm64.whl", hash = "sha256:8218f4e98d3c10d683584cb40f0424f4b9fd6e95610232dd75e13743b070ee33", size = 82888, upload-time = "2025-10-06T14:11:44.863Z" }, + { url = "https://files.pythonhosted.org/packages/06/5e/a15eb13db90abd87dfbefb9760c0f3f257ac42a5cac7e75dbc23bed97a9f/yarl-1.22.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:45c2842ff0e0d1b35a6bf1cd6c690939dacb617a70827f715232b2e0494d55d1", size = 146223, upload-time = "2025-10-06T14:11:46.796Z" }, + { url = "https://files.pythonhosted.org/packages/18/82/9665c61910d4d84f41a5bf6837597c89e665fa88aa4941080704645932a9/yarl-1.22.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:d947071e6ebcf2e2bee8fce76e10faca8f7a14808ca36a910263acaacef08eca", size = 95981, upload-time = "2025-10-06T14:11:48.845Z" }, + { url = "https://files.pythonhosted.org/packages/5d/9a/2f65743589809af4d0a6d3aa749343c4b5f4c380cc24a8e94a3c6625a808/yarl-1.22.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:334b8721303e61b00019474cc103bdac3d7b1f65e91f0bfedeec2d56dfe74b53", size = 97303, upload-time = "2025-10-06T14:11:50.897Z" }, + { url = "https://files.pythonhosted.org/packages/b0/ab/5b13d3e157505c43c3b43b5a776cbf7b24a02bc4cccc40314771197e3508/yarl-1.22.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1e7ce67c34138a058fd092f67d07a72b8e31ff0c9236e751957465a24b28910c", size = 361820, upload-time = "2025-10-06T14:11:52.549Z" }, + { url = "https://files.pythonhosted.org/packages/fb/76/242a5ef4677615cf95330cfc1b4610e78184400699bdda0acb897ef5e49a/yarl-1.22.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d77e1b2c6d04711478cb1c4ab90db07f1609ccf06a287d5607fcd90dc9863acf", size = 323203, upload-time = "2025-10-06T14:11:54.225Z" }, + { url = "https://files.pythonhosted.org/packages/8c/96/475509110d3f0153b43d06164cf4195c64d16999e0c7e2d8a099adcd6907/yarl-1.22.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c4647674b6150d2cae088fc07de2738a84b8bcedebef29802cf0b0a82ab6face", size = 363173, upload-time = "2025-10-06T14:11:56.069Z" }, + { url = "https://files.pythonhosted.org/packages/c9/66/59db471aecfbd559a1fd48aedd954435558cd98c7d0da8b03cc6c140a32c/yarl-1.22.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:efb07073be061c8f79d03d04139a80ba33cbd390ca8f0297aae9cce6411e4c6b", size = 373562, upload-time = "2025-10-06T14:11:58.783Z" }, + { url = "https://files.pythonhosted.org/packages/03/1f/c5d94abc91557384719da10ff166b916107c1b45e4d0423a88457071dd88/yarl-1.22.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e51ac5435758ba97ad69617e13233da53908beccc6cfcd6c34bbed8dcbede486", size = 339828, upload-time = "2025-10-06T14:12:00.686Z" }, + { url = "https://files.pythonhosted.org/packages/5f/97/aa6a143d3afba17b6465733681c70cf175af89f76ec8d9286e08437a7454/yarl-1.22.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:33e32a0dd0c8205efa8e83d04fc9f19313772b78522d1bdc7d9aed706bfd6138", size = 347551, upload-time = "2025-10-06T14:12:02.628Z" }, + { url = "https://files.pythonhosted.org/packages/43/3c/45a2b6d80195959239a7b2a8810506d4eea5487dce61c2a3393e7fc3c52e/yarl-1.22.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:bf4a21e58b9cde0e401e683ebd00f6ed30a06d14e93f7c8fd059f8b6e8f87b6a", size = 334512, upload-time = "2025-10-06T14:12:04.871Z" }, + { url = "https://files.pythonhosted.org/packages/86/a0/c2ab48d74599c7c84cb104ebd799c5813de252bea0f360ffc29d270c2caa/yarl-1.22.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:e4b582bab49ac33c8deb97e058cd67c2c50dac0dd134874106d9c774fd272529", size = 352400, upload-time = "2025-10-06T14:12:06.624Z" }, + { url = "https://files.pythonhosted.org/packages/32/75/f8919b2eafc929567d3d8411f72bdb1a2109c01caaab4ebfa5f8ffadc15b/yarl-1.22.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:0b5bcc1a9c4839e7e30b7b30dd47fe5e7e44fb7054ec29b5bb8d526aa1041093", size = 357140, upload-time = "2025-10-06T14:12:08.362Z" }, + { url = "https://files.pythonhosted.org/packages/cf/72/6a85bba382f22cf78add705d8c3731748397d986e197e53ecc7835e76de7/yarl-1.22.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c0232bce2170103ec23c454e54a57008a9a72b5d1c3105dc2496750da8cfa47c", size = 341473, upload-time = "2025-10-06T14:12:10.994Z" }, + { url = "https://files.pythonhosted.org/packages/35/18/55e6011f7c044dc80b98893060773cefcfdbf60dfefb8cb2f58b9bacbd83/yarl-1.22.0-cp314-cp314t-win32.whl", hash = "sha256:8009b3173bcd637be650922ac455946197d858b3630b6d8787aa9e5c4564533e", size = 89056, upload-time = "2025-10-06T14:12:13.317Z" }, + { url = "https://files.pythonhosted.org/packages/f9/86/0f0dccb6e59a9e7f122c5afd43568b1d31b8ab7dda5f1b01fb5c7025c9a9/yarl-1.22.0-cp314-cp314t-win_amd64.whl", hash = "sha256:9fb17ea16e972c63d25d4a97f016d235c78dd2344820eb35bc034bc32012ee27", size = 96292, upload-time = "2025-10-06T14:12:15.398Z" }, + { url = "https://files.pythonhosted.org/packages/48/b7/503c98092fb3b344a179579f55814b613c1fbb1c23b3ec14a7b008a66a6e/yarl-1.22.0-cp314-cp314t-win_arm64.whl", hash = "sha256:9f6d73c1436b934e3f01df1e1b21ff765cd1d28c77dfb9ace207f746d4610ee1", size = 85171, upload-time = "2025-10-06T14:12:16.935Z" }, + { url = "https://files.pythonhosted.org/packages/73/ae/b48f95715333080afb75a4504487cbe142cae1268afc482d06692d605ae6/yarl-1.22.0-py3-none-any.whl", hash = "sha256:1380560bdba02b6b6c90de54133c81c9f2a453dee9912fe58c1dcced1edb7cff", size = 46814, upload-time = "2025-10-06T14:12:53.872Z" }, +] From 1199eca649999a71810db6801ae1d8e861bc3b6c Mon Sep 17 00:00:00 2001 From: Dohyun Lim Date: Fri, 9 Jan 2026 10:30:03 +0900 Subject: [PATCH 2/6] upgrade marketing template --- app/utils/chatgpt_prompt.py | 46 +++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/app/utils/chatgpt_prompt.py b/app/utils/chatgpt_prompt.py index 866e7c0..f2c2ef9 100644 --- a/app/utils/chatgpt_prompt.py +++ b/app/utils/chatgpt_prompt.py @@ -315,25 +315,41 @@ class ChatgptService: APIError, APIConnectionError, RateLimitError: OpenAI API 오류 """ prompt = f"""[ROLE] - 마케팅 콘텐츠 요약 전문가 +마케팅 콘텐츠 요약 전문가 - [INPUT] - {text} +[INPUT] +{text} - [TASK] - 위 텍스트를 분석하여 핵심 내용을 항목별로 구분하여 500자 이내로 요약해주세요. +[TASK] +위 텍스트를 분석하여 핵심 내용을 항목별로 구분하여 500자 이내로 요약해주세요. - [OUTPUT REQUIREMENTS] - - 항목별로 구분하여 정리 (예: 타겟 고객, 차별점, 지역 특성 등) - - 총 500자 이내로 요약 - - 핵심 정보만 간결하게 포함 - - 한국어로 작성 +[OUTPUT REQUIREMENTS] +- 5개 항목으로 구분: 타겟 고객, 핵심 차별점, 지역 특성, 시즌별 포인트, 추천 키워드 +- 각 항목은 줄바꿈으로 구분 +- 총 500자 이내로 요약 +- 핵심 정보만 간결하게 포함 +- 한국어로 작성 +- 특수문자 사용 금지 (괄호, 슬래시, 하이픈, 물결표 등 제외) +- 쉼표와 마침표만 사용하여 자연스러운 문장으로 작성 - [OUTPUT FORMAT] - --- - [항목별로 구분된 500자 이내 요약] - --- - """ +[OUTPUT FORMAT - 반드시 아래 형식 준수] +--- +타겟 고객 +[대상 고객층을 자연스러운 문장으로 설명] + +핵심 차별점 +[숙소의 차별화 포인트를 자연스러운 문장으로 설명] + +지역 특성 +[주변 관광지와 지역 특색을 자연스러운 문장으로 설명] + +시즌별 포인트 +[계절별 매력 포인트를 자연스러운 문장으로 설명] + +추천 키워드 +[마케팅에 활용할 키워드를 쉼표로 구분하여 나열] +--- +""" result = await self.generate(prompt=prompt) From 2b777f531414672416ef81fc8b13166a53a6c85b Mon Sep 17 00:00:00 2001 From: Dohyun Lim Date: Fri, 9 Jan 2026 10:31:30 +0900 Subject: [PATCH 3/6] remove .gitkeep --- .gitkeep | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .gitkeep diff --git a/.gitkeep b/.gitkeep deleted file mode 100644 index e69de29..0000000 From 94aae50564d2b6e7c540855227f60cdbb2b8fcb5 Mon Sep 17 00:00:00 2001 From: Dohyun Lim Date: Mon, 12 Jan 2026 13:46:28 +0900 Subject: [PATCH 4/6] update crawler for short url --- app/utils/nvMapScraper.py | 48 +++++++++- poc/crawling/nvMapScraper-2026-01-12.py | 119 ++++++++++++++++++++++++ 2 files changed, 163 insertions(+), 4 deletions(-) create mode 100644 poc/crawling/nvMapScraper-2026-01-12.py diff --git a/app/utils/nvMapScraper.py b/app/utils/nvMapScraper.py index 1edf149..7eec1bf 100644 --- a/app/utils/nvMapScraper.py +++ b/app/utils/nvMapScraper.py @@ -1,8 +1,10 @@ +import asyncio import json import logging import re import aiohttp +import bs4 from config import crawler_settings @@ -27,7 +29,7 @@ class NvMapScraper: """ GRAPHQL_URL: str = "https://pcmap-api.place.naver.com/graphql" - REQUEST_TIMEOUT = 30 # 초 + REQUEST_TIMEOUT = 120 # 초 OVERVIEW_QUERY: str = """ query getAccommodation($id: String!, $deviceType: String) { @@ -65,6 +67,7 @@ query getAccommodation($id: String!, $deviceType: String) { self.rawdata: dict | None = None self.image_link_list: list[str] | None = None self.base_info: dict | None = None + self.facility_info: str | None = None def _get_request_headers(self) -> dict: headers = self.DEFAULT_HEADERS.copy() @@ -72,8 +75,19 @@ query getAccommodation($id: String!, $deviceType: String) { headers["Cookie"] = self.cookies return headers - def parse_url(self) -> str: + async def parse_url(self) -> str: + """URL에서 place ID를 추출합니다. 단축 URL인 경우 실제 URL로 변환합니다.""" place_pattern = r"/place/(\d+)" + + # URL에 place가 없는 경우 단축 URL 처리 + if "place" not in self.url: + if "naver.me" in self.url: + async with aiohttp.ClientSession() as session: + async with session.get(self.url) as response: + self.url = str(response.url) + else: + raise GraphQLException("This URL does not contain a place ID") + match = re.search(place_pattern, self.url) if not match: raise GraphQLException("Failed to parse place ID from URL") @@ -81,14 +95,17 @@ query getAccommodation($id: String!, $deviceType: String) { async def scrap(self): try: - place_id = self.parse_url() + place_id = await self.parse_url() data = await self._call_get_accommodation(place_id) self.rawdata = data + fac_data = await self._get_facility_string(place_id) + self.rawdata["facilities"] = fac_data self.image_link_list = [ nv_image["origin"] for nv_image in data["data"]["business"]["images"]["images"] ] self.base_info = data["data"]["business"]["base"] + self.facility_info = fac_data self.scrap_type = "GraphQL" except GraphQLException: @@ -141,7 +158,7 @@ query getAccommodation($id: String!, $deviceType: String) { f"Request failed with status {response.status}" ) - except TimeoutError: + except (TimeoutError, asyncio.TimeoutError): logger.error(f"[NvMapScraper] Timeout - place_id: {place_id}") print(f"[NvMapScraper] Timeout - place_id: {place_id}") raise CrawlingTimeoutException(f"Request timed out after {self.REQUEST_TIMEOUT}s") @@ -151,6 +168,29 @@ query getAccommodation($id: String!, $deviceType: String) { print(f"[NvMapScraper] Client error: {e}") raise GraphQLException(f"Client error: {e}") + async def _get_facility_string(self, place_id: str) -> str | None: + """숙소 페이지에서 편의시설 정보를 크롤링합니다. + + Args: + place_id: 네이버 지도 장소 ID + + Returns: + 편의시설 정보 문자열 또는 None + """ + url = f"https://pcmap.place.naver.com/accommodation/{place_id}/home" + try: + async with aiohttp.ClientSession() as session: + async with session.get(url, headers=self._get_request_headers()) as response: + soup = bs4.BeautifulSoup(await response.read(), "html.parser") + c_elem = soup.find("span", "place_blind", string="편의") + if c_elem: + facilities = c_elem.parent.parent.find("div").string + return facilities + return None + except Exception as e: + logger.warning(f"[NvMapScraper] Failed to get facility info: {e}") + return None + # if __name__ == "__main__": # import asyncio diff --git a/poc/crawling/nvMapScraper-2026-01-12.py b/poc/crawling/nvMapScraper-2026-01-12.py new file mode 100644 index 0000000..7d155e4 --- /dev/null +++ b/poc/crawling/nvMapScraper-2026-01-12.py @@ -0,0 +1,119 @@ +import re +import aiohttp +import json +import asyncio +import bs4 + +PLACE_PATTERN = r"/place/(\d+)" +GRAPHQL_URL = "https://pcmap-api.place.naver.com/graphql" +NAVER_COOKIES="NAC=mQ7mBownbQf4A; NNB=TQPII6AKDBFGQ; PLACE_LANGUAGE=ko; NACT=1; nid_inf=1431570813; NID_AUT=k2T7FraXOdIMRCHzEZIFtHQup+I7b87M5fd7+p65AXZTdGB/gelRmW8s/Q4oDxm8; tooltipDisplayed=true; SRT30=1762660151; NID_SES=AAAB1Lpy3y3hGzuPbJpJl8vvFx18C+HXXuZEFou/YPgocHe7k2/5MpFlgE48X1JF7c7IPoU2khZKkkuLx+tsvWAzOf0TnG/G8RrBGeawnSluSJcKcTdKKRJ4cygKc/OabVxoc3TNZJWxer3vFtXBoXkDS5querVNS6wvcMhA/p4vkPKOeepwKLR+1IJERlQJWZw4q29IdAysrbBNn3Akf9mDA5eTYvMDLYyRkToRh10TVMW/yhyNQeMXlIdnR8U1ZCNqe/9ErYdos5gQDstswEJQQA0T2cHFGJOtmlYMPlnhWado5w521iZXGJyKcA9ZawizM/i5nK5xNYtPGS3cvImUYl6B5ulIipUJSqpj8v2XstK0TZlOGxHToXaVDrCNmSfCA9vFYbTb6xJHB2JRAT3Jik/z6QgLjJLBWRnsucMDqldxoiEDAUHEhY3pjgZ89quR3c3hwAuTlI9hBn5I3e5VQR0Y/GxoS9mIkMF8pJmcGneqnE0BNIt91RN6Se5rDM69B+JWppBXtSir1JGuXADaRLLMP8VlxJX949iH0UYTKWKsrD4OgNNK5aUx24nAH494WPknBMlx4fCMIeWzy7K3sEZkNUn/+A+eHraqIFfbGpveSCNM+8EqEjMgA+YRgg3eig==; _naver_usersession_=Kkgzim/64JicPJzgkIIvqQ==; page_uid=jesTPsqVWUZssE4qJeossssssD0-011300; SRT5=1762662010; BUC=z5Fu3sAYtFwpbRDrrDFYdn4AgK5hNkOqX-DdaLU7VJM=" + +OVERVIEW_QUERY = ''' +query getAccommodation($id: String!, $deviceType: String) { + business: placeDetail(input: {id: $id, isNx: true, deviceType: $deviceType}) { + base { + id + name + category + roadAddress + address + phone + virtualPhone + microReviews + conveniences + visitorReviewsTotal + } + images { images { origin url } } + cpImages(source: [ugcImage]) { images { origin url } } + } +}''' + +REQUEST_HEADERS = { + "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36", + "Referer": "https://map.naver.com/", + "Origin": "https://map.naver.com", + "Content-Type": "application/json", + "Cookie": NAVER_COOKIES +} + +class GraphQLException(Exception): + pass + +class nvMapScraper(): + url : str = None + scrap_type : str = None + rawdata : dict = None + image_link_list : list[str] = None + base_info : dict = None + + + def __init__(self, url): + self.url = url + + async def parse_url(self): + if 'place' not in self.url: + if 'naver.me' in self.url: + async with aiohttp.ClientSession() as session: + async with session.get(self.url) as response: + self.url = str(response.url) + else: + raise GraphQLException("this shorten url not have place id") + try: + place_id = re.search(PLACE_PATTERN, self.url)[1] + except Exception as E: + raise GraphQLException("Cannot find place id") + + return place_id + + async def scrap(self): + try: + place_id = await self.parse_url() + data = await self.call_get_accomodation(place_id) + self.rawdata = data + fac_data = await self.get_facility_string(place_id) + self.rawdata['facilities'] = fac_data + self.image_link_list = [nv_image['origin'] for nv_image in data['data']['business']['images']['images']] + self.base_info = data['data']['business']['base'] + self.facility_info = fac_data + self.scrap_type = "GraphQL" + + except GraphQLException as G: + print (G) + print("fallback") + self.scrap_type = "Playwright" + pass # 나중에 pw 이용한 crawling으로 fallback 추가 + + return + + async def call_get_accomodation(self, place_id): + payload = { + "operationName" : "getAccommodation", + "variables": { "id": place_id, "deviceType": "pc" }, + "query": OVERVIEW_QUERY, + } + json_payload = json.dumps(payload) + + async with aiohttp.ClientSession() as session: + async with session.post(GRAPHQL_URL, data=json_payload, headers=REQUEST_HEADERS) as response: + response.encoding = 'utf-8' + if response.status == 200: # 요청 성공 + return await response.json() # await 주의 + else: # 요청 실패 + print('실패 상태 코드:', response.status) + print(response.text) + raise Exception() + + async def get_facility_string(self, place_id): + url = f"https://pcmap.place.naver.com/accommodation/{place_id}/home" + async with aiohttp.ClientSession() as session: + async with session.get(url, headers=REQUEST_HEADERS) as response: + soup = bs4.BeautifulSoup(await response.read(), 'html.parser') + c_elem = soup.find('span', 'place_blind', string='편의') + facilities = c_elem.parent.parent.find('div').string + return facilities + +url = "https://naver.me/IgJGCCic" +scraper = nvMapScraper(url) +asyncio.run(scraper.scrap()) +print(scraper.image_link_list) +print(len(scraper.image_link_list)) \ No newline at end of file From b84c07c325e1613c457d6c65068011ced2c2d9ea Mon Sep 17 00:00:00 2001 From: Dohyun Lim Date: Mon, 12 Jan 2026 14:29:50 +0900 Subject: [PATCH 5/6] update toml --- pyproject.toml | 1 + uv.lock | 3208 ++++++++++++++++++++++++------------------------ 2 files changed, 1617 insertions(+), 1592 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index e4443c4..8fecce6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,6 +9,7 @@ dependencies = [ "aiohttp>=3.13.2", "aiomysql>=0.3.2", "asyncmy>=0.2.10", + "beautifulsoup4>=4.14.3", "fastapi-cli>=0.0.16", "fastapi[standard]>=0.125.0", "openai>=2.13.0", diff --git a/uv.lock b/uv.lock index 6693df3..92264f0 100644 --- a/uv.lock +++ b/uv.lock @@ -1,1592 +1,1616 @@ -version = 1 -revision = 3 -requires-python = ">=3.13" - -[[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, upload-time = "2025-10-09T20:51:04.358Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/bc/8a/340a1555ae33d7354dbca4faa54948d76d89a27ceef032c8c3bc661d003e/aiofiles-25.1.0-py3-none-any.whl", hash = "sha256:abe311e527c862958650f9438e859c1fa7568a141b22abcd015e120e86a85695", size = 14668, upload-time = "2025-10-09T20:51:03.174Z" }, -] - -[[package]] -name = "aiohappyeyeballs" -version = "2.6.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/26/30/f84a107a9c4331c14b2b586036f40965c128aa4fee4dda5d3d51cb14ad54/aiohappyeyeballs-2.6.1.tar.gz", hash = "sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558", size = 22760, upload-time = "2025-03-12T01:42:48.764Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl", hash = "sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8", size = 15265, upload-time = "2025-03-12T01:42:47.083Z" }, -] - -[[package]] -name = "aiohttp" -version = "3.13.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "aiohappyeyeballs" }, - { name = "aiosignal" }, - { name = "attrs" }, - { name = "frozenlist" }, - { name = "multidict" }, - { name = "propcache" }, - { name = "yarl" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/1c/ce/3b83ebba6b3207a7135e5fcaba49706f8a4b6008153b4e30540c982fae26/aiohttp-3.13.2.tar.gz", hash = "sha256:40176a52c186aefef6eb3cad2cdd30cd06e3afbe88fe8ab2af9c0b90f228daca", size = 7837994, upload-time = "2025-10-28T20:59:39.937Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/bf/78/7e90ca79e5aa39f9694dcfd74f4720782d3c6828113bb1f3197f7e7c4a56/aiohttp-3.13.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:7519bdc7dfc1940d201651b52bf5e03f5503bda45ad6eacf64dda98be5b2b6be", size = 732139, upload-time = "2025-10-28T20:57:02.455Z" }, - { url = "https://files.pythonhosted.org/packages/db/ed/1f59215ab6853fbaa5c8495fa6cbc39edfc93553426152b75d82a5f32b76/aiohttp-3.13.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:088912a78b4d4f547a1f19c099d5a506df17eacec3c6f4375e2831ec1d995742", size = 490082, upload-time = "2025-10-28T20:57:04.784Z" }, - { url = "https://files.pythonhosted.org/packages/68/7b/fe0fe0f5e05e13629d893c760465173a15ad0039c0a5b0d0040995c8075e/aiohttp-3.13.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5276807b9de9092af38ed23ce120539ab0ac955547b38563a9ba4f5b07b95293", size = 489035, upload-time = "2025-10-28T20:57:06.894Z" }, - { url = "https://files.pythonhosted.org/packages/d2/04/db5279e38471b7ac801d7d36a57d1230feeee130bbe2a74f72731b23c2b1/aiohttp-3.13.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1237c1375eaef0db4dcd7c2559f42e8af7b87ea7d295b118c60c36a6e61cb811", size = 1720387, upload-time = "2025-10-28T20:57:08.685Z" }, - { url = "https://files.pythonhosted.org/packages/31/07/8ea4326bd7dae2bd59828f69d7fdc6e04523caa55e4a70f4a8725a7e4ed2/aiohttp-3.13.2-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:96581619c57419c3d7d78703d5b78c1e5e5fc0172d60f555bdebaced82ded19a", size = 1688314, upload-time = "2025-10-28T20:57:10.693Z" }, - { url = "https://files.pythonhosted.org/packages/48/ab/3d98007b5b87ffd519d065225438cc3b668b2f245572a8cb53da5dd2b1bc/aiohttp-3.13.2-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a2713a95b47374169409d18103366de1050fe0ea73db358fc7a7acb2880422d4", size = 1756317, upload-time = "2025-10-28T20:57:12.563Z" }, - { url = "https://files.pythonhosted.org/packages/97/3d/801ca172b3d857fafb7b50c7c03f91b72b867a13abca982ed6b3081774ef/aiohttp-3.13.2-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:228a1cd556b3caca590e9511a89444925da87d35219a49ab5da0c36d2d943a6a", size = 1858539, upload-time = "2025-10-28T20:57:14.623Z" }, - { url = "https://files.pythonhosted.org/packages/f7/0d/4764669bdf47bd472899b3d3db91fffbe925c8e3038ec591a2fd2ad6a14d/aiohttp-3.13.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ac6cde5fba8d7d8c6ac963dbb0256a9854e9fafff52fbcc58fdf819357892c3e", size = 1739597, upload-time = "2025-10-28T20:57:16.399Z" }, - { url = "https://files.pythonhosted.org/packages/c4/52/7bd3c6693da58ba16e657eb904a5b6decfc48ecd06e9ac098591653b1566/aiohttp-3.13.2-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f2bef8237544f4e42878c61cef4e2839fee6346dc60f5739f876a9c50be7fcdb", size = 1555006, upload-time = "2025-10-28T20:57:18.288Z" }, - { url = "https://files.pythonhosted.org/packages/48/30/9586667acec5993b6f41d2ebcf96e97a1255a85f62f3c653110a5de4d346/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:16f15a4eac3bc2d76c45f7ebdd48a65d41b242eb6c31c2245463b40b34584ded", size = 1683220, upload-time = "2025-10-28T20:57:20.241Z" }, - { url = "https://files.pythonhosted.org/packages/71/01/3afe4c96854cfd7b30d78333852e8e851dceaec1c40fd00fec90c6402dd2/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:bb7fb776645af5cc58ab804c58d7eba545a97e047254a52ce89c157b5af6cd0b", size = 1712570, upload-time = "2025-10-28T20:57:22.253Z" }, - { url = "https://files.pythonhosted.org/packages/11/2c/22799d8e720f4697a9e66fd9c02479e40a49de3de2f0bbe7f9f78a987808/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:e1b4951125ec10c70802f2cb09736c895861cd39fd9dcb35107b4dc8ae6220b8", size = 1733407, upload-time = "2025-10-28T20:57:24.37Z" }, - { url = "https://files.pythonhosted.org/packages/34/cb/90f15dd029f07cebbd91f8238a8b363978b530cd128488085b5703683594/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:550bf765101ae721ee1d37d8095f47b1f220650f85fe1af37a90ce75bab89d04", size = 1550093, upload-time = "2025-10-28T20:57:26.257Z" }, - { url = "https://files.pythonhosted.org/packages/69/46/12dce9be9d3303ecbf4d30ad45a7683dc63d90733c2d9fe512be6716cd40/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:fe91b87fc295973096251e2d25a811388e7d8adf3bd2b97ef6ae78bc4ac6c476", size = 1758084, upload-time = "2025-10-28T20:57:28.349Z" }, - { url = "https://files.pythonhosted.org/packages/f9/c8/0932b558da0c302ffd639fc6362a313b98fdf235dc417bc2493da8394df7/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e0c8e31cfcc4592cb200160344b2fb6ae0f9e4effe06c644b5a125d4ae5ebe23", size = 1716987, upload-time = "2025-10-28T20:57:30.233Z" }, - { url = "https://files.pythonhosted.org/packages/5d/8b/f5bd1a75003daed099baec373aed678f2e9b34f2ad40d85baa1368556396/aiohttp-3.13.2-cp313-cp313-win32.whl", hash = "sha256:0740f31a60848d6edb296a0df827473eede90c689b8f9f2a4cdde74889eb2254", size = 425859, upload-time = "2025-10-28T20:57:32.105Z" }, - { url = "https://files.pythonhosted.org/packages/5d/28/a8a9fc6957b2cee8902414e41816b5ab5536ecf43c3b1843c10e82c559b2/aiohttp-3.13.2-cp313-cp313-win_amd64.whl", hash = "sha256:a88d13e7ca367394908f8a276b89d04a3652044612b9a408a0bb22a5ed976a1a", size = 452192, upload-time = "2025-10-28T20:57:34.166Z" }, - { url = "https://files.pythonhosted.org/packages/9b/36/e2abae1bd815f01c957cbf7be817b3043304e1c87bad526292a0410fdcf9/aiohttp-3.13.2-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:2475391c29230e063ef53a66669b7b691c9bfc3f1426a0f7bcdf1216bdbac38b", size = 735234, upload-time = "2025-10-28T20:57:36.415Z" }, - { url = "https://files.pythonhosted.org/packages/ca/e3/1ee62dde9b335e4ed41db6bba02613295a0d5b41f74a783c142745a12763/aiohttp-3.13.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:f33c8748abef4d8717bb20e8fb1b3e07c6adacb7fd6beaae971a764cf5f30d61", size = 490733, upload-time = "2025-10-28T20:57:38.205Z" }, - { url = "https://files.pythonhosted.org/packages/1a/aa/7a451b1d6a04e8d15a362af3e9b897de71d86feac3babf8894545d08d537/aiohttp-3.13.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ae32f24bbfb7dbb485a24b30b1149e2f200be94777232aeadba3eecece4d0aa4", size = 491303, upload-time = "2025-10-28T20:57:40.122Z" }, - { url = "https://files.pythonhosted.org/packages/57/1e/209958dbb9b01174870f6a7538cd1f3f28274fdbc88a750c238e2c456295/aiohttp-3.13.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d7f02042c1f009ffb70067326ef183a047425bb2ff3bc434ead4dd4a4a66a2b", size = 1717965, upload-time = "2025-10-28T20:57:42.28Z" }, - { url = "https://files.pythonhosted.org/packages/08/aa/6a01848d6432f241416bc4866cae8dc03f05a5a884d2311280f6a09c73d6/aiohttp-3.13.2-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:93655083005d71cd6c072cdab54c886e6570ad2c4592139c3fb967bfc19e4694", size = 1667221, upload-time = "2025-10-28T20:57:44.869Z" }, - { url = "https://files.pythonhosted.org/packages/87/4f/36c1992432d31bbc789fa0b93c768d2e9047ec8c7177e5cd84ea85155f36/aiohttp-3.13.2-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0db1e24b852f5f664cd728db140cf11ea0e82450471232a394b3d1a540b0f906", size = 1757178, upload-time = "2025-10-28T20:57:47.216Z" }, - { url = "https://files.pythonhosted.org/packages/ac/b4/8e940dfb03b7e0f68a82b88fd182b9be0a65cb3f35612fe38c038c3112cf/aiohttp-3.13.2-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b009194665bcd128e23eaddef362e745601afa4641930848af4c8559e88f18f9", size = 1838001, upload-time = "2025-10-28T20:57:49.337Z" }, - { url = "https://files.pythonhosted.org/packages/d7/ef/39f3448795499c440ab66084a9db7d20ca7662e94305f175a80f5b7e0072/aiohttp-3.13.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c038a8fdc8103cd51dbd986ecdce141473ffd9775a7a8057a6ed9c3653478011", size = 1716325, upload-time = "2025-10-28T20:57:51.327Z" }, - { url = "https://files.pythonhosted.org/packages/d7/51/b311500ffc860b181c05d91c59a1313bdd05c82960fdd4035a15740d431e/aiohttp-3.13.2-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:66bac29b95a00db411cd758fea0e4b9bdba6d549dfe333f9a945430f5f2cc5a6", size = 1547978, upload-time = "2025-10-28T20:57:53.554Z" }, - { url = "https://files.pythonhosted.org/packages/31/64/b9d733296ef79815226dab8c586ff9e3df41c6aff2e16c06697b2d2e6775/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4ebf9cfc9ba24a74cf0718f04aac2a3bbe745902cc7c5ebc55c0f3b5777ef213", size = 1682042, upload-time = "2025-10-28T20:57:55.617Z" }, - { url = "https://files.pythonhosted.org/packages/3f/30/43d3e0f9d6473a6db7d472104c4eff4417b1e9df01774cb930338806d36b/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:a4b88ebe35ce54205c7074f7302bd08a4cb83256a3e0870c72d6f68a3aaf8e49", size = 1680085, upload-time = "2025-10-28T20:57:57.59Z" }, - { url = "https://files.pythonhosted.org/packages/16/51/c709f352c911b1864cfd1087577760ced64b3e5bee2aa88b8c0c8e2e4972/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:98c4fb90bb82b70a4ed79ca35f656f4281885be076f3f970ce315402b53099ae", size = 1728238, upload-time = "2025-10-28T20:57:59.525Z" }, - { url = "https://files.pythonhosted.org/packages/19/e2/19bd4c547092b773caeb48ff5ae4b1ae86756a0ee76c16727fcfd281404b/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:ec7534e63ae0f3759df3a1ed4fa6bc8f75082a924b590619c0dd2f76d7043caa", size = 1544395, upload-time = "2025-10-28T20:58:01.914Z" }, - { url = "https://files.pythonhosted.org/packages/cf/87/860f2803b27dfc5ed7be532832a3498e4919da61299b4a1f8eb89b8ff44d/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:5b927cf9b935a13e33644cbed6c8c4b2d0f25b713d838743f8fe7191b33829c4", size = 1742965, upload-time = "2025-10-28T20:58:03.972Z" }, - { url = "https://files.pythonhosted.org/packages/67/7f/db2fc7618925e8c7a601094d5cbe539f732df4fb570740be88ed9e40e99a/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:88d6c017966a78c5265d996c19cdb79235be5e6412268d7e2ce7dee339471b7a", size = 1697585, upload-time = "2025-10-28T20:58:06.189Z" }, - { url = "https://files.pythonhosted.org/packages/0c/07/9127916cb09bb38284db5036036042b7b2c514c8ebaeee79da550c43a6d6/aiohttp-3.13.2-cp314-cp314-win32.whl", hash = "sha256:f7c183e786e299b5d6c49fb43a769f8eb8e04a2726a2bd5887b98b5cc2d67940", size = 431621, upload-time = "2025-10-28T20:58:08.636Z" }, - { url = "https://files.pythonhosted.org/packages/fb/41/554a8a380df6d3a2bba8a7726429a23f4ac62aaf38de43bb6d6cde7b4d4d/aiohttp-3.13.2-cp314-cp314-win_amd64.whl", hash = "sha256:fe242cd381e0fb65758faf5ad96c2e460df6ee5b2de1072fe97e4127927e00b4", size = 457627, upload-time = "2025-10-28T20:58:11Z" }, - { url = "https://files.pythonhosted.org/packages/c7/8e/3824ef98c039d3951cb65b9205a96dd2b20f22241ee17d89c5701557c826/aiohttp-3.13.2-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:f10d9c0b0188fe85398c61147bbd2a657d616c876863bfeff43376e0e3134673", size = 767360, upload-time = "2025-10-28T20:58:13.358Z" }, - { url = "https://files.pythonhosted.org/packages/a4/0f/6a03e3fc7595421274fa34122c973bde2d89344f8a881b728fa8c774e4f1/aiohttp-3.13.2-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:e7c952aefdf2460f4ae55c5e9c3e80aa72f706a6317e06020f80e96253b1accd", size = 504616, upload-time = "2025-10-28T20:58:15.339Z" }, - { url = "https://files.pythonhosted.org/packages/c6/aa/ed341b670f1bc8a6f2c6a718353d13b9546e2cef3544f573c6a1ff0da711/aiohttp-3.13.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c20423ce14771d98353d2e25e83591fa75dfa90a3c1848f3d7c68243b4fbded3", size = 509131, upload-time = "2025-10-28T20:58:17.693Z" }, - { url = "https://files.pythonhosted.org/packages/7f/f0/c68dac234189dae5c4bbccc0f96ce0cc16b76632cfc3a08fff180045cfa4/aiohttp-3.13.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e96eb1a34396e9430c19d8338d2ec33015e4a87ef2b4449db94c22412e25ccdf", size = 1864168, upload-time = "2025-10-28T20:58:20.113Z" }, - { url = "https://files.pythonhosted.org/packages/8f/65/75a9a76db8364b5d0e52a0c20eabc5d52297385d9af9c35335b924fafdee/aiohttp-3.13.2-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:23fb0783bc1a33640036465019d3bba069942616a6a2353c6907d7fe1ccdaf4e", size = 1719200, upload-time = "2025-10-28T20:58:22.583Z" }, - { url = "https://files.pythonhosted.org/packages/f5/55/8df2ed78d7f41d232f6bd3ff866b6f617026551aa1d07e2f03458f964575/aiohttp-3.13.2-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2e1a9bea6244a1d05a4e57c295d69e159a5c50d8ef16aa390948ee873478d9a5", size = 1843497, upload-time = "2025-10-28T20:58:24.672Z" }, - { url = "https://files.pythonhosted.org/packages/e9/e0/94d7215e405c5a02ccb6a35c7a3a6cfff242f457a00196496935f700cde5/aiohttp-3.13.2-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0a3d54e822688b56e9f6b5816fb3de3a3a64660efac64e4c2dc435230ad23bad", size = 1935703, upload-time = "2025-10-28T20:58:26.758Z" }, - { url = "https://files.pythonhosted.org/packages/0b/78/1eeb63c3f9b2d1015a4c02788fb543141aad0a03ae3f7a7b669b2483f8d4/aiohttp-3.13.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7a653d872afe9f33497215745da7a943d1dc15b728a9c8da1c3ac423af35178e", size = 1792738, upload-time = "2025-10-28T20:58:29.787Z" }, - { url = "https://files.pythonhosted.org/packages/41/75/aaf1eea4c188e51538c04cc568040e3082db263a57086ea74a7d38c39e42/aiohttp-3.13.2-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:56d36e80d2003fa3fc0207fac644216d8532e9504a785ef9a8fd013f84a42c61", size = 1624061, upload-time = "2025-10-28T20:58:32.529Z" }, - { url = "https://files.pythonhosted.org/packages/9b/c2/3b6034de81fbcc43de8aeb209073a2286dfb50b86e927b4efd81cf848197/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:78cd586d8331fb8e241c2dd6b2f4061778cc69e150514b39a9e28dd050475661", size = 1789201, upload-time = "2025-10-28T20:58:34.618Z" }, - { url = "https://files.pythonhosted.org/packages/c9/38/c15dcf6d4d890217dae79d7213988f4e5fe6183d43893a9cf2fe9e84ca8d/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:20b10bbfbff766294fe99987f7bb3b74fdd2f1a2905f2562132641ad434dcf98", size = 1776868, upload-time = "2025-10-28T20:58:38.835Z" }, - { url = "https://files.pythonhosted.org/packages/04/75/f74fd178ac81adf4f283a74847807ade5150e48feda6aef024403716c30c/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:9ec49dff7e2b3c85cdeaa412e9d438f0ecd71676fde61ec57027dd392f00c693", size = 1790660, upload-time = "2025-10-28T20:58:41.507Z" }, - { url = "https://files.pythonhosted.org/packages/e7/80/7368bd0d06b16b3aba358c16b919e9c46cf11587dc572091031b0e9e3ef0/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:94f05348c4406450f9d73d38efb41d669ad6cd90c7ee194810d0eefbfa875a7a", size = 1617548, upload-time = "2025-10-28T20:58:43.674Z" }, - { url = "https://files.pythonhosted.org/packages/7d/4b/a6212790c50483cb3212e507378fbe26b5086d73941e1ec4b56a30439688/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:fa4dcb605c6f82a80c7f95713c2b11c3b8e9893b3ebd2bc9bde93165ed6107be", size = 1817240, upload-time = "2025-10-28T20:58:45.787Z" }, - { url = "https://files.pythonhosted.org/packages/ff/f7/ba5f0ba4ea8d8f3c32850912944532b933acbf0f3a75546b89269b9b7dde/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:cf00e5db968c3f67eccd2778574cf64d8b27d95b237770aa32400bd7a1ca4f6c", size = 1762334, upload-time = "2025-10-28T20:58:47.936Z" }, - { url = "https://files.pythonhosted.org/packages/7e/83/1a5a1856574588b1cad63609ea9ad75b32a8353ac995d830bf5da9357364/aiohttp-3.13.2-cp314-cp314t-win32.whl", hash = "sha256:d23b5fe492b0805a50d3371e8a728a9134d8de5447dce4c885f5587294750734", size = 464685, upload-time = "2025-10-28T20:58:50.642Z" }, - { url = "https://files.pythonhosted.org/packages/9f/4d/d22668674122c08f4d56972297c51a624e64b3ed1efaa40187607a7cb66e/aiohttp-3.13.2-cp314-cp314t-win_amd64.whl", hash = "sha256:ff0a7b0a82a7ab905cbda74006318d1b12e37c797eb1b0d4eb3e316cf47f658f", size = 498093, upload-time = "2025-10-28T20:58:52.782Z" }, -] - -[[package]] -name = "aiomysql" -version = "0.3.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pymysql" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/29/e0/302aeffe8d90853556f47f3106b89c16cc2ec2a4d269bdfd82e3f4ae12cc/aiomysql-0.3.2.tar.gz", hash = "sha256:72d15ef5cfc34c03468eb41e1b90adb9fd9347b0b589114bd23ead569a02ac1a", size = 108311, upload-time = "2025-10-22T00:15:21.278Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/4c/af/aae0153c3e28712adaf462328f6c7a3c196a1c1c27b491de4377dd3e6b52/aiomysql-0.3.2-py3-none-any.whl", hash = "sha256:c82c5ba04137d7afd5c693a258bea8ead2aad77101668044143a991e04632eb2", size = 71834, upload-time = "2025-10-22T00:15:15.905Z" }, -] - -[[package]] -name = "aiosignal" -version = "1.4.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "frozenlist" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/61/62/06741b579156360248d1ec624842ad0edf697050bbaf7c3e46394e106ad1/aiosignal-1.4.0.tar.gz", hash = "sha256:f47eecd9468083c2029cc99945502cb7708b082c232f9aca65da147157b251c7", size = 25007, upload-time = "2025-07-03T22:54:43.528Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl", hash = "sha256:053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e", size = 7490, upload-time = "2025-07-03T22:54:42.156Z" }, -] - -[[package]] -name = "annotated-doc" -version = "0.0.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/57/ba/046ceea27344560984e26a590f90bc7f4a75b06701f653222458922b558c/annotated_doc-0.0.4.tar.gz", hash = "sha256:fbcda96e87e9c92ad167c2e53839e57503ecfda18804ea28102353485033faa4", size = 7288, upload-time = "2025-11-10T22:07:42.062Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl", hash = "sha256:571ac1dc6991c450b25a9c2d84a3705e2ae7a53467b5d111c24fa8baabbed320", size = 5303, upload-time = "2025-11-10T22:07:40.673Z" }, -] - -[[package]] -name = "annotated-types" -version = "0.7.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, -] - -[[package]] -name = "anyio" -version = "4.12.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "idna" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/16/ce/8a777047513153587e5434fd752e89334ac33e379aa3497db860eeb60377/anyio-4.12.0.tar.gz", hash = "sha256:73c693b567b0c55130c104d0b43a9baf3aa6a31fc6110116509f27bf75e21ec0", size = 228266, upload-time = "2025-11-28T23:37:38.911Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7f/9c/36c5c37947ebfb8c7f22e0eb6e4d188ee2d53aa3880f3f2744fb894f0cb1/anyio-4.12.0-py3-none-any.whl", hash = "sha256:dad2376a628f98eeca4881fc56cd06affd18f659b17a747d3ff0307ced94b1bb", size = 113362, upload-time = "2025-11-28T23:36:57.897Z" }, -] - -[[package]] -name = "asyncmy" -version = "0.2.10" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b5/76/55cc0577f9e838c5a5213bf33159b9e484c9d9820a2bafd4d6bfa631bf86/asyncmy-0.2.10.tar.gz", hash = "sha256:f4b67edadf7caa56bdaf1c2e6cf451150c0a86f5353744deabe4426fe27aff4e", size = 63889, upload-time = "2024-12-12T14:45:09.2Z" } - -[[package]] -name = "attrs" -version = "25.4.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6b/5c/685e6633917e101e5dcb62b9dd76946cbb57c26e133bae9e0cd36033c0a9/attrs-25.4.0.tar.gz", hash = "sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11", size = 934251, upload-time = "2025-10-06T13:54:44.725Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl", hash = "sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373", size = 67615, upload-time = "2025-10-06T13:54:43.17Z" }, -] - -[[package]] -name = "certifi" -version = "2025.11.12" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a2/8c/58f469717fa48465e4a50c014a0400602d3c437d7c0c468e17ada824da3a/certifi-2025.11.12.tar.gz", hash = "sha256:d8ab5478f2ecd78af242878415affce761ca6bc54a22a27e026d7c25357c3316", size = 160538, upload-time = "2025-11-12T02:54:51.517Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/70/7d/9bc192684cea499815ff478dfcdc13835ddf401365057044fb721ec6bddb/certifi-2025.11.12-py3-none-any.whl", hash = "sha256:97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b", size = 159438, upload-time = "2025-11-12T02:54:49.735Z" }, -] - -[[package]] -name = "click" -version = "8.3.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/3d/fa/656b739db8587d7b5dfa22e22ed02566950fbfbcdc20311993483657a5c0/click-8.3.1.tar.gz", hash = "sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a", size = 295065, upload-time = "2025-11-15T20:45:42.706Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl", hash = "sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6", size = 108274, upload-time = "2025-11-15T20:45:41.139Z" }, -] - -[[package]] -name = "colorama" -version = "0.4.6" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, -] - -[[package]] -name = "distro" -version = "1.9.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/fc/f8/98eea607f65de6527f8a2e8885fc8015d3e6f5775df186e443e0964a11c3/distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed", size = 60722, upload-time = "2023-12-24T09:54:32.31Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/12/b3/231ffd4ab1fc9d679809f356cebee130ac7daa00d6d6f3206dd4fd137e9e/distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2", size = 20277, upload-time = "2023-12-24T09:54:30.421Z" }, -] - -[[package]] -name = "dnspython" -version = "2.8.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8c/8b/57666417c0f90f08bcafa776861060426765fdb422eb10212086fb811d26/dnspython-2.8.0.tar.gz", hash = "sha256:181d3c6996452cb1189c4046c61599b84a5a86e099562ffde77d26984ff26d0f", size = 368251, upload-time = "2025-09-07T18:58:00.022Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ba/5a/18ad964b0086c6e62e2e7500f7edc89e3faa45033c71c1893d34eed2b2de/dnspython-2.8.0-py3-none-any.whl", hash = "sha256:01d9bbc4a2d76bf0db7c1f729812ded6d912bd318d3b1cf81d30c0f845dbf3af", size = 331094, upload-time = "2025-09-07T18:57:58.071Z" }, -] - -[[package]] -name = "email-validator" -version = "2.3.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "dnspython" }, - { name = "idna" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/f5/22/900cb125c76b7aaa450ce02fd727f452243f2e91a61af068b40adba60ea9/email_validator-2.3.0.tar.gz", hash = "sha256:9fc05c37f2f6cf439ff414f8fc46d917929974a82244c20eb10231ba60c54426", size = 51238, upload-time = "2025-08-26T13:09:06.831Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/de/15/545e2b6cf2e3be84bc1ed85613edd75b8aea69807a71c26f4ca6a9258e82/email_validator-2.3.0-py3-none-any.whl", hash = "sha256:80f13f623413e6b197ae73bb10bf4eb0908faf509ad8362c5edeb0be7fd450b4", size = 35604, upload-time = "2025-08-26T13:09:05.858Z" }, -] - -[[package]] -name = "fastapi" -version = "0.125.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "annotated-doc" }, - { name = "pydantic" }, - { name = "starlette" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/17/71/2df15009fb4bdd522a069d2fbca6007c6c5487fce5cb965be00fc335f1d1/fastapi-0.125.0.tar.gz", hash = "sha256:16b532691a33e2c5dee1dac32feb31dc6eb41a3dd4ff29a95f9487cb21c054c0", size = 370550, upload-time = "2025-12-17T21:41:44.15Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/34/2f/ff2fcc98f500713368d8b650e1bbc4a0b3ebcdd3e050dcdaad5f5a13fd7e/fastapi-0.125.0-py3-none-any.whl", hash = "sha256:2570ec4f3aecf5cca8f0428aed2398b774fcdfee6c2116f86e80513f2f86a7a1", size = 112888, upload-time = "2025-12-17T21:41:41.286Z" }, -] - -[package.optional-dependencies] -standard = [ - { name = "email-validator" }, - { name = "fastapi-cli", extra = ["standard"] }, - { name = "httpx" }, - { name = "jinja2" }, - { name = "python-multipart" }, - { name = "uvicorn", extra = ["standard"] }, -] - -[[package]] -name = "fastapi-cli" -version = "0.0.16" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "rich-toolkit" }, - { name = "typer" }, - { name = "uvicorn", extra = ["standard"] }, -] -sdist = { url = "https://files.pythonhosted.org/packages/99/75/9407a6b452be4c988feacec9c9d2f58d8f315162a6c7258d5a649d933ebe/fastapi_cli-0.0.16.tar.gz", hash = "sha256:e8a2a1ecf7a4e062e3b2eec63ae34387d1e142d4849181d936b23c4bdfe29073", size = 19447, upload-time = "2025-11-10T19:01:07.856Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/55/43/678528c19318394320ee43757648d5e0a8070cf391b31f69d931e5c840d2/fastapi_cli-0.0.16-py3-none-any.whl", hash = "sha256:addcb6d130b5b9c91adbbf3f2947fe115991495fdb442fe3e51b5fc6327df9f4", size = 12312, upload-time = "2025-11-10T19:01:06.728Z" }, -] - -[package.optional-dependencies] -standard = [ - { name = "fastapi-cloud-cli" }, - { name = "uvicorn", extra = ["standard"] }, -] - -[[package]] -name = "fastapi-cloud-cli" -version = "0.7.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "fastar" }, - { name = "httpx" }, - { name = "pydantic", extra = ["email"] }, - { name = "rich-toolkit" }, - { name = "rignore" }, - { name = "sentry-sdk" }, - { name = "typer" }, - { name = "uvicorn", extra = ["standard"] }, -] -sdist = { url = "https://files.pythonhosted.org/packages/cf/0d/3b0d2991f481c122c552b4ae38a8b400a75ab0edbc85536f2a6224f72da2/fastapi_cloud_cli-0.7.0.tar.gz", hash = "sha256:8b025944475c3d53262105886dfe051f46383e4f287787a46892b524922ac0b6", size = 30906, upload-time = "2025-12-16T12:51:49.082Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2d/aa/a2319f008e123b178a5c4cba34935e8459e72d24d8c31214b244ab7266a6/fastapi_cloud_cli-0.7.0-py3-none-any.whl", hash = "sha256:9a152e80d08d465d4a6c4f5c75aa8871d1e8919f69ff131b0567f04e95d5f36c", size = 23376, upload-time = "2025-12-16T12:51:47.847Z" }, -] - -[[package]] -name = "fastar" -version = "0.8.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/69/e7/f89d54fb04104114dd0552836dc2b47914f416cc0e200b409dd04a33de5e/fastar-0.8.0.tar.gz", hash = "sha256:f4d4d68dbf1c4c2808f0e730fac5843493fc849f70fe3ad3af60dfbaf68b9a12", size = 68524, upload-time = "2025-11-26T02:36:00.72Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/a5/79ecba3646e22d03eef1a66fb7fc156567213e2e4ab9faab3bbd4489e483/fastar-0.8.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:a3253a06845462ca2196024c7a18f5c0ba4de1532ab1c4bad23a40b332a06a6a", size = 706112, upload-time = "2025-11-26T02:34:39.237Z" }, - { url = "https://files.pythonhosted.org/packages/0a/03/4f883bce878218a8676c2d7ca09b50c856a5470bb3b7f63baf9521ea6995/fastar-0.8.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5cbeb3ebfa0980c68ff8b126295cc6b208ccd81b638aebc5a723d810a7a0e5d2", size = 628954, upload-time = "2025-11-26T02:34:23.705Z" }, - { url = "https://files.pythonhosted.org/packages/4f/f1/892e471f156b03d10ba48ace9384f5a896702a54506137462545f38e40b8/fastar-0.8.0-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1c0d5956b917daac77d333d48b3f0f3ff927b8039d5b32d8125462782369f761", size = 868685, upload-time = "2025-11-26T02:33:53.077Z" }, - { url = "https://files.pythonhosted.org/packages/39/ba/e24915045852e30014ec6840446975c03f4234d1c9270394b51d3ad18394/fastar-0.8.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:27b404db2b786b65912927ce7f3790964a4bcbde42cdd13091b82a89cd655e1c", size = 765044, upload-time = "2025-11-26T02:32:48.187Z" }, - { url = "https://files.pythonhosted.org/packages/14/2c/1aa11ac21a99984864c2fca4994e094319ff3a2046e7a0343c39317bd5b9/fastar-0.8.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0902fc89dcf1e7f07b8563032a4159fe2b835e4c16942c76fd63451d0e5f76a3", size = 764322, upload-time = "2025-11-26T02:33:03.859Z" }, - { url = "https://files.pythonhosted.org/packages/ba/f0/4b91902af39fe2d3bae7c85c6d789586b9fbcf618d7fdb3d37323915906d/fastar-0.8.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:069347e2f0f7a8b99bbac8cd1bc0e06c7b4a31dc964fc60d84b95eab3d869dc1", size = 931016, upload-time = "2025-11-26T02:33:19.902Z" }, - { url = "https://files.pythonhosted.org/packages/c9/97/8fc43a5a9c0a2dc195730f6f7a0f367d171282cd8be2511d0e87c6d2dad0/fastar-0.8.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7fd135306f6bfe9a835918280e0eb440b70ab303e0187d90ab51ca86e143f70d", size = 821308, upload-time = "2025-11-26T02:33:34.664Z" }, - { url = "https://files.pythonhosted.org/packages/0c/e9/058615b63a7fd27965e8c5966f393ed0c169f7ff5012e1674f21684de3ba/fastar-0.8.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78d06d6897f43c27154b5f2d0eb930a43a81b7eec73f6f0b0114814d4a10ab38", size = 821171, upload-time = "2025-11-26T02:34:08.498Z" }, - { url = "https://files.pythonhosted.org/packages/ca/cf/69e16a17961570a755c37ffb5b5aa7610d2e77807625f537989da66f2a9d/fastar-0.8.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a922f8439231fa0c32b15e8d70ff6d415619b9d40492029dabbc14a0c53b5f18", size = 986227, upload-time = "2025-11-26T02:34:55.06Z" }, - { url = "https://files.pythonhosted.org/packages/fb/83/2100192372e59b56f4ace37d7d9cabda511afd71b5febad1643d1c334271/fastar-0.8.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:a739abd51eb766384b4caff83050888e80cd75bbcfec61e6d1e64875f94e4a40", size = 1039395, upload-time = "2025-11-26T02:35:12.166Z" }, - { url = "https://files.pythonhosted.org/packages/75/15/cdd03aca972f55872efbb7cf7540c3fa7b97a75d626303a3ea46932163dc/fastar-0.8.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:5a65f419d808b23ac89d5cd1b13a2f340f15bc5d1d9af79f39fdb77bba48ff1b", size = 1044766, upload-time = "2025-11-26T02:35:29.62Z" }, - { url = "https://files.pythonhosted.org/packages/3d/29/945e69e4e2652329ace545999334ec31f1431fbae3abb0105587e11af2ae/fastar-0.8.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7bb2ae6c0cce58f0db1c9f20495e7557cca2c1ee9c69bbd90eafd54f139171c5", size = 994740, upload-time = "2025-11-26T02:35:47.887Z" }, - { url = "https://files.pythonhosted.org/packages/4b/5d/dbfe28f8cd1eb484bba0c62e5259b2cf6fea229d6ef43e05c06b5a78c034/fastar-0.8.0-cp313-cp313-win32.whl", hash = "sha256:b28753e0d18a643272597cb16d39f1053842aa43131ad3e260c03a2417d38401", size = 455990, upload-time = "2025-11-26T02:36:28.502Z" }, - { url = "https://files.pythonhosted.org/packages/e1/01/e965740bd36e60ef4c5aa2cbe42b6c4eb1dc3551009238a97c2e5e96bd23/fastar-0.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:620e5d737dce8321d49a5ebb7997f1fd0047cde3512082c27dc66d6ac8c1927a", size = 490227, upload-time = "2025-11-26T02:36:14.363Z" }, - { url = "https://files.pythonhosted.org/packages/dd/10/c99202719b83e5249f26902ae53a05aea67d840eeb242019322f20fc171c/fastar-0.8.0-cp313-cp313-win_arm64.whl", hash = "sha256:c4c4bd08df563120cd33e854fe0a93b81579e8571b11f9b7da9e84c37da2d6b6", size = 461078, upload-time = "2025-11-26T02:36:04.94Z" }, - { url = "https://files.pythonhosted.org/packages/96/4a/9573b87a0ef07580ed111e7230259aec31bb33ca3667963ebee77022ec61/fastar-0.8.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:50b36ce654ba44b0e13fae607ae17ee6e1597b69f71df1bee64bb8328d881dfc", size = 706041, upload-time = "2025-11-26T02:34:40.638Z" }, - { url = "https://files.pythonhosted.org/packages/4a/19/f95444a1d4f375333af49300aa75ee93afa3335c0e40fda528e460ed859c/fastar-0.8.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:63a892762683d7ab00df0227d5ea9677c62ff2cde9b875e666c0be569ed940f3", size = 628617, upload-time = "2025-11-26T02:34:24.893Z" }, - { url = "https://files.pythonhosted.org/packages/b3/c9/b51481b38b7e3f16ef2b9e233b1a3623386c939d745d6e41bbd389eaae30/fastar-0.8.0-cp314-cp314-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4ae6a145c1bff592644bde13f2115e0239f4b7babaf506d14e7d208483cf01a5", size = 869299, upload-time = "2025-11-26T02:33:54.274Z" }, - { url = "https://files.pythonhosted.org/packages/bf/02/3ba1267ee5ba7314e29c431cf82eaa68586f2c40cdfa08be3632b7d07619/fastar-0.8.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ae0ff7c0a1c7e1428404b81faee8aebef466bfd0be25bfe4dabf5d535c68741", size = 764667, upload-time = "2025-11-26T02:32:49.606Z" }, - { url = "https://files.pythonhosted.org/packages/1b/84/bf33530fd015b5d7c2cc69e0bce4a38d736754a6955487005aab1af6adcd/fastar-0.8.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dbfd87dbd217b45c898b2dbcd0169aae534b2c1c5cbe3119510881f6a5ac8ef5", size = 763993, upload-time = "2025-11-26T02:33:05.782Z" }, - { url = "https://files.pythonhosted.org/packages/da/e0/9564d24e7cea6321a8d921c6d2a457044a476ef197aa4708e179d3d97f0d/fastar-0.8.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9a5abd99fcba83ef28c8fe6ae2927edc79053db43a0457a962ed85c9bf150d37", size = 930153, upload-time = "2025-11-26T02:33:21.53Z" }, - { url = "https://files.pythonhosted.org/packages/35/b1/6f57fcd8d6e192cfebf97e58eb27751640ad93784c857b79039e84387b51/fastar-0.8.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:91d4c685620c3a9d6b5ae091dbabab4f98b20049b7ecc7976e19cc9016c0d5d6", size = 821177, upload-time = "2025-11-26T02:33:35.839Z" }, - { url = "https://files.pythonhosted.org/packages/b3/78/9e004ea9f3aa7466f5ddb6f9518780e1d2f0ed3ca55f093632982598bace/fastar-0.8.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f77c2f2cad76e9dc7b6701297adb1eba87d0485944b416fc2ccf5516c01219a3", size = 820652, upload-time = "2025-11-26T02:34:09.776Z" }, - { url = "https://files.pythonhosted.org/packages/42/95/b604ed536544005c9f1aee7c4c74b00150db3d8d535cd8232dc20f947063/fastar-0.8.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e7f07c4a3dada7757a8fc430a5b4a29e6ef696d2212747213f57086ffd970316", size = 985961, upload-time = "2025-11-26T02:34:56.401Z" }, - { url = "https://files.pythonhosted.org/packages/f2/7b/fa9d4d96a5d494bdb8699363bb9de8178c0c21a02e1d89cd6f913d127018/fastar-0.8.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:90c0c3fe55105c0aed8a83135dbdeb31e683455dbd326a1c48fa44c378b85616", size = 1039316, upload-time = "2025-11-26T02:35:13.807Z" }, - { url = "https://files.pythonhosted.org/packages/4e/f9/8462789243bc3f33e8401378ec6d54de4e20cfa60c96a0e15e3e9d1389bb/fastar-0.8.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:fb9ee51e5bffe0dab3d3126d3a4fac8d8f7235cedcb4b8e74936087ce1c157f3", size = 1045028, upload-time = "2025-11-26T02:35:31.079Z" }, - { url = "https://files.pythonhosted.org/packages/a5/71/9abb128777e616127194b509e98fcda3db797d76288c1a8c23dd22afc14f/fastar-0.8.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e380b1e8d30317f52406c43b11e98d11e1d68723bbd031e18049ea3497b59a6d", size = 994677, upload-time = "2025-11-26T02:35:49.391Z" }, - { url = "https://files.pythonhosted.org/packages/de/c1/b81b3f194853d7ad232a67a1d768f5f51a016f165cfb56cb31b31bbc6177/fastar-0.8.0-cp314-cp314-win32.whl", hash = "sha256:1c4ffc06e9c4a8ca498c07e094670d8d8c0d25b17ca6465b9774da44ea997ab1", size = 456687, upload-time = "2025-11-26T02:36:30.205Z" }, - { url = "https://files.pythonhosted.org/packages/cb/87/9e0cd4768a98181d56f0cdbab2363404cc15deb93f4aad3b99cd2761bbaa/fastar-0.8.0-cp314-cp314-win_amd64.whl", hash = "sha256:5517a8ad4726267c57a3e0e2a44430b782e00b230bf51c55b5728e758bb3a692", size = 490578, upload-time = "2025-11-26T02:36:16.218Z" }, - { url = "https://files.pythonhosted.org/packages/aa/1e/580a76cf91847654f2ad6520e956e93218f778540975bc4190d363f709e2/fastar-0.8.0-cp314-cp314-win_arm64.whl", hash = "sha256:58030551046ff4a8616931e52a36c83545ff05996db5beb6e0cd2b7e748aa309", size = 461473, upload-time = "2025-11-26T02:36:06.373Z" }, - { url = "https://files.pythonhosted.org/packages/58/4c/bdb5c6efe934f68708529c8c9d4055ebef5c4be370621966438f658b29bd/fastar-0.8.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:1e7d29b6bfecb29db126a08baf3c04a5ab667f6cea2b7067d3e623a67729c4a6", size = 705570, upload-time = "2025-11-26T02:34:42.01Z" }, - { url = "https://files.pythonhosted.org/packages/6d/78/f01ac7e71d5a37621bd13598a26e948a12b85ca8042f7ee1a0a8c9f59cda/fastar-0.8.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:05eb7b96940f9526b485f1d0b02393839f0f61cac4b1f60024984f8b326d2640", size = 627761, upload-time = "2025-11-26T02:34:26.152Z" }, - { url = "https://files.pythonhosted.org/packages/06/45/6df0ecda86ea9d2e95053c1a655d153dee55fc121b6e13ea6d1e246a50b6/fastar-0.8.0-cp314-cp314t-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:619352d8ac011794e2345c462189dc02ba634750d23cd9d86a9267dd71b1f278", size = 869414, upload-time = "2025-11-26T02:33:55.618Z" }, - { url = "https://files.pythonhosted.org/packages/b2/72/486421f5a8c0c377cc82e7a50c8a8ea899a6ec2aa72bde8f09fb667a2dc8/fastar-0.8.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74ebfecef3fe6d7a90355fac1402fd30636988332a1d33f3e80019a10782bb24", size = 763863, upload-time = "2025-11-26T02:32:51.051Z" }, - { url = "https://files.pythonhosted.org/packages/d4/64/39f654dbb41a3867fb1f2c8081c014d8f1d32ea10585d84cacbef0b32995/fastar-0.8.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2975aca5a639e26a3ab0d23b4b0628d6dd6d521146c3c11486d782be621a35aa", size = 763065, upload-time = "2025-11-26T02:33:07.274Z" }, - { url = "https://files.pythonhosted.org/packages/4e/bd/c011a34fb3534c4c3301f7c87c4ffd7e47f6113c904c092ddc8a59a303ea/fastar-0.8.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:afc438eaed8ff0dcdd9308268be5cb38c1db7e94c3ccca7c498ca13a4a4535a3", size = 930530, upload-time = "2025-11-26T02:33:23.117Z" }, - { url = "https://files.pythonhosted.org/packages/55/9d/aa6e887a7033c571b1064429222bbe09adc9a3c1e04f3d1788ba5838ebd5/fastar-0.8.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6ced0a5399cc0a84a858ef0a31ca2d0c24d3bbec4bcda506a9192d8119f3590a", size = 820572, upload-time = "2025-11-26T02:33:37.542Z" }, - { url = "https://files.pythonhosted.org/packages/ad/9c/7a3a2278a1052e1a5d98646de7c095a00cffd2492b3b84ce730e2f1cd93a/fastar-0.8.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec9b23da8c4c039da3fe2e358973c66976a0c8508aa06d6626b4403cb5666c19", size = 820649, upload-time = "2025-11-26T02:34:11.108Z" }, - { url = "https://files.pythonhosted.org/packages/02/9e/d38edc1f4438cd047e56137c26d94783ffade42e1b3bde620ccf17b771ef/fastar-0.8.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:dfba078fcd53478032fd0ceed56960ec6b7ff0511cfc013a8a3a4307e3a7bac4", size = 985653, upload-time = "2025-11-26T02:34:57.884Z" }, - { url = "https://files.pythonhosted.org/packages/69/d9/2147d0c19757e165cd62d41cec3f7b38fad2ad68ab784978b5f81716c7ea/fastar-0.8.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:ade56c94c14be356d295fecb47a3fcd473dd43a8803ead2e2b5b9e58feb6dcfa", size = 1038140, upload-time = "2025-11-26T02:35:15.778Z" }, - { url = "https://files.pythonhosted.org/packages/7f/1d/ec4c717ffb8a308871e9602ec3197d957e238dc0227127ac573ec9bca952/fastar-0.8.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:e48d938f9366db5e59441728f70b7f6c1ccfab7eff84f96f9b7e689b07786c52", size = 1045195, upload-time = "2025-11-26T02:35:32.865Z" }, - { url = "https://files.pythonhosted.org/packages/6a/9f/637334dc8c8f3bb391388b064ae13f0ad9402bc5a6c3e77b8887d0c31921/fastar-0.8.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:79c441dc1482ff51a54fb3f57ae6f7bb3d2cff88fa2cc5d196c519f8aab64a56", size = 994686, upload-time = "2025-11-26T02:35:51.392Z" }, - { url = "https://files.pythonhosted.org/packages/c9/e2/dfa19a4b260b8ab3581b7484dcb80c09b25324f4daa6b6ae1c7640d1607a/fastar-0.8.0-cp314-cp314t-win32.whl", hash = "sha256:187f61dc739afe45ac8e47ed7fd1adc45d52eac110cf27d579155720507d6fbe", size = 455767, upload-time = "2025-11-26T02:36:34.758Z" }, - { url = "https://files.pythonhosted.org/packages/51/47/df65c72afc1297797b255f90c4778b5d6f1f0f80282a134d5ab610310ed9/fastar-0.8.0-cp314-cp314t-win_amd64.whl", hash = "sha256:40e9d763cf8bf85ce2fa256e010aa795c0fe3d3bd1326d5c3084e6ce7857127e", size = 489971, upload-time = "2025-11-26T02:36:22.081Z" }, - { url = "https://files.pythonhosted.org/packages/85/11/0aa8455af26f0ae89e42be67f3a874255ee5d7f0f026fc86e8d56f76b428/fastar-0.8.0-cp314-cp314t-win_arm64.whl", hash = "sha256:e59673307b6a08210987059a2bdea2614fe26e3335d0e5d1a3d95f49a05b1418", size = 460467, upload-time = "2025-11-26T02:36:07.978Z" }, -] - -[[package]] -name = "frozenlist" -version = "1.8.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/2d/f5/c831fac6cc817d26fd54c7eaccd04ef7e0288806943f7cc5bbf69f3ac1f0/frozenlist-1.8.0.tar.gz", hash = "sha256:3ede829ed8d842f6cd48fc7081d7a41001a56f1f38603f9d49bf3020d59a31ad", size = 45875, upload-time = "2025-10-06T05:38:17.865Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2d/40/0832c31a37d60f60ed79e9dfb5a92e1e2af4f40a16a29abcc7992af9edff/frozenlist-1.8.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8d92f1a84bb12d9e56f818b3a746f3efba93c1b63c8387a73dde655e1e42282a", size = 85717, upload-time = "2025-10-06T05:36:27.341Z" }, - { url = "https://files.pythonhosted.org/packages/30/ba/b0b3de23f40bc55a7057bd38434e25c34fa48e17f20ee273bbde5e0650f3/frozenlist-1.8.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:96153e77a591c8adc2ee805756c61f59fef4cf4073a9275ee86fe8cba41241f7", size = 49651, upload-time = "2025-10-06T05:36:28.855Z" }, - { url = "https://files.pythonhosted.org/packages/0c/ab/6e5080ee374f875296c4243c381bbdef97a9ac39c6e3ce1d5f7d42cb78d6/frozenlist-1.8.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f21f00a91358803399890ab167098c131ec2ddd5f8f5fd5fe9c9f2c6fcd91e40", size = 49417, upload-time = "2025-10-06T05:36:29.877Z" }, - { url = "https://files.pythonhosted.org/packages/d5/4e/e4691508f9477ce67da2015d8c00acd751e6287739123113a9fca6f1604e/frozenlist-1.8.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fb30f9626572a76dfe4293c7194a09fb1fe93ba94c7d4f720dfae3b646b45027", size = 234391, upload-time = "2025-10-06T05:36:31.301Z" }, - { url = "https://files.pythonhosted.org/packages/40/76/c202df58e3acdf12969a7895fd6f3bc016c642e6726aa63bd3025e0fc71c/frozenlist-1.8.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eaa352d7047a31d87dafcacbabe89df0aa506abb5b1b85a2fb91bc3faa02d822", size = 233048, upload-time = "2025-10-06T05:36:32.531Z" }, - { url = "https://files.pythonhosted.org/packages/f9/c0/8746afb90f17b73ca5979c7a3958116e105ff796e718575175319b5bb4ce/frozenlist-1.8.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:03ae967b4e297f58f8c774c7eabcce57fe3c2434817d4385c50661845a058121", size = 226549, upload-time = "2025-10-06T05:36:33.706Z" }, - { url = "https://files.pythonhosted.org/packages/7e/eb/4c7eefc718ff72f9b6c4893291abaae5fbc0c82226a32dcd8ef4f7a5dbef/frozenlist-1.8.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f6292f1de555ffcc675941d65fffffb0a5bcd992905015f85d0592201793e0e5", size = 239833, upload-time = "2025-10-06T05:36:34.947Z" }, - { url = "https://files.pythonhosted.org/packages/c2/4e/e5c02187cf704224f8b21bee886f3d713ca379535f16893233b9d672ea71/frozenlist-1.8.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:29548f9b5b5e3460ce7378144c3010363d8035cea44bc0bf02d57f5a685e084e", size = 245363, upload-time = "2025-10-06T05:36:36.534Z" }, - { url = "https://files.pythonhosted.org/packages/1f/96/cb85ec608464472e82ad37a17f844889c36100eed57bea094518bf270692/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ec3cc8c5d4084591b4237c0a272cc4f50a5b03396a47d9caaf76f5d7b38a4f11", size = 229314, upload-time = "2025-10-06T05:36:38.582Z" }, - { url = "https://files.pythonhosted.org/packages/5d/6f/4ae69c550e4cee66b57887daeebe006fe985917c01d0fff9caab9883f6d0/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:517279f58009d0b1f2e7c1b130b377a349405da3f7621ed6bfae50b10adf20c1", size = 243365, upload-time = "2025-10-06T05:36:40.152Z" }, - { url = "https://files.pythonhosted.org/packages/7a/58/afd56de246cf11780a40a2c28dc7cbabbf06337cc8ddb1c780a2d97e88d8/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:db1e72ede2d0d7ccb213f218df6a078a9c09a7de257c2fe8fcef16d5925230b1", size = 237763, upload-time = "2025-10-06T05:36:41.355Z" }, - { url = "https://files.pythonhosted.org/packages/cb/36/cdfaf6ed42e2644740d4a10452d8e97fa1c062e2a8006e4b09f1b5fd7d63/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b4dec9482a65c54a5044486847b8a66bf10c9cb4926d42927ec4e8fd5db7fed8", size = 240110, upload-time = "2025-10-06T05:36:42.716Z" }, - { url = "https://files.pythonhosted.org/packages/03/a8/9ea226fbefad669f11b52e864c55f0bd57d3c8d7eb07e9f2e9a0b39502e1/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:21900c48ae04d13d416f0e1e0c4d81f7931f73a9dfa0b7a8746fb2fe7dd970ed", size = 233717, upload-time = "2025-10-06T05:36:44.251Z" }, - { url = "https://files.pythonhosted.org/packages/1e/0b/1b5531611e83ba7d13ccc9988967ea1b51186af64c42b7a7af465dcc9568/frozenlist-1.8.0-cp313-cp313-win32.whl", hash = "sha256:8b7b94a067d1c504ee0b16def57ad5738701e4ba10cec90529f13fa03c833496", size = 39628, upload-time = "2025-10-06T05:36:45.423Z" }, - { url = "https://files.pythonhosted.org/packages/d8/cf/174c91dbc9cc49bc7b7aab74d8b734e974d1faa8f191c74af9b7e80848e6/frozenlist-1.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:878be833caa6a3821caf85eb39c5ba92d28e85df26d57afb06b35b2efd937231", size = 43882, upload-time = "2025-10-06T05:36:46.796Z" }, - { url = "https://files.pythonhosted.org/packages/c1/17/502cd212cbfa96eb1388614fe39a3fc9ab87dbbe042b66f97acb57474834/frozenlist-1.8.0-cp313-cp313-win_arm64.whl", hash = "sha256:44389d135b3ff43ba8cc89ff7f51f5a0bb6b63d829c8300f79a2fe4fe61bcc62", size = 39676, upload-time = "2025-10-06T05:36:47.8Z" }, - { url = "https://files.pythonhosted.org/packages/d2/5c/3bbfaa920dfab09e76946a5d2833a7cbdf7b9b4a91c714666ac4855b88b4/frozenlist-1.8.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:e25ac20a2ef37e91c1b39938b591457666a0fa835c7783c3a8f33ea42870db94", size = 89235, upload-time = "2025-10-06T05:36:48.78Z" }, - { url = "https://files.pythonhosted.org/packages/d2/d6/f03961ef72166cec1687e84e8925838442b615bd0b8854b54923ce5b7b8a/frozenlist-1.8.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:07cdca25a91a4386d2e76ad992916a85038a9b97561bf7a3fd12d5d9ce31870c", size = 50742, upload-time = "2025-10-06T05:36:49.837Z" }, - { url = "https://files.pythonhosted.org/packages/1e/bb/a6d12b7ba4c3337667d0e421f7181c82dda448ce4e7ad7ecd249a16fa806/frozenlist-1.8.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4e0c11f2cc6717e0a741f84a527c52616140741cd812a50422f83dc31749fb52", size = 51725, upload-time = "2025-10-06T05:36:50.851Z" }, - { url = "https://files.pythonhosted.org/packages/bc/71/d1fed0ffe2c2ccd70b43714c6cab0f4188f09f8a67a7914a6b46ee30f274/frozenlist-1.8.0-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b3210649ee28062ea6099cfda39e147fa1bc039583c8ee4481cb7811e2448c51", size = 284533, upload-time = "2025-10-06T05:36:51.898Z" }, - { url = "https://files.pythonhosted.org/packages/c9/1f/fb1685a7b009d89f9bf78a42d94461bc06581f6e718c39344754a5d9bada/frozenlist-1.8.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:581ef5194c48035a7de2aefc72ac6539823bb71508189e5de01d60c9dcd5fa65", size = 292506, upload-time = "2025-10-06T05:36:53.101Z" }, - { url = "https://files.pythonhosted.org/packages/e6/3b/b991fe1612703f7e0d05c0cf734c1b77aaf7c7d321df4572e8d36e7048c8/frozenlist-1.8.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3ef2d026f16a2b1866e1d86fc4e1291e1ed8a387b2c333809419a2f8b3a77b82", size = 274161, upload-time = "2025-10-06T05:36:54.309Z" }, - { url = "https://files.pythonhosted.org/packages/ca/ec/c5c618767bcdf66e88945ec0157d7f6c4a1322f1473392319b7a2501ded7/frozenlist-1.8.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5500ef82073f599ac84d888e3a8c1f77ac831183244bfd7f11eaa0289fb30714", size = 294676, upload-time = "2025-10-06T05:36:55.566Z" }, - { url = "https://files.pythonhosted.org/packages/7c/ce/3934758637d8f8a88d11f0585d6495ef54b2044ed6ec84492a91fa3b27aa/frozenlist-1.8.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:50066c3997d0091c411a66e710f4e11752251e6d2d73d70d8d5d4c76442a199d", size = 300638, upload-time = "2025-10-06T05:36:56.758Z" }, - { url = "https://files.pythonhosted.org/packages/fc/4f/a7e4d0d467298f42de4b41cbc7ddaf19d3cfeabaf9ff97c20c6c7ee409f9/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:5c1c8e78426e59b3f8005e9b19f6ff46e5845895adbde20ece9218319eca6506", size = 283067, upload-time = "2025-10-06T05:36:57.965Z" }, - { url = "https://files.pythonhosted.org/packages/dc/48/c7b163063d55a83772b268e6d1affb960771b0e203b632cfe09522d67ea5/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:eefdba20de0d938cec6a89bd4d70f346a03108a19b9df4248d3cf0d88f1b0f51", size = 292101, upload-time = "2025-10-06T05:36:59.237Z" }, - { url = "https://files.pythonhosted.org/packages/9f/d0/2366d3c4ecdc2fd391e0afa6e11500bfba0ea772764d631bbf82f0136c9d/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:cf253e0e1c3ceb4aaff6df637ce033ff6535fb8c70a764a8f46aafd3d6ab798e", size = 289901, upload-time = "2025-10-06T05:37:00.811Z" }, - { url = "https://files.pythonhosted.org/packages/b8/94/daff920e82c1b70e3618a2ac39fbc01ae3e2ff6124e80739ce5d71c9b920/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:032efa2674356903cd0261c4317a561a6850f3ac864a63fc1583147fb05a79b0", size = 289395, upload-time = "2025-10-06T05:37:02.115Z" }, - { url = "https://files.pythonhosted.org/packages/e3/20/bba307ab4235a09fdcd3cc5508dbabd17c4634a1af4b96e0f69bfe551ebd/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6da155091429aeba16851ecb10a9104a108bcd32f6c1642867eadaee401c1c41", size = 283659, upload-time = "2025-10-06T05:37:03.711Z" }, - { url = "https://files.pythonhosted.org/packages/fd/00/04ca1c3a7a124b6de4f8a9a17cc2fcad138b4608e7a3fc5877804b8715d7/frozenlist-1.8.0-cp313-cp313t-win32.whl", hash = "sha256:0f96534f8bfebc1a394209427d0f8a63d343c9779cda6fc25e8e121b5fd8555b", size = 43492, upload-time = "2025-10-06T05:37:04.915Z" }, - { url = "https://files.pythonhosted.org/packages/59/5e/c69f733a86a94ab10f68e496dc6b7e8bc078ebb415281d5698313e3af3a1/frozenlist-1.8.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5d63a068f978fc69421fb0e6eb91a9603187527c86b7cd3f534a5b77a592b888", size = 48034, upload-time = "2025-10-06T05:37:06.343Z" }, - { url = "https://files.pythonhosted.org/packages/16/6c/be9d79775d8abe79b05fa6d23da99ad6e7763a1d080fbae7290b286093fd/frozenlist-1.8.0-cp313-cp313t-win_arm64.whl", hash = "sha256:bf0a7e10b077bf5fb9380ad3ae8ce20ef919a6ad93b4552896419ac7e1d8e042", size = 41749, upload-time = "2025-10-06T05:37:07.431Z" }, - { url = "https://files.pythonhosted.org/packages/f1/c8/85da824b7e7b9b6e7f7705b2ecaf9591ba6f79c1177f324c2735e41d36a2/frozenlist-1.8.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:cee686f1f4cadeb2136007ddedd0aaf928ab95216e7691c63e50a8ec066336d0", size = 86127, upload-time = "2025-10-06T05:37:08.438Z" }, - { url = "https://files.pythonhosted.org/packages/8e/e8/a1185e236ec66c20afd72399522f142c3724c785789255202d27ae992818/frozenlist-1.8.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:119fb2a1bd47307e899c2fac7f28e85b9a543864df47aa7ec9d3c1b4545f096f", size = 49698, upload-time = "2025-10-06T05:37:09.48Z" }, - { url = "https://files.pythonhosted.org/packages/a1/93/72b1736d68f03fda5fdf0f2180fb6caaae3894f1b854d006ac61ecc727ee/frozenlist-1.8.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4970ece02dbc8c3a92fcc5228e36a3e933a01a999f7094ff7c23fbd2beeaa67c", size = 49749, upload-time = "2025-10-06T05:37:10.569Z" }, - { url = "https://files.pythonhosted.org/packages/a7/b2/fabede9fafd976b991e9f1b9c8c873ed86f202889b864756f240ce6dd855/frozenlist-1.8.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:cba69cb73723c3f329622e34bdbf5ce1f80c21c290ff04256cff1cd3c2036ed2", size = 231298, upload-time = "2025-10-06T05:37:11.993Z" }, - { url = "https://files.pythonhosted.org/packages/3a/3b/d9b1e0b0eed36e70477ffb8360c49c85c8ca8ef9700a4e6711f39a6e8b45/frozenlist-1.8.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:778a11b15673f6f1df23d9586f83c4846c471a8af693a22e066508b77d201ec8", size = 232015, upload-time = "2025-10-06T05:37:13.194Z" }, - { url = "https://files.pythonhosted.org/packages/dc/94/be719d2766c1138148564a3960fc2c06eb688da592bdc25adcf856101be7/frozenlist-1.8.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0325024fe97f94c41c08872db482cf8ac4800d80e79222c6b0b7b162d5b13686", size = 225038, upload-time = "2025-10-06T05:37:14.577Z" }, - { url = "https://files.pythonhosted.org/packages/e4/09/6712b6c5465f083f52f50cf74167b92d4ea2f50e46a9eea0523d658454ae/frozenlist-1.8.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:97260ff46b207a82a7567b581ab4190bd4dfa09f4db8a8b49d1a958f6aa4940e", size = 240130, upload-time = "2025-10-06T05:37:15.781Z" }, - { url = "https://files.pythonhosted.org/packages/f8/d4/cd065cdcf21550b54f3ce6a22e143ac9e4836ca42a0de1022da8498eac89/frozenlist-1.8.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:54b2077180eb7f83dd52c40b2750d0a9f175e06a42e3213ce047219de902717a", size = 242845, upload-time = "2025-10-06T05:37:17.037Z" }, - { url = "https://files.pythonhosted.org/packages/62/c3/f57a5c8c70cd1ead3d5d5f776f89d33110b1addae0ab010ad774d9a44fb9/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2f05983daecab868a31e1da44462873306d3cbfd76d1f0b5b69c473d21dbb128", size = 229131, upload-time = "2025-10-06T05:37:18.221Z" }, - { url = "https://files.pythonhosted.org/packages/6c/52/232476fe9cb64f0742f3fde2b7d26c1dac18b6d62071c74d4ded55e0ef94/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:33f48f51a446114bc5d251fb2954ab0164d5be02ad3382abcbfe07e2531d650f", size = 240542, upload-time = "2025-10-06T05:37:19.771Z" }, - { url = "https://files.pythonhosted.org/packages/5f/85/07bf3f5d0fb5414aee5f47d33c6f5c77bfe49aac680bfece33d4fdf6a246/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:154e55ec0655291b5dd1b8731c637ecdb50975a2ae70c606d100750a540082f7", size = 237308, upload-time = "2025-10-06T05:37:20.969Z" }, - { url = "https://files.pythonhosted.org/packages/11/99/ae3a33d5befd41ac0ca2cc7fd3aa707c9c324de2e89db0e0f45db9a64c26/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:4314debad13beb564b708b4a496020e5306c7333fa9a3ab90374169a20ffab30", size = 238210, upload-time = "2025-10-06T05:37:22.252Z" }, - { url = "https://files.pythonhosted.org/packages/b2/60/b1d2da22f4970e7a155f0adde9b1435712ece01b3cd45ba63702aea33938/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:073f8bf8becba60aa931eb3bc420b217bb7d5b8f4750e6f8b3be7f3da85d38b7", size = 231972, upload-time = "2025-10-06T05:37:23.5Z" }, - { url = "https://files.pythonhosted.org/packages/3f/ab/945b2f32de889993b9c9133216c068b7fcf257d8595a0ac420ac8677cab0/frozenlist-1.8.0-cp314-cp314-win32.whl", hash = "sha256:bac9c42ba2ac65ddc115d930c78d24ab8d4f465fd3fc473cdedfccadb9429806", size = 40536, upload-time = "2025-10-06T05:37:25.581Z" }, - { url = "https://files.pythonhosted.org/packages/59/ad/9caa9b9c836d9ad6f067157a531ac48b7d36499f5036d4141ce78c230b1b/frozenlist-1.8.0-cp314-cp314-win_amd64.whl", hash = "sha256:3e0761f4d1a44f1d1a47996511752cf3dcec5bbdd9cc2b4fe595caf97754b7a0", size = 44330, upload-time = "2025-10-06T05:37:26.928Z" }, - { url = "https://files.pythonhosted.org/packages/82/13/e6950121764f2676f43534c555249f57030150260aee9dcf7d64efda11dd/frozenlist-1.8.0-cp314-cp314-win_arm64.whl", hash = "sha256:d1eaff1d00c7751b7c6662e9c5ba6eb2c17a2306ba5e2a37f24ddf3cc953402b", size = 40627, upload-time = "2025-10-06T05:37:28.075Z" }, - { url = "https://files.pythonhosted.org/packages/c0/c7/43200656ecc4e02d3f8bc248df68256cd9572b3f0017f0a0c4e93440ae23/frozenlist-1.8.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:d3bb933317c52d7ea5004a1c442eef86f426886fba134ef8cf4226ea6ee1821d", size = 89238, upload-time = "2025-10-06T05:37:29.373Z" }, - { url = "https://files.pythonhosted.org/packages/d1/29/55c5f0689b9c0fb765055629f472c0de484dcaf0acee2f7707266ae3583c/frozenlist-1.8.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:8009897cdef112072f93a0efdce29cd819e717fd2f649ee3016efd3cd885a7ed", size = 50738, upload-time = "2025-10-06T05:37:30.792Z" }, - { url = "https://files.pythonhosted.org/packages/ba/7d/b7282a445956506fa11da8c2db7d276adcbf2b17d8bb8407a47685263f90/frozenlist-1.8.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2c5dcbbc55383e5883246d11fd179782a9d07a986c40f49abe89ddf865913930", size = 51739, upload-time = "2025-10-06T05:37:32.127Z" }, - { url = "https://files.pythonhosted.org/packages/62/1c/3d8622e60d0b767a5510d1d3cf21065b9db874696a51ea6d7a43180a259c/frozenlist-1.8.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:39ecbc32f1390387d2aa4f5a995e465e9e2f79ba3adcac92d68e3e0afae6657c", size = 284186, upload-time = "2025-10-06T05:37:33.21Z" }, - { url = "https://files.pythonhosted.org/packages/2d/14/aa36d5f85a89679a85a1d44cd7a6657e0b1c75f61e7cad987b203d2daca8/frozenlist-1.8.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92db2bf818d5cc8d9c1f1fc56b897662e24ea5adb36ad1f1d82875bd64e03c24", size = 292196, upload-time = "2025-10-06T05:37:36.107Z" }, - { url = "https://files.pythonhosted.org/packages/05/23/6bde59eb55abd407d34f77d39a5126fb7b4f109a3f611d3929f14b700c66/frozenlist-1.8.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2dc43a022e555de94c3b68a4ef0b11c4f747d12c024a520c7101709a2144fb37", size = 273830, upload-time = "2025-10-06T05:37:37.663Z" }, - { url = "https://files.pythonhosted.org/packages/d2/3f/22cff331bfad7a8afa616289000ba793347fcd7bc275f3b28ecea2a27909/frozenlist-1.8.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cb89a7f2de3602cfed448095bab3f178399646ab7c61454315089787df07733a", size = 294289, upload-time = "2025-10-06T05:37:39.261Z" }, - { url = "https://files.pythonhosted.org/packages/a4/89/5b057c799de4838b6c69aa82b79705f2027615e01be996d2486a69ca99c4/frozenlist-1.8.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:33139dc858c580ea50e7e60a1b0ea003efa1fd42e6ec7fdbad78fff65fad2fd2", size = 300318, upload-time = "2025-10-06T05:37:43.213Z" }, - { url = "https://files.pythonhosted.org/packages/30/de/2c22ab3eb2a8af6d69dc799e48455813bab3690c760de58e1bf43b36da3e/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:168c0969a329b416119507ba30b9ea13688fafffac1b7822802537569a1cb0ef", size = 282814, upload-time = "2025-10-06T05:37:45.337Z" }, - { url = "https://files.pythonhosted.org/packages/59/f7/970141a6a8dbd7f556d94977858cfb36fa9b66e0892c6dd780d2219d8cd8/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:28bd570e8e189d7f7b001966435f9dac6718324b5be2990ac496cf1ea9ddb7fe", size = 291762, upload-time = "2025-10-06T05:37:46.657Z" }, - { url = "https://files.pythonhosted.org/packages/c1/15/ca1adae83a719f82df9116d66f5bb28bb95557b3951903d39135620ef157/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:b2a095d45c5d46e5e79ba1e5b9cb787f541a8dee0433836cea4b96a2c439dcd8", size = 289470, upload-time = "2025-10-06T05:37:47.946Z" }, - { url = "https://files.pythonhosted.org/packages/ac/83/dca6dc53bf657d371fbc88ddeb21b79891e747189c5de990b9dfff2ccba1/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:eab8145831a0d56ec9c4139b6c3e594c7a83c2c8be25d5bcf2d86136a532287a", size = 289042, upload-time = "2025-10-06T05:37:49.499Z" }, - { url = "https://files.pythonhosted.org/packages/96/52/abddd34ca99be142f354398700536c5bd315880ed0a213812bc491cff5e4/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:974b28cf63cc99dfb2188d8d222bc6843656188164848c4f679e63dae4b0708e", size = 283148, upload-time = "2025-10-06T05:37:50.745Z" }, - { url = "https://files.pythonhosted.org/packages/af/d3/76bd4ed4317e7119c2b7f57c3f6934aba26d277acc6309f873341640e21f/frozenlist-1.8.0-cp314-cp314t-win32.whl", hash = "sha256:342c97bf697ac5480c0a7ec73cd700ecfa5a8a40ac923bd035484616efecc2df", size = 44676, upload-time = "2025-10-06T05:37:52.222Z" }, - { url = "https://files.pythonhosted.org/packages/89/76/c615883b7b521ead2944bb3480398cbb07e12b7b4e4d073d3752eb721558/frozenlist-1.8.0-cp314-cp314t-win_amd64.whl", hash = "sha256:06be8f67f39c8b1dc671f5d83aaefd3358ae5cdcf8314552c57e7ed3e6475bdd", size = 49451, upload-time = "2025-10-06T05:37:53.425Z" }, - { url = "https://files.pythonhosted.org/packages/e0/a3/5982da14e113d07b325230f95060e2169f5311b1017ea8af2a29b374c289/frozenlist-1.8.0-cp314-cp314t-win_arm64.whl", hash = "sha256:102e6314ca4da683dca92e3b1355490fed5f313b768500084fbe6371fddfdb79", size = 42507, upload-time = "2025-10-06T05:37:54.513Z" }, - { url = "https://files.pythonhosted.org/packages/9a/9a/e35b4a917281c0b8419d4207f4334c8e8c5dbf4f3f5f9ada73958d937dcc/frozenlist-1.8.0-py3-none-any.whl", hash = "sha256:0c18a16eab41e82c295618a77502e17b195883241c563b00f0aa5106fc4eaa0d", size = 13409, upload-time = "2025-10-06T05:38:16.721Z" }, -] - -[[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, upload-time = "2025-12-04T14:49:44.05Z" } -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, upload-time = "2025-12-04T14:23:01.282Z" }, - { 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, upload-time = "2025-12-04T14:50:08.309Z" }, - { 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, upload-time = "2025-12-04T14:57:43.968Z" }, - { 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, upload-time = "2025-12-04T15:07:14.697Z" }, - { 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, upload-time = "2025-12-04T14:26:03.669Z" }, - { 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, upload-time = "2025-12-04T15:04:25.276Z" }, - { 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, upload-time = "2025-12-04T14:27:30.804Z" }, - { url = "https://files.pythonhosted.org/packages/7e/71/ba21c3fb8c5dce83b8c01f458a42e99ffdb1963aeec08fff5a18588d8fd7/greenlet-3.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:9ee1942ea19550094033c35d25d20726e4f1c40d59545815e1128ac58d416d38", size = 301833, upload-time = "2025-12-04T14:32:23.929Z" }, - { 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, upload-time = "2025-12-04T14:23:05.267Z" }, - { 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, upload-time = "2025-12-04T14:50:10.026Z" }, - { 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, upload-time = "2025-12-04T14:57:45.41Z" }, - { 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, upload-time = "2025-12-04T15:07:15.789Z" }, - { 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, upload-time = "2025-12-04T14:26:05.099Z" }, - { 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, upload-time = "2025-12-04T15:04:27.041Z" }, - { 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, upload-time = "2025-12-04T14:27:32.366Z" }, - { url = "https://files.pythonhosted.org/packages/7c/9a/9030e6f9aa8fd7808e9c31ba4c38f87c4f8ec324ee67431d181fe396d705/greenlet-3.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:73f51dd0e0bdb596fb0417e475fa3c5e32d4c83638296e560086b8d7da7c4170", size = 305387, upload-time = "2025-12-04T14:26:51.063Z" }, - { 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, upload-time = "2025-12-04T14:25:20.941Z" }, - { 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, upload-time = "2025-12-04T14:50:11.039Z" }, - { 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, upload-time = "2025-12-04T14:57:47.007Z" }, - { 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, upload-time = "2025-12-04T15:07:16.906Z" }, - { 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, upload-time = "2025-12-04T14:26:06.225Z" }, - { 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, upload-time = "2025-12-04T15:04:28.484Z" }, - { 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, upload-time = "2025-12-04T14:27:33.531Z" }, -] - -[[package]] -name = "h11" -version = "0.16.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, -] - -[[package]] -name = "httpcore" -version = "1.0.9" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "certifi" }, - { name = "h11" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" }, -] - -[[package]] -name = "httptools" -version = "0.7.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b5/46/120a669232c7bdedb9d52d4aeae7e6c7dfe151e99dc70802e2fc7a5e1993/httptools-0.7.1.tar.gz", hash = "sha256:abd72556974f8e7c74a259655924a717a2365b236c882c3f6f8a45fe94703ac9", size = 258961, upload-time = "2025-10-10T03:55:08.559Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/09/8f/c77b1fcbfd262d422f12da02feb0d218fa228d52485b77b953832105bb90/httptools-0.7.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6babce6cfa2a99545c60bfef8bee0cc0545413cb0018f617c8059a30ad985de3", size = 202889, upload-time = "2025-10-10T03:54:47.089Z" }, - { url = "https://files.pythonhosted.org/packages/0a/1a/22887f53602feaa066354867bc49a68fc295c2293433177ee90870a7d517/httptools-0.7.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:601b7628de7504077dd3dcb3791c6b8694bbd967148a6d1f01806509254fb1ca", size = 108180, upload-time = "2025-10-10T03:54:48.052Z" }, - { url = "https://files.pythonhosted.org/packages/32/6a/6aaa91937f0010d288d3d124ca2946d48d60c3a5ee7ca62afe870e3ea011/httptools-0.7.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:04c6c0e6c5fb0739c5b8a9eb046d298650a0ff38cf42537fc372b28dc7e4472c", size = 478596, upload-time = "2025-10-10T03:54:48.919Z" }, - { url = "https://files.pythonhosted.org/packages/6d/70/023d7ce117993107be88d2cbca566a7c1323ccbaf0af7eabf2064fe356f6/httptools-0.7.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:69d4f9705c405ae3ee83d6a12283dc9feba8cc6aaec671b412917e644ab4fa66", size = 473268, upload-time = "2025-10-10T03:54:49.993Z" }, - { url = "https://files.pythonhosted.org/packages/32/4d/9dd616c38da088e3f436e9a616e1d0cc66544b8cdac405cc4e81c8679fc7/httptools-0.7.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:44c8f4347d4b31269c8a9205d8a5ee2df5322b09bbbd30f8f862185bb6b05346", size = 455517, upload-time = "2025-10-10T03:54:51.066Z" }, - { url = "https://files.pythonhosted.org/packages/1d/3a/a6c595c310b7df958e739aae88724e24f9246a514d909547778d776799be/httptools-0.7.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:465275d76db4d554918aba40bf1cbebe324670f3dfc979eaffaa5d108e2ed650", size = 458337, upload-time = "2025-10-10T03:54:52.196Z" }, - { url = "https://files.pythonhosted.org/packages/fd/82/88e8d6d2c51edc1cc391b6e044c6c435b6aebe97b1abc33db1b0b24cd582/httptools-0.7.1-cp313-cp313-win_amd64.whl", hash = "sha256:322d00c2068d125bd570f7bf78b2d367dad02b919d8581d7476d8b75b294e3e6", size = 85743, upload-time = "2025-10-10T03:54:53.448Z" }, - { url = "https://files.pythonhosted.org/packages/34/50/9d095fcbb6de2d523e027a2f304d4551855c2f46e0b82befd718b8b20056/httptools-0.7.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:c08fe65728b8d70b6923ce31e3956f859d5e1e8548e6f22ec520a962c6757270", size = 203619, upload-time = "2025-10-10T03:54:54.321Z" }, - { url = "https://files.pythonhosted.org/packages/07/f0/89720dc5139ae54b03f861b5e2c55a37dba9a5da7d51e1e824a1f343627f/httptools-0.7.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:7aea2e3c3953521c3c51106ee11487a910d45586e351202474d45472db7d72d3", size = 108714, upload-time = "2025-10-10T03:54:55.163Z" }, - { url = "https://files.pythonhosted.org/packages/b3/cb/eea88506f191fb552c11787c23f9a405f4c7b0c5799bf73f2249cd4f5228/httptools-0.7.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0e68b8582f4ea9166be62926077a3334064d422cf08ab87d8b74664f8e9058e1", size = 472909, upload-time = "2025-10-10T03:54:56.056Z" }, - { url = "https://files.pythonhosted.org/packages/e0/4a/a548bdfae6369c0d078bab5769f7b66f17f1bfaa6fa28f81d6be6959066b/httptools-0.7.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:df091cf961a3be783d6aebae963cc9b71e00d57fa6f149025075217bc6a55a7b", size = 470831, upload-time = "2025-10-10T03:54:57.219Z" }, - { url = "https://files.pythonhosted.org/packages/4d/31/14df99e1c43bd132eec921c2e7e11cda7852f65619bc0fc5bdc2d0cb126c/httptools-0.7.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f084813239e1eb403ddacd06a30de3d3e09a9b76e7894dcda2b22f8a726e9c60", size = 452631, upload-time = "2025-10-10T03:54:58.219Z" }, - { url = "https://files.pythonhosted.org/packages/22/d2/b7e131f7be8d854d48cb6d048113c30f9a46dca0c9a8b08fcb3fcd588cdc/httptools-0.7.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7347714368fb2b335e9063bc2b96f2f87a9ceffcd9758ac295f8bbcd3ffbc0ca", size = 452910, upload-time = "2025-10-10T03:54:59.366Z" }, - { url = "https://files.pythonhosted.org/packages/53/cf/878f3b91e4e6e011eff6d1fa9ca39f7eb17d19c9d7971b04873734112f30/httptools-0.7.1-cp314-cp314-win_amd64.whl", hash = "sha256:cfabda2a5bb85aa2a904ce06d974a3f30fb36cc63d7feaddec05d2050acede96", size = 88205, upload-time = "2025-10-10T03:55:00.389Z" }, -] - -[[package]] -name = "httpx" -version = "0.28.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "anyio" }, - { name = "certifi" }, - { name = "httpcore" }, - { name = "idna" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" }, -] - -[[package]] -name = "idna" -version = "3.11" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902", size = 194582, upload-time = "2025-10-12T14:55:20.501Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" }, -] - -[[package]] -name = "iniconfig" -version = "2.3.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, -] - -[[package]] -name = "itsdangerous" -version = "2.2.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/9c/cb/8ac0172223afbccb63986cc25049b154ecfb5e85932587206f42317be31d/itsdangerous-2.2.0.tar.gz", hash = "sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173", size = 54410, upload-time = "2024-04-16T21:28:15.614Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/04/96/92447566d16df59b2a776c0fb82dbc4d9e07cd95062562af01e408583fc4/itsdangerous-2.2.0-py3-none-any.whl", hash = "sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef", size = 16234, upload-time = "2024-04-16T21:28:14.499Z" }, -] - -[[package]] -name = "jinja2" -version = "3.1.6" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "markupsafe" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, -] - -[[package]] -name = "jiter" -version = "0.12.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/45/9d/e0660989c1370e25848bb4c52d061c71837239738ad937e83edca174c273/jiter-0.12.0.tar.gz", hash = "sha256:64dfcd7d5c168b38d3f9f8bba7fc639edb3418abcc74f22fdbe6b8938293f30b", size = 168294, upload-time = "2025-11-09T20:49:23.302Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3d/a6/97209693b177716e22576ee1161674d1d58029eb178e01866a0422b69224/jiter-0.12.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:6cc49d5130a14b732e0612bc76ae8db3b49898732223ef8b7599aa8d9810683e", size = 313658, upload-time = "2025-11-09T20:47:44.424Z" }, - { url = "https://files.pythonhosted.org/packages/06/4d/125c5c1537c7d8ee73ad3d530a442d6c619714b95027143f1b61c0b4dfe0/jiter-0.12.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:37f27a32ce36364d2fa4f7fdc507279db604d27d239ea2e044c8f148410defe1", size = 318605, upload-time = "2025-11-09T20:47:45.973Z" }, - { url = "https://files.pythonhosted.org/packages/99/bf/a840b89847885064c41a5f52de6e312e91fa84a520848ee56c97e4fa0205/jiter-0.12.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bbc0944aa3d4b4773e348cda635252824a78f4ba44328e042ef1ff3f6080d1cf", size = 349803, upload-time = "2025-11-09T20:47:47.535Z" }, - { url = "https://files.pythonhosted.org/packages/8a/88/e63441c28e0db50e305ae23e19c1d8fae012d78ed55365da392c1f34b09c/jiter-0.12.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:da25c62d4ee1ffbacb97fac6dfe4dcd6759ebdc9015991e92a6eae5816287f44", size = 365120, upload-time = "2025-11-09T20:47:49.284Z" }, - { url = "https://files.pythonhosted.org/packages/0a/7c/49b02714af4343970eb8aca63396bc1c82fa01197dbb1e9b0d274b550d4e/jiter-0.12.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:048485c654b838140b007390b8182ba9774621103bd4d77c9c3f6f117474ba45", size = 479918, upload-time = "2025-11-09T20:47:50.807Z" }, - { url = "https://files.pythonhosted.org/packages/69/ba/0a809817fdd5a1db80490b9150645f3aae16afad166960bcd562be194f3b/jiter-0.12.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:635e737fbb7315bef0037c19b88b799143d2d7d3507e61a76751025226b3ac87", size = 379008, upload-time = "2025-11-09T20:47:52.211Z" }, - { url = "https://files.pythonhosted.org/packages/5f/c3/c9fc0232e736c8877d9e6d83d6eeb0ba4e90c6c073835cc2e8f73fdeef51/jiter-0.12.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e017c417b1ebda911bd13b1e40612704b1f5420e30695112efdbed8a4b389ed", size = 361785, upload-time = "2025-11-09T20:47:53.512Z" }, - { url = "https://files.pythonhosted.org/packages/96/61/61f69b7e442e97ca6cd53086ddc1cf59fb830549bc72c0a293713a60c525/jiter-0.12.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:89b0bfb8b2bf2351fba36bb211ef8bfceba73ef58e7f0c68fb67b5a2795ca2f9", size = 386108, upload-time = "2025-11-09T20:47:54.893Z" }, - { url = "https://files.pythonhosted.org/packages/e9/2e/76bb3332f28550c8f1eba3bf6e5efe211efda0ddbbaf24976bc7078d42a5/jiter-0.12.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:f5aa5427a629a824a543672778c9ce0c5e556550d1569bb6ea28a85015287626", size = 519937, upload-time = "2025-11-09T20:47:56.253Z" }, - { url = "https://files.pythonhosted.org/packages/84/d6/fa96efa87dc8bff2094fb947f51f66368fa56d8d4fc9e77b25d7fbb23375/jiter-0.12.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed53b3d6acbcb0fd0b90f20c7cb3b24c357fe82a3518934d4edfa8c6898e498c", size = 510853, upload-time = "2025-11-09T20:47:58.32Z" }, - { url = "https://files.pythonhosted.org/packages/8a/28/93f67fdb4d5904a708119a6ab58a8f1ec226ff10a94a282e0215402a8462/jiter-0.12.0-cp313-cp313-win32.whl", hash = "sha256:4747de73d6b8c78f2e253a2787930f4fffc68da7fa319739f57437f95963c4de", size = 204699, upload-time = "2025-11-09T20:47:59.686Z" }, - { url = "https://files.pythonhosted.org/packages/c4/1f/30b0eb087045a0abe2a5c9c0c0c8da110875a1d3be83afd4a9a4e548be3c/jiter-0.12.0-cp313-cp313-win_amd64.whl", hash = "sha256:e25012eb0c456fcc13354255d0338cd5397cce26c77b2832b3c4e2e255ea5d9a", size = 204258, upload-time = "2025-11-09T20:48:01.01Z" }, - { url = "https://files.pythonhosted.org/packages/2c/f4/2b4daf99b96bce6fc47971890b14b2a36aef88d7beb9f057fafa032c6141/jiter-0.12.0-cp313-cp313-win_arm64.whl", hash = "sha256:c97b92c54fe6110138c872add030a1f99aea2401ddcdaa21edf74705a646dd60", size = 185503, upload-time = "2025-11-09T20:48:02.35Z" }, - { url = "https://files.pythonhosted.org/packages/39/ca/67bb15a7061d6fe20b9b2a2fd783e296a1e0f93468252c093481a2f00efa/jiter-0.12.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:53839b35a38f56b8be26a7851a48b89bc47e5d88e900929df10ed93b95fea3d6", size = 317965, upload-time = "2025-11-09T20:48:03.783Z" }, - { url = "https://files.pythonhosted.org/packages/18/af/1788031cd22e29c3b14bc6ca80b16a39a0b10e611367ffd480c06a259831/jiter-0.12.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94f669548e55c91ab47fef8bddd9c954dab1938644e715ea49d7e117015110a4", size = 345831, upload-time = "2025-11-09T20:48:05.55Z" }, - { url = "https://files.pythonhosted.org/packages/05/17/710bf8472d1dff0d3caf4ced6031060091c1320f84ee7d5dcbed1f352417/jiter-0.12.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:351d54f2b09a41600ffea43d081522d792e81dcfb915f6d2d242744c1cc48beb", size = 361272, upload-time = "2025-11-09T20:48:06.951Z" }, - { url = "https://files.pythonhosted.org/packages/fb/f1/1dcc4618b59761fef92d10bcbb0b038b5160be653b003651566a185f1a5c/jiter-0.12.0-cp313-cp313t-win_amd64.whl", hash = "sha256:2a5e90604620f94bf62264e7c2c038704d38217b7465b863896c6d7c902b06c7", size = 204604, upload-time = "2025-11-09T20:48:08.328Z" }, - { url = "https://files.pythonhosted.org/packages/d9/32/63cb1d9f1c5c6632a783c0052cde9ef7ba82688f7065e2f0d5f10a7e3edb/jiter-0.12.0-cp313-cp313t-win_arm64.whl", hash = "sha256:88ef757017e78d2860f96250f9393b7b577b06a956ad102c29c8237554380db3", size = 185628, upload-time = "2025-11-09T20:48:09.572Z" }, - { url = "https://files.pythonhosted.org/packages/a8/99/45c9f0dbe4a1416b2b9a8a6d1236459540f43d7fb8883cff769a8db0612d/jiter-0.12.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:c46d927acd09c67a9fb1416df45c5a04c27e83aae969267e98fba35b74e99525", size = 312478, upload-time = "2025-11-09T20:48:10.898Z" }, - { url = "https://files.pythonhosted.org/packages/4c/a7/54ae75613ba9e0f55fcb0bc5d1f807823b5167cc944e9333ff322e9f07dd/jiter-0.12.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:774ff60b27a84a85b27b88cd5583899c59940bcc126caca97eb2a9df6aa00c49", size = 318706, upload-time = "2025-11-09T20:48:12.266Z" }, - { url = "https://files.pythonhosted.org/packages/59/31/2aa241ad2c10774baf6c37f8b8e1f39c07db358f1329f4eb40eba179c2a2/jiter-0.12.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5433fab222fb072237df3f637d01b81f040a07dcac1cb4a5c75c7aa9ed0bef1", size = 351894, upload-time = "2025-11-09T20:48:13.673Z" }, - { url = "https://files.pythonhosted.org/packages/54/4f/0f2759522719133a9042781b18cc94e335b6d290f5e2d3e6899d6af933e3/jiter-0.12.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f8c593c6e71c07866ec6bfb790e202a833eeec885022296aff6b9e0b92d6a70e", size = 365714, upload-time = "2025-11-09T20:48:15.083Z" }, - { url = "https://files.pythonhosted.org/packages/dc/6f/806b895f476582c62a2f52c453151edd8a0fde5411b0497baaa41018e878/jiter-0.12.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:90d32894d4c6877a87ae00c6b915b609406819dce8bc0d4e962e4de2784e567e", size = 478989, upload-time = "2025-11-09T20:48:16.706Z" }, - { url = "https://files.pythonhosted.org/packages/86/6c/012d894dc6e1033acd8db2b8346add33e413ec1c7c002598915278a37f79/jiter-0.12.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:798e46eed9eb10c3adbbacbd3bdb5ecd4cf7064e453d00dbef08802dae6937ff", size = 378615, upload-time = "2025-11-09T20:48:18.614Z" }, - { url = "https://files.pythonhosted.org/packages/87/30/d718d599f6700163e28e2c71c0bbaf6dace692e7df2592fd793ac9276717/jiter-0.12.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3f1368f0a6719ea80013a4eb90ba72e75d7ea67cfc7846db2ca504f3df0169a", size = 364745, upload-time = "2025-11-09T20:48:20.117Z" }, - { url = "https://files.pythonhosted.org/packages/8f/85/315b45ce4b6ddc7d7fceca24068543b02bdc8782942f4ee49d652e2cc89f/jiter-0.12.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:65f04a9d0b4406f7e51279710b27484af411896246200e461d80d3ba0caa901a", size = 386502, upload-time = "2025-11-09T20:48:21.543Z" }, - { url = "https://files.pythonhosted.org/packages/74/0b/ce0434fb40c5b24b368fe81b17074d2840748b4952256bab451b72290a49/jiter-0.12.0-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:fd990541982a24281d12b67a335e44f117e4c6cbad3c3b75c7dea68bf4ce3a67", size = 519845, upload-time = "2025-11-09T20:48:22.964Z" }, - { url = "https://files.pythonhosted.org/packages/e8/a3/7a7a4488ba052767846b9c916d208b3ed114e3eb670ee984e4c565b9cf0d/jiter-0.12.0-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:b111b0e9152fa7df870ecaebb0bd30240d9f7fff1f2003bcb4ed0f519941820b", size = 510701, upload-time = "2025-11-09T20:48:24.483Z" }, - { url = "https://files.pythonhosted.org/packages/c3/16/052ffbf9d0467b70af24e30f91e0579e13ded0c17bb4a8eb2aed3cb60131/jiter-0.12.0-cp314-cp314-win32.whl", hash = "sha256:a78befb9cc0a45b5a5a0d537b06f8544c2ebb60d19d02c41ff15da28a9e22d42", size = 205029, upload-time = "2025-11-09T20:48:25.749Z" }, - { url = "https://files.pythonhosted.org/packages/e4/18/3cf1f3f0ccc789f76b9a754bdb7a6977e5d1d671ee97a9e14f7eb728d80e/jiter-0.12.0-cp314-cp314-win_amd64.whl", hash = "sha256:e1fe01c082f6aafbe5c8faf0ff074f38dfb911d53f07ec333ca03f8f6226debf", size = 204960, upload-time = "2025-11-09T20:48:27.415Z" }, - { url = "https://files.pythonhosted.org/packages/02/68/736821e52ecfdeeb0f024b8ab01b5a229f6b9293bbdb444c27efade50b0f/jiter-0.12.0-cp314-cp314-win_arm64.whl", hash = "sha256:d72f3b5a432a4c546ea4bedc84cce0c3404874f1d1676260b9c7f048a9855451", size = 185529, upload-time = "2025-11-09T20:48:29.125Z" }, - { url = "https://files.pythonhosted.org/packages/30/61/12ed8ee7a643cce29ac97c2281f9ce3956eb76b037e88d290f4ed0d41480/jiter-0.12.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:e6ded41aeba3603f9728ed2b6196e4df875348ab97b28fc8afff115ed42ba7a7", size = 318974, upload-time = "2025-11-09T20:48:30.87Z" }, - { url = "https://files.pythonhosted.org/packages/2d/c6/f3041ede6d0ed5e0e79ff0de4c8f14f401bbf196f2ef3971cdbe5fd08d1d/jiter-0.12.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a947920902420a6ada6ad51892082521978e9dd44a802663b001436e4b771684", size = 345932, upload-time = "2025-11-09T20:48:32.658Z" }, - { url = "https://files.pythonhosted.org/packages/d5/5d/4d94835889edd01ad0e2dbfc05f7bdfaed46292e7b504a6ac7839aa00edb/jiter-0.12.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:add5e227e0554d3a52cf390a7635edaffdf4f8fce4fdbcef3cc2055bb396a30c", size = 367243, upload-time = "2025-11-09T20:48:34.093Z" }, - { url = "https://files.pythonhosted.org/packages/fd/76/0051b0ac2816253a99d27baf3dda198663aff882fa6ea7deeb94046da24e/jiter-0.12.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f9b1cda8fcb736250d7e8711d4580ebf004a46771432be0ae4796944b5dfa5d", size = 479315, upload-time = "2025-11-09T20:48:35.507Z" }, - { url = "https://files.pythonhosted.org/packages/70/ae/83f793acd68e5cb24e483f44f482a1a15601848b9b6f199dacb970098f77/jiter-0.12.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:deeb12a2223fe0135c7ff1356a143d57f95bbf1f4a66584f1fc74df21d86b993", size = 380714, upload-time = "2025-11-09T20:48:40.014Z" }, - { url = "https://files.pythonhosted.org/packages/b1/5e/4808a88338ad2c228b1126b93fcd8ba145e919e886fe910d578230dabe3b/jiter-0.12.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c596cc0f4cb574877550ce4ecd51f8037469146addd676d7c1a30ebe6391923f", size = 365168, upload-time = "2025-11-09T20:48:41.462Z" }, - { url = "https://files.pythonhosted.org/packages/0c/d4/04619a9e8095b42aef436b5aeb4c0282b4ff1b27d1db1508df9f5dc82750/jiter-0.12.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5ab4c823b216a4aeab3fdbf579c5843165756bd9ad87cc6b1c65919c4715f783", size = 387893, upload-time = "2025-11-09T20:48:42.921Z" }, - { url = "https://files.pythonhosted.org/packages/17/ea/d3c7e62e4546fdc39197fa4a4315a563a89b95b6d54c0d25373842a59cbe/jiter-0.12.0-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:e427eee51149edf962203ff8db75a7514ab89be5cb623fb9cea1f20b54f1107b", size = 520828, upload-time = "2025-11-09T20:48:44.278Z" }, - { url = "https://files.pythonhosted.org/packages/cc/0b/c6d3562a03fd767e31cb119d9041ea7958c3c80cb3d753eafb19b3b18349/jiter-0.12.0-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:edb868841f84c111255ba5e80339d386d937ec1fdce419518ce1bd9370fac5b6", size = 511009, upload-time = "2025-11-09T20:48:45.726Z" }, - { url = "https://files.pythonhosted.org/packages/aa/51/2cb4468b3448a8385ebcd15059d325c9ce67df4e2758d133ab9442b19834/jiter-0.12.0-cp314-cp314t-win32.whl", hash = "sha256:8bbcfe2791dfdb7c5e48baf646d37a6a3dcb5a97a032017741dea9f817dca183", size = 205110, upload-time = "2025-11-09T20:48:47.033Z" }, - { url = "https://files.pythonhosted.org/packages/b2/c5/ae5ec83dec9c2d1af805fd5fe8f74ebded9c8670c5210ec7820ce0dbeb1e/jiter-0.12.0-cp314-cp314t-win_amd64.whl", hash = "sha256:2fa940963bf02e1d8226027ef461e36af472dea85d36054ff835aeed944dd873", size = 205223, upload-time = "2025-11-09T20:48:49.076Z" }, - { url = "https://files.pythonhosted.org/packages/97/9a/3c5391907277f0e55195550cf3fa8e293ae9ee0c00fb402fec1e38c0c82f/jiter-0.12.0-cp314-cp314t-win_arm64.whl", hash = "sha256:506c9708dd29b27288f9f8f1140c3cb0e3d8ddb045956d7757b1fa0e0f39a473", size = 185564, upload-time = "2025-11-09T20:48:50.376Z" }, -] - -[[package]] -name = "markdown-it-py" -version = "4.0.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "mdurl" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3", size = 73070, upload-time = "2025-08-11T12:57:52.854Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", size = 87321, upload-time = "2025-08-11T12:57:51.923Z" }, -] - -[[package]] -name = "markupsafe" -version = "3.0.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313, upload-time = "2025-09-27T18:37:40.426Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622, upload-time = "2025-09-27T18:36:41.777Z" }, - { url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029, upload-time = "2025-09-27T18:36:43.257Z" }, - { url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374, upload-time = "2025-09-27T18:36:44.508Z" }, - { url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", size = 22980, upload-time = "2025-09-27T18:36:45.385Z" }, - { url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", size = 21990, upload-time = "2025-09-27T18:36:46.916Z" }, - { url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", size = 23784, upload-time = "2025-09-27T18:36:47.884Z" }, - { url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", size = 21588, upload-time = "2025-09-27T18:36:48.82Z" }, - { url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", size = 23041, upload-time = "2025-09-27T18:36:49.797Z" }, - { url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543, upload-time = "2025-09-27T18:36:51.584Z" }, - { url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113, upload-time = "2025-09-27T18:36:52.537Z" }, - { url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911, upload-time = "2025-09-27T18:36:53.513Z" }, - { url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", size = 11658, upload-time = "2025-09-27T18:36:54.819Z" }, - { url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", size = 12066, upload-time = "2025-09-27T18:36:55.714Z" }, - { url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", size = 25639, upload-time = "2025-09-27T18:36:56.908Z" }, - { url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", size = 23569, upload-time = "2025-09-27T18:36:57.913Z" }, - { url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", size = 23284, upload-time = "2025-09-27T18:36:58.833Z" }, - { url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", size = 24801, upload-time = "2025-09-27T18:36:59.739Z" }, - { url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", size = 22769, upload-time = "2025-09-27T18:37:00.719Z" }, - { url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", size = 23642, upload-time = "2025-09-27T18:37:01.673Z" }, - { url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612, upload-time = "2025-09-27T18:37:02.639Z" }, - { url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200, upload-time = "2025-09-27T18:37:03.582Z" }, - { url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973, upload-time = "2025-09-27T18:37:04.929Z" }, - { url = "https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe", size = 11619, upload-time = "2025-09-27T18:37:06.342Z" }, - { url = "https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026", size = 12029, upload-time = "2025-09-27T18:37:07.213Z" }, - { url = "https://files.pythonhosted.org/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737", size = 24408, upload-time = "2025-09-27T18:37:09.572Z" }, - { url = "https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97", size = 23005, upload-time = "2025-09-27T18:37:10.58Z" }, - { url = "https://files.pythonhosted.org/packages/bc/20/b7fdf89a8456b099837cd1dc21974632a02a999ec9bf7ca3e490aacd98e7/markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d", size = 22048, upload-time = "2025-09-27T18:37:11.547Z" }, - { url = "https://files.pythonhosted.org/packages/9a/a7/591f592afdc734f47db08a75793a55d7fbcc6902a723ae4cfbab61010cc5/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda", size = 23821, upload-time = "2025-09-27T18:37:12.48Z" }, - { url = "https://files.pythonhosted.org/packages/7d/33/45b24e4f44195b26521bc6f1a82197118f74df348556594bd2262bda1038/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf", size = 21606, upload-time = "2025-09-27T18:37:13.485Z" }, - { url = "https://files.pythonhosted.org/packages/ff/0e/53dfaca23a69fbfbbf17a4b64072090e70717344c52eaaaa9c5ddff1e5f0/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe", size = 23043, upload-time = "2025-09-27T18:37:14.408Z" }, - { url = "https://files.pythonhosted.org/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9", size = 14747, upload-time = "2025-09-27T18:37:15.36Z" }, - { url = "https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581", size = 15341, upload-time = "2025-09-27T18:37:16.496Z" }, - { url = "https://files.pythonhosted.org/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4", size = 14073, upload-time = "2025-09-27T18:37:17.476Z" }, - { url = "https://files.pythonhosted.org/packages/3c/f0/57689aa4076e1b43b15fdfa646b04653969d50cf30c32a102762be2485da/markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab", size = 11661, upload-time = "2025-09-27T18:37:18.453Z" }, - { url = "https://files.pythonhosted.org/packages/89/c3/2e67a7ca217c6912985ec766c6393b636fb0c2344443ff9d91404dc4c79f/markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175", size = 12069, upload-time = "2025-09-27T18:37:19.332Z" }, - { url = "https://files.pythonhosted.org/packages/f0/00/be561dce4e6ca66b15276e184ce4b8aec61fe83662cce2f7d72bd3249d28/markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634", size = 25670, upload-time = "2025-09-27T18:37:20.245Z" }, - { url = "https://files.pythonhosted.org/packages/50/09/c419f6f5a92e5fadde27efd190eca90f05e1261b10dbd8cbcb39cd8ea1dc/markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50", size = 23598, upload-time = "2025-09-27T18:37:21.177Z" }, - { url = "https://files.pythonhosted.org/packages/22/44/a0681611106e0b2921b3033fc19bc53323e0b50bc70cffdd19f7d679bb66/markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e", size = 23261, upload-time = "2025-09-27T18:37:22.167Z" }, - { url = "https://files.pythonhosted.org/packages/5f/57/1b0b3f100259dc9fffe780cfb60d4be71375510e435efec3d116b6436d43/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5", size = 24835, upload-time = "2025-09-27T18:37:23.296Z" }, - { url = "https://files.pythonhosted.org/packages/26/6a/4bf6d0c97c4920f1597cc14dd720705eca0bf7c787aebc6bb4d1bead5388/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523", size = 22733, upload-time = "2025-09-27T18:37:24.237Z" }, - { url = "https://files.pythonhosted.org/packages/14/c7/ca723101509b518797fedc2fdf79ba57f886b4aca8a7d31857ba3ee8281f/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc", size = 23672, upload-time = "2025-09-27T18:37:25.271Z" }, - { url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", size = 14819, upload-time = "2025-09-27T18:37:26.285Z" }, - { url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", size = 15426, upload-time = "2025-09-27T18:37:27.316Z" }, - { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" }, -] - -[[package]] -name = "mdurl" -version = "0.1.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, -] - -[[package]] -name = "multidict" -version = "6.7.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/80/1e/5492c365f222f907de1039b91f922b93fa4f764c713ee858d235495d8f50/multidict-6.7.0.tar.gz", hash = "sha256:c6e99d9a65ca282e578dfea819cfa9c0a62b2499d8677392e09feaf305e9e6f5", size = 101834, upload-time = "2025-10-06T14:52:30.657Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d2/86/33272a544eeb36d66e4d9a920602d1a2f57d4ebea4ef3cdfe5a912574c95/multidict-6.7.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:bee7c0588aa0076ce77c0ea5d19a68d76ad81fcd9fe8501003b9a24f9d4000f6", size = 76135, upload-time = "2025-10-06T14:49:54.26Z" }, - { url = "https://files.pythonhosted.org/packages/91/1c/eb97db117a1ebe46d457a3d235a7b9d2e6dcab174f42d1b67663dd9e5371/multidict-6.7.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7ef6b61cad77091056ce0e7ce69814ef72afacb150b7ac6a3e9470def2198159", size = 45117, upload-time = "2025-10-06T14:49:55.82Z" }, - { url = "https://files.pythonhosted.org/packages/f1/d8/6c3442322e41fb1dd4de8bd67bfd11cd72352ac131f6368315617de752f1/multidict-6.7.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9c0359b1ec12b1d6849c59f9d319610b7f20ef990a6d454ab151aa0e3b9f78ca", size = 43472, upload-time = "2025-10-06T14:49:57.048Z" }, - { url = "https://files.pythonhosted.org/packages/75/3f/e2639e80325af0b6c6febdf8e57cc07043ff15f57fa1ef808f4ccb5ac4cd/multidict-6.7.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:cd240939f71c64bd658f186330603aac1a9a81bf6273f523fca63673cb7378a8", size = 249342, upload-time = "2025-10-06T14:49:58.368Z" }, - { url = "https://files.pythonhosted.org/packages/5d/cc/84e0585f805cbeaa9cbdaa95f9a3d6aed745b9d25700623ac89a6ecff400/multidict-6.7.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a60a4d75718a5efa473ebd5ab685786ba0c67b8381f781d1be14da49f1a2dc60", size = 257082, upload-time = "2025-10-06T14:49:59.89Z" }, - { url = "https://files.pythonhosted.org/packages/b0/9c/ac851c107c92289acbbf5cfb485694084690c1b17e555f44952c26ddc5bd/multidict-6.7.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:53a42d364f323275126aff81fb67c5ca1b7a04fda0546245730a55c8c5f24bc4", size = 240704, upload-time = "2025-10-06T14:50:01.485Z" }, - { url = "https://files.pythonhosted.org/packages/50/cc/5f93e99427248c09da95b62d64b25748a5f5c98c7c2ab09825a1d6af0e15/multidict-6.7.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3b29b980d0ddbecb736735ee5bef69bb2ddca56eff603c86f3f29a1128299b4f", size = 266355, upload-time = "2025-10-06T14:50:02.955Z" }, - { url = "https://files.pythonhosted.org/packages/ec/0c/2ec1d883ceb79c6f7f6d7ad90c919c898f5d1c6ea96d322751420211e072/multidict-6.7.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f8a93b1c0ed2d04b97a5e9336fd2d33371b9a6e29ab7dd6503d63407c20ffbaf", size = 267259, upload-time = "2025-10-06T14:50:04.446Z" }, - { url = "https://files.pythonhosted.org/packages/c6/2d/f0b184fa88d6630aa267680bdb8623fb69cb0d024b8c6f0d23f9a0f406d3/multidict-6.7.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9ff96e8815eecacc6645da76c413eb3b3d34cfca256c70b16b286a687d013c32", size = 254903, upload-time = "2025-10-06T14:50:05.98Z" }, - { url = "https://files.pythonhosted.org/packages/06/c9/11ea263ad0df7dfabcad404feb3c0dd40b131bc7f232d5537f2fb1356951/multidict-6.7.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7516c579652f6a6be0e266aec0acd0db80829ca305c3d771ed898538804c2036", size = 252365, upload-time = "2025-10-06T14:50:07.511Z" }, - { url = "https://files.pythonhosted.org/packages/41/88/d714b86ee2c17d6e09850c70c9d310abac3d808ab49dfa16b43aba9d53fd/multidict-6.7.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:040f393368e63fb0f3330e70c26bfd336656bed925e5cbe17c9da839a6ab13ec", size = 250062, upload-time = "2025-10-06T14:50:09.074Z" }, - { url = "https://files.pythonhosted.org/packages/15/fe/ad407bb9e818c2b31383f6131ca19ea7e35ce93cf1310fce69f12e89de75/multidict-6.7.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b3bc26a951007b1057a1c543af845f1c7e3e71cc240ed1ace7bf4484aa99196e", size = 249683, upload-time = "2025-10-06T14:50:10.714Z" }, - { url = "https://files.pythonhosted.org/packages/8c/a4/a89abdb0229e533fb925e7c6e5c40201c2873efebc9abaf14046a4536ee6/multidict-6.7.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:7b022717c748dd1992a83e219587aabe45980d88969f01b316e78683e6285f64", size = 261254, upload-time = "2025-10-06T14:50:12.28Z" }, - { url = "https://files.pythonhosted.org/packages/8d/aa/0e2b27bd88b40a4fb8dc53dd74eecac70edaa4c1dd0707eb2164da3675b3/multidict-6.7.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:9600082733859f00d79dee64effc7aef1beb26adb297416a4ad2116fd61374bd", size = 257967, upload-time = "2025-10-06T14:50:14.16Z" }, - { url = "https://files.pythonhosted.org/packages/d0/8e/0c67b7120d5d5f6d874ed85a085f9dc770a7f9d8813e80f44a9fec820bb7/multidict-6.7.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:94218fcec4d72bc61df51c198d098ce2b378e0ccbac41ddbed5ef44092913288", size = 250085, upload-time = "2025-10-06T14:50:15.639Z" }, - { url = "https://files.pythonhosted.org/packages/ba/55/b73e1d624ea4b8fd4dd07a3bb70f6e4c7c6c5d9d640a41c6ffe5cdbd2a55/multidict-6.7.0-cp313-cp313-win32.whl", hash = "sha256:a37bd74c3fa9d00be2d7b8eca074dc56bd8077ddd2917a839bd989612671ed17", size = 41713, upload-time = "2025-10-06T14:50:17.066Z" }, - { url = "https://files.pythonhosted.org/packages/32/31/75c59e7d3b4205075b4c183fa4ca398a2daf2303ddf616b04ae6ef55cffe/multidict-6.7.0-cp313-cp313-win_amd64.whl", hash = "sha256:30d193c6cc6d559db42b6bcec8a5d395d34d60c9877a0b71ecd7c204fcf15390", size = 45915, upload-time = "2025-10-06T14:50:18.264Z" }, - { url = "https://files.pythonhosted.org/packages/31/2a/8987831e811f1184c22bc2e45844934385363ee61c0a2dcfa8f71b87e608/multidict-6.7.0-cp313-cp313-win_arm64.whl", hash = "sha256:ea3334cabe4d41b7ccd01e4d349828678794edbc2d3ae97fc162a3312095092e", size = 43077, upload-time = "2025-10-06T14:50:19.853Z" }, - { url = "https://files.pythonhosted.org/packages/e8/68/7b3a5170a382a340147337b300b9eb25a9ddb573bcdfff19c0fa3f31ffba/multidict-6.7.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:ad9ce259f50abd98a1ca0aa6e490b58c316a0fce0617f609723e40804add2c00", size = 83114, upload-time = "2025-10-06T14:50:21.223Z" }, - { url = "https://files.pythonhosted.org/packages/55/5c/3fa2d07c84df4e302060f555bbf539310980362236ad49f50eeb0a1c1eb9/multidict-6.7.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:07f5594ac6d084cbb5de2df218d78baf55ef150b91f0ff8a21cc7a2e3a5a58eb", size = 48442, upload-time = "2025-10-06T14:50:22.871Z" }, - { url = "https://files.pythonhosted.org/packages/fc/56/67212d33239797f9bd91962bb899d72bb0f4c35a8652dcdb8ed049bef878/multidict-6.7.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0591b48acf279821a579282444814a2d8d0af624ae0bc600aa4d1b920b6e924b", size = 46885, upload-time = "2025-10-06T14:50:24.258Z" }, - { url = "https://files.pythonhosted.org/packages/46/d1/908f896224290350721597a61a69cd19b89ad8ee0ae1f38b3f5cd12ea2ac/multidict-6.7.0-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:749a72584761531d2b9467cfbdfd29487ee21124c304c4b6cb760d8777b27f9c", size = 242588, upload-time = "2025-10-06T14:50:25.716Z" }, - { url = "https://files.pythonhosted.org/packages/ab/67/8604288bbd68680eee0ab568fdcb56171d8b23a01bcd5cb0c8fedf6e5d99/multidict-6.7.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b4c3d199f953acd5b446bf7c0de1fe25d94e09e79086f8dc2f48a11a129cdf1", size = 249966, upload-time = "2025-10-06T14:50:28.192Z" }, - { url = "https://files.pythonhosted.org/packages/20/33/9228d76339f1ba51e3efef7da3ebd91964d3006217aae13211653193c3ff/multidict-6.7.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:9fb0211dfc3b51efea2f349ec92c114d7754dd62c01f81c3e32b765b70c45c9b", size = 228618, upload-time = "2025-10-06T14:50:29.82Z" }, - { url = "https://files.pythonhosted.org/packages/f8/2d/25d9b566d10cab1c42b3b9e5b11ef79c9111eaf4463b8c257a3bd89e0ead/multidict-6.7.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a027ec240fe73a8d6281872690b988eed307cd7d91b23998ff35ff577ca688b5", size = 257539, upload-time = "2025-10-06T14:50:31.731Z" }, - { url = "https://files.pythonhosted.org/packages/b6/b1/8d1a965e6637fc33de3c0d8f414485c2b7e4af00f42cab3d84e7b955c222/multidict-6.7.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1d964afecdf3a8288789df2f5751dc0a8261138c3768d9af117ed384e538fad", size = 256345, upload-time = "2025-10-06T14:50:33.26Z" }, - { url = "https://files.pythonhosted.org/packages/ba/0c/06b5a8adbdeedada6f4fb8d8f193d44a347223b11939b42953eeb6530b6b/multidict-6.7.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:caf53b15b1b7df9fbd0709aa01409000a2b4dd03a5f6f5cc548183c7c8f8b63c", size = 247934, upload-time = "2025-10-06T14:50:34.808Z" }, - { url = "https://files.pythonhosted.org/packages/8f/31/b2491b5fe167ca044c6eb4b8f2c9f3b8a00b24c432c365358eadac5d7625/multidict-6.7.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:654030da3197d927f05a536a66186070e98765aa5142794c9904555d3a9d8fb5", size = 245243, upload-time = "2025-10-06T14:50:36.436Z" }, - { url = "https://files.pythonhosted.org/packages/61/1a/982913957cb90406c8c94f53001abd9eafc271cb3e70ff6371590bec478e/multidict-6.7.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:2090d3718829d1e484706a2f525e50c892237b2bf9b17a79b059cb98cddc2f10", size = 235878, upload-time = "2025-10-06T14:50:37.953Z" }, - { url = "https://files.pythonhosted.org/packages/be/c0/21435d804c1a1cf7a2608593f4d19bca5bcbd7a81a70b253fdd1c12af9c0/multidict-6.7.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:2d2cfeec3f6f45651b3d408c4acec0ebf3daa9bc8a112a084206f5db5d05b754", size = 243452, upload-time = "2025-10-06T14:50:39.574Z" }, - { url = "https://files.pythonhosted.org/packages/54/0a/4349d540d4a883863191be6eb9a928846d4ec0ea007d3dcd36323bb058ac/multidict-6.7.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:4ef089f985b8c194d341eb2c24ae6e7408c9a0e2e5658699c92f497437d88c3c", size = 252312, upload-time = "2025-10-06T14:50:41.612Z" }, - { url = "https://files.pythonhosted.org/packages/26/64/d5416038dbda1488daf16b676e4dbfd9674dde10a0cc8f4fc2b502d8125d/multidict-6.7.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:e93a0617cd16998784bf4414c7e40f17a35d2350e5c6f0bd900d3a8e02bd3762", size = 246935, upload-time = "2025-10-06T14:50:43.972Z" }, - { url = "https://files.pythonhosted.org/packages/9f/8c/8290c50d14e49f35e0bd4abc25e1bc7711149ca9588ab7d04f886cdf03d9/multidict-6.7.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f0feece2ef8ebc42ed9e2e8c78fc4aa3cf455733b507c09ef7406364c94376c6", size = 243385, upload-time = "2025-10-06T14:50:45.648Z" }, - { url = "https://files.pythonhosted.org/packages/ef/a0/f83ae75e42d694b3fbad3e047670e511c138be747bc713cf1b10d5096416/multidict-6.7.0-cp313-cp313t-win32.whl", hash = "sha256:19a1d55338ec1be74ef62440ca9e04a2f001a04d0cc49a4983dc320ff0f3212d", size = 47777, upload-time = "2025-10-06T14:50:47.154Z" }, - { url = "https://files.pythonhosted.org/packages/dc/80/9b174a92814a3830b7357307a792300f42c9e94664b01dee8e457551fa66/multidict-6.7.0-cp313-cp313t-win_amd64.whl", hash = "sha256:3da4fb467498df97e986af166b12d01f05d2e04f978a9c1c680ea1988e0bc4b6", size = 53104, upload-time = "2025-10-06T14:50:48.851Z" }, - { url = "https://files.pythonhosted.org/packages/cc/28/04baeaf0428d95bb7a7bea0e691ba2f31394338ba424fb0679a9ed0f4c09/multidict-6.7.0-cp313-cp313t-win_arm64.whl", hash = "sha256:b4121773c49a0776461f4a904cdf6264c88e42218aaa8407e803ca8025872792", size = 45503, upload-time = "2025-10-06T14:50:50.16Z" }, - { url = "https://files.pythonhosted.org/packages/e2/b1/3da6934455dd4b261d4c72f897e3a5728eba81db59959f3a639245891baa/multidict-6.7.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3bab1e4aff7adaa34410f93b1f8e57c4b36b9af0426a76003f441ee1d3c7e842", size = 75128, upload-time = "2025-10-06T14:50:51.92Z" }, - { url = "https://files.pythonhosted.org/packages/14/2c/f069cab5b51d175a1a2cb4ccdf7a2c2dabd58aa5bd933fa036a8d15e2404/multidict-6.7.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:b8512bac933afc3e45fb2b18da8e59b78d4f408399a960339598374d4ae3b56b", size = 44410, upload-time = "2025-10-06T14:50:53.275Z" }, - { url = "https://files.pythonhosted.org/packages/42/e2/64bb41266427af6642b6b128e8774ed84c11b80a90702c13ac0a86bb10cc/multidict-6.7.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:79dcf9e477bc65414ebfea98ffd013cb39552b5ecd62908752e0e413d6d06e38", size = 43205, upload-time = "2025-10-06T14:50:54.911Z" }, - { url = "https://files.pythonhosted.org/packages/02/68/6b086fef8a3f1a8541b9236c594f0c9245617c29841f2e0395d979485cde/multidict-6.7.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:31bae522710064b5cbeddaf2e9f32b1abab70ac6ac91d42572502299e9953128", size = 245084, upload-time = "2025-10-06T14:50:56.369Z" }, - { url = "https://files.pythonhosted.org/packages/15/ee/f524093232007cd7a75c1d132df70f235cfd590a7c9eaccd7ff422ef4ae8/multidict-6.7.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a0df7ff02397bb63e2fd22af2c87dfa39e8c7f12947bc524dbdc528282c7e34", size = 252667, upload-time = "2025-10-06T14:50:57.991Z" }, - { url = "https://files.pythonhosted.org/packages/02/a5/eeb3f43ab45878f1895118c3ef157a480db58ede3f248e29b5354139c2c9/multidict-6.7.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7a0222514e8e4c514660e182d5156a415c13ef0aabbd71682fc714e327b95e99", size = 233590, upload-time = "2025-10-06T14:50:59.589Z" }, - { url = "https://files.pythonhosted.org/packages/6a/1e/76d02f8270b97269d7e3dbd45644b1785bda457b474315f8cf999525a193/multidict-6.7.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2397ab4daaf2698eb51a76721e98db21ce4f52339e535725de03ea962b5a3202", size = 264112, upload-time = "2025-10-06T14:51:01.183Z" }, - { url = "https://files.pythonhosted.org/packages/76/0b/c28a70ecb58963847c2a8efe334904cd254812b10e535aefb3bcce513918/multidict-6.7.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8891681594162635948a636c9fe0ff21746aeb3dd5463f6e25d9bea3a8a39ca1", size = 261194, upload-time = "2025-10-06T14:51:02.794Z" }, - { url = "https://files.pythonhosted.org/packages/b4/63/2ab26e4209773223159b83aa32721b4021ffb08102f8ac7d689c943fded1/multidict-6.7.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18706cc31dbf402a7945916dd5cddf160251b6dab8a2c5f3d6d5a55949f676b3", size = 248510, upload-time = "2025-10-06T14:51:04.724Z" }, - { url = "https://files.pythonhosted.org/packages/93/cd/06c1fa8282af1d1c46fd55c10a7930af652afdce43999501d4d68664170c/multidict-6.7.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f844a1bbf1d207dd311a56f383f7eda2d0e134921d45751842d8235e7778965d", size = 248395, upload-time = "2025-10-06T14:51:06.306Z" }, - { url = "https://files.pythonhosted.org/packages/99/ac/82cb419dd6b04ccf9e7e61befc00c77614fc8134362488b553402ecd55ce/multidict-6.7.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:d4393e3581e84e5645506923816b9cc81f5609a778c7e7534054091acc64d1c6", size = 239520, upload-time = "2025-10-06T14:51:08.091Z" }, - { url = "https://files.pythonhosted.org/packages/fa/f3/a0f9bf09493421bd8716a362e0cd1d244f5a6550f5beffdd6b47e885b331/multidict-6.7.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:fbd18dc82d7bf274b37aa48d664534330af744e03bccf696d6f4c6042e7d19e7", size = 245479, upload-time = "2025-10-06T14:51:10.365Z" }, - { url = "https://files.pythonhosted.org/packages/8d/01/476d38fc73a212843f43c852b0eee266b6971f0e28329c2184a8df90c376/multidict-6.7.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:b6234e14f9314731ec45c42fc4554b88133ad53a09092cc48a88e771c125dadb", size = 258903, upload-time = "2025-10-06T14:51:12.466Z" }, - { url = "https://files.pythonhosted.org/packages/49/6d/23faeb0868adba613b817d0e69c5f15531b24d462af8012c4f6de4fa8dc3/multidict-6.7.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:08d4379f9744d8f78d98c8673c06e202ffa88296f009c71bbafe8a6bf847d01f", size = 252333, upload-time = "2025-10-06T14:51:14.48Z" }, - { url = "https://files.pythonhosted.org/packages/1e/cc/48d02ac22b30fa247f7dad82866e4b1015431092f4ba6ebc7e77596e0b18/multidict-6.7.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:9fe04da3f79387f450fd0061d4dd2e45a72749d31bf634aecc9e27f24fdc4b3f", size = 243411, upload-time = "2025-10-06T14:51:16.072Z" }, - { url = "https://files.pythonhosted.org/packages/4a/03/29a8bf5a18abf1fe34535c88adbdfa88c9fb869b5a3b120692c64abe8284/multidict-6.7.0-cp314-cp314-win32.whl", hash = "sha256:fbafe31d191dfa7c4c51f7a6149c9fb7e914dcf9ffead27dcfd9f1ae382b3885", size = 40940, upload-time = "2025-10-06T14:51:17.544Z" }, - { url = "https://files.pythonhosted.org/packages/82/16/7ed27b680791b939de138f906d5cf2b4657b0d45ca6f5dd6236fdddafb1a/multidict-6.7.0-cp314-cp314-win_amd64.whl", hash = "sha256:2f67396ec0310764b9222a1728ced1ab638f61aadc6226f17a71dd9324f9a99c", size = 45087, upload-time = "2025-10-06T14:51:18.875Z" }, - { url = "https://files.pythonhosted.org/packages/cd/3c/e3e62eb35a1950292fe39315d3c89941e30a9d07d5d2df42965ab041da43/multidict-6.7.0-cp314-cp314-win_arm64.whl", hash = "sha256:ba672b26069957ee369cfa7fc180dde1fc6f176eaf1e6beaf61fbebbd3d9c000", size = 42368, upload-time = "2025-10-06T14:51:20.225Z" }, - { url = "https://files.pythonhosted.org/packages/8b/40/cd499bd0dbc5f1136726db3153042a735fffd0d77268e2ee20d5f33c010f/multidict-6.7.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:c1dcc7524066fa918c6a27d61444d4ee7900ec635779058571f70d042d86ed63", size = 82326, upload-time = "2025-10-06T14:51:21.588Z" }, - { url = "https://files.pythonhosted.org/packages/13/8a/18e031eca251c8df76daf0288e6790561806e439f5ce99a170b4af30676b/multidict-6.7.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:27e0b36c2d388dc7b6ced3406671b401e84ad7eb0656b8f3a2f46ed0ce483718", size = 48065, upload-time = "2025-10-06T14:51:22.93Z" }, - { url = "https://files.pythonhosted.org/packages/40/71/5e6701277470a87d234e433fb0a3a7deaf3bcd92566e421e7ae9776319de/multidict-6.7.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2a7baa46a22e77f0988e3b23d4ede5513ebec1929e34ee9495be535662c0dfe2", size = 46475, upload-time = "2025-10-06T14:51:24.352Z" }, - { url = "https://files.pythonhosted.org/packages/fe/6a/bab00cbab6d9cfb57afe1663318f72ec28289ea03fd4e8236bb78429893a/multidict-6.7.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:7bf77f54997a9166a2f5675d1201520586439424c2511723a7312bdb4bcc034e", size = 239324, upload-time = "2025-10-06T14:51:25.822Z" }, - { url = "https://files.pythonhosted.org/packages/2a/5f/8de95f629fc22a7769ade8b41028e3e5a822c1f8904f618d175945a81ad3/multidict-6.7.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e011555abada53f1578d63389610ac8a5400fc70ce71156b0aa30d326f1a5064", size = 246877, upload-time = "2025-10-06T14:51:27.604Z" }, - { url = "https://files.pythonhosted.org/packages/23/b4/38881a960458f25b89e9f4a4fdcb02ac101cfa710190db6e5528841e67de/multidict-6.7.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:28b37063541b897fd6a318007373930a75ca6d6ac7c940dbe14731ffdd8d498e", size = 225824, upload-time = "2025-10-06T14:51:29.664Z" }, - { url = "https://files.pythonhosted.org/packages/1e/39/6566210c83f8a261575f18e7144736059f0c460b362e96e9cf797a24b8e7/multidict-6.7.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:05047ada7a2fde2631a0ed706f1fd68b169a681dfe5e4cf0f8e4cb6618bbc2cd", size = 253558, upload-time = "2025-10-06T14:51:31.684Z" }, - { url = "https://files.pythonhosted.org/packages/00/a3/67f18315100f64c269f46e6c0319fa87ba68f0f64f2b8e7fd7c72b913a0b/multidict-6.7.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:716133f7d1d946a4e1b91b1756b23c088881e70ff180c24e864c26192ad7534a", size = 252339, upload-time = "2025-10-06T14:51:33.699Z" }, - { url = "https://files.pythonhosted.org/packages/c8/2a/1cb77266afee2458d82f50da41beba02159b1d6b1f7973afc9a1cad1499b/multidict-6.7.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d1bed1b467ef657f2a0ae62844a607909ef1c6889562de5e1d505f74457d0b96", size = 244895, upload-time = "2025-10-06T14:51:36.189Z" }, - { url = "https://files.pythonhosted.org/packages/dd/72/09fa7dd487f119b2eb9524946ddd36e2067c08510576d43ff68469563b3b/multidict-6.7.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ca43bdfa5d37bd6aee89d85e1d0831fb86e25541be7e9d376ead1b28974f8e5e", size = 241862, upload-time = "2025-10-06T14:51:41.291Z" }, - { url = "https://files.pythonhosted.org/packages/65/92/bc1f8bd0853d8669300f732c801974dfc3702c3eeadae2f60cef54dc69d7/multidict-6.7.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:44b546bd3eb645fd26fb949e43c02a25a2e632e2ca21a35e2e132c8105dc8599", size = 232376, upload-time = "2025-10-06T14:51:43.55Z" }, - { url = "https://files.pythonhosted.org/packages/09/86/ac39399e5cb9d0c2ac8ef6e10a768e4d3bc933ac808d49c41f9dc23337eb/multidict-6.7.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:a6ef16328011d3f468e7ebc326f24c1445f001ca1dec335b2f8e66bed3006394", size = 240272, upload-time = "2025-10-06T14:51:45.265Z" }, - { url = "https://files.pythonhosted.org/packages/3d/b6/fed5ac6b8563ec72df6cb1ea8dac6d17f0a4a1f65045f66b6d3bf1497c02/multidict-6.7.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:5aa873cbc8e593d361ae65c68f85faadd755c3295ea2c12040ee146802f23b38", size = 248774, upload-time = "2025-10-06T14:51:46.836Z" }, - { url = "https://files.pythonhosted.org/packages/6b/8d/b954d8c0dc132b68f760aefd45870978deec6818897389dace00fcde32ff/multidict-6.7.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:3d7b6ccce016e29df4b7ca819659f516f0bc7a4b3efa3bb2012ba06431b044f9", size = 242731, upload-time = "2025-10-06T14:51:48.541Z" }, - { url = "https://files.pythonhosted.org/packages/16/9d/a2dac7009125d3540c2f54e194829ea18ac53716c61b655d8ed300120b0f/multidict-6.7.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:171b73bd4ee683d307599b66793ac80981b06f069b62eea1c9e29c9241aa66b0", size = 240193, upload-time = "2025-10-06T14:51:50.355Z" }, - { url = "https://files.pythonhosted.org/packages/39/ca/c05f144128ea232ae2178b008d5011d4e2cea86e4ee8c85c2631b1b94802/multidict-6.7.0-cp314-cp314t-win32.whl", hash = "sha256:b2d7f80c4e1fd010b07cb26820aae86b7e73b681ee4889684fb8d2d4537aab13", size = 48023, upload-time = "2025-10-06T14:51:51.883Z" }, - { url = "https://files.pythonhosted.org/packages/ba/8f/0a60e501584145588be1af5cc829265701ba3c35a64aec8e07cbb71d39bb/multidict-6.7.0-cp314-cp314t-win_amd64.whl", hash = "sha256:09929cab6fcb68122776d575e03c6cc64ee0b8fca48d17e135474b042ce515cd", size = 53507, upload-time = "2025-10-06T14:51:53.672Z" }, - { url = "https://files.pythonhosted.org/packages/7f/ae/3148b988a9c6239903e786eac19c889fab607c31d6efa7fb2147e5680f23/multidict-6.7.0-cp314-cp314t-win_arm64.whl", hash = "sha256:cc41db090ed742f32bd2d2c721861725e6109681eddf835d0a82bd3a5c382827", size = 44804, upload-time = "2025-10-06T14:51:55.415Z" }, - { url = "https://files.pythonhosted.org/packages/b7/da/7d22601b625e241d4f23ef1ebff8acfc60da633c9e7e7922e24d10f592b3/multidict-6.7.0-py3-none-any.whl", hash = "sha256:394fc5c42a333c9ffc3e421a4c85e08580d990e08b99f6bf35b4132114c5dcb3", size = 12317, upload-time = "2025-10-06T14:52:29.272Z" }, -] - -[[package]] -name = "o2o-castad-backend" -version = "0.1.0" -source = { editable = "." } -dependencies = [ - { name = "aiofiles" }, - { name = "aiohttp" }, - { name = "aiomysql" }, - { name = "asyncmy" }, - { name = "fastapi", extra = ["standard"] }, - { name = "fastapi-cli" }, - { name = "openai" }, - { name = "pydantic-settings" }, - { name = "redis" }, - { name = "ruff" }, - { name = "scalar-fastapi" }, - { name = "sqladmin", extra = ["full"] }, - { name = "sqlalchemy", extra = ["asyncio"] }, - { name = "uuid7" }, -] - -[package.dev-dependencies] -dev = [ - { name = "pytest" }, - { name = "pytest-asyncio" }, -] - -[package.metadata] -requires-dist = [ - { name = "aiofiles", specifier = ">=25.1.0" }, - { name = "aiohttp", specifier = ">=3.13.2" }, - { name = "aiomysql", specifier = ">=0.3.2" }, - { name = "asyncmy", specifier = ">=0.2.10" }, - { name = "fastapi", extras = ["standard"], specifier = ">=0.125.0" }, - { name = "fastapi-cli", specifier = ">=0.0.16" }, - { name = "openai", specifier = ">=2.13.0" }, - { name = "pydantic-settings", specifier = ">=2.12.0" }, - { name = "redis", specifier = ">=7.1.0" }, - { name = "ruff", specifier = ">=0.14.9" }, - { name = "scalar-fastapi", specifier = ">=1.5.0" }, - { name = "sqladmin", extras = ["full"], specifier = ">=0.22.0" }, - { name = "sqlalchemy", extras = ["asyncio"], specifier = ">=2.0.45" }, - { name = "uuid7", specifier = ">=0.1.0" }, -] - -[package.metadata.requires-dev] -dev = [ - { name = "pytest", specifier = ">=9.0.2" }, - { name = "pytest-asyncio", specifier = ">=1.3.0" }, -] - -[[package]] -name = "openai" -version = "2.14.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "anyio" }, - { name = "distro" }, - { name = "httpx" }, - { name = "jiter" }, - { name = "pydantic" }, - { name = "sniffio" }, - { name = "tqdm" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/d8/b1/12fe1c196bea326261718eb037307c1c1fe1dedc2d2d4de777df822e6238/openai-2.14.0.tar.gz", hash = "sha256:419357bedde9402d23bf8f2ee372fca1985a73348debba94bddff06f19459952", size = 626938, upload-time = "2025-12-19T03:28:45.742Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/27/4b/7c1a00c2c3fbd004253937f7520f692a9650767aa73894d7a34f0d65d3f4/openai-2.14.0-py3-none-any.whl", hash = "sha256:7ea40aca4ffc4c4a776e77679021b47eec1160e341f42ae086ba949c9dcc9183", size = 1067558, upload-time = "2025-12-19T03:28:43.727Z" }, -] - -[[package]] -name = "packaging" -version = "25.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, -] - -[[package]] -name = "pluggy" -version = "1.6.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, -] - -[[package]] -name = "propcache" -version = "0.4.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/9e/da/e9fc233cf63743258bff22b3dfa7ea5baef7b5bc324af47a0ad89b8ffc6f/propcache-0.4.1.tar.gz", hash = "sha256:f48107a8c637e80362555f37ecf49abe20370e557cc4ab374f04ec4423c97c3d", size = 46442, upload-time = "2025-10-08T19:49:02.291Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/bf/df/6d9c1b6ac12b003837dde8a10231a7344512186e87b36e855bef32241942/propcache-0.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:43eedf29202c08550aac1d14e0ee619b0430aaef78f85864c1a892294fbc28cf", size = 77750, upload-time = "2025-10-08T19:47:07.648Z" }, - { url = "https://files.pythonhosted.org/packages/8b/e8/677a0025e8a2acf07d3418a2e7ba529c9c33caf09d3c1f25513023c1db56/propcache-0.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d62cdfcfd89ccb8de04e0eda998535c406bf5e060ffd56be6c586cbcc05b3311", size = 44780, upload-time = "2025-10-08T19:47:08.851Z" }, - { url = "https://files.pythonhosted.org/packages/89/a4/92380f7ca60f99ebae761936bc48a72a639e8a47b29050615eef757cb2a7/propcache-0.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cae65ad55793da34db5f54e4029b89d3b9b9490d8abe1b4c7ab5d4b8ec7ebf74", size = 46308, upload-time = "2025-10-08T19:47:09.982Z" }, - { url = "https://files.pythonhosted.org/packages/2d/48/c5ac64dee5262044348d1d78a5f85dd1a57464a60d30daee946699963eb3/propcache-0.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:333ddb9031d2704a301ee3e506dc46b1fe5f294ec198ed6435ad5b6a085facfe", size = 208182, upload-time = "2025-10-08T19:47:11.319Z" }, - { url = "https://files.pythonhosted.org/packages/c6/0c/cd762dd011a9287389a6a3eb43aa30207bde253610cca06824aeabfe9653/propcache-0.4.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fd0858c20f078a32cf55f7e81473d96dcf3b93fd2ccdb3d40fdf54b8573df3af", size = 211215, upload-time = "2025-10-08T19:47:13.146Z" }, - { url = "https://files.pythonhosted.org/packages/30/3e/49861e90233ba36890ae0ca4c660e95df565b2cd15d4a68556ab5865974e/propcache-0.4.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:678ae89ebc632c5c204c794f8dab2837c5f159aeb59e6ed0539500400577298c", size = 218112, upload-time = "2025-10-08T19:47:14.913Z" }, - { url = "https://files.pythonhosted.org/packages/f1/8b/544bc867e24e1bd48f3118cecd3b05c694e160a168478fa28770f22fd094/propcache-0.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d472aeb4fbf9865e0c6d622d7f4d54a4e101a89715d8904282bb5f9a2f476c3f", size = 204442, upload-time = "2025-10-08T19:47:16.277Z" }, - { url = "https://files.pythonhosted.org/packages/50/a6/4282772fd016a76d3e5c0df58380a5ea64900afd836cec2c2f662d1b9bb3/propcache-0.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4d3df5fa7e36b3225954fba85589da77a0fe6a53e3976de39caf04a0db4c36f1", size = 199398, upload-time = "2025-10-08T19:47:17.962Z" }, - { url = "https://files.pythonhosted.org/packages/3e/ec/d8a7cd406ee1ddb705db2139f8a10a8a427100347bd698e7014351c7af09/propcache-0.4.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:ee17f18d2498f2673e432faaa71698032b0127ebf23ae5974eeaf806c279df24", size = 196920, upload-time = "2025-10-08T19:47:19.355Z" }, - { url = "https://files.pythonhosted.org/packages/f6/6c/f38ab64af3764f431e359f8baf9e0a21013e24329e8b85d2da32e8ed07ca/propcache-0.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:580e97762b950f993ae618e167e7be9256b8353c2dcd8b99ec100eb50f5286aa", size = 203748, upload-time = "2025-10-08T19:47:21.338Z" }, - { url = "https://files.pythonhosted.org/packages/d6/e3/fa846bd70f6534d647886621388f0a265254d30e3ce47e5c8e6e27dbf153/propcache-0.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:501d20b891688eb8e7aa903021f0b72d5a55db40ffaab27edefd1027caaafa61", size = 205877, upload-time = "2025-10-08T19:47:23.059Z" }, - { url = "https://files.pythonhosted.org/packages/e2/39/8163fc6f3133fea7b5f2827e8eba2029a0277ab2c5beee6c1db7b10fc23d/propcache-0.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a0bd56e5b100aef69bd8562b74b46254e7c8812918d3baa700c8a8009b0af66", size = 199437, upload-time = "2025-10-08T19:47:24.445Z" }, - { url = "https://files.pythonhosted.org/packages/93/89/caa9089970ca49c7c01662bd0eeedfe85494e863e8043565aeb6472ce8fe/propcache-0.4.1-cp313-cp313-win32.whl", hash = "sha256:bcc9aaa5d80322bc2fb24bb7accb4a30f81e90ab8d6ba187aec0744bc302ad81", size = 37586, upload-time = "2025-10-08T19:47:25.736Z" }, - { url = "https://files.pythonhosted.org/packages/f5/ab/f76ec3c3627c883215b5c8080debb4394ef5a7a29be811f786415fc1e6fd/propcache-0.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:381914df18634f5494334d201e98245c0596067504b9372d8cf93f4bb23e025e", size = 40790, upload-time = "2025-10-08T19:47:26.847Z" }, - { url = "https://files.pythonhosted.org/packages/59/1b/e71ae98235f8e2ba5004d8cb19765a74877abf189bc53fc0c80d799e56c3/propcache-0.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:8873eb4460fd55333ea49b7d189749ecf6e55bf85080f11b1c4530ed3034cba1", size = 37158, upload-time = "2025-10-08T19:47:27.961Z" }, - { url = "https://files.pythonhosted.org/packages/83/ce/a31bbdfc24ee0dcbba458c8175ed26089cf109a55bbe7b7640ed2470cfe9/propcache-0.4.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:92d1935ee1f8d7442da9c0c4fa7ac20d07e94064184811b685f5c4fada64553b", size = 81451, upload-time = "2025-10-08T19:47:29.445Z" }, - { url = "https://files.pythonhosted.org/packages/25/9c/442a45a470a68456e710d96cacd3573ef26a1d0a60067e6a7d5e655621ed/propcache-0.4.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:473c61b39e1460d386479b9b2f337da492042447c9b685f28be4f74d3529e566", size = 46374, upload-time = "2025-10-08T19:47:30.579Z" }, - { url = "https://files.pythonhosted.org/packages/f4/bf/b1d5e21dbc3b2e889ea4327044fb16312a736d97640fb8b6aa3f9c7b3b65/propcache-0.4.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:c0ef0aaafc66fbd87842a3fe3902fd889825646bc21149eafe47be6072725835", size = 48396, upload-time = "2025-10-08T19:47:31.79Z" }, - { url = "https://files.pythonhosted.org/packages/f4/04/5b4c54a103d480e978d3c8a76073502b18db0c4bc17ab91b3cb5092ad949/propcache-0.4.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f95393b4d66bfae908c3ca8d169d5f79cd65636ae15b5e7a4f6e67af675adb0e", size = 275950, upload-time = "2025-10-08T19:47:33.481Z" }, - { url = "https://files.pythonhosted.org/packages/b4/c1/86f846827fb969c4b78b0af79bba1d1ea2156492e1b83dea8b8a6ae27395/propcache-0.4.1-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c07fda85708bc48578467e85099645167a955ba093be0a2dcba962195676e859", size = 273856, upload-time = "2025-10-08T19:47:34.906Z" }, - { url = "https://files.pythonhosted.org/packages/36/1d/fc272a63c8d3bbad6878c336c7a7dea15e8f2d23a544bda43205dfa83ada/propcache-0.4.1-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:af223b406d6d000830c6f65f1e6431783fc3f713ba3e6cc8c024d5ee96170a4b", size = 280420, upload-time = "2025-10-08T19:47:36.338Z" }, - { url = "https://files.pythonhosted.org/packages/07/0c/01f2219d39f7e53d52e5173bcb09c976609ba30209912a0680adfb8c593a/propcache-0.4.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a78372c932c90ee474559c5ddfffd718238e8673c340dc21fe45c5b8b54559a0", size = 263254, upload-time = "2025-10-08T19:47:37.692Z" }, - { url = "https://files.pythonhosted.org/packages/2d/18/cd28081658ce597898f0c4d174d4d0f3c5b6d4dc27ffafeef835c95eb359/propcache-0.4.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:564d9f0d4d9509e1a870c920a89b2fec951b44bf5ba7d537a9e7c1ccec2c18af", size = 261205, upload-time = "2025-10-08T19:47:39.659Z" }, - { url = "https://files.pythonhosted.org/packages/7a/71/1f9e22eb8b8316701c2a19fa1f388c8a3185082607da8e406a803c9b954e/propcache-0.4.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:17612831fda0138059cc5546f4d12a2aacfb9e47068c06af35c400ba58ba7393", size = 247873, upload-time = "2025-10-08T19:47:41.084Z" }, - { url = "https://files.pythonhosted.org/packages/4a/65/3d4b61f36af2b4eddba9def857959f1016a51066b4f1ce348e0cf7881f58/propcache-0.4.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:41a89040cb10bd345b3c1a873b2bf36413d48da1def52f268a055f7398514874", size = 262739, upload-time = "2025-10-08T19:47:42.51Z" }, - { url = "https://files.pythonhosted.org/packages/2a/42/26746ab087faa77c1c68079b228810436ccd9a5ce9ac85e2b7307195fd06/propcache-0.4.1-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:e35b88984e7fa64aacecea39236cee32dd9bd8c55f57ba8a75cf2399553f9bd7", size = 263514, upload-time = "2025-10-08T19:47:43.927Z" }, - { url = "https://files.pythonhosted.org/packages/94/13/630690fe201f5502d2403dd3cfd451ed8858fe3c738ee88d095ad2ff407b/propcache-0.4.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f8b465489f927b0df505cbe26ffbeed4d6d8a2bbc61ce90eb074ff129ef0ab1", size = 257781, upload-time = "2025-10-08T19:47:45.448Z" }, - { url = "https://files.pythonhosted.org/packages/92/f7/1d4ec5841505f423469efbfc381d64b7b467438cd5a4bbcbb063f3b73d27/propcache-0.4.1-cp313-cp313t-win32.whl", hash = "sha256:2ad890caa1d928c7c2965b48f3a3815c853180831d0e5503d35cf00c472f4717", size = 41396, upload-time = "2025-10-08T19:47:47.202Z" }, - { url = "https://files.pythonhosted.org/packages/48/f0/615c30622316496d2cbbc29f5985f7777d3ada70f23370608c1d3e081c1f/propcache-0.4.1-cp313-cp313t-win_amd64.whl", hash = "sha256:f7ee0e597f495cf415bcbd3da3caa3bd7e816b74d0d52b8145954c5e6fd3ff37", size = 44897, upload-time = "2025-10-08T19:47:48.336Z" }, - { url = "https://files.pythonhosted.org/packages/fd/ca/6002e46eccbe0e33dcd4069ef32f7f1c9e243736e07adca37ae8c4830ec3/propcache-0.4.1-cp313-cp313t-win_arm64.whl", hash = "sha256:929d7cbe1f01bb7baffb33dc14eb5691c95831450a26354cd210a8155170c93a", size = 39789, upload-time = "2025-10-08T19:47:49.876Z" }, - { url = "https://files.pythonhosted.org/packages/8e/5c/bca52d654a896f831b8256683457ceddd490ec18d9ec50e97dfd8fc726a8/propcache-0.4.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3f7124c9d820ba5548d431afb4632301acf965db49e666aa21c305cbe8c6de12", size = 78152, upload-time = "2025-10-08T19:47:51.051Z" }, - { url = "https://files.pythonhosted.org/packages/65/9b/03b04e7d82a5f54fb16113d839f5ea1ede58a61e90edf515f6577c66fa8f/propcache-0.4.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:c0d4b719b7da33599dfe3b22d3db1ef789210a0597bc650b7cee9c77c2be8c5c", size = 44869, upload-time = "2025-10-08T19:47:52.594Z" }, - { url = "https://files.pythonhosted.org/packages/b2/fa/89a8ef0468d5833a23fff277b143d0573897cf75bd56670a6d28126c7d68/propcache-0.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:9f302f4783709a78240ebc311b793f123328716a60911d667e0c036bc5dcbded", size = 46596, upload-time = "2025-10-08T19:47:54.073Z" }, - { url = "https://files.pythonhosted.org/packages/86/bd/47816020d337f4a746edc42fe8d53669965138f39ee117414c7d7a340cfe/propcache-0.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c80ee5802e3fb9ea37938e7eecc307fb984837091d5fd262bb37238b1ae97641", size = 206981, upload-time = "2025-10-08T19:47:55.715Z" }, - { url = "https://files.pythonhosted.org/packages/df/f6/c5fa1357cc9748510ee55f37173eb31bfde6d94e98ccd9e6f033f2fc06e1/propcache-0.4.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ed5a841e8bb29a55fb8159ed526b26adc5bdd7e8bd7bf793ce647cb08656cdf4", size = 211490, upload-time = "2025-10-08T19:47:57.499Z" }, - { url = "https://files.pythonhosted.org/packages/80/1e/e5889652a7c4a3846683401a48f0f2e5083ce0ec1a8a5221d8058fbd1adf/propcache-0.4.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:55c72fd6ea2da4c318e74ffdf93c4fe4e926051133657459131a95c846d16d44", size = 215371, upload-time = "2025-10-08T19:47:59.317Z" }, - { url = "https://files.pythonhosted.org/packages/b2/f2/889ad4b2408f72fe1a4f6a19491177b30ea7bf1a0fd5f17050ca08cfc882/propcache-0.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8326e144341460402713f91df60ade3c999d601e7eb5ff8f6f7862d54de0610d", size = 201424, upload-time = "2025-10-08T19:48:00.67Z" }, - { url = "https://files.pythonhosted.org/packages/27/73/033d63069b57b0812c8bd19f311faebeceb6ba31b8f32b73432d12a0b826/propcache-0.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:060b16ae65bc098da7f6d25bf359f1f31f688384858204fe5d652979e0015e5b", size = 197566, upload-time = "2025-10-08T19:48:02.604Z" }, - { url = "https://files.pythonhosted.org/packages/dc/89/ce24f3dc182630b4e07aa6d15f0ff4b14ed4b9955fae95a0b54c58d66c05/propcache-0.4.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:89eb3fa9524f7bec9de6e83cf3faed9d79bffa560672c118a96a171a6f55831e", size = 193130, upload-time = "2025-10-08T19:48:04.499Z" }, - { url = "https://files.pythonhosted.org/packages/a9/24/ef0d5fd1a811fb5c609278d0209c9f10c35f20581fcc16f818da959fc5b4/propcache-0.4.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:dee69d7015dc235f526fe80a9c90d65eb0039103fe565776250881731f06349f", size = 202625, upload-time = "2025-10-08T19:48:06.213Z" }, - { url = "https://files.pythonhosted.org/packages/f5/02/98ec20ff5546f68d673df2f7a69e8c0d076b5abd05ca882dc7ee3a83653d/propcache-0.4.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:5558992a00dfd54ccbc64a32726a3357ec93825a418a401f5cc67df0ac5d9e49", size = 204209, upload-time = "2025-10-08T19:48:08.432Z" }, - { url = "https://files.pythonhosted.org/packages/a0/87/492694f76759b15f0467a2a93ab68d32859672b646aa8a04ce4864e7932d/propcache-0.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c9b822a577f560fbd9554812526831712c1436d2c046cedee4c3796d3543b144", size = 197797, upload-time = "2025-10-08T19:48:09.968Z" }, - { url = "https://files.pythonhosted.org/packages/ee/36/66367de3575db1d2d3f3d177432bd14ee577a39d3f5d1b3d5df8afe3b6e2/propcache-0.4.1-cp314-cp314-win32.whl", hash = "sha256:ab4c29b49d560fe48b696cdcb127dd36e0bc2472548f3bf56cc5cb3da2b2984f", size = 38140, upload-time = "2025-10-08T19:48:11.232Z" }, - { url = "https://files.pythonhosted.org/packages/0c/2a/a758b47de253636e1b8aef181c0b4f4f204bf0dd964914fb2af90a95b49b/propcache-0.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:5a103c3eb905fcea0ab98be99c3a9a5ab2de60228aa5aceedc614c0281cf6153", size = 41257, upload-time = "2025-10-08T19:48:12.707Z" }, - { url = "https://files.pythonhosted.org/packages/34/5e/63bd5896c3fec12edcbd6f12508d4890d23c265df28c74b175e1ef9f4f3b/propcache-0.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:74c1fb26515153e482e00177a1ad654721bf9207da8a494a0c05e797ad27b992", size = 38097, upload-time = "2025-10-08T19:48:13.923Z" }, - { url = "https://files.pythonhosted.org/packages/99/85/9ff785d787ccf9bbb3f3106f79884a130951436f58392000231b4c737c80/propcache-0.4.1-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:824e908bce90fb2743bd6b59db36eb4f45cd350a39637c9f73b1c1ea66f5b75f", size = 81455, upload-time = "2025-10-08T19:48:15.16Z" }, - { url = "https://files.pythonhosted.org/packages/90/85/2431c10c8e7ddb1445c1f7c4b54d886e8ad20e3c6307e7218f05922cad67/propcache-0.4.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:c2b5e7db5328427c57c8e8831abda175421b709672f6cfc3d630c3b7e2146393", size = 46372, upload-time = "2025-10-08T19:48:16.424Z" }, - { url = "https://files.pythonhosted.org/packages/01/20/b0972d902472da9bcb683fa595099911f4d2e86e5683bcc45de60dd05dc3/propcache-0.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6f6ff873ed40292cd4969ef5310179afd5db59fdf055897e282485043fc80ad0", size = 48411, upload-time = "2025-10-08T19:48:17.577Z" }, - { url = "https://files.pythonhosted.org/packages/e2/e3/7dc89f4f21e8f99bad3d5ddb3a3389afcf9da4ac69e3deb2dcdc96e74169/propcache-0.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:49a2dc67c154db2c1463013594c458881a069fcf98940e61a0569016a583020a", size = 275712, upload-time = "2025-10-08T19:48:18.901Z" }, - { url = "https://files.pythonhosted.org/packages/20/67/89800c8352489b21a8047c773067644e3897f02ecbbd610f4d46b7f08612/propcache-0.4.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:005f08e6a0529984491e37d8dbc3dd86f84bd78a8ceb5fa9a021f4c48d4984be", size = 273557, upload-time = "2025-10-08T19:48:20.762Z" }, - { url = "https://files.pythonhosted.org/packages/e2/a1/b52b055c766a54ce6d9c16d9aca0cad8059acd9637cdf8aa0222f4a026ef/propcache-0.4.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5c3310452e0d31390da9035c348633b43d7e7feb2e37be252be6da45abd1abcc", size = 280015, upload-time = "2025-10-08T19:48:22.592Z" }, - { url = "https://files.pythonhosted.org/packages/48/c8/33cee30bd890672c63743049f3c9e4be087e6780906bfc3ec58528be59c1/propcache-0.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c3c70630930447f9ef1caac7728c8ad1c56bc5015338b20fed0d08ea2480b3a", size = 262880, upload-time = "2025-10-08T19:48:23.947Z" }, - { url = "https://files.pythonhosted.org/packages/0c/b1/8f08a143b204b418285c88b83d00edbd61afbc2c6415ffafc8905da7038b/propcache-0.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8e57061305815dfc910a3634dcf584f08168a8836e6999983569f51a8544cd89", size = 260938, upload-time = "2025-10-08T19:48:25.656Z" }, - { url = "https://files.pythonhosted.org/packages/cf/12/96e4664c82ca2f31e1c8dff86afb867348979eb78d3cb8546a680287a1e9/propcache-0.4.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:521a463429ef54143092c11a77e04056dd00636f72e8c45b70aaa3140d639726", size = 247641, upload-time = "2025-10-08T19:48:27.207Z" }, - { url = "https://files.pythonhosted.org/packages/18/ed/e7a9cfca28133386ba52278136d42209d3125db08d0a6395f0cba0c0285c/propcache-0.4.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:120c964da3fdc75e3731aa392527136d4ad35868cc556fd09bb6d09172d9a367", size = 262510, upload-time = "2025-10-08T19:48:28.65Z" }, - { url = "https://files.pythonhosted.org/packages/f5/76/16d8bf65e8845dd62b4e2b57444ab81f07f40caa5652b8969b87ddcf2ef6/propcache-0.4.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:d8f353eb14ee3441ee844ade4277d560cdd68288838673273b978e3d6d2c8f36", size = 263161, upload-time = "2025-10-08T19:48:30.133Z" }, - { url = "https://files.pythonhosted.org/packages/e7/70/c99e9edb5d91d5ad8a49fa3c1e8285ba64f1476782fed10ab251ff413ba1/propcache-0.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ab2943be7c652f09638800905ee1bab2c544e537edb57d527997a24c13dc1455", size = 257393, upload-time = "2025-10-08T19:48:31.567Z" }, - { url = "https://files.pythonhosted.org/packages/08/02/87b25304249a35c0915d236575bc3574a323f60b47939a2262b77632a3ee/propcache-0.4.1-cp314-cp314t-win32.whl", hash = "sha256:05674a162469f31358c30bcaa8883cb7829fa3110bf9c0991fe27d7896c42d85", size = 42546, upload-time = "2025-10-08T19:48:32.872Z" }, - { url = "https://files.pythonhosted.org/packages/cb/ef/3c6ecf8b317aa982f309835e8f96987466123c6e596646d4e6a1dfcd080f/propcache-0.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:990f6b3e2a27d683cb7602ed6c86f15ee6b43b1194736f9baaeb93d0016633b1", size = 46259, upload-time = "2025-10-08T19:48:34.226Z" }, - { url = "https://files.pythonhosted.org/packages/c4/2d/346e946d4951f37eca1e4f55be0f0174c52cd70720f84029b02f296f4a38/propcache-0.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:ecef2343af4cc68e05131e45024ba34f6095821988a9d0a02aa7c73fcc448aa9", size = 40428, upload-time = "2025-10-08T19:48:35.441Z" }, - { url = "https://files.pythonhosted.org/packages/5b/5a/bc7b4a4ef808fa59a816c17b20c4bef6884daebbdf627ff2a161da67da19/propcache-0.4.1-py3-none-any.whl", hash = "sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237", size = 13305, upload-time = "2025-10-08T19:49:00.792Z" }, -] - -[[package]] -name = "pydantic" -version = "2.12.5" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "annotated-types" }, - { name = "pydantic-core" }, - { name = "typing-extensions" }, - { name = "typing-inspection" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/69/44/36f1a6e523abc58ae5f928898e4aca2e0ea509b5aa6f6f392a5d882be928/pydantic-2.12.5.tar.gz", hash = "sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49", size = 821591, upload-time = "2025-11-26T15:11:46.471Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl", hash = "sha256:e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d", size = 463580, upload-time = "2025-11-26T15:11:44.605Z" }, -] - -[package.optional-dependencies] -email = [ - { name = "email-validator" }, -] - -[[package]] -name = "pydantic-core" -version = "2.41.5" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/71/70/23b021c950c2addd24ec408e9ab05d59b035b39d97cdc1130e1bce647bb6/pydantic_core-2.41.5.tar.gz", hash = "sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e", size = 460952, upload-time = "2025-11-04T13:43:49.098Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/87/06/8806241ff1f70d9939f9af039c6c35f2360cf16e93c2ca76f184e76b1564/pydantic_core-2.41.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:941103c9be18ac8daf7b7adca8228f8ed6bb7a1849020f643b3a14d15b1924d9", size = 2120403, upload-time = "2025-11-04T13:40:25.248Z" }, - { url = "https://files.pythonhosted.org/packages/94/02/abfa0e0bda67faa65fef1c84971c7e45928e108fe24333c81f3bfe35d5f5/pydantic_core-2.41.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:112e305c3314f40c93998e567879e887a3160bb8689ef3d2c04b6cc62c33ac34", size = 1896206, upload-time = "2025-11-04T13:40:27.099Z" }, - { url = "https://files.pythonhosted.org/packages/15/df/a4c740c0943e93e6500f9eb23f4ca7ec9bf71b19e608ae5b579678c8d02f/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cbaad15cb0c90aa221d43c00e77bb33c93e8d36e0bf74760cd00e732d10a6a0", size = 1919307, upload-time = "2025-11-04T13:40:29.806Z" }, - { url = "https://files.pythonhosted.org/packages/9a/e3/6324802931ae1d123528988e0e86587c2072ac2e5394b4bc2bc34b61ff6e/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:03ca43e12fab6023fc79d28ca6b39b05f794ad08ec2feccc59a339b02f2b3d33", size = 2063258, upload-time = "2025-11-04T13:40:33.544Z" }, - { url = "https://files.pythonhosted.org/packages/c9/d4/2230d7151d4957dd79c3044ea26346c148c98fbf0ee6ebd41056f2d62ab5/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc799088c08fa04e43144b164feb0c13f9a0bc40503f8df3e9fde58a3c0c101e", size = 2214917, upload-time = "2025-11-04T13:40:35.479Z" }, - { url = "https://files.pythonhosted.org/packages/e6/9f/eaac5df17a3672fef0081b6c1bb0b82b33ee89aa5cec0d7b05f52fd4a1fa/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:97aeba56665b4c3235a0e52b2c2f5ae9cd071b8a8310ad27bddb3f7fb30e9aa2", size = 2332186, upload-time = "2025-11-04T13:40:37.436Z" }, - { url = "https://files.pythonhosted.org/packages/cf/4e/35a80cae583a37cf15604b44240e45c05e04e86f9cfd766623149297e971/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:406bf18d345822d6c21366031003612b9c77b3e29ffdb0f612367352aab7d586", size = 2073164, upload-time = "2025-11-04T13:40:40.289Z" }, - { url = "https://files.pythonhosted.org/packages/bf/e3/f6e262673c6140dd3305d144d032f7bd5f7497d3871c1428521f19f9efa2/pydantic_core-2.41.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b93590ae81f7010dbe380cdeab6f515902ebcbefe0b9327cc4804d74e93ae69d", size = 2179146, upload-time = "2025-11-04T13:40:42.809Z" }, - { url = "https://files.pythonhosted.org/packages/75/c7/20bd7fc05f0c6ea2056a4565c6f36f8968c0924f19b7d97bbfea55780e73/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:01a3d0ab748ee531f4ea6c3e48ad9dac84ddba4b0d82291f87248f2f9de8d740", size = 2137788, upload-time = "2025-11-04T13:40:44.752Z" }, - { url = "https://files.pythonhosted.org/packages/3a/8d/34318ef985c45196e004bc46c6eab2eda437e744c124ef0dbe1ff2c9d06b/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:6561e94ba9dacc9c61bce40e2d6bdc3bfaa0259d3ff36ace3b1e6901936d2e3e", size = 2340133, upload-time = "2025-11-04T13:40:46.66Z" }, - { url = "https://files.pythonhosted.org/packages/9c/59/013626bf8c78a5a5d9350d12e7697d3d4de951a75565496abd40ccd46bee/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:915c3d10f81bec3a74fbd4faebe8391013ba61e5a1a8d48c4455b923bdda7858", size = 2324852, upload-time = "2025-11-04T13:40:48.575Z" }, - { url = "https://files.pythonhosted.org/packages/1a/d9/c248c103856f807ef70c18a4f986693a46a8ffe1602e5d361485da502d20/pydantic_core-2.41.5-cp313-cp313-win32.whl", hash = "sha256:650ae77860b45cfa6e2cdafc42618ceafab3a2d9a3811fcfbd3bbf8ac3c40d36", size = 1994679, upload-time = "2025-11-04T13:40:50.619Z" }, - { url = "https://files.pythonhosted.org/packages/9e/8b/341991b158ddab181cff136acd2552c9f35bd30380422a639c0671e99a91/pydantic_core-2.41.5-cp313-cp313-win_amd64.whl", hash = "sha256:79ec52ec461e99e13791ec6508c722742ad745571f234ea6255bed38c6480f11", size = 2019766, upload-time = "2025-11-04T13:40:52.631Z" }, - { url = "https://files.pythonhosted.org/packages/73/7d/f2f9db34af103bea3e09735bb40b021788a5e834c81eedb541991badf8f5/pydantic_core-2.41.5-cp313-cp313-win_arm64.whl", hash = "sha256:3f84d5c1b4ab906093bdc1ff10484838aca54ef08de4afa9de0f5f14d69639cd", size = 1981005, upload-time = "2025-11-04T13:40:54.734Z" }, - { url = "https://files.pythonhosted.org/packages/ea/28/46b7c5c9635ae96ea0fbb779e271a38129df2550f763937659ee6c5dbc65/pydantic_core-2.41.5-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a", size = 2119622, upload-time = "2025-11-04T13:40:56.68Z" }, - { url = "https://files.pythonhosted.org/packages/74/1a/145646e5687e8d9a1e8d09acb278c8535ebe9e972e1f162ed338a622f193/pydantic_core-2.41.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14", size = 1891725, upload-time = "2025-11-04T13:40:58.807Z" }, - { url = "https://files.pythonhosted.org/packages/23/04/e89c29e267b8060b40dca97bfc64a19b2a3cf99018167ea1677d96368273/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25e1c2af0fce638d5f1988b686f3b3ea8cd7de5f244ca147c777769e798a9cd1", size = 1915040, upload-time = "2025-11-04T13:41:00.853Z" }, - { url = "https://files.pythonhosted.org/packages/84/a3/15a82ac7bd97992a82257f777b3583d3e84bdb06ba6858f745daa2ec8a85/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:506d766a8727beef16b7adaeb8ee6217c64fc813646b424d0804d67c16eddb66", size = 2063691, upload-time = "2025-11-04T13:41:03.504Z" }, - { url = "https://files.pythonhosted.org/packages/74/9b/0046701313c6ef08c0c1cf0e028c67c770a4e1275ca73131563c5f2a310a/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4819fa52133c9aa3c387b3328f25c1facc356491e6135b459f1de698ff64d869", size = 2213897, upload-time = "2025-11-04T13:41:05.804Z" }, - { url = "https://files.pythonhosted.org/packages/8a/cd/6bac76ecd1b27e75a95ca3a9a559c643b3afcd2dd62086d4b7a32a18b169/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b761d210c9ea91feda40d25b4efe82a1707da2ef62901466a42492c028553a2", size = 2333302, upload-time = "2025-11-04T13:41:07.809Z" }, - { url = "https://files.pythonhosted.org/packages/4c/d2/ef2074dc020dd6e109611a8be4449b98cd25e1b9b8a303c2f0fca2f2bcf7/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375", size = 2064877, upload-time = "2025-11-04T13:41:09.827Z" }, - { url = "https://files.pythonhosted.org/packages/18/66/e9db17a9a763d72f03de903883c057b2592c09509ccfe468187f2a2eef29/pydantic_core-2.41.5-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2782c870e99878c634505236d81e5443092fba820f0373997ff75f90f68cd553", size = 2180680, upload-time = "2025-11-04T13:41:12.379Z" }, - { url = "https://files.pythonhosted.org/packages/d3/9e/3ce66cebb929f3ced22be85d4c2399b8e85b622db77dad36b73c5387f8f8/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:0177272f88ab8312479336e1d777f6b124537d47f2123f89cb37e0accea97f90", size = 2138960, upload-time = "2025-11-04T13:41:14.627Z" }, - { url = "https://files.pythonhosted.org/packages/a6/62/205a998f4327d2079326b01abee48e502ea739d174f0a89295c481a2272e/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:63510af5e38f8955b8ee5687740d6ebf7c2a0886d15a6d65c32814613681bc07", size = 2339102, upload-time = "2025-11-04T13:41:16.868Z" }, - { url = "https://files.pythonhosted.org/packages/3c/0d/f05e79471e889d74d3d88f5bd20d0ed189ad94c2423d81ff8d0000aab4ff/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:e56ba91f47764cc14f1daacd723e3e82d1a89d783f0f5afe9c364b8bb491ccdb", size = 2326039, upload-time = "2025-11-04T13:41:18.934Z" }, - { url = "https://files.pythonhosted.org/packages/ec/e1/e08a6208bb100da7e0c4b288eed624a703f4d129bde2da475721a80cab32/pydantic_core-2.41.5-cp314-cp314-win32.whl", hash = "sha256:aec5cf2fd867b4ff45b9959f8b20ea3993fc93e63c7363fe6851424c8a7e7c23", size = 1995126, upload-time = "2025-11-04T13:41:21.418Z" }, - { url = "https://files.pythonhosted.org/packages/48/5d/56ba7b24e9557f99c9237e29f5c09913c81eeb2f3217e40e922353668092/pydantic_core-2.41.5-cp314-cp314-win_amd64.whl", hash = "sha256:8e7c86f27c585ef37c35e56a96363ab8de4e549a95512445b85c96d3e2f7c1bf", size = 2015489, upload-time = "2025-11-04T13:41:24.076Z" }, - { url = "https://files.pythonhosted.org/packages/4e/bb/f7a190991ec9e3e0ba22e4993d8755bbc4a32925c0b5b42775c03e8148f9/pydantic_core-2.41.5-cp314-cp314-win_arm64.whl", hash = "sha256:e672ba74fbc2dc8eea59fb6d4aed6845e6905fc2a8afe93175d94a83ba2a01a0", size = 1977288, upload-time = "2025-11-04T13:41:26.33Z" }, - { url = "https://files.pythonhosted.org/packages/92/ed/77542d0c51538e32e15afe7899d79efce4b81eee631d99850edc2f5e9349/pydantic_core-2.41.5-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:8566def80554c3faa0e65ac30ab0932b9e3a5cd7f8323764303d468e5c37595a", size = 2120255, upload-time = "2025-11-04T13:41:28.569Z" }, - { url = "https://files.pythonhosted.org/packages/bb/3d/6913dde84d5be21e284439676168b28d8bbba5600d838b9dca99de0fad71/pydantic_core-2.41.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b80aa5095cd3109962a298ce14110ae16b8c1aece8b72f9dafe81cf597ad80b3", size = 1863760, upload-time = "2025-11-04T13:41:31.055Z" }, - { url = "https://files.pythonhosted.org/packages/5a/f0/e5e6b99d4191da102f2b0eb9687aaa7f5bea5d9964071a84effc3e40f997/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3006c3dd9ba34b0c094c544c6006cc79e87d8612999f1a5d43b769b89181f23c", size = 1878092, upload-time = "2025-11-04T13:41:33.21Z" }, - { url = "https://files.pythonhosted.org/packages/71/48/36fb760642d568925953bcc8116455513d6e34c4beaa37544118c36aba6d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:72f6c8b11857a856bcfa48c86f5368439f74453563f951e473514579d44aa612", size = 2053385, upload-time = "2025-11-04T13:41:35.508Z" }, - { url = "https://files.pythonhosted.org/packages/20/25/92dc684dd8eb75a234bc1c764b4210cf2646479d54b47bf46061657292a8/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5cb1b2f9742240e4bb26b652a5aeb840aa4b417c7748b6f8387927bc6e45e40d", size = 2218832, upload-time = "2025-11-04T13:41:37.732Z" }, - { url = "https://files.pythonhosted.org/packages/e2/09/f53e0b05023d3e30357d82eb35835d0f6340ca344720a4599cd663dca599/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bd3d54f38609ff308209bd43acea66061494157703364ae40c951f83ba99a1a9", size = 2327585, upload-time = "2025-11-04T13:41:40Z" }, - { url = "https://files.pythonhosted.org/packages/aa/4e/2ae1aa85d6af35a39b236b1b1641de73f5a6ac4d5a7509f77b814885760c/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ff4321e56e879ee8d2a879501c8e469414d948f4aba74a2d4593184eb326660", size = 2041078, upload-time = "2025-11-04T13:41:42.323Z" }, - { url = "https://files.pythonhosted.org/packages/cd/13/2e215f17f0ef326fc72afe94776edb77525142c693767fc347ed6288728d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d0d2568a8c11bf8225044aa94409e21da0cb09dcdafe9ecd10250b2baad531a9", size = 2173914, upload-time = "2025-11-04T13:41:45.221Z" }, - { url = "https://files.pythonhosted.org/packages/02/7a/f999a6dcbcd0e5660bc348a3991c8915ce6599f4f2c6ac22f01d7a10816c/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:a39455728aabd58ceabb03c90e12f71fd30fa69615760a075b9fec596456ccc3", size = 2129560, upload-time = "2025-11-04T13:41:47.474Z" }, - { url = "https://files.pythonhosted.org/packages/3a/b1/6c990ac65e3b4c079a4fb9f5b05f5b013afa0f4ed6780a3dd236d2cbdc64/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:239edca560d05757817c13dc17c50766136d21f7cd0fac50295499ae24f90fdf", size = 2329244, upload-time = "2025-11-04T13:41:49.992Z" }, - { url = "https://files.pythonhosted.org/packages/d9/02/3c562f3a51afd4d88fff8dffb1771b30cfdfd79befd9883ee094f5b6c0d8/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:2a5e06546e19f24c6a96a129142a75cee553cc018ffee48a460059b1185f4470", size = 2331955, upload-time = "2025-11-04T13:41:54.079Z" }, - { url = "https://files.pythonhosted.org/packages/5c/96/5fb7d8c3c17bc8c62fdb031c47d77a1af698f1d7a406b0f79aaa1338f9ad/pydantic_core-2.41.5-cp314-cp314t-win32.whl", hash = "sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa", size = 1988906, upload-time = "2025-11-04T13:41:56.606Z" }, - { url = "https://files.pythonhosted.org/packages/22/ed/182129d83032702912c2e2d8bbe33c036f342cc735737064668585dac28f/pydantic_core-2.41.5-cp314-cp314t-win_amd64.whl", hash = "sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c", size = 1981607, upload-time = "2025-11-04T13:41:58.889Z" }, - { url = "https://files.pythonhosted.org/packages/9f/ed/068e41660b832bb0b1aa5b58011dea2a3fe0ba7861ff38c4d4904c1c1a99/pydantic_core-2.41.5-cp314-cp314t-win_arm64.whl", hash = "sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008", size = 1974769, upload-time = "2025-11-04T13:42:01.186Z" }, -] - -[[package]] -name = "pydantic-settings" -version = "2.12.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pydantic" }, - { name = "python-dotenv" }, - { name = "typing-inspection" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/43/4b/ac7e0aae12027748076d72a8764ff1c9d82ca75a7a52622e67ed3f765c54/pydantic_settings-2.12.0.tar.gz", hash = "sha256:005538ef951e3c2a68e1c08b292b5f2e71490def8589d4221b95dab00dafcfd0", size = 194184, upload-time = "2025-11-10T14:25:47.013Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c1/60/5d4751ba3f4a40a6891f24eec885f51afd78d208498268c734e256fb13c4/pydantic_settings-2.12.0-py3-none-any.whl", hash = "sha256:fddb9fd99a5b18da837b29710391e945b1e30c135477f484084ee513adb93809", size = 51880, upload-time = "2025-11-10T14:25:45.546Z" }, -] - -[[package]] -name = "pygments" -version = "2.19.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, -] - -[[package]] -name = "pymysql" -version = "1.1.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f5/ae/1fe3fcd9f959efa0ebe200b8de88b5a5ce3e767e38c7ac32fb179f16a388/pymysql-1.1.2.tar.gz", hash = "sha256:4961d3e165614ae65014e361811a724e2044ad3ea3739de9903ae7c21f539f03", size = 48258, upload-time = "2025-08-24T12:55:55.146Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7c/4c/ad33b92b9864cbde84f259d5df035a6447f91891f5be77788e2a3892bce3/pymysql-1.1.2-py3-none-any.whl", hash = "sha256:e6b1d89711dd51f8f74b1631fe08f039e7d76cf67a42a323d3178f0f25762ed9", size = 45300, upload-time = "2025-08-24T12:55:53.394Z" }, -] - -[[package]] -name = "pytest" -version = "9.0.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, - { name = "iniconfig" }, - { name = "packaging" }, - { name = "pluggy" }, - { name = "pygments" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/d1/db/7ef3487e0fb0049ddb5ce41d3a49c235bf9ad299b6a25d5780a89f19230f/pytest-9.0.2.tar.gz", hash = "sha256:75186651a92bd89611d1d9fc20f0b4345fd827c41ccd5c299a868a05d70edf11", size = 1568901, upload-time = "2025-12-06T21:30:51.014Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl", hash = "sha256:711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b", size = 374801, upload-time = "2025-12-06T21:30:49.154Z" }, -] - -[[package]] -name = "pytest-asyncio" -version = "1.3.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pytest" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/90/2c/8af215c0f776415f3590cac4f9086ccefd6fd463befeae41cd4d3f193e5a/pytest_asyncio-1.3.0.tar.gz", hash = "sha256:d7f52f36d231b80ee124cd216ffb19369aa168fc10095013c6b014a34d3ee9e5", size = 50087, upload-time = "2025-11-10T16:07:47.256Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e5/35/f8b19922b6a25bc0880171a2f1a003eaeb93657475193ab516fd87cac9da/pytest_asyncio-1.3.0-py3-none-any.whl", hash = "sha256:611e26147c7f77640e6d0a92a38ed17c3e9848063698d5c93d5aa7aa11cebff5", size = 15075, upload-time = "2025-11-10T16:07:45.537Z" }, -] - -[[package]] -name = "python-dotenv" -version = "1.2.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f0/26/19cadc79a718c5edbec86fd4919a6b6d3f681039a2f6d66d14be94e75fb9/python_dotenv-1.2.1.tar.gz", hash = "sha256:42667e897e16ab0d66954af0e60a9caa94f0fd4ecf3aaf6d2d260eec1aa36ad6", size = 44221, upload-time = "2025-10-26T15:12:10.434Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/14/1b/a298b06749107c305e1fe0f814c6c74aea7b2f1e10989cb30f544a1b3253/python_dotenv-1.2.1-py3-none-any.whl", hash = "sha256:b81ee9561e9ca4004139c6cbba3a238c32b03e4894671e181b671e8cb8425d61", size = 21230, upload-time = "2025-10-26T15:12:09.109Z" }, -] - -[[package]] -name = "python-multipart" -version = "0.0.21" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/78/96/804520d0850c7db98e5ccb70282e29208723f0964e88ffd9d0da2f52ea09/python_multipart-0.0.21.tar.gz", hash = "sha256:7137ebd4d3bbf70ea1622998f902b97a29434a9e8dc40eb203bbcf7c2a2cba92", size = 37196, upload-time = "2025-12-17T09:24:22.446Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/aa/76/03af049af4dcee5d27442f71b6924f01f3efb5d2bd34f23fcd563f2cc5f5/python_multipart-0.0.21-py3-none-any.whl", hash = "sha256:cf7a6713e01c87aa35387f4774e812c4361150938d20d232800f75ffcf266090", size = 24541, upload-time = "2025-12-17T09:24:21.153Z" }, -] - -[[package]] -name = "pyyaml" -version = "6.0.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, - { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, - { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, - { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, - { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, - { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, - { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, - { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, - { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, - { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, - { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, - { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, - { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, - { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" }, - { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" }, - { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" }, - { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" }, - { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" }, - { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" }, - { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" }, - { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" }, - { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" }, - { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" }, - { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" }, - { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" }, - { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, - { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, - { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, -] - -[[package]] -name = "redis" -version = "7.1.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/43/c8/983d5c6579a411d8a99bc5823cc5712768859b5ce2c8afe1a65b37832c81/redis-7.1.0.tar.gz", hash = "sha256:b1cc3cfa5a2cb9c2ab3ba700864fb0ad75617b41f01352ce5779dabf6d5f9c3c", size = 4796669, upload-time = "2025-11-19T15:54:39.961Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/89/f0/8956f8a86b20d7bb9d6ac0187cf4cd54d8065bc9a1a09eb8011d4d326596/redis-7.1.0-py3-none-any.whl", hash = "sha256:23c52b208f92b56103e17c5d06bdc1a6c2c0b3106583985a76a18f83b265de2b", size = 354159, upload-time = "2025-11-19T15:54:38.064Z" }, -] - -[[package]] -name = "rich" -version = "14.2.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "markdown-it-py" }, - { name = "pygments" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/fb/d2/8920e102050a0de7bfabeb4c4614a49248cf8d5d7a8d01885fbb24dc767a/rich-14.2.0.tar.gz", hash = "sha256:73ff50c7c0c1c77c8243079283f4edb376f0f6442433aecb8ce7e6d0b92d1fe4", size = 219990, upload-time = "2025-10-09T14:16:53.064Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/25/7a/b0178788f8dc6cafce37a212c99565fa1fe7872c70c6c9c1e1a372d9d88f/rich-14.2.0-py3-none-any.whl", hash = "sha256:76bc51fe2e57d2b1be1f96c524b890b816e334ab4c1e45888799bfaab0021edd", size = 243393, upload-time = "2025-10-09T14:16:51.245Z" }, -] - -[[package]] -name = "rich-toolkit" -version = "0.17.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "click" }, - { name = "rich" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/97/09/3f9b8d9daaf235195c626f21e03604c05b987404ee3bcacee0c1f67f2a8e/rich_toolkit-0.17.1.tar.gz", hash = "sha256:5af54df8d1dd9c8530e462e1bdcaed625c9b49f5a55b035aa0ba1c17bdb87c9a", size = 187925, upload-time = "2025-12-17T10:49:22.583Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7f/7b/15e55fa8a76d0d41bf34d965af78acdaf80a315907adb30de8b63c272694/rich_toolkit-0.17.1-py3-none-any.whl", hash = "sha256:96d24bb921ecd225ffce7c526a9149e74006410c05e6d405bd74ffd54d5631ed", size = 31412, upload-time = "2025-12-17T10:49:21.793Z" }, -] - -[[package]] -name = "rignore" -version = "0.7.6" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e5/f5/8bed2310abe4ae04b67a38374a4d311dd85220f5d8da56f47ae9361be0b0/rignore-0.7.6.tar.gz", hash = "sha256:00d3546cd793c30cb17921ce674d2c8f3a4b00501cb0e3dd0e82217dbeba2671", size = 57140, upload-time = "2025-11-05T21:41:21.968Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/8a/a4078f6e14932ac7edb171149c481de29969d96ddee3ece5dc4c26f9e0c3/rignore-0.7.6-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:2bdab1d31ec9b4fb1331980ee49ea051c0d7f7bb6baa28b3125ef03cdc48fdaf", size = 883057, upload-time = "2025-11-05T20:42:42.741Z" }, - { url = "https://files.pythonhosted.org/packages/f9/8f/f8daacd177db4bf7c2223bab41e630c52711f8af9ed279be2058d2fe4982/rignore-0.7.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:90f0a00ce0c866c275bf888271f1dc0d2140f29b82fcf33cdbda1e1a6af01010", size = 820150, upload-time = "2025-11-05T20:42:26.545Z" }, - { url = "https://files.pythonhosted.org/packages/36/31/b65b837e39c3f7064c426754714ac633b66b8c2290978af9d7f513e14aa9/rignore-0.7.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1ad295537041dc2ed4b540fb1a3906bd9ede6ccdad3fe79770cd89e04e3c73c", size = 897406, upload-time = "2025-11-05T20:40:53.854Z" }, - { url = "https://files.pythonhosted.org/packages/ca/58/1970ce006c427e202ac7c081435719a076c478f07b3a23f469227788dc23/rignore-0.7.6-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f782dbd3a65a5ac85adfff69e5c6b101285ef3f845c3a3cae56a54bebf9fe116", size = 874050, upload-time = "2025-11-05T20:41:08.922Z" }, - { url = "https://files.pythonhosted.org/packages/d4/00/eb45db9f90137329072a732273be0d383cb7d7f50ddc8e0bceea34c1dfdf/rignore-0.7.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:65cece3b36e5b0826d946494734c0e6aaf5a0337e18ff55b071438efe13d559e", size = 1167835, upload-time = "2025-11-05T20:41:24.997Z" }, - { url = "https://files.pythonhosted.org/packages/f3/f1/6f1d72ddca41a64eed569680587a1236633587cc9f78136477ae69e2c88a/rignore-0.7.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d7e4bb66c13cd7602dc8931822c02dfbbd5252015c750ac5d6152b186f0a8be0", size = 941945, upload-time = "2025-11-05T20:41:40.628Z" }, - { url = "https://files.pythonhosted.org/packages/48/6f/2f178af1c1a276a065f563ec1e11e7a9e23d4996fd0465516afce4b5c636/rignore-0.7.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:297e500c15766e196f68aaaa70e8b6db85fa23fdc075b880d8231fdfba738cd7", size = 959067, upload-time = "2025-11-05T20:42:11.09Z" }, - { url = "https://files.pythonhosted.org/packages/5b/db/423a81c4c1e173877c7f9b5767dcaf1ab50484a94f60a0b2ed78be3fa765/rignore-0.7.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a07084211a8d35e1a5b1d32b9661a5ed20669970b369df0cf77da3adea3405de", size = 984438, upload-time = "2025-11-05T20:41:55.443Z" }, - { url = "https://files.pythonhosted.org/packages/31/eb/c4f92cc3f2825d501d3c46a244a671eb737fc1bcf7b05a3ecd34abb3e0d7/rignore-0.7.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:181eb2a975a22256a1441a9d2f15eb1292839ea3f05606620bd9e1938302cf79", size = 1078365, upload-time = "2025-11-05T21:40:15.148Z" }, - { url = "https://files.pythonhosted.org/packages/26/09/99442f02794bd7441bfc8ed1c7319e890449b816a7493b2db0e30af39095/rignore-0.7.6-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:7bbcdc52b5bf9f054b34ce4af5269df5d863d9c2456243338bc193c28022bd7b", size = 1139066, upload-time = "2025-11-05T21:40:32.771Z" }, - { url = "https://files.pythonhosted.org/packages/2c/88/bcfc21e520bba975410e9419450f4b90a2ac8236b9a80fd8130e87d098af/rignore-0.7.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f2e027a6da21a7c8c0d87553c24ca5cc4364def18d146057862c23a96546238e", size = 1118036, upload-time = "2025-11-05T21:40:49.646Z" }, - { url = "https://files.pythonhosted.org/packages/e2/25/d37215e4562cda5c13312636393aea0bafe38d54d4e0517520a4cc0753ec/rignore-0.7.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ee4a18b82cbbc648e4aac1510066682fe62beb5dc88e2c67c53a83954e541360", size = 1127550, upload-time = "2025-11-05T21:41:07.648Z" }, - { url = "https://files.pythonhosted.org/packages/dc/76/a264ab38bfa1620ec12a8ff1c07778da89e16d8c0f3450b0333020d3d6dc/rignore-0.7.6-cp313-cp313-win32.whl", hash = "sha256:a7d7148b6e5e95035d4390396895adc384d37ff4e06781a36fe573bba7c283e5", size = 646097, upload-time = "2025-11-05T21:41:53.201Z" }, - { url = "https://files.pythonhosted.org/packages/62/44/3c31b8983c29ea8832b6082ddb1d07b90379c2d993bd20fce4487b71b4f4/rignore-0.7.6-cp313-cp313-win_amd64.whl", hash = "sha256:b037c4b15a64dced08fc12310ee844ec2284c4c5c1ca77bc37d0a04f7bff386e", size = 726170, upload-time = "2025-11-05T21:41:38.131Z" }, - { url = "https://files.pythonhosted.org/packages/aa/41/e26a075cab83debe41a42661262f606166157df84e0e02e2d904d134c0d8/rignore-0.7.6-cp313-cp313-win_arm64.whl", hash = "sha256:e47443de9b12fe569889bdbe020abe0e0b667516ee2ab435443f6d0869bd2804", size = 656184, upload-time = "2025-11-05T21:41:27.396Z" }, - { url = "https://files.pythonhosted.org/packages/9a/b9/1f5bd82b87e5550cd843ceb3768b4a8ef274eb63f29333cf2f29644b3d75/rignore-0.7.6-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:8e41be9fa8f2f47239ded8920cc283699a052ac4c371f77f5ac017ebeed75732", size = 882632, upload-time = "2025-11-05T20:42:44.063Z" }, - { url = "https://files.pythonhosted.org/packages/e9/6b/07714a3efe4a8048864e8a5b7db311ba51b921e15268b17defaebf56d3db/rignore-0.7.6-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:6dc1e171e52cefa6c20e60c05394a71165663b48bca6c7666dee4f778f2a7d90", size = 820760, upload-time = "2025-11-05T20:42:27.885Z" }, - { url = "https://files.pythonhosted.org/packages/ac/0f/348c829ea2d8d596e856371b14b9092f8a5dfbb62674ec9b3f67e4939a9d/rignore-0.7.6-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ce2268837c3600f82ab8db58f5834009dc638ee17103582960da668963bebc5", size = 899044, upload-time = "2025-11-05T20:40:55.336Z" }, - { url = "https://files.pythonhosted.org/packages/f0/30/2e1841a19b4dd23878d73edd5d82e998a83d5ed9570a89675f140ca8b2ad/rignore-0.7.6-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:690a3e1b54bfe77e89c4bacb13f046e642f8baadafc61d68f5a726f324a76ab6", size = 874144, upload-time = "2025-11-05T20:41:10.195Z" }, - { url = "https://files.pythonhosted.org/packages/c2/bf/0ce9beb2e5f64c30e3580bef09f5829236889f01511a125f98b83169b993/rignore-0.7.6-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09d12ac7a0b6210c07bcd145007117ebd8abe99c8eeb383e9e4673910c2754b2", size = 1168062, upload-time = "2025-11-05T20:41:26.511Z" }, - { url = "https://files.pythonhosted.org/packages/b9/8b/571c178414eb4014969865317da8a02ce4cf5241a41676ef91a59aab24de/rignore-0.7.6-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2a2b2b74a8c60203b08452479b90e5ce3dbe96a916214bc9eb2e5af0b6a9beb0", size = 942542, upload-time = "2025-11-05T20:41:41.838Z" }, - { url = "https://files.pythonhosted.org/packages/19/62/7a3cf601d5a45137a7e2b89d10c05b5b86499190c4b7ca5c3c47d79ee519/rignore-0.7.6-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8fc5a531ef02131e44359419a366bfac57f773ea58f5278c2cdd915f7d10ea94", size = 958739, upload-time = "2025-11-05T20:42:12.463Z" }, - { url = "https://files.pythonhosted.org/packages/5f/1f/4261f6a0d7caf2058a5cde2f5045f565ab91aa7badc972b57d19ce58b14e/rignore-0.7.6-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b7a1f77d9c4cd7e76229e252614d963442686bfe12c787a49f4fe481df49e7a9", size = 984138, upload-time = "2025-11-05T20:41:56.775Z" }, - { url = "https://files.pythonhosted.org/packages/2b/bf/628dfe19c75e8ce1f45f7c248f5148b17dfa89a817f8e3552ab74c3ae812/rignore-0.7.6-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ead81f728682ba72b5b1c3d5846b011d3e0174da978de87c61645f2ed36659a7", size = 1079299, upload-time = "2025-11-05T21:40:16.639Z" }, - { url = "https://files.pythonhosted.org/packages/af/a5/be29c50f5c0c25c637ed32db8758fdf5b901a99e08b608971cda8afb293b/rignore-0.7.6-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:12ffd50f520c22ffdabed8cd8bfb567d9ac165b2b854d3e679f4bcaef11a9441", size = 1139618, upload-time = "2025-11-05T21:40:34.507Z" }, - { url = "https://files.pythonhosted.org/packages/2a/40/3c46cd7ce4fa05c20b525fd60f599165e820af66e66f2c371cd50644558f/rignore-0.7.6-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:e5a16890fbe3c894f8ca34b0fcacc2c200398d4d46ae654e03bc9b3dbf2a0a72", size = 1117626, upload-time = "2025-11-05T21:40:51.494Z" }, - { url = "https://files.pythonhosted.org/packages/8c/b9/aea926f263b8a29a23c75c2e0d8447965eb1879d3feb53cfcf84db67ed58/rignore-0.7.6-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:3abab3bf99e8a77488ef6c7c9a799fac22224c28fe9f25cc21aa7cc2b72bfc0b", size = 1128144, upload-time = "2025-11-05T21:41:09.169Z" }, - { url = "https://files.pythonhosted.org/packages/a4/f6/0d6242f8d0df7f2ecbe91679fefc1f75e7cd2072cb4f497abaab3f0f8523/rignore-0.7.6-cp314-cp314-win32.whl", hash = "sha256:eeef421c1782953c4375aa32f06ecae470c1285c6381eee2a30d2e02a5633001", size = 646385, upload-time = "2025-11-05T21:41:55.105Z" }, - { url = "https://files.pythonhosted.org/packages/d5/38/c0dcd7b10064f084343d6af26fe9414e46e9619c5f3224b5272e8e5d9956/rignore-0.7.6-cp314-cp314-win_amd64.whl", hash = "sha256:6aeed503b3b3d5af939b21d72a82521701a4bd3b89cd761da1e7dc78621af304", size = 725738, upload-time = "2025-11-05T21:41:39.736Z" }, - { url = "https://files.pythonhosted.org/packages/d9/7a/290f868296c1ece914d565757ab363b04730a728b544beb567ceb3b2d96f/rignore-0.7.6-cp314-cp314-win_arm64.whl", hash = "sha256:104f215b60b3c984c386c3e747d6ab4376d5656478694e22c7bd2f788ddd8304", size = 656008, upload-time = "2025-11-05T21:41:29.028Z" }, - { url = "https://files.pythonhosted.org/packages/ca/d2/3c74e3cd81fe8ea08a8dcd2d755c09ac2e8ad8fe409508904557b58383d3/rignore-0.7.6-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:bb24a5b947656dd94cb9e41c4bc8b23cec0c435b58be0d74a874f63c259549e8", size = 882835, upload-time = "2025-11-05T20:42:45.443Z" }, - { url = "https://files.pythonhosted.org/packages/77/61/a772a34b6b63154877433ac2d048364815b24c2dd308f76b212c408101a2/rignore-0.7.6-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5b1e33c9501cefe24b70a1eafd9821acfd0ebf0b35c3a379430a14df089993e3", size = 820301, upload-time = "2025-11-05T20:42:29.226Z" }, - { url = "https://files.pythonhosted.org/packages/71/30/054880b09c0b1b61d17eeb15279d8bf729c0ba52b36c3ada52fb827cbb3c/rignore-0.7.6-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bec3994665a44454df86deb762061e05cd4b61e3772f5b07d1882a8a0d2748d5", size = 897611, upload-time = "2025-11-05T20:40:56.475Z" }, - { url = "https://files.pythonhosted.org/packages/1e/40/b2d1c169f833d69931bf232600eaa3c7998ba4f9a402e43a822dad2ea9f2/rignore-0.7.6-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:26cba2edfe3cff1dfa72bddf65d316ddebf182f011f2f61538705d6dbaf54986", size = 873875, upload-time = "2025-11-05T20:41:11.561Z" }, - { url = "https://files.pythonhosted.org/packages/55/59/ca5ae93d83a1a60e44b21d87deb48b177a8db1b85e82fc8a9abb24a8986d/rignore-0.7.6-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ffa86694fec604c613696cb91e43892aa22e1fec5f9870e48f111c603e5ec4e9", size = 1167245, upload-time = "2025-11-05T20:41:28.29Z" }, - { url = "https://files.pythonhosted.org/packages/a5/52/cf3dce392ba2af806cba265aad6bcd9c48bb2a6cb5eee448d3319f6e505b/rignore-0.7.6-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48efe2ed95aa8104145004afb15cdfa02bea5cdde8b0344afeb0434f0d989aa2", size = 941750, upload-time = "2025-11-05T20:41:43.111Z" }, - { url = "https://files.pythonhosted.org/packages/ec/be/3f344c6218d779395e785091d05396dfd8b625f6aafbe502746fcd880af2/rignore-0.7.6-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8dcae43eb44b7f2457fef7cc87f103f9a0013017a6f4e62182c565e924948f21", size = 958896, upload-time = "2025-11-05T20:42:13.784Z" }, - { url = "https://files.pythonhosted.org/packages/c9/34/d3fa71938aed7d00dcad87f0f9bcb02ad66c85d6ffc83ba31078ce53646a/rignore-0.7.6-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2cd649a7091c0dad2f11ef65630d30c698d505cbe8660dd395268e7c099cc99f", size = 983992, upload-time = "2025-11-05T20:41:58.022Z" }, - { url = "https://files.pythonhosted.org/packages/24/a4/52a697158e9920705bdbd0748d59fa63e0f3233fb92e9df9a71afbead6ca/rignore-0.7.6-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:42de84b0289d478d30ceb7ae59023f7b0527786a9a5b490830e080f0e4ea5aeb", size = 1078181, upload-time = "2025-11-05T21:40:18.151Z" }, - { url = "https://files.pythonhosted.org/packages/ac/65/aa76dbcdabf3787a6f0fd61b5cc8ed1e88580590556d6c0207960d2384bb/rignore-0.7.6-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:875a617e57b53b4acbc5a91de418233849711c02e29cc1f4f9febb2f928af013", size = 1139232, upload-time = "2025-11-05T21:40:35.966Z" }, - { url = "https://files.pythonhosted.org/packages/08/44/31b31a49b3233c6842acc1c0731aa1e7fb322a7170612acf30327f700b44/rignore-0.7.6-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:8703998902771e96e49968105207719f22926e4431b108450f3f430b4e268b7c", size = 1117349, upload-time = "2025-11-05T21:40:53.013Z" }, - { url = "https://files.pythonhosted.org/packages/e9/ae/1b199a2302c19c658cf74e5ee1427605234e8c91787cfba0015f2ace145b/rignore-0.7.6-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:602ef33f3e1b04c1e9a10a3c03f8bc3cef2d2383dcc250d309be42b49923cabc", size = 1127702, upload-time = "2025-11-05T21:41:10.881Z" }, - { url = "https://files.pythonhosted.org/packages/fc/d3/18210222b37e87e36357f7b300b7d98c6dd62b133771e71ae27acba83a4f/rignore-0.7.6-cp314-cp314t-win32.whl", hash = "sha256:c1d8f117f7da0a4a96a8daef3da75bc090e3792d30b8b12cfadc240c631353f9", size = 647033, upload-time = "2025-11-05T21:42:00.095Z" }, - { url = "https://files.pythonhosted.org/packages/3e/87/033eebfbee3ec7d92b3bb1717d8f68c88e6fc7de54537040f3b3a405726f/rignore-0.7.6-cp314-cp314t-win_amd64.whl", hash = "sha256:ca36e59408bec81de75d307c568c2d0d410fb880b1769be43611472c61e85c96", size = 725647, upload-time = "2025-11-05T21:41:44.449Z" }, - { url = "https://files.pythonhosted.org/packages/79/62/b88e5879512c55b8ee979c666ee6902adc4ed05007226de266410ae27965/rignore-0.7.6-cp314-cp314t-win_arm64.whl", hash = "sha256:b83adabeb3e8cf662cabe1931b83e165b88c526fa6af6b3aa90429686e474896", size = 656035, upload-time = "2025-11-05T21:41:31.13Z" }, -] - -[[package]] -name = "ruff" -version = "0.14.10" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/57/08/52232a877978dd8f9cf2aeddce3e611b40a63287dfca29b6b8da791f5e8d/ruff-0.14.10.tar.gz", hash = "sha256:9a2e830f075d1a42cd28420d7809ace390832a490ed0966fe373ba288e77aaf4", size = 5859763, upload-time = "2025-12-18T19:28:57.98Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/60/01/933704d69f3f05ee16ef11406b78881733c186fe14b6a46b05cfcaf6d3b2/ruff-0.14.10-py3-none-linux_armv6l.whl", hash = "sha256:7a3ce585f2ade3e1f29ec1b92df13e3da262178df8c8bdf876f48fa0e8316c49", size = 13527080, upload-time = "2025-12-18T19:29:25.642Z" }, - { url = "https://files.pythonhosted.org/packages/df/58/a0349197a7dfa603ffb7f5b0470391efa79ddc327c1e29c4851e85b09cc5/ruff-0.14.10-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:674f9be9372907f7257c51f1d4fc902cb7cf014b9980152b802794317941f08f", size = 13797320, upload-time = "2025-12-18T19:29:02.571Z" }, - { url = "https://files.pythonhosted.org/packages/7b/82/36be59f00a6082e38c23536df4e71cdbc6af8d7c707eade97fcad5c98235/ruff-0.14.10-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d85713d522348837ef9df8efca33ccb8bd6fcfc86a2cde3ccb4bc9d28a18003d", size = 12918434, upload-time = "2025-12-18T19:28:51.202Z" }, - { url = "https://files.pythonhosted.org/packages/a6/00/45c62a7f7e34da92a25804f813ebe05c88aa9e0c25e5cb5a7d23dd7450e3/ruff-0.14.10-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6987ebe0501ae4f4308d7d24e2d0fe3d7a98430f5adfd0f1fead050a740a3a77", size = 13371961, upload-time = "2025-12-18T19:29:04.991Z" }, - { url = "https://files.pythonhosted.org/packages/40/31/a5906d60f0405f7e57045a70f2d57084a93ca7425f22e1d66904769d1628/ruff-0.14.10-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:16a01dfb7b9e4eee556fbfd5392806b1b8550c9b4a9f6acd3dbe6812b193c70a", size = 13275629, upload-time = "2025-12-18T19:29:21.381Z" }, - { url = "https://files.pythonhosted.org/packages/3e/60/61c0087df21894cf9d928dc04bcd4fb10e8b2e8dca7b1a276ba2155b2002/ruff-0.14.10-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7165d31a925b7a294465fa81be8c12a0e9b60fb02bf177e79067c867e71f8b1f", size = 14029234, upload-time = "2025-12-18T19:29:00.132Z" }, - { url = "https://files.pythonhosted.org/packages/44/84/77d911bee3b92348b6e5dab5a0c898d87084ea03ac5dc708f46d88407def/ruff-0.14.10-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:c561695675b972effb0c0a45db233f2c816ff3da8dcfbe7dfc7eed625f218935", size = 15449890, upload-time = "2025-12-18T19:28:53.573Z" }, - { url = "https://files.pythonhosted.org/packages/e9/36/480206eaefa24a7ec321582dda580443a8f0671fdbf6b1c80e9c3e93a16a/ruff-0.14.10-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4bb98fcbbc61725968893682fd4df8966a34611239c9fd07a1f6a07e7103d08e", size = 15123172, upload-time = "2025-12-18T19:29:23.453Z" }, - { url = "https://files.pythonhosted.org/packages/5c/38/68e414156015ba80cef5473d57919d27dfb62ec804b96180bafdeaf0e090/ruff-0.14.10-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f24b47993a9d8cb858429e97bdf8544c78029f09b520af615c1d261bf827001d", size = 14460260, upload-time = "2025-12-18T19:29:27.808Z" }, - { url = "https://files.pythonhosted.org/packages/b3/19/9e050c0dca8aba824d67cc0db69fb459c28d8cd3f6855b1405b3f29cc91d/ruff-0.14.10-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59aabd2e2c4fd614d2862e7939c34a532c04f1084476d6833dddef4afab87e9f", size = 14229978, upload-time = "2025-12-18T19:29:11.32Z" }, - { url = "https://files.pythonhosted.org/packages/51/eb/e8dd1dd6e05b9e695aa9dd420f4577debdd0f87a5ff2fedda33c09e9be8c/ruff-0.14.10-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:213db2b2e44be8625002dbea33bb9c60c66ea2c07c084a00d55732689d697a7f", size = 14338036, upload-time = "2025-12-18T19:29:09.184Z" }, - { url = "https://files.pythonhosted.org/packages/6a/12/f3e3a505db7c19303b70af370d137795fcfec136d670d5de5391e295c134/ruff-0.14.10-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:b914c40ab64865a17a9a5b67911d14df72346a634527240039eb3bd650e5979d", size = 13264051, upload-time = "2025-12-18T19:29:13.431Z" }, - { url = "https://files.pythonhosted.org/packages/08/64/8c3a47eaccfef8ac20e0484e68e0772013eb85802f8a9f7603ca751eb166/ruff-0.14.10-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:1484983559f026788e3a5c07c81ef7d1e97c1c78ed03041a18f75df104c45405", size = 13283998, upload-time = "2025-12-18T19:29:06.994Z" }, - { url = "https://files.pythonhosted.org/packages/12/84/534a5506f4074e5cc0529e5cd96cfc01bb480e460c7edf5af70d2bcae55e/ruff-0.14.10-py3-none-musllinux_1_2_i686.whl", hash = "sha256:c70427132db492d25f982fffc8d6c7535cc2fd2c83fc8888f05caaa248521e60", size = 13601891, upload-time = "2025-12-18T19:28:55.811Z" }, - { url = "https://files.pythonhosted.org/packages/0d/1e/14c916087d8598917dbad9b2921d340f7884824ad6e9c55de948a93b106d/ruff-0.14.10-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5bcf45b681e9f1ee6445d317ce1fa9d6cba9a6049542d1c3d5b5958986be8830", size = 14336660, upload-time = "2025-12-18T19:29:16.531Z" }, - { url = "https://files.pythonhosted.org/packages/f2/1c/d7b67ab43f30013b47c12b42d1acd354c195351a3f7a1d67f59e54227ede/ruff-0.14.10-py3-none-win32.whl", hash = "sha256:104c49fc7ab73f3f3a758039adea978869a918f31b73280db175b43a2d9b51d6", size = 13196187, upload-time = "2025-12-18T19:29:19.006Z" }, - { url = "https://files.pythonhosted.org/packages/fb/9c/896c862e13886fae2af961bef3e6312db9ebc6adc2b156fe95e615dee8c1/ruff-0.14.10-py3-none-win_amd64.whl", hash = "sha256:466297bd73638c6bdf06485683e812db1c00c7ac96d4ddd0294a338c62fdc154", size = 14661283, upload-time = "2025-12-18T19:29:30.16Z" }, - { url = "https://files.pythonhosted.org/packages/74/31/b0e29d572670dca3674eeee78e418f20bdf97fa8aa9ea71380885e175ca0/ruff-0.14.10-py3-none-win_arm64.whl", hash = "sha256:e51d046cf6dda98a4633b8a8a771451107413b0f07183b2bef03f075599e44e6", size = 13729839, upload-time = "2025-12-18T19:28:48.636Z" }, -] - -[[package]] -name = "scalar-fastapi" -version = "1.5.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b2/1a/4897819ef5682f40cce1f9b552a1e002d394bf7e12e5d6fe62f843ffef51/scalar_fastapi-1.5.0.tar.gz", hash = "sha256:5ae887fcc0db63305dc41dc39d61f7be183256085872aa33b294e0d48e29901e", size = 7447, upload-time = "2025-12-04T19:44:12.04Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7a/cc/c0712ac83a31ae96785d9916d7be54595914aa93375ea5df3ba3eadab8af/scalar_fastapi-1.5.0-py3-none-any.whl", hash = "sha256:8e712599ccdfbb614bff5583fdbee1bef03e5fac1e06520287337ff232cb667a", size = 6828, upload-time = "2025-12-04T19:44:11.242Z" }, -] - -[[package]] -name = "sentry-sdk" -version = "2.48.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "certifi" }, - { name = "urllib3" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/40/f0/0e9dc590513d5e742d7799e2038df3a05167cba084c6ca4f3cdd75b55164/sentry_sdk-2.48.0.tar.gz", hash = "sha256:5213190977ff7fdff8a58b722fb807f8d5524a80488626ebeda1b5676c0c1473", size = 384828, upload-time = "2025-12-16T14:55:41.722Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/4d/19/8d77f9992e5cbfcaa9133c3bf63b4fbbb051248802e1e803fed5c552fbb2/sentry_sdk-2.48.0-py2.py3-none-any.whl", hash = "sha256:6b12ac256769d41825d9b7518444e57fa35b5642df4c7c5e322af4d2c8721172", size = 414555, upload-time = "2025-12-16T14:55:40.152Z" }, -] - -[[package]] -name = "shellingham" -version = "1.5.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310, upload-time = "2023-10-24T04:13:40.426Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, -] - -[[package]] -name = "sniffio" -version = "1.3.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372, upload-time = "2024-02-25T23:20:04.057Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" }, -] - -[[package]] -name = "sqladmin" -version = "0.22.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "jinja2" }, - { name = "python-multipart" }, - { name = "sqlalchemy" }, - { name = "starlette" }, - { name = "wtforms" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/2c/ac/526bb3ff2dd94fbf8442bccb49ef40aa360045add19d4fbffcb43995e67a/sqladmin-0.22.0.tar.gz", hash = "sha256:4ea904d97e4d030edb68fb0681330b4d963f422442a64bee487fdc46119b3729", size = 1429937, upload-time = "2025-11-24T12:52:59.285Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f2/b4/ab78c7d7b13bd3f90d6d8a106c5ad12bf7a738f89eb0241b24ad8efe5d1e/sqladmin-0.22.0-py3-none-any.whl", hash = "sha256:f2fb11165a70601a97f71956104b47da2c432db49b0d7966dc65e9e6343887d3", size = 1445514, upload-time = "2025-11-24T12:53:00.511Z" }, -] - -[package.optional-dependencies] -full = [ - { name = "itsdangerous" }, -] - -[[package]] -name = "sqlalchemy" -version = "2.0.45" -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/be/f9/5e4491e5ccf42f5d9cfc663741d261b3e6e1683ae7812114e7636409fcc6/sqlalchemy-2.0.45.tar.gz", hash = "sha256:1632a4bda8d2d25703fdad6363058d882541bdaaee0e5e3ddfa0cd3229efce88", size = 9869912, upload-time = "2025-12-09T21:05:16.737Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/6a/c8/7cc5221b47a54edc72a0140a1efa56e0a2730eefa4058d7ed0b4c4357ff8/sqlalchemy-2.0.45-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fe187fc31a54d7fd90352f34e8c008cf3ad5d064d08fedd3de2e8df83eb4a1cf", size = 3277082, upload-time = "2025-12-09T22:11:06.167Z" }, - { url = "https://files.pythonhosted.org/packages/0e/50/80a8d080ac7d3d321e5e5d420c9a522b0aa770ec7013ea91f9a8b7d36e4a/sqlalchemy-2.0.45-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:672c45cae53ba88e0dad74b9027dddd09ef6f441e927786b05bec75d949fbb2e", size = 3293131, upload-time = "2025-12-09T22:13:52.626Z" }, - { url = "https://files.pythonhosted.org/packages/da/4c/13dab31266fc9904f7609a5dc308a2432a066141d65b857760c3bef97e69/sqlalchemy-2.0.45-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:470daea2c1ce73910f08caf10575676a37159a6d16c4da33d0033546bddebc9b", size = 3225389, upload-time = "2025-12-09T22:11:08.093Z" }, - { url = "https://files.pythonhosted.org/packages/74/04/891b5c2e9f83589de202e7abaf24cd4e4fa59e1837d64d528829ad6cc107/sqlalchemy-2.0.45-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9c6378449e0940476577047150fd09e242529b761dc887c9808a9a937fe990c8", size = 3266054, upload-time = "2025-12-09T22:13:54.262Z" }, - { url = "https://files.pythonhosted.org/packages/f1/24/fc59e7f71b0948cdd4cff7a286210e86b0443ef1d18a23b0d83b87e4b1f7/sqlalchemy-2.0.45-cp313-cp313-win32.whl", hash = "sha256:4b6bec67ca45bc166c8729910bd2a87f1c0407ee955df110d78948f5b5827e8a", size = 2110299, upload-time = "2025-12-09T21:39:33.486Z" }, - { url = "https://files.pythonhosted.org/packages/c0/c5/d17113020b2d43073412aeca09b60d2009442420372123b8d49cc253f8b8/sqlalchemy-2.0.45-cp313-cp313-win_amd64.whl", hash = "sha256:afbf47dc4de31fa38fd491f3705cac5307d21d4bb828a4f020ee59af412744ee", size = 2136264, upload-time = "2025-12-09T21:39:36.801Z" }, - { url = "https://files.pythonhosted.org/packages/3d/8d/bb40a5d10e7a5f2195f235c0b2f2c79b0bf6e8f00c0c223130a4fbd2db09/sqlalchemy-2.0.45-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:83d7009f40ce619d483d26ac1b757dfe3167b39921379a8bd1b596cf02dab4a6", size = 3521998, upload-time = "2025-12-09T22:13:28.622Z" }, - { url = "https://files.pythonhosted.org/packages/75/a5/346128b0464886f036c039ea287b7332a410aa2d3fb0bb5d404cb8861635/sqlalchemy-2.0.45-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:d8a2ca754e5415cde2b656c27900b19d50ba076aa05ce66e2207623d3fe41f5a", size = 3473434, upload-time = "2025-12-09T22:13:30.188Z" }, - { url = "https://files.pythonhosted.org/packages/cc/64/4e1913772646b060b025d3fc52ce91a58967fe58957df32b455de5a12b4f/sqlalchemy-2.0.45-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7f46ec744e7f51275582e6a24326e10c49fbdd3fc99103e01376841213028774", size = 3272404, upload-time = "2025-12-09T22:11:09.662Z" }, - { url = "https://files.pythonhosted.org/packages/b3/27/caf606ee924282fe4747ee4fd454b335a72a6e018f97eab5ff7f28199e16/sqlalchemy-2.0.45-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:883c600c345123c033c2f6caca18def08f1f7f4c3ebeb591a63b6fceffc95cce", size = 3277057, upload-time = "2025-12-09T22:13:56.213Z" }, - { url = "https://files.pythonhosted.org/packages/85/d0/3d64218c9724e91f3d1574d12eb7ff8f19f937643815d8daf792046d88ab/sqlalchemy-2.0.45-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2c0b74aa79e2deade948fe8593654c8ef4228c44ba862bb7c9585c8e0db90f33", size = 3222279, upload-time = "2025-12-09T22:11:11.1Z" }, - { url = "https://files.pythonhosted.org/packages/24/10/dd7688a81c5bc7690c2a3764d55a238c524cd1a5a19487928844cb247695/sqlalchemy-2.0.45-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:8a420169cef179d4c9064365f42d779f1e5895ad26ca0c8b4c0233920973db74", size = 3244508, upload-time = "2025-12-09T22:13:57.932Z" }, - { url = "https://files.pythonhosted.org/packages/aa/41/db75756ca49f777e029968d9c9fee338c7907c563267740c6d310a8e3f60/sqlalchemy-2.0.45-cp314-cp314-win32.whl", hash = "sha256:e50dcb81a5dfe4b7b4a4aa8f338116d127cb209559124f3694c70d6cd072b68f", size = 2113204, upload-time = "2025-12-09T21:39:38.365Z" }, - { url = "https://files.pythonhosted.org/packages/89/a2/0e1590e9adb292b1d576dbcf67ff7df8cf55e56e78d2c927686d01080f4b/sqlalchemy-2.0.45-cp314-cp314-win_amd64.whl", hash = "sha256:4748601c8ea959e37e03d13dcda4a44837afcd1b21338e637f7c935b8da06177", size = 2138785, upload-time = "2025-12-09T21:39:39.503Z" }, - { url = "https://files.pythonhosted.org/packages/42/39/f05f0ed54d451156bbed0e23eb0516bcad7cbb9f18b3bf219c786371b3f0/sqlalchemy-2.0.45-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cd337d3526ec5298f67d6a30bbbe4ed7e5e68862f0bf6dd21d289f8d37b7d60b", size = 3522029, upload-time = "2025-12-09T22:13:32.09Z" }, - { url = "https://files.pythonhosted.org/packages/54/0f/d15398b98b65c2bce288d5ee3f7d0a81f77ab89d9456994d5c7cc8b2a9db/sqlalchemy-2.0.45-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9a62b446b7d86a3909abbcd1cd3cc550a832f99c2bc37c5b22e1925438b9367b", size = 3475142, upload-time = "2025-12-09T22:13:33.739Z" }, - { url = "https://files.pythonhosted.org/packages/bf/e1/3ccb13c643399d22289c6a9786c1a91e3dcbb68bce4beb44926ac2c557bf/sqlalchemy-2.0.45-py3-none-any.whl", hash = "sha256:5225a288e4c8cc2308dbdd874edad6e7d0fd38eac1e9e5f23503425c8eee20d0", size = 1936672, upload-time = "2025-12-09T21:54:52.608Z" }, -] - -[package.optional-dependencies] -asyncio = [ - { name = "greenlet" }, -] - -[[package]] -name = "starlette" -version = "0.50.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "anyio" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/ba/b8/73a0e6a6e079a9d9cfa64113d771e421640b6f679a52eeb9b32f72d871a1/starlette-0.50.0.tar.gz", hash = "sha256:a2a17b22203254bcbc2e1f926d2d55f3f9497f769416b3190768befe598fa3ca", size = 2646985, upload-time = "2025-11-01T15:25:27.516Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d9/52/1064f510b141bd54025f9b55105e26d1fa970b9be67ad766380a3c9b74b0/starlette-0.50.0-py3-none-any.whl", hash = "sha256:9e5391843ec9b6e472eed1365a78c8098cfceb7a74bfd4d6b1c0c0095efb3bca", size = 74033, upload-time = "2025-11-01T15:25:25.461Z" }, -] - -[[package]] -name = "tqdm" -version = "4.67.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/a8/4b/29b4ef32e036bb34e4ab51796dd745cdba7ed47ad142a9f4a1eb8e0c744d/tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2", size = 169737, upload-time = "2024-11-24T20:12:22.481Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2", size = 78540, upload-time = "2024-11-24T20:12:19.698Z" }, -] - -[[package]] -name = "typer" -version = "0.20.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "click" }, - { name = "rich" }, - { name = "shellingham" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/8f/28/7c85c8032b91dbe79725b6f17d2fffc595dff06a35c7a30a37bef73a1ab4/typer-0.20.0.tar.gz", hash = "sha256:1aaf6494031793e4876fb0bacfa6a912b551cf43c1e63c800df8b1a866720c37", size = 106492, upload-time = "2025-10-20T17:03:49.445Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/78/64/7713ffe4b5983314e9d436a90d5bd4f63b6054e2aca783a3cfc44cb95bbf/typer-0.20.0-py3-none-any.whl", hash = "sha256:5b463df6793ec1dca6213a3cf4c0f03bc6e322ac5e16e13ddd622a889489784a", size = 47028, upload-time = "2025-10-20T17:03:47.617Z" }, -] - -[[package]] -name = "typing-extensions" -version = "4.15.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, -] - -[[package]] -name = "typing-inspection" -version = "0.4.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload-time = "2025-10-01T02:14:41.687Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" }, -] - -[[package]] -name = "urllib3" -version = "2.6.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1e/24/a2a2ed9addd907787d7aa0355ba36a6cadf1768b934c652ea78acbd59dcd/urllib3-2.6.2.tar.gz", hash = "sha256:016f9c98bb7e98085cb2b4b17b87d2c702975664e4f060c6532e64d1c1a5e797", size = 432930, upload-time = "2025-12-11T15:56:40.252Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/6d/b9/4095b668ea3678bf6a0af005527f39de12fb026516fb3df17495a733b7f8/urllib3-2.6.2-py3-none-any.whl", hash = "sha256:ec21cddfe7724fc7cb4ba4bea7aa8e2ef36f607a4bab81aa6ce42a13dc3f03dd", size = 131182, upload-time = "2025-12-11T15:56:38.584Z" }, -] - -[[package]] -name = "uuid7" -version = "0.1.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5c/19/7472bd526591e2192926247109dbf78692e709d3e56775792fec877a7720/uuid7-0.1.0.tar.gz", hash = "sha256:8c57aa32ee7456d3cc68c95c4530bc571646defac01895cfc73545449894a63c", size = 14052, upload-time = "2021-12-29T01:38:21.897Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b5/77/8852f89a91453956582a85024d80ad96f30a41fed4c2b3dce0c9f12ecc7e/uuid7-0.1.0-py2.py3-none-any.whl", hash = "sha256:5e259bb63c8cb4aded5927ff41b444a80d0c7124e8a0ced7cf44efa1f5cccf61", size = 7477, upload-time = "2021-12-29T01:38:20.418Z" }, -] - -[[package]] -name = "uvicorn" -version = "0.38.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "click" }, - { name = "h11" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/cb/ce/f06b84e2697fef4688ca63bdb2fdf113ca0a3be33f94488f2cadb690b0cf/uvicorn-0.38.0.tar.gz", hash = "sha256:fd97093bdd120a2609fc0d3afe931d4d4ad688b6e75f0f929fde1bc36fe0e91d", size = 80605, upload-time = "2025-10-18T13:46:44.63Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ee/d9/d88e73ca598f4f6ff671fb5fde8a32925c2e08a637303a1d12883c7305fa/uvicorn-0.38.0-py3-none-any.whl", hash = "sha256:48c0afd214ceb59340075b4a052ea1ee91c16fbc2a9b1469cca0e54566977b02", size = 68109, upload-time = "2025-10-18T13:46:42.958Z" }, -] - -[package.optional-dependencies] -standard = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, - { name = "httptools" }, - { name = "python-dotenv" }, - { name = "pyyaml" }, - { name = "uvloop", marker = "platform_python_implementation != 'PyPy' and sys_platform != 'cygwin' and sys_platform != 'win32'" }, - { name = "watchfiles" }, - { name = "websockets" }, -] - -[[package]] -name = "uvloop" -version = "0.22.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/06/f0/18d39dbd1971d6d62c4629cc7fa67f74821b0dc1f5a77af43719de7936a7/uvloop-0.22.1.tar.gz", hash = "sha256:6c84bae345b9147082b17371e3dd5d42775bddce91f885499017f4607fdaf39f", size = 2443250, upload-time = "2025-10-16T22:17:19.342Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/89/8c/182a2a593195bfd39842ea68ebc084e20c850806117213f5a299dfc513d9/uvloop-0.22.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:561577354eb94200d75aca23fbde86ee11be36b00e52a4eaf8f50fb0c86b7705", size = 1358611, upload-time = "2025-10-16T22:16:36.833Z" }, - { url = "https://files.pythonhosted.org/packages/d2/14/e301ee96a6dc95224b6f1162cd3312f6d1217be3907b79173b06785f2fe7/uvloop-0.22.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1cdf5192ab3e674ca26da2eada35b288d2fa49fdd0f357a19f0e7c4e7d5077c8", size = 751811, upload-time = "2025-10-16T22:16:38.275Z" }, - { url = "https://files.pythonhosted.org/packages/b7/02/654426ce265ac19e2980bfd9ea6590ca96a56f10c76e63801a2df01c0486/uvloop-0.22.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6e2ea3d6190a2968f4a14a23019d3b16870dd2190cd69c8180f7c632d21de68d", size = 4288562, upload-time = "2025-10-16T22:16:39.375Z" }, - { url = "https://files.pythonhosted.org/packages/15/c0/0be24758891ef825f2065cd5db8741aaddabe3e248ee6acc5e8a80f04005/uvloop-0.22.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0530a5fbad9c9e4ee3f2b33b148c6a64d47bbad8000ea63704fa8260f4cf728e", size = 4366890, upload-time = "2025-10-16T22:16:40.547Z" }, - { url = "https://files.pythonhosted.org/packages/d2/53/8369e5219a5855869bcee5f4d317f6da0e2c669aecf0ef7d371e3d084449/uvloop-0.22.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bc5ef13bbc10b5335792360623cc378d52d7e62c2de64660616478c32cd0598e", size = 4119472, upload-time = "2025-10-16T22:16:41.694Z" }, - { url = "https://files.pythonhosted.org/packages/f8/ba/d69adbe699b768f6b29a5eec7b47dd610bd17a69de51b251126a801369ea/uvloop-0.22.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1f38ec5e3f18c8a10ded09742f7fb8de0108796eb673f30ce7762ce1b8550cad", size = 4239051, upload-time = "2025-10-16T22:16:43.224Z" }, - { url = "https://files.pythonhosted.org/packages/90/cd/b62bdeaa429758aee8de8b00ac0dd26593a9de93d302bff3d21439e9791d/uvloop-0.22.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3879b88423ec7e97cd4eba2a443aa26ed4e59b45e6b76aabf13fe2f27023a142", size = 1362067, upload-time = "2025-10-16T22:16:44.503Z" }, - { url = "https://files.pythonhosted.org/packages/0d/f8/a132124dfda0777e489ca86732e85e69afcd1ff7686647000050ba670689/uvloop-0.22.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:4baa86acedf1d62115c1dc6ad1e17134476688f08c6efd8a2ab076e815665c74", size = 752423, upload-time = "2025-10-16T22:16:45.968Z" }, - { url = "https://files.pythonhosted.org/packages/a3/94/94af78c156f88da4b3a733773ad5ba0b164393e357cc4bd0ab2e2677a7d6/uvloop-0.22.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:297c27d8003520596236bdb2335e6b3f649480bd09e00d1e3a99144b691d2a35", size = 4272437, upload-time = "2025-10-16T22:16:47.451Z" }, - { url = "https://files.pythonhosted.org/packages/b5/35/60249e9fd07b32c665192cec7af29e06c7cd96fa1d08b84f012a56a0b38e/uvloop-0.22.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c1955d5a1dd43198244d47664a5858082a3239766a839b2102a269aaff7a4e25", size = 4292101, upload-time = "2025-10-16T22:16:49.318Z" }, - { url = "https://files.pythonhosted.org/packages/02/62/67d382dfcb25d0a98ce73c11ed1a6fba5037a1a1d533dcbb7cab033a2636/uvloop-0.22.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b31dc2fccbd42adc73bc4e7cdbae4fc5086cf378979e53ca5d0301838c5682c6", size = 4114158, upload-time = "2025-10-16T22:16:50.517Z" }, - { url = "https://files.pythonhosted.org/packages/f0/7a/f1171b4a882a5d13c8b7576f348acfe6074d72eaf52cccef752f748d4a9f/uvloop-0.22.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:93f617675b2d03af4e72a5333ef89450dfaa5321303ede6e67ba9c9d26878079", size = 4177360, upload-time = "2025-10-16T22:16:52.646Z" }, - { url = "https://files.pythonhosted.org/packages/79/7b/b01414f31546caf0919da80ad57cbfe24c56b151d12af68cee1b04922ca8/uvloop-0.22.1-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:37554f70528f60cad66945b885eb01f1bb514f132d92b6eeed1c90fd54ed6289", size = 1454790, upload-time = "2025-10-16T22:16:54.355Z" }, - { url = "https://files.pythonhosted.org/packages/d4/31/0bb232318dd838cad3fa8fb0c68c8b40e1145b32025581975e18b11fab40/uvloop-0.22.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:b76324e2dc033a0b2f435f33eb88ff9913c156ef78e153fb210e03c13da746b3", size = 796783, upload-time = "2025-10-16T22:16:55.906Z" }, - { url = "https://files.pythonhosted.org/packages/42/38/c9b09f3271a7a723a5de69f8e237ab8e7803183131bc57c890db0b6bb872/uvloop-0.22.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:badb4d8e58ee08dad957002027830d5c3b06aea446a6a3744483c2b3b745345c", size = 4647548, upload-time = "2025-10-16T22:16:57.008Z" }, - { url = "https://files.pythonhosted.org/packages/c1/37/945b4ca0ac27e3dc4952642d4c900edd030b3da6c9634875af6e13ae80e5/uvloop-0.22.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b91328c72635f6f9e0282e4a57da7470c7350ab1c9f48546c0f2866205349d21", size = 4467065, upload-time = "2025-10-16T22:16:58.206Z" }, - { url = "https://files.pythonhosted.org/packages/97/cc/48d232f33d60e2e2e0b42f4e73455b146b76ebe216487e862700457fbf3c/uvloop-0.22.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:daf620c2995d193449393d6c62131b3fbd40a63bf7b307a1527856ace637fe88", size = 4328384, upload-time = "2025-10-16T22:16:59.36Z" }, - { url = "https://files.pythonhosted.org/packages/e4/16/c1fd27e9549f3c4baf1dc9c20c456cd2f822dbf8de9f463824b0c0357e06/uvloop-0.22.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6cde23eeda1a25c75b2e07d39970f3374105d5eafbaab2a4482be82f272d5a5e", size = 4296730, upload-time = "2025-10-16T22:17:00.744Z" }, -] - -[[package]] -name = "watchfiles" -version = "1.1.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "anyio" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/c2/c9/8869df9b2a2d6c59d79220a4db37679e74f807c559ffe5265e08b227a210/watchfiles-1.1.1.tar.gz", hash = "sha256:a173cb5c16c4f40ab19cecf48a534c409f7ea983ab8fed0741304a1c0a31b3f2", size = 94440, upload-time = "2025-10-14T15:06:21.08Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/bb/f4/f750b29225fe77139f7ae5de89d4949f5a99f934c65a1f1c0b248f26f747/watchfiles-1.1.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:130e4876309e8686a5e37dba7d5e9bc77e6ed908266996ca26572437a5271e18", size = 404321, upload-time = "2025-10-14T15:05:02.063Z" }, - { url = "https://files.pythonhosted.org/packages/2b/f9/f07a295cde762644aa4c4bb0f88921d2d141af45e735b965fb2e87858328/watchfiles-1.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5f3bde70f157f84ece3765b42b4a52c6ac1a50334903c6eaf765362f6ccca88a", size = 391783, upload-time = "2025-10-14T15:05:03.052Z" }, - { url = "https://files.pythonhosted.org/packages/bc/11/fc2502457e0bea39a5c958d86d2cb69e407a4d00b85735ca724bfa6e0d1a/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:14e0b1fe858430fc0251737ef3824c54027bedb8c37c38114488b8e131cf8219", size = 449279, upload-time = "2025-10-14T15:05:04.004Z" }, - { url = "https://files.pythonhosted.org/packages/e3/1f/d66bc15ea0b728df3ed96a539c777acfcad0eb78555ad9efcaa1274688f0/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f27db948078f3823a6bb3b465180db8ebecf26dd5dae6f6180bd87383b6b4428", size = 459405, upload-time = "2025-10-14T15:05:04.942Z" }, - { url = "https://files.pythonhosted.org/packages/be/90/9f4a65c0aec3ccf032703e6db02d89a157462fbb2cf20dd415128251cac0/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:059098c3a429f62fc98e8ec62b982230ef2c8df68c79e826e37b895bc359a9c0", size = 488976, upload-time = "2025-10-14T15:05:05.905Z" }, - { url = "https://files.pythonhosted.org/packages/37/57/ee347af605d867f712be7029bb94c8c071732a4b44792e3176fa3c612d39/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfb5862016acc9b869bb57284e6cb35fdf8e22fe59f7548858e2f971d045f150", size = 595506, upload-time = "2025-10-14T15:05:06.906Z" }, - { url = "https://files.pythonhosted.org/packages/a8/78/cc5ab0b86c122047f75e8fc471c67a04dee395daf847d3e59381996c8707/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:319b27255aacd9923b8a276bb14d21a5f7ff82564c744235fc5eae58d95422ae", size = 474936, upload-time = "2025-10-14T15:05:07.906Z" }, - { url = "https://files.pythonhosted.org/packages/62/da/def65b170a3815af7bd40a3e7010bf6ab53089ef1b75d05dd5385b87cf08/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c755367e51db90e75b19454b680903631d41f9e3607fbd941d296a020c2d752d", size = 456147, upload-time = "2025-10-14T15:05:09.138Z" }, - { url = "https://files.pythonhosted.org/packages/57/99/da6573ba71166e82d288d4df0839128004c67d2778d3b566c138695f5c0b/watchfiles-1.1.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c22c776292a23bfc7237a98f791b9ad3144b02116ff10d820829ce62dff46d0b", size = 630007, upload-time = "2025-10-14T15:05:10.117Z" }, - { url = "https://files.pythonhosted.org/packages/a8/51/7439c4dd39511368849eb1e53279cd3454b4a4dbace80bab88feeb83c6b5/watchfiles-1.1.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:3a476189be23c3686bc2f4321dd501cb329c0a0469e77b7b534ee10129ae6374", size = 622280, upload-time = "2025-10-14T15:05:11.146Z" }, - { url = "https://files.pythonhosted.org/packages/95/9c/8ed97d4bba5db6fdcdb2b298d3898f2dd5c20f6b73aee04eabe56c59677e/watchfiles-1.1.1-cp313-cp313-win32.whl", hash = "sha256:bf0a91bfb5574a2f7fc223cf95eeea79abfefa404bf1ea5e339c0c1560ae99a0", size = 272056, upload-time = "2025-10-14T15:05:12.156Z" }, - { url = "https://files.pythonhosted.org/packages/1f/f3/c14e28429f744a260d8ceae18bf58c1d5fa56b50d006a7a9f80e1882cb0d/watchfiles-1.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:52e06553899e11e8074503c8e716d574adeeb7e68913115c4b3653c53f9bae42", size = 288162, upload-time = "2025-10-14T15:05:13.208Z" }, - { url = "https://files.pythonhosted.org/packages/dc/61/fe0e56c40d5cd29523e398d31153218718c5786b5e636d9ae8ae79453d27/watchfiles-1.1.1-cp313-cp313-win_arm64.whl", hash = "sha256:ac3cc5759570cd02662b15fbcd9d917f7ecd47efe0d6b40474eafd246f91ea18", size = 277909, upload-time = "2025-10-14T15:05:14.49Z" }, - { url = "https://files.pythonhosted.org/packages/79/42/e0a7d749626f1e28c7108a99fb9bf524b501bbbeb9b261ceecde644d5a07/watchfiles-1.1.1-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:563b116874a9a7ce6f96f87cd0b94f7faf92d08d0021e837796f0a14318ef8da", size = 403389, upload-time = "2025-10-14T15:05:15.777Z" }, - { url = "https://files.pythonhosted.org/packages/15/49/08732f90ce0fbbc13913f9f215c689cfc9ced345fb1bcd8829a50007cc8d/watchfiles-1.1.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3ad9fe1dae4ab4212d8c91e80b832425e24f421703b5a42ef2e4a1e215aff051", size = 389964, upload-time = "2025-10-14T15:05:16.85Z" }, - { url = "https://files.pythonhosted.org/packages/27/0d/7c315d4bd5f2538910491a0393c56bf70d333d51bc5b34bee8e68e8cea19/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce70f96a46b894b36eba678f153f052967a0d06d5b5a19b336ab0dbbd029f73e", size = 448114, upload-time = "2025-10-14T15:05:17.876Z" }, - { url = "https://files.pythonhosted.org/packages/c3/24/9e096de47a4d11bc4df41e9d1e61776393eac4cb6eb11b3e23315b78b2cc/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cb467c999c2eff23a6417e58d75e5828716f42ed8289fe6b77a7e5a91036ca70", size = 460264, upload-time = "2025-10-14T15:05:18.962Z" }, - { url = "https://files.pythonhosted.org/packages/cc/0f/e8dea6375f1d3ba5fcb0b3583e2b493e77379834c74fd5a22d66d85d6540/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:836398932192dae4146c8f6f737d74baeac8b70ce14831a239bdb1ca882fc261", size = 487877, upload-time = "2025-10-14T15:05:20.094Z" }, - { url = "https://files.pythonhosted.org/packages/ac/5b/df24cfc6424a12deb41503b64d42fbea6b8cb357ec62ca84a5a3476f654a/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:743185e7372b7bc7c389e1badcc606931a827112fbbd37f14c537320fca08620", size = 595176, upload-time = "2025-10-14T15:05:21.134Z" }, - { url = "https://files.pythonhosted.org/packages/8f/b5/853b6757f7347de4e9b37e8cc3289283fb983cba1ab4d2d7144694871d9c/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:afaeff7696e0ad9f02cbb8f56365ff4686ab205fcf9c4c5b6fdfaaa16549dd04", size = 473577, upload-time = "2025-10-14T15:05:22.306Z" }, - { url = "https://files.pythonhosted.org/packages/e1/f7/0a4467be0a56e80447c8529c9fce5b38eab4f513cb3d9bf82e7392a5696b/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f7eb7da0eb23aa2ba036d4f616d46906013a68caf61b7fdbe42fc8b25132e77", size = 455425, upload-time = "2025-10-14T15:05:23.348Z" }, - { url = "https://files.pythonhosted.org/packages/8e/e0/82583485ea00137ddf69bc84a2db88bd92ab4a6e3c405e5fb878ead8d0e7/watchfiles-1.1.1-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:831a62658609f0e5c64178211c942ace999517f5770fe9436be4c2faeba0c0ef", size = 628826, upload-time = "2025-10-14T15:05:24.398Z" }, - { url = "https://files.pythonhosted.org/packages/28/9a/a785356fccf9fae84c0cc90570f11702ae9571036fb25932f1242c82191c/watchfiles-1.1.1-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:f9a2ae5c91cecc9edd47e041a930490c31c3afb1f5e6d71de3dc671bfaca02bf", size = 622208, upload-time = "2025-10-14T15:05:25.45Z" }, - { url = "https://files.pythonhosted.org/packages/c3/f4/0872229324ef69b2c3edec35e84bd57a1289e7d3fe74588048ed8947a323/watchfiles-1.1.1-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:d1715143123baeeaeadec0528bb7441103979a1d5f6fd0e1f915383fea7ea6d5", size = 404315, upload-time = "2025-10-14T15:05:26.501Z" }, - { url = "https://files.pythonhosted.org/packages/7b/22/16d5331eaed1cb107b873f6ae1b69e9ced582fcf0c59a50cd84f403b1c32/watchfiles-1.1.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:39574d6370c4579d7f5d0ad940ce5b20db0e4117444e39b6d8f99db5676c52fd", size = 390869, upload-time = "2025-10-14T15:05:27.649Z" }, - { url = "https://files.pythonhosted.org/packages/b2/7e/5643bfff5acb6539b18483128fdc0ef2cccc94a5b8fbda130c823e8ed636/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7365b92c2e69ee952902e8f70f3ba6360d0d596d9299d55d7d386df84b6941fb", size = 449919, upload-time = "2025-10-14T15:05:28.701Z" }, - { url = "https://files.pythonhosted.org/packages/51/2e/c410993ba5025a9f9357c376f48976ef0e1b1aefb73b97a5ae01a5972755/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bfff9740c69c0e4ed32416f013f3c45e2ae42ccedd1167ef2d805c000b6c71a5", size = 460845, upload-time = "2025-10-14T15:05:30.064Z" }, - { url = "https://files.pythonhosted.org/packages/8e/a4/2df3b404469122e8680f0fcd06079317e48db58a2da2950fb45020947734/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b27cf2eb1dda37b2089e3907d8ea92922b673c0c427886d4edc6b94d8dfe5db3", size = 489027, upload-time = "2025-10-14T15:05:31.064Z" }, - { url = "https://files.pythonhosted.org/packages/ea/84/4587ba5b1f267167ee715b7f66e6382cca6938e0a4b870adad93e44747e6/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:526e86aced14a65a5b0ec50827c745597c782ff46b571dbfe46192ab9e0b3c33", size = 595615, upload-time = "2025-10-14T15:05:32.074Z" }, - { url = "https://files.pythonhosted.org/packages/6a/0f/c6988c91d06e93cd0bb3d4a808bcf32375ca1904609835c3031799e3ecae/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:04e78dd0b6352db95507fd8cb46f39d185cf8c74e4cf1e4fbad1d3df96faf510", size = 474836, upload-time = "2025-10-14T15:05:33.209Z" }, - { url = "https://files.pythonhosted.org/packages/b4/36/ded8aebea91919485b7bbabbd14f5f359326cb5ec218cd67074d1e426d74/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c85794a4cfa094714fb9c08d4a218375b2b95b8ed1666e8677c349906246c05", size = 455099, upload-time = "2025-10-14T15:05:34.189Z" }, - { url = "https://files.pythonhosted.org/packages/98/e0/8c9bdba88af756a2fce230dd365fab2baf927ba42cd47521ee7498fd5211/watchfiles-1.1.1-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:74d5012b7630714b66be7b7b7a78855ef7ad58e8650c73afc4c076a1f480a8d6", size = 630626, upload-time = "2025-10-14T15:05:35.216Z" }, - { url = "https://files.pythonhosted.org/packages/2a/84/a95db05354bf2d19e438520d92a8ca475e578c647f78f53197f5a2f17aaf/watchfiles-1.1.1-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:8fbe85cb3201c7d380d3d0b90e63d520f15d6afe217165d7f98c9c649654db81", size = 622519, upload-time = "2025-10-14T15:05:36.259Z" }, - { url = "https://files.pythonhosted.org/packages/1d/ce/d8acdc8de545de995c339be67711e474c77d643555a9bb74a9334252bd55/watchfiles-1.1.1-cp314-cp314-win32.whl", hash = "sha256:3fa0b59c92278b5a7800d3ee7733da9d096d4aabcfabb9a928918bd276ef9b9b", size = 272078, upload-time = "2025-10-14T15:05:37.63Z" }, - { url = "https://files.pythonhosted.org/packages/c4/c9/a74487f72d0451524be827e8edec251da0cc1fcf111646a511ae752e1a3d/watchfiles-1.1.1-cp314-cp314-win_amd64.whl", hash = "sha256:c2047d0b6cea13b3316bdbafbfa0c4228ae593d995030fda39089d36e64fc03a", size = 287664, upload-time = "2025-10-14T15:05:38.95Z" }, - { url = "https://files.pythonhosted.org/packages/df/b8/8ac000702cdd496cdce998c6f4ee0ca1f15977bba51bdf07d872ebdfc34c/watchfiles-1.1.1-cp314-cp314-win_arm64.whl", hash = "sha256:842178b126593addc05acf6fce960d28bc5fae7afbaa2c6c1b3a7b9460e5be02", size = 277154, upload-time = "2025-10-14T15:05:39.954Z" }, - { url = "https://files.pythonhosted.org/packages/47/a8/e3af2184707c29f0f14b1963c0aace6529f9d1b8582d5b99f31bbf42f59e/watchfiles-1.1.1-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:88863fbbc1a7312972f1c511f202eb30866370ebb8493aef2812b9ff28156a21", size = 403820, upload-time = "2025-10-14T15:05:40.932Z" }, - { url = "https://files.pythonhosted.org/packages/c0/ec/e47e307c2f4bd75f9f9e8afbe3876679b18e1bcec449beca132a1c5ffb2d/watchfiles-1.1.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:55c7475190662e202c08c6c0f4d9e345a29367438cf8e8037f3155e10a88d5a5", size = 390510, upload-time = "2025-10-14T15:05:41.945Z" }, - { url = "https://files.pythonhosted.org/packages/d5/a0/ad235642118090f66e7b2f18fd5c42082418404a79205cdfca50b6309c13/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f53fa183d53a1d7a8852277c92b967ae99c2d4dcee2bfacff8868e6e30b15f7", size = 448408, upload-time = "2025-10-14T15:05:43.385Z" }, - { url = "https://files.pythonhosted.org/packages/df/85/97fa10fd5ff3332ae17e7e40e20784e419e28521549780869f1413742e9d/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6aae418a8b323732fa89721d86f39ec8f092fc2af67f4217a2b07fd3e93c6101", size = 458968, upload-time = "2025-10-14T15:05:44.404Z" }, - { url = "https://files.pythonhosted.org/packages/47/c2/9059c2e8966ea5ce678166617a7f75ecba6164375f3b288e50a40dc6d489/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f096076119da54a6080e8920cbdaac3dbee667eb91dcc5e5b78840b87415bd44", size = 488096, upload-time = "2025-10-14T15:05:45.398Z" }, - { url = "https://files.pythonhosted.org/packages/94/44/d90a9ec8ac309bc26db808a13e7bfc0e4e78b6fc051078a554e132e80160/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:00485f441d183717038ed2e887a7c868154f216877653121068107b227a2f64c", size = 596040, upload-time = "2025-10-14T15:05:46.502Z" }, - { url = "https://files.pythonhosted.org/packages/95/68/4e3479b20ca305cfc561db3ed207a8a1c745ee32bf24f2026a129d0ddb6e/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a55f3e9e493158d7bfdb60a1165035f1cf7d320914e7b7ea83fe22c6023b58fc", size = 473847, upload-time = "2025-10-14T15:05:47.484Z" }, - { url = "https://files.pythonhosted.org/packages/4f/55/2af26693fd15165c4ff7857e38330e1b61ab8c37d15dc79118cdba115b7a/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c91ed27800188c2ae96d16e3149f199d62f86c7af5f5f4d2c61a3ed8cd3666c", size = 455072, upload-time = "2025-10-14T15:05:48.928Z" }, - { url = "https://files.pythonhosted.org/packages/66/1d/d0d200b10c9311ec25d2273f8aad8c3ef7cc7ea11808022501811208a750/watchfiles-1.1.1-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:311ff15a0bae3714ffb603e6ba6dbfba4065ab60865d15a6ec544133bdb21099", size = 629104, upload-time = "2025-10-14T15:05:49.908Z" }, - { url = "https://files.pythonhosted.org/packages/e3/bd/fa9bb053192491b3867ba07d2343d9f2252e00811567d30ae8d0f78136fe/watchfiles-1.1.1-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:a916a2932da8f8ab582f242c065f5c81bed3462849ca79ee357dd9551b0e9b01", size = 622112, upload-time = "2025-10-14T15:05:50.941Z" }, -] - -[[package]] -name = "websockets" -version = "15.0.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/21/e6/26d09fab466b7ca9c7737474c52be4f76a40301b08362eb2dbc19dcc16c1/websockets-15.0.1.tar.gz", hash = "sha256:82544de02076bafba038ce055ee6412d68da13ab47f0c60cab827346de828dee", size = 177016, upload-time = "2025-03-05T20:03:41.606Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/cb/9f/51f0cf64471a9d2b4d0fc6c534f323b664e7095640c34562f5182e5a7195/websockets-15.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ee443ef070bb3b6ed74514f5efaa37a252af57c90eb33b956d35c8e9c10a1931", size = 175440, upload-time = "2025-03-05T20:02:36.695Z" }, - { url = "https://files.pythonhosted.org/packages/8a/05/aa116ec9943c718905997412c5989f7ed671bc0188ee2ba89520e8765d7b/websockets-15.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5a939de6b7b4e18ca683218320fc67ea886038265fd1ed30173f5ce3f8e85675", size = 173098, upload-time = "2025-03-05T20:02:37.985Z" }, - { url = "https://files.pythonhosted.org/packages/ff/0b/33cef55ff24f2d92924923c99926dcce78e7bd922d649467f0eda8368923/websockets-15.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:746ee8dba912cd6fc889a8147168991d50ed70447bf18bcda7039f7d2e3d9151", size = 173329, upload-time = "2025-03-05T20:02:39.298Z" }, - { url = "https://files.pythonhosted.org/packages/31/1d/063b25dcc01faa8fada1469bdf769de3768b7044eac9d41f734fd7b6ad6d/websockets-15.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:595b6c3969023ecf9041b2936ac3827e4623bfa3ccf007575f04c5a6aa318c22", size = 183111, upload-time = "2025-03-05T20:02:40.595Z" }, - { url = "https://files.pythonhosted.org/packages/93/53/9a87ee494a51bf63e4ec9241c1ccc4f7c2f45fff85d5bde2ff74fcb68b9e/websockets-15.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c714d2fc58b5ca3e285461a4cc0c9a66bd0e24c5da9911e30158286c9b5be7f", size = 182054, upload-time = "2025-03-05T20:02:41.926Z" }, - { url = "https://files.pythonhosted.org/packages/ff/b2/83a6ddf56cdcbad4e3d841fcc55d6ba7d19aeb89c50f24dd7e859ec0805f/websockets-15.0.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f3c1e2ab208db911594ae5b4f79addeb3501604a165019dd221c0bdcabe4db8", size = 182496, upload-time = "2025-03-05T20:02:43.304Z" }, - { url = "https://files.pythonhosted.org/packages/98/41/e7038944ed0abf34c45aa4635ba28136f06052e08fc2168520bb8b25149f/websockets-15.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:229cf1d3ca6c1804400b0a9790dc66528e08a6a1feec0d5040e8b9eb14422375", size = 182829, upload-time = "2025-03-05T20:02:48.812Z" }, - { url = "https://files.pythonhosted.org/packages/e0/17/de15b6158680c7623c6ef0db361da965ab25d813ae54fcfeae2e5b9ef910/websockets-15.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:756c56e867a90fb00177d530dca4b097dd753cde348448a1012ed6c5131f8b7d", size = 182217, upload-time = "2025-03-05T20:02:50.14Z" }, - { url = "https://files.pythonhosted.org/packages/33/2b/1f168cb6041853eef0362fb9554c3824367c5560cbdaad89ac40f8c2edfc/websockets-15.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:558d023b3df0bffe50a04e710bc87742de35060580a293c2a984299ed83bc4e4", size = 182195, upload-time = "2025-03-05T20:02:51.561Z" }, - { url = "https://files.pythonhosted.org/packages/86/eb/20b6cdf273913d0ad05a6a14aed4b9a85591c18a987a3d47f20fa13dcc47/websockets-15.0.1-cp313-cp313-win32.whl", hash = "sha256:ba9e56e8ceeeedb2e080147ba85ffcd5cd0711b89576b83784d8605a7df455fa", size = 176393, upload-time = "2025-03-05T20:02:53.814Z" }, - { url = "https://files.pythonhosted.org/packages/1b/6c/c65773d6cab416a64d191d6ee8a8b1c68a09970ea6909d16965d26bfed1e/websockets-15.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:e09473f095a819042ecb2ab9465aee615bd9c2028e4ef7d933600a8401c79561", size = 176837, upload-time = "2025-03-05T20:02:55.237Z" }, - { url = "https://files.pythonhosted.org/packages/fa/a8/5b41e0da817d64113292ab1f8247140aac61cbf6cfd085d6a0fa77f4984f/websockets-15.0.1-py3-none-any.whl", hash = "sha256:f7a866fbc1e97b5c617ee4116daaa09b722101d4a3c170c787450ba409f9736f", size = 169743, upload-time = "2025-03-05T20:03:39.41Z" }, -] - -[[package]] -name = "wtforms" -version = "3.1.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "markupsafe" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/6a/c7/96d10183c3470f1836846f7b9527d6cb0b6c2226ebca40f36fa29f23de60/wtforms-3.1.2.tar.gz", hash = "sha256:f8d76180d7239c94c6322f7990ae1216dae3659b7aa1cee94b6318bdffb474b9", size = 134705, upload-time = "2024-01-06T07:52:41.075Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/18/19/c3232f35e24dccfad372e9f341c4f3a1166ae7c66e4e1351a9467c921cc1/wtforms-3.1.2-py3-none-any.whl", hash = "sha256:bf831c042829c8cdbad74c27575098d541d039b1faa74c771545ecac916f2c07", size = 145961, upload-time = "2024-01-06T07:52:43.023Z" }, -] - -[[package]] -name = "yarl" -version = "1.22.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "idna" }, - { name = "multidict" }, - { name = "propcache" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/57/63/0c6ebca57330cd313f6102b16dd57ffaf3ec4c83403dcb45dbd15c6f3ea1/yarl-1.22.0.tar.gz", hash = "sha256:bebf8557577d4401ba8bd9ff33906f1376c877aa78d1fe216ad01b4d6745af71", size = 187169, upload-time = "2025-10-06T14:12:55.963Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ea/f3/d67de7260456ee105dc1d162d43a019ecad6b91e2f51809d6cddaa56690e/yarl-1.22.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8dee9c25c74997f6a750cd317b8ca63545169c098faee42c84aa5e506c819b53", size = 139980, upload-time = "2025-10-06T14:10:14.601Z" }, - { url = "https://files.pythonhosted.org/packages/01/88/04d98af0b47e0ef42597b9b28863b9060bb515524da0a65d5f4db160b2d5/yarl-1.22.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:01e73b85a5434f89fc4fe27dcda2aff08ddf35e4d47bbbea3bdcd25321af538a", size = 93424, upload-time = "2025-10-06T14:10:16.115Z" }, - { url = "https://files.pythonhosted.org/packages/18/91/3274b215fd8442a03975ce6bee5fe6aa57a8326b29b9d3d56234a1dca244/yarl-1.22.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:22965c2af250d20c873cdbee8ff958fb809940aeb2e74ba5f20aaf6b7ac8c70c", size = 93821, upload-time = "2025-10-06T14:10:17.993Z" }, - { url = "https://files.pythonhosted.org/packages/61/3a/caf4e25036db0f2da4ca22a353dfeb3c9d3c95d2761ebe9b14df8fc16eb0/yarl-1.22.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b4f15793aa49793ec8d1c708ab7f9eded1aa72edc5174cae703651555ed1b601", size = 373243, upload-time = "2025-10-06T14:10:19.44Z" }, - { url = "https://files.pythonhosted.org/packages/6e/9e/51a77ac7516e8e7803b06e01f74e78649c24ee1021eca3d6a739cb6ea49c/yarl-1.22.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e5542339dcf2747135c5c85f68680353d5cb9ffd741c0f2e8d832d054d41f35a", size = 342361, upload-time = "2025-10-06T14:10:21.124Z" }, - { url = "https://files.pythonhosted.org/packages/d4/f8/33b92454789dde8407f156c00303e9a891f1f51a0330b0fad7c909f87692/yarl-1.22.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5c401e05ad47a75869c3ab3e35137f8468b846770587e70d71e11de797d113df", size = 387036, upload-time = "2025-10-06T14:10:22.902Z" }, - { url = "https://files.pythonhosted.org/packages/d9/9a/c5db84ea024f76838220280f732970aa4ee154015d7f5c1bfb60a267af6f/yarl-1.22.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:243dda95d901c733f5b59214d28b0120893d91777cb8aa043e6ef059d3cddfe2", size = 397671, upload-time = "2025-10-06T14:10:24.523Z" }, - { url = "https://files.pythonhosted.org/packages/11/c9/cd8538dc2e7727095e0c1d867bad1e40c98f37763e6d995c1939f5fdc7b1/yarl-1.22.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bec03d0d388060058f5d291a813f21c011041938a441c593374da6077fe21b1b", size = 377059, upload-time = "2025-10-06T14:10:26.406Z" }, - { url = "https://files.pythonhosted.org/packages/a1/b9/ab437b261702ced75122ed78a876a6dec0a1b0f5e17a4ac7a9a2482d8abe/yarl-1.22.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b0748275abb8c1e1e09301ee3cf90c8a99678a4e92e4373705f2a2570d581273", size = 365356, upload-time = "2025-10-06T14:10:28.461Z" }, - { url = "https://files.pythonhosted.org/packages/b2/9d/8e1ae6d1d008a9567877b08f0ce4077a29974c04c062dabdb923ed98e6fe/yarl-1.22.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:47fdb18187e2a4e18fda2c25c05d8251a9e4a521edaed757fef033e7d8498d9a", size = 361331, upload-time = "2025-10-06T14:10:30.541Z" }, - { url = "https://files.pythonhosted.org/packages/ca/5a/09b7be3905962f145b73beb468cdd53db8aa171cf18c80400a54c5b82846/yarl-1.22.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c7044802eec4524fde550afc28edda0dd5784c4c45f0be151a2d3ba017daca7d", size = 382590, upload-time = "2025-10-06T14:10:33.352Z" }, - { url = "https://files.pythonhosted.org/packages/aa/7f/59ec509abf90eda5048b0bc3e2d7b5099dffdb3e6b127019895ab9d5ef44/yarl-1.22.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:139718f35149ff544caba20fce6e8a2f71f1e39b92c700d8438a0b1d2a631a02", size = 385316, upload-time = "2025-10-06T14:10:35.034Z" }, - { url = "https://files.pythonhosted.org/packages/e5/84/891158426bc8036bfdfd862fabd0e0fa25df4176ec793e447f4b85cf1be4/yarl-1.22.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e1b51bebd221006d3d2f95fbe124b22b247136647ae5dcc8c7acafba66e5ee67", size = 374431, upload-time = "2025-10-06T14:10:37.76Z" }, - { url = "https://files.pythonhosted.org/packages/bb/49/03da1580665baa8bef5e8ed34c6df2c2aca0a2f28bf397ed238cc1bbc6f2/yarl-1.22.0-cp313-cp313-win32.whl", hash = "sha256:d3e32536234a95f513bd374e93d717cf6b2231a791758de6c509e3653f234c95", size = 81555, upload-time = "2025-10-06T14:10:39.649Z" }, - { url = "https://files.pythonhosted.org/packages/9a/ee/450914ae11b419eadd067c6183ae08381cfdfcb9798b90b2b713bbebddda/yarl-1.22.0-cp313-cp313-win_amd64.whl", hash = "sha256:47743b82b76d89a1d20b83e60d5c20314cbd5ba2befc9cda8f28300c4a08ed4d", size = 86965, upload-time = "2025-10-06T14:10:41.313Z" }, - { url = "https://files.pythonhosted.org/packages/98/4d/264a01eae03b6cf629ad69bae94e3b0e5344741e929073678e84bf7a3e3b/yarl-1.22.0-cp313-cp313-win_arm64.whl", hash = "sha256:5d0fcda9608875f7d052eff120c7a5da474a6796fe4d83e152e0e4d42f6d1a9b", size = 81205, upload-time = "2025-10-06T14:10:43.167Z" }, - { url = "https://files.pythonhosted.org/packages/88/fc/6908f062a2f77b5f9f6d69cecb1747260831ff206adcbc5b510aff88df91/yarl-1.22.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:719ae08b6972befcba4310e49edb1161a88cdd331e3a694b84466bd938a6ab10", size = 146209, upload-time = "2025-10-06T14:10:44.643Z" }, - { url = "https://files.pythonhosted.org/packages/65/47/76594ae8eab26210b4867be6f49129861ad33da1f1ebdf7051e98492bf62/yarl-1.22.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:47d8a5c446df1c4db9d21b49619ffdba90e77c89ec6e283f453856c74b50b9e3", size = 95966, upload-time = "2025-10-06T14:10:46.554Z" }, - { url = "https://files.pythonhosted.org/packages/ab/ce/05e9828a49271ba6b5b038b15b3934e996980dd78abdfeb52a04cfb9467e/yarl-1.22.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:cfebc0ac8333520d2d0423cbbe43ae43c8838862ddb898f5ca68565e395516e9", size = 97312, upload-time = "2025-10-06T14:10:48.007Z" }, - { url = "https://files.pythonhosted.org/packages/d1/c5/7dffad5e4f2265b29c9d7ec869c369e4223166e4f9206fc2243ee9eea727/yarl-1.22.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4398557cbf484207df000309235979c79c4356518fd5c99158c7d38203c4da4f", size = 361967, upload-time = "2025-10-06T14:10:49.997Z" }, - { url = "https://files.pythonhosted.org/packages/50/b2/375b933c93a54bff7fc041e1a6ad2c0f6f733ffb0c6e642ce56ee3b39970/yarl-1.22.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2ca6fd72a8cd803be290d42f2dec5cdcd5299eeb93c2d929bf060ad9efaf5de0", size = 323949, upload-time = "2025-10-06T14:10:52.004Z" }, - { url = "https://files.pythonhosted.org/packages/66/50/bfc2a29a1d78644c5a7220ce2f304f38248dc94124a326794e677634b6cf/yarl-1.22.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ca1f59c4e1ab6e72f0a23c13fca5430f889634166be85dbf1013683e49e3278e", size = 361818, upload-time = "2025-10-06T14:10:54.078Z" }, - { url = "https://files.pythonhosted.org/packages/46/96/f3941a46af7d5d0f0498f86d71275696800ddcdd20426298e572b19b91ff/yarl-1.22.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6c5010a52015e7c70f86eb967db0f37f3c8bd503a695a49f8d45700144667708", size = 372626, upload-time = "2025-10-06T14:10:55.767Z" }, - { url = "https://files.pythonhosted.org/packages/c1/42/8b27c83bb875cd89448e42cd627e0fb971fa1675c9ec546393d18826cb50/yarl-1.22.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d7672ecf7557476642c88497c2f8d8542f8e36596e928e9bcba0e42e1e7d71f", size = 341129, upload-time = "2025-10-06T14:10:57.985Z" }, - { url = "https://files.pythonhosted.org/packages/49/36/99ca3122201b382a3cf7cc937b95235b0ac944f7e9f2d5331d50821ed352/yarl-1.22.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:3b7c88eeef021579d600e50363e0b6ee4f7f6f728cd3486b9d0f3ee7b946398d", size = 346776, upload-time = "2025-10-06T14:10:59.633Z" }, - { url = "https://files.pythonhosted.org/packages/85/b4/47328bf996acd01a4c16ef9dcd2f59c969f495073616586f78cd5f2efb99/yarl-1.22.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:f4afb5c34f2c6fecdcc182dfcfc6af6cccf1aa923eed4d6a12e9d96904e1a0d8", size = 334879, upload-time = "2025-10-06T14:11:01.454Z" }, - { url = "https://files.pythonhosted.org/packages/c2/ad/b77d7b3f14a4283bffb8e92c6026496f6de49751c2f97d4352242bba3990/yarl-1.22.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:59c189e3e99a59cf8d83cbb31d4db02d66cda5a1a4374e8a012b51255341abf5", size = 350996, upload-time = "2025-10-06T14:11:03.452Z" }, - { url = "https://files.pythonhosted.org/packages/81/c8/06e1d69295792ba54d556f06686cbd6a7ce39c22307100e3fb4a2c0b0a1d/yarl-1.22.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:5a3bf7f62a289fa90f1990422dc8dff5a458469ea71d1624585ec3a4c8d6960f", size = 356047, upload-time = "2025-10-06T14:11:05.115Z" }, - { url = "https://files.pythonhosted.org/packages/4b/b8/4c0e9e9f597074b208d18cef227d83aac36184bfbc6eab204ea55783dbc5/yarl-1.22.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:de6b9a04c606978fdfe72666fa216ffcf2d1a9f6a381058d4378f8d7b1e5de62", size = 342947, upload-time = "2025-10-06T14:11:08.137Z" }, - { url = "https://files.pythonhosted.org/packages/e0/e5/11f140a58bf4c6ad7aca69a892bff0ee638c31bea4206748fc0df4ebcb3a/yarl-1.22.0-cp313-cp313t-win32.whl", hash = "sha256:1834bb90991cc2999f10f97f5f01317f99b143284766d197e43cd5b45eb18d03", size = 86943, upload-time = "2025-10-06T14:11:10.284Z" }, - { url = "https://files.pythonhosted.org/packages/31/74/8b74bae38ed7fe6793d0c15a0c8207bbb819cf287788459e5ed230996cdd/yarl-1.22.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ff86011bd159a9d2dfc89c34cfd8aff12875980e3bd6a39ff097887520e60249", size = 93715, upload-time = "2025-10-06T14:11:11.739Z" }, - { url = "https://files.pythonhosted.org/packages/69/66/991858aa4b5892d57aef7ee1ba6b4d01ec3b7eb3060795d34090a3ca3278/yarl-1.22.0-cp313-cp313t-win_arm64.whl", hash = "sha256:7861058d0582b847bc4e3a4a4c46828a410bca738673f35a29ba3ca5db0b473b", size = 83857, upload-time = "2025-10-06T14:11:13.586Z" }, - { url = "https://files.pythonhosted.org/packages/46/b3/e20ef504049f1a1c54a814b4b9bed96d1ac0e0610c3b4da178f87209db05/yarl-1.22.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:34b36c2c57124530884d89d50ed2c1478697ad7473efd59cfd479945c95650e4", size = 140520, upload-time = "2025-10-06T14:11:15.465Z" }, - { url = "https://files.pythonhosted.org/packages/e4/04/3532d990fdbab02e5ede063676b5c4260e7f3abea2151099c2aa745acc4c/yarl-1.22.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:0dd9a702591ca2e543631c2a017e4a547e38a5c0f29eece37d9097e04a7ac683", size = 93504, upload-time = "2025-10-06T14:11:17.106Z" }, - { url = "https://files.pythonhosted.org/packages/11/63/ff458113c5c2dac9a9719ac68ee7c947cb621432bcf28c9972b1c0e83938/yarl-1.22.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:594fcab1032e2d2cc3321bb2e51271e7cd2b516c7d9aee780ece81b07ff8244b", size = 94282, upload-time = "2025-10-06T14:11:19.064Z" }, - { url = "https://files.pythonhosted.org/packages/a7/bc/315a56aca762d44a6aaaf7ad253f04d996cb6b27bad34410f82d76ea8038/yarl-1.22.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f3d7a87a78d46a2e3d5b72587ac14b4c16952dd0887dbb051451eceac774411e", size = 372080, upload-time = "2025-10-06T14:11:20.996Z" }, - { url = "https://files.pythonhosted.org/packages/3f/3f/08e9b826ec2e099ea6e7c69a61272f4f6da62cb5b1b63590bb80ca2e4a40/yarl-1.22.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:852863707010316c973162e703bddabec35e8757e67fcb8ad58829de1ebc8590", size = 338696, upload-time = "2025-10-06T14:11:22.847Z" }, - { url = "https://files.pythonhosted.org/packages/e3/9f/90360108e3b32bd76789088e99538febfea24a102380ae73827f62073543/yarl-1.22.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:131a085a53bfe839a477c0845acf21efc77457ba2bcf5899618136d64f3303a2", size = 387121, upload-time = "2025-10-06T14:11:24.889Z" }, - { url = "https://files.pythonhosted.org/packages/98/92/ab8d4657bd5b46a38094cfaea498f18bb70ce6b63508fd7e909bd1f93066/yarl-1.22.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:078a8aefd263f4d4f923a9677b942b445a2be970ca24548a8102689a3a8ab8da", size = 394080, upload-time = "2025-10-06T14:11:27.307Z" }, - { url = "https://files.pythonhosted.org/packages/f5/e7/d8c5a7752fef68205296201f8ec2bf718f5c805a7a7e9880576c67600658/yarl-1.22.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bca03b91c323036913993ff5c738d0842fc9c60c4648e5c8d98331526df89784", size = 372661, upload-time = "2025-10-06T14:11:29.387Z" }, - { url = "https://files.pythonhosted.org/packages/b6/2e/f4d26183c8db0bb82d491b072f3127fb8c381a6206a3a56332714b79b751/yarl-1.22.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:68986a61557d37bb90d3051a45b91fa3d5c516d177dfc6dd6f2f436a07ff2b6b", size = 364645, upload-time = "2025-10-06T14:11:31.423Z" }, - { url = "https://files.pythonhosted.org/packages/80/7c/428e5812e6b87cd00ee8e898328a62c95825bf37c7fa87f0b6bb2ad31304/yarl-1.22.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:4792b262d585ff0dff6bcb787f8492e40698443ec982a3568c2096433660c694", size = 355361, upload-time = "2025-10-06T14:11:33.055Z" }, - { url = "https://files.pythonhosted.org/packages/ec/2a/249405fd26776f8b13c067378ef4d7dd49c9098d1b6457cdd152a99e96a9/yarl-1.22.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:ebd4549b108d732dba1d4ace67614b9545b21ece30937a63a65dd34efa19732d", size = 381451, upload-time = "2025-10-06T14:11:35.136Z" }, - { url = "https://files.pythonhosted.org/packages/67/a8/fb6b1adbe98cf1e2dd9fad71003d3a63a1bc22459c6e15f5714eb9323b93/yarl-1.22.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:f87ac53513d22240c7d59203f25cc3beac1e574c6cd681bbfd321987b69f95fd", size = 383814, upload-time = "2025-10-06T14:11:37.094Z" }, - { url = "https://files.pythonhosted.org/packages/d9/f9/3aa2c0e480fb73e872ae2814c43bc1e734740bb0d54e8cb2a95925f98131/yarl-1.22.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:22b029f2881599e2f1b06f8f1db2ee63bd309e2293ba2d566e008ba12778b8da", size = 370799, upload-time = "2025-10-06T14:11:38.83Z" }, - { url = "https://files.pythonhosted.org/packages/50/3c/af9dba3b8b5eeb302f36f16f92791f3ea62e3f47763406abf6d5a4a3333b/yarl-1.22.0-cp314-cp314-win32.whl", hash = "sha256:6a635ea45ba4ea8238463b4f7d0e721bad669f80878b7bfd1f89266e2ae63da2", size = 82990, upload-time = "2025-10-06T14:11:40.624Z" }, - { url = "https://files.pythonhosted.org/packages/ac/30/ac3a0c5bdc1d6efd1b41fa24d4897a4329b3b1e98de9449679dd327af4f0/yarl-1.22.0-cp314-cp314-win_amd64.whl", hash = "sha256:0d6e6885777af0f110b0e5d7e5dda8b704efed3894da26220b7f3d887b839a79", size = 88292, upload-time = "2025-10-06T14:11:42.578Z" }, - { url = "https://files.pythonhosted.org/packages/df/0a/227ab4ff5b998a1b7410abc7b46c9b7a26b0ca9e86c34ba4b8d8bc7c63d5/yarl-1.22.0-cp314-cp314-win_arm64.whl", hash = "sha256:8218f4e98d3c10d683584cb40f0424f4b9fd6e95610232dd75e13743b070ee33", size = 82888, upload-time = "2025-10-06T14:11:44.863Z" }, - { url = "https://files.pythonhosted.org/packages/06/5e/a15eb13db90abd87dfbefb9760c0f3f257ac42a5cac7e75dbc23bed97a9f/yarl-1.22.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:45c2842ff0e0d1b35a6bf1cd6c690939dacb617a70827f715232b2e0494d55d1", size = 146223, upload-time = "2025-10-06T14:11:46.796Z" }, - { url = "https://files.pythonhosted.org/packages/18/82/9665c61910d4d84f41a5bf6837597c89e665fa88aa4941080704645932a9/yarl-1.22.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:d947071e6ebcf2e2bee8fce76e10faca8f7a14808ca36a910263acaacef08eca", size = 95981, upload-time = "2025-10-06T14:11:48.845Z" }, - { url = "https://files.pythonhosted.org/packages/5d/9a/2f65743589809af4d0a6d3aa749343c4b5f4c380cc24a8e94a3c6625a808/yarl-1.22.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:334b8721303e61b00019474cc103bdac3d7b1f65e91f0bfedeec2d56dfe74b53", size = 97303, upload-time = "2025-10-06T14:11:50.897Z" }, - { url = "https://files.pythonhosted.org/packages/b0/ab/5b13d3e157505c43c3b43b5a776cbf7b24a02bc4cccc40314771197e3508/yarl-1.22.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1e7ce67c34138a058fd092f67d07a72b8e31ff0c9236e751957465a24b28910c", size = 361820, upload-time = "2025-10-06T14:11:52.549Z" }, - { url = "https://files.pythonhosted.org/packages/fb/76/242a5ef4677615cf95330cfc1b4610e78184400699bdda0acb897ef5e49a/yarl-1.22.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d77e1b2c6d04711478cb1c4ab90db07f1609ccf06a287d5607fcd90dc9863acf", size = 323203, upload-time = "2025-10-06T14:11:54.225Z" }, - { url = "https://files.pythonhosted.org/packages/8c/96/475509110d3f0153b43d06164cf4195c64d16999e0c7e2d8a099adcd6907/yarl-1.22.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c4647674b6150d2cae088fc07de2738a84b8bcedebef29802cf0b0a82ab6face", size = 363173, upload-time = "2025-10-06T14:11:56.069Z" }, - { url = "https://files.pythonhosted.org/packages/c9/66/59db471aecfbd559a1fd48aedd954435558cd98c7d0da8b03cc6c140a32c/yarl-1.22.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:efb07073be061c8f79d03d04139a80ba33cbd390ca8f0297aae9cce6411e4c6b", size = 373562, upload-time = "2025-10-06T14:11:58.783Z" }, - { url = "https://files.pythonhosted.org/packages/03/1f/c5d94abc91557384719da10ff166b916107c1b45e4d0423a88457071dd88/yarl-1.22.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e51ac5435758ba97ad69617e13233da53908beccc6cfcd6c34bbed8dcbede486", size = 339828, upload-time = "2025-10-06T14:12:00.686Z" }, - { url = "https://files.pythonhosted.org/packages/5f/97/aa6a143d3afba17b6465733681c70cf175af89f76ec8d9286e08437a7454/yarl-1.22.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:33e32a0dd0c8205efa8e83d04fc9f19313772b78522d1bdc7d9aed706bfd6138", size = 347551, upload-time = "2025-10-06T14:12:02.628Z" }, - { url = "https://files.pythonhosted.org/packages/43/3c/45a2b6d80195959239a7b2a8810506d4eea5487dce61c2a3393e7fc3c52e/yarl-1.22.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:bf4a21e58b9cde0e401e683ebd00f6ed30a06d14e93f7c8fd059f8b6e8f87b6a", size = 334512, upload-time = "2025-10-06T14:12:04.871Z" }, - { url = "https://files.pythonhosted.org/packages/86/a0/c2ab48d74599c7c84cb104ebd799c5813de252bea0f360ffc29d270c2caa/yarl-1.22.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:e4b582bab49ac33c8deb97e058cd67c2c50dac0dd134874106d9c774fd272529", size = 352400, upload-time = "2025-10-06T14:12:06.624Z" }, - { url = "https://files.pythonhosted.org/packages/32/75/f8919b2eafc929567d3d8411f72bdb1a2109c01caaab4ebfa5f8ffadc15b/yarl-1.22.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:0b5bcc1a9c4839e7e30b7b30dd47fe5e7e44fb7054ec29b5bb8d526aa1041093", size = 357140, upload-time = "2025-10-06T14:12:08.362Z" }, - { url = "https://files.pythonhosted.org/packages/cf/72/6a85bba382f22cf78add705d8c3731748397d986e197e53ecc7835e76de7/yarl-1.22.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c0232bce2170103ec23c454e54a57008a9a72b5d1c3105dc2496750da8cfa47c", size = 341473, upload-time = "2025-10-06T14:12:10.994Z" }, - { url = "https://files.pythonhosted.org/packages/35/18/55e6011f7c044dc80b98893060773cefcfdbf60dfefb8cb2f58b9bacbd83/yarl-1.22.0-cp314-cp314t-win32.whl", hash = "sha256:8009b3173bcd637be650922ac455946197d858b3630b6d8787aa9e5c4564533e", size = 89056, upload-time = "2025-10-06T14:12:13.317Z" }, - { url = "https://files.pythonhosted.org/packages/f9/86/0f0dccb6e59a9e7f122c5afd43568b1d31b8ab7dda5f1b01fb5c7025c9a9/yarl-1.22.0-cp314-cp314t-win_amd64.whl", hash = "sha256:9fb17ea16e972c63d25d4a97f016d235c78dd2344820eb35bc034bc32012ee27", size = 96292, upload-time = "2025-10-06T14:12:15.398Z" }, - { url = "https://files.pythonhosted.org/packages/48/b7/503c98092fb3b344a179579f55814b613c1fbb1c23b3ec14a7b008a66a6e/yarl-1.22.0-cp314-cp314t-win_arm64.whl", hash = "sha256:9f6d73c1436b934e3f01df1e1b21ff765cd1d28c77dfb9ace207f746d4610ee1", size = 85171, upload-time = "2025-10-06T14:12:16.935Z" }, - { url = "https://files.pythonhosted.org/packages/73/ae/b48f95715333080afb75a4504487cbe142cae1268afc482d06692d605ae6/yarl-1.22.0-py3-none-any.whl", hash = "sha256:1380560bdba02b6b6c90de54133c81c9f2a453dee9912fe58c1dcced1edb7cff", size = 46814, upload-time = "2025-10-06T14:12:53.872Z" }, -] +version = 1 +revision = 3 +requires-python = ">=3.13" + +[[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, upload-time = "2025-10-09T20:51:04.358Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bc/8a/340a1555ae33d7354dbca4faa54948d76d89a27ceef032c8c3bc661d003e/aiofiles-25.1.0-py3-none-any.whl", hash = "sha256:abe311e527c862958650f9438e859c1fa7568a141b22abcd015e120e86a85695", size = 14668, upload-time = "2025-10-09T20:51:03.174Z" }, +] + +[[package]] +name = "aiohappyeyeballs" +version = "2.6.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/26/30/f84a107a9c4331c14b2b586036f40965c128aa4fee4dda5d3d51cb14ad54/aiohappyeyeballs-2.6.1.tar.gz", hash = "sha256:c3f9d0113123803ccadfdf3f0faa505bc78e6a72d1cc4806cbd719826e943558", size = 22760, upload-time = "2025-03-12T01:42:48.764Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0f/15/5bf3b99495fb160b63f95972b81750f18f7f4e02ad051373b669d17d44f2/aiohappyeyeballs-2.6.1-py3-none-any.whl", hash = "sha256:f349ba8f4b75cb25c99c5c2d84e997e485204d2902a9597802b0371f09331fb8", size = 15265, upload-time = "2025-03-12T01:42:47.083Z" }, +] + +[[package]] +name = "aiohttp" +version = "3.13.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiohappyeyeballs" }, + { name = "aiosignal" }, + { name = "attrs" }, + { name = "frozenlist" }, + { name = "multidict" }, + { name = "propcache" }, + { name = "yarl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1c/ce/3b83ebba6b3207a7135e5fcaba49706f8a4b6008153b4e30540c982fae26/aiohttp-3.13.2.tar.gz", hash = "sha256:40176a52c186aefef6eb3cad2cdd30cd06e3afbe88fe8ab2af9c0b90f228daca", size = 7837994, upload-time = "2025-10-28T20:59:39.937Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bf/78/7e90ca79e5aa39f9694dcfd74f4720782d3c6828113bb1f3197f7e7c4a56/aiohttp-3.13.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:7519bdc7dfc1940d201651b52bf5e03f5503bda45ad6eacf64dda98be5b2b6be", size = 732139, upload-time = "2025-10-28T20:57:02.455Z" }, + { url = "https://files.pythonhosted.org/packages/db/ed/1f59215ab6853fbaa5c8495fa6cbc39edfc93553426152b75d82a5f32b76/aiohttp-3.13.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:088912a78b4d4f547a1f19c099d5a506df17eacec3c6f4375e2831ec1d995742", size = 490082, upload-time = "2025-10-28T20:57:04.784Z" }, + { url = "https://files.pythonhosted.org/packages/68/7b/fe0fe0f5e05e13629d893c760465173a15ad0039c0a5b0d0040995c8075e/aiohttp-3.13.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5276807b9de9092af38ed23ce120539ab0ac955547b38563a9ba4f5b07b95293", size = 489035, upload-time = "2025-10-28T20:57:06.894Z" }, + { url = "https://files.pythonhosted.org/packages/d2/04/db5279e38471b7ac801d7d36a57d1230feeee130bbe2a74f72731b23c2b1/aiohttp-3.13.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1237c1375eaef0db4dcd7c2559f42e8af7b87ea7d295b118c60c36a6e61cb811", size = 1720387, upload-time = "2025-10-28T20:57:08.685Z" }, + { url = "https://files.pythonhosted.org/packages/31/07/8ea4326bd7dae2bd59828f69d7fdc6e04523caa55e4a70f4a8725a7e4ed2/aiohttp-3.13.2-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:96581619c57419c3d7d78703d5b78c1e5e5fc0172d60f555bdebaced82ded19a", size = 1688314, upload-time = "2025-10-28T20:57:10.693Z" }, + { url = "https://files.pythonhosted.org/packages/48/ab/3d98007b5b87ffd519d065225438cc3b668b2f245572a8cb53da5dd2b1bc/aiohttp-3.13.2-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a2713a95b47374169409d18103366de1050fe0ea73db358fc7a7acb2880422d4", size = 1756317, upload-time = "2025-10-28T20:57:12.563Z" }, + { url = "https://files.pythonhosted.org/packages/97/3d/801ca172b3d857fafb7b50c7c03f91b72b867a13abca982ed6b3081774ef/aiohttp-3.13.2-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:228a1cd556b3caca590e9511a89444925da87d35219a49ab5da0c36d2d943a6a", size = 1858539, upload-time = "2025-10-28T20:57:14.623Z" }, + { url = "https://files.pythonhosted.org/packages/f7/0d/4764669bdf47bd472899b3d3db91fffbe925c8e3038ec591a2fd2ad6a14d/aiohttp-3.13.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ac6cde5fba8d7d8c6ac963dbb0256a9854e9fafff52fbcc58fdf819357892c3e", size = 1739597, upload-time = "2025-10-28T20:57:16.399Z" }, + { url = "https://files.pythonhosted.org/packages/c4/52/7bd3c6693da58ba16e657eb904a5b6decfc48ecd06e9ac098591653b1566/aiohttp-3.13.2-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f2bef8237544f4e42878c61cef4e2839fee6346dc60f5739f876a9c50be7fcdb", size = 1555006, upload-time = "2025-10-28T20:57:18.288Z" }, + { url = "https://files.pythonhosted.org/packages/48/30/9586667acec5993b6f41d2ebcf96e97a1255a85f62f3c653110a5de4d346/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:16f15a4eac3bc2d76c45f7ebdd48a65d41b242eb6c31c2245463b40b34584ded", size = 1683220, upload-time = "2025-10-28T20:57:20.241Z" }, + { url = "https://files.pythonhosted.org/packages/71/01/3afe4c96854cfd7b30d78333852e8e851dceaec1c40fd00fec90c6402dd2/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:bb7fb776645af5cc58ab804c58d7eba545a97e047254a52ce89c157b5af6cd0b", size = 1712570, upload-time = "2025-10-28T20:57:22.253Z" }, + { url = "https://files.pythonhosted.org/packages/11/2c/22799d8e720f4697a9e66fd9c02479e40a49de3de2f0bbe7f9f78a987808/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:e1b4951125ec10c70802f2cb09736c895861cd39fd9dcb35107b4dc8ae6220b8", size = 1733407, upload-time = "2025-10-28T20:57:24.37Z" }, + { url = "https://files.pythonhosted.org/packages/34/cb/90f15dd029f07cebbd91f8238a8b363978b530cd128488085b5703683594/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:550bf765101ae721ee1d37d8095f47b1f220650f85fe1af37a90ce75bab89d04", size = 1550093, upload-time = "2025-10-28T20:57:26.257Z" }, + { url = "https://files.pythonhosted.org/packages/69/46/12dce9be9d3303ecbf4d30ad45a7683dc63d90733c2d9fe512be6716cd40/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:fe91b87fc295973096251e2d25a811388e7d8adf3bd2b97ef6ae78bc4ac6c476", size = 1758084, upload-time = "2025-10-28T20:57:28.349Z" }, + { url = "https://files.pythonhosted.org/packages/f9/c8/0932b558da0c302ffd639fc6362a313b98fdf235dc417bc2493da8394df7/aiohttp-3.13.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e0c8e31cfcc4592cb200160344b2fb6ae0f9e4effe06c644b5a125d4ae5ebe23", size = 1716987, upload-time = "2025-10-28T20:57:30.233Z" }, + { url = "https://files.pythonhosted.org/packages/5d/8b/f5bd1a75003daed099baec373aed678f2e9b34f2ad40d85baa1368556396/aiohttp-3.13.2-cp313-cp313-win32.whl", hash = "sha256:0740f31a60848d6edb296a0df827473eede90c689b8f9f2a4cdde74889eb2254", size = 425859, upload-time = "2025-10-28T20:57:32.105Z" }, + { url = "https://files.pythonhosted.org/packages/5d/28/a8a9fc6957b2cee8902414e41816b5ab5536ecf43c3b1843c10e82c559b2/aiohttp-3.13.2-cp313-cp313-win_amd64.whl", hash = "sha256:a88d13e7ca367394908f8a276b89d04a3652044612b9a408a0bb22a5ed976a1a", size = 452192, upload-time = "2025-10-28T20:57:34.166Z" }, + { url = "https://files.pythonhosted.org/packages/9b/36/e2abae1bd815f01c957cbf7be817b3043304e1c87bad526292a0410fdcf9/aiohttp-3.13.2-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:2475391c29230e063ef53a66669b7b691c9bfc3f1426a0f7bcdf1216bdbac38b", size = 735234, upload-time = "2025-10-28T20:57:36.415Z" }, + { url = "https://files.pythonhosted.org/packages/ca/e3/1ee62dde9b335e4ed41db6bba02613295a0d5b41f74a783c142745a12763/aiohttp-3.13.2-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:f33c8748abef4d8717bb20e8fb1b3e07c6adacb7fd6beaae971a764cf5f30d61", size = 490733, upload-time = "2025-10-28T20:57:38.205Z" }, + { url = "https://files.pythonhosted.org/packages/1a/aa/7a451b1d6a04e8d15a362af3e9b897de71d86feac3babf8894545d08d537/aiohttp-3.13.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ae32f24bbfb7dbb485a24b30b1149e2f200be94777232aeadba3eecece4d0aa4", size = 491303, upload-time = "2025-10-28T20:57:40.122Z" }, + { url = "https://files.pythonhosted.org/packages/57/1e/209958dbb9b01174870f6a7538cd1f3f28274fdbc88a750c238e2c456295/aiohttp-3.13.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d7f02042c1f009ffb70067326ef183a047425bb2ff3bc434ead4dd4a4a66a2b", size = 1717965, upload-time = "2025-10-28T20:57:42.28Z" }, + { url = "https://files.pythonhosted.org/packages/08/aa/6a01848d6432f241416bc4866cae8dc03f05a5a884d2311280f6a09c73d6/aiohttp-3.13.2-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:93655083005d71cd6c072cdab54c886e6570ad2c4592139c3fb967bfc19e4694", size = 1667221, upload-time = "2025-10-28T20:57:44.869Z" }, + { url = "https://files.pythonhosted.org/packages/87/4f/36c1992432d31bbc789fa0b93c768d2e9047ec8c7177e5cd84ea85155f36/aiohttp-3.13.2-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0db1e24b852f5f664cd728db140cf11ea0e82450471232a394b3d1a540b0f906", size = 1757178, upload-time = "2025-10-28T20:57:47.216Z" }, + { url = "https://files.pythonhosted.org/packages/ac/b4/8e940dfb03b7e0f68a82b88fd182b9be0a65cb3f35612fe38c038c3112cf/aiohttp-3.13.2-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b009194665bcd128e23eaddef362e745601afa4641930848af4c8559e88f18f9", size = 1838001, upload-time = "2025-10-28T20:57:49.337Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ef/39f3448795499c440ab66084a9db7d20ca7662e94305f175a80f5b7e0072/aiohttp-3.13.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c038a8fdc8103cd51dbd986ecdce141473ffd9775a7a8057a6ed9c3653478011", size = 1716325, upload-time = "2025-10-28T20:57:51.327Z" }, + { url = "https://files.pythonhosted.org/packages/d7/51/b311500ffc860b181c05d91c59a1313bdd05c82960fdd4035a15740d431e/aiohttp-3.13.2-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:66bac29b95a00db411cd758fea0e4b9bdba6d549dfe333f9a945430f5f2cc5a6", size = 1547978, upload-time = "2025-10-28T20:57:53.554Z" }, + { url = "https://files.pythonhosted.org/packages/31/64/b9d733296ef79815226dab8c586ff9e3df41c6aff2e16c06697b2d2e6775/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4ebf9cfc9ba24a74cf0718f04aac2a3bbe745902cc7c5ebc55c0f3b5777ef213", size = 1682042, upload-time = "2025-10-28T20:57:55.617Z" }, + { url = "https://files.pythonhosted.org/packages/3f/30/43d3e0f9d6473a6db7d472104c4eff4417b1e9df01774cb930338806d36b/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:a4b88ebe35ce54205c7074f7302bd08a4cb83256a3e0870c72d6f68a3aaf8e49", size = 1680085, upload-time = "2025-10-28T20:57:57.59Z" }, + { url = "https://files.pythonhosted.org/packages/16/51/c709f352c911b1864cfd1087577760ced64b3e5bee2aa88b8c0c8e2e4972/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:98c4fb90bb82b70a4ed79ca35f656f4281885be076f3f970ce315402b53099ae", size = 1728238, upload-time = "2025-10-28T20:57:59.525Z" }, + { url = "https://files.pythonhosted.org/packages/19/e2/19bd4c547092b773caeb48ff5ae4b1ae86756a0ee76c16727fcfd281404b/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:ec7534e63ae0f3759df3a1ed4fa6bc8f75082a924b590619c0dd2f76d7043caa", size = 1544395, upload-time = "2025-10-28T20:58:01.914Z" }, + { url = "https://files.pythonhosted.org/packages/cf/87/860f2803b27dfc5ed7be532832a3498e4919da61299b4a1f8eb89b8ff44d/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:5b927cf9b935a13e33644cbed6c8c4b2d0f25b713d838743f8fe7191b33829c4", size = 1742965, upload-time = "2025-10-28T20:58:03.972Z" }, + { url = "https://files.pythonhosted.org/packages/67/7f/db2fc7618925e8c7a601094d5cbe539f732df4fb570740be88ed9e40e99a/aiohttp-3.13.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:88d6c017966a78c5265d996c19cdb79235be5e6412268d7e2ce7dee339471b7a", size = 1697585, upload-time = "2025-10-28T20:58:06.189Z" }, + { url = "https://files.pythonhosted.org/packages/0c/07/9127916cb09bb38284db5036036042b7b2c514c8ebaeee79da550c43a6d6/aiohttp-3.13.2-cp314-cp314-win32.whl", hash = "sha256:f7c183e786e299b5d6c49fb43a769f8eb8e04a2726a2bd5887b98b5cc2d67940", size = 431621, upload-time = "2025-10-28T20:58:08.636Z" }, + { url = "https://files.pythonhosted.org/packages/fb/41/554a8a380df6d3a2bba8a7726429a23f4ac62aaf38de43bb6d6cde7b4d4d/aiohttp-3.13.2-cp314-cp314-win_amd64.whl", hash = "sha256:fe242cd381e0fb65758faf5ad96c2e460df6ee5b2de1072fe97e4127927e00b4", size = 457627, upload-time = "2025-10-28T20:58:11Z" }, + { url = "https://files.pythonhosted.org/packages/c7/8e/3824ef98c039d3951cb65b9205a96dd2b20f22241ee17d89c5701557c826/aiohttp-3.13.2-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:f10d9c0b0188fe85398c61147bbd2a657d616c876863bfeff43376e0e3134673", size = 767360, upload-time = "2025-10-28T20:58:13.358Z" }, + { url = "https://files.pythonhosted.org/packages/a4/0f/6a03e3fc7595421274fa34122c973bde2d89344f8a881b728fa8c774e4f1/aiohttp-3.13.2-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:e7c952aefdf2460f4ae55c5e9c3e80aa72f706a6317e06020f80e96253b1accd", size = 504616, upload-time = "2025-10-28T20:58:15.339Z" }, + { url = "https://files.pythonhosted.org/packages/c6/aa/ed341b670f1bc8a6f2c6a718353d13b9546e2cef3544f573c6a1ff0da711/aiohttp-3.13.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c20423ce14771d98353d2e25e83591fa75dfa90a3c1848f3d7c68243b4fbded3", size = 509131, upload-time = "2025-10-28T20:58:17.693Z" }, + { url = "https://files.pythonhosted.org/packages/7f/f0/c68dac234189dae5c4bbccc0f96ce0cc16b76632cfc3a08fff180045cfa4/aiohttp-3.13.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e96eb1a34396e9430c19d8338d2ec33015e4a87ef2b4449db94c22412e25ccdf", size = 1864168, upload-time = "2025-10-28T20:58:20.113Z" }, + { url = "https://files.pythonhosted.org/packages/8f/65/75a9a76db8364b5d0e52a0c20eabc5d52297385d9af9c35335b924fafdee/aiohttp-3.13.2-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:23fb0783bc1a33640036465019d3bba069942616a6a2353c6907d7fe1ccdaf4e", size = 1719200, upload-time = "2025-10-28T20:58:22.583Z" }, + { url = "https://files.pythonhosted.org/packages/f5/55/8df2ed78d7f41d232f6bd3ff866b6f617026551aa1d07e2f03458f964575/aiohttp-3.13.2-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2e1a9bea6244a1d05a4e57c295d69e159a5c50d8ef16aa390948ee873478d9a5", size = 1843497, upload-time = "2025-10-28T20:58:24.672Z" }, + { url = "https://files.pythonhosted.org/packages/e9/e0/94d7215e405c5a02ccb6a35c7a3a6cfff242f457a00196496935f700cde5/aiohttp-3.13.2-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0a3d54e822688b56e9f6b5816fb3de3a3a64660efac64e4c2dc435230ad23bad", size = 1935703, upload-time = "2025-10-28T20:58:26.758Z" }, + { url = "https://files.pythonhosted.org/packages/0b/78/1eeb63c3f9b2d1015a4c02788fb543141aad0a03ae3f7a7b669b2483f8d4/aiohttp-3.13.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7a653d872afe9f33497215745da7a943d1dc15b728a9c8da1c3ac423af35178e", size = 1792738, upload-time = "2025-10-28T20:58:29.787Z" }, + { url = "https://files.pythonhosted.org/packages/41/75/aaf1eea4c188e51538c04cc568040e3082db263a57086ea74a7d38c39e42/aiohttp-3.13.2-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:56d36e80d2003fa3fc0207fac644216d8532e9504a785ef9a8fd013f84a42c61", size = 1624061, upload-time = "2025-10-28T20:58:32.529Z" }, + { url = "https://files.pythonhosted.org/packages/9b/c2/3b6034de81fbcc43de8aeb209073a2286dfb50b86e927b4efd81cf848197/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:78cd586d8331fb8e241c2dd6b2f4061778cc69e150514b39a9e28dd050475661", size = 1789201, upload-time = "2025-10-28T20:58:34.618Z" }, + { url = "https://files.pythonhosted.org/packages/c9/38/c15dcf6d4d890217dae79d7213988f4e5fe6183d43893a9cf2fe9e84ca8d/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:20b10bbfbff766294fe99987f7bb3b74fdd2f1a2905f2562132641ad434dcf98", size = 1776868, upload-time = "2025-10-28T20:58:38.835Z" }, + { url = "https://files.pythonhosted.org/packages/04/75/f74fd178ac81adf4f283a74847807ade5150e48feda6aef024403716c30c/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:9ec49dff7e2b3c85cdeaa412e9d438f0ecd71676fde61ec57027dd392f00c693", size = 1790660, upload-time = "2025-10-28T20:58:41.507Z" }, + { url = "https://files.pythonhosted.org/packages/e7/80/7368bd0d06b16b3aba358c16b919e9c46cf11587dc572091031b0e9e3ef0/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:94f05348c4406450f9d73d38efb41d669ad6cd90c7ee194810d0eefbfa875a7a", size = 1617548, upload-time = "2025-10-28T20:58:43.674Z" }, + { url = "https://files.pythonhosted.org/packages/7d/4b/a6212790c50483cb3212e507378fbe26b5086d73941e1ec4b56a30439688/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:fa4dcb605c6f82a80c7f95713c2b11c3b8e9893b3ebd2bc9bde93165ed6107be", size = 1817240, upload-time = "2025-10-28T20:58:45.787Z" }, + { url = "https://files.pythonhosted.org/packages/ff/f7/ba5f0ba4ea8d8f3c32850912944532b933acbf0f3a75546b89269b9b7dde/aiohttp-3.13.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:cf00e5db968c3f67eccd2778574cf64d8b27d95b237770aa32400bd7a1ca4f6c", size = 1762334, upload-time = "2025-10-28T20:58:47.936Z" }, + { url = "https://files.pythonhosted.org/packages/7e/83/1a5a1856574588b1cad63609ea9ad75b32a8353ac995d830bf5da9357364/aiohttp-3.13.2-cp314-cp314t-win32.whl", hash = "sha256:d23b5fe492b0805a50d3371e8a728a9134d8de5447dce4c885f5587294750734", size = 464685, upload-time = "2025-10-28T20:58:50.642Z" }, + { url = "https://files.pythonhosted.org/packages/9f/4d/d22668674122c08f4d56972297c51a624e64b3ed1efaa40187607a7cb66e/aiohttp-3.13.2-cp314-cp314t-win_amd64.whl", hash = "sha256:ff0a7b0a82a7ab905cbda74006318d1b12e37c797eb1b0d4eb3e316cf47f658f", size = 498093, upload-time = "2025-10-28T20:58:52.782Z" }, +] + +[[package]] +name = "aiomysql" +version = "0.3.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pymysql" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/29/e0/302aeffe8d90853556f47f3106b89c16cc2ec2a4d269bdfd82e3f4ae12cc/aiomysql-0.3.2.tar.gz", hash = "sha256:72d15ef5cfc34c03468eb41e1b90adb9fd9347b0b589114bd23ead569a02ac1a", size = 108311, upload-time = "2025-10-22T00:15:21.278Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4c/af/aae0153c3e28712adaf462328f6c7a3c196a1c1c27b491de4377dd3e6b52/aiomysql-0.3.2-py3-none-any.whl", hash = "sha256:c82c5ba04137d7afd5c693a258bea8ead2aad77101668044143a991e04632eb2", size = 71834, upload-time = "2025-10-22T00:15:15.905Z" }, +] + +[[package]] +name = "aiosignal" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "frozenlist" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/61/62/06741b579156360248d1ec624842ad0edf697050bbaf7c3e46394e106ad1/aiosignal-1.4.0.tar.gz", hash = "sha256:f47eecd9468083c2029cc99945502cb7708b082c232f9aca65da147157b251c7", size = 25007, upload-time = "2025-07-03T22:54:43.528Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/76/641ae371508676492379f16e2fa48f4e2c11741bd63c48be4b12a6b09cba/aiosignal-1.4.0-py3-none-any.whl", hash = "sha256:053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e", size = 7490, upload-time = "2025-07-03T22:54:42.156Z" }, +] + +[[package]] +name = "annotated-doc" +version = "0.0.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/57/ba/046ceea27344560984e26a590f90bc7f4a75b06701f653222458922b558c/annotated_doc-0.0.4.tar.gz", hash = "sha256:fbcda96e87e9c92ad167c2e53839e57503ecfda18804ea28102353485033faa4", size = 7288, upload-time = "2025-11-10T22:07:42.062Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/d3/26bf1008eb3d2daa8ef4cacc7f3bfdc11818d111f7e2d0201bc6e3b49d45/annotated_doc-0.0.4-py3-none-any.whl", hash = "sha256:571ac1dc6991c450b25a9c2d84a3705e2ae7a53467b5d111c24fa8baabbed320", size = 5303, upload-time = "2025-11-10T22:07:40.673Z" }, +] + +[[package]] +name = "annotated-types" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, +] + +[[package]] +name = "anyio" +version = "4.12.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "idna" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/16/ce/8a777047513153587e5434fd752e89334ac33e379aa3497db860eeb60377/anyio-4.12.0.tar.gz", hash = "sha256:73c693b567b0c55130c104d0b43a9baf3aa6a31fc6110116509f27bf75e21ec0", size = 228266, upload-time = "2025-11-28T23:37:38.911Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7f/9c/36c5c37947ebfb8c7f22e0eb6e4d188ee2d53aa3880f3f2744fb894f0cb1/anyio-4.12.0-py3-none-any.whl", hash = "sha256:dad2376a628f98eeca4881fc56cd06affd18f659b17a747d3ff0307ced94b1bb", size = 113362, upload-time = "2025-11-28T23:36:57.897Z" }, +] + +[[package]] +name = "asyncmy" +version = "0.2.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b5/76/55cc0577f9e838c5a5213bf33159b9e484c9d9820a2bafd4d6bfa631bf86/asyncmy-0.2.10.tar.gz", hash = "sha256:f4b67edadf7caa56bdaf1c2e6cf451150c0a86f5353744deabe4426fe27aff4e", size = 63889, upload-time = "2024-12-12T14:45:09.2Z" } + +[[package]] +name = "attrs" +version = "25.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6b/5c/685e6633917e101e5dcb62b9dd76946cbb57c26e133bae9e0cd36033c0a9/attrs-25.4.0.tar.gz", hash = "sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11", size = 934251, upload-time = "2025-10-06T13:54:44.725Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl", hash = "sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373", size = 67615, upload-time = "2025-10-06T13:54:43.17Z" }, +] + +[[package]] +name = "beautifulsoup4" +version = "4.14.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "soupsieve" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c3/b0/1c6a16426d389813b48d95e26898aff79abbde42ad353958ad95cc8c9b21/beautifulsoup4-4.14.3.tar.gz", hash = "sha256:6292b1c5186d356bba669ef9f7f051757099565ad9ada5dd630bd9de5fa7fb86", size = 627737, upload-time = "2025-11-30T15:08:26.084Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1a/39/47f9197bdd44df24d67ac8893641e16f386c984a0619ef2ee4c51fbbc019/beautifulsoup4-4.14.3-py3-none-any.whl", hash = "sha256:0918bfe44902e6ad8d57732ba310582e98da931428d231a5ecb9e7c703a735bb", size = 107721, upload-time = "2025-11-30T15:08:24.087Z" }, +] + +[[package]] +name = "certifi" +version = "2025.11.12" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/8c/58f469717fa48465e4a50c014a0400602d3c437d7c0c468e17ada824da3a/certifi-2025.11.12.tar.gz", hash = "sha256:d8ab5478f2ecd78af242878415affce761ca6bc54a22a27e026d7c25357c3316", size = 160538, upload-time = "2025-11-12T02:54:51.517Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/70/7d/9bc192684cea499815ff478dfcdc13835ddf401365057044fb721ec6bddb/certifi-2025.11.12-py3-none-any.whl", hash = "sha256:97de8790030bbd5c2d96b7ec782fc2f7820ef8dba6db909ccf95449f2d062d4b", size = 159438, upload-time = "2025-11-12T02:54:49.735Z" }, +] + +[[package]] +name = "click" +version = "8.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3d/fa/656b739db8587d7b5dfa22e22ed02566950fbfbcdc20311993483657a5c0/click-8.3.1.tar.gz", hash = "sha256:12ff4785d337a1bb490bb7e9c2b1ee5da3112e94a8622f26a6c77f5d2fc6842a", size = 295065, upload-time = "2025-11-15T20:45:42.706Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/98/78/01c019cdb5d6498122777c1a43056ebb3ebfeef2076d9d026bfe15583b2b/click-8.3.1-py3-none-any.whl", hash = "sha256:981153a64e25f12d547d3426c367a4857371575ee7ad18df2a6183ab0545b2a6", size = 108274, upload-time = "2025-11-15T20:45:41.139Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "distro" +version = "1.9.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/fc/f8/98eea607f65de6527f8a2e8885fc8015d3e6f5775df186e443e0964a11c3/distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed", size = 60722, upload-time = "2023-12-24T09:54:32.31Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/12/b3/231ffd4ab1fc9d679809f356cebee130ac7daa00d6d6f3206dd4fd137e9e/distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2", size = 20277, upload-time = "2023-12-24T09:54:30.421Z" }, +] + +[[package]] +name = "dnspython" +version = "2.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8c/8b/57666417c0f90f08bcafa776861060426765fdb422eb10212086fb811d26/dnspython-2.8.0.tar.gz", hash = "sha256:181d3c6996452cb1189c4046c61599b84a5a86e099562ffde77d26984ff26d0f", size = 368251, upload-time = "2025-09-07T18:58:00.022Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ba/5a/18ad964b0086c6e62e2e7500f7edc89e3faa45033c71c1893d34eed2b2de/dnspython-2.8.0-py3-none-any.whl", hash = "sha256:01d9bbc4a2d76bf0db7c1f729812ded6d912bd318d3b1cf81d30c0f845dbf3af", size = 331094, upload-time = "2025-09-07T18:57:58.071Z" }, +] + +[[package]] +name = "email-validator" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "dnspython" }, + { name = "idna" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f5/22/900cb125c76b7aaa450ce02fd727f452243f2e91a61af068b40adba60ea9/email_validator-2.3.0.tar.gz", hash = "sha256:9fc05c37f2f6cf439ff414f8fc46d917929974a82244c20eb10231ba60c54426", size = 51238, upload-time = "2025-08-26T13:09:06.831Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/de/15/545e2b6cf2e3be84bc1ed85613edd75b8aea69807a71c26f4ca6a9258e82/email_validator-2.3.0-py3-none-any.whl", hash = "sha256:80f13f623413e6b197ae73bb10bf4eb0908faf509ad8362c5edeb0be7fd450b4", size = 35604, upload-time = "2025-08-26T13:09:05.858Z" }, +] + +[[package]] +name = "fastapi" +version = "0.125.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-doc" }, + { name = "pydantic" }, + { name = "starlette" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/17/71/2df15009fb4bdd522a069d2fbca6007c6c5487fce5cb965be00fc335f1d1/fastapi-0.125.0.tar.gz", hash = "sha256:16b532691a33e2c5dee1dac32feb31dc6eb41a3dd4ff29a95f9487cb21c054c0", size = 370550, upload-time = "2025-12-17T21:41:44.15Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/34/2f/ff2fcc98f500713368d8b650e1bbc4a0b3ebcdd3e050dcdaad5f5a13fd7e/fastapi-0.125.0-py3-none-any.whl", hash = "sha256:2570ec4f3aecf5cca8f0428aed2398b774fcdfee6c2116f86e80513f2f86a7a1", size = 112888, upload-time = "2025-12-17T21:41:41.286Z" }, +] + +[package.optional-dependencies] +standard = [ + { name = "email-validator" }, + { name = "fastapi-cli", extra = ["standard"] }, + { name = "httpx" }, + { name = "jinja2" }, + { name = "python-multipart" }, + { name = "uvicorn", extra = ["standard"] }, +] + +[[package]] +name = "fastapi-cli" +version = "0.0.16" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "rich-toolkit" }, + { name = "typer" }, + { name = "uvicorn", extra = ["standard"] }, +] +sdist = { url = "https://files.pythonhosted.org/packages/99/75/9407a6b452be4c988feacec9c9d2f58d8f315162a6c7258d5a649d933ebe/fastapi_cli-0.0.16.tar.gz", hash = "sha256:e8a2a1ecf7a4e062e3b2eec63ae34387d1e142d4849181d936b23c4bdfe29073", size = 19447, upload-time = "2025-11-10T19:01:07.856Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/55/43/678528c19318394320ee43757648d5e0a8070cf391b31f69d931e5c840d2/fastapi_cli-0.0.16-py3-none-any.whl", hash = "sha256:addcb6d130b5b9c91adbbf3f2947fe115991495fdb442fe3e51b5fc6327df9f4", size = 12312, upload-time = "2025-11-10T19:01:06.728Z" }, +] + +[package.optional-dependencies] +standard = [ + { name = "fastapi-cloud-cli" }, + { name = "uvicorn", extra = ["standard"] }, +] + +[[package]] +name = "fastapi-cloud-cli" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "fastar" }, + { name = "httpx" }, + { name = "pydantic", extra = ["email"] }, + { name = "rich-toolkit" }, + { name = "rignore" }, + { name = "sentry-sdk" }, + { name = "typer" }, + { name = "uvicorn", extra = ["standard"] }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cf/0d/3b0d2991f481c122c552b4ae38a8b400a75ab0edbc85536f2a6224f72da2/fastapi_cloud_cli-0.7.0.tar.gz", hash = "sha256:8b025944475c3d53262105886dfe051f46383e4f287787a46892b524922ac0b6", size = 30906, upload-time = "2025-12-16T12:51:49.082Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2d/aa/a2319f008e123b178a5c4cba34935e8459e72d24d8c31214b244ab7266a6/fastapi_cloud_cli-0.7.0-py3-none-any.whl", hash = "sha256:9a152e80d08d465d4a6c4f5c75aa8871d1e8919f69ff131b0567f04e95d5f36c", size = 23376, upload-time = "2025-12-16T12:51:47.847Z" }, +] + +[[package]] +name = "fastar" +version = "0.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/69/e7/f89d54fb04104114dd0552836dc2b47914f416cc0e200b409dd04a33de5e/fastar-0.8.0.tar.gz", hash = "sha256:f4d4d68dbf1c4c2808f0e730fac5843493fc849f70fe3ad3af60dfbaf68b9a12", size = 68524, upload-time = "2025-11-26T02:36:00.72Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/a5/79ecba3646e22d03eef1a66fb7fc156567213e2e4ab9faab3bbd4489e483/fastar-0.8.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:a3253a06845462ca2196024c7a18f5c0ba4de1532ab1c4bad23a40b332a06a6a", size = 706112, upload-time = "2025-11-26T02:34:39.237Z" }, + { url = "https://files.pythonhosted.org/packages/0a/03/4f883bce878218a8676c2d7ca09b50c856a5470bb3b7f63baf9521ea6995/fastar-0.8.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5cbeb3ebfa0980c68ff8b126295cc6b208ccd81b638aebc5a723d810a7a0e5d2", size = 628954, upload-time = "2025-11-26T02:34:23.705Z" }, + { url = "https://files.pythonhosted.org/packages/4f/f1/892e471f156b03d10ba48ace9384f5a896702a54506137462545f38e40b8/fastar-0.8.0-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1c0d5956b917daac77d333d48b3f0f3ff927b8039d5b32d8125462782369f761", size = 868685, upload-time = "2025-11-26T02:33:53.077Z" }, + { url = "https://files.pythonhosted.org/packages/39/ba/e24915045852e30014ec6840446975c03f4234d1c9270394b51d3ad18394/fastar-0.8.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:27b404db2b786b65912927ce7f3790964a4bcbde42cdd13091b82a89cd655e1c", size = 765044, upload-time = "2025-11-26T02:32:48.187Z" }, + { url = "https://files.pythonhosted.org/packages/14/2c/1aa11ac21a99984864c2fca4994e094319ff3a2046e7a0343c39317bd5b9/fastar-0.8.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0902fc89dcf1e7f07b8563032a4159fe2b835e4c16942c76fd63451d0e5f76a3", size = 764322, upload-time = "2025-11-26T02:33:03.859Z" }, + { url = "https://files.pythonhosted.org/packages/ba/f0/4b91902af39fe2d3bae7c85c6d789586b9fbcf618d7fdb3d37323915906d/fastar-0.8.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:069347e2f0f7a8b99bbac8cd1bc0e06c7b4a31dc964fc60d84b95eab3d869dc1", size = 931016, upload-time = "2025-11-26T02:33:19.902Z" }, + { url = "https://files.pythonhosted.org/packages/c9/97/8fc43a5a9c0a2dc195730f6f7a0f367d171282cd8be2511d0e87c6d2dad0/fastar-0.8.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7fd135306f6bfe9a835918280e0eb440b70ab303e0187d90ab51ca86e143f70d", size = 821308, upload-time = "2025-11-26T02:33:34.664Z" }, + { url = "https://files.pythonhosted.org/packages/0c/e9/058615b63a7fd27965e8c5966f393ed0c169f7ff5012e1674f21684de3ba/fastar-0.8.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78d06d6897f43c27154b5f2d0eb930a43a81b7eec73f6f0b0114814d4a10ab38", size = 821171, upload-time = "2025-11-26T02:34:08.498Z" }, + { url = "https://files.pythonhosted.org/packages/ca/cf/69e16a17961570a755c37ffb5b5aa7610d2e77807625f537989da66f2a9d/fastar-0.8.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a922f8439231fa0c32b15e8d70ff6d415619b9d40492029dabbc14a0c53b5f18", size = 986227, upload-time = "2025-11-26T02:34:55.06Z" }, + { url = "https://files.pythonhosted.org/packages/fb/83/2100192372e59b56f4ace37d7d9cabda511afd71b5febad1643d1c334271/fastar-0.8.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:a739abd51eb766384b4caff83050888e80cd75bbcfec61e6d1e64875f94e4a40", size = 1039395, upload-time = "2025-11-26T02:35:12.166Z" }, + { url = "https://files.pythonhosted.org/packages/75/15/cdd03aca972f55872efbb7cf7540c3fa7b97a75d626303a3ea46932163dc/fastar-0.8.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:5a65f419d808b23ac89d5cd1b13a2f340f15bc5d1d9af79f39fdb77bba48ff1b", size = 1044766, upload-time = "2025-11-26T02:35:29.62Z" }, + { url = "https://files.pythonhosted.org/packages/3d/29/945e69e4e2652329ace545999334ec31f1431fbae3abb0105587e11af2ae/fastar-0.8.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7bb2ae6c0cce58f0db1c9f20495e7557cca2c1ee9c69bbd90eafd54f139171c5", size = 994740, upload-time = "2025-11-26T02:35:47.887Z" }, + { url = "https://files.pythonhosted.org/packages/4b/5d/dbfe28f8cd1eb484bba0c62e5259b2cf6fea229d6ef43e05c06b5a78c034/fastar-0.8.0-cp313-cp313-win32.whl", hash = "sha256:b28753e0d18a643272597cb16d39f1053842aa43131ad3e260c03a2417d38401", size = 455990, upload-time = "2025-11-26T02:36:28.502Z" }, + { url = "https://files.pythonhosted.org/packages/e1/01/e965740bd36e60ef4c5aa2cbe42b6c4eb1dc3551009238a97c2e5e96bd23/fastar-0.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:620e5d737dce8321d49a5ebb7997f1fd0047cde3512082c27dc66d6ac8c1927a", size = 490227, upload-time = "2025-11-26T02:36:14.363Z" }, + { url = "https://files.pythonhosted.org/packages/dd/10/c99202719b83e5249f26902ae53a05aea67d840eeb242019322f20fc171c/fastar-0.8.0-cp313-cp313-win_arm64.whl", hash = "sha256:c4c4bd08df563120cd33e854fe0a93b81579e8571b11f9b7da9e84c37da2d6b6", size = 461078, upload-time = "2025-11-26T02:36:04.94Z" }, + { url = "https://files.pythonhosted.org/packages/96/4a/9573b87a0ef07580ed111e7230259aec31bb33ca3667963ebee77022ec61/fastar-0.8.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:50b36ce654ba44b0e13fae607ae17ee6e1597b69f71df1bee64bb8328d881dfc", size = 706041, upload-time = "2025-11-26T02:34:40.638Z" }, + { url = "https://files.pythonhosted.org/packages/4a/19/f95444a1d4f375333af49300aa75ee93afa3335c0e40fda528e460ed859c/fastar-0.8.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:63a892762683d7ab00df0227d5ea9677c62ff2cde9b875e666c0be569ed940f3", size = 628617, upload-time = "2025-11-26T02:34:24.893Z" }, + { url = "https://files.pythonhosted.org/packages/b3/c9/b51481b38b7e3f16ef2b9e233b1a3623386c939d745d6e41bbd389eaae30/fastar-0.8.0-cp314-cp314-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4ae6a145c1bff592644bde13f2115e0239f4b7babaf506d14e7d208483cf01a5", size = 869299, upload-time = "2025-11-26T02:33:54.274Z" }, + { url = "https://files.pythonhosted.org/packages/bf/02/3ba1267ee5ba7314e29c431cf82eaa68586f2c40cdfa08be3632b7d07619/fastar-0.8.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ae0ff7c0a1c7e1428404b81faee8aebef466bfd0be25bfe4dabf5d535c68741", size = 764667, upload-time = "2025-11-26T02:32:49.606Z" }, + { url = "https://files.pythonhosted.org/packages/1b/84/bf33530fd015b5d7c2cc69e0bce4a38d736754a6955487005aab1af6adcd/fastar-0.8.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dbfd87dbd217b45c898b2dbcd0169aae534b2c1c5cbe3119510881f6a5ac8ef5", size = 763993, upload-time = "2025-11-26T02:33:05.782Z" }, + { url = "https://files.pythonhosted.org/packages/da/e0/9564d24e7cea6321a8d921c6d2a457044a476ef197aa4708e179d3d97f0d/fastar-0.8.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9a5abd99fcba83ef28c8fe6ae2927edc79053db43a0457a962ed85c9bf150d37", size = 930153, upload-time = "2025-11-26T02:33:21.53Z" }, + { url = "https://files.pythonhosted.org/packages/35/b1/6f57fcd8d6e192cfebf97e58eb27751640ad93784c857b79039e84387b51/fastar-0.8.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:91d4c685620c3a9d6b5ae091dbabab4f98b20049b7ecc7976e19cc9016c0d5d6", size = 821177, upload-time = "2025-11-26T02:33:35.839Z" }, + { url = "https://files.pythonhosted.org/packages/b3/78/9e004ea9f3aa7466f5ddb6f9518780e1d2f0ed3ca55f093632982598bace/fastar-0.8.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f77c2f2cad76e9dc7b6701297adb1eba87d0485944b416fc2ccf5516c01219a3", size = 820652, upload-time = "2025-11-26T02:34:09.776Z" }, + { url = "https://files.pythonhosted.org/packages/42/95/b604ed536544005c9f1aee7c4c74b00150db3d8d535cd8232dc20f947063/fastar-0.8.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e7f07c4a3dada7757a8fc430a5b4a29e6ef696d2212747213f57086ffd970316", size = 985961, upload-time = "2025-11-26T02:34:56.401Z" }, + { url = "https://files.pythonhosted.org/packages/f2/7b/fa9d4d96a5d494bdb8699363bb9de8178c0c21a02e1d89cd6f913d127018/fastar-0.8.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:90c0c3fe55105c0aed8a83135dbdeb31e683455dbd326a1c48fa44c378b85616", size = 1039316, upload-time = "2025-11-26T02:35:13.807Z" }, + { url = "https://files.pythonhosted.org/packages/4e/f9/8462789243bc3f33e8401378ec6d54de4e20cfa60c96a0e15e3e9d1389bb/fastar-0.8.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:fb9ee51e5bffe0dab3d3126d3a4fac8d8f7235cedcb4b8e74936087ce1c157f3", size = 1045028, upload-time = "2025-11-26T02:35:31.079Z" }, + { url = "https://files.pythonhosted.org/packages/a5/71/9abb128777e616127194b509e98fcda3db797d76288c1a8c23dd22afc14f/fastar-0.8.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e380b1e8d30317f52406c43b11e98d11e1d68723bbd031e18049ea3497b59a6d", size = 994677, upload-time = "2025-11-26T02:35:49.391Z" }, + { url = "https://files.pythonhosted.org/packages/de/c1/b81b3f194853d7ad232a67a1d768f5f51a016f165cfb56cb31b31bbc6177/fastar-0.8.0-cp314-cp314-win32.whl", hash = "sha256:1c4ffc06e9c4a8ca498c07e094670d8d8c0d25b17ca6465b9774da44ea997ab1", size = 456687, upload-time = "2025-11-26T02:36:30.205Z" }, + { url = "https://files.pythonhosted.org/packages/cb/87/9e0cd4768a98181d56f0cdbab2363404cc15deb93f4aad3b99cd2761bbaa/fastar-0.8.0-cp314-cp314-win_amd64.whl", hash = "sha256:5517a8ad4726267c57a3e0e2a44430b782e00b230bf51c55b5728e758bb3a692", size = 490578, upload-time = "2025-11-26T02:36:16.218Z" }, + { url = "https://files.pythonhosted.org/packages/aa/1e/580a76cf91847654f2ad6520e956e93218f778540975bc4190d363f709e2/fastar-0.8.0-cp314-cp314-win_arm64.whl", hash = "sha256:58030551046ff4a8616931e52a36c83545ff05996db5beb6e0cd2b7e748aa309", size = 461473, upload-time = "2025-11-26T02:36:06.373Z" }, + { url = "https://files.pythonhosted.org/packages/58/4c/bdb5c6efe934f68708529c8c9d4055ebef5c4be370621966438f658b29bd/fastar-0.8.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:1e7d29b6bfecb29db126a08baf3c04a5ab667f6cea2b7067d3e623a67729c4a6", size = 705570, upload-time = "2025-11-26T02:34:42.01Z" }, + { url = "https://files.pythonhosted.org/packages/6d/78/f01ac7e71d5a37621bd13598a26e948a12b85ca8042f7ee1a0a8c9f59cda/fastar-0.8.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:05eb7b96940f9526b485f1d0b02393839f0f61cac4b1f60024984f8b326d2640", size = 627761, upload-time = "2025-11-26T02:34:26.152Z" }, + { url = "https://files.pythonhosted.org/packages/06/45/6df0ecda86ea9d2e95053c1a655d153dee55fc121b6e13ea6d1e246a50b6/fastar-0.8.0-cp314-cp314t-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:619352d8ac011794e2345c462189dc02ba634750d23cd9d86a9267dd71b1f278", size = 869414, upload-time = "2025-11-26T02:33:55.618Z" }, + { url = "https://files.pythonhosted.org/packages/b2/72/486421f5a8c0c377cc82e7a50c8a8ea899a6ec2aa72bde8f09fb667a2dc8/fastar-0.8.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74ebfecef3fe6d7a90355fac1402fd30636988332a1d33f3e80019a10782bb24", size = 763863, upload-time = "2025-11-26T02:32:51.051Z" }, + { url = "https://files.pythonhosted.org/packages/d4/64/39f654dbb41a3867fb1f2c8081c014d8f1d32ea10585d84cacbef0b32995/fastar-0.8.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2975aca5a639e26a3ab0d23b4b0628d6dd6d521146c3c11486d782be621a35aa", size = 763065, upload-time = "2025-11-26T02:33:07.274Z" }, + { url = "https://files.pythonhosted.org/packages/4e/bd/c011a34fb3534c4c3301f7c87c4ffd7e47f6113c904c092ddc8a59a303ea/fastar-0.8.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:afc438eaed8ff0dcdd9308268be5cb38c1db7e94c3ccca7c498ca13a4a4535a3", size = 930530, upload-time = "2025-11-26T02:33:23.117Z" }, + { url = "https://files.pythonhosted.org/packages/55/9d/aa6e887a7033c571b1064429222bbe09adc9a3c1e04f3d1788ba5838ebd5/fastar-0.8.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6ced0a5399cc0a84a858ef0a31ca2d0c24d3bbec4bcda506a9192d8119f3590a", size = 820572, upload-time = "2025-11-26T02:33:37.542Z" }, + { url = "https://files.pythonhosted.org/packages/ad/9c/7a3a2278a1052e1a5d98646de7c095a00cffd2492b3b84ce730e2f1cd93a/fastar-0.8.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec9b23da8c4c039da3fe2e358973c66976a0c8508aa06d6626b4403cb5666c19", size = 820649, upload-time = "2025-11-26T02:34:11.108Z" }, + { url = "https://files.pythonhosted.org/packages/02/9e/d38edc1f4438cd047e56137c26d94783ffade42e1b3bde620ccf17b771ef/fastar-0.8.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:dfba078fcd53478032fd0ceed56960ec6b7ff0511cfc013a8a3a4307e3a7bac4", size = 985653, upload-time = "2025-11-26T02:34:57.884Z" }, + { url = "https://files.pythonhosted.org/packages/69/d9/2147d0c19757e165cd62d41cec3f7b38fad2ad68ab784978b5f81716c7ea/fastar-0.8.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:ade56c94c14be356d295fecb47a3fcd473dd43a8803ead2e2b5b9e58feb6dcfa", size = 1038140, upload-time = "2025-11-26T02:35:15.778Z" }, + { url = "https://files.pythonhosted.org/packages/7f/1d/ec4c717ffb8a308871e9602ec3197d957e238dc0227127ac573ec9bca952/fastar-0.8.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:e48d938f9366db5e59441728f70b7f6c1ccfab7eff84f96f9b7e689b07786c52", size = 1045195, upload-time = "2025-11-26T02:35:32.865Z" }, + { url = "https://files.pythonhosted.org/packages/6a/9f/637334dc8c8f3bb391388b064ae13f0ad9402bc5a6c3e77b8887d0c31921/fastar-0.8.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:79c441dc1482ff51a54fb3f57ae6f7bb3d2cff88fa2cc5d196c519f8aab64a56", size = 994686, upload-time = "2025-11-26T02:35:51.392Z" }, + { url = "https://files.pythonhosted.org/packages/c9/e2/dfa19a4b260b8ab3581b7484dcb80c09b25324f4daa6b6ae1c7640d1607a/fastar-0.8.0-cp314-cp314t-win32.whl", hash = "sha256:187f61dc739afe45ac8e47ed7fd1adc45d52eac110cf27d579155720507d6fbe", size = 455767, upload-time = "2025-11-26T02:36:34.758Z" }, + { url = "https://files.pythonhosted.org/packages/51/47/df65c72afc1297797b255f90c4778b5d6f1f0f80282a134d5ab610310ed9/fastar-0.8.0-cp314-cp314t-win_amd64.whl", hash = "sha256:40e9d763cf8bf85ce2fa256e010aa795c0fe3d3bd1326d5c3084e6ce7857127e", size = 489971, upload-time = "2025-11-26T02:36:22.081Z" }, + { url = "https://files.pythonhosted.org/packages/85/11/0aa8455af26f0ae89e42be67f3a874255ee5d7f0f026fc86e8d56f76b428/fastar-0.8.0-cp314-cp314t-win_arm64.whl", hash = "sha256:e59673307b6a08210987059a2bdea2614fe26e3335d0e5d1a3d95f49a05b1418", size = 460467, upload-time = "2025-11-26T02:36:07.978Z" }, +] + +[[package]] +name = "frozenlist" +version = "1.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2d/f5/c831fac6cc817d26fd54c7eaccd04ef7e0288806943f7cc5bbf69f3ac1f0/frozenlist-1.8.0.tar.gz", hash = "sha256:3ede829ed8d842f6cd48fc7081d7a41001a56f1f38603f9d49bf3020d59a31ad", size = 45875, upload-time = "2025-10-06T05:38:17.865Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2d/40/0832c31a37d60f60ed79e9dfb5a92e1e2af4f40a16a29abcc7992af9edff/frozenlist-1.8.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8d92f1a84bb12d9e56f818b3a746f3efba93c1b63c8387a73dde655e1e42282a", size = 85717, upload-time = "2025-10-06T05:36:27.341Z" }, + { url = "https://files.pythonhosted.org/packages/30/ba/b0b3de23f40bc55a7057bd38434e25c34fa48e17f20ee273bbde5e0650f3/frozenlist-1.8.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:96153e77a591c8adc2ee805756c61f59fef4cf4073a9275ee86fe8cba41241f7", size = 49651, upload-time = "2025-10-06T05:36:28.855Z" }, + { url = "https://files.pythonhosted.org/packages/0c/ab/6e5080ee374f875296c4243c381bbdef97a9ac39c6e3ce1d5f7d42cb78d6/frozenlist-1.8.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f21f00a91358803399890ab167098c131ec2ddd5f8f5fd5fe9c9f2c6fcd91e40", size = 49417, upload-time = "2025-10-06T05:36:29.877Z" }, + { url = "https://files.pythonhosted.org/packages/d5/4e/e4691508f9477ce67da2015d8c00acd751e6287739123113a9fca6f1604e/frozenlist-1.8.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fb30f9626572a76dfe4293c7194a09fb1fe93ba94c7d4f720dfae3b646b45027", size = 234391, upload-time = "2025-10-06T05:36:31.301Z" }, + { url = "https://files.pythonhosted.org/packages/40/76/c202df58e3acdf12969a7895fd6f3bc016c642e6726aa63bd3025e0fc71c/frozenlist-1.8.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eaa352d7047a31d87dafcacbabe89df0aa506abb5b1b85a2fb91bc3faa02d822", size = 233048, upload-time = "2025-10-06T05:36:32.531Z" }, + { url = "https://files.pythonhosted.org/packages/f9/c0/8746afb90f17b73ca5979c7a3958116e105ff796e718575175319b5bb4ce/frozenlist-1.8.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:03ae967b4e297f58f8c774c7eabcce57fe3c2434817d4385c50661845a058121", size = 226549, upload-time = "2025-10-06T05:36:33.706Z" }, + { url = "https://files.pythonhosted.org/packages/7e/eb/4c7eefc718ff72f9b6c4893291abaae5fbc0c82226a32dcd8ef4f7a5dbef/frozenlist-1.8.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f6292f1de555ffcc675941d65fffffb0a5bcd992905015f85d0592201793e0e5", size = 239833, upload-time = "2025-10-06T05:36:34.947Z" }, + { url = "https://files.pythonhosted.org/packages/c2/4e/e5c02187cf704224f8b21bee886f3d713ca379535f16893233b9d672ea71/frozenlist-1.8.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:29548f9b5b5e3460ce7378144c3010363d8035cea44bc0bf02d57f5a685e084e", size = 245363, upload-time = "2025-10-06T05:36:36.534Z" }, + { url = "https://files.pythonhosted.org/packages/1f/96/cb85ec608464472e82ad37a17f844889c36100eed57bea094518bf270692/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ec3cc8c5d4084591b4237c0a272cc4f50a5b03396a47d9caaf76f5d7b38a4f11", size = 229314, upload-time = "2025-10-06T05:36:38.582Z" }, + { url = "https://files.pythonhosted.org/packages/5d/6f/4ae69c550e4cee66b57887daeebe006fe985917c01d0fff9caab9883f6d0/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:517279f58009d0b1f2e7c1b130b377a349405da3f7621ed6bfae50b10adf20c1", size = 243365, upload-time = "2025-10-06T05:36:40.152Z" }, + { url = "https://files.pythonhosted.org/packages/7a/58/afd56de246cf11780a40a2c28dc7cbabbf06337cc8ddb1c780a2d97e88d8/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:db1e72ede2d0d7ccb213f218df6a078a9c09a7de257c2fe8fcef16d5925230b1", size = 237763, upload-time = "2025-10-06T05:36:41.355Z" }, + { url = "https://files.pythonhosted.org/packages/cb/36/cdfaf6ed42e2644740d4a10452d8e97fa1c062e2a8006e4b09f1b5fd7d63/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b4dec9482a65c54a5044486847b8a66bf10c9cb4926d42927ec4e8fd5db7fed8", size = 240110, upload-time = "2025-10-06T05:36:42.716Z" }, + { url = "https://files.pythonhosted.org/packages/03/a8/9ea226fbefad669f11b52e864c55f0bd57d3c8d7eb07e9f2e9a0b39502e1/frozenlist-1.8.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:21900c48ae04d13d416f0e1e0c4d81f7931f73a9dfa0b7a8746fb2fe7dd970ed", size = 233717, upload-time = "2025-10-06T05:36:44.251Z" }, + { url = "https://files.pythonhosted.org/packages/1e/0b/1b5531611e83ba7d13ccc9988967ea1b51186af64c42b7a7af465dcc9568/frozenlist-1.8.0-cp313-cp313-win32.whl", hash = "sha256:8b7b94a067d1c504ee0b16def57ad5738701e4ba10cec90529f13fa03c833496", size = 39628, upload-time = "2025-10-06T05:36:45.423Z" }, + { url = "https://files.pythonhosted.org/packages/d8/cf/174c91dbc9cc49bc7b7aab74d8b734e974d1faa8f191c74af9b7e80848e6/frozenlist-1.8.0-cp313-cp313-win_amd64.whl", hash = "sha256:878be833caa6a3821caf85eb39c5ba92d28e85df26d57afb06b35b2efd937231", size = 43882, upload-time = "2025-10-06T05:36:46.796Z" }, + { url = "https://files.pythonhosted.org/packages/c1/17/502cd212cbfa96eb1388614fe39a3fc9ab87dbbe042b66f97acb57474834/frozenlist-1.8.0-cp313-cp313-win_arm64.whl", hash = "sha256:44389d135b3ff43ba8cc89ff7f51f5a0bb6b63d829c8300f79a2fe4fe61bcc62", size = 39676, upload-time = "2025-10-06T05:36:47.8Z" }, + { url = "https://files.pythonhosted.org/packages/d2/5c/3bbfaa920dfab09e76946a5d2833a7cbdf7b9b4a91c714666ac4855b88b4/frozenlist-1.8.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:e25ac20a2ef37e91c1b39938b591457666a0fa835c7783c3a8f33ea42870db94", size = 89235, upload-time = "2025-10-06T05:36:48.78Z" }, + { url = "https://files.pythonhosted.org/packages/d2/d6/f03961ef72166cec1687e84e8925838442b615bd0b8854b54923ce5b7b8a/frozenlist-1.8.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:07cdca25a91a4386d2e76ad992916a85038a9b97561bf7a3fd12d5d9ce31870c", size = 50742, upload-time = "2025-10-06T05:36:49.837Z" }, + { url = "https://files.pythonhosted.org/packages/1e/bb/a6d12b7ba4c3337667d0e421f7181c82dda448ce4e7ad7ecd249a16fa806/frozenlist-1.8.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4e0c11f2cc6717e0a741f84a527c52616140741cd812a50422f83dc31749fb52", size = 51725, upload-time = "2025-10-06T05:36:50.851Z" }, + { url = "https://files.pythonhosted.org/packages/bc/71/d1fed0ffe2c2ccd70b43714c6cab0f4188f09f8a67a7914a6b46ee30f274/frozenlist-1.8.0-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b3210649ee28062ea6099cfda39e147fa1bc039583c8ee4481cb7811e2448c51", size = 284533, upload-time = "2025-10-06T05:36:51.898Z" }, + { url = "https://files.pythonhosted.org/packages/c9/1f/fb1685a7b009d89f9bf78a42d94461bc06581f6e718c39344754a5d9bada/frozenlist-1.8.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:581ef5194c48035a7de2aefc72ac6539823bb71508189e5de01d60c9dcd5fa65", size = 292506, upload-time = "2025-10-06T05:36:53.101Z" }, + { url = "https://files.pythonhosted.org/packages/e6/3b/b991fe1612703f7e0d05c0cf734c1b77aaf7c7d321df4572e8d36e7048c8/frozenlist-1.8.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3ef2d026f16a2b1866e1d86fc4e1291e1ed8a387b2c333809419a2f8b3a77b82", size = 274161, upload-time = "2025-10-06T05:36:54.309Z" }, + { url = "https://files.pythonhosted.org/packages/ca/ec/c5c618767bcdf66e88945ec0157d7f6c4a1322f1473392319b7a2501ded7/frozenlist-1.8.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5500ef82073f599ac84d888e3a8c1f77ac831183244bfd7f11eaa0289fb30714", size = 294676, upload-time = "2025-10-06T05:36:55.566Z" }, + { url = "https://files.pythonhosted.org/packages/7c/ce/3934758637d8f8a88d11f0585d6495ef54b2044ed6ec84492a91fa3b27aa/frozenlist-1.8.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:50066c3997d0091c411a66e710f4e11752251e6d2d73d70d8d5d4c76442a199d", size = 300638, upload-time = "2025-10-06T05:36:56.758Z" }, + { url = "https://files.pythonhosted.org/packages/fc/4f/a7e4d0d467298f42de4b41cbc7ddaf19d3cfeabaf9ff97c20c6c7ee409f9/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:5c1c8e78426e59b3f8005e9b19f6ff46e5845895adbde20ece9218319eca6506", size = 283067, upload-time = "2025-10-06T05:36:57.965Z" }, + { url = "https://files.pythonhosted.org/packages/dc/48/c7b163063d55a83772b268e6d1affb960771b0e203b632cfe09522d67ea5/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:eefdba20de0d938cec6a89bd4d70f346a03108a19b9df4248d3cf0d88f1b0f51", size = 292101, upload-time = "2025-10-06T05:36:59.237Z" }, + { url = "https://files.pythonhosted.org/packages/9f/d0/2366d3c4ecdc2fd391e0afa6e11500bfba0ea772764d631bbf82f0136c9d/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:cf253e0e1c3ceb4aaff6df637ce033ff6535fb8c70a764a8f46aafd3d6ab798e", size = 289901, upload-time = "2025-10-06T05:37:00.811Z" }, + { url = "https://files.pythonhosted.org/packages/b8/94/daff920e82c1b70e3618a2ac39fbc01ae3e2ff6124e80739ce5d71c9b920/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:032efa2674356903cd0261c4317a561a6850f3ac864a63fc1583147fb05a79b0", size = 289395, upload-time = "2025-10-06T05:37:02.115Z" }, + { url = "https://files.pythonhosted.org/packages/e3/20/bba307ab4235a09fdcd3cc5508dbabd17c4634a1af4b96e0f69bfe551ebd/frozenlist-1.8.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6da155091429aeba16851ecb10a9104a108bcd32f6c1642867eadaee401c1c41", size = 283659, upload-time = "2025-10-06T05:37:03.711Z" }, + { url = "https://files.pythonhosted.org/packages/fd/00/04ca1c3a7a124b6de4f8a9a17cc2fcad138b4608e7a3fc5877804b8715d7/frozenlist-1.8.0-cp313-cp313t-win32.whl", hash = "sha256:0f96534f8bfebc1a394209427d0f8a63d343c9779cda6fc25e8e121b5fd8555b", size = 43492, upload-time = "2025-10-06T05:37:04.915Z" }, + { url = "https://files.pythonhosted.org/packages/59/5e/c69f733a86a94ab10f68e496dc6b7e8bc078ebb415281d5698313e3af3a1/frozenlist-1.8.0-cp313-cp313t-win_amd64.whl", hash = "sha256:5d63a068f978fc69421fb0e6eb91a9603187527c86b7cd3f534a5b77a592b888", size = 48034, upload-time = "2025-10-06T05:37:06.343Z" }, + { url = "https://files.pythonhosted.org/packages/16/6c/be9d79775d8abe79b05fa6d23da99ad6e7763a1d080fbae7290b286093fd/frozenlist-1.8.0-cp313-cp313t-win_arm64.whl", hash = "sha256:bf0a7e10b077bf5fb9380ad3ae8ce20ef919a6ad93b4552896419ac7e1d8e042", size = 41749, upload-time = "2025-10-06T05:37:07.431Z" }, + { url = "https://files.pythonhosted.org/packages/f1/c8/85da824b7e7b9b6e7f7705b2ecaf9591ba6f79c1177f324c2735e41d36a2/frozenlist-1.8.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:cee686f1f4cadeb2136007ddedd0aaf928ab95216e7691c63e50a8ec066336d0", size = 86127, upload-time = "2025-10-06T05:37:08.438Z" }, + { url = "https://files.pythonhosted.org/packages/8e/e8/a1185e236ec66c20afd72399522f142c3724c785789255202d27ae992818/frozenlist-1.8.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:119fb2a1bd47307e899c2fac7f28e85b9a543864df47aa7ec9d3c1b4545f096f", size = 49698, upload-time = "2025-10-06T05:37:09.48Z" }, + { url = "https://files.pythonhosted.org/packages/a1/93/72b1736d68f03fda5fdf0f2180fb6caaae3894f1b854d006ac61ecc727ee/frozenlist-1.8.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:4970ece02dbc8c3a92fcc5228e36a3e933a01a999f7094ff7c23fbd2beeaa67c", size = 49749, upload-time = "2025-10-06T05:37:10.569Z" }, + { url = "https://files.pythonhosted.org/packages/a7/b2/fabede9fafd976b991e9f1b9c8c873ed86f202889b864756f240ce6dd855/frozenlist-1.8.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:cba69cb73723c3f329622e34bdbf5ce1f80c21c290ff04256cff1cd3c2036ed2", size = 231298, upload-time = "2025-10-06T05:37:11.993Z" }, + { url = "https://files.pythonhosted.org/packages/3a/3b/d9b1e0b0eed36e70477ffb8360c49c85c8ca8ef9700a4e6711f39a6e8b45/frozenlist-1.8.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:778a11b15673f6f1df23d9586f83c4846c471a8af693a22e066508b77d201ec8", size = 232015, upload-time = "2025-10-06T05:37:13.194Z" }, + { url = "https://files.pythonhosted.org/packages/dc/94/be719d2766c1138148564a3960fc2c06eb688da592bdc25adcf856101be7/frozenlist-1.8.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:0325024fe97f94c41c08872db482cf8ac4800d80e79222c6b0b7b162d5b13686", size = 225038, upload-time = "2025-10-06T05:37:14.577Z" }, + { url = "https://files.pythonhosted.org/packages/e4/09/6712b6c5465f083f52f50cf74167b92d4ea2f50e46a9eea0523d658454ae/frozenlist-1.8.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:97260ff46b207a82a7567b581ab4190bd4dfa09f4db8a8b49d1a958f6aa4940e", size = 240130, upload-time = "2025-10-06T05:37:15.781Z" }, + { url = "https://files.pythonhosted.org/packages/f8/d4/cd065cdcf21550b54f3ce6a22e143ac9e4836ca42a0de1022da8498eac89/frozenlist-1.8.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:54b2077180eb7f83dd52c40b2750d0a9f175e06a42e3213ce047219de902717a", size = 242845, upload-time = "2025-10-06T05:37:17.037Z" }, + { url = "https://files.pythonhosted.org/packages/62/c3/f57a5c8c70cd1ead3d5d5f776f89d33110b1addae0ab010ad774d9a44fb9/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2f05983daecab868a31e1da44462873306d3cbfd76d1f0b5b69c473d21dbb128", size = 229131, upload-time = "2025-10-06T05:37:18.221Z" }, + { url = "https://files.pythonhosted.org/packages/6c/52/232476fe9cb64f0742f3fde2b7d26c1dac18b6d62071c74d4ded55e0ef94/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:33f48f51a446114bc5d251fb2954ab0164d5be02ad3382abcbfe07e2531d650f", size = 240542, upload-time = "2025-10-06T05:37:19.771Z" }, + { url = "https://files.pythonhosted.org/packages/5f/85/07bf3f5d0fb5414aee5f47d33c6f5c77bfe49aac680bfece33d4fdf6a246/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:154e55ec0655291b5dd1b8731c637ecdb50975a2ae70c606d100750a540082f7", size = 237308, upload-time = "2025-10-06T05:37:20.969Z" }, + { url = "https://files.pythonhosted.org/packages/11/99/ae3a33d5befd41ac0ca2cc7fd3aa707c9c324de2e89db0e0f45db9a64c26/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:4314debad13beb564b708b4a496020e5306c7333fa9a3ab90374169a20ffab30", size = 238210, upload-time = "2025-10-06T05:37:22.252Z" }, + { url = "https://files.pythonhosted.org/packages/b2/60/b1d2da22f4970e7a155f0adde9b1435712ece01b3cd45ba63702aea33938/frozenlist-1.8.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:073f8bf8becba60aa931eb3bc420b217bb7d5b8f4750e6f8b3be7f3da85d38b7", size = 231972, upload-time = "2025-10-06T05:37:23.5Z" }, + { url = "https://files.pythonhosted.org/packages/3f/ab/945b2f32de889993b9c9133216c068b7fcf257d8595a0ac420ac8677cab0/frozenlist-1.8.0-cp314-cp314-win32.whl", hash = "sha256:bac9c42ba2ac65ddc115d930c78d24ab8d4f465fd3fc473cdedfccadb9429806", size = 40536, upload-time = "2025-10-06T05:37:25.581Z" }, + { url = "https://files.pythonhosted.org/packages/59/ad/9caa9b9c836d9ad6f067157a531ac48b7d36499f5036d4141ce78c230b1b/frozenlist-1.8.0-cp314-cp314-win_amd64.whl", hash = "sha256:3e0761f4d1a44f1d1a47996511752cf3dcec5bbdd9cc2b4fe595caf97754b7a0", size = 44330, upload-time = "2025-10-06T05:37:26.928Z" }, + { url = "https://files.pythonhosted.org/packages/82/13/e6950121764f2676f43534c555249f57030150260aee9dcf7d64efda11dd/frozenlist-1.8.0-cp314-cp314-win_arm64.whl", hash = "sha256:d1eaff1d00c7751b7c6662e9c5ba6eb2c17a2306ba5e2a37f24ddf3cc953402b", size = 40627, upload-time = "2025-10-06T05:37:28.075Z" }, + { url = "https://files.pythonhosted.org/packages/c0/c7/43200656ecc4e02d3f8bc248df68256cd9572b3f0017f0a0c4e93440ae23/frozenlist-1.8.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:d3bb933317c52d7ea5004a1c442eef86f426886fba134ef8cf4226ea6ee1821d", size = 89238, upload-time = "2025-10-06T05:37:29.373Z" }, + { url = "https://files.pythonhosted.org/packages/d1/29/55c5f0689b9c0fb765055629f472c0de484dcaf0acee2f7707266ae3583c/frozenlist-1.8.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:8009897cdef112072f93a0efdce29cd819e717fd2f649ee3016efd3cd885a7ed", size = 50738, upload-time = "2025-10-06T05:37:30.792Z" }, + { url = "https://files.pythonhosted.org/packages/ba/7d/b7282a445956506fa11da8c2db7d276adcbf2b17d8bb8407a47685263f90/frozenlist-1.8.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2c5dcbbc55383e5883246d11fd179782a9d07a986c40f49abe89ddf865913930", size = 51739, upload-time = "2025-10-06T05:37:32.127Z" }, + { url = "https://files.pythonhosted.org/packages/62/1c/3d8622e60d0b767a5510d1d3cf21065b9db874696a51ea6d7a43180a259c/frozenlist-1.8.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:39ecbc32f1390387d2aa4f5a995e465e9e2f79ba3adcac92d68e3e0afae6657c", size = 284186, upload-time = "2025-10-06T05:37:33.21Z" }, + { url = "https://files.pythonhosted.org/packages/2d/14/aa36d5f85a89679a85a1d44cd7a6657e0b1c75f61e7cad987b203d2daca8/frozenlist-1.8.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92db2bf818d5cc8d9c1f1fc56b897662e24ea5adb36ad1f1d82875bd64e03c24", size = 292196, upload-time = "2025-10-06T05:37:36.107Z" }, + { url = "https://files.pythonhosted.org/packages/05/23/6bde59eb55abd407d34f77d39a5126fb7b4f109a3f611d3929f14b700c66/frozenlist-1.8.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2dc43a022e555de94c3b68a4ef0b11c4f747d12c024a520c7101709a2144fb37", size = 273830, upload-time = "2025-10-06T05:37:37.663Z" }, + { url = "https://files.pythonhosted.org/packages/d2/3f/22cff331bfad7a8afa616289000ba793347fcd7bc275f3b28ecea2a27909/frozenlist-1.8.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cb89a7f2de3602cfed448095bab3f178399646ab7c61454315089787df07733a", size = 294289, upload-time = "2025-10-06T05:37:39.261Z" }, + { url = "https://files.pythonhosted.org/packages/a4/89/5b057c799de4838b6c69aa82b79705f2027615e01be996d2486a69ca99c4/frozenlist-1.8.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:33139dc858c580ea50e7e60a1b0ea003efa1fd42e6ec7fdbad78fff65fad2fd2", size = 300318, upload-time = "2025-10-06T05:37:43.213Z" }, + { url = "https://files.pythonhosted.org/packages/30/de/2c22ab3eb2a8af6d69dc799e48455813bab3690c760de58e1bf43b36da3e/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:168c0969a329b416119507ba30b9ea13688fafffac1b7822802537569a1cb0ef", size = 282814, upload-time = "2025-10-06T05:37:45.337Z" }, + { url = "https://files.pythonhosted.org/packages/59/f7/970141a6a8dbd7f556d94977858cfb36fa9b66e0892c6dd780d2219d8cd8/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:28bd570e8e189d7f7b001966435f9dac6718324b5be2990ac496cf1ea9ddb7fe", size = 291762, upload-time = "2025-10-06T05:37:46.657Z" }, + { url = "https://files.pythonhosted.org/packages/c1/15/ca1adae83a719f82df9116d66f5bb28bb95557b3951903d39135620ef157/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:b2a095d45c5d46e5e79ba1e5b9cb787f541a8dee0433836cea4b96a2c439dcd8", size = 289470, upload-time = "2025-10-06T05:37:47.946Z" }, + { url = "https://files.pythonhosted.org/packages/ac/83/dca6dc53bf657d371fbc88ddeb21b79891e747189c5de990b9dfff2ccba1/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:eab8145831a0d56ec9c4139b6c3e594c7a83c2c8be25d5bcf2d86136a532287a", size = 289042, upload-time = "2025-10-06T05:37:49.499Z" }, + { url = "https://files.pythonhosted.org/packages/96/52/abddd34ca99be142f354398700536c5bd315880ed0a213812bc491cff5e4/frozenlist-1.8.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:974b28cf63cc99dfb2188d8d222bc6843656188164848c4f679e63dae4b0708e", size = 283148, upload-time = "2025-10-06T05:37:50.745Z" }, + { url = "https://files.pythonhosted.org/packages/af/d3/76bd4ed4317e7119c2b7f57c3f6934aba26d277acc6309f873341640e21f/frozenlist-1.8.0-cp314-cp314t-win32.whl", hash = "sha256:342c97bf697ac5480c0a7ec73cd700ecfa5a8a40ac923bd035484616efecc2df", size = 44676, upload-time = "2025-10-06T05:37:52.222Z" }, + { url = "https://files.pythonhosted.org/packages/89/76/c615883b7b521ead2944bb3480398cbb07e12b7b4e4d073d3752eb721558/frozenlist-1.8.0-cp314-cp314t-win_amd64.whl", hash = "sha256:06be8f67f39c8b1dc671f5d83aaefd3358ae5cdcf8314552c57e7ed3e6475bdd", size = 49451, upload-time = "2025-10-06T05:37:53.425Z" }, + { url = "https://files.pythonhosted.org/packages/e0/a3/5982da14e113d07b325230f95060e2169f5311b1017ea8af2a29b374c289/frozenlist-1.8.0-cp314-cp314t-win_arm64.whl", hash = "sha256:102e6314ca4da683dca92e3b1355490fed5f313b768500084fbe6371fddfdb79", size = 42507, upload-time = "2025-10-06T05:37:54.513Z" }, + { url = "https://files.pythonhosted.org/packages/9a/9a/e35b4a917281c0b8419d4207f4334c8e8c5dbf4f3f5f9ada73958d937dcc/frozenlist-1.8.0-py3-none-any.whl", hash = "sha256:0c18a16eab41e82c295618a77502e17b195883241c563b00f0aa5106fc4eaa0d", size = 13409, upload-time = "2025-10-06T05:38:16.721Z" }, +] + +[[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, upload-time = "2025-12-04T14:49:44.05Z" } +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, upload-time = "2025-12-04T14:23:01.282Z" }, + { 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, upload-time = "2025-12-04T14:50:08.309Z" }, + { 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, upload-time = "2025-12-04T14:57:43.968Z" }, + { 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, upload-time = "2025-12-04T15:07:14.697Z" }, + { 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, upload-time = "2025-12-04T14:26:03.669Z" }, + { 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, upload-time = "2025-12-04T15:04:25.276Z" }, + { 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, upload-time = "2025-12-04T14:27:30.804Z" }, + { url = "https://files.pythonhosted.org/packages/7e/71/ba21c3fb8c5dce83b8c01f458a42e99ffdb1963aeec08fff5a18588d8fd7/greenlet-3.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:9ee1942ea19550094033c35d25d20726e4f1c40d59545815e1128ac58d416d38", size = 301833, upload-time = "2025-12-04T14:32:23.929Z" }, + { 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, upload-time = "2025-12-04T14:23:05.267Z" }, + { 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, upload-time = "2025-12-04T14:50:10.026Z" }, + { 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, upload-time = "2025-12-04T14:57:45.41Z" }, + { 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, upload-time = "2025-12-04T15:07:15.789Z" }, + { 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, upload-time = "2025-12-04T14:26:05.099Z" }, + { 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, upload-time = "2025-12-04T15:04:27.041Z" }, + { 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, upload-time = "2025-12-04T14:27:32.366Z" }, + { url = "https://files.pythonhosted.org/packages/7c/9a/9030e6f9aa8fd7808e9c31ba4c38f87c4f8ec324ee67431d181fe396d705/greenlet-3.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:73f51dd0e0bdb596fb0417e475fa3c5e32d4c83638296e560086b8d7da7c4170", size = 305387, upload-time = "2025-12-04T14:26:51.063Z" }, + { 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, upload-time = "2025-12-04T14:25:20.941Z" }, + { 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, upload-time = "2025-12-04T14:50:11.039Z" }, + { 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, upload-time = "2025-12-04T14:57:47.007Z" }, + { 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, upload-time = "2025-12-04T15:07:16.906Z" }, + { 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, upload-time = "2025-12-04T14:26:06.225Z" }, + { 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, upload-time = "2025-12-04T15:04:28.484Z" }, + { 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, upload-time = "2025-12-04T14:27:33.531Z" }, +] + +[[package]] +name = "h11" +version = "0.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, +] + +[[package]] +name = "httpcore" +version = "1.0.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "h11" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" }, +] + +[[package]] +name = "httptools" +version = "0.7.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b5/46/120a669232c7bdedb9d52d4aeae7e6c7dfe151e99dc70802e2fc7a5e1993/httptools-0.7.1.tar.gz", hash = "sha256:abd72556974f8e7c74a259655924a717a2365b236c882c3f6f8a45fe94703ac9", size = 258961, upload-time = "2025-10-10T03:55:08.559Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/09/8f/c77b1fcbfd262d422f12da02feb0d218fa228d52485b77b953832105bb90/httptools-0.7.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6babce6cfa2a99545c60bfef8bee0cc0545413cb0018f617c8059a30ad985de3", size = 202889, upload-time = "2025-10-10T03:54:47.089Z" }, + { url = "https://files.pythonhosted.org/packages/0a/1a/22887f53602feaa066354867bc49a68fc295c2293433177ee90870a7d517/httptools-0.7.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:601b7628de7504077dd3dcb3791c6b8694bbd967148a6d1f01806509254fb1ca", size = 108180, upload-time = "2025-10-10T03:54:48.052Z" }, + { url = "https://files.pythonhosted.org/packages/32/6a/6aaa91937f0010d288d3d124ca2946d48d60c3a5ee7ca62afe870e3ea011/httptools-0.7.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:04c6c0e6c5fb0739c5b8a9eb046d298650a0ff38cf42537fc372b28dc7e4472c", size = 478596, upload-time = "2025-10-10T03:54:48.919Z" }, + { url = "https://files.pythonhosted.org/packages/6d/70/023d7ce117993107be88d2cbca566a7c1323ccbaf0af7eabf2064fe356f6/httptools-0.7.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:69d4f9705c405ae3ee83d6a12283dc9feba8cc6aaec671b412917e644ab4fa66", size = 473268, upload-time = "2025-10-10T03:54:49.993Z" }, + { url = "https://files.pythonhosted.org/packages/32/4d/9dd616c38da088e3f436e9a616e1d0cc66544b8cdac405cc4e81c8679fc7/httptools-0.7.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:44c8f4347d4b31269c8a9205d8a5ee2df5322b09bbbd30f8f862185bb6b05346", size = 455517, upload-time = "2025-10-10T03:54:51.066Z" }, + { url = "https://files.pythonhosted.org/packages/1d/3a/a6c595c310b7df958e739aae88724e24f9246a514d909547778d776799be/httptools-0.7.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:465275d76db4d554918aba40bf1cbebe324670f3dfc979eaffaa5d108e2ed650", size = 458337, upload-time = "2025-10-10T03:54:52.196Z" }, + { url = "https://files.pythonhosted.org/packages/fd/82/88e8d6d2c51edc1cc391b6e044c6c435b6aebe97b1abc33db1b0b24cd582/httptools-0.7.1-cp313-cp313-win_amd64.whl", hash = "sha256:322d00c2068d125bd570f7bf78b2d367dad02b919d8581d7476d8b75b294e3e6", size = 85743, upload-time = "2025-10-10T03:54:53.448Z" }, + { url = "https://files.pythonhosted.org/packages/34/50/9d095fcbb6de2d523e027a2f304d4551855c2f46e0b82befd718b8b20056/httptools-0.7.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:c08fe65728b8d70b6923ce31e3956f859d5e1e8548e6f22ec520a962c6757270", size = 203619, upload-time = "2025-10-10T03:54:54.321Z" }, + { url = "https://files.pythonhosted.org/packages/07/f0/89720dc5139ae54b03f861b5e2c55a37dba9a5da7d51e1e824a1f343627f/httptools-0.7.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:7aea2e3c3953521c3c51106ee11487a910d45586e351202474d45472db7d72d3", size = 108714, upload-time = "2025-10-10T03:54:55.163Z" }, + { url = "https://files.pythonhosted.org/packages/b3/cb/eea88506f191fb552c11787c23f9a405f4c7b0c5799bf73f2249cd4f5228/httptools-0.7.1-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0e68b8582f4ea9166be62926077a3334064d422cf08ab87d8b74664f8e9058e1", size = 472909, upload-time = "2025-10-10T03:54:56.056Z" }, + { url = "https://files.pythonhosted.org/packages/e0/4a/a548bdfae6369c0d078bab5769f7b66f17f1bfaa6fa28f81d6be6959066b/httptools-0.7.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:df091cf961a3be783d6aebae963cc9b71e00d57fa6f149025075217bc6a55a7b", size = 470831, upload-time = "2025-10-10T03:54:57.219Z" }, + { url = "https://files.pythonhosted.org/packages/4d/31/14df99e1c43bd132eec921c2e7e11cda7852f65619bc0fc5bdc2d0cb126c/httptools-0.7.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f084813239e1eb403ddacd06a30de3d3e09a9b76e7894dcda2b22f8a726e9c60", size = 452631, upload-time = "2025-10-10T03:54:58.219Z" }, + { url = "https://files.pythonhosted.org/packages/22/d2/b7e131f7be8d854d48cb6d048113c30f9a46dca0c9a8b08fcb3fcd588cdc/httptools-0.7.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7347714368fb2b335e9063bc2b96f2f87a9ceffcd9758ac295f8bbcd3ffbc0ca", size = 452910, upload-time = "2025-10-10T03:54:59.366Z" }, + { url = "https://files.pythonhosted.org/packages/53/cf/878f3b91e4e6e011eff6d1fa9ca39f7eb17d19c9d7971b04873734112f30/httptools-0.7.1-cp314-cp314-win_amd64.whl", hash = "sha256:cfabda2a5bb85aa2a904ce06d974a3f30fb36cc63d7feaddec05d2050acede96", size = 88205, upload-time = "2025-10-10T03:55:00.389Z" }, +] + +[[package]] +name = "httpx" +version = "0.28.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "certifi" }, + { name = "httpcore" }, + { name = "idna" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" }, +] + +[[package]] +name = "idna" +version = "3.11" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/0703ccc57f3a7233505399edb88de3cbd678da106337b9fcde432b65ed60/idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902", size = 194582, upload-time = "2025-10-12T14:55:20.501Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea", size = 71008, upload-time = "2025-10-12T14:55:18.883Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, +] + +[[package]] +name = "itsdangerous" +version = "2.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9c/cb/8ac0172223afbccb63986cc25049b154ecfb5e85932587206f42317be31d/itsdangerous-2.2.0.tar.gz", hash = "sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173", size = 54410, upload-time = "2024-04-16T21:28:15.614Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/96/92447566d16df59b2a776c0fb82dbc4d9e07cd95062562af01e408583fc4/itsdangerous-2.2.0-py3-none-any.whl", hash = "sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef", size = 16234, upload-time = "2024-04-16T21:28:14.499Z" }, +] + +[[package]] +name = "jinja2" +version = "3.1.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, +] + +[[package]] +name = "jiter" +version = "0.12.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/45/9d/e0660989c1370e25848bb4c52d061c71837239738ad937e83edca174c273/jiter-0.12.0.tar.gz", hash = "sha256:64dfcd7d5c168b38d3f9f8bba7fc639edb3418abcc74f22fdbe6b8938293f30b", size = 168294, upload-time = "2025-11-09T20:49:23.302Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3d/a6/97209693b177716e22576ee1161674d1d58029eb178e01866a0422b69224/jiter-0.12.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:6cc49d5130a14b732e0612bc76ae8db3b49898732223ef8b7599aa8d9810683e", size = 313658, upload-time = "2025-11-09T20:47:44.424Z" }, + { url = "https://files.pythonhosted.org/packages/06/4d/125c5c1537c7d8ee73ad3d530a442d6c619714b95027143f1b61c0b4dfe0/jiter-0.12.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:37f27a32ce36364d2fa4f7fdc507279db604d27d239ea2e044c8f148410defe1", size = 318605, upload-time = "2025-11-09T20:47:45.973Z" }, + { url = "https://files.pythonhosted.org/packages/99/bf/a840b89847885064c41a5f52de6e312e91fa84a520848ee56c97e4fa0205/jiter-0.12.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bbc0944aa3d4b4773e348cda635252824a78f4ba44328e042ef1ff3f6080d1cf", size = 349803, upload-time = "2025-11-09T20:47:47.535Z" }, + { url = "https://files.pythonhosted.org/packages/8a/88/e63441c28e0db50e305ae23e19c1d8fae012d78ed55365da392c1f34b09c/jiter-0.12.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:da25c62d4ee1ffbacb97fac6dfe4dcd6759ebdc9015991e92a6eae5816287f44", size = 365120, upload-time = "2025-11-09T20:47:49.284Z" }, + { url = "https://files.pythonhosted.org/packages/0a/7c/49b02714af4343970eb8aca63396bc1c82fa01197dbb1e9b0d274b550d4e/jiter-0.12.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:048485c654b838140b007390b8182ba9774621103bd4d77c9c3f6f117474ba45", size = 479918, upload-time = "2025-11-09T20:47:50.807Z" }, + { url = "https://files.pythonhosted.org/packages/69/ba/0a809817fdd5a1db80490b9150645f3aae16afad166960bcd562be194f3b/jiter-0.12.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:635e737fbb7315bef0037c19b88b799143d2d7d3507e61a76751025226b3ac87", size = 379008, upload-time = "2025-11-09T20:47:52.211Z" }, + { url = "https://files.pythonhosted.org/packages/5f/c3/c9fc0232e736c8877d9e6d83d6eeb0ba4e90c6c073835cc2e8f73fdeef51/jiter-0.12.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e017c417b1ebda911bd13b1e40612704b1f5420e30695112efdbed8a4b389ed", size = 361785, upload-time = "2025-11-09T20:47:53.512Z" }, + { url = "https://files.pythonhosted.org/packages/96/61/61f69b7e442e97ca6cd53086ddc1cf59fb830549bc72c0a293713a60c525/jiter-0.12.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:89b0bfb8b2bf2351fba36bb211ef8bfceba73ef58e7f0c68fb67b5a2795ca2f9", size = 386108, upload-time = "2025-11-09T20:47:54.893Z" }, + { url = "https://files.pythonhosted.org/packages/e9/2e/76bb3332f28550c8f1eba3bf6e5efe211efda0ddbbaf24976bc7078d42a5/jiter-0.12.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:f5aa5427a629a824a543672778c9ce0c5e556550d1569bb6ea28a85015287626", size = 519937, upload-time = "2025-11-09T20:47:56.253Z" }, + { url = "https://files.pythonhosted.org/packages/84/d6/fa96efa87dc8bff2094fb947f51f66368fa56d8d4fc9e77b25d7fbb23375/jiter-0.12.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed53b3d6acbcb0fd0b90f20c7cb3b24c357fe82a3518934d4edfa8c6898e498c", size = 510853, upload-time = "2025-11-09T20:47:58.32Z" }, + { url = "https://files.pythonhosted.org/packages/8a/28/93f67fdb4d5904a708119a6ab58a8f1ec226ff10a94a282e0215402a8462/jiter-0.12.0-cp313-cp313-win32.whl", hash = "sha256:4747de73d6b8c78f2e253a2787930f4fffc68da7fa319739f57437f95963c4de", size = 204699, upload-time = "2025-11-09T20:47:59.686Z" }, + { url = "https://files.pythonhosted.org/packages/c4/1f/30b0eb087045a0abe2a5c9c0c0c8da110875a1d3be83afd4a9a4e548be3c/jiter-0.12.0-cp313-cp313-win_amd64.whl", hash = "sha256:e25012eb0c456fcc13354255d0338cd5397cce26c77b2832b3c4e2e255ea5d9a", size = 204258, upload-time = "2025-11-09T20:48:01.01Z" }, + { url = "https://files.pythonhosted.org/packages/2c/f4/2b4daf99b96bce6fc47971890b14b2a36aef88d7beb9f057fafa032c6141/jiter-0.12.0-cp313-cp313-win_arm64.whl", hash = "sha256:c97b92c54fe6110138c872add030a1f99aea2401ddcdaa21edf74705a646dd60", size = 185503, upload-time = "2025-11-09T20:48:02.35Z" }, + { url = "https://files.pythonhosted.org/packages/39/ca/67bb15a7061d6fe20b9b2a2fd783e296a1e0f93468252c093481a2f00efa/jiter-0.12.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:53839b35a38f56b8be26a7851a48b89bc47e5d88e900929df10ed93b95fea3d6", size = 317965, upload-time = "2025-11-09T20:48:03.783Z" }, + { url = "https://files.pythonhosted.org/packages/18/af/1788031cd22e29c3b14bc6ca80b16a39a0b10e611367ffd480c06a259831/jiter-0.12.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94f669548e55c91ab47fef8bddd9c954dab1938644e715ea49d7e117015110a4", size = 345831, upload-time = "2025-11-09T20:48:05.55Z" }, + { url = "https://files.pythonhosted.org/packages/05/17/710bf8472d1dff0d3caf4ced6031060091c1320f84ee7d5dcbed1f352417/jiter-0.12.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:351d54f2b09a41600ffea43d081522d792e81dcfb915f6d2d242744c1cc48beb", size = 361272, upload-time = "2025-11-09T20:48:06.951Z" }, + { url = "https://files.pythonhosted.org/packages/fb/f1/1dcc4618b59761fef92d10bcbb0b038b5160be653b003651566a185f1a5c/jiter-0.12.0-cp313-cp313t-win_amd64.whl", hash = "sha256:2a5e90604620f94bf62264e7c2c038704d38217b7465b863896c6d7c902b06c7", size = 204604, upload-time = "2025-11-09T20:48:08.328Z" }, + { url = "https://files.pythonhosted.org/packages/d9/32/63cb1d9f1c5c6632a783c0052cde9ef7ba82688f7065e2f0d5f10a7e3edb/jiter-0.12.0-cp313-cp313t-win_arm64.whl", hash = "sha256:88ef757017e78d2860f96250f9393b7b577b06a956ad102c29c8237554380db3", size = 185628, upload-time = "2025-11-09T20:48:09.572Z" }, + { url = "https://files.pythonhosted.org/packages/a8/99/45c9f0dbe4a1416b2b9a8a6d1236459540f43d7fb8883cff769a8db0612d/jiter-0.12.0-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:c46d927acd09c67a9fb1416df45c5a04c27e83aae969267e98fba35b74e99525", size = 312478, upload-time = "2025-11-09T20:48:10.898Z" }, + { url = "https://files.pythonhosted.org/packages/4c/a7/54ae75613ba9e0f55fcb0bc5d1f807823b5167cc944e9333ff322e9f07dd/jiter-0.12.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:774ff60b27a84a85b27b88cd5583899c59940bcc126caca97eb2a9df6aa00c49", size = 318706, upload-time = "2025-11-09T20:48:12.266Z" }, + { url = "https://files.pythonhosted.org/packages/59/31/2aa241ad2c10774baf6c37f8b8e1f39c07db358f1329f4eb40eba179c2a2/jiter-0.12.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5433fab222fb072237df3f637d01b81f040a07dcac1cb4a5c75c7aa9ed0bef1", size = 351894, upload-time = "2025-11-09T20:48:13.673Z" }, + { url = "https://files.pythonhosted.org/packages/54/4f/0f2759522719133a9042781b18cc94e335b6d290f5e2d3e6899d6af933e3/jiter-0.12.0-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f8c593c6e71c07866ec6bfb790e202a833eeec885022296aff6b9e0b92d6a70e", size = 365714, upload-time = "2025-11-09T20:48:15.083Z" }, + { url = "https://files.pythonhosted.org/packages/dc/6f/806b895f476582c62a2f52c453151edd8a0fde5411b0497baaa41018e878/jiter-0.12.0-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:90d32894d4c6877a87ae00c6b915b609406819dce8bc0d4e962e4de2784e567e", size = 478989, upload-time = "2025-11-09T20:48:16.706Z" }, + { url = "https://files.pythonhosted.org/packages/86/6c/012d894dc6e1033acd8db2b8346add33e413ec1c7c002598915278a37f79/jiter-0.12.0-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:798e46eed9eb10c3adbbacbd3bdb5ecd4cf7064e453d00dbef08802dae6937ff", size = 378615, upload-time = "2025-11-09T20:48:18.614Z" }, + { url = "https://files.pythonhosted.org/packages/87/30/d718d599f6700163e28e2c71c0bbaf6dace692e7df2592fd793ac9276717/jiter-0.12.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3f1368f0a6719ea80013a4eb90ba72e75d7ea67cfc7846db2ca504f3df0169a", size = 364745, upload-time = "2025-11-09T20:48:20.117Z" }, + { url = "https://files.pythonhosted.org/packages/8f/85/315b45ce4b6ddc7d7fceca24068543b02bdc8782942f4ee49d652e2cc89f/jiter-0.12.0-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:65f04a9d0b4406f7e51279710b27484af411896246200e461d80d3ba0caa901a", size = 386502, upload-time = "2025-11-09T20:48:21.543Z" }, + { url = "https://files.pythonhosted.org/packages/74/0b/ce0434fb40c5b24b368fe81b17074d2840748b4952256bab451b72290a49/jiter-0.12.0-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:fd990541982a24281d12b67a335e44f117e4c6cbad3c3b75c7dea68bf4ce3a67", size = 519845, upload-time = "2025-11-09T20:48:22.964Z" }, + { url = "https://files.pythonhosted.org/packages/e8/a3/7a7a4488ba052767846b9c916d208b3ed114e3eb670ee984e4c565b9cf0d/jiter-0.12.0-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:b111b0e9152fa7df870ecaebb0bd30240d9f7fff1f2003bcb4ed0f519941820b", size = 510701, upload-time = "2025-11-09T20:48:24.483Z" }, + { url = "https://files.pythonhosted.org/packages/c3/16/052ffbf9d0467b70af24e30f91e0579e13ded0c17bb4a8eb2aed3cb60131/jiter-0.12.0-cp314-cp314-win32.whl", hash = "sha256:a78befb9cc0a45b5a5a0d537b06f8544c2ebb60d19d02c41ff15da28a9e22d42", size = 205029, upload-time = "2025-11-09T20:48:25.749Z" }, + { url = "https://files.pythonhosted.org/packages/e4/18/3cf1f3f0ccc789f76b9a754bdb7a6977e5d1d671ee97a9e14f7eb728d80e/jiter-0.12.0-cp314-cp314-win_amd64.whl", hash = "sha256:e1fe01c082f6aafbe5c8faf0ff074f38dfb911d53f07ec333ca03f8f6226debf", size = 204960, upload-time = "2025-11-09T20:48:27.415Z" }, + { url = "https://files.pythonhosted.org/packages/02/68/736821e52ecfdeeb0f024b8ab01b5a229f6b9293bbdb444c27efade50b0f/jiter-0.12.0-cp314-cp314-win_arm64.whl", hash = "sha256:d72f3b5a432a4c546ea4bedc84cce0c3404874f1d1676260b9c7f048a9855451", size = 185529, upload-time = "2025-11-09T20:48:29.125Z" }, + { url = "https://files.pythonhosted.org/packages/30/61/12ed8ee7a643cce29ac97c2281f9ce3956eb76b037e88d290f4ed0d41480/jiter-0.12.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:e6ded41aeba3603f9728ed2b6196e4df875348ab97b28fc8afff115ed42ba7a7", size = 318974, upload-time = "2025-11-09T20:48:30.87Z" }, + { url = "https://files.pythonhosted.org/packages/2d/c6/f3041ede6d0ed5e0e79ff0de4c8f14f401bbf196f2ef3971cdbe5fd08d1d/jiter-0.12.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a947920902420a6ada6ad51892082521978e9dd44a802663b001436e4b771684", size = 345932, upload-time = "2025-11-09T20:48:32.658Z" }, + { url = "https://files.pythonhosted.org/packages/d5/5d/4d94835889edd01ad0e2dbfc05f7bdfaed46292e7b504a6ac7839aa00edb/jiter-0.12.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:add5e227e0554d3a52cf390a7635edaffdf4f8fce4fdbcef3cc2055bb396a30c", size = 367243, upload-time = "2025-11-09T20:48:34.093Z" }, + { url = "https://files.pythonhosted.org/packages/fd/76/0051b0ac2816253a99d27baf3dda198663aff882fa6ea7deeb94046da24e/jiter-0.12.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f9b1cda8fcb736250d7e8711d4580ebf004a46771432be0ae4796944b5dfa5d", size = 479315, upload-time = "2025-11-09T20:48:35.507Z" }, + { url = "https://files.pythonhosted.org/packages/70/ae/83f793acd68e5cb24e483f44f482a1a15601848b9b6f199dacb970098f77/jiter-0.12.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:deeb12a2223fe0135c7ff1356a143d57f95bbf1f4a66584f1fc74df21d86b993", size = 380714, upload-time = "2025-11-09T20:48:40.014Z" }, + { url = "https://files.pythonhosted.org/packages/b1/5e/4808a88338ad2c228b1126b93fcd8ba145e919e886fe910d578230dabe3b/jiter-0.12.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c596cc0f4cb574877550ce4ecd51f8037469146addd676d7c1a30ebe6391923f", size = 365168, upload-time = "2025-11-09T20:48:41.462Z" }, + { url = "https://files.pythonhosted.org/packages/0c/d4/04619a9e8095b42aef436b5aeb4c0282b4ff1b27d1db1508df9f5dc82750/jiter-0.12.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5ab4c823b216a4aeab3fdbf579c5843165756bd9ad87cc6b1c65919c4715f783", size = 387893, upload-time = "2025-11-09T20:48:42.921Z" }, + { url = "https://files.pythonhosted.org/packages/17/ea/d3c7e62e4546fdc39197fa4a4315a563a89b95b6d54c0d25373842a59cbe/jiter-0.12.0-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:e427eee51149edf962203ff8db75a7514ab89be5cb623fb9cea1f20b54f1107b", size = 520828, upload-time = "2025-11-09T20:48:44.278Z" }, + { url = "https://files.pythonhosted.org/packages/cc/0b/c6d3562a03fd767e31cb119d9041ea7958c3c80cb3d753eafb19b3b18349/jiter-0.12.0-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:edb868841f84c111255ba5e80339d386d937ec1fdce419518ce1bd9370fac5b6", size = 511009, upload-time = "2025-11-09T20:48:45.726Z" }, + { url = "https://files.pythonhosted.org/packages/aa/51/2cb4468b3448a8385ebcd15059d325c9ce67df4e2758d133ab9442b19834/jiter-0.12.0-cp314-cp314t-win32.whl", hash = "sha256:8bbcfe2791dfdb7c5e48baf646d37a6a3dcb5a97a032017741dea9f817dca183", size = 205110, upload-time = "2025-11-09T20:48:47.033Z" }, + { url = "https://files.pythonhosted.org/packages/b2/c5/ae5ec83dec9c2d1af805fd5fe8f74ebded9c8670c5210ec7820ce0dbeb1e/jiter-0.12.0-cp314-cp314t-win_amd64.whl", hash = "sha256:2fa940963bf02e1d8226027ef461e36af472dea85d36054ff835aeed944dd873", size = 205223, upload-time = "2025-11-09T20:48:49.076Z" }, + { url = "https://files.pythonhosted.org/packages/97/9a/3c5391907277f0e55195550cf3fa8e293ae9ee0c00fb402fec1e38c0c82f/jiter-0.12.0-cp314-cp314t-win_arm64.whl", hash = "sha256:506c9708dd29b27288f9f8f1140c3cb0e3d8ddb045956d7757b1fa0e0f39a473", size = 185564, upload-time = "2025-11-09T20:48:50.376Z" }, +] + +[[package]] +name = "markdown-it-py" +version = "4.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mdurl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3", size = 73070, upload-time = "2025-08-11T12:57:52.854Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", size = 87321, upload-time = "2025-08-11T12:57:51.923Z" }, +] + +[[package]] +name = "markupsafe" +version = "3.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313, upload-time = "2025-09-27T18:37:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622, upload-time = "2025-09-27T18:36:41.777Z" }, + { url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029, upload-time = "2025-09-27T18:36:43.257Z" }, + { url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374, upload-time = "2025-09-27T18:36:44.508Z" }, + { url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", size = 22980, upload-time = "2025-09-27T18:36:45.385Z" }, + { url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", size = 21990, upload-time = "2025-09-27T18:36:46.916Z" }, + { url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", size = 23784, upload-time = "2025-09-27T18:36:47.884Z" }, + { url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", size = 21588, upload-time = "2025-09-27T18:36:48.82Z" }, + { url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", size = 23041, upload-time = "2025-09-27T18:36:49.797Z" }, + { url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543, upload-time = "2025-09-27T18:36:51.584Z" }, + { url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113, upload-time = "2025-09-27T18:36:52.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911, upload-time = "2025-09-27T18:36:53.513Z" }, + { url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", size = 11658, upload-time = "2025-09-27T18:36:54.819Z" }, + { url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", size = 12066, upload-time = "2025-09-27T18:36:55.714Z" }, + { url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", size = 25639, upload-time = "2025-09-27T18:36:56.908Z" }, + { url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", size = 23569, upload-time = "2025-09-27T18:36:57.913Z" }, + { url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", size = 23284, upload-time = "2025-09-27T18:36:58.833Z" }, + { url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", size = 24801, upload-time = "2025-09-27T18:36:59.739Z" }, + { url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", size = 22769, upload-time = "2025-09-27T18:37:00.719Z" }, + { url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", size = 23642, upload-time = "2025-09-27T18:37:01.673Z" }, + { url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612, upload-time = "2025-09-27T18:37:02.639Z" }, + { url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200, upload-time = "2025-09-27T18:37:03.582Z" }, + { url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973, upload-time = "2025-09-27T18:37:04.929Z" }, + { url = "https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe", size = 11619, upload-time = "2025-09-27T18:37:06.342Z" }, + { url = "https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026", size = 12029, upload-time = "2025-09-27T18:37:07.213Z" }, + { url = "https://files.pythonhosted.org/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737", size = 24408, upload-time = "2025-09-27T18:37:09.572Z" }, + { url = "https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97", size = 23005, upload-time = "2025-09-27T18:37:10.58Z" }, + { url = "https://files.pythonhosted.org/packages/bc/20/b7fdf89a8456b099837cd1dc21974632a02a999ec9bf7ca3e490aacd98e7/markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d", size = 22048, upload-time = "2025-09-27T18:37:11.547Z" }, + { url = "https://files.pythonhosted.org/packages/9a/a7/591f592afdc734f47db08a75793a55d7fbcc6902a723ae4cfbab61010cc5/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda", size = 23821, upload-time = "2025-09-27T18:37:12.48Z" }, + { url = "https://files.pythonhosted.org/packages/7d/33/45b24e4f44195b26521bc6f1a82197118f74df348556594bd2262bda1038/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf", size = 21606, upload-time = "2025-09-27T18:37:13.485Z" }, + { url = "https://files.pythonhosted.org/packages/ff/0e/53dfaca23a69fbfbbf17a4b64072090e70717344c52eaaaa9c5ddff1e5f0/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe", size = 23043, upload-time = "2025-09-27T18:37:14.408Z" }, + { url = "https://files.pythonhosted.org/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9", size = 14747, upload-time = "2025-09-27T18:37:15.36Z" }, + { url = "https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581", size = 15341, upload-time = "2025-09-27T18:37:16.496Z" }, + { url = "https://files.pythonhosted.org/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4", size = 14073, upload-time = "2025-09-27T18:37:17.476Z" }, + { url = "https://files.pythonhosted.org/packages/3c/f0/57689aa4076e1b43b15fdfa646b04653969d50cf30c32a102762be2485da/markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab", size = 11661, upload-time = "2025-09-27T18:37:18.453Z" }, + { url = "https://files.pythonhosted.org/packages/89/c3/2e67a7ca217c6912985ec766c6393b636fb0c2344443ff9d91404dc4c79f/markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175", size = 12069, upload-time = "2025-09-27T18:37:19.332Z" }, + { url = "https://files.pythonhosted.org/packages/f0/00/be561dce4e6ca66b15276e184ce4b8aec61fe83662cce2f7d72bd3249d28/markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634", size = 25670, upload-time = "2025-09-27T18:37:20.245Z" }, + { url = "https://files.pythonhosted.org/packages/50/09/c419f6f5a92e5fadde27efd190eca90f05e1261b10dbd8cbcb39cd8ea1dc/markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50", size = 23598, upload-time = "2025-09-27T18:37:21.177Z" }, + { url = "https://files.pythonhosted.org/packages/22/44/a0681611106e0b2921b3033fc19bc53323e0b50bc70cffdd19f7d679bb66/markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e", size = 23261, upload-time = "2025-09-27T18:37:22.167Z" }, + { url = "https://files.pythonhosted.org/packages/5f/57/1b0b3f100259dc9fffe780cfb60d4be71375510e435efec3d116b6436d43/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5", size = 24835, upload-time = "2025-09-27T18:37:23.296Z" }, + { url = "https://files.pythonhosted.org/packages/26/6a/4bf6d0c97c4920f1597cc14dd720705eca0bf7c787aebc6bb4d1bead5388/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523", size = 22733, upload-time = "2025-09-27T18:37:24.237Z" }, + { url = "https://files.pythonhosted.org/packages/14/c7/ca723101509b518797fedc2fdf79ba57f886b4aca8a7d31857ba3ee8281f/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc", size = 23672, upload-time = "2025-09-27T18:37:25.271Z" }, + { url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", size = 14819, upload-time = "2025-09-27T18:37:26.285Z" }, + { url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", size = 15426, upload-time = "2025-09-27T18:37:27.316Z" }, + { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" }, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, +] + +[[package]] +name = "multidict" +version = "6.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/80/1e/5492c365f222f907de1039b91f922b93fa4f764c713ee858d235495d8f50/multidict-6.7.0.tar.gz", hash = "sha256:c6e99d9a65ca282e578dfea819cfa9c0a62b2499d8677392e09feaf305e9e6f5", size = 101834, upload-time = "2025-10-06T14:52:30.657Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/86/33272a544eeb36d66e4d9a920602d1a2f57d4ebea4ef3cdfe5a912574c95/multidict-6.7.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:bee7c0588aa0076ce77c0ea5d19a68d76ad81fcd9fe8501003b9a24f9d4000f6", size = 76135, upload-time = "2025-10-06T14:49:54.26Z" }, + { url = "https://files.pythonhosted.org/packages/91/1c/eb97db117a1ebe46d457a3d235a7b9d2e6dcab174f42d1b67663dd9e5371/multidict-6.7.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7ef6b61cad77091056ce0e7ce69814ef72afacb150b7ac6a3e9470def2198159", size = 45117, upload-time = "2025-10-06T14:49:55.82Z" }, + { url = "https://files.pythonhosted.org/packages/f1/d8/6c3442322e41fb1dd4de8bd67bfd11cd72352ac131f6368315617de752f1/multidict-6.7.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9c0359b1ec12b1d6849c59f9d319610b7f20ef990a6d454ab151aa0e3b9f78ca", size = 43472, upload-time = "2025-10-06T14:49:57.048Z" }, + { url = "https://files.pythonhosted.org/packages/75/3f/e2639e80325af0b6c6febdf8e57cc07043ff15f57fa1ef808f4ccb5ac4cd/multidict-6.7.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:cd240939f71c64bd658f186330603aac1a9a81bf6273f523fca63673cb7378a8", size = 249342, upload-time = "2025-10-06T14:49:58.368Z" }, + { url = "https://files.pythonhosted.org/packages/5d/cc/84e0585f805cbeaa9cbdaa95f9a3d6aed745b9d25700623ac89a6ecff400/multidict-6.7.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a60a4d75718a5efa473ebd5ab685786ba0c67b8381f781d1be14da49f1a2dc60", size = 257082, upload-time = "2025-10-06T14:49:59.89Z" }, + { url = "https://files.pythonhosted.org/packages/b0/9c/ac851c107c92289acbbf5cfb485694084690c1b17e555f44952c26ddc5bd/multidict-6.7.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:53a42d364f323275126aff81fb67c5ca1b7a04fda0546245730a55c8c5f24bc4", size = 240704, upload-time = "2025-10-06T14:50:01.485Z" }, + { url = "https://files.pythonhosted.org/packages/50/cc/5f93e99427248c09da95b62d64b25748a5f5c98c7c2ab09825a1d6af0e15/multidict-6.7.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3b29b980d0ddbecb736735ee5bef69bb2ddca56eff603c86f3f29a1128299b4f", size = 266355, upload-time = "2025-10-06T14:50:02.955Z" }, + { url = "https://files.pythonhosted.org/packages/ec/0c/2ec1d883ceb79c6f7f6d7ad90c919c898f5d1c6ea96d322751420211e072/multidict-6.7.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f8a93b1c0ed2d04b97a5e9336fd2d33371b9a6e29ab7dd6503d63407c20ffbaf", size = 267259, upload-time = "2025-10-06T14:50:04.446Z" }, + { url = "https://files.pythonhosted.org/packages/c6/2d/f0b184fa88d6630aa267680bdb8623fb69cb0d024b8c6f0d23f9a0f406d3/multidict-6.7.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9ff96e8815eecacc6645da76c413eb3b3d34cfca256c70b16b286a687d013c32", size = 254903, upload-time = "2025-10-06T14:50:05.98Z" }, + { url = "https://files.pythonhosted.org/packages/06/c9/11ea263ad0df7dfabcad404feb3c0dd40b131bc7f232d5537f2fb1356951/multidict-6.7.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7516c579652f6a6be0e266aec0acd0db80829ca305c3d771ed898538804c2036", size = 252365, upload-time = "2025-10-06T14:50:07.511Z" }, + { url = "https://files.pythonhosted.org/packages/41/88/d714b86ee2c17d6e09850c70c9d310abac3d808ab49dfa16b43aba9d53fd/multidict-6.7.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:040f393368e63fb0f3330e70c26bfd336656bed925e5cbe17c9da839a6ab13ec", size = 250062, upload-time = "2025-10-06T14:50:09.074Z" }, + { url = "https://files.pythonhosted.org/packages/15/fe/ad407bb9e818c2b31383f6131ca19ea7e35ce93cf1310fce69f12e89de75/multidict-6.7.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b3bc26a951007b1057a1c543af845f1c7e3e71cc240ed1ace7bf4484aa99196e", size = 249683, upload-time = "2025-10-06T14:50:10.714Z" }, + { url = "https://files.pythonhosted.org/packages/8c/a4/a89abdb0229e533fb925e7c6e5c40201c2873efebc9abaf14046a4536ee6/multidict-6.7.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:7b022717c748dd1992a83e219587aabe45980d88969f01b316e78683e6285f64", size = 261254, upload-time = "2025-10-06T14:50:12.28Z" }, + { url = "https://files.pythonhosted.org/packages/8d/aa/0e2b27bd88b40a4fb8dc53dd74eecac70edaa4c1dd0707eb2164da3675b3/multidict-6.7.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:9600082733859f00d79dee64effc7aef1beb26adb297416a4ad2116fd61374bd", size = 257967, upload-time = "2025-10-06T14:50:14.16Z" }, + { url = "https://files.pythonhosted.org/packages/d0/8e/0c67b7120d5d5f6d874ed85a085f9dc770a7f9d8813e80f44a9fec820bb7/multidict-6.7.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:94218fcec4d72bc61df51c198d098ce2b378e0ccbac41ddbed5ef44092913288", size = 250085, upload-time = "2025-10-06T14:50:15.639Z" }, + { url = "https://files.pythonhosted.org/packages/ba/55/b73e1d624ea4b8fd4dd07a3bb70f6e4c7c6c5d9d640a41c6ffe5cdbd2a55/multidict-6.7.0-cp313-cp313-win32.whl", hash = "sha256:a37bd74c3fa9d00be2d7b8eca074dc56bd8077ddd2917a839bd989612671ed17", size = 41713, upload-time = "2025-10-06T14:50:17.066Z" }, + { url = "https://files.pythonhosted.org/packages/32/31/75c59e7d3b4205075b4c183fa4ca398a2daf2303ddf616b04ae6ef55cffe/multidict-6.7.0-cp313-cp313-win_amd64.whl", hash = "sha256:30d193c6cc6d559db42b6bcec8a5d395d34d60c9877a0b71ecd7c204fcf15390", size = 45915, upload-time = "2025-10-06T14:50:18.264Z" }, + { url = "https://files.pythonhosted.org/packages/31/2a/8987831e811f1184c22bc2e45844934385363ee61c0a2dcfa8f71b87e608/multidict-6.7.0-cp313-cp313-win_arm64.whl", hash = "sha256:ea3334cabe4d41b7ccd01e4d349828678794edbc2d3ae97fc162a3312095092e", size = 43077, upload-time = "2025-10-06T14:50:19.853Z" }, + { url = "https://files.pythonhosted.org/packages/e8/68/7b3a5170a382a340147337b300b9eb25a9ddb573bcdfff19c0fa3f31ffba/multidict-6.7.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:ad9ce259f50abd98a1ca0aa6e490b58c316a0fce0617f609723e40804add2c00", size = 83114, upload-time = "2025-10-06T14:50:21.223Z" }, + { url = "https://files.pythonhosted.org/packages/55/5c/3fa2d07c84df4e302060f555bbf539310980362236ad49f50eeb0a1c1eb9/multidict-6.7.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:07f5594ac6d084cbb5de2df218d78baf55ef150b91f0ff8a21cc7a2e3a5a58eb", size = 48442, upload-time = "2025-10-06T14:50:22.871Z" }, + { url = "https://files.pythonhosted.org/packages/fc/56/67212d33239797f9bd91962bb899d72bb0f4c35a8652dcdb8ed049bef878/multidict-6.7.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0591b48acf279821a579282444814a2d8d0af624ae0bc600aa4d1b920b6e924b", size = 46885, upload-time = "2025-10-06T14:50:24.258Z" }, + { url = "https://files.pythonhosted.org/packages/46/d1/908f896224290350721597a61a69cd19b89ad8ee0ae1f38b3f5cd12ea2ac/multidict-6.7.0-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:749a72584761531d2b9467cfbdfd29487ee21124c304c4b6cb760d8777b27f9c", size = 242588, upload-time = "2025-10-06T14:50:25.716Z" }, + { url = "https://files.pythonhosted.org/packages/ab/67/8604288bbd68680eee0ab568fdcb56171d8b23a01bcd5cb0c8fedf6e5d99/multidict-6.7.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b4c3d199f953acd5b446bf7c0de1fe25d94e09e79086f8dc2f48a11a129cdf1", size = 249966, upload-time = "2025-10-06T14:50:28.192Z" }, + { url = "https://files.pythonhosted.org/packages/20/33/9228d76339f1ba51e3efef7da3ebd91964d3006217aae13211653193c3ff/multidict-6.7.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:9fb0211dfc3b51efea2f349ec92c114d7754dd62c01f81c3e32b765b70c45c9b", size = 228618, upload-time = "2025-10-06T14:50:29.82Z" }, + { url = "https://files.pythonhosted.org/packages/f8/2d/25d9b566d10cab1c42b3b9e5b11ef79c9111eaf4463b8c257a3bd89e0ead/multidict-6.7.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a027ec240fe73a8d6281872690b988eed307cd7d91b23998ff35ff577ca688b5", size = 257539, upload-time = "2025-10-06T14:50:31.731Z" }, + { url = "https://files.pythonhosted.org/packages/b6/b1/8d1a965e6637fc33de3c0d8f414485c2b7e4af00f42cab3d84e7b955c222/multidict-6.7.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d1d964afecdf3a8288789df2f5751dc0a8261138c3768d9af117ed384e538fad", size = 256345, upload-time = "2025-10-06T14:50:33.26Z" }, + { url = "https://files.pythonhosted.org/packages/ba/0c/06b5a8adbdeedada6f4fb8d8f193d44a347223b11939b42953eeb6530b6b/multidict-6.7.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:caf53b15b1b7df9fbd0709aa01409000a2b4dd03a5f6f5cc548183c7c8f8b63c", size = 247934, upload-time = "2025-10-06T14:50:34.808Z" }, + { url = "https://files.pythonhosted.org/packages/8f/31/b2491b5fe167ca044c6eb4b8f2c9f3b8a00b24c432c365358eadac5d7625/multidict-6.7.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:654030da3197d927f05a536a66186070e98765aa5142794c9904555d3a9d8fb5", size = 245243, upload-time = "2025-10-06T14:50:36.436Z" }, + { url = "https://files.pythonhosted.org/packages/61/1a/982913957cb90406c8c94f53001abd9eafc271cb3e70ff6371590bec478e/multidict-6.7.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:2090d3718829d1e484706a2f525e50c892237b2bf9b17a79b059cb98cddc2f10", size = 235878, upload-time = "2025-10-06T14:50:37.953Z" }, + { url = "https://files.pythonhosted.org/packages/be/c0/21435d804c1a1cf7a2608593f4d19bca5bcbd7a81a70b253fdd1c12af9c0/multidict-6.7.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:2d2cfeec3f6f45651b3d408c4acec0ebf3daa9bc8a112a084206f5db5d05b754", size = 243452, upload-time = "2025-10-06T14:50:39.574Z" }, + { url = "https://files.pythonhosted.org/packages/54/0a/4349d540d4a883863191be6eb9a928846d4ec0ea007d3dcd36323bb058ac/multidict-6.7.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:4ef089f985b8c194d341eb2c24ae6e7408c9a0e2e5658699c92f497437d88c3c", size = 252312, upload-time = "2025-10-06T14:50:41.612Z" }, + { url = "https://files.pythonhosted.org/packages/26/64/d5416038dbda1488daf16b676e4dbfd9674dde10a0cc8f4fc2b502d8125d/multidict-6.7.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:e93a0617cd16998784bf4414c7e40f17a35d2350e5c6f0bd900d3a8e02bd3762", size = 246935, upload-time = "2025-10-06T14:50:43.972Z" }, + { url = "https://files.pythonhosted.org/packages/9f/8c/8290c50d14e49f35e0bd4abc25e1bc7711149ca9588ab7d04f886cdf03d9/multidict-6.7.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f0feece2ef8ebc42ed9e2e8c78fc4aa3cf455733b507c09ef7406364c94376c6", size = 243385, upload-time = "2025-10-06T14:50:45.648Z" }, + { url = "https://files.pythonhosted.org/packages/ef/a0/f83ae75e42d694b3fbad3e047670e511c138be747bc713cf1b10d5096416/multidict-6.7.0-cp313-cp313t-win32.whl", hash = "sha256:19a1d55338ec1be74ef62440ca9e04a2f001a04d0cc49a4983dc320ff0f3212d", size = 47777, upload-time = "2025-10-06T14:50:47.154Z" }, + { url = "https://files.pythonhosted.org/packages/dc/80/9b174a92814a3830b7357307a792300f42c9e94664b01dee8e457551fa66/multidict-6.7.0-cp313-cp313t-win_amd64.whl", hash = "sha256:3da4fb467498df97e986af166b12d01f05d2e04f978a9c1c680ea1988e0bc4b6", size = 53104, upload-time = "2025-10-06T14:50:48.851Z" }, + { url = "https://files.pythonhosted.org/packages/cc/28/04baeaf0428d95bb7a7bea0e691ba2f31394338ba424fb0679a9ed0f4c09/multidict-6.7.0-cp313-cp313t-win_arm64.whl", hash = "sha256:b4121773c49a0776461f4a904cdf6264c88e42218aaa8407e803ca8025872792", size = 45503, upload-time = "2025-10-06T14:50:50.16Z" }, + { url = "https://files.pythonhosted.org/packages/e2/b1/3da6934455dd4b261d4c72f897e3a5728eba81db59959f3a639245891baa/multidict-6.7.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3bab1e4aff7adaa34410f93b1f8e57c4b36b9af0426a76003f441ee1d3c7e842", size = 75128, upload-time = "2025-10-06T14:50:51.92Z" }, + { url = "https://files.pythonhosted.org/packages/14/2c/f069cab5b51d175a1a2cb4ccdf7a2c2dabd58aa5bd933fa036a8d15e2404/multidict-6.7.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:b8512bac933afc3e45fb2b18da8e59b78d4f408399a960339598374d4ae3b56b", size = 44410, upload-time = "2025-10-06T14:50:53.275Z" }, + { url = "https://files.pythonhosted.org/packages/42/e2/64bb41266427af6642b6b128e8774ed84c11b80a90702c13ac0a86bb10cc/multidict-6.7.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:79dcf9e477bc65414ebfea98ffd013cb39552b5ecd62908752e0e413d6d06e38", size = 43205, upload-time = "2025-10-06T14:50:54.911Z" }, + { url = "https://files.pythonhosted.org/packages/02/68/6b086fef8a3f1a8541b9236c594f0c9245617c29841f2e0395d979485cde/multidict-6.7.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:31bae522710064b5cbeddaf2e9f32b1abab70ac6ac91d42572502299e9953128", size = 245084, upload-time = "2025-10-06T14:50:56.369Z" }, + { url = "https://files.pythonhosted.org/packages/15/ee/f524093232007cd7a75c1d132df70f235cfd590a7c9eaccd7ff422ef4ae8/multidict-6.7.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4a0df7ff02397bb63e2fd22af2c87dfa39e8c7f12947bc524dbdc528282c7e34", size = 252667, upload-time = "2025-10-06T14:50:57.991Z" }, + { url = "https://files.pythonhosted.org/packages/02/a5/eeb3f43ab45878f1895118c3ef157a480db58ede3f248e29b5354139c2c9/multidict-6.7.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7a0222514e8e4c514660e182d5156a415c13ef0aabbd71682fc714e327b95e99", size = 233590, upload-time = "2025-10-06T14:50:59.589Z" }, + { url = "https://files.pythonhosted.org/packages/6a/1e/76d02f8270b97269d7e3dbd45644b1785bda457b474315f8cf999525a193/multidict-6.7.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2397ab4daaf2698eb51a76721e98db21ce4f52339e535725de03ea962b5a3202", size = 264112, upload-time = "2025-10-06T14:51:01.183Z" }, + { url = "https://files.pythonhosted.org/packages/76/0b/c28a70ecb58963847c2a8efe334904cd254812b10e535aefb3bcce513918/multidict-6.7.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8891681594162635948a636c9fe0ff21746aeb3dd5463f6e25d9bea3a8a39ca1", size = 261194, upload-time = "2025-10-06T14:51:02.794Z" }, + { url = "https://files.pythonhosted.org/packages/b4/63/2ab26e4209773223159b83aa32721b4021ffb08102f8ac7d689c943fded1/multidict-6.7.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18706cc31dbf402a7945916dd5cddf160251b6dab8a2c5f3d6d5a55949f676b3", size = 248510, upload-time = "2025-10-06T14:51:04.724Z" }, + { url = "https://files.pythonhosted.org/packages/93/cd/06c1fa8282af1d1c46fd55c10a7930af652afdce43999501d4d68664170c/multidict-6.7.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f844a1bbf1d207dd311a56f383f7eda2d0e134921d45751842d8235e7778965d", size = 248395, upload-time = "2025-10-06T14:51:06.306Z" }, + { url = "https://files.pythonhosted.org/packages/99/ac/82cb419dd6b04ccf9e7e61befc00c77614fc8134362488b553402ecd55ce/multidict-6.7.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:d4393e3581e84e5645506923816b9cc81f5609a778c7e7534054091acc64d1c6", size = 239520, upload-time = "2025-10-06T14:51:08.091Z" }, + { url = "https://files.pythonhosted.org/packages/fa/f3/a0f9bf09493421bd8716a362e0cd1d244f5a6550f5beffdd6b47e885b331/multidict-6.7.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:fbd18dc82d7bf274b37aa48d664534330af744e03bccf696d6f4c6042e7d19e7", size = 245479, upload-time = "2025-10-06T14:51:10.365Z" }, + { url = "https://files.pythonhosted.org/packages/8d/01/476d38fc73a212843f43c852b0eee266b6971f0e28329c2184a8df90c376/multidict-6.7.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:b6234e14f9314731ec45c42fc4554b88133ad53a09092cc48a88e771c125dadb", size = 258903, upload-time = "2025-10-06T14:51:12.466Z" }, + { url = "https://files.pythonhosted.org/packages/49/6d/23faeb0868adba613b817d0e69c5f15531b24d462af8012c4f6de4fa8dc3/multidict-6.7.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:08d4379f9744d8f78d98c8673c06e202ffa88296f009c71bbafe8a6bf847d01f", size = 252333, upload-time = "2025-10-06T14:51:14.48Z" }, + { url = "https://files.pythonhosted.org/packages/1e/cc/48d02ac22b30fa247f7dad82866e4b1015431092f4ba6ebc7e77596e0b18/multidict-6.7.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:9fe04da3f79387f450fd0061d4dd2e45a72749d31bf634aecc9e27f24fdc4b3f", size = 243411, upload-time = "2025-10-06T14:51:16.072Z" }, + { url = "https://files.pythonhosted.org/packages/4a/03/29a8bf5a18abf1fe34535c88adbdfa88c9fb869b5a3b120692c64abe8284/multidict-6.7.0-cp314-cp314-win32.whl", hash = "sha256:fbafe31d191dfa7c4c51f7a6149c9fb7e914dcf9ffead27dcfd9f1ae382b3885", size = 40940, upload-time = "2025-10-06T14:51:17.544Z" }, + { url = "https://files.pythonhosted.org/packages/82/16/7ed27b680791b939de138f906d5cf2b4657b0d45ca6f5dd6236fdddafb1a/multidict-6.7.0-cp314-cp314-win_amd64.whl", hash = "sha256:2f67396ec0310764b9222a1728ced1ab638f61aadc6226f17a71dd9324f9a99c", size = 45087, upload-time = "2025-10-06T14:51:18.875Z" }, + { url = "https://files.pythonhosted.org/packages/cd/3c/e3e62eb35a1950292fe39315d3c89941e30a9d07d5d2df42965ab041da43/multidict-6.7.0-cp314-cp314-win_arm64.whl", hash = "sha256:ba672b26069957ee369cfa7fc180dde1fc6f176eaf1e6beaf61fbebbd3d9c000", size = 42368, upload-time = "2025-10-06T14:51:20.225Z" }, + { url = "https://files.pythonhosted.org/packages/8b/40/cd499bd0dbc5f1136726db3153042a735fffd0d77268e2ee20d5f33c010f/multidict-6.7.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:c1dcc7524066fa918c6a27d61444d4ee7900ec635779058571f70d042d86ed63", size = 82326, upload-time = "2025-10-06T14:51:21.588Z" }, + { url = "https://files.pythonhosted.org/packages/13/8a/18e031eca251c8df76daf0288e6790561806e439f5ce99a170b4af30676b/multidict-6.7.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:27e0b36c2d388dc7b6ced3406671b401e84ad7eb0656b8f3a2f46ed0ce483718", size = 48065, upload-time = "2025-10-06T14:51:22.93Z" }, + { url = "https://files.pythonhosted.org/packages/40/71/5e6701277470a87d234e433fb0a3a7deaf3bcd92566e421e7ae9776319de/multidict-6.7.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:2a7baa46a22e77f0988e3b23d4ede5513ebec1929e34ee9495be535662c0dfe2", size = 46475, upload-time = "2025-10-06T14:51:24.352Z" }, + { url = "https://files.pythonhosted.org/packages/fe/6a/bab00cbab6d9cfb57afe1663318f72ec28289ea03fd4e8236bb78429893a/multidict-6.7.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:7bf77f54997a9166a2f5675d1201520586439424c2511723a7312bdb4bcc034e", size = 239324, upload-time = "2025-10-06T14:51:25.822Z" }, + { url = "https://files.pythonhosted.org/packages/2a/5f/8de95f629fc22a7769ade8b41028e3e5a822c1f8904f618d175945a81ad3/multidict-6.7.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e011555abada53f1578d63389610ac8a5400fc70ce71156b0aa30d326f1a5064", size = 246877, upload-time = "2025-10-06T14:51:27.604Z" }, + { url = "https://files.pythonhosted.org/packages/23/b4/38881a960458f25b89e9f4a4fdcb02ac101cfa710190db6e5528841e67de/multidict-6.7.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:28b37063541b897fd6a318007373930a75ca6d6ac7c940dbe14731ffdd8d498e", size = 225824, upload-time = "2025-10-06T14:51:29.664Z" }, + { url = "https://files.pythonhosted.org/packages/1e/39/6566210c83f8a261575f18e7144736059f0c460b362e96e9cf797a24b8e7/multidict-6.7.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:05047ada7a2fde2631a0ed706f1fd68b169a681dfe5e4cf0f8e4cb6618bbc2cd", size = 253558, upload-time = "2025-10-06T14:51:31.684Z" }, + { url = "https://files.pythonhosted.org/packages/00/a3/67f18315100f64c269f46e6c0319fa87ba68f0f64f2b8e7fd7c72b913a0b/multidict-6.7.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:716133f7d1d946a4e1b91b1756b23c088881e70ff180c24e864c26192ad7534a", size = 252339, upload-time = "2025-10-06T14:51:33.699Z" }, + { url = "https://files.pythonhosted.org/packages/c8/2a/1cb77266afee2458d82f50da41beba02159b1d6b1f7973afc9a1cad1499b/multidict-6.7.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d1bed1b467ef657f2a0ae62844a607909ef1c6889562de5e1d505f74457d0b96", size = 244895, upload-time = "2025-10-06T14:51:36.189Z" }, + { url = "https://files.pythonhosted.org/packages/dd/72/09fa7dd487f119b2eb9524946ddd36e2067c08510576d43ff68469563b3b/multidict-6.7.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ca43bdfa5d37bd6aee89d85e1d0831fb86e25541be7e9d376ead1b28974f8e5e", size = 241862, upload-time = "2025-10-06T14:51:41.291Z" }, + { url = "https://files.pythonhosted.org/packages/65/92/bc1f8bd0853d8669300f732c801974dfc3702c3eeadae2f60cef54dc69d7/multidict-6.7.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:44b546bd3eb645fd26fb949e43c02a25a2e632e2ca21a35e2e132c8105dc8599", size = 232376, upload-time = "2025-10-06T14:51:43.55Z" }, + { url = "https://files.pythonhosted.org/packages/09/86/ac39399e5cb9d0c2ac8ef6e10a768e4d3bc933ac808d49c41f9dc23337eb/multidict-6.7.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:a6ef16328011d3f468e7ebc326f24c1445f001ca1dec335b2f8e66bed3006394", size = 240272, upload-time = "2025-10-06T14:51:45.265Z" }, + { url = "https://files.pythonhosted.org/packages/3d/b6/fed5ac6b8563ec72df6cb1ea8dac6d17f0a4a1f65045f66b6d3bf1497c02/multidict-6.7.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:5aa873cbc8e593d361ae65c68f85faadd755c3295ea2c12040ee146802f23b38", size = 248774, upload-time = "2025-10-06T14:51:46.836Z" }, + { url = "https://files.pythonhosted.org/packages/6b/8d/b954d8c0dc132b68f760aefd45870978deec6818897389dace00fcde32ff/multidict-6.7.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:3d7b6ccce016e29df4b7ca819659f516f0bc7a4b3efa3bb2012ba06431b044f9", size = 242731, upload-time = "2025-10-06T14:51:48.541Z" }, + { url = "https://files.pythonhosted.org/packages/16/9d/a2dac7009125d3540c2f54e194829ea18ac53716c61b655d8ed300120b0f/multidict-6.7.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:171b73bd4ee683d307599b66793ac80981b06f069b62eea1c9e29c9241aa66b0", size = 240193, upload-time = "2025-10-06T14:51:50.355Z" }, + { url = "https://files.pythonhosted.org/packages/39/ca/c05f144128ea232ae2178b008d5011d4e2cea86e4ee8c85c2631b1b94802/multidict-6.7.0-cp314-cp314t-win32.whl", hash = "sha256:b2d7f80c4e1fd010b07cb26820aae86b7e73b681ee4889684fb8d2d4537aab13", size = 48023, upload-time = "2025-10-06T14:51:51.883Z" }, + { url = "https://files.pythonhosted.org/packages/ba/8f/0a60e501584145588be1af5cc829265701ba3c35a64aec8e07cbb71d39bb/multidict-6.7.0-cp314-cp314t-win_amd64.whl", hash = "sha256:09929cab6fcb68122776d575e03c6cc64ee0b8fca48d17e135474b042ce515cd", size = 53507, upload-time = "2025-10-06T14:51:53.672Z" }, + { url = "https://files.pythonhosted.org/packages/7f/ae/3148b988a9c6239903e786eac19c889fab607c31d6efa7fb2147e5680f23/multidict-6.7.0-cp314-cp314t-win_arm64.whl", hash = "sha256:cc41db090ed742f32bd2d2c721861725e6109681eddf835d0a82bd3a5c382827", size = 44804, upload-time = "2025-10-06T14:51:55.415Z" }, + { url = "https://files.pythonhosted.org/packages/b7/da/7d22601b625e241d4f23ef1ebff8acfc60da633c9e7e7922e24d10f592b3/multidict-6.7.0-py3-none-any.whl", hash = "sha256:394fc5c42a333c9ffc3e421a4c85e08580d990e08b99f6bf35b4132114c5dcb3", size = 12317, upload-time = "2025-10-06T14:52:29.272Z" }, +] + +[[package]] +name = "o2o-castad-backend" +version = "0.1.0" +source = { editable = "." } +dependencies = [ + { name = "aiofiles" }, + { name = "aiohttp" }, + { name = "aiomysql" }, + { name = "asyncmy" }, + { name = "beautifulsoup4" }, + { name = "fastapi", extra = ["standard"] }, + { name = "fastapi-cli" }, + { name = "openai" }, + { name = "pydantic-settings" }, + { name = "redis" }, + { name = "ruff" }, + { name = "scalar-fastapi" }, + { name = "sqladmin", extra = ["full"] }, + { name = "sqlalchemy", extra = ["asyncio"] }, + { name = "uuid7" }, +] + +[package.dev-dependencies] +dev = [ + { name = "pytest" }, + { name = "pytest-asyncio" }, +] + +[package.metadata] +requires-dist = [ + { name = "aiofiles", specifier = ">=25.1.0" }, + { name = "aiohttp", specifier = ">=3.13.2" }, + { name = "aiomysql", specifier = ">=0.3.2" }, + { name = "asyncmy", specifier = ">=0.2.10" }, + { name = "beautifulsoup4", specifier = ">=4.14.3" }, + { name = "fastapi", extras = ["standard"], specifier = ">=0.125.0" }, + { name = "fastapi-cli", specifier = ">=0.0.16" }, + { name = "openai", specifier = ">=2.13.0" }, + { name = "pydantic-settings", specifier = ">=2.12.0" }, + { name = "redis", specifier = ">=7.1.0" }, + { name = "ruff", specifier = ">=0.14.9" }, + { name = "scalar-fastapi", specifier = ">=1.5.0" }, + { name = "sqladmin", extras = ["full"], specifier = ">=0.22.0" }, + { name = "sqlalchemy", extras = ["asyncio"], specifier = ">=2.0.45" }, + { name = "uuid7", specifier = ">=0.1.0" }, +] + +[package.metadata.requires-dev] +dev = [ + { name = "pytest", specifier = ">=9.0.2" }, + { name = "pytest-asyncio", specifier = ">=1.3.0" }, +] + +[[package]] +name = "openai" +version = "2.14.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "distro" }, + { name = "httpx" }, + { name = "jiter" }, + { name = "pydantic" }, + { name = "sniffio" }, + { name = "tqdm" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d8/b1/12fe1c196bea326261718eb037307c1c1fe1dedc2d2d4de777df822e6238/openai-2.14.0.tar.gz", hash = "sha256:419357bedde9402d23bf8f2ee372fca1985a73348debba94bddff06f19459952", size = 626938, upload-time = "2025-12-19T03:28:45.742Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/27/4b/7c1a00c2c3fbd004253937f7520f692a9650767aa73894d7a34f0d65d3f4/openai-2.14.0-py3-none-any.whl", hash = "sha256:7ea40aca4ffc4c4a776e77679021b47eec1160e341f42ae086ba949c9dcc9183", size = 1067558, upload-time = "2025-12-19T03:28:43.727Z" }, +] + +[[package]] +name = "packaging" +version = "25.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "propcache" +version = "0.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9e/da/e9fc233cf63743258bff22b3dfa7ea5baef7b5bc324af47a0ad89b8ffc6f/propcache-0.4.1.tar.gz", hash = "sha256:f48107a8c637e80362555f37ecf49abe20370e557cc4ab374f04ec4423c97c3d", size = 46442, upload-time = "2025-10-08T19:49:02.291Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bf/df/6d9c1b6ac12b003837dde8a10231a7344512186e87b36e855bef32241942/propcache-0.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:43eedf29202c08550aac1d14e0ee619b0430aaef78f85864c1a892294fbc28cf", size = 77750, upload-time = "2025-10-08T19:47:07.648Z" }, + { url = "https://files.pythonhosted.org/packages/8b/e8/677a0025e8a2acf07d3418a2e7ba529c9c33caf09d3c1f25513023c1db56/propcache-0.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d62cdfcfd89ccb8de04e0eda998535c406bf5e060ffd56be6c586cbcc05b3311", size = 44780, upload-time = "2025-10-08T19:47:08.851Z" }, + { url = "https://files.pythonhosted.org/packages/89/a4/92380f7ca60f99ebae761936bc48a72a639e8a47b29050615eef757cb2a7/propcache-0.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cae65ad55793da34db5f54e4029b89d3b9b9490d8abe1b4c7ab5d4b8ec7ebf74", size = 46308, upload-time = "2025-10-08T19:47:09.982Z" }, + { url = "https://files.pythonhosted.org/packages/2d/48/c5ac64dee5262044348d1d78a5f85dd1a57464a60d30daee946699963eb3/propcache-0.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:333ddb9031d2704a301ee3e506dc46b1fe5f294ec198ed6435ad5b6a085facfe", size = 208182, upload-time = "2025-10-08T19:47:11.319Z" }, + { url = "https://files.pythonhosted.org/packages/c6/0c/cd762dd011a9287389a6a3eb43aa30207bde253610cca06824aeabfe9653/propcache-0.4.1-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:fd0858c20f078a32cf55f7e81473d96dcf3b93fd2ccdb3d40fdf54b8573df3af", size = 211215, upload-time = "2025-10-08T19:47:13.146Z" }, + { url = "https://files.pythonhosted.org/packages/30/3e/49861e90233ba36890ae0ca4c660e95df565b2cd15d4a68556ab5865974e/propcache-0.4.1-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:678ae89ebc632c5c204c794f8dab2837c5f159aeb59e6ed0539500400577298c", size = 218112, upload-time = "2025-10-08T19:47:14.913Z" }, + { url = "https://files.pythonhosted.org/packages/f1/8b/544bc867e24e1bd48f3118cecd3b05c694e160a168478fa28770f22fd094/propcache-0.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d472aeb4fbf9865e0c6d622d7f4d54a4e101a89715d8904282bb5f9a2f476c3f", size = 204442, upload-time = "2025-10-08T19:47:16.277Z" }, + { url = "https://files.pythonhosted.org/packages/50/a6/4282772fd016a76d3e5c0df58380a5ea64900afd836cec2c2f662d1b9bb3/propcache-0.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4d3df5fa7e36b3225954fba85589da77a0fe6a53e3976de39caf04a0db4c36f1", size = 199398, upload-time = "2025-10-08T19:47:17.962Z" }, + { url = "https://files.pythonhosted.org/packages/3e/ec/d8a7cd406ee1ddb705db2139f8a10a8a427100347bd698e7014351c7af09/propcache-0.4.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:ee17f18d2498f2673e432faaa71698032b0127ebf23ae5974eeaf806c279df24", size = 196920, upload-time = "2025-10-08T19:47:19.355Z" }, + { url = "https://files.pythonhosted.org/packages/f6/6c/f38ab64af3764f431e359f8baf9e0a21013e24329e8b85d2da32e8ed07ca/propcache-0.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:580e97762b950f993ae618e167e7be9256b8353c2dcd8b99ec100eb50f5286aa", size = 203748, upload-time = "2025-10-08T19:47:21.338Z" }, + { url = "https://files.pythonhosted.org/packages/d6/e3/fa846bd70f6534d647886621388f0a265254d30e3ce47e5c8e6e27dbf153/propcache-0.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:501d20b891688eb8e7aa903021f0b72d5a55db40ffaab27edefd1027caaafa61", size = 205877, upload-time = "2025-10-08T19:47:23.059Z" }, + { url = "https://files.pythonhosted.org/packages/e2/39/8163fc6f3133fea7b5f2827e8eba2029a0277ab2c5beee6c1db7b10fc23d/propcache-0.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9a0bd56e5b100aef69bd8562b74b46254e7c8812918d3baa700c8a8009b0af66", size = 199437, upload-time = "2025-10-08T19:47:24.445Z" }, + { url = "https://files.pythonhosted.org/packages/93/89/caa9089970ca49c7c01662bd0eeedfe85494e863e8043565aeb6472ce8fe/propcache-0.4.1-cp313-cp313-win32.whl", hash = "sha256:bcc9aaa5d80322bc2fb24bb7accb4a30f81e90ab8d6ba187aec0744bc302ad81", size = 37586, upload-time = "2025-10-08T19:47:25.736Z" }, + { url = "https://files.pythonhosted.org/packages/f5/ab/f76ec3c3627c883215b5c8080debb4394ef5a7a29be811f786415fc1e6fd/propcache-0.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:381914df18634f5494334d201e98245c0596067504b9372d8cf93f4bb23e025e", size = 40790, upload-time = "2025-10-08T19:47:26.847Z" }, + { url = "https://files.pythonhosted.org/packages/59/1b/e71ae98235f8e2ba5004d8cb19765a74877abf189bc53fc0c80d799e56c3/propcache-0.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:8873eb4460fd55333ea49b7d189749ecf6e55bf85080f11b1c4530ed3034cba1", size = 37158, upload-time = "2025-10-08T19:47:27.961Z" }, + { url = "https://files.pythonhosted.org/packages/83/ce/a31bbdfc24ee0dcbba458c8175ed26089cf109a55bbe7b7640ed2470cfe9/propcache-0.4.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:92d1935ee1f8d7442da9c0c4fa7ac20d07e94064184811b685f5c4fada64553b", size = 81451, upload-time = "2025-10-08T19:47:29.445Z" }, + { url = "https://files.pythonhosted.org/packages/25/9c/442a45a470a68456e710d96cacd3573ef26a1d0a60067e6a7d5e655621ed/propcache-0.4.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:473c61b39e1460d386479b9b2f337da492042447c9b685f28be4f74d3529e566", size = 46374, upload-time = "2025-10-08T19:47:30.579Z" }, + { url = "https://files.pythonhosted.org/packages/f4/bf/b1d5e21dbc3b2e889ea4327044fb16312a736d97640fb8b6aa3f9c7b3b65/propcache-0.4.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:c0ef0aaafc66fbd87842a3fe3902fd889825646bc21149eafe47be6072725835", size = 48396, upload-time = "2025-10-08T19:47:31.79Z" }, + { url = "https://files.pythonhosted.org/packages/f4/04/5b4c54a103d480e978d3c8a76073502b18db0c4bc17ab91b3cb5092ad949/propcache-0.4.1-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f95393b4d66bfae908c3ca8d169d5f79cd65636ae15b5e7a4f6e67af675adb0e", size = 275950, upload-time = "2025-10-08T19:47:33.481Z" }, + { url = "https://files.pythonhosted.org/packages/b4/c1/86f846827fb969c4b78b0af79bba1d1ea2156492e1b83dea8b8a6ae27395/propcache-0.4.1-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c07fda85708bc48578467e85099645167a955ba093be0a2dcba962195676e859", size = 273856, upload-time = "2025-10-08T19:47:34.906Z" }, + { url = "https://files.pythonhosted.org/packages/36/1d/fc272a63c8d3bbad6878c336c7a7dea15e8f2d23a544bda43205dfa83ada/propcache-0.4.1-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:af223b406d6d000830c6f65f1e6431783fc3f713ba3e6cc8c024d5ee96170a4b", size = 280420, upload-time = "2025-10-08T19:47:36.338Z" }, + { url = "https://files.pythonhosted.org/packages/07/0c/01f2219d39f7e53d52e5173bcb09c976609ba30209912a0680adfb8c593a/propcache-0.4.1-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a78372c932c90ee474559c5ddfffd718238e8673c340dc21fe45c5b8b54559a0", size = 263254, upload-time = "2025-10-08T19:47:37.692Z" }, + { url = "https://files.pythonhosted.org/packages/2d/18/cd28081658ce597898f0c4d174d4d0f3c5b6d4dc27ffafeef835c95eb359/propcache-0.4.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:564d9f0d4d9509e1a870c920a89b2fec951b44bf5ba7d537a9e7c1ccec2c18af", size = 261205, upload-time = "2025-10-08T19:47:39.659Z" }, + { url = "https://files.pythonhosted.org/packages/7a/71/1f9e22eb8b8316701c2a19fa1f388c8a3185082607da8e406a803c9b954e/propcache-0.4.1-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:17612831fda0138059cc5546f4d12a2aacfb9e47068c06af35c400ba58ba7393", size = 247873, upload-time = "2025-10-08T19:47:41.084Z" }, + { url = "https://files.pythonhosted.org/packages/4a/65/3d4b61f36af2b4eddba9def857959f1016a51066b4f1ce348e0cf7881f58/propcache-0.4.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:41a89040cb10bd345b3c1a873b2bf36413d48da1def52f268a055f7398514874", size = 262739, upload-time = "2025-10-08T19:47:42.51Z" }, + { url = "https://files.pythonhosted.org/packages/2a/42/26746ab087faa77c1c68079b228810436ccd9a5ce9ac85e2b7307195fd06/propcache-0.4.1-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:e35b88984e7fa64aacecea39236cee32dd9bd8c55f57ba8a75cf2399553f9bd7", size = 263514, upload-time = "2025-10-08T19:47:43.927Z" }, + { url = "https://files.pythonhosted.org/packages/94/13/630690fe201f5502d2403dd3cfd451ed8858fe3c738ee88d095ad2ff407b/propcache-0.4.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f8b465489f927b0df505cbe26ffbeed4d6d8a2bbc61ce90eb074ff129ef0ab1", size = 257781, upload-time = "2025-10-08T19:47:45.448Z" }, + { url = "https://files.pythonhosted.org/packages/92/f7/1d4ec5841505f423469efbfc381d64b7b467438cd5a4bbcbb063f3b73d27/propcache-0.4.1-cp313-cp313t-win32.whl", hash = "sha256:2ad890caa1d928c7c2965b48f3a3815c853180831d0e5503d35cf00c472f4717", size = 41396, upload-time = "2025-10-08T19:47:47.202Z" }, + { url = "https://files.pythonhosted.org/packages/48/f0/615c30622316496d2cbbc29f5985f7777d3ada70f23370608c1d3e081c1f/propcache-0.4.1-cp313-cp313t-win_amd64.whl", hash = "sha256:f7ee0e597f495cf415bcbd3da3caa3bd7e816b74d0d52b8145954c5e6fd3ff37", size = 44897, upload-time = "2025-10-08T19:47:48.336Z" }, + { url = "https://files.pythonhosted.org/packages/fd/ca/6002e46eccbe0e33dcd4069ef32f7f1c9e243736e07adca37ae8c4830ec3/propcache-0.4.1-cp313-cp313t-win_arm64.whl", hash = "sha256:929d7cbe1f01bb7baffb33dc14eb5691c95831450a26354cd210a8155170c93a", size = 39789, upload-time = "2025-10-08T19:47:49.876Z" }, + { url = "https://files.pythonhosted.org/packages/8e/5c/bca52d654a896f831b8256683457ceddd490ec18d9ec50e97dfd8fc726a8/propcache-0.4.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3f7124c9d820ba5548d431afb4632301acf965db49e666aa21c305cbe8c6de12", size = 78152, upload-time = "2025-10-08T19:47:51.051Z" }, + { url = "https://files.pythonhosted.org/packages/65/9b/03b04e7d82a5f54fb16113d839f5ea1ede58a61e90edf515f6577c66fa8f/propcache-0.4.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:c0d4b719b7da33599dfe3b22d3db1ef789210a0597bc650b7cee9c77c2be8c5c", size = 44869, upload-time = "2025-10-08T19:47:52.594Z" }, + { url = "https://files.pythonhosted.org/packages/b2/fa/89a8ef0468d5833a23fff277b143d0573897cf75bd56670a6d28126c7d68/propcache-0.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:9f302f4783709a78240ebc311b793f123328716a60911d667e0c036bc5dcbded", size = 46596, upload-time = "2025-10-08T19:47:54.073Z" }, + { url = "https://files.pythonhosted.org/packages/86/bd/47816020d337f4a746edc42fe8d53669965138f39ee117414c7d7a340cfe/propcache-0.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c80ee5802e3fb9ea37938e7eecc307fb984837091d5fd262bb37238b1ae97641", size = 206981, upload-time = "2025-10-08T19:47:55.715Z" }, + { url = "https://files.pythonhosted.org/packages/df/f6/c5fa1357cc9748510ee55f37173eb31bfde6d94e98ccd9e6f033f2fc06e1/propcache-0.4.1-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ed5a841e8bb29a55fb8159ed526b26adc5bdd7e8bd7bf793ce647cb08656cdf4", size = 211490, upload-time = "2025-10-08T19:47:57.499Z" }, + { url = "https://files.pythonhosted.org/packages/80/1e/e5889652a7c4a3846683401a48f0f2e5083ce0ec1a8a5221d8058fbd1adf/propcache-0.4.1-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:55c72fd6ea2da4c318e74ffdf93c4fe4e926051133657459131a95c846d16d44", size = 215371, upload-time = "2025-10-08T19:47:59.317Z" }, + { url = "https://files.pythonhosted.org/packages/b2/f2/889ad4b2408f72fe1a4f6a19491177b30ea7bf1a0fd5f17050ca08cfc882/propcache-0.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8326e144341460402713f91df60ade3c999d601e7eb5ff8f6f7862d54de0610d", size = 201424, upload-time = "2025-10-08T19:48:00.67Z" }, + { url = "https://files.pythonhosted.org/packages/27/73/033d63069b57b0812c8bd19f311faebeceb6ba31b8f32b73432d12a0b826/propcache-0.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:060b16ae65bc098da7f6d25bf359f1f31f688384858204fe5d652979e0015e5b", size = 197566, upload-time = "2025-10-08T19:48:02.604Z" }, + { url = "https://files.pythonhosted.org/packages/dc/89/ce24f3dc182630b4e07aa6d15f0ff4b14ed4b9955fae95a0b54c58d66c05/propcache-0.4.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:89eb3fa9524f7bec9de6e83cf3faed9d79bffa560672c118a96a171a6f55831e", size = 193130, upload-time = "2025-10-08T19:48:04.499Z" }, + { url = "https://files.pythonhosted.org/packages/a9/24/ef0d5fd1a811fb5c609278d0209c9f10c35f20581fcc16f818da959fc5b4/propcache-0.4.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:dee69d7015dc235f526fe80a9c90d65eb0039103fe565776250881731f06349f", size = 202625, upload-time = "2025-10-08T19:48:06.213Z" }, + { url = "https://files.pythonhosted.org/packages/f5/02/98ec20ff5546f68d673df2f7a69e8c0d076b5abd05ca882dc7ee3a83653d/propcache-0.4.1-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:5558992a00dfd54ccbc64a32726a3357ec93825a418a401f5cc67df0ac5d9e49", size = 204209, upload-time = "2025-10-08T19:48:08.432Z" }, + { url = "https://files.pythonhosted.org/packages/a0/87/492694f76759b15f0467a2a93ab68d32859672b646aa8a04ce4864e7932d/propcache-0.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c9b822a577f560fbd9554812526831712c1436d2c046cedee4c3796d3543b144", size = 197797, upload-time = "2025-10-08T19:48:09.968Z" }, + { url = "https://files.pythonhosted.org/packages/ee/36/66367de3575db1d2d3f3d177432bd14ee577a39d3f5d1b3d5df8afe3b6e2/propcache-0.4.1-cp314-cp314-win32.whl", hash = "sha256:ab4c29b49d560fe48b696cdcb127dd36e0bc2472548f3bf56cc5cb3da2b2984f", size = 38140, upload-time = "2025-10-08T19:48:11.232Z" }, + { url = "https://files.pythonhosted.org/packages/0c/2a/a758b47de253636e1b8aef181c0b4f4f204bf0dd964914fb2af90a95b49b/propcache-0.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:5a103c3eb905fcea0ab98be99c3a9a5ab2de60228aa5aceedc614c0281cf6153", size = 41257, upload-time = "2025-10-08T19:48:12.707Z" }, + { url = "https://files.pythonhosted.org/packages/34/5e/63bd5896c3fec12edcbd6f12508d4890d23c265df28c74b175e1ef9f4f3b/propcache-0.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:74c1fb26515153e482e00177a1ad654721bf9207da8a494a0c05e797ad27b992", size = 38097, upload-time = "2025-10-08T19:48:13.923Z" }, + { url = "https://files.pythonhosted.org/packages/99/85/9ff785d787ccf9bbb3f3106f79884a130951436f58392000231b4c737c80/propcache-0.4.1-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:824e908bce90fb2743bd6b59db36eb4f45cd350a39637c9f73b1c1ea66f5b75f", size = 81455, upload-time = "2025-10-08T19:48:15.16Z" }, + { url = "https://files.pythonhosted.org/packages/90/85/2431c10c8e7ddb1445c1f7c4b54d886e8ad20e3c6307e7218f05922cad67/propcache-0.4.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:c2b5e7db5328427c57c8e8831abda175421b709672f6cfc3d630c3b7e2146393", size = 46372, upload-time = "2025-10-08T19:48:16.424Z" }, + { url = "https://files.pythonhosted.org/packages/01/20/b0972d902472da9bcb683fa595099911f4d2e86e5683bcc45de60dd05dc3/propcache-0.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6f6ff873ed40292cd4969ef5310179afd5db59fdf055897e282485043fc80ad0", size = 48411, upload-time = "2025-10-08T19:48:17.577Z" }, + { url = "https://files.pythonhosted.org/packages/e2/e3/7dc89f4f21e8f99bad3d5ddb3a3389afcf9da4ac69e3deb2dcdc96e74169/propcache-0.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:49a2dc67c154db2c1463013594c458881a069fcf98940e61a0569016a583020a", size = 275712, upload-time = "2025-10-08T19:48:18.901Z" }, + { url = "https://files.pythonhosted.org/packages/20/67/89800c8352489b21a8047c773067644e3897f02ecbbd610f4d46b7f08612/propcache-0.4.1-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:005f08e6a0529984491e37d8dbc3dd86f84bd78a8ceb5fa9a021f4c48d4984be", size = 273557, upload-time = "2025-10-08T19:48:20.762Z" }, + { url = "https://files.pythonhosted.org/packages/e2/a1/b52b055c766a54ce6d9c16d9aca0cad8059acd9637cdf8aa0222f4a026ef/propcache-0.4.1-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5c3310452e0d31390da9035c348633b43d7e7feb2e37be252be6da45abd1abcc", size = 280015, upload-time = "2025-10-08T19:48:22.592Z" }, + { url = "https://files.pythonhosted.org/packages/48/c8/33cee30bd890672c63743049f3c9e4be087e6780906bfc3ec58528be59c1/propcache-0.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c3c70630930447f9ef1caac7728c8ad1c56bc5015338b20fed0d08ea2480b3a", size = 262880, upload-time = "2025-10-08T19:48:23.947Z" }, + { url = "https://files.pythonhosted.org/packages/0c/b1/8f08a143b204b418285c88b83d00edbd61afbc2c6415ffafc8905da7038b/propcache-0.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8e57061305815dfc910a3634dcf584f08168a8836e6999983569f51a8544cd89", size = 260938, upload-time = "2025-10-08T19:48:25.656Z" }, + { url = "https://files.pythonhosted.org/packages/cf/12/96e4664c82ca2f31e1c8dff86afb867348979eb78d3cb8546a680287a1e9/propcache-0.4.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:521a463429ef54143092c11a77e04056dd00636f72e8c45b70aaa3140d639726", size = 247641, upload-time = "2025-10-08T19:48:27.207Z" }, + { url = "https://files.pythonhosted.org/packages/18/ed/e7a9cfca28133386ba52278136d42209d3125db08d0a6395f0cba0c0285c/propcache-0.4.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:120c964da3fdc75e3731aa392527136d4ad35868cc556fd09bb6d09172d9a367", size = 262510, upload-time = "2025-10-08T19:48:28.65Z" }, + { url = "https://files.pythonhosted.org/packages/f5/76/16d8bf65e8845dd62b4e2b57444ab81f07f40caa5652b8969b87ddcf2ef6/propcache-0.4.1-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:d8f353eb14ee3441ee844ade4277d560cdd68288838673273b978e3d6d2c8f36", size = 263161, upload-time = "2025-10-08T19:48:30.133Z" }, + { url = "https://files.pythonhosted.org/packages/e7/70/c99e9edb5d91d5ad8a49fa3c1e8285ba64f1476782fed10ab251ff413ba1/propcache-0.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ab2943be7c652f09638800905ee1bab2c544e537edb57d527997a24c13dc1455", size = 257393, upload-time = "2025-10-08T19:48:31.567Z" }, + { url = "https://files.pythonhosted.org/packages/08/02/87b25304249a35c0915d236575bc3574a323f60b47939a2262b77632a3ee/propcache-0.4.1-cp314-cp314t-win32.whl", hash = "sha256:05674a162469f31358c30bcaa8883cb7829fa3110bf9c0991fe27d7896c42d85", size = 42546, upload-time = "2025-10-08T19:48:32.872Z" }, + { url = "https://files.pythonhosted.org/packages/cb/ef/3c6ecf8b317aa982f309835e8f96987466123c6e596646d4e6a1dfcd080f/propcache-0.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:990f6b3e2a27d683cb7602ed6c86f15ee6b43b1194736f9baaeb93d0016633b1", size = 46259, upload-time = "2025-10-08T19:48:34.226Z" }, + { url = "https://files.pythonhosted.org/packages/c4/2d/346e946d4951f37eca1e4f55be0f0174c52cd70720f84029b02f296f4a38/propcache-0.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:ecef2343af4cc68e05131e45024ba34f6095821988a9d0a02aa7c73fcc448aa9", size = 40428, upload-time = "2025-10-08T19:48:35.441Z" }, + { url = "https://files.pythonhosted.org/packages/5b/5a/bc7b4a4ef808fa59a816c17b20c4bef6884daebbdf627ff2a161da67da19/propcache-0.4.1-py3-none-any.whl", hash = "sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237", size = 13305, upload-time = "2025-10-08T19:49:00.792Z" }, +] + +[[package]] +name = "pydantic" +version = "2.12.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-types" }, + { name = "pydantic-core" }, + { name = "typing-extensions" }, + { name = "typing-inspection" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/69/44/36f1a6e523abc58ae5f928898e4aca2e0ea509b5aa6f6f392a5d882be928/pydantic-2.12.5.tar.gz", hash = "sha256:4d351024c75c0f085a9febbb665ce8c0c6ec5d30e903bdb6394b7ede26aebb49", size = 821591, upload-time = "2025-11-26T15:11:46.471Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5a/87/b70ad306ebb6f9b585f114d0ac2137d792b48be34d732d60e597c2f8465a/pydantic-2.12.5-py3-none-any.whl", hash = "sha256:e561593fccf61e8a20fc46dfc2dfe075b8be7d0188df33f221ad1f0139180f9d", size = 463580, upload-time = "2025-11-26T15:11:44.605Z" }, +] + +[package.optional-dependencies] +email = [ + { name = "email-validator" }, +] + +[[package]] +name = "pydantic-core" +version = "2.41.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/71/70/23b021c950c2addd24ec408e9ab05d59b035b39d97cdc1130e1bce647bb6/pydantic_core-2.41.5.tar.gz", hash = "sha256:08daa51ea16ad373ffd5e7606252cc32f07bc72b28284b6bc9c6df804816476e", size = 460952, upload-time = "2025-11-04T13:43:49.098Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/87/06/8806241ff1f70d9939f9af039c6c35f2360cf16e93c2ca76f184e76b1564/pydantic_core-2.41.5-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:941103c9be18ac8daf7b7adca8228f8ed6bb7a1849020f643b3a14d15b1924d9", size = 2120403, upload-time = "2025-11-04T13:40:25.248Z" }, + { url = "https://files.pythonhosted.org/packages/94/02/abfa0e0bda67faa65fef1c84971c7e45928e108fe24333c81f3bfe35d5f5/pydantic_core-2.41.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:112e305c3314f40c93998e567879e887a3160bb8689ef3d2c04b6cc62c33ac34", size = 1896206, upload-time = "2025-11-04T13:40:27.099Z" }, + { url = "https://files.pythonhosted.org/packages/15/df/a4c740c0943e93e6500f9eb23f4ca7ec9bf71b19e608ae5b579678c8d02f/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cbaad15cb0c90aa221d43c00e77bb33c93e8d36e0bf74760cd00e732d10a6a0", size = 1919307, upload-time = "2025-11-04T13:40:29.806Z" }, + { url = "https://files.pythonhosted.org/packages/9a/e3/6324802931ae1d123528988e0e86587c2072ac2e5394b4bc2bc34b61ff6e/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:03ca43e12fab6023fc79d28ca6b39b05f794ad08ec2feccc59a339b02f2b3d33", size = 2063258, upload-time = "2025-11-04T13:40:33.544Z" }, + { url = "https://files.pythonhosted.org/packages/c9/d4/2230d7151d4957dd79c3044ea26346c148c98fbf0ee6ebd41056f2d62ab5/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc799088c08fa04e43144b164feb0c13f9a0bc40503f8df3e9fde58a3c0c101e", size = 2214917, upload-time = "2025-11-04T13:40:35.479Z" }, + { url = "https://files.pythonhosted.org/packages/e6/9f/eaac5df17a3672fef0081b6c1bb0b82b33ee89aa5cec0d7b05f52fd4a1fa/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:97aeba56665b4c3235a0e52b2c2f5ae9cd071b8a8310ad27bddb3f7fb30e9aa2", size = 2332186, upload-time = "2025-11-04T13:40:37.436Z" }, + { url = "https://files.pythonhosted.org/packages/cf/4e/35a80cae583a37cf15604b44240e45c05e04e86f9cfd766623149297e971/pydantic_core-2.41.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:406bf18d345822d6c21366031003612b9c77b3e29ffdb0f612367352aab7d586", size = 2073164, upload-time = "2025-11-04T13:40:40.289Z" }, + { url = "https://files.pythonhosted.org/packages/bf/e3/f6e262673c6140dd3305d144d032f7bd5f7497d3871c1428521f19f9efa2/pydantic_core-2.41.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b93590ae81f7010dbe380cdeab6f515902ebcbefe0b9327cc4804d74e93ae69d", size = 2179146, upload-time = "2025-11-04T13:40:42.809Z" }, + { url = "https://files.pythonhosted.org/packages/75/c7/20bd7fc05f0c6ea2056a4565c6f36f8968c0924f19b7d97bbfea55780e73/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:01a3d0ab748ee531f4ea6c3e48ad9dac84ddba4b0d82291f87248f2f9de8d740", size = 2137788, upload-time = "2025-11-04T13:40:44.752Z" }, + { url = "https://files.pythonhosted.org/packages/3a/8d/34318ef985c45196e004bc46c6eab2eda437e744c124ef0dbe1ff2c9d06b/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:6561e94ba9dacc9c61bce40e2d6bdc3bfaa0259d3ff36ace3b1e6901936d2e3e", size = 2340133, upload-time = "2025-11-04T13:40:46.66Z" }, + { url = "https://files.pythonhosted.org/packages/9c/59/013626bf8c78a5a5d9350d12e7697d3d4de951a75565496abd40ccd46bee/pydantic_core-2.41.5-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:915c3d10f81bec3a74fbd4faebe8391013ba61e5a1a8d48c4455b923bdda7858", size = 2324852, upload-time = "2025-11-04T13:40:48.575Z" }, + { url = "https://files.pythonhosted.org/packages/1a/d9/c248c103856f807ef70c18a4f986693a46a8ffe1602e5d361485da502d20/pydantic_core-2.41.5-cp313-cp313-win32.whl", hash = "sha256:650ae77860b45cfa6e2cdafc42618ceafab3a2d9a3811fcfbd3bbf8ac3c40d36", size = 1994679, upload-time = "2025-11-04T13:40:50.619Z" }, + { url = "https://files.pythonhosted.org/packages/9e/8b/341991b158ddab181cff136acd2552c9f35bd30380422a639c0671e99a91/pydantic_core-2.41.5-cp313-cp313-win_amd64.whl", hash = "sha256:79ec52ec461e99e13791ec6508c722742ad745571f234ea6255bed38c6480f11", size = 2019766, upload-time = "2025-11-04T13:40:52.631Z" }, + { url = "https://files.pythonhosted.org/packages/73/7d/f2f9db34af103bea3e09735bb40b021788a5e834c81eedb541991badf8f5/pydantic_core-2.41.5-cp313-cp313-win_arm64.whl", hash = "sha256:3f84d5c1b4ab906093bdc1ff10484838aca54ef08de4afa9de0f5f14d69639cd", size = 1981005, upload-time = "2025-11-04T13:40:54.734Z" }, + { url = "https://files.pythonhosted.org/packages/ea/28/46b7c5c9635ae96ea0fbb779e271a38129df2550f763937659ee6c5dbc65/pydantic_core-2.41.5-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:3f37a19d7ebcdd20b96485056ba9e8b304e27d9904d233d7b1015db320e51f0a", size = 2119622, upload-time = "2025-11-04T13:40:56.68Z" }, + { url = "https://files.pythonhosted.org/packages/74/1a/145646e5687e8d9a1e8d09acb278c8535ebe9e972e1f162ed338a622f193/pydantic_core-2.41.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1d1d9764366c73f996edd17abb6d9d7649a7eb690006ab6adbda117717099b14", size = 1891725, upload-time = "2025-11-04T13:40:58.807Z" }, + { url = "https://files.pythonhosted.org/packages/23/04/e89c29e267b8060b40dca97bfc64a19b2a3cf99018167ea1677d96368273/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25e1c2af0fce638d5f1988b686f3b3ea8cd7de5f244ca147c777769e798a9cd1", size = 1915040, upload-time = "2025-11-04T13:41:00.853Z" }, + { url = "https://files.pythonhosted.org/packages/84/a3/15a82ac7bd97992a82257f777b3583d3e84bdb06ba6858f745daa2ec8a85/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:506d766a8727beef16b7adaeb8ee6217c64fc813646b424d0804d67c16eddb66", size = 2063691, upload-time = "2025-11-04T13:41:03.504Z" }, + { url = "https://files.pythonhosted.org/packages/74/9b/0046701313c6ef08c0c1cf0e028c67c770a4e1275ca73131563c5f2a310a/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4819fa52133c9aa3c387b3328f25c1facc356491e6135b459f1de698ff64d869", size = 2213897, upload-time = "2025-11-04T13:41:05.804Z" }, + { url = "https://files.pythonhosted.org/packages/8a/cd/6bac76ecd1b27e75a95ca3a9a559c643b3afcd2dd62086d4b7a32a18b169/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b761d210c9ea91feda40d25b4efe82a1707da2ef62901466a42492c028553a2", size = 2333302, upload-time = "2025-11-04T13:41:07.809Z" }, + { url = "https://files.pythonhosted.org/packages/4c/d2/ef2074dc020dd6e109611a8be4449b98cd25e1b9b8a303c2f0fca2f2bcf7/pydantic_core-2.41.5-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22f0fb8c1c583a3b6f24df2470833b40207e907b90c928cc8d3594b76f874375", size = 2064877, upload-time = "2025-11-04T13:41:09.827Z" }, + { url = "https://files.pythonhosted.org/packages/18/66/e9db17a9a763d72f03de903883c057b2592c09509ccfe468187f2a2eef29/pydantic_core-2.41.5-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2782c870e99878c634505236d81e5443092fba820f0373997ff75f90f68cd553", size = 2180680, upload-time = "2025-11-04T13:41:12.379Z" }, + { url = "https://files.pythonhosted.org/packages/d3/9e/3ce66cebb929f3ced22be85d4c2399b8e85b622db77dad36b73c5387f8f8/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:0177272f88ab8312479336e1d777f6b124537d47f2123f89cb37e0accea97f90", size = 2138960, upload-time = "2025-11-04T13:41:14.627Z" }, + { url = "https://files.pythonhosted.org/packages/a6/62/205a998f4327d2079326b01abee48e502ea739d174f0a89295c481a2272e/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:63510af5e38f8955b8ee5687740d6ebf7c2a0886d15a6d65c32814613681bc07", size = 2339102, upload-time = "2025-11-04T13:41:16.868Z" }, + { url = "https://files.pythonhosted.org/packages/3c/0d/f05e79471e889d74d3d88f5bd20d0ed189ad94c2423d81ff8d0000aab4ff/pydantic_core-2.41.5-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:e56ba91f47764cc14f1daacd723e3e82d1a89d783f0f5afe9c364b8bb491ccdb", size = 2326039, upload-time = "2025-11-04T13:41:18.934Z" }, + { url = "https://files.pythonhosted.org/packages/ec/e1/e08a6208bb100da7e0c4b288eed624a703f4d129bde2da475721a80cab32/pydantic_core-2.41.5-cp314-cp314-win32.whl", hash = "sha256:aec5cf2fd867b4ff45b9959f8b20ea3993fc93e63c7363fe6851424c8a7e7c23", size = 1995126, upload-time = "2025-11-04T13:41:21.418Z" }, + { url = "https://files.pythonhosted.org/packages/48/5d/56ba7b24e9557f99c9237e29f5c09913c81eeb2f3217e40e922353668092/pydantic_core-2.41.5-cp314-cp314-win_amd64.whl", hash = "sha256:8e7c86f27c585ef37c35e56a96363ab8de4e549a95512445b85c96d3e2f7c1bf", size = 2015489, upload-time = "2025-11-04T13:41:24.076Z" }, + { url = "https://files.pythonhosted.org/packages/4e/bb/f7a190991ec9e3e0ba22e4993d8755bbc4a32925c0b5b42775c03e8148f9/pydantic_core-2.41.5-cp314-cp314-win_arm64.whl", hash = "sha256:e672ba74fbc2dc8eea59fb6d4aed6845e6905fc2a8afe93175d94a83ba2a01a0", size = 1977288, upload-time = "2025-11-04T13:41:26.33Z" }, + { url = "https://files.pythonhosted.org/packages/92/ed/77542d0c51538e32e15afe7899d79efce4b81eee631d99850edc2f5e9349/pydantic_core-2.41.5-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:8566def80554c3faa0e65ac30ab0932b9e3a5cd7f8323764303d468e5c37595a", size = 2120255, upload-time = "2025-11-04T13:41:28.569Z" }, + { url = "https://files.pythonhosted.org/packages/bb/3d/6913dde84d5be21e284439676168b28d8bbba5600d838b9dca99de0fad71/pydantic_core-2.41.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:b80aa5095cd3109962a298ce14110ae16b8c1aece8b72f9dafe81cf597ad80b3", size = 1863760, upload-time = "2025-11-04T13:41:31.055Z" }, + { url = "https://files.pythonhosted.org/packages/5a/f0/e5e6b99d4191da102f2b0eb9687aaa7f5bea5d9964071a84effc3e40f997/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3006c3dd9ba34b0c094c544c6006cc79e87d8612999f1a5d43b769b89181f23c", size = 1878092, upload-time = "2025-11-04T13:41:33.21Z" }, + { url = "https://files.pythonhosted.org/packages/71/48/36fb760642d568925953bcc8116455513d6e34c4beaa37544118c36aba6d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:72f6c8b11857a856bcfa48c86f5368439f74453563f951e473514579d44aa612", size = 2053385, upload-time = "2025-11-04T13:41:35.508Z" }, + { url = "https://files.pythonhosted.org/packages/20/25/92dc684dd8eb75a234bc1c764b4210cf2646479d54b47bf46061657292a8/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5cb1b2f9742240e4bb26b652a5aeb840aa4b417c7748b6f8387927bc6e45e40d", size = 2218832, upload-time = "2025-11-04T13:41:37.732Z" }, + { url = "https://files.pythonhosted.org/packages/e2/09/f53e0b05023d3e30357d82eb35835d0f6340ca344720a4599cd663dca599/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bd3d54f38609ff308209bd43acea66061494157703364ae40c951f83ba99a1a9", size = 2327585, upload-time = "2025-11-04T13:41:40Z" }, + { url = "https://files.pythonhosted.org/packages/aa/4e/2ae1aa85d6af35a39b236b1b1641de73f5a6ac4d5a7509f77b814885760c/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ff4321e56e879ee8d2a879501c8e469414d948f4aba74a2d4593184eb326660", size = 2041078, upload-time = "2025-11-04T13:41:42.323Z" }, + { url = "https://files.pythonhosted.org/packages/cd/13/2e215f17f0ef326fc72afe94776edb77525142c693767fc347ed6288728d/pydantic_core-2.41.5-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d0d2568a8c11bf8225044aa94409e21da0cb09dcdafe9ecd10250b2baad531a9", size = 2173914, upload-time = "2025-11-04T13:41:45.221Z" }, + { url = "https://files.pythonhosted.org/packages/02/7a/f999a6dcbcd0e5660bc348a3991c8915ce6599f4f2c6ac22f01d7a10816c/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:a39455728aabd58ceabb03c90e12f71fd30fa69615760a075b9fec596456ccc3", size = 2129560, upload-time = "2025-11-04T13:41:47.474Z" }, + { url = "https://files.pythonhosted.org/packages/3a/b1/6c990ac65e3b4c079a4fb9f5b05f5b013afa0f4ed6780a3dd236d2cbdc64/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:239edca560d05757817c13dc17c50766136d21f7cd0fac50295499ae24f90fdf", size = 2329244, upload-time = "2025-11-04T13:41:49.992Z" }, + { url = "https://files.pythonhosted.org/packages/d9/02/3c562f3a51afd4d88fff8dffb1771b30cfdfd79befd9883ee094f5b6c0d8/pydantic_core-2.41.5-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:2a5e06546e19f24c6a96a129142a75cee553cc018ffee48a460059b1185f4470", size = 2331955, upload-time = "2025-11-04T13:41:54.079Z" }, + { url = "https://files.pythonhosted.org/packages/5c/96/5fb7d8c3c17bc8c62fdb031c47d77a1af698f1d7a406b0f79aaa1338f9ad/pydantic_core-2.41.5-cp314-cp314t-win32.whl", hash = "sha256:b4ececa40ac28afa90871c2cc2b9ffd2ff0bf749380fbdf57d165fd23da353aa", size = 1988906, upload-time = "2025-11-04T13:41:56.606Z" }, + { url = "https://files.pythonhosted.org/packages/22/ed/182129d83032702912c2e2d8bbe33c036f342cc735737064668585dac28f/pydantic_core-2.41.5-cp314-cp314t-win_amd64.whl", hash = "sha256:80aa89cad80b32a912a65332f64a4450ed00966111b6615ca6816153d3585a8c", size = 1981607, upload-time = "2025-11-04T13:41:58.889Z" }, + { url = "https://files.pythonhosted.org/packages/9f/ed/068e41660b832bb0b1aa5b58011dea2a3fe0ba7861ff38c4d4904c1c1a99/pydantic_core-2.41.5-cp314-cp314t-win_arm64.whl", hash = "sha256:35b44f37a3199f771c3eaa53051bc8a70cd7b54f333531c59e29fd4db5d15008", size = 1974769, upload-time = "2025-11-04T13:42:01.186Z" }, +] + +[[package]] +name = "pydantic-settings" +version = "2.12.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pydantic" }, + { name = "python-dotenv" }, + { name = "typing-inspection" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/43/4b/ac7e0aae12027748076d72a8764ff1c9d82ca75a7a52622e67ed3f765c54/pydantic_settings-2.12.0.tar.gz", hash = "sha256:005538ef951e3c2a68e1c08b292b5f2e71490def8589d4221b95dab00dafcfd0", size = 194184, upload-time = "2025-11-10T14:25:47.013Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c1/60/5d4751ba3f4a40a6891f24eec885f51afd78d208498268c734e256fb13c4/pydantic_settings-2.12.0-py3-none-any.whl", hash = "sha256:fddb9fd99a5b18da837b29710391e945b1e30c135477f484084ee513adb93809", size = 51880, upload-time = "2025-11-10T14:25:45.546Z" }, +] + +[[package]] +name = "pygments" +version = "2.19.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, +] + +[[package]] +name = "pymysql" +version = "1.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f5/ae/1fe3fcd9f959efa0ebe200b8de88b5a5ce3e767e38c7ac32fb179f16a388/pymysql-1.1.2.tar.gz", hash = "sha256:4961d3e165614ae65014e361811a724e2044ad3ea3739de9903ae7c21f539f03", size = 48258, upload-time = "2025-08-24T12:55:55.146Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7c/4c/ad33b92b9864cbde84f259d5df035a6447f91891f5be77788e2a3892bce3/pymysql-1.1.2-py3-none-any.whl", hash = "sha256:e6b1d89711dd51f8f74b1631fe08f039e7d76cf67a42a323d3178f0f25762ed9", size = 45300, upload-time = "2025-08-24T12:55:53.394Z" }, +] + +[[package]] +name = "pytest" +version = "9.0.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d1/db/7ef3487e0fb0049ddb5ce41d3a49c235bf9ad299b6a25d5780a89f19230f/pytest-9.0.2.tar.gz", hash = "sha256:75186651a92bd89611d1d9fc20f0b4345fd827c41ccd5c299a868a05d70edf11", size = 1568901, upload-time = "2025-12-06T21:30:51.014Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3b/ab/b3226f0bd7cdcf710fbede2b3548584366da3b19b5021e74f5bde2a8fa3f/pytest-9.0.2-py3-none-any.whl", hash = "sha256:711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b", size = 374801, upload-time = "2025-12-06T21:30:49.154Z" }, +] + +[[package]] +name = "pytest-asyncio" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/90/2c/8af215c0f776415f3590cac4f9086ccefd6fd463befeae41cd4d3f193e5a/pytest_asyncio-1.3.0.tar.gz", hash = "sha256:d7f52f36d231b80ee124cd216ffb19369aa168fc10095013c6b014a34d3ee9e5", size = 50087, upload-time = "2025-11-10T16:07:47.256Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e5/35/f8b19922b6a25bc0880171a2f1a003eaeb93657475193ab516fd87cac9da/pytest_asyncio-1.3.0-py3-none-any.whl", hash = "sha256:611e26147c7f77640e6d0a92a38ed17c3e9848063698d5c93d5aa7aa11cebff5", size = 15075, upload-time = "2025-11-10T16:07:45.537Z" }, +] + +[[package]] +name = "python-dotenv" +version = "1.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f0/26/19cadc79a718c5edbec86fd4919a6b6d3f681039a2f6d66d14be94e75fb9/python_dotenv-1.2.1.tar.gz", hash = "sha256:42667e897e16ab0d66954af0e60a9caa94f0fd4ecf3aaf6d2d260eec1aa36ad6", size = 44221, upload-time = "2025-10-26T15:12:10.434Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/14/1b/a298b06749107c305e1fe0f814c6c74aea7b2f1e10989cb30f544a1b3253/python_dotenv-1.2.1-py3-none-any.whl", hash = "sha256:b81ee9561e9ca4004139c6cbba3a238c32b03e4894671e181b671e8cb8425d61", size = 21230, upload-time = "2025-10-26T15:12:09.109Z" }, +] + +[[package]] +name = "python-multipart" +version = "0.0.21" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/78/96/804520d0850c7db98e5ccb70282e29208723f0964e88ffd9d0da2f52ea09/python_multipart-0.0.21.tar.gz", hash = "sha256:7137ebd4d3bbf70ea1622998f902b97a29434a9e8dc40eb203bbcf7c2a2cba92", size = 37196, upload-time = "2025-12-17T09:24:22.446Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/aa/76/03af049af4dcee5d27442f71b6924f01f3efb5d2bd34f23fcd563f2cc5f5/python_multipart-0.0.21-py3-none-any.whl", hash = "sha256:cf7a6713e01c87aa35387f4774e812c4361150938d20d232800f75ffcf266090", size = 24541, upload-time = "2025-12-17T09:24:21.153Z" }, +] + +[[package]] +name = "pyyaml" +version = "6.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, + { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, + { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, + { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, + { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, + { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, + { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, + { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, + { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, + { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, + { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, + { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, + { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" }, + { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" }, + { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" }, + { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" }, + { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" }, + { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" }, + { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" }, + { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" }, + { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" }, + { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, + { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, +] + +[[package]] +name = "redis" +version = "7.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/c8/983d5c6579a411d8a99bc5823cc5712768859b5ce2c8afe1a65b37832c81/redis-7.1.0.tar.gz", hash = "sha256:b1cc3cfa5a2cb9c2ab3ba700864fb0ad75617b41f01352ce5779dabf6d5f9c3c", size = 4796669, upload-time = "2025-11-19T15:54:39.961Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/89/f0/8956f8a86b20d7bb9d6ac0187cf4cd54d8065bc9a1a09eb8011d4d326596/redis-7.1.0-py3-none-any.whl", hash = "sha256:23c52b208f92b56103e17c5d06bdc1a6c2c0b3106583985a76a18f83b265de2b", size = 354159, upload-time = "2025-11-19T15:54:38.064Z" }, +] + +[[package]] +name = "rich" +version = "14.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fb/d2/8920e102050a0de7bfabeb4c4614a49248cf8d5d7a8d01885fbb24dc767a/rich-14.2.0.tar.gz", hash = "sha256:73ff50c7c0c1c77c8243079283f4edb376f0f6442433aecb8ce7e6d0b92d1fe4", size = 219990, upload-time = "2025-10-09T14:16:53.064Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/25/7a/b0178788f8dc6cafce37a212c99565fa1fe7872c70c6c9c1e1a372d9d88f/rich-14.2.0-py3-none-any.whl", hash = "sha256:76bc51fe2e57d2b1be1f96c524b890b816e334ab4c1e45888799bfaab0021edd", size = 243393, upload-time = "2025-10-09T14:16:51.245Z" }, +] + +[[package]] +name = "rich-toolkit" +version = "0.17.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "rich" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/97/09/3f9b8d9daaf235195c626f21e03604c05b987404ee3bcacee0c1f67f2a8e/rich_toolkit-0.17.1.tar.gz", hash = "sha256:5af54df8d1dd9c8530e462e1bdcaed625c9b49f5a55b035aa0ba1c17bdb87c9a", size = 187925, upload-time = "2025-12-17T10:49:22.583Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7f/7b/15e55fa8a76d0d41bf34d965af78acdaf80a315907adb30de8b63c272694/rich_toolkit-0.17.1-py3-none-any.whl", hash = "sha256:96d24bb921ecd225ffce7c526a9149e74006410c05e6d405bd74ffd54d5631ed", size = 31412, upload-time = "2025-12-17T10:49:21.793Z" }, +] + +[[package]] +name = "rignore" +version = "0.7.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e5/f5/8bed2310abe4ae04b67a38374a4d311dd85220f5d8da56f47ae9361be0b0/rignore-0.7.6.tar.gz", hash = "sha256:00d3546cd793c30cb17921ce674d2c8f3a4b00501cb0e3dd0e82217dbeba2671", size = 57140, upload-time = "2025-11-05T21:41:21.968Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/8a/a4078f6e14932ac7edb171149c481de29969d96ddee3ece5dc4c26f9e0c3/rignore-0.7.6-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:2bdab1d31ec9b4fb1331980ee49ea051c0d7f7bb6baa28b3125ef03cdc48fdaf", size = 883057, upload-time = "2025-11-05T20:42:42.741Z" }, + { url = "https://files.pythonhosted.org/packages/f9/8f/f8daacd177db4bf7c2223bab41e630c52711f8af9ed279be2058d2fe4982/rignore-0.7.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:90f0a00ce0c866c275bf888271f1dc0d2140f29b82fcf33cdbda1e1a6af01010", size = 820150, upload-time = "2025-11-05T20:42:26.545Z" }, + { url = "https://files.pythonhosted.org/packages/36/31/b65b837e39c3f7064c426754714ac633b66b8c2290978af9d7f513e14aa9/rignore-0.7.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1ad295537041dc2ed4b540fb1a3906bd9ede6ccdad3fe79770cd89e04e3c73c", size = 897406, upload-time = "2025-11-05T20:40:53.854Z" }, + { url = "https://files.pythonhosted.org/packages/ca/58/1970ce006c427e202ac7c081435719a076c478f07b3a23f469227788dc23/rignore-0.7.6-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f782dbd3a65a5ac85adfff69e5c6b101285ef3f845c3a3cae56a54bebf9fe116", size = 874050, upload-time = "2025-11-05T20:41:08.922Z" }, + { url = "https://files.pythonhosted.org/packages/d4/00/eb45db9f90137329072a732273be0d383cb7d7f50ddc8e0bceea34c1dfdf/rignore-0.7.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:65cece3b36e5b0826d946494734c0e6aaf5a0337e18ff55b071438efe13d559e", size = 1167835, upload-time = "2025-11-05T20:41:24.997Z" }, + { url = "https://files.pythonhosted.org/packages/f3/f1/6f1d72ddca41a64eed569680587a1236633587cc9f78136477ae69e2c88a/rignore-0.7.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d7e4bb66c13cd7602dc8931822c02dfbbd5252015c750ac5d6152b186f0a8be0", size = 941945, upload-time = "2025-11-05T20:41:40.628Z" }, + { url = "https://files.pythonhosted.org/packages/48/6f/2f178af1c1a276a065f563ec1e11e7a9e23d4996fd0465516afce4b5c636/rignore-0.7.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:297e500c15766e196f68aaaa70e8b6db85fa23fdc075b880d8231fdfba738cd7", size = 959067, upload-time = "2025-11-05T20:42:11.09Z" }, + { url = "https://files.pythonhosted.org/packages/5b/db/423a81c4c1e173877c7f9b5767dcaf1ab50484a94f60a0b2ed78be3fa765/rignore-0.7.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a07084211a8d35e1a5b1d32b9661a5ed20669970b369df0cf77da3adea3405de", size = 984438, upload-time = "2025-11-05T20:41:55.443Z" }, + { url = "https://files.pythonhosted.org/packages/31/eb/c4f92cc3f2825d501d3c46a244a671eb737fc1bcf7b05a3ecd34abb3e0d7/rignore-0.7.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:181eb2a975a22256a1441a9d2f15eb1292839ea3f05606620bd9e1938302cf79", size = 1078365, upload-time = "2025-11-05T21:40:15.148Z" }, + { url = "https://files.pythonhosted.org/packages/26/09/99442f02794bd7441bfc8ed1c7319e890449b816a7493b2db0e30af39095/rignore-0.7.6-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:7bbcdc52b5bf9f054b34ce4af5269df5d863d9c2456243338bc193c28022bd7b", size = 1139066, upload-time = "2025-11-05T21:40:32.771Z" }, + { url = "https://files.pythonhosted.org/packages/2c/88/bcfc21e520bba975410e9419450f4b90a2ac8236b9a80fd8130e87d098af/rignore-0.7.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f2e027a6da21a7c8c0d87553c24ca5cc4364def18d146057862c23a96546238e", size = 1118036, upload-time = "2025-11-05T21:40:49.646Z" }, + { url = "https://files.pythonhosted.org/packages/e2/25/d37215e4562cda5c13312636393aea0bafe38d54d4e0517520a4cc0753ec/rignore-0.7.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ee4a18b82cbbc648e4aac1510066682fe62beb5dc88e2c67c53a83954e541360", size = 1127550, upload-time = "2025-11-05T21:41:07.648Z" }, + { url = "https://files.pythonhosted.org/packages/dc/76/a264ab38bfa1620ec12a8ff1c07778da89e16d8c0f3450b0333020d3d6dc/rignore-0.7.6-cp313-cp313-win32.whl", hash = "sha256:a7d7148b6e5e95035d4390396895adc384d37ff4e06781a36fe573bba7c283e5", size = 646097, upload-time = "2025-11-05T21:41:53.201Z" }, + { url = "https://files.pythonhosted.org/packages/62/44/3c31b8983c29ea8832b6082ddb1d07b90379c2d993bd20fce4487b71b4f4/rignore-0.7.6-cp313-cp313-win_amd64.whl", hash = "sha256:b037c4b15a64dced08fc12310ee844ec2284c4c5c1ca77bc37d0a04f7bff386e", size = 726170, upload-time = "2025-11-05T21:41:38.131Z" }, + { url = "https://files.pythonhosted.org/packages/aa/41/e26a075cab83debe41a42661262f606166157df84e0e02e2d904d134c0d8/rignore-0.7.6-cp313-cp313-win_arm64.whl", hash = "sha256:e47443de9b12fe569889bdbe020abe0e0b667516ee2ab435443f6d0869bd2804", size = 656184, upload-time = "2025-11-05T21:41:27.396Z" }, + { url = "https://files.pythonhosted.org/packages/9a/b9/1f5bd82b87e5550cd843ceb3768b4a8ef274eb63f29333cf2f29644b3d75/rignore-0.7.6-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:8e41be9fa8f2f47239ded8920cc283699a052ac4c371f77f5ac017ebeed75732", size = 882632, upload-time = "2025-11-05T20:42:44.063Z" }, + { url = "https://files.pythonhosted.org/packages/e9/6b/07714a3efe4a8048864e8a5b7db311ba51b921e15268b17defaebf56d3db/rignore-0.7.6-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:6dc1e171e52cefa6c20e60c05394a71165663b48bca6c7666dee4f778f2a7d90", size = 820760, upload-time = "2025-11-05T20:42:27.885Z" }, + { url = "https://files.pythonhosted.org/packages/ac/0f/348c829ea2d8d596e856371b14b9092f8a5dfbb62674ec9b3f67e4939a9d/rignore-0.7.6-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ce2268837c3600f82ab8db58f5834009dc638ee17103582960da668963bebc5", size = 899044, upload-time = "2025-11-05T20:40:55.336Z" }, + { url = "https://files.pythonhosted.org/packages/f0/30/2e1841a19b4dd23878d73edd5d82e998a83d5ed9570a89675f140ca8b2ad/rignore-0.7.6-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:690a3e1b54bfe77e89c4bacb13f046e642f8baadafc61d68f5a726f324a76ab6", size = 874144, upload-time = "2025-11-05T20:41:10.195Z" }, + { url = "https://files.pythonhosted.org/packages/c2/bf/0ce9beb2e5f64c30e3580bef09f5829236889f01511a125f98b83169b993/rignore-0.7.6-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09d12ac7a0b6210c07bcd145007117ebd8abe99c8eeb383e9e4673910c2754b2", size = 1168062, upload-time = "2025-11-05T20:41:26.511Z" }, + { url = "https://files.pythonhosted.org/packages/b9/8b/571c178414eb4014969865317da8a02ce4cf5241a41676ef91a59aab24de/rignore-0.7.6-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2a2b2b74a8c60203b08452479b90e5ce3dbe96a916214bc9eb2e5af0b6a9beb0", size = 942542, upload-time = "2025-11-05T20:41:41.838Z" }, + { url = "https://files.pythonhosted.org/packages/19/62/7a3cf601d5a45137a7e2b89d10c05b5b86499190c4b7ca5c3c47d79ee519/rignore-0.7.6-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8fc5a531ef02131e44359419a366bfac57f773ea58f5278c2cdd915f7d10ea94", size = 958739, upload-time = "2025-11-05T20:42:12.463Z" }, + { url = "https://files.pythonhosted.org/packages/5f/1f/4261f6a0d7caf2058a5cde2f5045f565ab91aa7badc972b57d19ce58b14e/rignore-0.7.6-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b7a1f77d9c4cd7e76229e252614d963442686bfe12c787a49f4fe481df49e7a9", size = 984138, upload-time = "2025-11-05T20:41:56.775Z" }, + { url = "https://files.pythonhosted.org/packages/2b/bf/628dfe19c75e8ce1f45f7c248f5148b17dfa89a817f8e3552ab74c3ae812/rignore-0.7.6-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ead81f728682ba72b5b1c3d5846b011d3e0174da978de87c61645f2ed36659a7", size = 1079299, upload-time = "2025-11-05T21:40:16.639Z" }, + { url = "https://files.pythonhosted.org/packages/af/a5/be29c50f5c0c25c637ed32db8758fdf5b901a99e08b608971cda8afb293b/rignore-0.7.6-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:12ffd50f520c22ffdabed8cd8bfb567d9ac165b2b854d3e679f4bcaef11a9441", size = 1139618, upload-time = "2025-11-05T21:40:34.507Z" }, + { url = "https://files.pythonhosted.org/packages/2a/40/3c46cd7ce4fa05c20b525fd60f599165e820af66e66f2c371cd50644558f/rignore-0.7.6-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:e5a16890fbe3c894f8ca34b0fcacc2c200398d4d46ae654e03bc9b3dbf2a0a72", size = 1117626, upload-time = "2025-11-05T21:40:51.494Z" }, + { url = "https://files.pythonhosted.org/packages/8c/b9/aea926f263b8a29a23c75c2e0d8447965eb1879d3feb53cfcf84db67ed58/rignore-0.7.6-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:3abab3bf99e8a77488ef6c7c9a799fac22224c28fe9f25cc21aa7cc2b72bfc0b", size = 1128144, upload-time = "2025-11-05T21:41:09.169Z" }, + { url = "https://files.pythonhosted.org/packages/a4/f6/0d6242f8d0df7f2ecbe91679fefc1f75e7cd2072cb4f497abaab3f0f8523/rignore-0.7.6-cp314-cp314-win32.whl", hash = "sha256:eeef421c1782953c4375aa32f06ecae470c1285c6381eee2a30d2e02a5633001", size = 646385, upload-time = "2025-11-05T21:41:55.105Z" }, + { url = "https://files.pythonhosted.org/packages/d5/38/c0dcd7b10064f084343d6af26fe9414e46e9619c5f3224b5272e8e5d9956/rignore-0.7.6-cp314-cp314-win_amd64.whl", hash = "sha256:6aeed503b3b3d5af939b21d72a82521701a4bd3b89cd761da1e7dc78621af304", size = 725738, upload-time = "2025-11-05T21:41:39.736Z" }, + { url = "https://files.pythonhosted.org/packages/d9/7a/290f868296c1ece914d565757ab363b04730a728b544beb567ceb3b2d96f/rignore-0.7.6-cp314-cp314-win_arm64.whl", hash = "sha256:104f215b60b3c984c386c3e747d6ab4376d5656478694e22c7bd2f788ddd8304", size = 656008, upload-time = "2025-11-05T21:41:29.028Z" }, + { url = "https://files.pythonhosted.org/packages/ca/d2/3c74e3cd81fe8ea08a8dcd2d755c09ac2e8ad8fe409508904557b58383d3/rignore-0.7.6-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:bb24a5b947656dd94cb9e41c4bc8b23cec0c435b58be0d74a874f63c259549e8", size = 882835, upload-time = "2025-11-05T20:42:45.443Z" }, + { url = "https://files.pythonhosted.org/packages/77/61/a772a34b6b63154877433ac2d048364815b24c2dd308f76b212c408101a2/rignore-0.7.6-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5b1e33c9501cefe24b70a1eafd9821acfd0ebf0b35c3a379430a14df089993e3", size = 820301, upload-time = "2025-11-05T20:42:29.226Z" }, + { url = "https://files.pythonhosted.org/packages/71/30/054880b09c0b1b61d17eeb15279d8bf729c0ba52b36c3ada52fb827cbb3c/rignore-0.7.6-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bec3994665a44454df86deb762061e05cd4b61e3772f5b07d1882a8a0d2748d5", size = 897611, upload-time = "2025-11-05T20:40:56.475Z" }, + { url = "https://files.pythonhosted.org/packages/1e/40/b2d1c169f833d69931bf232600eaa3c7998ba4f9a402e43a822dad2ea9f2/rignore-0.7.6-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:26cba2edfe3cff1dfa72bddf65d316ddebf182f011f2f61538705d6dbaf54986", size = 873875, upload-time = "2025-11-05T20:41:11.561Z" }, + { url = "https://files.pythonhosted.org/packages/55/59/ca5ae93d83a1a60e44b21d87deb48b177a8db1b85e82fc8a9abb24a8986d/rignore-0.7.6-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ffa86694fec604c613696cb91e43892aa22e1fec5f9870e48f111c603e5ec4e9", size = 1167245, upload-time = "2025-11-05T20:41:28.29Z" }, + { url = "https://files.pythonhosted.org/packages/a5/52/cf3dce392ba2af806cba265aad6bcd9c48bb2a6cb5eee448d3319f6e505b/rignore-0.7.6-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48efe2ed95aa8104145004afb15cdfa02bea5cdde8b0344afeb0434f0d989aa2", size = 941750, upload-time = "2025-11-05T20:41:43.111Z" }, + { url = "https://files.pythonhosted.org/packages/ec/be/3f344c6218d779395e785091d05396dfd8b625f6aafbe502746fcd880af2/rignore-0.7.6-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8dcae43eb44b7f2457fef7cc87f103f9a0013017a6f4e62182c565e924948f21", size = 958896, upload-time = "2025-11-05T20:42:13.784Z" }, + { url = "https://files.pythonhosted.org/packages/c9/34/d3fa71938aed7d00dcad87f0f9bcb02ad66c85d6ffc83ba31078ce53646a/rignore-0.7.6-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2cd649a7091c0dad2f11ef65630d30c698d505cbe8660dd395268e7c099cc99f", size = 983992, upload-time = "2025-11-05T20:41:58.022Z" }, + { url = "https://files.pythonhosted.org/packages/24/a4/52a697158e9920705bdbd0748d59fa63e0f3233fb92e9df9a71afbead6ca/rignore-0.7.6-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:42de84b0289d478d30ceb7ae59023f7b0527786a9a5b490830e080f0e4ea5aeb", size = 1078181, upload-time = "2025-11-05T21:40:18.151Z" }, + { url = "https://files.pythonhosted.org/packages/ac/65/aa76dbcdabf3787a6f0fd61b5cc8ed1e88580590556d6c0207960d2384bb/rignore-0.7.6-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:875a617e57b53b4acbc5a91de418233849711c02e29cc1f4f9febb2f928af013", size = 1139232, upload-time = "2025-11-05T21:40:35.966Z" }, + { url = "https://files.pythonhosted.org/packages/08/44/31b31a49b3233c6842acc1c0731aa1e7fb322a7170612acf30327f700b44/rignore-0.7.6-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:8703998902771e96e49968105207719f22926e4431b108450f3f430b4e268b7c", size = 1117349, upload-time = "2025-11-05T21:40:53.013Z" }, + { url = "https://files.pythonhosted.org/packages/e9/ae/1b199a2302c19c658cf74e5ee1427605234e8c91787cfba0015f2ace145b/rignore-0.7.6-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:602ef33f3e1b04c1e9a10a3c03f8bc3cef2d2383dcc250d309be42b49923cabc", size = 1127702, upload-time = "2025-11-05T21:41:10.881Z" }, + { url = "https://files.pythonhosted.org/packages/fc/d3/18210222b37e87e36357f7b300b7d98c6dd62b133771e71ae27acba83a4f/rignore-0.7.6-cp314-cp314t-win32.whl", hash = "sha256:c1d8f117f7da0a4a96a8daef3da75bc090e3792d30b8b12cfadc240c631353f9", size = 647033, upload-time = "2025-11-05T21:42:00.095Z" }, + { url = "https://files.pythonhosted.org/packages/3e/87/033eebfbee3ec7d92b3bb1717d8f68c88e6fc7de54537040f3b3a405726f/rignore-0.7.6-cp314-cp314t-win_amd64.whl", hash = "sha256:ca36e59408bec81de75d307c568c2d0d410fb880b1769be43611472c61e85c96", size = 725647, upload-time = "2025-11-05T21:41:44.449Z" }, + { url = "https://files.pythonhosted.org/packages/79/62/b88e5879512c55b8ee979c666ee6902adc4ed05007226de266410ae27965/rignore-0.7.6-cp314-cp314t-win_arm64.whl", hash = "sha256:b83adabeb3e8cf662cabe1931b83e165b88c526fa6af6b3aa90429686e474896", size = 656035, upload-time = "2025-11-05T21:41:31.13Z" }, +] + +[[package]] +name = "ruff" +version = "0.14.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/57/08/52232a877978dd8f9cf2aeddce3e611b40a63287dfca29b6b8da791f5e8d/ruff-0.14.10.tar.gz", hash = "sha256:9a2e830f075d1a42cd28420d7809ace390832a490ed0966fe373ba288e77aaf4", size = 5859763, upload-time = "2025-12-18T19:28:57.98Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/60/01/933704d69f3f05ee16ef11406b78881733c186fe14b6a46b05cfcaf6d3b2/ruff-0.14.10-py3-none-linux_armv6l.whl", hash = "sha256:7a3ce585f2ade3e1f29ec1b92df13e3da262178df8c8bdf876f48fa0e8316c49", size = 13527080, upload-time = "2025-12-18T19:29:25.642Z" }, + { url = "https://files.pythonhosted.org/packages/df/58/a0349197a7dfa603ffb7f5b0470391efa79ddc327c1e29c4851e85b09cc5/ruff-0.14.10-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:674f9be9372907f7257c51f1d4fc902cb7cf014b9980152b802794317941f08f", size = 13797320, upload-time = "2025-12-18T19:29:02.571Z" }, + { url = "https://files.pythonhosted.org/packages/7b/82/36be59f00a6082e38c23536df4e71cdbc6af8d7c707eade97fcad5c98235/ruff-0.14.10-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d85713d522348837ef9df8efca33ccb8bd6fcfc86a2cde3ccb4bc9d28a18003d", size = 12918434, upload-time = "2025-12-18T19:28:51.202Z" }, + { url = "https://files.pythonhosted.org/packages/a6/00/45c62a7f7e34da92a25804f813ebe05c88aa9e0c25e5cb5a7d23dd7450e3/ruff-0.14.10-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6987ebe0501ae4f4308d7d24e2d0fe3d7a98430f5adfd0f1fead050a740a3a77", size = 13371961, upload-time = "2025-12-18T19:29:04.991Z" }, + { url = "https://files.pythonhosted.org/packages/40/31/a5906d60f0405f7e57045a70f2d57084a93ca7425f22e1d66904769d1628/ruff-0.14.10-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:16a01dfb7b9e4eee556fbfd5392806b1b8550c9b4a9f6acd3dbe6812b193c70a", size = 13275629, upload-time = "2025-12-18T19:29:21.381Z" }, + { url = "https://files.pythonhosted.org/packages/3e/60/61c0087df21894cf9d928dc04bcd4fb10e8b2e8dca7b1a276ba2155b2002/ruff-0.14.10-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7165d31a925b7a294465fa81be8c12a0e9b60fb02bf177e79067c867e71f8b1f", size = 14029234, upload-time = "2025-12-18T19:29:00.132Z" }, + { url = "https://files.pythonhosted.org/packages/44/84/77d911bee3b92348b6e5dab5a0c898d87084ea03ac5dc708f46d88407def/ruff-0.14.10-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:c561695675b972effb0c0a45db233f2c816ff3da8dcfbe7dfc7eed625f218935", size = 15449890, upload-time = "2025-12-18T19:28:53.573Z" }, + { url = "https://files.pythonhosted.org/packages/e9/36/480206eaefa24a7ec321582dda580443a8f0671fdbf6b1c80e9c3e93a16a/ruff-0.14.10-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4bb98fcbbc61725968893682fd4df8966a34611239c9fd07a1f6a07e7103d08e", size = 15123172, upload-time = "2025-12-18T19:29:23.453Z" }, + { url = "https://files.pythonhosted.org/packages/5c/38/68e414156015ba80cef5473d57919d27dfb62ec804b96180bafdeaf0e090/ruff-0.14.10-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f24b47993a9d8cb858429e97bdf8544c78029f09b520af615c1d261bf827001d", size = 14460260, upload-time = "2025-12-18T19:29:27.808Z" }, + { url = "https://files.pythonhosted.org/packages/b3/19/9e050c0dca8aba824d67cc0db69fb459c28d8cd3f6855b1405b3f29cc91d/ruff-0.14.10-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59aabd2e2c4fd614d2862e7939c34a532c04f1084476d6833dddef4afab87e9f", size = 14229978, upload-time = "2025-12-18T19:29:11.32Z" }, + { url = "https://files.pythonhosted.org/packages/51/eb/e8dd1dd6e05b9e695aa9dd420f4577debdd0f87a5ff2fedda33c09e9be8c/ruff-0.14.10-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:213db2b2e44be8625002dbea33bb9c60c66ea2c07c084a00d55732689d697a7f", size = 14338036, upload-time = "2025-12-18T19:29:09.184Z" }, + { url = "https://files.pythonhosted.org/packages/6a/12/f3e3a505db7c19303b70af370d137795fcfec136d670d5de5391e295c134/ruff-0.14.10-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:b914c40ab64865a17a9a5b67911d14df72346a634527240039eb3bd650e5979d", size = 13264051, upload-time = "2025-12-18T19:29:13.431Z" }, + { url = "https://files.pythonhosted.org/packages/08/64/8c3a47eaccfef8ac20e0484e68e0772013eb85802f8a9f7603ca751eb166/ruff-0.14.10-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:1484983559f026788e3a5c07c81ef7d1e97c1c78ed03041a18f75df104c45405", size = 13283998, upload-time = "2025-12-18T19:29:06.994Z" }, + { url = "https://files.pythonhosted.org/packages/12/84/534a5506f4074e5cc0529e5cd96cfc01bb480e460c7edf5af70d2bcae55e/ruff-0.14.10-py3-none-musllinux_1_2_i686.whl", hash = "sha256:c70427132db492d25f982fffc8d6c7535cc2fd2c83fc8888f05caaa248521e60", size = 13601891, upload-time = "2025-12-18T19:28:55.811Z" }, + { url = "https://files.pythonhosted.org/packages/0d/1e/14c916087d8598917dbad9b2921d340f7884824ad6e9c55de948a93b106d/ruff-0.14.10-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5bcf45b681e9f1ee6445d317ce1fa9d6cba9a6049542d1c3d5b5958986be8830", size = 14336660, upload-time = "2025-12-18T19:29:16.531Z" }, + { url = "https://files.pythonhosted.org/packages/f2/1c/d7b67ab43f30013b47c12b42d1acd354c195351a3f7a1d67f59e54227ede/ruff-0.14.10-py3-none-win32.whl", hash = "sha256:104c49fc7ab73f3f3a758039adea978869a918f31b73280db175b43a2d9b51d6", size = 13196187, upload-time = "2025-12-18T19:29:19.006Z" }, + { url = "https://files.pythonhosted.org/packages/fb/9c/896c862e13886fae2af961bef3e6312db9ebc6adc2b156fe95e615dee8c1/ruff-0.14.10-py3-none-win_amd64.whl", hash = "sha256:466297bd73638c6bdf06485683e812db1c00c7ac96d4ddd0294a338c62fdc154", size = 14661283, upload-time = "2025-12-18T19:29:30.16Z" }, + { url = "https://files.pythonhosted.org/packages/74/31/b0e29d572670dca3674eeee78e418f20bdf97fa8aa9ea71380885e175ca0/ruff-0.14.10-py3-none-win_arm64.whl", hash = "sha256:e51d046cf6dda98a4633b8a8a771451107413b0f07183b2bef03f075599e44e6", size = 13729839, upload-time = "2025-12-18T19:28:48.636Z" }, +] + +[[package]] +name = "scalar-fastapi" +version = "1.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b2/1a/4897819ef5682f40cce1f9b552a1e002d394bf7e12e5d6fe62f843ffef51/scalar_fastapi-1.5.0.tar.gz", hash = "sha256:5ae887fcc0db63305dc41dc39d61f7be183256085872aa33b294e0d48e29901e", size = 7447, upload-time = "2025-12-04T19:44:12.04Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7a/cc/c0712ac83a31ae96785d9916d7be54595914aa93375ea5df3ba3eadab8af/scalar_fastapi-1.5.0-py3-none-any.whl", hash = "sha256:8e712599ccdfbb614bff5583fdbee1bef03e5fac1e06520287337ff232cb667a", size = 6828, upload-time = "2025-12-04T19:44:11.242Z" }, +] + +[[package]] +name = "sentry-sdk" +version = "2.48.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/40/f0/0e9dc590513d5e742d7799e2038df3a05167cba084c6ca4f3cdd75b55164/sentry_sdk-2.48.0.tar.gz", hash = "sha256:5213190977ff7fdff8a58b722fb807f8d5524a80488626ebeda1b5676c0c1473", size = 384828, upload-time = "2025-12-16T14:55:41.722Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4d/19/8d77f9992e5cbfcaa9133c3bf63b4fbbb051248802e1e803fed5c552fbb2/sentry_sdk-2.48.0-py2.py3-none-any.whl", hash = "sha256:6b12ac256769d41825d9b7518444e57fa35b5642df4c7c5e322af4d2c8721172", size = 414555, upload-time = "2025-12-16T14:55:40.152Z" }, +] + +[[package]] +name = "shellingham" +version = "1.5.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310, upload-time = "2023-10-24T04:13:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, +] + +[[package]] +name = "sniffio" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372, upload-time = "2024-02-25T23:20:04.057Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" }, +] + +[[package]] +name = "soupsieve" +version = "2.8.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/89/23/adf3796d740536d63a6fbda113d07e60c734b6ed5d3058d1e47fc0495e47/soupsieve-2.8.1.tar.gz", hash = "sha256:4cf733bc50fa805f5df4b8ef4740fc0e0fa6218cf3006269afd3f9d6d80fd350", size = 117856, upload-time = "2025-12-18T13:50:34.655Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/48/f3/b67d6ea49ca9154453b6d70b34ea22f3996b9fa55da105a79d8732227adc/soupsieve-2.8.1-py3-none-any.whl", hash = "sha256:a11fe2a6f3d76ab3cf2de04eb339c1be5b506a8a47f2ceb6d139803177f85434", size = 36710, upload-time = "2025-12-18T13:50:33.267Z" }, +] + +[[package]] +name = "sqladmin" +version = "0.22.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jinja2" }, + { name = "python-multipart" }, + { name = "sqlalchemy" }, + { name = "starlette" }, + { name = "wtforms" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2c/ac/526bb3ff2dd94fbf8442bccb49ef40aa360045add19d4fbffcb43995e67a/sqladmin-0.22.0.tar.gz", hash = "sha256:4ea904d97e4d030edb68fb0681330b4d963f422442a64bee487fdc46119b3729", size = 1429937, upload-time = "2025-11-24T12:52:59.285Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f2/b4/ab78c7d7b13bd3f90d6d8a106c5ad12bf7a738f89eb0241b24ad8efe5d1e/sqladmin-0.22.0-py3-none-any.whl", hash = "sha256:f2fb11165a70601a97f71956104b47da2c432db49b0d7966dc65e9e6343887d3", size = 1445514, upload-time = "2025-11-24T12:53:00.511Z" }, +] + +[package.optional-dependencies] +full = [ + { name = "itsdangerous" }, +] + +[[package]] +name = "sqlalchemy" +version = "2.0.45" +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/be/f9/5e4491e5ccf42f5d9cfc663741d261b3e6e1683ae7812114e7636409fcc6/sqlalchemy-2.0.45.tar.gz", hash = "sha256:1632a4bda8d2d25703fdad6363058d882541bdaaee0e5e3ddfa0cd3229efce88", size = 9869912, upload-time = "2025-12-09T21:05:16.737Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6a/c8/7cc5221b47a54edc72a0140a1efa56e0a2730eefa4058d7ed0b4c4357ff8/sqlalchemy-2.0.45-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fe187fc31a54d7fd90352f34e8c008cf3ad5d064d08fedd3de2e8df83eb4a1cf", size = 3277082, upload-time = "2025-12-09T22:11:06.167Z" }, + { url = "https://files.pythonhosted.org/packages/0e/50/80a8d080ac7d3d321e5e5d420c9a522b0aa770ec7013ea91f9a8b7d36e4a/sqlalchemy-2.0.45-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:672c45cae53ba88e0dad74b9027dddd09ef6f441e927786b05bec75d949fbb2e", size = 3293131, upload-time = "2025-12-09T22:13:52.626Z" }, + { url = "https://files.pythonhosted.org/packages/da/4c/13dab31266fc9904f7609a5dc308a2432a066141d65b857760c3bef97e69/sqlalchemy-2.0.45-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:470daea2c1ce73910f08caf10575676a37159a6d16c4da33d0033546bddebc9b", size = 3225389, upload-time = "2025-12-09T22:11:08.093Z" }, + { url = "https://files.pythonhosted.org/packages/74/04/891b5c2e9f83589de202e7abaf24cd4e4fa59e1837d64d528829ad6cc107/sqlalchemy-2.0.45-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9c6378449e0940476577047150fd09e242529b761dc887c9808a9a937fe990c8", size = 3266054, upload-time = "2025-12-09T22:13:54.262Z" }, + { url = "https://files.pythonhosted.org/packages/f1/24/fc59e7f71b0948cdd4cff7a286210e86b0443ef1d18a23b0d83b87e4b1f7/sqlalchemy-2.0.45-cp313-cp313-win32.whl", hash = "sha256:4b6bec67ca45bc166c8729910bd2a87f1c0407ee955df110d78948f5b5827e8a", size = 2110299, upload-time = "2025-12-09T21:39:33.486Z" }, + { url = "https://files.pythonhosted.org/packages/c0/c5/d17113020b2d43073412aeca09b60d2009442420372123b8d49cc253f8b8/sqlalchemy-2.0.45-cp313-cp313-win_amd64.whl", hash = "sha256:afbf47dc4de31fa38fd491f3705cac5307d21d4bb828a4f020ee59af412744ee", size = 2136264, upload-time = "2025-12-09T21:39:36.801Z" }, + { url = "https://files.pythonhosted.org/packages/3d/8d/bb40a5d10e7a5f2195f235c0b2f2c79b0bf6e8f00c0c223130a4fbd2db09/sqlalchemy-2.0.45-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:83d7009f40ce619d483d26ac1b757dfe3167b39921379a8bd1b596cf02dab4a6", size = 3521998, upload-time = "2025-12-09T22:13:28.622Z" }, + { url = "https://files.pythonhosted.org/packages/75/a5/346128b0464886f036c039ea287b7332a410aa2d3fb0bb5d404cb8861635/sqlalchemy-2.0.45-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:d8a2ca754e5415cde2b656c27900b19d50ba076aa05ce66e2207623d3fe41f5a", size = 3473434, upload-time = "2025-12-09T22:13:30.188Z" }, + { url = "https://files.pythonhosted.org/packages/cc/64/4e1913772646b060b025d3fc52ce91a58967fe58957df32b455de5a12b4f/sqlalchemy-2.0.45-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7f46ec744e7f51275582e6a24326e10c49fbdd3fc99103e01376841213028774", size = 3272404, upload-time = "2025-12-09T22:11:09.662Z" }, + { url = "https://files.pythonhosted.org/packages/b3/27/caf606ee924282fe4747ee4fd454b335a72a6e018f97eab5ff7f28199e16/sqlalchemy-2.0.45-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:883c600c345123c033c2f6caca18def08f1f7f4c3ebeb591a63b6fceffc95cce", size = 3277057, upload-time = "2025-12-09T22:13:56.213Z" }, + { url = "https://files.pythonhosted.org/packages/85/d0/3d64218c9724e91f3d1574d12eb7ff8f19f937643815d8daf792046d88ab/sqlalchemy-2.0.45-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:2c0b74aa79e2deade948fe8593654c8ef4228c44ba862bb7c9585c8e0db90f33", size = 3222279, upload-time = "2025-12-09T22:11:11.1Z" }, + { url = "https://files.pythonhosted.org/packages/24/10/dd7688a81c5bc7690c2a3764d55a238c524cd1a5a19487928844cb247695/sqlalchemy-2.0.45-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:8a420169cef179d4c9064365f42d779f1e5895ad26ca0c8b4c0233920973db74", size = 3244508, upload-time = "2025-12-09T22:13:57.932Z" }, + { url = "https://files.pythonhosted.org/packages/aa/41/db75756ca49f777e029968d9c9fee338c7907c563267740c6d310a8e3f60/sqlalchemy-2.0.45-cp314-cp314-win32.whl", hash = "sha256:e50dcb81a5dfe4b7b4a4aa8f338116d127cb209559124f3694c70d6cd072b68f", size = 2113204, upload-time = "2025-12-09T21:39:38.365Z" }, + { url = "https://files.pythonhosted.org/packages/89/a2/0e1590e9adb292b1d576dbcf67ff7df8cf55e56e78d2c927686d01080f4b/sqlalchemy-2.0.45-cp314-cp314-win_amd64.whl", hash = "sha256:4748601c8ea959e37e03d13dcda4a44837afcd1b21338e637f7c935b8da06177", size = 2138785, upload-time = "2025-12-09T21:39:39.503Z" }, + { url = "https://files.pythonhosted.org/packages/42/39/f05f0ed54d451156bbed0e23eb0516bcad7cbb9f18b3bf219c786371b3f0/sqlalchemy-2.0.45-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cd337d3526ec5298f67d6a30bbbe4ed7e5e68862f0bf6dd21d289f8d37b7d60b", size = 3522029, upload-time = "2025-12-09T22:13:32.09Z" }, + { url = "https://files.pythonhosted.org/packages/54/0f/d15398b98b65c2bce288d5ee3f7d0a81f77ab89d9456994d5c7cc8b2a9db/sqlalchemy-2.0.45-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9a62b446b7d86a3909abbcd1cd3cc550a832f99c2bc37c5b22e1925438b9367b", size = 3475142, upload-time = "2025-12-09T22:13:33.739Z" }, + { url = "https://files.pythonhosted.org/packages/bf/e1/3ccb13c643399d22289c6a9786c1a91e3dcbb68bce4beb44926ac2c557bf/sqlalchemy-2.0.45-py3-none-any.whl", hash = "sha256:5225a288e4c8cc2308dbdd874edad6e7d0fd38eac1e9e5f23503425c8eee20d0", size = 1936672, upload-time = "2025-12-09T21:54:52.608Z" }, +] + +[package.optional-dependencies] +asyncio = [ + { name = "greenlet" }, +] + +[[package]] +name = "starlette" +version = "0.50.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ba/b8/73a0e6a6e079a9d9cfa64113d771e421640b6f679a52eeb9b32f72d871a1/starlette-0.50.0.tar.gz", hash = "sha256:a2a17b22203254bcbc2e1f926d2d55f3f9497f769416b3190768befe598fa3ca", size = 2646985, upload-time = "2025-11-01T15:25:27.516Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d9/52/1064f510b141bd54025f9b55105e26d1fa970b9be67ad766380a3c9b74b0/starlette-0.50.0-py3-none-any.whl", hash = "sha256:9e5391843ec9b6e472eed1365a78c8098cfceb7a74bfd4d6b1c0c0095efb3bca", size = 74033, upload-time = "2025-11-01T15:25:25.461Z" }, +] + +[[package]] +name = "tqdm" +version = "4.67.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a8/4b/29b4ef32e036bb34e4ab51796dd745cdba7ed47ad142a9f4a1eb8e0c744d/tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2", size = 169737, upload-time = "2024-11-24T20:12:22.481Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2", size = 78540, upload-time = "2024-11-24T20:12:19.698Z" }, +] + +[[package]] +name = "typer" +version = "0.20.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "rich" }, + { name = "shellingham" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8f/28/7c85c8032b91dbe79725b6f17d2fffc595dff06a35c7a30a37bef73a1ab4/typer-0.20.0.tar.gz", hash = "sha256:1aaf6494031793e4876fb0bacfa6a912b551cf43c1e63c800df8b1a866720c37", size = 106492, upload-time = "2025-10-20T17:03:49.445Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/64/7713ffe4b5983314e9d436a90d5bd4f63b6054e2aca783a3cfc44cb95bbf/typer-0.20.0-py3-none-any.whl", hash = "sha256:5b463df6793ec1dca6213a3cf4c0f03bc6e322ac5e16e13ddd622a889489784a", size = 47028, upload-time = "2025-10-20T17:03:47.617Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.15.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, +] + +[[package]] +name = "typing-inspection" +version = "0.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload-time = "2025-10-01T02:14:41.687Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" }, +] + +[[package]] +name = "urllib3" +version = "2.6.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1e/24/a2a2ed9addd907787d7aa0355ba36a6cadf1768b934c652ea78acbd59dcd/urllib3-2.6.2.tar.gz", hash = "sha256:016f9c98bb7e98085cb2b4b17b87d2c702975664e4f060c6532e64d1c1a5e797", size = 432930, upload-time = "2025-12-11T15:56:40.252Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6d/b9/4095b668ea3678bf6a0af005527f39de12fb026516fb3df17495a733b7f8/urllib3-2.6.2-py3-none-any.whl", hash = "sha256:ec21cddfe7724fc7cb4ba4bea7aa8e2ef36f607a4bab81aa6ce42a13dc3f03dd", size = 131182, upload-time = "2025-12-11T15:56:38.584Z" }, +] + +[[package]] +name = "uuid7" +version = "0.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5c/19/7472bd526591e2192926247109dbf78692e709d3e56775792fec877a7720/uuid7-0.1.0.tar.gz", hash = "sha256:8c57aa32ee7456d3cc68c95c4530bc571646defac01895cfc73545449894a63c", size = 14052, upload-time = "2021-12-29T01:38:21.897Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b5/77/8852f89a91453956582a85024d80ad96f30a41fed4c2b3dce0c9f12ecc7e/uuid7-0.1.0-py2.py3-none-any.whl", hash = "sha256:5e259bb63c8cb4aded5927ff41b444a80d0c7124e8a0ced7cf44efa1f5cccf61", size = 7477, upload-time = "2021-12-29T01:38:20.418Z" }, +] + +[[package]] +name = "uvicorn" +version = "0.38.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "h11" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cb/ce/f06b84e2697fef4688ca63bdb2fdf113ca0a3be33f94488f2cadb690b0cf/uvicorn-0.38.0.tar.gz", hash = "sha256:fd97093bdd120a2609fc0d3afe931d4d4ad688b6e75f0f929fde1bc36fe0e91d", size = 80605, upload-time = "2025-10-18T13:46:44.63Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ee/d9/d88e73ca598f4f6ff671fb5fde8a32925c2e08a637303a1d12883c7305fa/uvicorn-0.38.0-py3-none-any.whl", hash = "sha256:48c0afd214ceb59340075b4a052ea1ee91c16fbc2a9b1469cca0e54566977b02", size = 68109, upload-time = "2025-10-18T13:46:42.958Z" }, +] + +[package.optional-dependencies] +standard = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "httptools" }, + { name = "python-dotenv" }, + { name = "pyyaml" }, + { name = "uvloop", marker = "platform_python_implementation != 'PyPy' and sys_platform != 'cygwin' and sys_platform != 'win32'" }, + { name = "watchfiles" }, + { name = "websockets" }, +] + +[[package]] +name = "uvloop" +version = "0.22.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/06/f0/18d39dbd1971d6d62c4629cc7fa67f74821b0dc1f5a77af43719de7936a7/uvloop-0.22.1.tar.gz", hash = "sha256:6c84bae345b9147082b17371e3dd5d42775bddce91f885499017f4607fdaf39f", size = 2443250, upload-time = "2025-10-16T22:17:19.342Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/89/8c/182a2a593195bfd39842ea68ebc084e20c850806117213f5a299dfc513d9/uvloop-0.22.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:561577354eb94200d75aca23fbde86ee11be36b00e52a4eaf8f50fb0c86b7705", size = 1358611, upload-time = "2025-10-16T22:16:36.833Z" }, + { url = "https://files.pythonhosted.org/packages/d2/14/e301ee96a6dc95224b6f1162cd3312f6d1217be3907b79173b06785f2fe7/uvloop-0.22.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1cdf5192ab3e674ca26da2eada35b288d2fa49fdd0f357a19f0e7c4e7d5077c8", size = 751811, upload-time = "2025-10-16T22:16:38.275Z" }, + { url = "https://files.pythonhosted.org/packages/b7/02/654426ce265ac19e2980bfd9ea6590ca96a56f10c76e63801a2df01c0486/uvloop-0.22.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6e2ea3d6190a2968f4a14a23019d3b16870dd2190cd69c8180f7c632d21de68d", size = 4288562, upload-time = "2025-10-16T22:16:39.375Z" }, + { url = "https://files.pythonhosted.org/packages/15/c0/0be24758891ef825f2065cd5db8741aaddabe3e248ee6acc5e8a80f04005/uvloop-0.22.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0530a5fbad9c9e4ee3f2b33b148c6a64d47bbad8000ea63704fa8260f4cf728e", size = 4366890, upload-time = "2025-10-16T22:16:40.547Z" }, + { url = "https://files.pythonhosted.org/packages/d2/53/8369e5219a5855869bcee5f4d317f6da0e2c669aecf0ef7d371e3d084449/uvloop-0.22.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bc5ef13bbc10b5335792360623cc378d52d7e62c2de64660616478c32cd0598e", size = 4119472, upload-time = "2025-10-16T22:16:41.694Z" }, + { url = "https://files.pythonhosted.org/packages/f8/ba/d69adbe699b768f6b29a5eec7b47dd610bd17a69de51b251126a801369ea/uvloop-0.22.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1f38ec5e3f18c8a10ded09742f7fb8de0108796eb673f30ce7762ce1b8550cad", size = 4239051, upload-time = "2025-10-16T22:16:43.224Z" }, + { url = "https://files.pythonhosted.org/packages/90/cd/b62bdeaa429758aee8de8b00ac0dd26593a9de93d302bff3d21439e9791d/uvloop-0.22.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3879b88423ec7e97cd4eba2a443aa26ed4e59b45e6b76aabf13fe2f27023a142", size = 1362067, upload-time = "2025-10-16T22:16:44.503Z" }, + { url = "https://files.pythonhosted.org/packages/0d/f8/a132124dfda0777e489ca86732e85e69afcd1ff7686647000050ba670689/uvloop-0.22.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:4baa86acedf1d62115c1dc6ad1e17134476688f08c6efd8a2ab076e815665c74", size = 752423, upload-time = "2025-10-16T22:16:45.968Z" }, + { url = "https://files.pythonhosted.org/packages/a3/94/94af78c156f88da4b3a733773ad5ba0b164393e357cc4bd0ab2e2677a7d6/uvloop-0.22.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:297c27d8003520596236bdb2335e6b3f649480bd09e00d1e3a99144b691d2a35", size = 4272437, upload-time = "2025-10-16T22:16:47.451Z" }, + { url = "https://files.pythonhosted.org/packages/b5/35/60249e9fd07b32c665192cec7af29e06c7cd96fa1d08b84f012a56a0b38e/uvloop-0.22.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c1955d5a1dd43198244d47664a5858082a3239766a839b2102a269aaff7a4e25", size = 4292101, upload-time = "2025-10-16T22:16:49.318Z" }, + { url = "https://files.pythonhosted.org/packages/02/62/67d382dfcb25d0a98ce73c11ed1a6fba5037a1a1d533dcbb7cab033a2636/uvloop-0.22.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b31dc2fccbd42adc73bc4e7cdbae4fc5086cf378979e53ca5d0301838c5682c6", size = 4114158, upload-time = "2025-10-16T22:16:50.517Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7a/f1171b4a882a5d13c8b7576f348acfe6074d72eaf52cccef752f748d4a9f/uvloop-0.22.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:93f617675b2d03af4e72a5333ef89450dfaa5321303ede6e67ba9c9d26878079", size = 4177360, upload-time = "2025-10-16T22:16:52.646Z" }, + { url = "https://files.pythonhosted.org/packages/79/7b/b01414f31546caf0919da80ad57cbfe24c56b151d12af68cee1b04922ca8/uvloop-0.22.1-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:37554f70528f60cad66945b885eb01f1bb514f132d92b6eeed1c90fd54ed6289", size = 1454790, upload-time = "2025-10-16T22:16:54.355Z" }, + { url = "https://files.pythonhosted.org/packages/d4/31/0bb232318dd838cad3fa8fb0c68c8b40e1145b32025581975e18b11fab40/uvloop-0.22.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:b76324e2dc033a0b2f435f33eb88ff9913c156ef78e153fb210e03c13da746b3", size = 796783, upload-time = "2025-10-16T22:16:55.906Z" }, + { url = "https://files.pythonhosted.org/packages/42/38/c9b09f3271a7a723a5de69f8e237ab8e7803183131bc57c890db0b6bb872/uvloop-0.22.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:badb4d8e58ee08dad957002027830d5c3b06aea446a6a3744483c2b3b745345c", size = 4647548, upload-time = "2025-10-16T22:16:57.008Z" }, + { url = "https://files.pythonhosted.org/packages/c1/37/945b4ca0ac27e3dc4952642d4c900edd030b3da6c9634875af6e13ae80e5/uvloop-0.22.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b91328c72635f6f9e0282e4a57da7470c7350ab1c9f48546c0f2866205349d21", size = 4467065, upload-time = "2025-10-16T22:16:58.206Z" }, + { url = "https://files.pythonhosted.org/packages/97/cc/48d232f33d60e2e2e0b42f4e73455b146b76ebe216487e862700457fbf3c/uvloop-0.22.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:daf620c2995d193449393d6c62131b3fbd40a63bf7b307a1527856ace637fe88", size = 4328384, upload-time = "2025-10-16T22:16:59.36Z" }, + { url = "https://files.pythonhosted.org/packages/e4/16/c1fd27e9549f3c4baf1dc9c20c456cd2f822dbf8de9f463824b0c0357e06/uvloop-0.22.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6cde23eeda1a25c75b2e07d39970f3374105d5eafbaab2a4482be82f272d5a5e", size = 4296730, upload-time = "2025-10-16T22:17:00.744Z" }, +] + +[[package]] +name = "watchfiles" +version = "1.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c2/c9/8869df9b2a2d6c59d79220a4db37679e74f807c559ffe5265e08b227a210/watchfiles-1.1.1.tar.gz", hash = "sha256:a173cb5c16c4f40ab19cecf48a534c409f7ea983ab8fed0741304a1c0a31b3f2", size = 94440, upload-time = "2025-10-14T15:06:21.08Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bb/f4/f750b29225fe77139f7ae5de89d4949f5a99f934c65a1f1c0b248f26f747/watchfiles-1.1.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:130e4876309e8686a5e37dba7d5e9bc77e6ed908266996ca26572437a5271e18", size = 404321, upload-time = "2025-10-14T15:05:02.063Z" }, + { url = "https://files.pythonhosted.org/packages/2b/f9/f07a295cde762644aa4c4bb0f88921d2d141af45e735b965fb2e87858328/watchfiles-1.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5f3bde70f157f84ece3765b42b4a52c6ac1a50334903c6eaf765362f6ccca88a", size = 391783, upload-time = "2025-10-14T15:05:03.052Z" }, + { url = "https://files.pythonhosted.org/packages/bc/11/fc2502457e0bea39a5c958d86d2cb69e407a4d00b85735ca724bfa6e0d1a/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:14e0b1fe858430fc0251737ef3824c54027bedb8c37c38114488b8e131cf8219", size = 449279, upload-time = "2025-10-14T15:05:04.004Z" }, + { url = "https://files.pythonhosted.org/packages/e3/1f/d66bc15ea0b728df3ed96a539c777acfcad0eb78555ad9efcaa1274688f0/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f27db948078f3823a6bb3b465180db8ebecf26dd5dae6f6180bd87383b6b4428", size = 459405, upload-time = "2025-10-14T15:05:04.942Z" }, + { url = "https://files.pythonhosted.org/packages/be/90/9f4a65c0aec3ccf032703e6db02d89a157462fbb2cf20dd415128251cac0/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:059098c3a429f62fc98e8ec62b982230ef2c8df68c79e826e37b895bc359a9c0", size = 488976, upload-time = "2025-10-14T15:05:05.905Z" }, + { url = "https://files.pythonhosted.org/packages/37/57/ee347af605d867f712be7029bb94c8c071732a4b44792e3176fa3c612d39/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bfb5862016acc9b869bb57284e6cb35fdf8e22fe59f7548858e2f971d045f150", size = 595506, upload-time = "2025-10-14T15:05:06.906Z" }, + { url = "https://files.pythonhosted.org/packages/a8/78/cc5ab0b86c122047f75e8fc471c67a04dee395daf847d3e59381996c8707/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:319b27255aacd9923b8a276bb14d21a5f7ff82564c744235fc5eae58d95422ae", size = 474936, upload-time = "2025-10-14T15:05:07.906Z" }, + { url = "https://files.pythonhosted.org/packages/62/da/def65b170a3815af7bd40a3e7010bf6ab53089ef1b75d05dd5385b87cf08/watchfiles-1.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c755367e51db90e75b19454b680903631d41f9e3607fbd941d296a020c2d752d", size = 456147, upload-time = "2025-10-14T15:05:09.138Z" }, + { url = "https://files.pythonhosted.org/packages/57/99/da6573ba71166e82d288d4df0839128004c67d2778d3b566c138695f5c0b/watchfiles-1.1.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c22c776292a23bfc7237a98f791b9ad3144b02116ff10d820829ce62dff46d0b", size = 630007, upload-time = "2025-10-14T15:05:10.117Z" }, + { url = "https://files.pythonhosted.org/packages/a8/51/7439c4dd39511368849eb1e53279cd3454b4a4dbace80bab88feeb83c6b5/watchfiles-1.1.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:3a476189be23c3686bc2f4321dd501cb329c0a0469e77b7b534ee10129ae6374", size = 622280, upload-time = "2025-10-14T15:05:11.146Z" }, + { url = "https://files.pythonhosted.org/packages/95/9c/8ed97d4bba5db6fdcdb2b298d3898f2dd5c20f6b73aee04eabe56c59677e/watchfiles-1.1.1-cp313-cp313-win32.whl", hash = "sha256:bf0a91bfb5574a2f7fc223cf95eeea79abfefa404bf1ea5e339c0c1560ae99a0", size = 272056, upload-time = "2025-10-14T15:05:12.156Z" }, + { url = "https://files.pythonhosted.org/packages/1f/f3/c14e28429f744a260d8ceae18bf58c1d5fa56b50d006a7a9f80e1882cb0d/watchfiles-1.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:52e06553899e11e8074503c8e716d574adeeb7e68913115c4b3653c53f9bae42", size = 288162, upload-time = "2025-10-14T15:05:13.208Z" }, + { url = "https://files.pythonhosted.org/packages/dc/61/fe0e56c40d5cd29523e398d31153218718c5786b5e636d9ae8ae79453d27/watchfiles-1.1.1-cp313-cp313-win_arm64.whl", hash = "sha256:ac3cc5759570cd02662b15fbcd9d917f7ecd47efe0d6b40474eafd246f91ea18", size = 277909, upload-time = "2025-10-14T15:05:14.49Z" }, + { url = "https://files.pythonhosted.org/packages/79/42/e0a7d749626f1e28c7108a99fb9bf524b501bbbeb9b261ceecde644d5a07/watchfiles-1.1.1-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:563b116874a9a7ce6f96f87cd0b94f7faf92d08d0021e837796f0a14318ef8da", size = 403389, upload-time = "2025-10-14T15:05:15.777Z" }, + { url = "https://files.pythonhosted.org/packages/15/49/08732f90ce0fbbc13913f9f215c689cfc9ced345fb1bcd8829a50007cc8d/watchfiles-1.1.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3ad9fe1dae4ab4212d8c91e80b832425e24f421703b5a42ef2e4a1e215aff051", size = 389964, upload-time = "2025-10-14T15:05:16.85Z" }, + { url = "https://files.pythonhosted.org/packages/27/0d/7c315d4bd5f2538910491a0393c56bf70d333d51bc5b34bee8e68e8cea19/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce70f96a46b894b36eba678f153f052967a0d06d5b5a19b336ab0dbbd029f73e", size = 448114, upload-time = "2025-10-14T15:05:17.876Z" }, + { url = "https://files.pythonhosted.org/packages/c3/24/9e096de47a4d11bc4df41e9d1e61776393eac4cb6eb11b3e23315b78b2cc/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:cb467c999c2eff23a6417e58d75e5828716f42ed8289fe6b77a7e5a91036ca70", size = 460264, upload-time = "2025-10-14T15:05:18.962Z" }, + { url = "https://files.pythonhosted.org/packages/cc/0f/e8dea6375f1d3ba5fcb0b3583e2b493e77379834c74fd5a22d66d85d6540/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:836398932192dae4146c8f6f737d74baeac8b70ce14831a239bdb1ca882fc261", size = 487877, upload-time = "2025-10-14T15:05:20.094Z" }, + { url = "https://files.pythonhosted.org/packages/ac/5b/df24cfc6424a12deb41503b64d42fbea6b8cb357ec62ca84a5a3476f654a/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:743185e7372b7bc7c389e1badcc606931a827112fbbd37f14c537320fca08620", size = 595176, upload-time = "2025-10-14T15:05:21.134Z" }, + { url = "https://files.pythonhosted.org/packages/8f/b5/853b6757f7347de4e9b37e8cc3289283fb983cba1ab4d2d7144694871d9c/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:afaeff7696e0ad9f02cbb8f56365ff4686ab205fcf9c4c5b6fdfaaa16549dd04", size = 473577, upload-time = "2025-10-14T15:05:22.306Z" }, + { url = "https://files.pythonhosted.org/packages/e1/f7/0a4467be0a56e80447c8529c9fce5b38eab4f513cb3d9bf82e7392a5696b/watchfiles-1.1.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f7eb7da0eb23aa2ba036d4f616d46906013a68caf61b7fdbe42fc8b25132e77", size = 455425, upload-time = "2025-10-14T15:05:23.348Z" }, + { url = "https://files.pythonhosted.org/packages/8e/e0/82583485ea00137ddf69bc84a2db88bd92ab4a6e3c405e5fb878ead8d0e7/watchfiles-1.1.1-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:831a62658609f0e5c64178211c942ace999517f5770fe9436be4c2faeba0c0ef", size = 628826, upload-time = "2025-10-14T15:05:24.398Z" }, + { url = "https://files.pythonhosted.org/packages/28/9a/a785356fccf9fae84c0cc90570f11702ae9571036fb25932f1242c82191c/watchfiles-1.1.1-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:f9a2ae5c91cecc9edd47e041a930490c31c3afb1f5e6d71de3dc671bfaca02bf", size = 622208, upload-time = "2025-10-14T15:05:25.45Z" }, + { url = "https://files.pythonhosted.org/packages/c3/f4/0872229324ef69b2c3edec35e84bd57a1289e7d3fe74588048ed8947a323/watchfiles-1.1.1-cp314-cp314-macosx_10_12_x86_64.whl", hash = "sha256:d1715143123baeeaeadec0528bb7441103979a1d5f6fd0e1f915383fea7ea6d5", size = 404315, upload-time = "2025-10-14T15:05:26.501Z" }, + { url = "https://files.pythonhosted.org/packages/7b/22/16d5331eaed1cb107b873f6ae1b69e9ced582fcf0c59a50cd84f403b1c32/watchfiles-1.1.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:39574d6370c4579d7f5d0ad940ce5b20db0e4117444e39b6d8f99db5676c52fd", size = 390869, upload-time = "2025-10-14T15:05:27.649Z" }, + { url = "https://files.pythonhosted.org/packages/b2/7e/5643bfff5acb6539b18483128fdc0ef2cccc94a5b8fbda130c823e8ed636/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7365b92c2e69ee952902e8f70f3ba6360d0d596d9299d55d7d386df84b6941fb", size = 449919, upload-time = "2025-10-14T15:05:28.701Z" }, + { url = "https://files.pythonhosted.org/packages/51/2e/c410993ba5025a9f9357c376f48976ef0e1b1aefb73b97a5ae01a5972755/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bfff9740c69c0e4ed32416f013f3c45e2ae42ccedd1167ef2d805c000b6c71a5", size = 460845, upload-time = "2025-10-14T15:05:30.064Z" }, + { url = "https://files.pythonhosted.org/packages/8e/a4/2df3b404469122e8680f0fcd06079317e48db58a2da2950fb45020947734/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b27cf2eb1dda37b2089e3907d8ea92922b673c0c427886d4edc6b94d8dfe5db3", size = 489027, upload-time = "2025-10-14T15:05:31.064Z" }, + { url = "https://files.pythonhosted.org/packages/ea/84/4587ba5b1f267167ee715b7f66e6382cca6938e0a4b870adad93e44747e6/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:526e86aced14a65a5b0ec50827c745597c782ff46b571dbfe46192ab9e0b3c33", size = 595615, upload-time = "2025-10-14T15:05:32.074Z" }, + { url = "https://files.pythonhosted.org/packages/6a/0f/c6988c91d06e93cd0bb3d4a808bcf32375ca1904609835c3031799e3ecae/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:04e78dd0b6352db95507fd8cb46f39d185cf8c74e4cf1e4fbad1d3df96faf510", size = 474836, upload-time = "2025-10-14T15:05:33.209Z" }, + { url = "https://files.pythonhosted.org/packages/b4/36/ded8aebea91919485b7bbabbd14f5f359326cb5ec218cd67074d1e426d74/watchfiles-1.1.1-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c85794a4cfa094714fb9c08d4a218375b2b95b8ed1666e8677c349906246c05", size = 455099, upload-time = "2025-10-14T15:05:34.189Z" }, + { url = "https://files.pythonhosted.org/packages/98/e0/8c9bdba88af756a2fce230dd365fab2baf927ba42cd47521ee7498fd5211/watchfiles-1.1.1-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:74d5012b7630714b66be7b7b7a78855ef7ad58e8650c73afc4c076a1f480a8d6", size = 630626, upload-time = "2025-10-14T15:05:35.216Z" }, + { url = "https://files.pythonhosted.org/packages/2a/84/a95db05354bf2d19e438520d92a8ca475e578c647f78f53197f5a2f17aaf/watchfiles-1.1.1-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:8fbe85cb3201c7d380d3d0b90e63d520f15d6afe217165d7f98c9c649654db81", size = 622519, upload-time = "2025-10-14T15:05:36.259Z" }, + { url = "https://files.pythonhosted.org/packages/1d/ce/d8acdc8de545de995c339be67711e474c77d643555a9bb74a9334252bd55/watchfiles-1.1.1-cp314-cp314-win32.whl", hash = "sha256:3fa0b59c92278b5a7800d3ee7733da9d096d4aabcfabb9a928918bd276ef9b9b", size = 272078, upload-time = "2025-10-14T15:05:37.63Z" }, + { url = "https://files.pythonhosted.org/packages/c4/c9/a74487f72d0451524be827e8edec251da0cc1fcf111646a511ae752e1a3d/watchfiles-1.1.1-cp314-cp314-win_amd64.whl", hash = "sha256:c2047d0b6cea13b3316bdbafbfa0c4228ae593d995030fda39089d36e64fc03a", size = 287664, upload-time = "2025-10-14T15:05:38.95Z" }, + { url = "https://files.pythonhosted.org/packages/df/b8/8ac000702cdd496cdce998c6f4ee0ca1f15977bba51bdf07d872ebdfc34c/watchfiles-1.1.1-cp314-cp314-win_arm64.whl", hash = "sha256:842178b126593addc05acf6fce960d28bc5fae7afbaa2c6c1b3a7b9460e5be02", size = 277154, upload-time = "2025-10-14T15:05:39.954Z" }, + { url = "https://files.pythonhosted.org/packages/47/a8/e3af2184707c29f0f14b1963c0aace6529f9d1b8582d5b99f31bbf42f59e/watchfiles-1.1.1-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:88863fbbc1a7312972f1c511f202eb30866370ebb8493aef2812b9ff28156a21", size = 403820, upload-time = "2025-10-14T15:05:40.932Z" }, + { url = "https://files.pythonhosted.org/packages/c0/ec/e47e307c2f4bd75f9f9e8afbe3876679b18e1bcec449beca132a1c5ffb2d/watchfiles-1.1.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:55c7475190662e202c08c6c0f4d9e345a29367438cf8e8037f3155e10a88d5a5", size = 390510, upload-time = "2025-10-14T15:05:41.945Z" }, + { url = "https://files.pythonhosted.org/packages/d5/a0/ad235642118090f66e7b2f18fd5c42082418404a79205cdfca50b6309c13/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f53fa183d53a1d7a8852277c92b967ae99c2d4dcee2bfacff8868e6e30b15f7", size = 448408, upload-time = "2025-10-14T15:05:43.385Z" }, + { url = "https://files.pythonhosted.org/packages/df/85/97fa10fd5ff3332ae17e7e40e20784e419e28521549780869f1413742e9d/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6aae418a8b323732fa89721d86f39ec8f092fc2af67f4217a2b07fd3e93c6101", size = 458968, upload-time = "2025-10-14T15:05:44.404Z" }, + { url = "https://files.pythonhosted.org/packages/47/c2/9059c2e8966ea5ce678166617a7f75ecba6164375f3b288e50a40dc6d489/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f096076119da54a6080e8920cbdaac3dbee667eb91dcc5e5b78840b87415bd44", size = 488096, upload-time = "2025-10-14T15:05:45.398Z" }, + { url = "https://files.pythonhosted.org/packages/94/44/d90a9ec8ac309bc26db808a13e7bfc0e4e78b6fc051078a554e132e80160/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:00485f441d183717038ed2e887a7c868154f216877653121068107b227a2f64c", size = 596040, upload-time = "2025-10-14T15:05:46.502Z" }, + { url = "https://files.pythonhosted.org/packages/95/68/4e3479b20ca305cfc561db3ed207a8a1c745ee32bf24f2026a129d0ddb6e/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a55f3e9e493158d7bfdb60a1165035f1cf7d320914e7b7ea83fe22c6023b58fc", size = 473847, upload-time = "2025-10-14T15:05:47.484Z" }, + { url = "https://files.pythonhosted.org/packages/4f/55/2af26693fd15165c4ff7857e38330e1b61ab8c37d15dc79118cdba115b7a/watchfiles-1.1.1-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c91ed27800188c2ae96d16e3149f199d62f86c7af5f5f4d2c61a3ed8cd3666c", size = 455072, upload-time = "2025-10-14T15:05:48.928Z" }, + { url = "https://files.pythonhosted.org/packages/66/1d/d0d200b10c9311ec25d2273f8aad8c3ef7cc7ea11808022501811208a750/watchfiles-1.1.1-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:311ff15a0bae3714ffb603e6ba6dbfba4065ab60865d15a6ec544133bdb21099", size = 629104, upload-time = "2025-10-14T15:05:49.908Z" }, + { url = "https://files.pythonhosted.org/packages/e3/bd/fa9bb053192491b3867ba07d2343d9f2252e00811567d30ae8d0f78136fe/watchfiles-1.1.1-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:a916a2932da8f8ab582f242c065f5c81bed3462849ca79ee357dd9551b0e9b01", size = 622112, upload-time = "2025-10-14T15:05:50.941Z" }, +] + +[[package]] +name = "websockets" +version = "15.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/21/e6/26d09fab466b7ca9c7737474c52be4f76a40301b08362eb2dbc19dcc16c1/websockets-15.0.1.tar.gz", hash = "sha256:82544de02076bafba038ce055ee6412d68da13ab47f0c60cab827346de828dee", size = 177016, upload-time = "2025-03-05T20:03:41.606Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/9f/51f0cf64471a9d2b4d0fc6c534f323b664e7095640c34562f5182e5a7195/websockets-15.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ee443ef070bb3b6ed74514f5efaa37a252af57c90eb33b956d35c8e9c10a1931", size = 175440, upload-time = "2025-03-05T20:02:36.695Z" }, + { url = "https://files.pythonhosted.org/packages/8a/05/aa116ec9943c718905997412c5989f7ed671bc0188ee2ba89520e8765d7b/websockets-15.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5a939de6b7b4e18ca683218320fc67ea886038265fd1ed30173f5ce3f8e85675", size = 173098, upload-time = "2025-03-05T20:02:37.985Z" }, + { url = "https://files.pythonhosted.org/packages/ff/0b/33cef55ff24f2d92924923c99926dcce78e7bd922d649467f0eda8368923/websockets-15.0.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:746ee8dba912cd6fc889a8147168991d50ed70447bf18bcda7039f7d2e3d9151", size = 173329, upload-time = "2025-03-05T20:02:39.298Z" }, + { url = "https://files.pythonhosted.org/packages/31/1d/063b25dcc01faa8fada1469bdf769de3768b7044eac9d41f734fd7b6ad6d/websockets-15.0.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:595b6c3969023ecf9041b2936ac3827e4623bfa3ccf007575f04c5a6aa318c22", size = 183111, upload-time = "2025-03-05T20:02:40.595Z" }, + { url = "https://files.pythonhosted.org/packages/93/53/9a87ee494a51bf63e4ec9241c1ccc4f7c2f45fff85d5bde2ff74fcb68b9e/websockets-15.0.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c714d2fc58b5ca3e285461a4cc0c9a66bd0e24c5da9911e30158286c9b5be7f", size = 182054, upload-time = "2025-03-05T20:02:41.926Z" }, + { url = "https://files.pythonhosted.org/packages/ff/b2/83a6ddf56cdcbad4e3d841fcc55d6ba7d19aeb89c50f24dd7e859ec0805f/websockets-15.0.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f3c1e2ab208db911594ae5b4f79addeb3501604a165019dd221c0bdcabe4db8", size = 182496, upload-time = "2025-03-05T20:02:43.304Z" }, + { url = "https://files.pythonhosted.org/packages/98/41/e7038944ed0abf34c45aa4635ba28136f06052e08fc2168520bb8b25149f/websockets-15.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:229cf1d3ca6c1804400b0a9790dc66528e08a6a1feec0d5040e8b9eb14422375", size = 182829, upload-time = "2025-03-05T20:02:48.812Z" }, + { url = "https://files.pythonhosted.org/packages/e0/17/de15b6158680c7623c6ef0db361da965ab25d813ae54fcfeae2e5b9ef910/websockets-15.0.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:756c56e867a90fb00177d530dca4b097dd753cde348448a1012ed6c5131f8b7d", size = 182217, upload-time = "2025-03-05T20:02:50.14Z" }, + { url = "https://files.pythonhosted.org/packages/33/2b/1f168cb6041853eef0362fb9554c3824367c5560cbdaad89ac40f8c2edfc/websockets-15.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:558d023b3df0bffe50a04e710bc87742de35060580a293c2a984299ed83bc4e4", size = 182195, upload-time = "2025-03-05T20:02:51.561Z" }, + { url = "https://files.pythonhosted.org/packages/86/eb/20b6cdf273913d0ad05a6a14aed4b9a85591c18a987a3d47f20fa13dcc47/websockets-15.0.1-cp313-cp313-win32.whl", hash = "sha256:ba9e56e8ceeeedb2e080147ba85ffcd5cd0711b89576b83784d8605a7df455fa", size = 176393, upload-time = "2025-03-05T20:02:53.814Z" }, + { url = "https://files.pythonhosted.org/packages/1b/6c/c65773d6cab416a64d191d6ee8a8b1c68a09970ea6909d16965d26bfed1e/websockets-15.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:e09473f095a819042ecb2ab9465aee615bd9c2028e4ef7d933600a8401c79561", size = 176837, upload-time = "2025-03-05T20:02:55.237Z" }, + { url = "https://files.pythonhosted.org/packages/fa/a8/5b41e0da817d64113292ab1f8247140aac61cbf6cfd085d6a0fa77f4984f/websockets-15.0.1-py3-none-any.whl", hash = "sha256:f7a866fbc1e97b5c617ee4116daaa09b722101d4a3c170c787450ba409f9736f", size = 169743, upload-time = "2025-03-05T20:03:39.41Z" }, +] + +[[package]] +name = "wtforms" +version = "3.1.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6a/c7/96d10183c3470f1836846f7b9527d6cb0b6c2226ebca40f36fa29f23de60/wtforms-3.1.2.tar.gz", hash = "sha256:f8d76180d7239c94c6322f7990ae1216dae3659b7aa1cee94b6318bdffb474b9", size = 134705, upload-time = "2024-01-06T07:52:41.075Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/19/c3232f35e24dccfad372e9f341c4f3a1166ae7c66e4e1351a9467c921cc1/wtforms-3.1.2-py3-none-any.whl", hash = "sha256:bf831c042829c8cdbad74c27575098d541d039b1faa74c771545ecac916f2c07", size = 145961, upload-time = "2024-01-06T07:52:43.023Z" }, +] + +[[package]] +name = "yarl" +version = "1.22.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "idna" }, + { name = "multidict" }, + { name = "propcache" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/57/63/0c6ebca57330cd313f6102b16dd57ffaf3ec4c83403dcb45dbd15c6f3ea1/yarl-1.22.0.tar.gz", hash = "sha256:bebf8557577d4401ba8bd9ff33906f1376c877aa78d1fe216ad01b4d6745af71", size = 187169, upload-time = "2025-10-06T14:12:55.963Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ea/f3/d67de7260456ee105dc1d162d43a019ecad6b91e2f51809d6cddaa56690e/yarl-1.22.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8dee9c25c74997f6a750cd317b8ca63545169c098faee42c84aa5e506c819b53", size = 139980, upload-time = "2025-10-06T14:10:14.601Z" }, + { url = "https://files.pythonhosted.org/packages/01/88/04d98af0b47e0ef42597b9b28863b9060bb515524da0a65d5f4db160b2d5/yarl-1.22.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:01e73b85a5434f89fc4fe27dcda2aff08ddf35e4d47bbbea3bdcd25321af538a", size = 93424, upload-time = "2025-10-06T14:10:16.115Z" }, + { url = "https://files.pythonhosted.org/packages/18/91/3274b215fd8442a03975ce6bee5fe6aa57a8326b29b9d3d56234a1dca244/yarl-1.22.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:22965c2af250d20c873cdbee8ff958fb809940aeb2e74ba5f20aaf6b7ac8c70c", size = 93821, upload-time = "2025-10-06T14:10:17.993Z" }, + { url = "https://files.pythonhosted.org/packages/61/3a/caf4e25036db0f2da4ca22a353dfeb3c9d3c95d2761ebe9b14df8fc16eb0/yarl-1.22.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b4f15793aa49793ec8d1c708ab7f9eded1aa72edc5174cae703651555ed1b601", size = 373243, upload-time = "2025-10-06T14:10:19.44Z" }, + { url = "https://files.pythonhosted.org/packages/6e/9e/51a77ac7516e8e7803b06e01f74e78649c24ee1021eca3d6a739cb6ea49c/yarl-1.22.0-cp313-cp313-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:e5542339dcf2747135c5c85f68680353d5cb9ffd741c0f2e8d832d054d41f35a", size = 342361, upload-time = "2025-10-06T14:10:21.124Z" }, + { url = "https://files.pythonhosted.org/packages/d4/f8/33b92454789dde8407f156c00303e9a891f1f51a0330b0fad7c909f87692/yarl-1.22.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5c401e05ad47a75869c3ab3e35137f8468b846770587e70d71e11de797d113df", size = 387036, upload-time = "2025-10-06T14:10:22.902Z" }, + { url = "https://files.pythonhosted.org/packages/d9/9a/c5db84ea024f76838220280f732970aa4ee154015d7f5c1bfb60a267af6f/yarl-1.22.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:243dda95d901c733f5b59214d28b0120893d91777cb8aa043e6ef059d3cddfe2", size = 397671, upload-time = "2025-10-06T14:10:24.523Z" }, + { url = "https://files.pythonhosted.org/packages/11/c9/cd8538dc2e7727095e0c1d867bad1e40c98f37763e6d995c1939f5fdc7b1/yarl-1.22.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bec03d0d388060058f5d291a813f21c011041938a441c593374da6077fe21b1b", size = 377059, upload-time = "2025-10-06T14:10:26.406Z" }, + { url = "https://files.pythonhosted.org/packages/a1/b9/ab437b261702ced75122ed78a876a6dec0a1b0f5e17a4ac7a9a2482d8abe/yarl-1.22.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b0748275abb8c1e1e09301ee3cf90c8a99678a4e92e4373705f2a2570d581273", size = 365356, upload-time = "2025-10-06T14:10:28.461Z" }, + { url = "https://files.pythonhosted.org/packages/b2/9d/8e1ae6d1d008a9567877b08f0ce4077a29974c04c062dabdb923ed98e6fe/yarl-1.22.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:47fdb18187e2a4e18fda2c25c05d8251a9e4a521edaed757fef033e7d8498d9a", size = 361331, upload-time = "2025-10-06T14:10:30.541Z" }, + { url = "https://files.pythonhosted.org/packages/ca/5a/09b7be3905962f145b73beb468cdd53db8aa171cf18c80400a54c5b82846/yarl-1.22.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c7044802eec4524fde550afc28edda0dd5784c4c45f0be151a2d3ba017daca7d", size = 382590, upload-time = "2025-10-06T14:10:33.352Z" }, + { url = "https://files.pythonhosted.org/packages/aa/7f/59ec509abf90eda5048b0bc3e2d7b5099dffdb3e6b127019895ab9d5ef44/yarl-1.22.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:139718f35149ff544caba20fce6e8a2f71f1e39b92c700d8438a0b1d2a631a02", size = 385316, upload-time = "2025-10-06T14:10:35.034Z" }, + { url = "https://files.pythonhosted.org/packages/e5/84/891158426bc8036bfdfd862fabd0e0fa25df4176ec793e447f4b85cf1be4/yarl-1.22.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e1b51bebd221006d3d2f95fbe124b22b247136647ae5dcc8c7acafba66e5ee67", size = 374431, upload-time = "2025-10-06T14:10:37.76Z" }, + { url = "https://files.pythonhosted.org/packages/bb/49/03da1580665baa8bef5e8ed34c6df2c2aca0a2f28bf397ed238cc1bbc6f2/yarl-1.22.0-cp313-cp313-win32.whl", hash = "sha256:d3e32536234a95f513bd374e93d717cf6b2231a791758de6c509e3653f234c95", size = 81555, upload-time = "2025-10-06T14:10:39.649Z" }, + { url = "https://files.pythonhosted.org/packages/9a/ee/450914ae11b419eadd067c6183ae08381cfdfcb9798b90b2b713bbebddda/yarl-1.22.0-cp313-cp313-win_amd64.whl", hash = "sha256:47743b82b76d89a1d20b83e60d5c20314cbd5ba2befc9cda8f28300c4a08ed4d", size = 86965, upload-time = "2025-10-06T14:10:41.313Z" }, + { url = "https://files.pythonhosted.org/packages/98/4d/264a01eae03b6cf629ad69bae94e3b0e5344741e929073678e84bf7a3e3b/yarl-1.22.0-cp313-cp313-win_arm64.whl", hash = "sha256:5d0fcda9608875f7d052eff120c7a5da474a6796fe4d83e152e0e4d42f6d1a9b", size = 81205, upload-time = "2025-10-06T14:10:43.167Z" }, + { url = "https://files.pythonhosted.org/packages/88/fc/6908f062a2f77b5f9f6d69cecb1747260831ff206adcbc5b510aff88df91/yarl-1.22.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:719ae08b6972befcba4310e49edb1161a88cdd331e3a694b84466bd938a6ab10", size = 146209, upload-time = "2025-10-06T14:10:44.643Z" }, + { url = "https://files.pythonhosted.org/packages/65/47/76594ae8eab26210b4867be6f49129861ad33da1f1ebdf7051e98492bf62/yarl-1.22.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:47d8a5c446df1c4db9d21b49619ffdba90e77c89ec6e283f453856c74b50b9e3", size = 95966, upload-time = "2025-10-06T14:10:46.554Z" }, + { url = "https://files.pythonhosted.org/packages/ab/ce/05e9828a49271ba6b5b038b15b3934e996980dd78abdfeb52a04cfb9467e/yarl-1.22.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:cfebc0ac8333520d2d0423cbbe43ae43c8838862ddb898f5ca68565e395516e9", size = 97312, upload-time = "2025-10-06T14:10:48.007Z" }, + { url = "https://files.pythonhosted.org/packages/d1/c5/7dffad5e4f2265b29c9d7ec869c369e4223166e4f9206fc2243ee9eea727/yarl-1.22.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4398557cbf484207df000309235979c79c4356518fd5c99158c7d38203c4da4f", size = 361967, upload-time = "2025-10-06T14:10:49.997Z" }, + { url = "https://files.pythonhosted.org/packages/50/b2/375b933c93a54bff7fc041e1a6ad2c0f6f733ffb0c6e642ce56ee3b39970/yarl-1.22.0-cp313-cp313t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:2ca6fd72a8cd803be290d42f2dec5cdcd5299eeb93c2d929bf060ad9efaf5de0", size = 323949, upload-time = "2025-10-06T14:10:52.004Z" }, + { url = "https://files.pythonhosted.org/packages/66/50/bfc2a29a1d78644c5a7220ce2f304f38248dc94124a326794e677634b6cf/yarl-1.22.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ca1f59c4e1ab6e72f0a23c13fca5430f889634166be85dbf1013683e49e3278e", size = 361818, upload-time = "2025-10-06T14:10:54.078Z" }, + { url = "https://files.pythonhosted.org/packages/46/96/f3941a46af7d5d0f0498f86d71275696800ddcdd20426298e572b19b91ff/yarl-1.22.0-cp313-cp313t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6c5010a52015e7c70f86eb967db0f37f3c8bd503a695a49f8d45700144667708", size = 372626, upload-time = "2025-10-06T14:10:55.767Z" }, + { url = "https://files.pythonhosted.org/packages/c1/42/8b27c83bb875cd89448e42cd627e0fb971fa1675c9ec546393d18826cb50/yarl-1.22.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d7672ecf7557476642c88497c2f8d8542f8e36596e928e9bcba0e42e1e7d71f", size = 341129, upload-time = "2025-10-06T14:10:57.985Z" }, + { url = "https://files.pythonhosted.org/packages/49/36/99ca3122201b382a3cf7cc937b95235b0ac944f7e9f2d5331d50821ed352/yarl-1.22.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:3b7c88eeef021579d600e50363e0b6ee4f7f6f728cd3486b9d0f3ee7b946398d", size = 346776, upload-time = "2025-10-06T14:10:59.633Z" }, + { url = "https://files.pythonhosted.org/packages/85/b4/47328bf996acd01a4c16ef9dcd2f59c969f495073616586f78cd5f2efb99/yarl-1.22.0-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:f4afb5c34f2c6fecdcc182dfcfc6af6cccf1aa923eed4d6a12e9d96904e1a0d8", size = 334879, upload-time = "2025-10-06T14:11:01.454Z" }, + { url = "https://files.pythonhosted.org/packages/c2/ad/b77d7b3f14a4283bffb8e92c6026496f6de49751c2f97d4352242bba3990/yarl-1.22.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:59c189e3e99a59cf8d83cbb31d4db02d66cda5a1a4374e8a012b51255341abf5", size = 350996, upload-time = "2025-10-06T14:11:03.452Z" }, + { url = "https://files.pythonhosted.org/packages/81/c8/06e1d69295792ba54d556f06686cbd6a7ce39c22307100e3fb4a2c0b0a1d/yarl-1.22.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:5a3bf7f62a289fa90f1990422dc8dff5a458469ea71d1624585ec3a4c8d6960f", size = 356047, upload-time = "2025-10-06T14:11:05.115Z" }, + { url = "https://files.pythonhosted.org/packages/4b/b8/4c0e9e9f597074b208d18cef227d83aac36184bfbc6eab204ea55783dbc5/yarl-1.22.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:de6b9a04c606978fdfe72666fa216ffcf2d1a9f6a381058d4378f8d7b1e5de62", size = 342947, upload-time = "2025-10-06T14:11:08.137Z" }, + { url = "https://files.pythonhosted.org/packages/e0/e5/11f140a58bf4c6ad7aca69a892bff0ee638c31bea4206748fc0df4ebcb3a/yarl-1.22.0-cp313-cp313t-win32.whl", hash = "sha256:1834bb90991cc2999f10f97f5f01317f99b143284766d197e43cd5b45eb18d03", size = 86943, upload-time = "2025-10-06T14:11:10.284Z" }, + { url = "https://files.pythonhosted.org/packages/31/74/8b74bae38ed7fe6793d0c15a0c8207bbb819cf287788459e5ed230996cdd/yarl-1.22.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ff86011bd159a9d2dfc89c34cfd8aff12875980e3bd6a39ff097887520e60249", size = 93715, upload-time = "2025-10-06T14:11:11.739Z" }, + { url = "https://files.pythonhosted.org/packages/69/66/991858aa4b5892d57aef7ee1ba6b4d01ec3b7eb3060795d34090a3ca3278/yarl-1.22.0-cp313-cp313t-win_arm64.whl", hash = "sha256:7861058d0582b847bc4e3a4a4c46828a410bca738673f35a29ba3ca5db0b473b", size = 83857, upload-time = "2025-10-06T14:11:13.586Z" }, + { url = "https://files.pythonhosted.org/packages/46/b3/e20ef504049f1a1c54a814b4b9bed96d1ac0e0610c3b4da178f87209db05/yarl-1.22.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:34b36c2c57124530884d89d50ed2c1478697ad7473efd59cfd479945c95650e4", size = 140520, upload-time = "2025-10-06T14:11:15.465Z" }, + { url = "https://files.pythonhosted.org/packages/e4/04/3532d990fdbab02e5ede063676b5c4260e7f3abea2151099c2aa745acc4c/yarl-1.22.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:0dd9a702591ca2e543631c2a017e4a547e38a5c0f29eece37d9097e04a7ac683", size = 93504, upload-time = "2025-10-06T14:11:17.106Z" }, + { url = "https://files.pythonhosted.org/packages/11/63/ff458113c5c2dac9a9719ac68ee7c947cb621432bcf28c9972b1c0e83938/yarl-1.22.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:594fcab1032e2d2cc3321bb2e51271e7cd2b516c7d9aee780ece81b07ff8244b", size = 94282, upload-time = "2025-10-06T14:11:19.064Z" }, + { url = "https://files.pythonhosted.org/packages/a7/bc/315a56aca762d44a6aaaf7ad253f04d996cb6b27bad34410f82d76ea8038/yarl-1.22.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f3d7a87a78d46a2e3d5b72587ac14b4c16952dd0887dbb051451eceac774411e", size = 372080, upload-time = "2025-10-06T14:11:20.996Z" }, + { url = "https://files.pythonhosted.org/packages/3f/3f/08e9b826ec2e099ea6e7c69a61272f4f6da62cb5b1b63590bb80ca2e4a40/yarl-1.22.0-cp314-cp314-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:852863707010316c973162e703bddabec35e8757e67fcb8ad58829de1ebc8590", size = 338696, upload-time = "2025-10-06T14:11:22.847Z" }, + { url = "https://files.pythonhosted.org/packages/e3/9f/90360108e3b32bd76789088e99538febfea24a102380ae73827f62073543/yarl-1.22.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:131a085a53bfe839a477c0845acf21efc77457ba2bcf5899618136d64f3303a2", size = 387121, upload-time = "2025-10-06T14:11:24.889Z" }, + { url = "https://files.pythonhosted.org/packages/98/92/ab8d4657bd5b46a38094cfaea498f18bb70ce6b63508fd7e909bd1f93066/yarl-1.22.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:078a8aefd263f4d4f923a9677b942b445a2be970ca24548a8102689a3a8ab8da", size = 394080, upload-time = "2025-10-06T14:11:27.307Z" }, + { url = "https://files.pythonhosted.org/packages/f5/e7/d8c5a7752fef68205296201f8ec2bf718f5c805a7a7e9880576c67600658/yarl-1.22.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bca03b91c323036913993ff5c738d0842fc9c60c4648e5c8d98331526df89784", size = 372661, upload-time = "2025-10-06T14:11:29.387Z" }, + { url = "https://files.pythonhosted.org/packages/b6/2e/f4d26183c8db0bb82d491b072f3127fb8c381a6206a3a56332714b79b751/yarl-1.22.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:68986a61557d37bb90d3051a45b91fa3d5c516d177dfc6dd6f2f436a07ff2b6b", size = 364645, upload-time = "2025-10-06T14:11:31.423Z" }, + { url = "https://files.pythonhosted.org/packages/80/7c/428e5812e6b87cd00ee8e898328a62c95825bf37c7fa87f0b6bb2ad31304/yarl-1.22.0-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:4792b262d585ff0dff6bcb787f8492e40698443ec982a3568c2096433660c694", size = 355361, upload-time = "2025-10-06T14:11:33.055Z" }, + { url = "https://files.pythonhosted.org/packages/ec/2a/249405fd26776f8b13c067378ef4d7dd49c9098d1b6457cdd152a99e96a9/yarl-1.22.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:ebd4549b108d732dba1d4ace67614b9545b21ece30937a63a65dd34efa19732d", size = 381451, upload-time = "2025-10-06T14:11:35.136Z" }, + { url = "https://files.pythonhosted.org/packages/67/a8/fb6b1adbe98cf1e2dd9fad71003d3a63a1bc22459c6e15f5714eb9323b93/yarl-1.22.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:f87ac53513d22240c7d59203f25cc3beac1e574c6cd681bbfd321987b69f95fd", size = 383814, upload-time = "2025-10-06T14:11:37.094Z" }, + { url = "https://files.pythonhosted.org/packages/d9/f9/3aa2c0e480fb73e872ae2814c43bc1e734740bb0d54e8cb2a95925f98131/yarl-1.22.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:22b029f2881599e2f1b06f8f1db2ee63bd309e2293ba2d566e008ba12778b8da", size = 370799, upload-time = "2025-10-06T14:11:38.83Z" }, + { url = "https://files.pythonhosted.org/packages/50/3c/af9dba3b8b5eeb302f36f16f92791f3ea62e3f47763406abf6d5a4a3333b/yarl-1.22.0-cp314-cp314-win32.whl", hash = "sha256:6a635ea45ba4ea8238463b4f7d0e721bad669f80878b7bfd1f89266e2ae63da2", size = 82990, upload-time = "2025-10-06T14:11:40.624Z" }, + { url = "https://files.pythonhosted.org/packages/ac/30/ac3a0c5bdc1d6efd1b41fa24d4897a4329b3b1e98de9449679dd327af4f0/yarl-1.22.0-cp314-cp314-win_amd64.whl", hash = "sha256:0d6e6885777af0f110b0e5d7e5dda8b704efed3894da26220b7f3d887b839a79", size = 88292, upload-time = "2025-10-06T14:11:42.578Z" }, + { url = "https://files.pythonhosted.org/packages/df/0a/227ab4ff5b998a1b7410abc7b46c9b7a26b0ca9e86c34ba4b8d8bc7c63d5/yarl-1.22.0-cp314-cp314-win_arm64.whl", hash = "sha256:8218f4e98d3c10d683584cb40f0424f4b9fd6e95610232dd75e13743b070ee33", size = 82888, upload-time = "2025-10-06T14:11:44.863Z" }, + { url = "https://files.pythonhosted.org/packages/06/5e/a15eb13db90abd87dfbefb9760c0f3f257ac42a5cac7e75dbc23bed97a9f/yarl-1.22.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:45c2842ff0e0d1b35a6bf1cd6c690939dacb617a70827f715232b2e0494d55d1", size = 146223, upload-time = "2025-10-06T14:11:46.796Z" }, + { url = "https://files.pythonhosted.org/packages/18/82/9665c61910d4d84f41a5bf6837597c89e665fa88aa4941080704645932a9/yarl-1.22.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:d947071e6ebcf2e2bee8fce76e10faca8f7a14808ca36a910263acaacef08eca", size = 95981, upload-time = "2025-10-06T14:11:48.845Z" }, + { url = "https://files.pythonhosted.org/packages/5d/9a/2f65743589809af4d0a6d3aa749343c4b5f4c380cc24a8e94a3c6625a808/yarl-1.22.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:334b8721303e61b00019474cc103bdac3d7b1f65e91f0bfedeec2d56dfe74b53", size = 97303, upload-time = "2025-10-06T14:11:50.897Z" }, + { url = "https://files.pythonhosted.org/packages/b0/ab/5b13d3e157505c43c3b43b5a776cbf7b24a02bc4cccc40314771197e3508/yarl-1.22.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1e7ce67c34138a058fd092f67d07a72b8e31ff0c9236e751957465a24b28910c", size = 361820, upload-time = "2025-10-06T14:11:52.549Z" }, + { url = "https://files.pythonhosted.org/packages/fb/76/242a5ef4677615cf95330cfc1b4610e78184400699bdda0acb897ef5e49a/yarl-1.22.0-cp314-cp314t-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d77e1b2c6d04711478cb1c4ab90db07f1609ccf06a287d5607fcd90dc9863acf", size = 323203, upload-time = "2025-10-06T14:11:54.225Z" }, + { url = "https://files.pythonhosted.org/packages/8c/96/475509110d3f0153b43d06164cf4195c64d16999e0c7e2d8a099adcd6907/yarl-1.22.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c4647674b6150d2cae088fc07de2738a84b8bcedebef29802cf0b0a82ab6face", size = 363173, upload-time = "2025-10-06T14:11:56.069Z" }, + { url = "https://files.pythonhosted.org/packages/c9/66/59db471aecfbd559a1fd48aedd954435558cd98c7d0da8b03cc6c140a32c/yarl-1.22.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:efb07073be061c8f79d03d04139a80ba33cbd390ca8f0297aae9cce6411e4c6b", size = 373562, upload-time = "2025-10-06T14:11:58.783Z" }, + { url = "https://files.pythonhosted.org/packages/03/1f/c5d94abc91557384719da10ff166b916107c1b45e4d0423a88457071dd88/yarl-1.22.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e51ac5435758ba97ad69617e13233da53908beccc6cfcd6c34bbed8dcbede486", size = 339828, upload-time = "2025-10-06T14:12:00.686Z" }, + { url = "https://files.pythonhosted.org/packages/5f/97/aa6a143d3afba17b6465733681c70cf175af89f76ec8d9286e08437a7454/yarl-1.22.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:33e32a0dd0c8205efa8e83d04fc9f19313772b78522d1bdc7d9aed706bfd6138", size = 347551, upload-time = "2025-10-06T14:12:02.628Z" }, + { url = "https://files.pythonhosted.org/packages/43/3c/45a2b6d80195959239a7b2a8810506d4eea5487dce61c2a3393e7fc3c52e/yarl-1.22.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:bf4a21e58b9cde0e401e683ebd00f6ed30a06d14e93f7c8fd059f8b6e8f87b6a", size = 334512, upload-time = "2025-10-06T14:12:04.871Z" }, + { url = "https://files.pythonhosted.org/packages/86/a0/c2ab48d74599c7c84cb104ebd799c5813de252bea0f360ffc29d270c2caa/yarl-1.22.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:e4b582bab49ac33c8deb97e058cd67c2c50dac0dd134874106d9c774fd272529", size = 352400, upload-time = "2025-10-06T14:12:06.624Z" }, + { url = "https://files.pythonhosted.org/packages/32/75/f8919b2eafc929567d3d8411f72bdb1a2109c01caaab4ebfa5f8ffadc15b/yarl-1.22.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:0b5bcc1a9c4839e7e30b7b30dd47fe5e7e44fb7054ec29b5bb8d526aa1041093", size = 357140, upload-time = "2025-10-06T14:12:08.362Z" }, + { url = "https://files.pythonhosted.org/packages/cf/72/6a85bba382f22cf78add705d8c3731748397d986e197e53ecc7835e76de7/yarl-1.22.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c0232bce2170103ec23c454e54a57008a9a72b5d1c3105dc2496750da8cfa47c", size = 341473, upload-time = "2025-10-06T14:12:10.994Z" }, + { url = "https://files.pythonhosted.org/packages/35/18/55e6011f7c044dc80b98893060773cefcfdbf60dfefb8cb2f58b9bacbd83/yarl-1.22.0-cp314-cp314t-win32.whl", hash = "sha256:8009b3173bcd637be650922ac455946197d858b3630b6d8787aa9e5c4564533e", size = 89056, upload-time = "2025-10-06T14:12:13.317Z" }, + { url = "https://files.pythonhosted.org/packages/f9/86/0f0dccb6e59a9e7f122c5afd43568b1d31b8ab7dda5f1b01fb5c7025c9a9/yarl-1.22.0-cp314-cp314t-win_amd64.whl", hash = "sha256:9fb17ea16e972c63d25d4a97f016d235c78dd2344820eb35bc034bc32012ee27", size = 96292, upload-time = "2025-10-06T14:12:15.398Z" }, + { url = "https://files.pythonhosted.org/packages/48/b7/503c98092fb3b344a179579f55814b613c1fbb1c23b3ec14a7b008a66a6e/yarl-1.22.0-cp314-cp314t-win_arm64.whl", hash = "sha256:9f6d73c1436b934e3f01df1e1b21ff765cd1d28c77dfb9ace207f746d4610ee1", size = 85171, upload-time = "2025-10-06T14:12:16.935Z" }, + { url = "https://files.pythonhosted.org/packages/73/ae/b48f95715333080afb75a4504487cbe142cae1268afc482d06692d605ae6/yarl-1.22.0-py3-none-any.whl", hash = "sha256:1380560bdba02b6b6c90de54133c81c9f2a453dee9912fe58c1dcced1edb7cff", size = 46814, upload-time = "2025-10-06T14:12:53.872Z" }, +] From 3f75b6d61d685115c801639fdb8df0d553f9fb92 Mon Sep 17 00:00:00 2001 From: Dohyun Lim Date: Mon, 12 Jan 2026 16:50:16 +0900 Subject: [PATCH 6/6] add facilities from result of crawling --- .DS_Store | Bin 0 -> 8196 bytes app/.DS_Store | Bin 0 -> 8196 bytes app/home/.DS_Store | Bin 0 -> 6148 bytes app/home/api/routers/v1/home.py | 7 +- app/lyric/.DS_Store | Bin 0 -> 6148 bytes app/song/.DS_Store | Bin 0 -> 6148 bytes app/utils/chatgpt_prompt.py | 33 +++-- app/utils/nvMapPwScraper.py | 113 ++++++++++++++++++ app/video/.DS_Store | Bin 0 -> 6148 bytes docs/.DS_Store | Bin 0 -> 6148 bytes image/.DS_Store | Bin 0 -> 6148 bytes image/2025-12-26/.DS_Store | Bin 0 -> 10244 bytes poc/.DS_Store | Bin 0 -> 6148 bytes poc/crawling/2026-01-12/main-PwScraper.py | 29 +++++ poc/crawling/2026-01-12/nvMapPwScraper.py | 113 ++++++++++++++++++ .../nvMapScraper.py} | 10 +- 16 files changed, 286 insertions(+), 19 deletions(-) create mode 100644 .DS_Store create mode 100644 app/.DS_Store create mode 100644 app/home/.DS_Store create mode 100644 app/lyric/.DS_Store create mode 100644 app/song/.DS_Store create mode 100644 app/utils/nvMapPwScraper.py create mode 100644 app/video/.DS_Store create mode 100644 docs/.DS_Store create mode 100644 image/.DS_Store create mode 100644 image/2025-12-26/.DS_Store create mode 100644 poc/.DS_Store create mode 100644 poc/crawling/2026-01-12/main-PwScraper.py create mode 100644 poc/crawling/2026-01-12/nvMapPwScraper.py rename poc/crawling/{nvMapScraper-2026-01-12.py => 2026-01-12/nvMapScraper.py} (96%) diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..8e90c8cff201144f5b4d7f469ffbde513a443e25 GIT binary patch literal 8196 zcmeHL&ubGw6n>MWCYVbE4}}(71;HK^tABuNN%1Na1wn{SH>P5f4K^(Z9`+)XLZKpv z7jIq^{3oPPk3D$sD4wb(@efeH`O)1s-3>wmQs|p9^V0d=oA1rHv%9<{A~m-b%@R!# zQ4L+&Mjb;z)41-rR&q0!U=`wNr8~Q@6!!)>Pni$}L;+Di6c7bOf#ae8-r2gxx-3Pl-qtREP6QlYgniUOiQUIAUZSLh0L=@AXR`u)tGFC6Q| z&1QQgZey5vATKF5#Q(B@$^kw9N8J-K##pk0vd0snjziqock64%I z_-}8XFOku!j4TH<@barad4>EO!t<%#+BnE3MKg`^sK?g`uqe(&L@{((^%$$A&m7~N zch9ry?qd0_i*S#(dRy~O;4JpA*DiHD=9&3DALZOzFW!B;XU`mq=j_EE9{*pi$FDJ+U5ax4+K2ZUKl8{mFZS^GEyEO4zlPp2=W>;X&?3TrZF5Q=n>!}Lz0-k0 zUAl}s`}B}vKiBCuSnP-^@qOL7|2t?|U5~t4ros5D`Fff2QpR0@bL#K^^*;9R5Wb(O zz5Rn{Q;KH!@kdRcS6X=a8hUt#j$>T0200fUcYNORO~^7)&`1Yszt0SB@Ls b0IoVFbT+XTGid+)Lx8;hjqWm>Yz6)Tru2?* literal 0 HcmV?d00001 diff --git a/app/.DS_Store b/app/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..725195a47e501098ecf095c065f5fda01d6ca58c GIT binary patch literal 8196 zcmeHMziSjh6n=BL!-ZI+OkuI0e}KUzV6(#lpo0;2tlifSC5z#j=^G)`>x8Iv@=5~1-A~I|H{S~5RB8t!% zmliS9G`4fEw1&TO4QLQg)T8_814^k=@zx8ffGVI0r~;~hD)2WbfOj^xXvTZrS#?we zRDu6e0e(Kj=!}WS!l8Y1V6Y_su!+mIVU9Y$#>5^IkA*`UihH{1!T3<)OAO<}VUO7z zn0PE4x^OZsoQ!8SzCtmU9dWUBCzCkTQ58@HstR!JzKCkQLt}ar)bE|)*2+dN&&DpO zbvWBI%iHblFz>=6dUx;n!RY1JTl2j8zu`R|$Sh*q7Eg>G<+MX-nBk2~+GI|bRu5nK zoXXfNpJq{K4|zA4H=;hiZ|tFW(RVNM-#)7Ik$F5$k0;tx?j`e?=NIN>H|H|)O0j<_ zjqGd$eYWw}Zm7@Io5*jbugvqw(ZknXuQ~ox{eHzi%sW9U*vA3(F}t9n`F=;*WM1p% zr{Btb^s!R6I(xv|c+0#k8se<)K%-uukooX2v`X%iyJr(_5ii;6JwpBi=5ONcG-;Riv?DZZY z|8-t>iynZT&uSj7eE1`@O8)ns%C(Dl$zSgg@+Zu%O%+fDrV1>$=`z><>$AWAPXlzO z3aA4AoC2oV-e|93S-!TeERbvM7=06+8~YUwZ3qTijstBu4lMs+hh!GY> z82C*rh`U!)-uY77O^HZUPg-T75)pYQjQK@WQ-b@sq+(9DECYqS zN0aubNgZlaJ;inn&H?AZZ*zdxZV{`sP6Il}+D+DPy|-VkHKYDONnUx#X7-~nZ1kcA z7@k;vzCOHsugqe%zQG=JOciS^CI^)R>RS55(oNE1>Uq0;8tKvF`caZU-D~9&a`Fo_ z)Vo?AnTJ+h+P*;E35J>fQ@o7wr&x)OY?h@5(?)pE)21Ujr7m=}Cl$>-PUD!Gs;l>} zJL(yw?q#|&i)ZU9v95VKW;LiMJSuM4y{49rjj<_2)-P!JN8p5 z+(CiWZ)&)zj5SPfk|&hKv2{ov*o(gqII}stqC!_Y2b=@Wfw2R;Klmt&fyP*&+&WOn zR{&rh%`$K;_duY}4ZuKStPm{-p@st0P@!Kjgc^=^U-JTuu|hSRgv^Zl=*&XDp$NSL z3t!Sn1PWd49B>ZU4&>Cw5}*H@+3)}MAos~R;2ii@4v2hM3#*utK3h|h@CM0cnG)oC81Vz!%t*(Aoe1 literal 0 HcmV?d00001 diff --git a/app/home/api/routers/v1/home.py b/app/home/api/routers/v1/home.py index 440cb8b..fad8ca7 100644 --- a/app/home/api/routers/v1/home.py +++ b/app/home/api/routers/v1/home.py @@ -193,9 +193,12 @@ async def crawling(request_body: CrawlingRequest): logger.info(f"[crawling] Step 3-3: GPT API 호출 완료 - 응답 {len(raw_response)}자 ({step3_3_elapsed:.1f}ms)") print(f"[crawling] Step 3-3: GPT API 호출 완료 - 응답 {len(raw_response)}자 ({step3_3_elapsed:.1f}ms)") - # Step 3-4: 응답 파싱 + # Step 3-4: 응답 파싱 (크롤링에서 가져온 facility_info 전달) step3_4_start = time.perf_counter() - parsed = await chatgpt_service.parse_marketing_analysis(raw_response) + print(f"[crawling] Step 3-4: 응답 파싱 시작 - facility_info: {scraper.facility_info}") + parsed = await chatgpt_service.parse_marketing_analysis( + raw_response, facility_info=scraper.facility_info + ) marketing_analysis = MarketingAnalysis(**parsed) step3_4_elapsed = (time.perf_counter() - step3_4_start) * 1000 print(f"[crawling] Step 3-4: 응답 파싱 완료 ({step3_4_elapsed:.1f}ms)") diff --git a/app/lyric/.DS_Store b/app/lyric/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..6b464c008fe676bed2297a8954ed4be0be1fbc58 GIT binary patch literal 6148 zcmeHLJx{|h5IxfZ5fxI|81ob8$bb~8up@P1YUzh)MN1-DiVy>tI|09f5eWeU8wEY^V^s+rKy7`UhxNWl7U@|$djHzSu8+B8U$>+U3=A-j^QCdIiwd=icy=Cg_ zw^|RC`*z)}+iZkc-)j!8wH_1mm^@}j*?elu#{-`h9n+9H;MJOBH2jV+=GV3gxQmpwOeT{*}L?Jvdp;Cb=Rp=vzQ0W-=bzGn^QK-^M=);H5m4!Z`2w5HT`!bwF zpwRVB0jGeiKu+BjdH>&;eg3zT+?`XvDe$ip5c#kYmhqAF-kSMvyx00@H8eJkOBBi! lbb33M7rYho{|eIJ^Z5c8XiOAh1m=DSNEuw`6!=jEz5vRc)eryx literal 0 HcmV?d00001 diff --git a/app/song/.DS_Store b/app/song/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..4e8bde65f06b362ed74882aacfb10bbdec489631 GIT binary patch literal 6148 zcmeHLyH3L}6uqVeDvD4g79^H@0{w$fm4ykZ6H}oN(TavdEfjUj%mjP|GXpTQAhC60 zW8pgx=h{|dH%TQH1jv?rPhubYo}9>WT_O^-i%ylOLPRB0#^M@6M&W+0sj{S7wtzy; z(WYZ+Q;)jTOtD>qbHF+9+Z^DvTgGZ_QbZH1-DLeX2Pf4=I}9Qvd2^W048nT7H3(Z^ zl*XOMo3pEz-9_xqH`r0nRI$Ti3Q!qQ-_|#sCOxK}r|p>@JuV27{OMjRpYSj#td0qVdgz+by1Mg<#-CXnQ`7p}-SeS( zN2$3?Rf~8Tx|Zpj)gaD!#G=XQHMMNK&$L*KN4Rf4CMIOi2aUg~Kk$^p$OR22TMdyHXz&S8;fWHqODxJcgz=EVx-5Cpv) i%M0F$`F{mj(C6_5(AO9%L<@@hAs}sV!8!1w4txPc dict: + async def parse_marketing_analysis( + self, raw_response: str, facility_info: str | None = None + ) -> dict: """ChatGPT 마케팅 분석 응답을 파싱하고 요약하여 딕셔너리로 반환 + Args: + raw_response: ChatGPT 마케팅 분석 응답 원문 + facility_info: 크롤링에서 가져온 편의시설 정보 문자열 + Returns: dict: {"report": str, "tags": list[str], "facilities": list[str]} """ @@ -377,7 +374,7 @@ class ChatgptService: try: json_data = json.loads(json_match.group(1)) tags = json_data.get("tags", []) - facilities = json_data.get("facilities", []) + print(f"[parse_marketing_analysis] GPT 응답에서 tags 파싱 완료: {tags}") # JSON 블록을 제외한 리포트 부분 추출 report = raw_response[: json_match.start()].strip() # --- 구분자 제거 @@ -386,10 +383,22 @@ class ChatgptService: if report.endswith("---"): report = report[:-3].strip() except json.JSONDecodeError: + print("[parse_marketing_analysis] JSON 파싱 실패") pass + # 크롤링에서 가져온 facility_info로 facilities 설정 + print(f"[parse_marketing_analysis] 크롤링 facility_info 원본: {facility_info}") + if facility_info: + # 쉼표로 구분된 편의시설 문자열을 리스트로 변환 + facilities = [f.strip() for f in facility_info.split(",") if f.strip()] + print(f"[parse_marketing_analysis] facility_info 파싱 결과: {facilities}") + else: + facilities = ["등록된 정보 없음"] + print("[parse_marketing_analysis] facility_info 없음 - '등록된 정보 없음' 설정") + # 리포트 내용을 500자로 요약 if report: report = await self.summarize_marketing(report) + print(f"[parse_marketing_analysis] 최종 facilities: {facilities}") return {"report": report, "tags": tags, "facilities": facilities} diff --git a/app/utils/nvMapPwScraper.py b/app/utils/nvMapPwScraper.py new file mode 100644 index 0000000..d724764 --- /dev/null +++ b/app/utils/nvMapPwScraper.py @@ -0,0 +1,113 @@ +import asyncio +from playwright.async_api import async_playwright +from urllib import parse + +class nvMapPwScraper(): + # cls vars + is_ready = False + _playwright = None + _browser = None + _context = None + _win_width = 1280 + _win_height = 720 + _max_retry = 30 # place id timeout threshold seconds + + # instance var + page = None + + @classmethod + def default_context_builder(cls): + context_builder_dict = {} + context_builder_dict['viewport'] = { + 'width' : cls._win_width, + 'height' : cls._win_height + } + context_builder_dict['screen'] = { + 'width' : cls._win_width, + 'height' : cls._win_height + } + context_builder_dict['user_agent'] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36" + context_builder_dict['locale'] = 'ko-KR' + context_builder_dict['timezone_id']='Asia/Seoul' + + return context_builder_dict + + @classmethod + async def initiate_scraper(cls): + if not cls._playwright: + cls._playwright = await async_playwright().start() + if not cls._browser: + cls._browser = await cls._playwright.chromium.launch(headless=True) + if not cls._context: + cls._context = await cls._browser.new_context(**cls.default_context_builder()) + cls.is_ready = True + + def __init__(self): + if not self.is_ready: + raise Exception("nvMapScraper is not initiated") + + async def __aenter__(self): + await self.create_page() + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.page.close() + + async def create_page(self): + self.page = await self._context.new_page() + await self.page.add_init_script( +'''const defaultGetter = Object.getOwnPropertyDescriptor( + Navigator.prototype, + "webdriver" +).get; +defaultGetter.apply(navigator); +defaultGetter.toString(); +Object.defineProperty(Navigator.prototype, "webdriver", { + set: undefined, + enumerable: true, + configurable: true, + get: new Proxy(defaultGetter, { + apply: (target, thisArg, args) => { + Reflect.apply(target, thisArg, args); + return false; + }, + }), +}); +const patchedGetter = Object.getOwnPropertyDescriptor( + Navigator.prototype, + "webdriver" +).get; +patchedGetter.apply(navigator); +patchedGetter.toString();''') + + await self.page.set_extra_http_headers({ + 'sec-ch-ua': '\"Not?A_Brand\";v=\"99\", \"Chromium\";v=\"130\"' + }) + await self.page.goto("http://google.com") + + async def goto_url(self, url, wait_until="domcontentloaded", timeout=20000): + page = self.page + await page.goto(url, wait_until=wait_until, timeout=timeout) + + async def get_place_id_url(self, selected): + + title = selected['title'].replace("", "").replace("", "") + address = selected.get('roadAddress', selected['address']).replace("", "").replace("", "") + encoded_query = parse.quote(f"{address} {title}") + url = f"https://map.naver.com/p/search/{encoded_query}" + + await self.goto_url(url, wait_until="networkidle",timeout = self._max_retry/2*1000) + + if "/place/" in self.page.url: + return self.page.url + + url = self.page.url.replace("?","?isCorrectAnswer=true&") + await self.goto_url(url, wait_until="networkidle",timeout = self._max_retry/2*1000) + + if "/place/" in self.page.url: + return self.page.url + + if (count == self._max_retry / 2): + raise Exception("Failed to identify place id. loading timeout") + else: + raise Exception("Failed to identify place id. item is ambiguous") diff --git a/app/video/.DS_Store b/app/video/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..2803a5f4acad20189bdaea8da4322a0407f7e065 GIT binary patch literal 6148 zcmeHLyH3L}6uqVeD!P=7F#{U|lrIQX*%4)7D)b>*wIvZP&nYt#urMI8v$1tWUHUit z00W$BTaBHxl~@oUTe6Sidz^c6BFA-!NR-YSMWO-`4@D`Csp)C`Wpt?C z(G*_n&ODy2D?&QhQ(nS`YOIl?(GCg>niS jy&cOAZ^it-f-H!6+yVL;BZU}2aX$p44X$wx{HOz85n|L( literal 0 HcmV?d00001 diff --git a/docs/.DS_Store b/docs/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..d146433ed984bdbf6ee9824c0a8f271827a3c1db GIT binary patch literal 6148 zcmeHKu};G<5IvU&6&TtHb<7Vi^bbN6B$zuP7Sg7)h^DDp7?|)1f5K~2BSi|*ju`=(trzKs}aystz zSF)u;6c7dengVtMNN7e0O{wz#9p>5GkPXgmfK7~hIawaZgK0kCv4@N2*Yl^h<$w&sCFiK2igAPN);@ct0O86$_d!UE-!MZE!uKY?((7B%*x$Rl$jmx4^29$ z$f871Kosy5*s+goKL1bF-~at0c@hOgfq$id3gUj;!;;+Dy0SPvYeV=YoQ?CeMN@*{ hj$_l{qqqY%hOv+vz{sJth#r`H2pAb8hyuT=z$a~|q#*zR literal 0 HcmV?d00001 diff --git a/image/.DS_Store b/image/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..e870d4fa32d44e97cf0ce5967fdcfbd8a4ce6dcb GIT binary patch literal 6148 zcmeHKy-ou$47Q=e36_qGSs6~^km!g)bqvgX0aPl{q2;=C&&-R#z`$$p7JUAp;>1;A zKnNjQa=s+C6W=FY5)%s8Cd8qPD$=Z z$oC9-fy{ULukM@KUANw7(x>&yKEHL>w)0gthrPPFe0zR)e7f52yZE;6X8C#lS4|_D zU?3O>27-ZL;0GAMoh?!w8%7%p1OvgqjsZCz5>zld7DGKc&}az&lxMUG`cg|sOmfVQ z#Sj(nC+5&W6zj1HnL_fkPXP<^I3M zFEd!=_d{Y73 literal 0 HcmV?d00001 diff --git a/image/2025-12-26/.DS_Store b/image/2025-12-26/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..bf8036b15815419a806e4f2d25a1034702b464f5 GIT binary patch literal 10244 zcmeI1KX21O7{=eDRTT*a#*Q93uprq^ z!Z+YkFfexP^WL5C(b%#Z*9f8ath>iP-#u1-esj@#AtH5jUIauQ5sgq;pFTlTQ}{mD zjq=F$>_Zji6D`O`oziot6d@o4gn$qb0z%+lB!J&+E~Cdrr4<4~KnVOM!0UsD%9>a$ zjq0TXjZOieyXe*h=g0%}9M5WEwKS@y!qa3A%1%`_#ZYEC?t45OnpiE3n(3s>bW--o z%4R4^KOOTtJ)BfxR9Yb*1U3n9?tXx5J))Qn|H$8$$m0WK@>AS1XETiBgR}bu<+P*_ zy3qGCN+~~i8yx5B)tP?G-j7!g>AhOd=h?|RgXie$mrvhbzyJQ?Vf~9i{m&4WI#Z(SiHc-Y)m6pN-sm_*dMA@NePH{6a8} zK{>G8WAx>BxQ{{J*D;^t4Fx!6G;ZPE%iHCCoqw*2_n!V0_aXdSxQB@B0*rahi4oCe zor$ofxbdEWa*p>CV^jv_A+8Twx%cvRxu0Ita_{M1aUa6Jm3yS4JkzTTM?SCbk^T-; z>r9Hb!*8ZQyVUIj@gKFsdk7z1xwi6lxnF*0;NHu>;y#3b2kt4@goxr42Xi+u?Z&$g zekoS<363$M-p3XCI&k0G+vR@qv5|WZ|BCw%{x#hBw^fP|5CTF#2nYcoP)}gTbbGx2 z|FZf2|N6<&D+GkVe?dU)&X4Cu_$YR7ed9y%Ub~0-29*nsD~;+YX!LeGRBy-Qg16(J zq4HRtl?%=jtEEx&p#1ee19%U!VQ<0Bhla?{SL-St8p6LOA9D8@d*$dI@=(eDIiUA8 Q_IH{4);V+s?)Ub-1%kTjUH||9 literal 0 HcmV?d00001 diff --git a/poc/.DS_Store b/poc/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..098ffaf34cbae05b39806147847404c8ff36efcf GIT binary patch literal 6148 zcmeHKu};H44D~^Ws4#RwjQNE24?>lGK_@0?+NdBkq?A@nNSP5Iz&G#@NEHh^8-K&I zeQFvt6_f!1vZeF8^VxU4C*_aTlCEex z8F%^{-exccjDg?A0Drpy4QWOLx}~-6cbI2WO}6(?=ac1eoJ{hB=YqTT`|$qtq~34z zCBNxKr(fN스테이,머뭄', + 'link': 'https://www.instagram.com/staymeomoom', + 'category': '숙박>펜션', + 'description': '', + 'telephone': '', + 'address': '전북특별자치도 군산시 신흥동 63-18', + 'roadAddress': '전북특별자치도 군산시 절골길 18', + 'mapx': '1267061254', + 'mapy': '359864175', + 'lng': 126.7061254, + 'lat': 35.9864175} + + async with nvMapPwScraper() as pw_scraper: + new_url = await pw_scraper.get_place_id_url(selected) + + print(new_url) + nv_scraper = nvMapScraper(new_url) # 이후 동일한 플로우 + await nv_scraper.scrap() + print(nv_scraper.rawdata) + return + +print("running main_funtion..") +asyncio.run(main_function()) \ No newline at end of file diff --git a/poc/crawling/2026-01-12/nvMapPwScraper.py b/poc/crawling/2026-01-12/nvMapPwScraper.py new file mode 100644 index 0000000..d724764 --- /dev/null +++ b/poc/crawling/2026-01-12/nvMapPwScraper.py @@ -0,0 +1,113 @@ +import asyncio +from playwright.async_api import async_playwright +from urllib import parse + +class nvMapPwScraper(): + # cls vars + is_ready = False + _playwright = None + _browser = None + _context = None + _win_width = 1280 + _win_height = 720 + _max_retry = 30 # place id timeout threshold seconds + + # instance var + page = None + + @classmethod + def default_context_builder(cls): + context_builder_dict = {} + context_builder_dict['viewport'] = { + 'width' : cls._win_width, + 'height' : cls._win_height + } + context_builder_dict['screen'] = { + 'width' : cls._win_width, + 'height' : cls._win_height + } + context_builder_dict['user_agent'] = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36" + context_builder_dict['locale'] = 'ko-KR' + context_builder_dict['timezone_id']='Asia/Seoul' + + return context_builder_dict + + @classmethod + async def initiate_scraper(cls): + if not cls._playwright: + cls._playwright = await async_playwright().start() + if not cls._browser: + cls._browser = await cls._playwright.chromium.launch(headless=True) + if not cls._context: + cls._context = await cls._browser.new_context(**cls.default_context_builder()) + cls.is_ready = True + + def __init__(self): + if not self.is_ready: + raise Exception("nvMapScraper is not initiated") + + async def __aenter__(self): + await self.create_page() + return self + + async def __aexit__(self, exc_type, exc, tb): + await self.page.close() + + async def create_page(self): + self.page = await self._context.new_page() + await self.page.add_init_script( +'''const defaultGetter = Object.getOwnPropertyDescriptor( + Navigator.prototype, + "webdriver" +).get; +defaultGetter.apply(navigator); +defaultGetter.toString(); +Object.defineProperty(Navigator.prototype, "webdriver", { + set: undefined, + enumerable: true, + configurable: true, + get: new Proxy(defaultGetter, { + apply: (target, thisArg, args) => { + Reflect.apply(target, thisArg, args); + return false; + }, + }), +}); +const patchedGetter = Object.getOwnPropertyDescriptor( + Navigator.prototype, + "webdriver" +).get; +patchedGetter.apply(navigator); +patchedGetter.toString();''') + + await self.page.set_extra_http_headers({ + 'sec-ch-ua': '\"Not?A_Brand\";v=\"99\", \"Chromium\";v=\"130\"' + }) + await self.page.goto("http://google.com") + + async def goto_url(self, url, wait_until="domcontentloaded", timeout=20000): + page = self.page + await page.goto(url, wait_until=wait_until, timeout=timeout) + + async def get_place_id_url(self, selected): + + title = selected['title'].replace("", "").replace("", "") + address = selected.get('roadAddress', selected['address']).replace("", "").replace("", "") + encoded_query = parse.quote(f"{address} {title}") + url = f"https://map.naver.com/p/search/{encoded_query}" + + await self.goto_url(url, wait_until="networkidle",timeout = self._max_retry/2*1000) + + if "/place/" in self.page.url: + return self.page.url + + url = self.page.url.replace("?","?isCorrectAnswer=true&") + await self.goto_url(url, wait_until="networkidle",timeout = self._max_retry/2*1000) + + if "/place/" in self.page.url: + return self.page.url + + if (count == self._max_retry / 2): + raise Exception("Failed to identify place id. loading timeout") + else: + raise Exception("Failed to identify place id. item is ambiguous") diff --git a/poc/crawling/nvMapScraper-2026-01-12.py b/poc/crawling/2026-01-12/nvMapScraper.py similarity index 96% rename from poc/crawling/nvMapScraper-2026-01-12.py rename to poc/crawling/2026-01-12/nvMapScraper.py index 7d155e4..38bc1cd 100644 --- a/poc/crawling/nvMapScraper-2026-01-12.py +++ b/poc/crawling/2026-01-12/nvMapScraper.py @@ -112,8 +112,8 @@ class nvMapScraper(): facilities = c_elem.parent.parent.find('div').string return facilities -url = "https://naver.me/IgJGCCic" -scraper = nvMapScraper(url) -asyncio.run(scraper.scrap()) -print(scraper.image_link_list) -print(len(scraper.image_link_list)) \ No newline at end of file +# url = "https://naver.me/IgJGCCic" +# scraper = nvMapScraper(url) +# asyncio.run(scraper.scrap()) +# print(scraper.image_link_list) +# print(len(scraper.image_link_list)) \ No newline at end of file

| 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%0DZa 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 U&3Ugi^?hDz&3Ugi^?hIe*=mOZhX4Qo literal 0 HcmV?d00001 diff --git a/image/2025-12-26/0694e0e8-ee74-7d65-8000-2ac63bd131de/darak-1_003.jpg b/image/2025-12-26/0694e0e8-ee74-7d65-8000-2ac63bd131de/darak-1_003.jpg new file mode 100644 index 0000000000000000000000000000000000000000..05462d6f14cc6cf89c60a81f5dfc22b83e0034ec GIT binary patch literal 195312 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%0DF1Y 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 z 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 TI{RN~)q4-P{`!!=j935JmEGzb literal 0 HcmV?d00001 diff --git a/image/2025-12-26/0694e0e8-ee74-7d65-8000-2ac63bd131de/darak-2_004.jpg b/image/2025-12-26/0694e0e8-ee74-7d65-8000-2ac63bd131de/darak-2_004.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7ba93ea22b944f2f57d6dcd323af6d9daa0822f9 GIT binary patch literal 96737 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