adsfolio.pdf.identifier
PDF-to-ADS record identification utilities.
- class adsfolio.pdf.identifier.AdsQueryResult(num_found, documents)[source]
Bases:
objectDocuments returned by one ADS query, including the total match count.
- class adsfolio.pdf.identifier.PdfIdentifier(client=None, logger=None, suppress_parser_warnings=True)[source]
Bases:
objectResolve ADS metadata for local PDF files.
- Parameters:
client (ADSClient | None)
logger (logging.Logger | None)
suppress_parser_warnings (bool)
- MAX_ANALYSIS_WORKERS = 24
- MAX_BATCH_TERMS = 50
- SEARCH_FIELDS: ClassVar[list[str]] = ['abstract', 'bibcode', 'identifier', 'alternate_bibcode', 'citation_count', 'doi', 'title', 'author', 'author_count', 'year', 'bibstem', 'volume', 'page', 'pub']
- build_record(doc, pdf_path, sha256=None, *, manual_confirmation=False, manual_conflict_override=False, filename_bibcode=None, allow_filename_association=False)[source]
Build a library record, after checking the PDF is the paper in doc.
- Raises:
IdentityConflictError – The PDF’s own identifiers contradict doc.
UnverifiedIdentityError – The PDF does not confirm doc and manual_confirmation is false.
- Parameters:
doc (collections.abc.Mapping[str, Any])
pdf_path (pathlib.Path)
sha256 (str | None)
manual_confirmation (bool)
manual_conflict_override (bool)
filename_bibcode (str | None)
allow_filename_association (bool)
- Return type:
- compute_sha256(pdf_path)[source]
Compute SHA-256 for duplicate detection.
- Parameters:
pdf_path (pathlib.Path)
- Return type:
- extract_arxiv_from_first_page(pdf_path)[source]
Return the PDF’s own arXiv identifier if it states exactly one.
- Parameters:
pdf_path (pathlib.Path)
- Return type:
str | None
- extract_bibcode_from_first_page(pdf_path)[source]
Find a bibcode in first-page PDF text.
- Parameters:
pdf_path (pathlib.Path)
- Return type:
str | None
- extract_bibcode_from_metadata(pdf_path)[source]
Extract bibcode-like token from PDF metadata fields.
- Parameters:
pdf_path (pathlib.Path)
- Return type:
str | None
- extract_bibcode_from_pdf(pdf_path)[source]
Find a bibcode in searchable PDF text before requiring OCR.
- Parameters:
pdf_path (pathlib.Path)
- Return type:
str | None
- extract_doi_candidates(pdf_path)[source]
Extract DOI candidates in one parse pass.
Returns
(metadata_doi, text_doi)where text DOI is only populated when metadata DOI is missing.- Parameters:
pdf_path (pathlib.Path)
- Return type:
- extract_doi_from_metadata(pdf_path)[source]
Extract DOI from PDF metadata first, then metadata free text.
- Parameters:
pdf_path (pathlib.Path)
- Return type:
str | None
- extract_doi_from_text(pdf_path)[source]
Extract DOI from first-page text.
- Parameters:
pdf_path (pathlib.Path)
- Return type:
str | None
- extract_preferred_bibcode(pdf_path)[source]
Extract one Bibcode candidate in filename/metadata/first-page order.
- Parameters:
pdf_path (pathlib.Path)
- Return type:
str | None
- extract_title_candidates(pdf_path)[source]
Extract first-page heading blocks for exact ADS title verification.
Text larger than the character-weighted modal font size supplies candidates. This assumes the dominant size is body text. Font sizes include the PDF text and page transforms. Uniform-size OCR falls back to the text-boundary extractor; neither method proves a title’s identity.
- Parameters:
pdf_path (pathlib.Path)
- Return type:
- extract_title_from_metadata(pdf_path)[source]
Extract title from metadata fields.
- Parameters:
pdf_path (pathlib.Path)
- Return type:
str | None
- extract_title_from_text(pdf_path)[source]
Heuristically infer paper title from the first page.
- Parameters:
pdf_path (pathlib.Path)
- Return type:
str | None
- identity_failures: dict[pathlib.Path, adsfolio.pdf.identity.IdentityValidationError]
- parse_filename(filename, journal_map=None)[source]
Extract author/year/journal/volume/page hints from filename.
- pdf_is_readable(pdf_path)[source]
Return whether a PDF can be parsed and contains at least one page.
An encrypted PDF is readable when its user password is empty. Many journal PDFs set only an owner password, which limits printing or copying but needs no password to open.
- Parameters:
pdf_path (pathlib.Path)
- Return type:
- query_docs_for_arxiv_ids(arxiv_ids, ads_documents_callback=None)[source]
Resolve arXiv identifiers through ADS
identifier:"arXiv:ID".An identifier maps to a document only if exactly one returned document carries that arXiv identifier among its own aliases.
- query_docs_for_bibcodes(bibcodes, progress_callback=None, ads_documents_callback=None)[source]
Resolve current and former bibcodes using batched ADS queries.
- Parameters:
bibcodes (list[str]) – Bibcodes to look up. The lookup ignores case when it removes duplicates.
progress_callback (collections.abc.Callable[[int, int], None] | None) – Optional callback for the number of completed query batches.
ads_documents_callback (collections.abc.Callable[[list[dict[str, Any]]], None] | None) – Optional callback for each complete batch of ADS documents.
- Returns:
Each requested bibcode maps to its unique ADS document, or None when no document or more than one document claims it.
- Return type:
Notes
ADS must list a bibcode as a primary or alternate identifier. An arXiv bibcode can also match a complete arXiv identifier for the same eprint.
- query_docs_for_dois(dois, progress_callback=None, ads_documents_callback=None)[source]
Resolve DOI candidates using batched ADS queries.
Returns normalized DOI -> unique matching doc, or None when ambiguous/missing.
- query_documents(query, ads_documents_callback=None)[source]
Return one ADS result page and its total match count.
- Parameters:
- Return type:
- resolve(pdf_path, journal_map=None, ads_documents_callback=None, cached_candidate_lookup=None, allow_network_lookup=True, *, strategies=(IdentifyStrategy.FIRST_PAGE_ARXIV, IdentifyStrategy.FILENAME_BIBCODE, IdentifyStrategy.FILENAME_DOI, IdentifyStrategy.PDF_METADATA_BIBCODE, IdentifyStrategy.PDF_METADATA_DOI, IdentifyStrategy.FIRST_PAGE_BIBCODE, IdentifyStrategy.FIRST_PAGE_DOI, IdentifyStrategy.STRUCTURED_FILENAME, IdentifyStrategy.PDF_METADATA_TITLE, IdentifyStrategy.FIRST_PAGE_TITLE), providers=(DoiProvider.ADS, DoiProvider.CROSSREF, DoiProvider.DATACITE), allow_external_network_lookup=None)[source]
Resolve one PDF with the canonical ordered strategy engine.
By default, allow_network_lookup also controls DOI provider requests. Set allow_external_network_lookup to control those requests separately.
- Parameters:
pdf_path (pathlib.Path)
journal_map (collections.abc.Mapping[str, Any] | None)
ads_documents_callback (collections.abc.Callable[[list[dict[str, Any]]], None] | None)
cached_candidate_lookup (collections.abc.Callable[[str, Any], tuple[bool, dict[str, Any] | None]] | None)
allow_network_lookup (bool)
strategies (tuple[adsfolio.pdf.identify_settings.IdentifyStrategy, ...])
providers (tuple[adsfolio.pdf.doi_providers.DoiProvider, ...])
allow_external_network_lookup (bool | None)
- Return type:
- resolve_many(pdf_paths, journal_map=None, sha256_by_path=None, progress_callback=None, ads_documents_callback=None, cached_candidate_lookup=None, allow_network_lookup=True, *, strategies=(IdentifyStrategy.FIRST_PAGE_ARXIV, IdentifyStrategy.FILENAME_BIBCODE, IdentifyStrategy.FILENAME_DOI, IdentifyStrategy.PDF_METADATA_BIBCODE, IdentifyStrategy.PDF_METADATA_DOI, IdentifyStrategy.FIRST_PAGE_BIBCODE, IdentifyStrategy.FIRST_PAGE_DOI, IdentifyStrategy.STRUCTURED_FILENAME, IdentifyStrategy.PDF_METADATA_TITLE, IdentifyStrategy.FIRST_PAGE_TITLE), providers=(DoiProvider.ADS, DoiProvider.CROSSREF, DoiProvider.DATACITE), allow_external_network_lookup=None)[source]
Resolve PDFs in configured stage order while batching equal lookups.
By default, allow_network_lookup also controls DOI provider requests. Set allow_external_network_lookup to control those requests separately.
- Parameters:
pdf_paths (list[pathlib.Path])
journal_map (collections.abc.Mapping[str, Any] | None)
sha256_by_path (collections.abc.Mapping[pathlib.Path, str] | None)
progress_callback (collections.abc.Callable[[str, int, int], None] | None)
ads_documents_callback (collections.abc.Callable[[list[dict[str, Any]]], None] | None)
cached_candidate_lookup (collections.abc.Callable[[str, Any], tuple[bool, dict[str, Any] | None]] | None)
allow_network_lookup (bool)
strategies (tuple[adsfolio.pdf.identify_settings.IdentifyStrategy, ...])
providers (tuple[adsfolio.pdf.doi_providers.DoiProvider, ...])
allow_external_network_lookup (bool | None)
- Return type:
dict[pathlib.Path, dict[str, Any] | None]
- adsfolio.pdf.identifier.extract_doi_candidates_pdf(pdf_path, suppress_parser_warnings=True)[source]
Extract DOI candidates directly from a PDF path in a single parser pass.
Returns
(metadata_doi, text_doi)where text DOI is only attempted when metadata DOI is missing.- Parameters:
pdf_path (pathlib.Path)
suppress_parser_warnings (bool)
- Return type:
- adsfolio.pdf.identifier.extract_first_page_text_pdf(pdf_path, suppress_parser_warnings=True, max_chars=1200)[source]
Extract first-page text preview from PDF and normalize whitespace.
- Parameters:
pdf_path (pathlib.Path)
suppress_parser_warnings (bool)
max_chars (int)
- Return type:
- adsfolio.pdf.identifier.fetch_external_identifier(kind, value, providers)[source]
Look up a DOI or arXiv ID outside ADS, in the given provider order.
An arXiv ID is looked up through its DataCite DOI,
10.48550/arXiv.<id>. ADS entries in providers are skipped. A provider error moves on to the next provider.- Parameters:
kind (str) –
"doi"or"arxiv".value (str) – The DOI, or the arXiv ID without its version.
providers (iterable of DoiProvider) – Provider order, usually the saved Identify setting.
- Returns:
Document metadata with a
providerkey, or None when no provider knows the identifier.- Return type:
dict or None
- Raises:
ProviderError or ValueError – Lookup failed and no later provider returned metadata. A failed request does not establish that the identifier is missing.