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-python

Usage

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})