Python SDK
Integrate Perly churn prevention into your Python application with support for FastAPI and Django out of the box.
perly-pythonv1.0.05 minutes
Installation
pip install perly-pythonUsage
The Python SDK supports both FastAPI and Django. Choose the integration that matches your framework.
FastAPI
# main.py
import os
from fastapi import FastAPI
from perly import PerlyMiddleware
app = FastAPI()
app.add_middleware(
PerlyMiddleware,
api_key=os.environ["PERLY_API_KEY"],
resolver=resolve_user, # defined below
)Django
# settings.py
import os
MIDDLEWARE = [
"perly.django.PerlyMiddleware",
"django.middleware.security.SecurityMiddleware",
# ... other middleware
]
PERLY_API_KEY = os.environ["PERLY_API_KEY"]User Resolver
The resolver maps incoming requests to Perly users using the builder pattern. The Python SDK uses snake_case method names.
FastAPI Resolver
from perly import PerlyBuilder
async def resolve_user(request):
user = request.state.user
if not user:
return None
return (
PerlyBuilder()
.set_id(user.id)
.set_metadata({
"plan": user.plan,
"region": user.region,
"company_id": user.company_id,
})
.link_stripe_by_id(user.stripe_customer_id)
.link_hubspot_by_id(user.hubspot_contact_id)
.build()
)Django Resolver
# perly_resolver.py
from perly import PerlyBuilder
def resolve_user(request):
if not request.user.is_authenticated:
return None
return (
PerlyBuilder()
.set_id(str(request.user.pk))
.set_metadata({
"plan": request.user.profile.plan,
"region": request.user.profile.region,
})
.link_stripe_by_id(request.user.profile.stripe_customer_id)
.link_hubspot_by_id(request.user.profile.hubspot_contact_id)
.build()
)Point Django to the resolver in settings:
PERLY_USER_RESOLVER = "myapp.perly_resolver.resolve_user"Tracking Events
Use the Perly client to track customer events from anywhere in your application.
from perly import get_perly
perly = get_perly()
# In a route handler or service
await perly.track(user_id, "onboarding_completed")
await perly.track(user_id, "report_exported", {"format": "csv"})
await perly.track(user_id, "team_member_invited", {"email": email})
await perly.track(user_id, "feature_activated", {"feature": "advanced_analytics"})Expansion Signals
Send signals when a customer approaches or hits usage limits to trigger expansion workflows in Perly.
from perly import get_perly
perly = get_perly()
await perly.signal(user_id, "seat_limit_near", {"current": 48, "limit": 50})
await perly.signal(user_id, "api_usage_high", {"current": 9500, "limit": 10000})
await perly.signal(user_id, "storage_limit_near", {"used_gb": 9.2, "limit_gb": 10})
await perly.signal(user_id, "token_usage_high", {"current": 950000, "limit": 1000000})
await perly.signal(user_id, "billing_retry_failed", {"attempt": 3})