PyOTP is a Python library for generating and verifying one-time passwords, implementing HOTP (RFC 4226) and TOTP (RFC 6238) for 2FA or MFA in web applications and other systems. It is useful for server-side OTP support, including generating provisioning URIs for OTP authenticator apps (and parsing those URIs) so users can set up credentials by scanning a QR code.
Project status
- The source shows evidence of ongoing activity, with an upstream push on 2026-01-03, but the most recent tagged update in the provided summaries is v2.9.0 (2023-07-27), suggesting it may be maintained but with longer gaps between published updates/tags.
- Apparent update cadence from the listed tags is roughly every 1 to 2 years in earlier periods (2020 to 2023), followed by a longer tag gap since 2023, even though commits appear to continue in 2026.
AI summary generated 2 weeks ago
Recent updates
v2.9.0
7/27/2023v2.9.0 adds Steam-specific support to `parse_uri()` so that `otpauth://...` URLs with `encoder=steam` create a `pyotp.contrib.Steam` instance. The release notes also mention test and documentation improvements, and the diff shows corresponding CI and documentation build changes.
Featuresv2.8.0
12/14/2022Release v2.8.0 updates PyOTP with constant-time OTP generation, plus documentation and CI/runtime support changes. It also drops Python 3.6 support, adds Python 3.11 testing, and updates the Sphinx configuration.
Securityv2.7.0
9/11/2022v2.7.0 adds Steam TOTP support. It also includes various build, test, and documentation/CI adjustments around packaging, linting, formatting, and the test runner.
Featuresv2.6.0
2/4/2021v2.6.0 increases the default and minimum generated secret lengths (base32 to 32 chars, hex to 40 chars) in line with RFC guidance. It also fixes a bug where calling verify() could cause subsequent provisioning_uri() calls to produce invalid results.
Breakingv2.5.1
1/30/2021Release v2.5.1 updates PyOTP so that parse_uri no longer rejects an optional image query parameter. The code change is narrowly scoped to parameter validation, and the tests were adjusted accordingly.
v2.5.0
1/29/2021PyOTP v2.5.0 adds support for embedding a logo image in the OTP provisioning URI and extends OTP parsing to allow 7-digit codes. It also increases the default and minimum generated base32 secret length to 26 for stronger default secret material.
BreakingSecurityFeaturesv2.4.1
10/16/2020v2.4.1 contains a fix to how otpauth URIs are parsed for period and counter, plus an enhancement to support timezone-aware datetimes in TOTP.timecode(). The diff also shows behavioral changes around HOTP counter handling that are not explicitly called out in the release notes.
Featuresv2.4.0
7/29/2020Release v2.4.0 adds secret generation and provisioning URI support, including a new random_hex helper and parse_uri for otpauth URIs. It also fixes data typing around TOTP.at(for_time) and adds stricter validation for secrets that are too short. The code changes include additional refactors around typing and compatibility, beyond what the release notes explicitly describe.
BreakingFeaturesv2.3.0
7/26/2019Release v2.3.0 primarily addresses Python 2.7 comparison behavior. The code change ensures string normalization comparisons use UTF-8 byte encoding explicitly.
v2.2.9
7/26/2019v2.2.9 makes a small but security-relevant change to how PyOTP compares normalized Unicode strings, and updates project metadata and CI configuration. It also includes build and release automation changes (CI adds Python 3.7, packaging version/classifiers updated, release scripts adjusted).
Features