Python ๐
The official Python client for the CardScan API provides a pythonic interface for all API operations.
Installation
pip install cardscan-client
Basic Usage
from cardscan_client import CardScanApi
from cardscan_client.exceptions import ApiException
# Initialize with your API key
api_key = "sk_test_cardscan_ai_..."
client = CardScanApi(api_key=api_key)
# Generate a session token for a user
token_response = client.get_access_token(user_id="unique-user-123")
session_token = token_response["Token"]
identity_id = token_response["IdentityId"]
session_id = token_response["session_id"]
# Initialize client with session token for frontend operations
user_client = CardScanApi(session_token=session_token, live=False)
Quick Start with full_scan
The easiest way to scan cards is using the full_scan
helper method that handles the entire workflow:
from cardscan_client import CardScanApi
# Initialize the client
client = CardScanApi(api_key="sk_test_cardscan_ai_...")
# Scan a card (front and back)
async def scan_card():
# Using file paths
result = await client.full_scan(
front_image="./front-card.jpg",
back_image="./back-card.jpg", # Optional - omit for front-only
user_id="unique-user-123"
)
# Or using file objects
with open("./front-card.jpg", "rb") as front:
with open("./back-card.jpg", "rb") as back:
result = await client.full_scan(
front_image=front,
back_image=back,
user_id="unique-user-123"
)
# Access the results
print(f"Card ID: {result['card_id']}")
print(f"Member ID: {result['details']['member_id']}")
print(f"Group: {result['details']['group_number']}")
print(f"Payer: {result['details']['payer_name']}")
return result
# Run the async function
import asyncio
result = asyncio.run(scan_card())
The full_scan
method automatically:
Generates a session token for the user
Creates a card with appropriate settings
Uploads images in the correct order
Polls for processing completion
Returns the completed card with all extracted data
Manual Card Scanning Workflow
For more control over the scanning process, you can use the step-by-step approach:
1. Create a Card
# Create a card with options
card = user_client.create_card(
enable_backside_scan=False,
enable_livescan=False,
metadata={
"patient_id": "12345",
"visit_id": "v-67890"
}
)
print(f"Card ID: {card['card_id']}")
print(f"State: {card['state']}") # 'pending'
2. Generate Upload URL
# Generate pre-signed upload URL
upload_data = user_client.generate_card_upload_url(
card_id=card["card_id"],
orientation="front",
capture_type="manual"
)
upload_url = upload_data["upload_url"]
upload_parameters = upload_data["upload_parameters"]
3. Upload Image
import requests
# Read image file
with open("insurance_card.jpg", "rb") as f:
files = {"file": f}
# Upload to S3 using pre-signed URL
response = requests.post(
upload_url,
data=upload_parameters,
files=files
)
response.raise_for_status()
4. Poll for Results
import time
def wait_for_completion(card_id, timeout=300):
"""Poll for card completion with timeout."""
start_time = time.time()
while time.time() - start_time < timeout:
card = user_client.get_card(card_id=card_id)
if card["state"] in ["completed", "error"]:
return card
time.sleep(2) # Wait 2 seconds between polls
raise TimeoutError(f"Card {card_id} did not complete within {timeout} seconds")
completed_card = wait_for_completion(card["card_id"])
print("Insurance Info:", completed_card.get("details"))
Error Handling
from cardscan_client.exceptions import ApiException
try:
card = client.get_card(card_id="invalid-id")
except ApiException as e:
print(f"API Error: {e.status} - {e.body}")
if e.status == 401:
print("Invalid API key or session token")
elif e.status == 404:
print("Card not found")
elif e.status == 429:
print("Rate limit exceeded")
Async Support
The client supports async operations using asyncio
:
import asyncio
from cardscan_client import AsyncCardScanApi
async def scan_card_async():
async_client = AsyncCardScanApi(api_key="sk_test_cardscan_ai_...")
# All methods are available as async versions
token_response = await async_client.get_access_token(
user_id="unique-user-123"
)
card = await async_client.create_card(
session_token=token_response["Token"],
enable_backside_scan=False
)
return card
# Run async function
card = asyncio.run(scan_card_async())
WebSocket Support
For real-time updates using WebSocket:
import websocket
import json
def on_message(ws, message):
data = json.loads(message)
if data["type"] == "card.processing":
print("Card processing started")
elif data["type"] == "card.completed":
print(f"Card completed: {data['card_id']}")
elif data["type"] == "card.error":
print(f"Card error: {data['error']}")
def on_error(ws, error):
print(f"WebSocket error: {error}")
# Connect to WebSocket
ws_url = f"wss://sandbox.cardscan.ai/v1/ws?token={session_token}"
ws = websocket.WebSocketApp(
ws_url,
on_message=on_message,
on_error=on_error
)
# Run in a separate thread
import threading
wst = threading.Thread(target=ws.run_forever)
wst.daemon = True
wst.start()
Eligibility Verification
# Create eligibility request
eligibility = client.create_eligibility(
card_id=completed_card["card_id"],
eligibility={
"provider": {
"first_name": "John",
"last_name": "Smith",
"npi": "1234567890"
},
"subscriber": {
"first_name": "Jane",
"last_name": "Smith",
"date_of_birth": "1980-01-01"
}
}
)
# Poll for eligibility results
eligibility_result = wait_for_eligibility_completion(
eligibility["eligibility_id"]
)
# Access eligibility information
if eligibility_result["state"] == "completed":
summary = eligibility_result["eligibility_summarized_response"]
print(f"Coverage Active: {summary['coverage_active']}")
print(f"Copay: ${summary['copay']}")
Batch Operations
Process multiple cards efficiently:
def process_cards_batch(image_paths):
"""Process multiple insurance cards in parallel."""
cards = []
# Create cards
for path in image_paths:
card = user_client.create_card(enable_backside_scan=False)
cards.append(card)
# Upload images in parallel
import concurrent.futures
with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
futures = []
for card, image_path in zip(cards, image_paths):
future = executor.submit(
upload_and_process_card,
card["card_id"],
image_path
)
futures.append(future)
# Wait for all uploads to complete
results = [f.result() for f in futures]
return results
Configuration Options
from cardscan_client import CardScanApi
# Custom configuration
client = CardScanApi(
api_key="sk_test_cardscan_ai_...",
base_url="https://sandbox.cardscan.ai/v1",
retries=3,
timeout=30,
verify_ssl=True
)
Type Hints
The client includes comprehensive type hints:
from typing import Dict, Optional
from cardscan_client.models import (
CardApiResponse,
CreateCardRequest,
EligibilityApiResponse
)
def process_card(card: CardApiResponse) -> Optional[Dict[str, str]]:
"""Extract key information from a completed card."""
if card.state == "completed" and card.details:
return {
"member_id": card.details.member_id,
"group_number": card.details.group_number,
"payer_name": card.details.payer_name
}
return None
Logging
Enable detailed logging for debugging:
import logging
# Enable debug logging
logging.basicConfig(level=logging.DEBUG)
# The client will now log all requests and responses
client = CardScanApi(api_key="sk_test_cardscan_ai_...")
Source Code
View the source code and contribute: GitHub
Last updated
Was this helpful?