148211e236
- app.py: replace print() with logging, basicConfig with LOG_LEVEL env var - api_client.py: shared AsyncClient instance (connection pooling), URL-encode delete_document path parameter, aclose() for cleanup - services/document.py: validate file exists and extension before ingest - tests/: ChatService (4) + DocumentService (6) unit tests via pytest-asyncio - pyproject.toml: asyncio_mode = auto - requirements-dev.txt: pytest, pytest-asyncio Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
25 lines
836 B
Python
25 lines
836 B
Python
from pathlib import Path
|
|
|
|
from api_client import APIClientProtocol
|
|
|
|
_ALLOWED_EXTENSIONS = {".pdf", ".txt"}
|
|
|
|
|
|
class DocumentService:
|
|
def __init__(self, api_client: APIClientProtocol):
|
|
self._api = api_client
|
|
|
|
async def ingest(self, file_path: str) -> dict:
|
|
path = Path(file_path)
|
|
if not path.is_file():
|
|
raise ValueError(f"파일을 찾을 수 없습니다: {file_path}")
|
|
if path.suffix.lower() not in _ALLOWED_EXTENSIONS:
|
|
raise ValueError(f"지원하지 않는 파일 형식입니다: {path.suffix} (허용: pdf, txt)")
|
|
return await self._api.ingest(file_path)
|
|
|
|
async def list_documents(self) -> list[str]:
|
|
return await self._api.list_documents()
|
|
|
|
async def delete_document(self, source: str) -> None:
|
|
await self._api.delete_document(source)
|