Official Python SDK for DocWal API - Issue and manage verifiable digital credentials
Project description
DocWal Python SDK
Official Python SDK for DocWal API - Issue and manage verifiable digital credentials.
Installation
pip install docwal
Quick Start
from docwal import DocWalClient
# Initialize client with your API key
client = DocWalClient(api_key="docwal_live_xxxxx")
# Issue a credential
result = client.credentials.issue(
template_id="template-123",
individual_email="student@example.com",
credential_data={
"student_name": "John Doe",
"degree": "Bachelor of Science",
"major": "Computer Science",
"graduation_date": "2024-05-15",
"gpa": "3.8"
}
)
print(f"Credential issued! Doc ID: {result['doc_id']}")
print(f"Claim token: {result['claim_token']}")
Authentication
Get your API key from your DocWal dashboard:
- Login to https://docwal.com
- Navigate to Settings → API Keys
- Click "Generate API Key"
- Copy and store securely
Requirements:
- Pilot tier or above
- Owner or Admin role
Environment Configuration
# Production (default)
client = DocWalClient(api_key="docwal_live_xxxxx")
# Staging
client = DocWalClient(
api_key="docwal_test_xxxxx",
base_url="https://sandbox.docwal.com/api"
)
# Custom timeout
client = DocWalClient(
api_key="docwal_live_xxxxx",
timeout=60 # seconds
)
Usage Examples
Issue Single Credential
# Basic credential
result = client.credentials.issue(
template_id="template-123",
individual_email="student@example.com",
credential_data={
"student_name": "John Doe",
"degree": "Bachelor of Science",
"graduation_date": "2024-05-15"
}
)
# With PDF attachment
with open("certificate.pdf", "rb") as f:
result = client.credentials.issue(
template_id="template-123",
individual_email="student@example.com",
credential_data={"student_name": "John Doe"},
document_file=f,
claim_token_expires_hours=168 # 7 days
)
Batch Issue Credentials
credentials_list = [
{
"individual_email": "student1@example.com",
"credential_data": {
"student_name": "Alice Smith",
"degree": "Bachelor of Arts",
"graduation_date": "2024-05-15"
}
},
{
"individual_email": "student2@example.com",
"credential_data": {
"student_name": "Bob Johnson",
"degree": "Bachelor of Science",
"graduation_date": "2024-05-15"
}
}
]
result = client.credentials.batch_issue(
template_id="template-123",
credentials=credentials_list,
send_notifications=True
)
print(f"Success: {result['success_count']}/{result['total_rows']}")
Batch Upload with ZIP
# ZIP structure:
# batch_credentials.zip
# ├── credentials.csv
# └── documents/
# ├── student001.pdf
# ├── student002.pdf
# └── student003.pdf
with open("batch_credentials.zip", "rb") as f:
result = client.credentials.batch_upload(
template_id="template-123",
file=f,
send_notifications=True
)
print(f"Processed: {result['total_rows']}")
print(f"Success: {result['success_count']}")
print(f"Failed: {result['failure_count']}")
for item in result['results']:
if item['status'] == 'success':
print(f"Row {item['row']}: {item['doc_id']}")
else:
print(f"Row {item['row']}: {item['error']}")
List and Get Credentials
# List all credentials
credentials = client.credentials.list(limit=50, offset=0)
for cred in credentials:
print(f"{cred['doc_id']}: {cred['template_name']}")
# Get specific credential
credential = client.credentials.get("DOC123456")
print(f"Issued to: {credential['ownership']['individual_email']}")
print(f"Status: {'Claimed' if credential['ownership']['is_claimed'] else 'Pending'}")
Revoke Credential
result = client.credentials.revoke(
doc_id="DOC123456",
reason="Student expelled for academic misconduct"
)
print(result['message'])
Resend Claim Link
result = client.credentials.resend_claim_link(
doc_id="DOC123456",
claim_token_expires_hours=168 # 7 days
)
print(f"Sent to: {result['recipient_email']}")
print(f"Expires: {result['claim_token_expires']}")
Download Credential File
# Download PDF file
pdf_content = client.credentials.download("DOC123456")
with open("credential.pdf", "wb") as f:
f.write(pdf_content)
Template Management
# List templates
templates = client.templates.list()
# Get template
template = client.templates.get("template-123")
# Create template
template = client.templates.create(
name="Bachelor Degree Certificate",
description="Template for bachelor degree graduation certificates",
credential_type="certificate",
schema={
"student_name": {
"type": "string",
"required": True,
"label": "Student Name"
},
"degree": {
"type": "string",
"required": True,
"label": "Degree Program"
},
"graduation_date": {
"type": "date",
"required": True,
"label": "Graduation Date"
}
},
version="1.0"
)
# Update template
client.templates.update(
"template-123",
description="Updated description"
)
# Delete template (soft delete)
client.templates.delete("template-123")
API Key Management
# Generate new API key (Owner/Admin only)
result = client.api_keys.generate()
print(f"New API key: {result['api_key']}")
print("⚠️ Store securely - shown only once!")
# Get API key info
info = client.api_keys.info()
print(f"Masked key: {info['api_key_masked']}")
print(f"Created: {info['created_at']}")
print(f"Last used: {info['last_used_at']}")
# Regenerate API key
result = client.api_keys.regenerate()
print(f"New API key: {result['api_key']}")
# Revoke API key
client.api_keys.revoke()
Team Management
# List team members
team = client.team.list()
print(f"Active members: {team['stats']['active_members']}")
print(f"Pending invitations: {team['stats']['pending_invitations']}")
# Check email before inviting
check = client.team.check_email("newmember@university.edu")
if check['recommendation'] == 'add_directly':
print("User exists - can add directly")
elif check['recommendation'] == 'send_invitation':
print("User doesn't exist - must send invitation")
# Invite team member
result = client.team.invite(
email="newmember@university.edu",
role="issuer",
send_email=True
)
# Update member role
client.team.update_role(
member_id="member-123",
role="admin"
)
# Deactivate member
client.team.deactivate(
member_id="member-123",
reason="Employee on leave"
)
# Reactivate member
client.team.reactivate("member-123")
# Remove member permanently
client.team.remove("member-123")
Error Handling
from docwal import DocWalClient, DocWalError, AuthenticationError, ValidationError
client = DocWalClient(api_key="docwal_live_xxxxx")
try:
result = client.credentials.issue(
template_id="invalid-template",
individual_email="student@example.com",
credential_data={}
)
except AuthenticationError as e:
print(f"Authentication failed: {e}")
print("Check your API key")
except ValidationError as e:
print(f"Validation error: {e}")
print("Check required fields")
except DocWalError as e:
print(f"API error: {e}")
print(f"Status code: {e.status_code}")
Rate Limits
- Pilot: 500 requests/hour
- Standard: 1,000 requests/hour
- Enterprise: Unlimited
When rate limit is exceeded, RateLimitError is raised.
Support
- Email: support@docwal.com
- Documentation: https://docs.docwal.com
- API Reference: https://docwal.com/api/docs
- GitHub: https://github.com/docwal/docwal-python
License
MIT License - see LICENSE file for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file docwal-1.0.1.tar.gz.
File metadata
- Download URL: docwal-1.0.1.tar.gz
- Upload date:
- Size: 11.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8645a604c6dcc92037f6bbbfa0e8da0aca68893ec71138fa3e4ca596d5e51e49
|
|
| MD5 |
69dae815dada6d2f6c1a7f9c9ff8e26b
|
|
| BLAKE2b-256 |
44238e5479ca3271176317fb92bd6c75533795c9633bda31fc4828ef6e00695e
|
File details
Details for the file docwal-1.0.1-py3-none-any.whl.
File metadata
- Download URL: docwal-1.0.1-py3-none-any.whl
- Upload date:
- Size: 8.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
28724e7d1ff264cbb3521b1c8c1380b20b0c8384acf44b1517e31d0c99e6e524
|
|
| MD5 |
67a969cfa2dd99897af2b838f22fce61
|
|
| BLAKE2b-256 |
d1788b35c03e1b50ab17c7362c2d40549c33c3b6ef6905ed875c333ae417cba8
|