Install & Compatibility
Where this runs
tested against v2.0.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
muslpy 3.10–3.910 runs
installs and imports cleanly · install 0.0s · import 0.000s · 17.9MB
glibcpy 3.10–3.910 runs
installs and imports cleanly · install 1.5s · import 0.000s · 18MB
16MB installed
● package 16MB
Code
Verified usage
Verified import paths — ran on the pinned version, not inferred.
Challenge
✓ from altcha import Challenge
✗ from altcha import Altcha
create_challenge
✓ from altcha import create_challenge
✗ from altcha import Altcha
verify_solution
✓ from altcha import verify_solution
✗ from altcha import Altcha
This quickstart demonstrates how to initialize the `Altcha` object with a secret key, generate a challenge to be sent to a client, and then verify a client's response. It includes a hardcoded example of a valid client response for successful verification, and an example of an invalid response for error handling. Remember to replace the placeholder secret key with a strong, random key in production.
import os
import time
from altcha import Altcha, ChallengeResult
# Initialize Altcha with your secret key
# IMPORTANT: Replace 'altcha-dev-secret-key...' with a strong, random, 32+ character key
# and set it via an environment variable in production (e.g., ALTCHA_SECRET_KEY).
secret_key = os.environ.get('ALTCHA_SECRET_KEY', 'altcha-dev-secret-key-1234567890abcdef')
if secret_key == 'altcha-dev-secret-key-1234567890abcdef':
print("WARNING: Using a default development secret key. Set ALTCHA_SECRET_KEY environment variable with a strong, random key in production!")
altcha = Altcha(secret_key)
# --- QUICKSTART PART 1: Generate a Challenge ---
print("\n--- Generating a Challenge ---")
# The 'challenge_obj' contains all necessary fields for the client.
challenge_obj = altcha.generate_challenge()
challenge_for_client = challenge_obj.to_json() # This JSON string is what you send to the client.
print(f"Generated Challenge (for client): {challenge_for_client}")
# In a real scenario, the client-side JavaScript library would solve this challenge
# and send back the original challenge data along with a computed 'response' string.
# --- QUICKSTART PART 2: Verify a Challenge Response ---
print("\n--- Verifying a Challenge Response ---")
# For demonstration, we'll use a hardcoded valid challenge/response pair.
# This 'solved_client_response' simulates what a client would send back after solving.
# The 'response' field comes from the client-side JS library's computation.
solved_client_response = {
"challenge": "b4e4d7730e6a8e8073b64c748c5a21e421e421e4",
"signature": "283738b52a16d8a39e99279a059c259687e35b7501a4e1d1f042657d47833072",
"algorithm": "sha1",
"salt": "altcha_salt",
"expire": int(time.time() + 3600), # Ensure expiry is in the future for verification.
"response": "sha1:1000:altcha_salt:s/h0QhQ2L2yYmYg5X2V5Q5R5R5Q5Y5h5y5Q5L2xY="
}
try:
verification_result: ChallengeResult = altcha.verify(solved_client_response)
if verification_result.verified:
print("✅ Challenge Verified Successfully!")
else:
print(f"❌ Challenge Verification Failed: {verification_result.error}")
# Common errors: 'challenge_expired', 'invalid_signature', 'incorrect_proof'
except ValueError as e:
print(f"❌ Verification Error (ValueError): {e}")
# --- QUICKSTART PART 3: Demonstrate an Invalid Response ---
print("\n--- Demonstrating an Invalid Response ---")
# An example where the challenge hash is intentionally wrong.
invalid_response_data = {
"challenge": "wrong_challenge_hash",
"signature": solved_client_response["signature"],
"algorithm": solved_client_response["algorithm"],
"salt": solved_client_response["salt"],
"expire": solved_client_response["expire"],
"response": solved_client_response["response"]
}
try:
invalid_result = altcha.verify(invalid_response_data)
if not invalid_result.verified:
print(f"✅ Invalid challenge handled correctly. Error: {invalid_result.error}")
else:
print("❌ Unexpected: Invalid challenge was verified.")
except ValueError as e:
print(f"✅ Invalid challenge handled correctly with ValueError: {e}")
Upgrade
Version history
2.0.0latest on PyPI · released Apr 7, 2026
Audit
Dependencies
No dependency data recorded yet.