Python SDK'sına genel bakış
Python SDK’sına genel bakış
“Python SDK’sına genel bakış” başlıklı bölümNextPDF Python yazılım geliştirme kiti (SDK), kaynak izi içeren Taşınabilir Belge Biçimi (PDF) ayıklamasına ihtiyaç duyan Python uygulamaları içindir. Sayfa dizinini, güven değerini, isteğe bağlı sınırlayıcı kutuları ve kaynak PDF o yapıyı sunduğunda anlamsal düğüm tanımlayıcılarını kapsayan alıntı bağlantı noktalarına sahip yapılandırılmış bloklar döndürür.
Veri işleme hattınızın “Bu metin hangi sayfadan geldi?”, “Bu değeri hangi tablo destekliyor?” ya da “Bu iki PDF arasında ne değişti?” gibi soruları, PDF ayıklamasını anonim düz metin gibi ele almadan yanıtlaması gerekiyorsa SDK’yı kullanın.
Neler sağlar
“Neler sağlar” başlıklı bölüm- Betikler, toplu işler ve not defterleri için eşzamanlı bir
NextPDFistemcisi. - Eşzamansız bir
AsyncNextPDFistemcisi —asyncio, FastAPI ve diğer eşzamansız çalışma ortamları için. - Bir dosya yolundan ya da standart girdiden tek seferlik ayıklama yapıp standart çıktıya veya bir dosyaya yazan bir
nextpdfkomut satırı arabirimi (CLI). - Yapay zeka (AI) aracılarının PDF ayıklama araçlarını doğrudan çağırabilmesi için isteğe bağlı bir Model Context Protocol (MCP) sunucusu.
- NextPDF Connect ile üretim kullanımı için uzak bir arka uç.
- Çevrimdışı, yalnızca kitaplık tabanlı ayıklama için
pypdfaracılığıyla çalışan yerel bir arka uç.
Arka uç seçenekleri
“Arka uç seçenekleri” başlıklı bölümUzak arka uç, PDF baytlarını bir NextPDF Connect sunucusuna gönderir. Ayıklama davranışını, kimlik doğrulamayı, kotaları ve operasyonel denetimleri merkezileştirdiği için üretimde önerilen yol budur.
Yerel arka uç, Python işleminin içinde çalışır ve PDF’leri pypdf aracılığıyla okur. Çevrimdışı geliştirme ve etiketli PDF’ler için kullanışlıdır; ancak kesin sınırlayıcı kutular sağlayamaz ve etiketsiz PDF’lerde sezgisel, paragraf düzeyinde ayıklama kullanır. Yerel arka uç yalnızca kitaplık tabanlıdır: kullanmak için bir LocalBackend örneğini AsyncNextPDF içine enjekte edin. nextpdf CLI ve MCP sunucusu bu arka ucu kullanamaz. Tam karşılaştırma için Arka uç seçim matrisi bölümüne bakın.
Kısıtlamalar
“Kısıtlamalar” başlıklı bölümSDK optik karakter tanıma (OCR) yapmaz. NextPDF’in gömülü metni ayıklayabilmesi için taranmış ya da yalnızca görüntü içeren PDF’lerde bir OCR adımı gerekir. Karmaşık yerleşimler, üst üste binen metinler ve sıra dışı PDF üreticileri de ayıklama kalitesini düşürebilir.
Bu nextpdf CLI yalnızca uzaktan çalışır ve bir akış arabirimi değildir. Her komut PDF’nin tamamını belleğe okur (bir dosya yolundan ya da standart girdiden), bir NextPDF Connect sunucusuna gönderir, sonucun tamamını bellekte oluşturur ve tek bir yazma işleminde dizeye dönüştürür. Bu çıktıyı --output (ya da -o) ile bir dosyaya veya standart çıktıya yönlendirebilirsiniz; ancak sonuç artımlı olarak üretilmez, bütünüyle ara belleğe alınır. CLI, yerel pypdf arka ucunu kullanamaz.
İstemci seçimi: eşzamanlı mı, eşzamansız mı
“İstemci seçimi: eşzamanlı mı, eşzamansız mı” başlıklı bölümHer iki istemci de soyut sözdizimi ağacı (AST) işlemleri için tek bir ast yöntem ad alanını paylaşır ve aynı Pydantic modellerini döndürür. Yalnızca eşzamanlılık modelleri farklıdır.
| Bağlamınız | Kullanım | Neden |
|---|---|---|
| Betikler ve toplu işler | NextPDF (eşzamanlı) | Doğrusal denetim akışı; yönetilecek olay döngüsü yok. |
| Jupyter not defterleri | NextPDF (eşzamanlı) | run_sync, çalışan olay döngüsünü algılar ve işi bir çalışan iş parçacığına yönlendirir; böylece engelleyici çağrılar hücrelerin içinde çalışır. |
Bu nextpdf CLI | NextPDF (eşzamanlı, dahili) | CLI sizin için eşzamanlı bir istemci oluşturur. |
asyncio hizmetleri | AsyncNextPDF | Yerel await; iş parçacığı devri yok. |
| FastAPI, Starlette, Eşzamansız Sunucu Ağ Geçidi Arabirimi (ASGI) | AsyncNextPDF | İstek olay döngüsünü ve aynı bağlantı havuzunu paylaşır. |
| Yüksek eşzamanlılıkla dağıtım | AsyncNextPDF | Tek bir havuzlanmış istemci üzerinden asyncio.gather ile birçok ayıklamayı eşzamanlı çalıştırın. |
NextPDF, dahili bir AsyncNextPDF örneğini sarmalar ve her çağrıyı run_sync üzerinden çalıştırır. Bir not defteri gibi çalışan bir olay döngüsünün içinde run_sync eşyordamı, işi kendi döngüsüne sahip tek çalışanlı bir iş parçacığına yönlendirir; böylece iç içe asyncio.run hatasıyla karşılaşmazsınız. Bir asyncio ya da ASGI hizmetinde, her çağrıda bu iş parçacığı devrinin bedelini ödemek yerine doğrudan AsyncNextPDF çağırın.
Eşzamansız istemci, bağlantı havuzlaması için bir httpx.AsyncClient örneğine sahiptir; bu nedenle tek bir AsyncNextPDF örneğini yeniden kullanın ve bir kez kapatın. Eşzamanlı NextPDF istemcisi close() yöntemi sunmaz. Uzun ömürlü eşzamansız iş yüklerinde AsyncNextPDF tercih edin ve yaşam döngüsünü açıkça yönetin (bkz. Üretim operasyonel modeli).
Arka uç seçim matrisi
“Arka uç seçim matrisi” başlıklı bölümBir arka uç, PdfBackend protokolünü uygular. Uzak arka uç (RemoteBackend), base_url ve api_key sağladığınızda otomatik olarak seçilir. Yerel arka ucu (LocalBackend) backend= parametresiyle AsyncNextPDF içine açıkça enjekte etmeniz gerekir; bu arka uç üst düzey nextpdf paketinden dışa aktarılmaz ve CLI veya MCP sunucusundan erişilemez.
| Yetenek | Uzak (RemoteBackend) | Yerel (LocalBackend) |
|---|---|---|
| Seçim ölçütü | base_url + api_key | AsyncNextPDF(backend=LocalBackend(...)) |
| Ağ | Güvenli Hiper Metin Aktarım Protokolü (HTTPS) üzerinden NextPDF Connect | Yok; işlem içinde çalışır |
| Kimlik doğrulama, kotalar, ölçümleme | Sunucuda merkezileştirilmiştir | Yok |
| Gözlemlenebilirlik ve operasyonel denetimler | Sunucu tarafında | Yok |
| Etiketli PDF (StructTree) ayıklaması | Evet | Evet |
| Etiketsiz PDF ayıklaması | Sunucu motoru | Sezgisel paragraf bölme, güven değeri 0.5 |
| Sınırlayıcı kutular | Evet (sunucu bunları sağladığında) | Hayır (bbox değeri None) |
| Etiketsiz PDF’lerde tablo ayıklaması | Sunucu motoru | Hiç tablo döndürmez |
| CLI / MCP sunucusundan erişilebilir | Evet | Hayır (yalnızca kitaplık) |
| Önerilen kullanım | Üretim | Çevrimdışı geliştirme, etiketli PDF testleri |
Üretimde uzak arka ucu kullanın; çünkü merkezi kimlik doğrulama, kota uygulama, ölçümleme ve gözlemlenebilirlik sunan tek yol budur. Etiketsiz girdilerde sezgisel sonuçları, sınırlayıcı kutuların olmamasını ve tablo döndürülmemesini kabul ederek yerel arka ucu çevrimdışı geliştirme ve etiketli PDF’lere karşı yapılan testler için kullanın.
"""Inject the local backend for offline, library-only extraction."""
from nextpdf import AsyncNextPDFfrom nextpdf.backends.local import LocalBackend
async def extract_offline(pdf_bytes: bytes) -> None: """Extract cited text without a NextPDF Connect server.""" async with AsyncNextPDF(backend=LocalBackend()) as client: blocks = await client.ast.extract_cited_text(pdf_bytes) for block in blocks: # Heuristic blocks on untagged PDFs report confidence 0.5. print(block.citation.confidence, block.text)Üretim operasyonel modeli
“Üretim operasyonel modeli” başlıklı bölümÜretimde uzak arka ucu NextPDF Connect ile çalıştırın. Aşağıdaki kalıplar istemci yeniden kullanımını, hata işlemeyi, yeniden denemeleri, kota işlemeyi ve zaman aşımlarını kapsar. Burada kullanılan her simge SDK’da bulunur. SDK sizin yerinize yeniden deneme yapmaz; bu nedenle yeniden deneme döngüsünden siz sorumlusunuz.
İstemciyi yeniden kullanın ve bağlantıları havuzlayın
“İstemciyi yeniden kullanın ve bağlantıları havuzlayın” başlıklı bölümRemoteBackend, bağlantı havuzlaması için kalıcı tek bir httpx.AsyncClient örneği tutar. AsyncNextPDF örneğini bir kez oluşturun, istekler arasında paylaşın ve kapanış sırasında kapatın. Her istek için ayrı bir istemci oluşturmayın.
"""Reuse one pooled async client for the lifetime of the process."""
import asyncioimport osfrom pathlib import Path
from nextpdf import AsyncNextPDF
async def main() -> None: """Run several extractions over a single pooled client.""" base_url = os.environ["NEXTPDF_BASE_URL"] # Treat the API key as a secret; read it from the environment, never hard-code it. api_key = os.environ["NEXTPDF_API_KEY"]
async with AsyncNextPDF(base_url=base_url, api_key=api_key) as client: pdf_paths = (Path("a.pdf"), Path("b.pdf"), Path("c.pdf")) tasks = [ client.ast.get_document_ast(path.read_bytes()) for path in pdf_paths ] documents = await asyncio.gather(*tasks) for document in documents: print(document.page_count, document.estimated_tokens)
if __name__ == "__main__": asyncio.run(main())Eşzamansız bağlam yöneticisi, çıkışta close() çağırır ve bu da alttaki aktarımı kapatır. Bağlam yöneticisi kullanmıyorsanız await client.close() çağrısını kendiniz yapın.
Hataları özel durum hiyerarşisiyle işleyin
“Hataları özel durum hiyerarşisiyle işleyin” başlıklı bölümSDK, türü belirlenmiş bir özel durum hiyerarşisi oluşturur. Tüm hatalar NextPDFError öğesinden türetilir; Hiper Metin Aktarım Protokolü (HTTP) düzeyindeki hatalar ise NextPDFAPIError öğesinden türetilir ve bir status_code taşır. İşleyebileceğiniz belirli türleri yakalayın ve gerektiğinde temel türe geri dönün.
| Özel durum | Oluşma koşulu | Önemli öznitelikler |
|---|---|---|
NextPDFError | Tüm SDK hataları için temel tür | status_code |
NextPDFAPIError | Sunucudan gelen herhangi bir HTTP hatası | status_code, error_code |
NextPDFLicenseError | HTTP 402; özellik daha yüksek bir sunucu katmanı gerektirir | status_code (402) |
QuotaExceededError | HTTP 429; hız sınırı veya kota aşıldı | retry_after |
AstNoStructTreeError | HTTP 422; sezgisel mod kapalıyken etiketsiz PDF | status_code (422) |
AstBuildTimeoutError | HTTP 504; AST derlemesi zaman aşımına uğradı | status_code (504) |
"""Map SDK exceptions to caller-facing outcomes."""
from nextpdf import ( AstBuildTimeoutError, AstNoStructTreeError, AsyncNextPDF, NextPDFAPIError, NextPDFError, NextPDFLicenseError, QuotaExceededError,)
async def safe_extract(client: AsyncNextPDF, pdf_bytes: bytes) -> str: """Extract text, translating known failures into a stable status string.""" try: blocks = await client.ast.extract_cited_text(pdf_bytes) except QuotaExceededError as exc: # exc.retry_after holds the server Retry-After value in seconds, or None. return f"rate-limited; retry after {exc.retry_after}s" except NextPDFLicenseError: return "feature requires a higher server tier" except AstNoStructTreeError: return "untagged PDF; enable heuristic mode or use a tagged PDF" except AstBuildTimeoutError: return "build timed out; reduce the page range" except NextPDFAPIError as exc: return f"server error (status {exc.status_code})" except NextPDFError: return "extraction failed" return "\n".join(block.text for block in blocks)Geçici hataları geri çekilmeyle yeniden deneyin
“Geçici hataları geri çekilmeyle yeniden deneyin” başlıklı bölümSDK otomatik yeniden deneme yapmaz. Çağrıları, geçici HTTP hatalarında yeniden deneyen ve sunucunun Retry-After değerini dikkate alan kendi döngünüze sarın; bu değer QuotaExceededError tarafından retry_after olarak sunulur (saniye cinsinden tam sayı ya da None). Diğer geçici durumlar için üstel geri çekilme kullanın ve NextPDFLicenseError hatasını yeniden denemeyin.
"""Retry transient failures with exponential backoff and Retry-After support."""
import asynciofrom collections.abc import Awaitable, Callablefrom typing import TypeVar
from nextpdf import NextPDFAPIError, QuotaExceededError
_RETRYABLE_STATUS = frozenset({500, 502, 503, 504})
_T = TypeVar("_T")
async def with_retry( coro_factory: Callable[[], Awaitable[_T]], *, max_attempts: int = 4,) -> _T: """Call coro_factory() with bounded retries on transient server errors.
Args: coro_factory: A zero-argument callable returning a fresh awaitable. max_attempts: Maximum number of attempts before giving up.
Returns: The awaited result of the first successful attempt.
Raises: NextPDFAPIError: When all attempts fail or the error is not retryable. """ delay = 1.0 for attempt in range(1, max_attempts + 1): try: return await coro_factory() except QuotaExceededError as exc: if attempt == max_attempts: raise await asyncio.sleep(exc.retry_after if exc.retry_after is not None else delay) delay *= 2.0 except NextPDFAPIError as exc: if attempt == max_attempts or exc.status_code not in _RETRYABLE_STATUS: raise await asyncio.sleep(delay) delay *= 2.0 raise RuntimeError("unreachable")Kotaları, hız sınırlarını ve zaman aşımlarını yönetin
“Kotaları, hız sınırlarını ve zaman aşımlarını yönetin” başlıklı bölümKota ve hız sınırı uygulaması sunucuda gerçekleşir. HTTP 429 durumunda SDK QuotaExceededError oluşturur ve Retry-After üst bilgisini retry_after değerine ayrıştırır. Uzak arka uç, işleme yanıtlarında X-RateLimit-* üst bilgilerini de sunar; böylece kesin bir sınıra ulaşmadan önce önleyici hız kısıtlaması yapabilirsiniz.
İstek zaman aşımları için, 10 saniyelik bağlanma zaman aşımıyla birlikte toplam 60 saniyelik sabit bir varsayılan kullanılır (httpx.Timeout(60.0, connect=10.0)). Uzun AST derlemelerini sınırlarken yalnızca zaman aşımına güvenmek yerine işi page_range_start, page_range_end ya da token_budget ile daraltın; aşırı uzun bir derleme AstBuildTimeoutError (HTTP 504) döndürür.
Örnek mimariler
“Örnek mimariler” başlıklı bölümToplu iş
“Toplu iş” başlıklı bölümBir toplu iş çalışanı PDF’leri okur, alıntılanan metni ayıklar ve yapılandırılmış çıktı yazar. Havuzlanmış tek bir istemciyi yeniden kullanın, eşzamanlılığı bir semaforla sınırlayın ve yukarıdaki yeniden deneme yardımcısını uygulayın.
"""Batch-extract a directory of PDFs over one pooled async client."""
import asyncioimport osfrom pathlib import Path
from nextpdf import AsyncNextPDF
async def run_batch(input_dir: Path, concurrency: int = 8) -> None: """Extract cited text for every PDF in input_dir, bounded by concurrency.""" semaphore = asyncio.Semaphore(concurrency)
async def worker(client: AsyncNextPDF, path: Path) -> None: async with semaphore: blocks = await client.ast.extract_cited_text(path.read_bytes()) out = path.with_suffix(".txt") out.write_text("\n".join(b.text for b in blocks), encoding="utf-8")
async with AsyncNextPDF( base_url=os.environ["NEXTPDF_BASE_URL"], api_key=os.environ["NEXTPDF_API_KEY"], ) as client: await asyncio.gather(*(worker(client, p) for p in input_dir.glob("*.pdf")))Web hizmeti
“Web hizmeti” başlıklı bölümBir FastAPI hizmeti, uygulama yaşam süresi boyunca istekler arasında tek bir AsyncNextPDF örneğini paylaşır; böylece her istek bağlantı havuzunu yeniden kullanır. Kimlik bilgilerini ortamdan okuyun ve API anahtarını gizli bilgi olarak ele alın.
"""FastAPI service that shares one pooled NextPDF client across requests."""
import osfrom contextlib import asynccontextmanager
from fastapi import FastAPI, UploadFile
from nextpdf import AsyncNextPDF
@asynccontextmanagerasync def lifespan(app: FastAPI): """Create the pooled client on startup and close it on shutdown.""" app.state.client = AsyncNextPDF( base_url=os.environ["NEXTPDF_BASE_URL"], api_key=os.environ["NEXTPDF_API_KEY"], ) try: yield finally: await app.state.client.close()
app = FastAPI(lifespan=lifespan)
@app.post("/extract")async def extract(file: UploadFile) -> dict[str, list[str]]: """Return cited text blocks for an uploaded PDF.""" pdf_bytes = await file.read() blocks = await app.state.client.ast.extract_cited_text(pdf_bytes) return {"text": [block.text for block in blocks]}Aracıya yönelik araç
“Aracıya yönelik araç” başlıklı bölümAI aracıları için MCP sunucusunu çalıştırın. Standart girdi ve çıktı üzerinden PDF araçlarını (örneğin nextpdf_extract_text, nextpdf_extract_tables, nextpdf_get_ast, nextpdf_info, nextpdf_search, nextpdf_get_outline, nextpdf_diff ve nextpdf_health) sunar. Sunucu, NEXTPDF_BASE_URL ve NEXTPDF_API_KEY değerlerini ortamdan okur; bu nedenle uzak arka uçla çalışır ve CLI gibi yerel arka ucu kullanamaz. İsteğe bağlı ek paketi yükleyin ve modülü çalıştırın.
pip install "nextpdf[mcp]"python -m nextpdf.mcpAracı tümleştirmesine yönelik adım adım kılavuz için Python MCP sunucusu, uçbirim kullanımı için Python CLI ve tam istemci, model ve özel durum yüzeyi için Python API başvurusu bölümlerine bakın.