GitHub

Authentication

The auth namespace provides user authentication, registration, and API key management capabilities for secure access to the Functor platform.

Basic Operations

Register a New User

from functor_sdk import FunctorClient
client = FunctorClient()
# Register a new user
user = client.auth.register(
email="user@example.com",
password="secure_password_123",
name="John Doe"
)
print(f"User ID: {user['user_id']}")
print(f"Email: {user['email']}")
print(f"Token: {user['token']}")

Login a User

# Login with email and password
user = client.auth.login(
email="user@example.com",
password="secure_password_123"
)
print(f"Welcome back, {user['name']}")
print(f"Token: {user['token']}")
print(f"User ID: {user['user_id']}")

Create an API Key

# Create a new API key
key = client.auth.create_api_key(
name="Production Key",
scopes=["read", "write"]
)
print(f"API Key: {key['api_key']}")
print(f"Key ID: {key['key_id']}")
print(f"Scopes: {key['scopes']}")

List API Keys

# List all API keys for the authenticated user
keys = client.auth.list_api_keys()
for key in keys:
print(f"\nKey: {key['name']}")
print(f" ID: {key['key_id']}")
print(f" Created: {key['created_at']}")
print(f" Scopes: {key['scopes']}")

Delete an API Key

# Delete an API key by ID
response = client.auth.delete_api_key("key_abc123")
print(response.message) # "API key deleted successfully"

Complete Parameter Reference

register() Parameters

user = client.auth.register(
email="user@example.com", # Required: User email
password="secure_password", # Required: User password
name="John Doe" # Optional: User display name
)

login() Parameters

user = client.auth.login(
email="user@example.com", # Required: User email
password="secure_password" # Required: User password
)

create_api_key() Parameters

key = client.auth.create_api_key(
name="Production Key", # Required: Key name/description
scopes=["read", "write"] # Optional: Permission scopes
)

list_api_keys() Parameters

keys = client.auth.list_api_keys()
# No parameters required

delete_api_key() Parameters

response = client.auth.delete_api_key(
key_id="key_abc123" # Required: Key ID to delete
)

Available Scopes

The following permission scopes are available for API keys:

  • read - Read access to resources
  • write - Write access to resources
  • admin - Administrative privileges
  • analytics - Access to analytics and usage data
  • benchmarks - Permission to run benchmarks

Advanced Usage Patterns

User Registration Flow

from functor_sdk import FunctorClient, FunctorAPIError
def register_new_user(email, password, name):
"""Register a new user with error handling."""
client = FunctorClient()
try:
user = client.auth.register(
email=email,
password=password,
name=name
)
# Store token for future requests
return {
"success": True,
"user_id": user['user_id'],
"token": user['token'],
"message": f"Welcome, {user['name']}!"
}
except FunctorAPIError as e:
if e.status_code == 409:
return {
"success": False,
"error": "Email already registered"
}
else:
return {
"success": False,
"error": f"Registration failed: {e.message}"
}
# Usage
result = register_new_user(
email="newuser@example.com",
password="SecurePass123!",
name="Jane Smith"
)
if result["success"]:
print(result["message"])
# Store token securely
token = result["token"]
else:
print(f"Error: {result['error']}")

API Key Management

