97 lines
2.4 KiB
Python
97 lines
2.4 KiB
Python
"""
|
|
# Summary
|
|
|
|
PDF client abstractions for OmniRead.
|
|
|
|
This module defines the **client layer** responsible for retrieving raw PDF
|
|
bytes from a concrete backing store.
|
|
|
|
Clients provide low-level access to PDF binaries and are intentionally
|
|
decoupled from scraping and parsing logic. They do not perform validation,
|
|
interpretation, or content extraction.
|
|
|
|
Typical backing stores include:
|
|
|
|
- Local filesystems
|
|
- Object storage (S3, GCS, etc.)
|
|
- Network file systems
|
|
"""
|
|
|
|
from abc import ABC, abstractmethod
|
|
from pathlib import Path
|
|
from typing import Any
|
|
|
|
|
|
class BasePDFClient(ABC):
|
|
"""
|
|
Abstract client responsible for retrieving PDF bytes.
|
|
|
|
Retrieves bytes from a specific backing store (filesystem, S3, FTP, etc.).
|
|
|
|
Notes:
|
|
**Responsibilities:**
|
|
|
|
- Implementations must accept a source identifier appropriate to
|
|
the backing store.
|
|
- Return the full PDF binary payload.
|
|
- Raise retrieval-specific errors on failure.
|
|
"""
|
|
|
|
@abstractmethod
|
|
def fetch(self, source: Any) -> bytes:
|
|
"""
|
|
Fetch raw PDF bytes from the given source.
|
|
|
|
Args:
|
|
source (Any):
|
|
Identifier of the PDF location, such as a file path, object storage key, or remote reference.
|
|
|
|
Returns:
|
|
bytes:
|
|
Raw PDF bytes.
|
|
|
|
Raises:
|
|
Exception:
|
|
Retrieval-specific errors defined by the implementation.
|
|
"""
|
|
raise NotImplementedError
|
|
|
|
|
|
class FileSystemPDFClient(BasePDFClient):
|
|
"""
|
|
PDF client that reads from the local filesystem.
|
|
|
|
Notes:
|
|
**Guarantees:**
|
|
|
|
- This client reads PDF files directly from the disk and returns
|
|
their raw binary contents.
|
|
"""
|
|
|
|
def fetch(self, path: Path) -> bytes:
|
|
"""
|
|
Read a PDF file from the local filesystem.
|
|
|
|
Args:
|
|
path (Path):
|
|
Filesystem path to the PDF file.
|
|
|
|
Returns:
|
|
bytes:
|
|
Raw PDF bytes.
|
|
|
|
Raises:
|
|
FileNotFoundError:
|
|
If the path does not exist.
|
|
ValueError:
|
|
If the path exists but is not a file.
|
|
"""
|
|
|
|
if not path.exists():
|
|
raise FileNotFoundError(f"PDF not found: {path}")
|
|
|
|
if not path.is_file():
|
|
raise ValueError(f"Path is not a file: {path}")
|
|
|
|
return path.read_bytes()
|