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 adapters.python import ApploiClient
from datetime import date
# Initialize client
client = ApploiClient(
api_key="your-api-key",
authorization="your-auth-token"
)
# Get job applications with native Python types
applicants = client.get_job_applications(
job_id=12345, # Pass int, not string!
updated_after=date(2024, 1, 1), # Pass date object!
limit=50 # Pass int, not string!
)
# Work with strongly-typed results
for applicant in applicants:
print(f"{applicant.name} - {applicant.status.value}")
print(f" Email: {applicant.email}")
print(f" Applied: {applicant.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 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:
applicant_id: str
job_id: str
status: ApplicationStatus
first_name: Optional[str]
last_name: Optional[str]
email: Optional[str]
phone: Optional[str]
applied_at: Optional[datetime]
updated_at: Optional[datetime]
team_id: Optional[str]
@property
def name(self) -> str:
"""Full name (first + last)"""
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 adapters.python import (
ApploiValidationError,
ApploiAuthenticationError,
ApploiAPIError
)
try:
applicants = 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 applicants
all_applicants = client.get_job_applications()
print(f"Found {len(all_applicants)} applicants")
Filtering
# Filter with native types
filtered = 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
result = client.get_job_applications(limit=1)
if result:
applicant = result[0]
# Strongly typed fields
print(f"ID: {applicant.applicant_id}")
print(f"Name: {applicant.name}")
print(f"Status: {applicant.status.value}")
# Date handling
if applicant.applied_at:
days_ago = (datetime.now() - applicant.applied_at).days
print(f"Applied {days_ago} days ago")
# Access raw data if needed
raw = applicant.raw_data
Testing
# 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 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]
Metadata
Release files for apploitech-apploi-client 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| apploitech_apploi_client-0.1.2.tar.gz | 5.1 MB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| apploitech_apploi_client-0.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 5.1 MB
Release files / apploitech_apploi_client-0.1.2.tar.gz
| Download URL | apploitech_apploi_client-0.1.2.tar.gz |
|---|---|
| Size | 5.1 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
80a952c3b13fffe801f3336843e048efe442969469ff71b3b6926a178bbf7bff
|
|
BLAKE2b-256 checksum How to use checksums |
4759b979bc44be0394021994a4481ebf7102d3505c452aa2558075b321daadf7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.3
|
Release files / apploitech_apploi_client-0.1.2-py3-none-any.whl
| Download URL | apploitech_apploi_client-0.1.2-py3-none-any.whl |
|---|---|
| Size | 30.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
8ca1a31ba2eaba19fd8701bd1cc924094bc3c4823698853a2575870d2a24b6b0
|
|
BLAKE2b-256 checksum How to use checksums |
667ff952f5911085ceccf184b14b0836771290c417430f90ef3acca8bf3767af
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.3
|
Security for apploitech-apploi-client 0.1.2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.