adsfolio.pdf.identifier

PDF-to-ADS record identification utilities.

class adsfolio.pdf.identifier.AdsQueryResult(num_found, documents)[source]

Bases: object

Documents returned by one ADS query, including the total match count.

Parameters:
documents: tuple[dict[str, Any], ...]
num_found: int
class adsfolio.pdf.identifier.PdfIdentifier(client=None, logger=None, suppress_parser_warnings=True)[source]

Bases: object

Resolve ADS metadata for local PDF files.

Parameters:
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:
Parameters:
Return type:

dict[str, Any]

compute_sha256(pdf_path)[source]

Compute SHA-256 for duplicate detection.

Parameters:

pdf_path (pathlib.Path)

Return type:

str

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_filename(filename)[source]

Return the sole exact bibcode in the filename.

Parameters:

filename (str)

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_bibcode_from_text(text)[source]

Extract likely ADS bibcode token from text.

Parameters:

text (str)

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:

tuple[str | None, str | None]

extract_doi_from_filename(filename)[source]

Extract DOI-like token from filename variants.

Parameters:

filename (str)

Return type:

str | None

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:

tuple[str, …]

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.

Parameters:
Return type:

dict[str, str]

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:

bool

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.

Parameters:
Return type:

dict[str, dict[str, Any] | None]

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:

dict[str, dict[str, Any] | None]

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.

Parameters:
Return type:

dict[str, dict[str, Any] | None]

query_documents(query, ads_documents_callback=None)[source]

Return one ADS result page and its total match count.

Parameters:
Return type:

adsfolio.pdf.identifier.AdsQueryResult

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:
Return type:

dict[str, Any] | None

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:
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:
Return type:

tuple[str | None, str | None]

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:
Return type:

str

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 provider key, 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.