Skip to main content

Aletheca: Asynchronous Python client for the OpenAlex API

Samuel Mok -- s.mok@utwente.nl -- 2025-2026

Aletheca is an async Python client for the OpenAlex API, built on bibliofabric.

Docs: utsmok.github.io/aletheca -- PyPI: aletheca -- License: MIT

Features

  • Async by design -- built on httpx + asyncio with proper connection pooling
  • Typed throughout -- Pydantic v2 models for all entities, PEP 561 py.typed marker
  • Cursor pagination -- efficient iteration over large result sets via cursor-based auto-pagination
  • Filter serialization -- automatic conversion to OpenAlex filter=key:value syntax with Pydantic filter models
  • Safe types -- SafeList and SafeStr for None-safe traversal of API responses
  • Convenience queries -- high-level functions for common workflows (works_by_author, citing_works, etc.)

Installation

uv add aletheca

Or with pip: pip install aletheca. Requires Python >=3.12.

Quick Start

import asyncio
from aletheca import AlethecaSession

async def main():
    async with AlethecaSession() as session:
        # Get a work by OpenAlex ID
        work = await session.works.get("W1234567890")
        print(work.title)

        # Search works
        results = await session.works.search(search="machine learning", page_size=10)
        for work in results.results:
            print(f"{work.title} ({work.publication_year})")

        # Iterate all works by an author (cursor-based auto-pagination)
        async for work in session.works.iterate(
            filters={"authorships.author.id": "A1234567890"},
            page_size=100,
        ):
            print(work.title)

asyncio.run(main())

No authentication required -- the OpenAlex API works without it. For higher rate limits, see Authentication.

Examples

All examples in examples/ are dual-purpose -- run as scripts or as interactive marimo notebooks:

# As a script
uv run examples/simple_example.py

# As an interactive notebook
uv run marimo edit examples/simple_example.py
Script Description
simple_example.py Search, iterate, get works
02_filtering_and_search.py WorksFilters, AuthorsFilters, and other filter models
03_institution_research.py Works by institution, topic analysis
04_author_discovery.py Find authors, retrieve their works
05_advanced_queries.py Cursor pagination, select fields, sort
06_convenience_queries.py session.queries.* convenience functions
07_iterator_helpers.py collect(), count(), first() from bibliofabric mixins
08_safe_types_and_helpers.py SafeList, SafeStr, DOI normalization, abstract reconstruction

See examples/README.md for details on running examples as interactive marimo notebooks.

Authentication

Aletheca auto-detects the OpenAlex API key from environment variables or .env files (prefixed with ALETHECA_). No auth is the default if nothing is configured.

ALETHECA_OPENALEX_API_KEY=your_api_key

Or pass explicitly:

async with AlethecaSession(api_key="your_api_key") as session:
    ...

With an API key you get faster responses (dedicated pool). Without one, you use the polite pool (slower).

→ Full guide: Authentication

Basic Usage

Get a single entity

work = await session.works.get("W2741809801")
print(work.title, work.doi, work.publication_year)
results = await session.works.search(search="machine learning", page_size=5)
for work in results.results:
    print(work.title)

Iterate all results

async for work in session.works.iterate(
    filters={"publication_year": 2024, "is_oa": True},
    page_size=100,
):
    print(work.title)
    break  # stop when you want

Convenience queries

citations = await session.queries.citing_works("W2741809801")
print(f"{len(citations)} citations")

→ Full guide: Usage Basics · Works · All Entities

Known OpenAlex API Issues

Full bug report with reproduction steps: OPENALEX_BUG_REPORT.md.

  • OpenAPI spec is substantially incomplete -- 50+ fields returned by the live API are missing from the spec schemas across all entity types. Several spec fields don't exist in the live API.
  • Wrong field names in spec -- content_url (spec) vs content_urls (live), grants_count (spec) vs awards_count (live)
  • Undocumented fields -- institution_awarded on Awards is not documented anywhere; 15+ nested Award filters are missing from the docs filter table
  • Awards endpoint missing from llms.txt -- the awards endpoint is not listed in the API quick reference
  • per_page max is 100 -- 200 still works but is deprecated legacy behavior, slated for removal (OpenAlex docs, 2026-08); all examples here use 100
  • Keyword IDs are slug paths, not short IDs -- live keyword records carry ids like https://openalex.org/keywords/photosynthesis, and the single-record route rejects that full-URL form (nested slashes → HTML 404) even though /works/https://openalex.org/W… is accepted. get() normalizes both forms.
  • Awards 400 body is the authoritative filter list -- the awards endpoint rejects several filters its docs summaries suggest (funder.country_code, plain display_name, lead_investigator.id, from_/to_*_date) and its 400 error body enumerates all 40 valid filters, which is more complete than any docs table.

Development

uv sync --all-groups --all-extras         # install everything
uv run ruff check src/ --fix              # lint
uv run ruff format src/                   # format
uvx ty check src/                         # type check
uv run pytest tests/                      # run tests
uv run pytest --cov=aletheca tests/       # coverage (CI threshold: 95%)
uv build                                  # build package
uv run mkdocs serve                       # local docs

Contributions welcome -- see Contributing.

License

MIT

Metadata

Release files for aletheca 0.2.2

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

Source distribution (sdist)

Source distribution for aletheca 0.2.2
File Size Uploaded Provenance Actions
aletheca-0.2.2.tar.gz 22.1 kB Without provenance Details for aletheca-0.2.2.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for aletheca 0.2.2
File Interpreter ABI Platform Actions
aletheca-0.2.2-py3-none-any.whl Python 3 none any Details for aletheca-0.2.2-py3-none-any.whl

Total release size: 57.4 kB

Release files / aletheca-0.2.2.tar.gz

Download URL aletheca-0.2.2.tar.gz
Size 22.1 kB
Tags Source
SHA-256 checksum
How to use checksums
4c233e89735dfd714c4c86e667dc4ac0c0282d50ab77e9fc5b568e87f132ba8d
BLAKE2b-256 checksum
How to use checksums
80121ed0fc1099a232535e3a27154d4e746caf0abb623ae4f9aa6ebc359c9ec3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.10 {"installer":{"name":"uv","version":"0.12.10","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / aletheca-0.2.2-py3-none-any.whl

Download URL aletheca-0.2.2-py3-none-any.whl
Size 35.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
93d28235f6d177aae96b2bd689d90da57b0a01792ca6e3577baaebea04c6d00d
BLAKE2b-256 checksum
How to use checksums
605747fdb987e3b33b410934a73653116b4d2b8eab639f07d0e7915948a6832a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.12.10 {"installer":{"name":"uv","version":"0.12.10","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for aletheca 0.2.2

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

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