Skip to main content

Extra citations support for FLM

See the FLM README file.

Install with:

$ pip install flm-citations

Use the additional config front matter in your FLM files to enable citations with automatic citation retrieval from arXiv, DOI, etc.

---
$import:
  -  pkg:flm_citations
bibliography:
  - my-csl-bibliography.yaml
---

Then process your file as usual with flm.

The bibliography file(s) you provide (in the example above, my-csl-bibliography.yaml) should be in CSL JSON or CSL YAML format. They can easily be exported from Zotero, for example.

With the default configuration, the following citation keys are processed:

  • \cite{arXiv:XXXX.YYYYY} - fetch citation information from the arXiv, and from its corresponding DOI if applicable.
  • \cite{doi:XXX} - fetch citation information using its DOI
  • \cite{manual:{X et al., Journal of Future Results (2034)}} - manual citation text
  • \cite{bib:BibKey2023} - use a citation from any of your bibliography files specified in your document front matter.

Configuration

All options go under flm.features.flm_citations in your config or front matter.

Option
sources which citation sources to enable, and under which prefixes — see below
bib_csl_style path to a CSL style file for rendering entries
cache_dir, cache_base where the citation cache lives (default: next to the document, base .flm-citations)
on_citation_error fatal (default) aborts the build on an unresolvable citation; warn logs it and renders a visible placeholder
user_agent User-Agent sent with every request; arXiv and doi.org throttle harder when they cannot tell who is calling, and adding a contact address is customary
drop_csl_fields top-level CSL fields stripped before caching (default abstract, reference — doi.org returns the cited paper's entire bibliography under reference)
manual_format markup name manual: citation text is stored under (default flm). Setting it to anything else declares that those keys are not FLM, so they render verbatim rather than as markup
ttl_policy, retry, max_chain_depth cache-expiry and retry/backoff tuning
prune_cache drop cache entries expired past the grace window after each run (default off)
write_csljson_file, write_bibtex_file export the document's citations
on_event a callable receiving one dict per retrieval event (passes, per-source progress, requests, waits) — for driving a progress display. Not settable from YAML, since it takes a function

Progress is otherwise reported through the flm_citations.retrieve logger: at INFO you get passes and per-source counters, at DEBUG every HTTP request and resolved citation. Nothing is reported, and no reporter is even attached, when that logger is quieter than INFO.

Each entry of sources is {name: …, config: {…}}. A source's cite_prefix chooses the citation prefix it answers to, so the same kind of source can be registered more than once — for instance a second bibliography over different files:

flm:
  features:
    flm_citations:
      sources:
        - $defaults:
        - $merge-config:
            name: 'bibliographyfile'
            config:
              cite_prefix: b
              bibliography_file:
                - my-other-bibliography.yaml

Refresh batching

Cached entries expire (arXiv after 10 days, DOIs after 360), and refreshing a handful of them costs as much rate-limited time as refreshing many. So by default a source waits until enough entries are stale to be worth a request — arXiv 20, doi.org 10 — and tops a request that is going out anyway up with entries that are nearly due. Missing citations are always fetched straight away, and a stale entry is served from the cache while it waits (at most 2 days past expiry for arXiv, 30 for DOIs). A bibliography file is re-read in full whenever any of its entries is refreshed.

A source's refresh_batching option adjusts this:

sources:
  - name: arxiv
    config:
      refresh_batching:
        min_batch: 50          # wait for 50 stale entries...
        max_defer_days: 7      # ...but never more than a week past expiry
        top_up:
          min_age_percent: 50  # fill requests with entries half-way through their lifetime
          fill: chunk          # up to the request's capacity (or a count, e.g. 5)
  - name: doi
    config:
      refresh_batching: eager  # refetch whatever is due, as soon as it is due

Settings not given keep the source's default; eager: true inside the mapping starts from eager instead, and top_up: false never pulls entries forward.

The citation cache

Resolved citations are cached in .flm-citations.jsonl next to your document: one sorted entry per line, so a diff stays readable. Commit it if you want builds to be reproducible offline. A run also creates a few throwaway lock and log files while it is in flight; they all carry a ._ prefix and delete themselves, so one ignore rule covers them:

._.flm-citations*

Manual citation text is never written to the cache at all, so arbitrary \cite{manual:…} text cannot leak into a committed file.

Metadata Fetching

Thank you to arXiv and doi.org for use of their open access interoperability.

Since version 0.3, retrieval is handled by autocitefetch, a Rust library shipped as a compiled extension module. It brings automatic retry with backoff, correct rate limiting, stale-while-revalidate caching, and per-citation error tolerance. This package keeps the FLM integration and the citeproc-py rendering.

In case citeproc chokes on certain entries fetched by DOI

Sometimes automatically generated citeproc/JSON entries fetched through various available online APIs (doi.org, crossref.org, arXiv.org, etc.) might not be fully conforming or exactly matching the structure expected by the citeproc-py citation formatting library that this project uses. If you run against such issues, you might consider installing a patched version of the library that smoothed out some issues I had in the past; you can install it with

> pip install git+https://github.com/phfaist/citeproc-py.git@pr-branch

until my upstream PR is considered.

Note that citeproc-py needs issued in the {"date-parts": [[2022, 8, 12]]} form; the [{year: 2022, month: 8}] shape some CSL-YAML exporters produce is not accepted.

Upgrading from 0.2

Existing configurations keep working, with two exceptions and a few deprecations that are reported when they are used:

  • Custom Python citation source classes are gone. A sources entry naming an importable class (name: 'my.module.MyClass') is now an error; retrieval happens in the Rust library, which has no Python source interface.
  • cache_file is replaced by cache_dir + cache_base. The cache is no longer a single JSON file. The old .flm-citations.cache.json is not read and can be deleted.
  • cache_entry_duration_dt is ignored. Cache lifetimes are now per source (arXiv 10 days, DOI 360 days, bibliography files 60 s, manual entries not cached); only a bibliography source's lifetime is configurable, via ttl_seconds.
  • chunk_size and chunk_query_delay_ms are ignored. Chunk sizes and request pacing are properties of each remote API and are fixed by the library.

Two output differences are worth knowing about:

  • An arXiv entry's date is now its last revision (<updated>) rather than its original submission, so a paper's citation year may change.
  • write_csljson_file / write_bibtex_file now export exactly the citations the document uses, rather than everything that happened to be in the cache.

Development

pip install maturin
maturin develop            # build the extension into the current virtualenv
cargo test                 # Rust unit tests
pytest -m 'not network'    # Python tests, offline
pytest -m network          # live arXiv/doi.org checks (slow, rate-limited)

The Rust half depends on autocitefetch, pulled as a git dependency over anonymous https; no credentials are needed to build.

License

MIT

Metadata

Release files for flm-citations 0.3.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for flm-citations 0.3.1
File Size Uploaded Provenance Actions
flm_citations-0.3.1.tar.gz 72.2 kB With provenance Details for flm_citations-0.3.1.tar.gz

Built distributions (wheels)

Table of built distributions (wheels) for flm-citations 0.3.1
File Actions
flm_citations-0.3.1-cp39-abi3-win_amd64.whl CPython 3.9 abi3 Windows x86-64 Details for flm_citations-0.3.1-cp39-abi3-win_amd64.whl
flm_citations-0.3.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.9 abi3 Linux glibc 2.17+ x86-64 Details for flm_citations-0.3.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
flm_citations-0.3.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl CPython 3.9 abi3 Linux glibc 2.17+ ARM64 Details for flm_citations-0.3.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
flm_citations-0.3.1-cp39-abi3-macosx_11_0_arm64.whl CPython 3.9 abi3 macOS 11.0+ ARM64 Details for flm_citations-0.3.1-cp39-abi3-macosx_11_0_arm64.whl
flm_citations-0.3.1-cp39-abi3-macosx_10_12_x86_64.whl CPython 3.9 abi3 macOS 10.12+ x86-64 Details for flm_citations-0.3.1-cp39-abi3-macosx_10_12_x86_64.whl

Total release size: 6.8 MB

Release files / flm_citations-0.3.1.tar.gz

Download URL flm_citations-0.3.1.tar.gz
Size 72.2 kB
Tags Source
SHA-256 checksum
How to use checksums
0737761d10ca18d9a912b864eb8bbe09c12223fdc6cf798c31b6dde5a18b9fee
BLAKE2b-256 checksum
How to use checksums
c936b2622b17216eb60904fb2e69bae2b93719242182c74930b6fb18abedbf45
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.

Transparency log

Release files / flm_citations-0.3.1-cp39-abi3-win_amd64.whl

Download URL flm_citations-0.3.1-cp39-abi3-win_amd64.whl
Size 1.2 MB
Tags CPython 3.9 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
7b5cd49b42d99d83274cb805bfade951d19072b4369fe5dda95fc97183a7d922
BLAKE2b-256 checksum
How to use checksums
1c1dfbe69b7159930bcb74ec0e79d8de71991f4fe3c40e5732b934e36e843dc8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.

Transparency log

Release files / flm_citations-0.3.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL flm_citations-0.3.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 1.4 MB
Tags CPython 3.9 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
4a553e563f76c59e61cfd189e56b3f53783a679da8f7eef67b147bca43bf4e29
BLAKE2b-256 checksum
How to use checksums
f6917da16966f7811b4b6b7b802949c98baf01691fbb492279e0ec88b8a79dc8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.

Transparency log

Release files / flm_citations-0.3.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

Download URL flm_citations-0.3.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
Size 1.4 MB
Tags CPython 3.9 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
ab3f4226d6fc559e812488949178137730691d14b11f14eb717d39a7f2f609b6
BLAKE2b-256 checksum
How to use checksums
04a5edf2640b03f31c8ef843ed9580e5f4477e014489a3f6077d1e65deee372b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.

Transparency log

Release files / flm_citations-0.3.1-cp39-abi3-macosx_11_0_arm64.whl

Download URL flm_citations-0.3.1-cp39-abi3-macosx_11_0_arm64.whl
Size 1.3 MB
Tags CPython 3.9 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
b634e9e4e0b87223efcde63e1ea12ccb0ec7b4f96498c2ff93ba426cabdb5ec5
BLAKE2b-256 checksum
How to use checksums
909468723e490af7ebbf903b17e0956669fc09104b7b9a8f5654ecfb56b217e9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.

Transparency log

Release files / flm_citations-0.3.1-cp39-abi3-macosx_10_12_x86_64.whl

Download URL flm_citations-0.3.1-cp39-abi3-macosx_10_12_x86_64.whl
Size 1.4 MB
Tags CPython 3.9 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
e8a1782adfc80a4fc613ec9e0d110b6a93ac7d7b92de37981480c3d8108e31b1
BLAKE2b-256 checksum
How to use checksums
80bb554a69a2cfa8f013a977b1b8cf6a0f60ebe5a9887560ea91a5e053edc226
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.

Transparency log

Security for flm-citations 0.3.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 6 files in this release have been uploaded with provenance metadata.

Select from 6 files

Attestation for flm_citations-0.3.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page