* feat: accept pdf, images and office files * refactor: rename FileConverter to FileParser, simplify file retain API - Rename engine/converters/ → engine/parsers/, FileConverter → FileParser, ConverterRegistry → FileParserRegistry, MarkitdownConverter → MarkitdownParser - Rename env var HINDSIGHT_API_FILE_CONVERTER → HINDSIGHT_API_FILE_PARSER - Remove async/document_tags params from FileRetainRequest (always async now) - Add retain_files() to Python Hindsight client and retainFiles() to TypeScript client - Add sample.pdf to doc examples for working file upload demonstrations - Update test_file_retain.py to use new parser names and always-async behavior - Fix Go client missing os import in api_files.go - Simplify postgresql.py storage to minimal schema * fix: update rust CLI tests to use is_supported_file instead of is_text_file * fix: patch Go api_files.go to add missing 'os' import after generation * fix: insert 'os' import after 'net/url' in api_files.go patch for correct position * chore: regenerate OpenAPI spec and clients (converter→parser description update)
83 lines
1.8 KiB
Python
83 lines
1.8 KiB
Python
"""Abstract base class for file storage backends."""
|
|
|
|
from abc import ABC, abstractmethod
|
|
|
|
|
|
class FileStorage(ABC):
|
|
"""Abstract base for file storage backends."""
|
|
|
|
@abstractmethod
|
|
async def store(
|
|
self,
|
|
file_data: bytes,
|
|
key: str,
|
|
metadata: dict[str, str] | None = None,
|
|
) -> str:
|
|
"""
|
|
Store file and return storage key.
|
|
|
|
Args:
|
|
file_data: Raw file bytes
|
|
key: Storage key (e.g., "banks/{bank_id}/files/{file_id}.pdf")
|
|
metadata: Optional metadata to store with file
|
|
|
|
Returns:
|
|
Storage key that can be used to retrieve the file
|
|
"""
|
|
pass
|
|
|
|
@abstractmethod
|
|
async def retrieve(self, key: str) -> bytes:
|
|
"""
|
|
Retrieve file by storage key.
|
|
|
|
Args:
|
|
key: Storage key
|
|
|
|
Returns:
|
|
File data as bytes
|
|
|
|
Raises:
|
|
FileNotFoundError: If file does not exist
|
|
"""
|
|
pass
|
|
|
|
@abstractmethod
|
|
async def delete(self, key: str) -> None:
|
|
"""
|
|
Delete file by storage key.
|
|
|
|
Args:
|
|
key: Storage key
|
|
"""
|
|
pass
|
|
|
|
@abstractmethod
|
|
async def exists(self, key: str) -> bool:
|
|
"""
|
|
Check if file exists.
|
|
|
|
Args:
|
|
key: Storage key
|
|
|
|
Returns:
|
|
True if file exists, False otherwise
|
|
"""
|
|
pass
|
|
|
|
@abstractmethod
|
|
async def get_download_url(self, key: str, expires_in: int = 3600) -> str:
|
|
"""
|
|
Get a URL for downloading the file.
|
|
|
|
For PostgreSQL storage, this might be a relative API path.
|
|
For S3, this would be a pre-signed URL.
|
|
|
|
Args:
|
|
key: Storage key
|
|
expires_in: Expiration time in seconds (may be ignored for some backends)
|
|
|
|
Returns:
|
|
Download URL or path
|
|
"""
|
|
pass
|