class APIKeyManager:
def __init__(self, client):
self.client = client
def create_key_with_expiry(self, name, scopes, days=365):
"""Create an API key with automatic expiry tracking."""
from datetime import datetime, timedelta
key = self.client.auth.create_api_key(
name=name,
scopes=scopes
)
# Track key locally with expiry
key_info = {
"key_id": key['key_id'],
"name": name,
"created_at": datetime.now().isoformat(),
"expires_at": (datetime.now() + timedelta(days=days)).isoformat(),
"scopes": scopes
}
return key_info
def rotate_api_key(self, old_key_id, name, scopes):
"""Rotate an API key by creating new and deleting old."""
# Create new key
new_key = self.client.auth.create_api_key(
name=f"{name} (Rotated)",
scopes=scopes
)
# Delete old key
self.client.auth.delete_api_key(old_key_id)
return new_key
def audit_keys(self):
"""Audit all API keys and check for issues."""
keys = self.client.auth.list_api_keys()
audit_report = {
"total_keys": len(keys),
"keys_by_scope": {},
"warnings": []
}
for key in keys:
# Count by scope
scope_str = ",".join(sorted(key['scopes']))
audit_report["keys_by_scope"][scope_str] = \
audit_report["keys_by_scope"].get(scope_str, 0) + 1
# Check for admin scope
if "admin" in key['scopes']:
audit_report["warnings"].append(
f"Key '{key['name']}' has admin scope"
)
return audit_report
# Usage
client = FunctorClient(token="user-token")
manager = APIKeyManager(client)
# Create key with expiry
key_info = manager.create_key_with_expiry(
name="Production API",
scopes=["read", "write"],
days=90
)
# Audit keys
audit = manager.audit_keys()
print(f"Total keys: {audit['total_keys']}")
print(f"Warnings: {audit['warnings']}")

Secure Authentication Flow

import os
from getpass import getpass
from functor_sdk import FunctorClient
class SecureAuthFlow:
def __init__(self):
self.client = None
self.token = None
def login_interactive(self):
"""Interactive login with password masking."""
email = input("Email: ")
password = getpass("Password: ") # Masks password input
try:
client = FunctorClient()
user = client.auth.login(email=email, password=password)
self.token = user['token']
self.client = FunctorClient(token=self.token)
print(f"\nWelcome, {user['name']}!")
return True
except Exception as e:
print(f"\nLogin failed: {e}")
return False
def save_token_securely(self, filepath=".functor_token"):
"""Save token to a secure file."""
if self.token:
with open(filepath, 'w') as f:
f.write(self.token)
# Set file permissions (Unix/Linux only)
os.chmod(filepath, 0o600)
print(f"Token saved to {filepath}")
def load_token(self, filepath=".functor_token"):
"""Load token from file."""
try:
with open(filepath, 'r') as f:
self.token = f.read().strip()
self.client = FunctorClient(token=self.token)
return True
except FileNotFoundError:
return False
def logout(self):
"""Logout and clear token."""
self.token = None
self.client = None
print("Logged out successfully")
# Usage
auth = SecureAuthFlow()
# Try to load existing token
if not auth.load_token():
# If no token, prompt for login
if auth.login_interactive():
auth.save_token_securely()
# Now use the authenticated client
if auth.client:
# Make authenticated requests
health = auth.client.health.check()
print(f"System status: {health['status']}")

Async Authentication

import asyncio
from functor_sdk import FunctorClient
async def async_auth_operations():
"""Perform authentication operations asynchronously."""
async with FunctorClient() as client:
# Login
user = await client.auth.login_async(
email="user@example.com",
password="password123"
)
print(f"Logged in as: {user['name']}")
# Create authenticated client with token
async with FunctorClient(token=user['token']) as auth_client:
# List keys concurrently
keys_task = auth_client.auth.list_api_keys_async()
# Create new key concurrently
new_key_task = auth_client.auth.create_api_key_async(
name="Async Key",
scopes=["read"]
)
keys, new_key = await asyncio.gather(
keys_task,
new_key_task
)
print(f"Existing keys: {len(keys)}")
print(f"New key created: {new_key['key_id']}")
# Usage
asyncio.run(async_auth_operations())

Security Best Practices

  • Never hardcode credentials: Use environment variables or secure vaults for API keys and tokens
  • Use scoped API keys: Grant only the minimum necessary permissions
  • Rotate keys regularly: Replace API keys periodically for security
  • Store tokens securely: Use secure file permissions (0600) on token files
  • Use HTTPS only: Never transmit credentials over unencrypted connections
  • Implement logout: Clear tokens when users log out

Next Steps