python3-openid
OpenID 2.0 authentication library for Python 3, with relying-party (consumer) and identity-provider (server) support.
Repository Health
Technical Analysis
python3-openid is a Python 3 port of the original python-openid library, giving applications a complete implementation of the OpenID 2.0 decentralized identity protocol. It ships both sides of the handshake: an openid.consumer package for sites that want to let users sign in with an OpenID, and an openid.server package for sites that want to run their own OpenID provider.
Beyond the core protocol, the library bundles support for Yadis discovery, the Simple Registration (SREG) and Attribute Exchange (AX) extensions, and pluggable persistence via file, in-memory, MySQL, or PostgreSQL stores — so teams can drop it into an existing web stack (the repo includes a Django example app) without writing their own association and nonce storage from scratch.
What You Get
- Consumer library -
openid.consumer.consumer.Consumerdrives the begin/complete authentication flow for relying-party sites that let users log in with an OpenID. - Server library -
openid.server.server.Serverimplements the provider side, handling checkid requests, association, and signed responses for sites running their own OpenID identity provider. - Pluggable stores -
openid.storeships file, in-memory, MySQL, and PostgreSQL backends implementing a commonOpenIDStoreinterface for associations and nonces. - Discovery and extensions - built-in Yadis-based service discovery plus Simple Registration (SREG), Attribute Exchange (AX), and Provider Authentication Policy Extension (PAPE) support.
- Reference examples - the
examples/directory includes runnable consumer and server scripts, plus a Django-based OpenID provider/consumer app (djopenid).
Common Use Cases
- Add OpenID login to a site - a web app integrates
openid.consumer.consumer.Consumerto let visitors authenticate with an existing OpenID identity instead of creating a new account. - Run a self-hosted OpenID provider - a team stands up its own identity provider using
openid.server.server.Server, issuing and verifying OpenID assertions for relying-party sites. - Persist association state across requests - a deployment picks a
storebackend (file, memory, MySQL, or PostgreSQL) to hold OpenID associations and nonces between the begin and complete steps of the handshake. - Pull profile data via SREG/AX - a relying party requests basic profile fields (email, nickname) through the Simple Registration or Attribute Exchange extensions during authentication.
Under The Hood
Architecture
The library is organized around the two roles defined by the OpenID spec: openid.consumer.consumer.Consumer drives the relying-party flow (begin() for discovery/redirect, complete() for verifying the provider’s response), while openid.server.server.Server handles the provider side of the same handshake. Both depend on a common openid.store.interface.OpenIDStore abstraction — implemented by filestore.py, memstore.py, and sqlstore.py — that persists associations and nonces between the two HTTP requests a full OpenID exchange requires; swapping the store is the main extension point, and the Django example in examples/djopenid shows how a host application wires the library’s stateless core into a real request/response cycle.
Tech Stack
Pure Python 3 (3.5+ per CI, tested through 3.13 and PyPy3) with almost no hard runtime dependency beyond defusedxml for safe XML parsing; MySQL and PostgreSQL store support is opt-in via the mysql/postgresql extras (mysql-connector-python, psycopg2). Packaging uses classic setuptools/setup.py, and the GitHub Actions workflow runs the test suite against a matrix of CPython and PyPy versions with live MySQL and Postgres service containers for the store backends.
Code Quality
The openid/test/ directory contains an extensive unittest-based suite (dozens of files covering message parsing, discovery, association, extensions, and both consumer and server flows), run via coverage run -m unittest openid.test.test_suite in CI with coverage reported to Coveralls. Modules carry Epydoc-style docstrings describing parameters and behavior in detail, and error handling favors explicit exceptions (e.g. DiscoveryFailure, ProtocolError) over silent failure. There is no type-checker or static linter wired into CI, and the codebase predates modern type hints.
What Makes It Unique Rather than being a thin OAuth/OIDC wrapper, this is a from-scratch implementation of the older OpenID 2.0 decentralized-identity protocol, including the lower-level plumbing (Diffie-Hellman association negotiation, XRDS/Yadis discovery, nonce handling) that most modern auth libraries no longer need to expose. That completeness is also its niche: OpenID 2.0 has been largely superseded by OpenID Connect, so the library’s value today is chiefly for maintaining legacy relying parties and providers still speaking the older protocol.