### Setup 2FA Authentication Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/api-overview.md Initiates 2FA setup by generating a secret, creating a TOTP object, generating a provisioning URI for QR codes, and verifying the user's initial code. ```python import pyotp # User initiates 2FA setup secret = pyotp.random_base32() totp = pyotp.TOTP(secret, name='alice@example.com', issuer='MyApp') # Generate provisioning URI for QR code uri = totp.provisioning_uri() # Store secret in database db.users.update(user_id, twofa_secret=secret) # User scans QR code and returns verification code user_code = request.form['verification_code'] if totp.verify(user_code, valid_window=1): db.users.update(user_id, twofa_enabled=True) return "2FA enabled successfully" ``` -------------------------------- ### HOTP Setup and Login Verification Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/api-reference/class-hotp.md Demonstrates the complete HOTP authentication flow, including generating a provisioning URI for QR code scanning during setup and verifying user-entered OTPs during login. Includes a look-ahead mechanism to handle counter desynchronization. ```python import pyotp # During OTP setup (user scanning QR code) hotp = pyotp.HOTP(secret_from_user) uri = hotp.provisioning_uri(name='alice@example.com', issuer='MyApp') qr_code = encode_qr(uri) store_in_database(user_id, secret=hotp.secret, counter=0) # During login (user entering OTP) stored_secret, stored_counter = get_from_database(user_id) hotp = pyotp.HOTP(stored_secret) user_code = request_from_user() # Resynchronize with look-ahead LOOK_AHEAD = 5 for offset in range(LOOK_AHEAD): candidate_counter = stored_counter + 1 + offset if hotp.verify(user_code, candidate_counter): update_database(user_id, counter=candidate_counter) accept_login() break else: reject_login() # No match found ``` -------------------------------- ### Common TOTP Usage Example Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/api-overview.md Demonstrates generating a secret, creating a TOTP object, generating a provisioning URI, and verifying user-provided OTP codes. Includes an example of generating the current OTP code for testing. ```python import pyotp # Generate a secret secret = pyotp.random_base32() # Create TOTP (time-based OTP for Google Authenticator, Authy, etc.) totp = pyotp.TOTP(secret, name='user@example.com', issuer='MyApp') # Generate QR code URI for provisioning uri = totp.provisioning_uri() # otpauth://totp/... # Verify OTP from user code = input("Enter authenticator code: ") if totp.verify(code, valid_window=1): print("Authentication successful") else: print("Invalid code") # Generate code for testing current_code = totp.now() print(current_code) # e.g., '492039' ``` -------------------------------- ### Typical Steam OTP Usage: Setup and Verification Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/api-reference/class-steam.md Demonstrates the typical workflow for setting up Steam OTP and verifying user-provided authentication codes. This includes generating the secret, sharing the provisioning URI (e.g., via QR code), and verifying codes entered by the user. ```python import pyotp # Setup: Generate and share secret steam = pyotp.contrib.Steam('JBSWY3DPEHPK3PXP', name='user@steam', issuer='Steam') uri = steam.provisioning_uri() # Share QR code with user for scanning into Steam authenticator app # Verification during login user_input = input("Enter Steam authenticator code: ") # e.g., 'QCMYQ' if steam.verify(user_input): print("Steam authentication successful") else: print("Invalid code") # With time skew tolerance if steam.verify(user_input, valid_window=1): print("Steam authentication successful (with tolerance)") ``` -------------------------------- ### Default HOTP Configuration Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/configuration.md Initialize an HOTP object with the default counter starting at 0. ```python import pyotp # Counter starts at 0 (default) hotp = pyotp.HOTP('JBSWY3DPEHPK3PXP') ``` -------------------------------- ### Generate Current OTP Source: https://github.com/pyauth/pyotp/blob/main/README.rst A working example demonstrating how to generate the current OTP using a TOTP object. This code can be run after setting up a TOTP secret. ```python import pyotp totp = pyotp.TOTP("JBSWY3DPEHPK3PXP") print("Current OTP:", totp.now()) ``` -------------------------------- ### build_uri Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/api-reference/utils.md Builds an otpauth:// provisioning URI for OTP setup. This function is used internally by TOTP and HOTP provisioning_uri() methods but is also available for custom URI generation. ```APIDOC ## build_uri ### Description Builds an otpauth:// provisioning URI for OTP setup. This function is used internally by TOTP and HOTP provisioning_uri() methods but is also available for custom URI generation. ### Parameters #### Path Parameters None #### Query Parameters - **secret** (str) - Required - Base32-encoded shared secret - **name** (str) - Required - Account name/identifier - **initial_count** (Optional[int]) - Optional - Counter value for HOTP. If present, generates HOTP URI; if absent, generates TOTP URI. - **issuer** (Optional[str]) - Optional - Organization/app issuer name - **algorithm** (Optional[str]) - Optional - Hash algorithm: 'SHA1' (default), 'SHA256', or 'SHA512'. Only non-default values included in URI. - **digits** (Optional[int]) - Optional - Number of OTP digits. Only non-default (6) values included in URI. - **period** (Optional[int]) - Optional - Time interval for TOTP in seconds. Only non-default (30) values included in URI. - **kwargs** (str values) - Optional - Additional URI query parameters (all values must be strings). Supports custom fields like `image`. ### Request Example ```python from pyotp.utils import build_uri # Generate TOTP URI uri = build_uri( secret='JBSWY3DPEHPK3PXP', name='alice@example.com', issuer='MyApp' ) print(uri) # Generate HOTP URI with custom parameters uri = build_uri( secret='JBSWY3DPEHPK3PXP', name='alice@example.com', initial_count=5, issuer='MyApp', algorithm='sha256', digits=8, image='https://example.com/logo.png' ) print(uri) # Custom parameters uri = build_uri( secret='JBSWY3DPEHPK3PXP', name='user', issuer='Company', algorithm='sha512', custom_field='custom_value' ) ``` ### Response #### Success Response (200) - **str** - Complete otpauth:// URI string with URL-encoded components. #### Response Example ``` otpauth://totp/MyApp:alice%40example.com?secret=JBSWY3DPEHPK3PXP&issuer=MyApp ``` ### Error Handling - `ValueError` if any kwargs value is not a string - `ValueError` if `image` parameter is not a valid HTTPS URL ``` -------------------------------- ### OTP Initialization with Custom Configuration Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/api-reference/class-otp.md Shows how to initialize an OTP handler with custom digits, digest algorithm, account name, and issuer. This allows for more specific OTP configurations. ```python # Custom digits and digest otp = pyotp.OTP( 'JBSWY3DPEHPK3PXP', digits=8, digest=hashlib.sha256, name='alice@example.com', issuer='MyApp' ) ``` -------------------------------- ### Generate Random Base32 Secret Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/api-reference/module-init.md Generates a random base32 secret suitable for Google Authenticator. Use this when a new secret is needed for OTP setup. ```python import pyotp secret = pyotp.random_base32() print(secret) # e.g., 'JBSWY3DPEHPK3PXP4AOAXFLBKFXWQ3O5' totp = pyotp.TOTP(secret) print(totp.now()) # Current OTP code ``` -------------------------------- ### Using Inherited TOTP Methods with Steam Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/api-reference/class-steam.md Demonstrates how to use standard TOTP methods like `now()`, `verify()`, and `provisioning_uri()` with the Steam OTP class. Ensure the Steam secret key is provided during initialization. ```python import pyotp\n\nsteam = pyotp.contrib.Steam('JBSWY3DPEHPK3PXP', name='user@steam', issuer='Steam')\n\n# All TOTP methods available\ncode = steam.now()\nverified = steam.verify(code)\uri = steam.provisioning_uri() ``` -------------------------------- ### Configured Steam Constructor Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/configuration.md Configure the Steam OTP generator with account name and issuer. ```python import pyotp steam = pyotp.contrib.Steam( 'JBSWY3DPEHPK3PXP', name='user@steam', issuer='Steam' ) ``` -------------------------------- ### Verify OTP and Get Timecode Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/api-reference/class-totp.md Verifies an OTP code and returns the matching timecode. Useful for preventing replay attacks by storing and comparing timecodes. Accepts the OTP, an optional time to verify against, and a validation window. ```python import pyotp import datetime totp = pyotp.TOTP('JBSWY3DPEHPK3PXP') # Verify and get timecode code = totp.now() timecode = totp.verify_and_get_timecode(code) if timecode is not False: print(f"Valid code at timecode: {timecode}") # Store timecode in database to prevent replay # In subsequent logins, only accept codes with timecode > stored_timecode stored_timecode = timecode # Reject replayed code result = totp.verify_and_get_timecode(code) if result is not False and result > stored_timecode: print("Fresh code accepted") else: print("Replayed code rejected") else: print("Invalid code") ``` ```python # During authentication timecode = totp.verify_and_get_timecode(user_input) if timecode is False: deny_login() elif timecode <= last_successful_timecode: deny_login() # Replay attack else: accept_login() last_successful_timecode = timecode # Store for next time ``` -------------------------------- ### Build URI with Custom Query Parameters Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/api-reference/utils.md Demonstrates how to include arbitrary custom query parameters in an otpauth:// URI. All custom parameter values must be strings. ```python from pyotp.utils import build_uri # Custom parameters uri = build_uri( secret='JBSWY3DPEHPK3PXP', name='user', issuer='Company', algorithm='sha512', custom_field='custom_value' ) ``` -------------------------------- ### Handle HOTP (SMS-based or Hardware Token) Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/api-overview.md Demonstrates handling HOTP (Hash-based One-Time Password) for scenarios like SMS-based codes or hardware tokens. It includes sending the initial code, verifying user input, and resynchronizing with look-ahead. ```python import pyotp # Initialize HOTP secret = pyotp.random_base32() hotp = pyotp.HOTP(secret, name='alice@example.com', issuer='MyApp') # Send SMS with first code initial_code = hotp.at(0) send_sms(user_phone, f"Your code: {initial_code}") # User enters code user_code = request.form['otp_code'] # Verify and resynchronize with look-ahead LOOK_AHEAD = 5 last_counter = db.users.get(user_id).hotp_counter or -1 for offset in range(LOOK_AHEAD): candidate = last_counter + 1 + offset if hotp.verify(user_code, candidate): db.users.update(user_id, hotp_counter=candidate) return "HOTP verified" return "Invalid code" ``` -------------------------------- ### Parse and Verify Provisioning URI Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/api-overview.md Parses a provisioning URI, which can be obtained from a QR code or manual entry, and then generates and verifies an OTP code using the parsed information. ```python import pyotp # Parse URI from QR code or manual entry uri = 'otpauth://totp/MyApp:alice%40example.com?secret=JBSWY3DPEHPK3PXP&issuer=MyApp' otp = pyotp.parse_uri(uri) # Generate and verify code = otp.now() verified = otp.verify(code) ``` -------------------------------- ### Minimal OTP Configuration Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/configuration.md Use this snippet for basic OTP instantiation with only the required shared secret. ```python import pyotp # Minimal configuration otp = pyotp.OTP('JBSWY3DPEHPK3PXP') ``` -------------------------------- ### Constructor Parameters Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/api-overview.md All OTP classes accept common parameters for initialization, including the base32 secret, code length, digest function, account name, and issuer name. Specific classes like TOTP and HOTP have additional parameters for interval and initial count. ```APIDOC ## Constructor Parameters All OTP classes support: - `s` (str) — Base32 secret (REQUIRED) - `digits` (int) — Code length, 1-10 (default: 6) - `digest` — HMAC digest function (default: sha1) - `name` (str) — Account name (default: None) - `issuer` (str) — Organization name (default: None) Additional parameters: - `TOTP`: `interval` (int, default: 30 seconds) - `HOTP`: `initial_count` (int, default: 0) - `Steam`: All same as TOTP, but hardcoded to 5-char alphabet ``` -------------------------------- ### Verify HOTP with Look-Ahead Window Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/api-reference/class-hotp.md Demonstrates how a server can verify an HOTP code submitted by a user by checking a window of future counter values. This is crucial for handling out-of-order submissions or client-server counter drift. ```python import pyotp hotp = pyotp.HOTP('JBSWY3DPEHPK3PXP') user_input_code = '123456' # Server's last-accepted counter for user last_counter = 50 # Look ahead up to 10 counters for a match LOOK_AHEAD_WINDOW = 10 matched_counter = None for offset in range(LOOK_AHEAD_WINDOW): if hotp.verify(user_input_code, last_counter + 1 + offset): matched_counter = last_counter + 1 + offset break if matched_counter is not None: # Update server's counter last_counter = matched_counter accept_login() else: reject_login() ``` -------------------------------- ### Basic OTP Initialization Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/api-reference/class-otp.md Demonstrates basic initialization of an OTP handler using a base32 encoded secret. This is typically done via subclasses like TOTP or HOTP. ```python import pyotp import hashlib # Basic initialization otp = pyotp.OTP('JBSWY3DPEHPK3PXP') ``` -------------------------------- ### Import Core Classes and Helper Functions Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/api-overview.md Import necessary classes like TOTP, HOTP, and OTP, as well as helper functions for generating random secrets and parsing URIs. ```python # Core classes from pyotp import TOTP, HOTP, OTP # Helper functions from pyotp import random_base32, random_hex, parse_uri # Contrib modules from pyotp.contrib import Steam # Internal utilities (rarely needed) from pyotp.utils import build_uri, strings_equal ``` -------------------------------- ### Steam OTP Typical Usage Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/api-reference/class-steam.md Demonstrates the typical workflow for using the Steam OTP class, including generating a secret and provisioning URI, and verifying user-provided OTP codes with optional time skew tolerance. ```APIDOC ## Typical Usage ```python import pyotp # Setup: Generate and share secret steam = pyotp.contrib.Steam('JBSWY3DPEHPK3PXP', name='user@steam', issuer='Steam') uri = steam.provisioning_uri() # Share QR code with user for scanning into Steam authenticator app # Verification during login user_input = input("Enter Steam authenticator code: ") # e.g., 'QCMYQ' if steam.verify(user_input): print("Steam authentication successful") else: print("Invalid code") # With time skew tolerance if steam.verify(user_input, valid_window=1): print("Steam authentication successful (with tolerance)") ``` ``` -------------------------------- ### HOTP.provisioning_uri() Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/api-reference/class-hotp.md Generates an otpauth:// URI, which can be used for QR code generation to provision OTP apps. Supports custom parameters. ```APIDOC ## HOTP.provisioning_uri() ### Description Generates an otpauth:// URI suitable for QR code encoding and provisioning OTP apps. Supports custom parameters. ### Method Signature ```python def provisioning_uri( self, name: Optional[str] = None, initial_count: Optional[int] = None, issuer_name: Optional[str] = None, **kwargs, ) -> str ``` ### Parameters #### Path Parameters - **name** (Optional[str]) - Optional - Account name. Uses constructor `name` if not provided. - **initial_count** (Optional[int]) - Optional - Starting counter value in URI. Uses constructor `initial_count` if not provided. - **issuer_name** (Optional[str]) - Optional - Issuer name. Uses constructor `issuer` if not provided. - **kwargs** (str values) - Optional - Additional query parameters (must have string values). Supports custom fields. ### Returns - **str** - An otpauth:// URI string. ### Raises - `ValueError` if kwargs values are not strings - `ValueError` if `image` parameter is an invalid URL ### Example ```python import pyotp hotp = pyotp.HOTP('JBSWY3DPEHPK3PXP', name='alice@example.com', issuer='MyApp', initial_count=0) # Basic provisioning URI uri = hotp.provisioning_uri() print(uri) # otpauth://hotp/MyApp:alice%40example.com?secret=JBSWY3DPEHPK3PXP&issuer=MyApp&counter=0&algorithm=SHA1&digits=6 # Override initial counter uri = hotp.provisioning_uri(initial_count=10) print(uri) # Custom parameters uri = hotp.provisioning_uri( name='alice@example.com', issuer_name='Company', initial_count=5, image='https://example.com/logo.png' ) ``` ### URI Contents - **secret:** The shared secret (base32-encoded) - **issuer:** Organization/app name - **counter:** Starting counter value - **algorithm:** Hash algorithm used (SHA1, SHA256, or SHA512) - **digits:** Number of digits in code Non-default values are included in the URI; defaults are omitted for brevity. ``` -------------------------------- ### Generate and Verify Counter-Based OTP (HOTP) Source: https://github.com/pyauth/pyotp/blob/main/README.rst Shows how to create an HOTP object with a base32 secret and generate OTPs for specific counter values. It also demonstrates verifying an OTP against a given counter. ```python import pyotp hotp = pyotp.HOTP('base32secret3232') hotp.at(0) # => '260182' hotp.at(1) # => '055283' hotp.at(1401) # => '316439' # OTP verified with a counter hotp.verify('316439', 1401) # => True hotp.verify('316439', 1402) # => False ``` -------------------------------- ### Basic Steam Constructor Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/configuration.md Instantiate the Steam OTP generator with the required shared secret. ```python import pyotp steam = pyotp.contrib.Steam('JBSWY3DPEHPK3PXP') ``` -------------------------------- ### Full OTP Configuration Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/configuration.md Configure OTP with all available parameters: secret, digits, digest, name, and issuer. ```python import pyotp import hashlib # Full configuration otp = pyotp.OTP( s='JBSWY3DPEHPK3PXP', digits=8, digest=hashlib.sha256, name='alice@example.com', issuer='MyCompany' ) ``` -------------------------------- ### Generate and Verify Time-Based OTP (TOTP) Source: https://github.com/pyauth/pyotp/blob/main/README.rst Demonstrates how to create a TOTP object with a base32 secret, generate the current OTP, and verify an OTP for the current time. Note that verification will fail after the time step expires. ```python import pyotp import time totp = pyotp.TOTP('base32secret3232') totp.now() # => '492039' # OTP verified for current time totp.verify('492039') # => True time.sleep(30) totp.verify('492039') # => False ``` -------------------------------- ### Provisioning URI Format Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/INDEX.md Illustrates the standard `otpauth://` URI format used for sharing OTP configurations with authenticator apps. This format includes parameters like secret, issuer, algorithm, digits, period, and counter. ```plaintext otpauth://[totp|hotp]/[issuer:]account?secret=...&issuer=...&algorithm=...&digits=...&period=...&counter=... ``` -------------------------------- ### Parse HOTP Provisioning URI Source: https://github.com/pyauth/pyotp/blob/main/README.rst Parses a provisioning URI string to create a pyotp.hotp.HOTP object. Supports HOTP URIs with counter information. ```python pyotp.parse_uri('otpauth://hotp/Secure%20App:alice%40google.com?secret=JBSWY3DPEHPK3PXP&issuer=Secure%20App&counter=0') ``` -------------------------------- ### Provisioning URI String Format Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/types.md Methods for generating provisioning URIs return fully-formed 'otpauth://' strings. These URIs are used for easily adding OTP configurations to authenticator apps. ```python import pyotp totp = pyotp.TOTP('JBSWY3DPEHPK3PXP', name='user@example.com', issuer='App') uri = totp.provisioning_uri() type(uri) # str uri.startswith('otpauth://') # True # e.g., 'otpauth://totp/App:user%40example.com?secret=...' ``` -------------------------------- ### Build HOTP Provisioning URI with Custom Parameters Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/api-reference/utils.md Generates an otpauth:// URI for HMAC-based One-Time Passwords (HOTP) including custom parameters like algorithm, digits, and an image URL. The `initial_count` parameter is crucial for HOTP URIs. ```python from pyotp.utils import build_uri # Generate HOTP URI with custom parameters uri = build_uri( secret='JBSWY3DPEHPK3PXP', name='alice@example.com', initial_count=5, issuer='MyApp', algorithm='sha256', digits=8, image='https://example.com/logo.png' ) print(uri) # otpauth://hotp/MyApp:alice%40example.com?secret=JBSWY3DPEHPK3PXP&counter=5&issuer=MyApp&algorithm=SHA256&digits=8&image=https%3A%2F%2Fexample.com%2Flogo.png ``` -------------------------------- ### Steam OTP Provisioning URI Format Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/api-reference/class-steam.md This is the standard format for Steam OTP provisioning URIs, including the necessary `encoder=steam` parameter. ```plaintext otpauth://totp/[issuer:]account?secret=SECRET&issuer=ISSUER&encoder=steam&algorithm=SHA1&period=30 ``` -------------------------------- ### Safely Parse Provisioning URI Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/errors.md Safely parses a provisioning URI, handling potential errors if the URI is malformed. Returns None if parsing fails. ```python import pyotp def parse_uri_safely(uri): """Safely parse provisioning URI.""" try: return pyotp.parse_uri(uri) except ValueError as e: print(f"Invalid provisioning URI: {e}") return None ``` -------------------------------- ### Helper Functions Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/api-overview.md Provides documentation for utility functions available in the `pyotp` module for generating secrets and parsing URIs. ```APIDOC ## Helper Functions ### Description This section covers the helper functions available in the `pyotp` module for generating random secrets and parsing provisioning URIs. ### Functions #### `random_base32(length=None, chars=None)` - **Description**: Generates a random base32 encoded secret. - **Parameters**: - `length` (int, optional): The desired length of the secret. - `chars` (string, optional): The characters to use for encoding. #### `random_hex(length=None, chars=None)` - **Description**: Generates a random hex-encoded secret. - **Parameters**: - `length` (int, optional): The desired length of the secret. - `chars` (string, optional): The characters to use for encoding. #### `parse_uri(uri)` - **Description**: Parses an `otpauth://` provisioning URI. - **Parameters**: - `uri` (string): The `otpauth://` URI to parse. - **Returns**: A dictionary containing the parsed URI components. ``` -------------------------------- ### Generate Provisioning URI Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/api-reference/class-totp.md Generates an otpauth:// URI for provisioning OTP apps, suitable for QR code encoding. Accepts an optional account name, issuer name, and additional query parameters. ```python import pyotp totp = pyotp.TOTP('JBSWY3DPEHPK3PXP', name='alice@example.com', issuer='MyApp') # Basic provisioning URI uri = totp.provisioning_uri() print(uri) # otpauth://totp/MyApp:alice%40example.com?secret=JBSWY3DPEHPK3PXP&issuer=MyApp&algorithm=SHA1&digits=6&period=30 # Override account name uri = totp.provisioning_uri(name='alice@gmail.com') print(uri) # Custom parameters uri = totp.provisioning_uri( name='alice@example.com', issuer_name='Company', image='https://example.com/logo.png' ) ``` -------------------------------- ### Create Test HOTP Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/configuration.md Create an HOTP object specifically for unit testing purposes. ```python import pyotp import hashlib def create_test_hotp(secret='JBSWY3DPEHPK3PXP'): """Create HOTP for unit tests.""" return pyotp.HOTP( s=secret, initial_count=0, name='test@example.com', issuer='TestApp' ) ``` -------------------------------- ### provisioning_uri Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/api-reference/class-totp.md Generates an otpauth:// URI suitable for QR code encoding and provisioning OTP apps. This URI can be used to set up authenticator apps like Google Authenticator or Authy. ```APIDOC ## provisioning_uri ### Description Generates an otpauth:// URI suitable for QR code encoding and provisioning OTP apps. ### Method Signature ```python def provisioning_uri(self, name: Optional[str] = None, issuer_name: Optional[str] = None, **kwargs) -> str ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **name** (Optional[str]) - Optional - Account name. Uses constructor `name` if not provided. - **issuer_name** (Optional[str]) - Optional - Issuer name. Uses constructor `issuer` if not provided. - **kwargs** (str values) - Optional - Additional query parameters (must have string values). Supports custom fields. ### Request Example ```python import pyotp totp = pyotp.TOTP('JBSWY3DPEHPK3PXP', name='alice@example.com', issuer='MyApp') # Basic provisioning URI uri = totp.provisioning_uri() print(uri) # otpauth://totp/MyApp:alice%40example.com?secret=JBSWY3DPEHPK3PXP&issuer=MyApp&algorithm=SHA1&digits=6&period=30 # Override account name uri = totp.provisioning_uri(name='alice@gmail.com') print(uri) # Custom parameters uri = totp.provisioning_uri( name='alice@example.com', issuer_name='Company', image='https://example.com/logo.png' ) print(uri) ``` ### Response #### Success Response (200) - **str** - An otpauth:// URI string. #### Response Example ``` # Example output for basic provisioning URI: otpauth://totp/MyApp:alice%40example.com?secret=JBSWY3DPEHPK3PXP&issuer=MyApp&algorithm=SHA1&digits=6&period=30 ``` ### Error Handling - `ValueError` if kwargs values are not strings - `ValueError` if `image` parameter is an invalid URL ``` -------------------------------- ### Parse TOTP Provisioning URI Source: https://github.com/pyauth/pyotp/blob/main/README.rst Parses a provisioning URI string to create a pyotp.totp.TOTP object. This is useful for applications that need to read OTP configurations from URIs. ```python pyotp.parse_uri('otpauth://totp/Secure%20App:alice%40google.com?secret=JBSWY3DPEHPK3PXP&issuer=Secure%20App') ``` -------------------------------- ### HOTP Methods Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/INDEX.md Offers methods for generating and verifying Counter-based One-Time Passwords. Use `at()` to generate an OTP for a specific counter value and `verify()` to validate a given OTP against a counter. ```python at(count: int) -> str verify(otp: str, counter: int) -> bool provisioning_uri(name=None, initial_count=None, issuer_name=None, **kwargs) -> str ``` -------------------------------- ### OTP Constructor Parameters Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/api-reference/class-otp.md Initializes an OTP handler with a shared secret and configuration. Parameters include the secret key, number of digits, hash function, account name, and issuer. Raises ValueError for invalid digits or digest. ```python def __init__( self, s: str, digits: int = 6, digest: Any = hashlib.sha1, name: Optional[str] = None, issuer: Optional[str] = None, ) -> None ``` -------------------------------- ### Generate HOTP Provisioning URI Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/api-reference/class-hotp.md Generates an otpauth:// URI for provisioning HOTP apps. Supports overriding account name, issuer, and initial counter. Custom query parameters can be added. ```python import pyotp hotp = pyotp.HOTP('JBSWY3DPEHPK3PXP', name='alice@example.com', issuer='MyApp', initial_count=0) # Basic provisioning URI uri = hotp.provisioning_uri() print(uri) # otpauth://hotp/MyApp:alice%40example.com?secret=JBSWY3DPEHPK3PXP&issuer=MyApp&counter=0&algorithm=SHA1&digits=6 # Override initial counter uri = hotp.provisioning_uri(initial_count=10) print(uri) # Custom parameters uri = hotp.provisioning_uri( name='alice@example.com', issuer_name='Company', initial_count=5, image='https://example.com/logo.png' ) ``` -------------------------------- ### Standard TOTP Configuration Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/configuration.md Instantiate a TOTP object compatible with Google Authenticator using the default settings. ```python import pyotp # Standard Google Authenticator compatible totp = pyotp.TOTP('JBSWY3DPEHPK3PXP') ``` -------------------------------- ### HOTP Core Methods Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/api-overview.md The `HOTP` class offers methods to generate an OTP for a specific counter value and to verify a given OTP against a counter. ```APIDOC ## HOTP Core Methods - `at(count)`: Generate OTP for counter value. - `verify(otp, counter)`: Verify counter-based OTP. - `provisioning_uri(name, initial_count, issuer_name, **kwargs)`: Generate otpauth:// URI. ``` -------------------------------- ### Steam Constructor Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/api-reference/class-steam.md Initializes a Steam OTP handler with a shared secret. This class uses Steam's proprietary 5-character alphanumeric alphabet. ```APIDOC ## Constructor Steam ### Description Initializes a Steam OTP handler with a shared secret. This class uses Steam's proprietary 5-character alphanumeric alphabet. ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **s** (str) - Required - Secret in base32 format (case-insensitive) - **name** (Optional[str]) - Optional - Account name or description. Used in provisioning URIs. - **issuer** (Optional[str]) - Optional - Name of the OTP issuer. Used in provisioning URIs. - **interval** (int) - Optional - Time interval in seconds for OTP validity. Standard is 30 seconds. - **digits** (int) - Optional - Number of characters in generated OTP code. Fixed at 5 for Steam (parameter for API compatibility). ### Request Example ```python import pyotp # Steam OTP steam = pyotp.contrib.Steam('JBSWY3DPEHPK3PXP') code = steam.now() print(code) # e.g., 'QCMYQ' (5-character alphanumeric using Steam alphabet) # With custom name/issuer steam = pyotp.contrib.Steam( 'JBSWY3DPEHPK3PXP', name='user@steam', issuer='Steam' ) ``` ### Response #### Success Response (200) Not applicable for constructor. #### Response Example Not applicable for constructor. ``` -------------------------------- ### Accessing OTP via Subclasses Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/api-reference/class-otp.md Illustrates the common practice of accessing OTP functionality through its subclasses, such as TOTP, which are typically used in applications. ```python # Typically accessed through TOTP or HOTP subclasses totp = pyotp.TOTP('JBSWY3DPEHPK3PXP', name='user@example.com', issuer='Company') ``` -------------------------------- ### Generate HOTP Provisioning URI Source: https://github.com/pyauth/pyotp/blob/main/README.rst Generates a provisioning URI for an HOTP secret, including the initial counter value. This URI can be used for QR code generation. ```python pyotp.hotp.HOTP('JBSWY3DPEHPK3PXP').provisioning_uri(name="alice@google.com", issuer_name="Secure App", initial_count=0) ``` -------------------------------- ### TOTP.verify() with valid_window Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/configuration.md Verify a TOTP code with configurable time skew tolerance. Use `valid_window` to specify the number of intervals before and after the current time to check. ```python import pyotp totp = pyotp.TOTP('JBSWY3DPEHPK3PXP') code = totp.now() # Strict verification (no skew tolerance) result = totp.verify(code, valid_window=0) # Tolerant verification (±30 seconds with default 30-sec interval) result = totp.verify(code, valid_window=1) # Very tolerant (±60 seconds) result = totp.verify(code, valid_window=2) ``` -------------------------------- ### OTP Constructors Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/INDEX.md Constructors for creating OTP objects. The base OTP class is abstract and should not be instantiated directly. Use TOTP, HOTP, or Steam. ```APIDOC ## OTP Base Class ### Constructor ```python OTP(s, digits=6, digest=hashlib.sha1, name=None, issuer=None) ``` ### Description Base class for OTP generation. Not intended for direct instantiation. ## Time-based OTP (TOTP) ### Constructor ```python TOTP(s, digits=6, digest=None, name=None, issuer=None, interval=30) ``` ### Description Generates Time-based One-Time Passwords (TOTP) according to RFC 6238. The `interval` parameter specifies the time step in seconds. ## Counter-based OTP (HOTP) ### Constructor ```python HOTP(s, digits=6, digest=None, name=None, issuer=None, initial_count=0) ``` ### Description Generates Counter-based One-Time Passwords (HOTP) according to RFC 4226. `initial_count` sets the starting counter value. ## Steam OTP ### Constructor ```python Steam(s, name=None, issuer=None, interval=30, digits=5) ``` ### Description Generates OTPs in the format used by Steam Guard Mobile Authenticator. `interval` is typically 30 seconds, and `digits` is usually 5. ``` -------------------------------- ### Using Custom Digest Functions in OTP Constructors Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/types.md Demonstrates how to specify a custom digest function (e.g., SHA256) when creating TOTP or HOTP instances. If no digest is provided, hashlib.sha1 is used by default. ```python import pyotp import hashlib # Using SHA256 instead of default SHA1 totp = pyotp.TOTP('JBSWY3DPEHPK3PXP', digest=hashlib.sha256) hotp = pyotp.HOTP('JBSWY3DPEHPK3PXP', digest=hashlib.sha512) # Default (SHA1) totp = pyotp.TOTP('JBSWY3DPEHPK3PXP') # digest defaults to hashlib.sha1 ``` -------------------------------- ### Custom HOTP Configuration Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/configuration.md Configure HOTP with a specific initial counter value, digits, digest, name, and issuer. ```python import pyotp import hashlib # Counter starts at specific value (e.g., resynchronizing) hotp = pyotp.HOTP( 'JBSWY3DPEHPK3PXP', initial_count=1000, digits=8, digest=hashlib.sha512, name='alice@example.com', issuer='SecureApp' ) ``` -------------------------------- ### verify(otp, for_time=None, valid_window=0) Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/api-reference/class-totp.md Verifies a given OTP code against a specified time or the current time if `for_time` is not provided. It includes a `valid_window` parameter to allow for time skew tolerance, accepting codes from adjacent intervals. ```APIDOC ## verify(otp, for_time=None, valid_window=0) ### Description Verifies an OTP code against a specific time (or current time if not specified). ### Parameters #### Path Parameters - **otp** (str) - Required - The OTP code to verify (as a string). - **for_time** (Optional[datetime.datetime]) - Optional - Time to verify against. If None, uses current time. Defaults to None. - **valid_window** (int) - Optional - Number of time intervals before and after the current one to accept. Allows for time skew tolerance. Defaults to 0. ### Returns `bool` — True if OTP is valid, False otherwise. ### Raises None (returns False on mismatch) ### Example ```python import pyotp import datetime import time totp = pyotp.TOTP('JBSWY3DPEHPK3PXP') # Verify immediate code code = totp.now() result = totp.verify(code) # True print(result) # Verify with time skew tolerance (±30 seconds) result = totp.verify(code, valid_window=1) # True print(result) # Verify past code (requires valid_window) time.sleep(35) old_code = totp.at(datetime.datetime.now() - datetime.timedelta(seconds=30)) result = totp.verify(old_code, valid_window=1) # True if within window print(result) ``` ### Timing-Safe Uses constant-time string comparison to prevent timing attacks. ### Time Skew Handling The `valid_window` parameter allows acceptance of codes outside the current interval window. For example: - `valid_window=0` (default): only current interval accepted - `valid_window=1`: current + 1 before + 1 after = 3 intervals (90 seconds with default 30-sec interval) - `valid_window=2`: current + 2 before + 2 after = 5 intervals (150 seconds) ``` -------------------------------- ### Unit Test for OTP Generation Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/api-overview.md Demonstrates how to perform unit tests for OTP generation using a fixed secret. Ensures the generated code is a 6-digit string. ```python import pyotp TEST_SECRET = 'JBSWY3DPEHPK3PXP' def test_otp_generation(): totp = pyotp.TOTP(TEST_SECRET) code = totp.now() assert isinstance(code, str) assert len(code) == 6 assert code.isdigit() ``` -------------------------------- ### Validate Provisioning URI Format and Parsability Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/errors.md Validates that a provisioning URI adheres to expected formats and can be parsed by pyotp. It checks for required components and handles parsing errors. ```python import pyotp def validate_provisioning_uri(uri): """Validate that a provisioning URI is well-formed.""" required_checks = [ ('otpauth://' in uri, "URI must start with otpauth://"), (('totp' in uri or 'hotp' in uri), "URI must contain totp or hotp"), ('secret=' in uri, "URI must contain secret parameter"), ] for check, message in required_checks: if not check: print(f"Validation failed: {message}") return False # Try to parse try: otp = pyotp.parse_uri(uri) print(f"Valid {type(otp).__name__} URI") return True except ValueError as e: print(f"Parse error: {e}") return False ``` -------------------------------- ### Generate HOTP provisioning URI Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/configuration.md Generates a provisioning URI for an HOTP object. This allows overriding the account name, initial counter value, issuer name, and adding custom parameters. ```python hotp.provisioning_uri(name=None, initial_count=None, issuer_name=None, **kwargs) ``` ```python import pyotp hotp = pyotp.HOTP('JBSWY3DPEHPK3PXP', initial_count=0, issuer='App') # Use constructor values uri1 = hotp.provisioning_uri() # Override counter for resynchronization uri2 = hotp.provisioning_uri(initial_count=100) # Full customization uri3 = hotp.provisioning_uri( name='alice@example.com', initial_count=50, issuer_name='SecureApp', image='https://app.com/logo.png' ) ``` -------------------------------- ### Generate Steam Provisioning URI Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/api-reference/class-steam.md Generates a provisioning URI for a Steam account using the pyotp.contrib.Steam class. This URI can be used to generate a QR code for users to add their account to the Steam mobile authenticator app. ```python import pyotp steam = pyotp.contrib.Steam('JBSWY3DPEHPK3PXP', name='user@steam', issuer='Steam') uri = steam.provisioning_uri() print(uri) # otpauth://totp/Steam:user%40steam?secret=JBSWY3DPEHPK3PXP&issuer=Steam&encoder=steam&algorithm=SHA1&period=30 ``` -------------------------------- ### TOTP Methods Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/INDEX.md Provides methods for generating and verifying Time-based One-Time Passwords. Use `now()` for the current OTP, `at()` for a specific time, and `verify()` to check a provided OTP. `verify_and_get_timecode()` is useful for replay prevention. ```python now() -> str at(for_time: Union[int, datetime], counter_offset=0) -> str verify(otp: str, for_time=None, valid_window=0) -> bool verify_and_get_timecode(otp: str, for_time=None, valid_window=0) -> int | False provisioning_uri(name=None, issuer_name=None, **kwargs) -> str timecode(for_time: datetime) -> int ``` -------------------------------- ### Generate TOTP Provisioning URI Source: https://github.com/pyauth/pyotp/blob/main/README.rst Generates a provisioning URI for a TOTP secret, suitable for QR code generation. Includes the user's name and the issuer name. ```python pyotp.totp.TOTP('JBSWY3DPEHPK3PXP').provisioning_uri(name='alice@google.com', issuer_name='Secure App') ``` -------------------------------- ### Utility Functions Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/INDEX.md General utility functions provided by the pyotp library. ```APIDOC ## Utility Functions ### `random_base32(length=32, chars="ABCDEFGHIJKLMNOPQRSTUVWXYZ234567")` ```python random_base32(length=32, chars="ABCDEFGHIJKLMNOPQRSTUVWXYZ234567") -> str ``` **Description**: Generates a random Base32 encoded string of a specified length, suitable for OTP secrets. ### `random_hex(length=40, chars="ABCDEF0123456789")` ```python random_hex(length=40, chars="ABCDEF0123456789") -> str ``` **Description**: Generates a random hexadecimal string of a specified length. ### `parse_uri(uri)` ```python parse_uri(uri: str) -> OTP | TOTP | HOTP | Steam ``` **Description**: Parses an otpauth:// URI and returns the corresponding OTP object (OTP, TOTP, HOTP, or Steam). ### `build_uri(secret, name, initial_count=None, issuer=None, ...)` ```python build_uri(secret, name, initial_count=None, issuer=None, ...) -> str ``` **Description**: Builds an otpauth:// URI from the provided parameters. This is a convenience function that can construct URIs for TOTP, HOTP, and other OTP types. ### `strings_equal(s1, s2)` ```python strings_equal(s1: str, s2: str) -> bool ``` **Description**: Compares two strings in constant time to prevent timing attacks. This is used internally for OTP verification but can also be used for general secure string comparison. ``` -------------------------------- ### Initialize Steam OTP Handler Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/api-reference/class-steam.md Initializes a Steam OTP handler with a shared secret. The `digits` parameter is fixed at 5 for API compatibility. ```python import pyotp # Steam OTP steam = pyotp.contrib.Steam('JBSWY3DPEHPK3PXP') code = steam.now() print(code) # e.g., 'QCMYQ' (5-character alphanumeric using Steam alphabet) # With custom name/issuer steam = pyotp.contrib.Steam( 'JBSWY3DPEHPK3PXP', name='user@steam', issuer='Steam' ) ``` -------------------------------- ### TOTP Core Methods Source: https://github.com/pyauth/pyotp/blob/main/_autodocs/api-overview.md The `TOTP` class provides methods for generating the current OTP, generating OTPs for specific times, verifying OTPs against a time window, and generating provisioning URIs for authenticator apps. ```APIDOC ## TOTP Core Methods - `now()`: Generate current time-based OTP. - `at(for_time, counter_offset)`: Generate OTP for specific time. - `verify(otp, for_time, valid_window)`: Verify time-based OTP. - `verify_and_get_timecode(otp, for_time, valid_window)`: Verify and return timecode (for replay prevention). - `provisioning_uri(name, issuer_name, **kwargs)`: Generate otpauth:// URI. - `timecode(for_time)`: Convert datetime to timecode. ```