Python SDK
Official Python SDK for Apploi’s Partner API can be found at https://pypi.org/project/apploi-partner-api/
Overview
A production-ready Python client for the Apploi Partner API. It provides native Python types via dataclasses, input validation before requests, pagination utilities, and structured exceptions for reliable, testable integrations.
- Use when building Python services or scripts that integrate with Apploi to read or sync applicants, jobs, and related entities.
- Wraps the generated SDK with a higher-level, safer API and sensible defaults.
Installation
pip install apploi-partner-apiQuick Start
from apploi_partner_api import ApploiClient
from datetime import date
# Initialize client
client = ApploiClient(api_key="your-api-key")
# Get job applications with native Python types
job_applications = client.get_job_applications(
job_id=12345,
updated_after=date(2024, 1, 1),
limit=50
)
# Work with strongly-typed results
for application in job_applications:
print(f"{application.candidate.name} - {application.status.value}")
print(f" Email: {application.email}")
print(f" Applied: {application.applied_at}")
print(f" Job: {application.job.name}")Key Features
🎯 Simple Integration
- Single pip install - no complex setup required
- Works with Python 3.7+ across all major platforms
- Minimal dependencies for easy deployment
🔧 Native Python Experience
- Use native Python types: int, date, datetime, bool
- Automatic type conversion and validation
- Pythonic method names and parameter handling
- No need to manually format dates or convert integers to strings
🛡️ Robust Error Handling
- Custom exception hierarchy for different error types
- Descriptive error messages with actionable guidance
- Automatic retry logic for transient network issues
- Proper handling of rate limits and API quotas
📊 Rich Data Models
- Structured dataclasses with full type annotations
- Nested models for complex data (Job, Candidate, Application)
- Convenient properties for common operations
- Access to both processed and raw API response data
🚀 Production Ready
- Comprehensive test coverage and validation
- Built-in pagination for large datasets
- Configurable timeouts and connection settings
- Thread-safe for concurrent usage
API Reference
Client Initialization
from adapters.python import ApploiClient
client = ApploiClient(
api_key="your-api-key", # Required
authorization="your-auth", # Required
base_url=None, # Optional, defaults to production
timeout=60 # Optional, request timeout in seconds
)get_job_applications()
Retrieve job applications with filtering and pagination.
applicants = client.get_job_applications(
state="applied", # Filter by status
query="engineer", # Search query
limit=50, # Max results (1-1000)
team_id=123, # Team ID (int or str)
updated_before=datetime.now(), # Before date
offset=0, # Pagination offset
job_id=456, # Job ID (int or str)
updated_after=date(2024, 1, 1) # After date
)Parameters:
- All parameters are optional
- IDs accept
intorstr - Dates accept
date,datetime, or ISO string - Limit must be 1-1000
- Offset must be ≥ 0
Returns: ApplicantsList with:
items: List ofJobApplicationobjectstotal: Total count availablelimit: Page sizeoffset: Current offsethas_more: Boolean for more pages
Domain Models
JobApplication
@dataclass
class JobApplication:
# Identifiers
id: int # Application ID
candidate_id: int # Candidate ID
job_id: int # Job ID
# Required fields
status: ApplicationStatus # Application status
job: Job # Job details (nested)
candidate: Candidate # Candidate details (nested)
email: str # Applicant email
applicant_state: str # Current state
applicant_state_id: int # State ID
# DateTime/State Management
date_current_state_assigned: Optional[datetime]
previous_applicant_state: Optional[str]
previous_applicant_state_id: Optional[int]
date_previous_state_assigned: Optional[datetime]
applicant_updated: Optional[datetime]
date_created: Optional[datetime]
application_source: Optional[str]
# Optional fields
first_name: Optional[str]
last_name: Optional[str]
phone: Optional[str]
applied_at: Optional[datetime]
updated_at: Optional[datetime]
team_id: Optional[int]
@property
def name(self) -> str:
"""Full name (first + last)"""Job
@dataclass
class Job:
id: Optional[int]
name: Optional[str] # Job title
archived: Optional[bool] # Is archived
archived_date: Optional[datetime]
address: Optional[str] # Job location
source: Optional[str] # Job source
brand_name: Optional[str] # Company brand
job_code: Optional[str] # Internal job code
creator_id: Optional[int] # Creator ID
team_id: Optional[int] # Team ID
team_name: Optional[str] # Team name
role_type: Optional[str] # Role type
longitude: Optional[float] # Geo coordinates
latitude: Optional[float]Candidate
@dataclass
class Candidate:
id: int # Candidate ID
first_name: Optional[str]
last_name: Optional[str]
email: Optional[str]
home_phone_number: Optional[str]
mobile_phone_number: Optional[str]
city: Optional[str]
state: Optional[str]
country: Optional[str]
address: Optional[str]
zip_code: Optional[str]
@property
def name(self) -> str:
"""Full name (first + last)"""
@property
def phone(self) -> Optional[str]:
"""Primary phone (mobile or home)"""ApplicationStatus
class ApplicationStatus(Enum):
APPLIED = "applied"
SCREENING = "screening"
INTERVIEWING = "interviewing"
REFERENCE_CHECK = "reference_check"
OFFER_EXTENDED = "offer_extended"
HIRED = "hired"
REJECTED = "rejected"
WITHDRAWN = "withdrawn"
ON_HOLD = "on_hold"
UNKNOWN = "unknown" # Fallback for unrecognized valuesNote: The enum supports legacy values "interview" and "offer" for backwards compatibility, automatically mapping them to INTERVIEWING and OFFER_EXTENDED respectively.
Error Handling
from apploi_partner_api import (
ApploiValidationError,
ApploiAuthenticationError,
ApploiAPIError
)
try:
job_applications = client.get_job_applications(limit=50)
except ApploiValidationError as e:
# Invalid parameters (e.g., limit > 1000)
print(f"Validation error: {e}")
except ApploiAuthenticationError as e:
# 401/403 errors
print(f"Auth failed: {e}")
except ApploiAPIError as e:
# Other API errors
print(f"API error: {e}")
if e.status_code == 429:
# Handle rate limiting
time.sleep(60)Usage Examples
Basic Usage
# Get all job applications
all_job_applications = client.get_job_applications()
print(f"Found {len(all_job_applications)} job applications")Filtering
# Filter with native types
filtered_job_applications = client.get_job_applications(
job_id=12345, # Integer
team_id=789, # Integer
updated_after=date(2024, 1, 1), # Date object
state="applied", # String
limit=50 # Integer
)Pagination
# Paginate through all results
all_results = []
offset = 0
page_size = 50
while True:
page = client.get_job_applications(
limit=page_size,
offset=offset
)
all_results.extend(page.items)
if not page.has_more:
break
offset += page_size
print(f"Total fetched: {len(all_results)}")Working with Results
job_applications = client.get_job_applications(limit=1)
if job_applications:
application = job_applications[0]
# Strongly typed fields
print(f"ID: {application.id}")
print(f"Name: {application.candidate.name}")
print(f"Status: {application.status.value}")
# Date handling
if application.applied_at:
days_ago = (datetime.now() - application.applied_at).days
print(f"Applied {days_ago} days ago")
# Access raw data if needed
raw = application.raw_dataTesting
# Run all tests
pytest tests/
# Run specific test file
pytest tests/test_client.py -v
# Run with coverage
pytest tests/ --cov=adapters.python
# Integration tests (requires credentials)
export APPLOI_API_KEY="your-key"
export APPLOI_AUTHORIZATION="your-auth"
pytest tests/integration/ -m integrationRequirements
- Python 3.7+
- httpx (for Fern SDK)
- python-dateutil (optional, for date parsing)
Updated 6 days ago
What’s Next
