Official Python client for Apploi Partner API with high-level abstractions
Project description
Python Adapter for Apploi Partner API
A clean, type-safe Python adapter that wraps the Fern-generated SDK with better abstractions, validation, and error handling.
Installation
# Install dependencies
pip install httpx python-dateutil
# Or install all requirements
pip install -r requirements.txt
Quick 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.name} - {application.status.value}")
print(f" Email: {application.email}")
print(f" Applied: {application.applied_at}")
💡 See
example_usage.pyfor comprehensive usage examples including pagination, error handling, and comparisons with the raw SDK.
Features
- ✅ Native Python Types: Use
int,date,datetimeinstead of strings - ✅ Type Safety: Dataclasses with proper type hints
- ✅ Validation: Parameters validated before API calls
- ✅ Error Handling: Custom exception hierarchy
- ✅ IDE Support: Full autocomplete and type checking
API Reference
Client Initialization
from apploi_partner_api import ApploiClient
client = ApploiClient(
api_key="your-api-key", # 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.
job_applications = client.get_job_applications(
state="applied", # Filter by status
query="Smith", # Search query filters by name, phone number, or email
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: JobApplicationsList 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 values
Note: 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_data
Testing
# Run all tests
pytest tests/
# Run specific test file
pytest tests/test_client.py -v
# Run with coverage
pytest tests/ --cov=apploi_partner_api
# Integration tests (requires credentials)
export APPLOI_API_KEY=\"your-key\"
export APPLOI_AUTHORIZATION=\"your-auth\"
pytest tests/integration/ -m integration
Project Structure
python/
├── __init__.py # Package initialization
├── client.py # Main ApploiClient class
├── exceptions.py # Custom exceptions
├── models/
│ ├── __init__.py
│ ├── job_application.py # JobApplication, JobApplicationsList
│ └── common.py # Shared models
├── validators/
│ ├── __init__.py
│ ├── dates.py # Date validation/parsing
│ └── parameters.py # Parameter validation
├── example_usage.py # Usage examples
├── requirements.txt # Dependencies
└── README.md # This file
Requirements
- Python 3.7+
- httpx (for Fern SDK)
- python-dateutil (optional, for date parsing)
Differences from Raw SDK
Without Adapter (Fern SDK)
# Everything must be strings
sdk.applicants.get_applicants(
job_id="12345",
limit="50",
updated_after="2024-01-01"
) # Returns: Dict[str, Any]
With Adapter
# Native Python types
client.get_job_applications(
job_id=12345,
limit=50,
updated_after=date(2024, 1, 1)
) # Returns: ApplicantsList (typed)
Architecture
See ARCHITECTURE.md for detailed design documentation.
Contributing
- Follow existing patterns
- Add tests for new features
- Update type hints
- Run tests before submitting
License
[Your License Here]
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 apploi_partner_api-0.1.7.tar.gz.
File metadata
- Download URL: apploi_partner_api-0.1.7.tar.gz
- Upload date:
- Size: 5.1 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c33f25af5bcd9eb576d9a12410001bec8d8fbdee88dae85e8267e87110443d67
|
|
| MD5 |
6aa218af2d3ce2f9e05283769868f0bb
|
|
| BLAKE2b-256 |
9e89dbad1a1e9fdb94dd7e6d9228ba5aa8d1087568e8cd3e560b21d10eec7e55
|
File details
Details for the file apploi_partner_api-0.1.7-py3-none-any.whl.
File metadata
- Download URL: apploi_partner_api-0.1.7-py3-none-any.whl
- Upload date:
- Size: 31.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
78e3bb6b13fdf71cd0a19f4606ac39e55aa9cffa5dcdf574d06266dd052c60d3
|
|
| MD5 |
583a271ac1475bbea6737fde572d6fdc
|
|
| BLAKE2b-256 |
96ee38ed683d5314210082ff000bbb37582f8470c5f82877918a7149601dbc7a
|