Python SDK for MecaPy API - A clean, simple, and robust client library.
- π Keycloak Authentication - Full support for OAuth2/OIDC with automatic token refresh
- π Async/Await Support - Modern Python async programming
- π Type Hints - Full type safety with Pydantic models
- π‘οΈ Error Handling - Comprehensive exception handling
- π§ͺ Well Tested - Extensive test coverage
- π Environment Variables - Easy configuration management
pip install mecapy-sdk
from mecapy import MecaPyClient
# Simple usage with default authentication (auto-detection)
client = MecaPyClient()
# Get current user info
user = client.get_current_user()
print(f"Hello, {user.preferred_username}!")
# Upload a file
upload_result = client.upload_archive("my-archive.zip")
print(f"Uploaded: {upload_result.uploaded_filename}")
from mecapy import MecaPyClient, Auth
# Using service account token
auth = Auth.Token("your-long-lived-service-account-token")
client = MecaPyClient(auth=auth)
# Get current user info
user = client.get_current_user()
print(f"Authenticated as: {user.preferred_username}")
from mecapy import MecaPyClient
# Set environment variables:
# MECAPY_TOKEN=your-service-account-token # For token auth
#
# OR for OAuth2:
# MECAPY_USERNAME=your-username
# MECAPY_PASSWORD=your-password
#
# Optional overrides for on-premise:
# MECAPY_API_URL=https://your-api.company.com
# MECAPY_KEYCLOAK_URL=https://your-auth.company.com
# Create client - uses auto-detection
client = MecaPyClient()
# Check API health
health = client.health_check()
print(f"API Status: {health['status']}")
# Get API info
info = client.get_root()
print(f"API Version: {info.version}")
Variable | Description | Default |
---|---|---|
MECAPY_API_URL |
MecaPy API base URL | https://api.mecapy.com |
MECAPY_TOKEN |
Service account token | None (triggers auto-detection) |
MECAPY_KEYCLOAK_URL |
Keycloak server URL | https://auth.mecapy.com |
MECAPY_REALM |
Keycloak realm | mecapy |
MECAPY_CLIENT_ID |
Keycloak client ID | mecapy-api-public |
MECAPY_USERNAME |
Username for OAuth2 | None |
MECAPY_PASSWORD |
Password for OAuth2 | None |
MECAPY_TIMEOUT |
Request timeout (seconds) | 30.0 |
π― For most users: Set MECAPY_TOKEN
with your service account token for the simplest experience.
π For interactive use: Set MECAPY_USERNAME
and MECAPY_PASSWORD
for OAuth2 browser-based login.
π’ For on-premise installations: Override MECAPY_API_URL
and MECAPY_KEYCLOAK_URL
as needed.
Minimal .env file (token auth):
MECAPY_TOKEN=your-service-account-token
OAuth2 .env file:
MECAPY_USERNAME=your-username
MECAPY_PASSWORD=your-password
Complete .env file (on-premise):
MECAPY_API_URL=https://your-api.company.com
MECAPY_KEYCLOAK_URL=https://your-auth.company.com
MECAPY_REALM=mecapy
MECAPY_CLIENT_ID=mecapy-api-public
MECAPY_TOKEN=your-service-account-token
Then load it:
from dotenv import load_dotenv
from mecapy import MecaPyClient
load_dotenv()
client = MecaPyClient()
user = client.get_current_user()
print(f"Authenticated as: {user.preferred_username}")
get_current_user() -> UserInfo
- Get current user informationtest_protected_route() -> ProtectedResponse
- Test protected endpoint accesstest_admin_route() -> AdminResponse
- Test admin endpoint access (requires admin role)
upload_archive(file, filename=None) -> UploadResponse
- Upload ZIP archive
get_root() -> APIResponse
- Get API informationhealth_check() -> Dict[str, str]
- Check API health
Auth.Token(token: str)
- Create token-based authenticationAuth.ServiceAccount(client_id, client_secret)
- Create service account authenticationAuth.OAuth2()
- Create interactive OAuth2 authenticationAuth.Default()
- Create auto-detection authentication
MecaPyClient.from_env()
- Create client with auto-detectionMecaPyClient.from_token(token)
- Create client with token authentication
The SDK provides specific exception types for different error scenarios:
from mecapy import MecaPyClient
from mecapy.exceptions import (
AuthenticationError,
ValidationError,
NotFoundError,
ServerError,
NetworkError
)
client = MecaPyClient()
try:
user = client.get_current_user()
print(f"Hello, {user.preferred_username}!")
except AuthenticationError:
print("Authentication failed - check credentials")
except ValidationError as e:
print(f"Validation failed: {e.message}")
except NotFoundError:
print("Resource not found")
except ServerError as e:
print(f"Server error: {e.status_code}")
except NetworkError:
print("Network connection failed")
All API responses are validated using Pydantic models:
class UserInfo(BaseModel):
preferred_username: str
email: Optional[str] = None
given_name: Optional[str] = None
family_name: Optional[str] = None
roles: List[str] = []
class UploadResponse(BaseModel):
message: str
original_filename: str
uploaded_filename: str
md5: str
size: int
from pathlib import Path
from mecapy import MecaPyClient, Auth
# Using token authentication
auth = Auth.Token("your-service-account-token")
with MecaPyClient(auth=auth) as client:
# Upload from file path
result = client.upload_archive("data.zip")
print(f"File uploaded: {result.uploaded_filename}")
# Upload from Path object
file_path = Path("archive.zip")
result = client.upload_archive(file_path)
print(f"MD5: {result.md5}")
# Upload from file-like object
with open("data.zip", "rb") as f:
result = client.upload_archive(f, filename="data.zip")
print(f"Size: {result.size} bytes")
from mecapy import MecaPyClient, Auth
from mecapy.exceptions import AuthenticationError
# Using auto-detection (will try MECAPY_TOKEN, then OAuth2)
client = MecaPyClient()
# Get current user
user = client.get_current_user()
print(f"Username: {user.preferred_username}")
print(f"Email: {user.email}")
print(f"Roles: {', '.join(user.roles)}")
# Test role-based access
try:
admin_response = client.test_admin_route()
print("Admin access granted!")
except AuthenticationError:
print("Admin access denied")
from mecapy import MecaPyClient, Auth
# 1. Token authentication (simplest for CI/CD)
auth = Auth.Token("your-service-account-token")
client = MecaPyClient(auth=auth)
# 2. Service account with client credentials (automatic token refresh)
auth = Auth.ServiceAccount(
client_id="mecapy-sdk-service",
client_secret="your-client-secret"
)
client = MecaPyClient(auth=auth)
# 3. Interactive OAuth2 (browser-based login)
auth = Auth.OAuth2()
client = MecaPyClient(auth=auth) # Will open browser for login
# 4. Custom Keycloak configuration
auth = Auth.ServiceAccount(
client_id="custom-client",
client_secret="custom-secret",
keycloak_url="https://custom-auth.example.com",
realm="custom-realm"
)
client = MecaPyClient("https://api.example.com", auth=auth)
user = client.get_current_user()
print(f"Authenticated: {user.preferred_username}")
git clone https://github.com/mecapy/python-sdk.git
cd python-sdk
# Initialize development environment
task init
# Or manually with uv
uv sync --group dev
# Run unit tests
task test:unit
# Run all tests
task test
# Run interactive tests
task test:interactive
# Format code and fix linting
task format
# Run all quality checks (ruff + mypy)
task check
# Build package
task build
This project is licensed under the MIT License - see the LICENSE file for details.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
- π Documentation
- π Issue Tracker
- π¬ Discussions
Made with β€οΈ by the MecaPy team