Leanbase Help Center

Your Guide to Building Products Customers Love

Install Python SDK

The Leanbase Python SDK makes it easy to capture events and track errors in your Python apps.


Installation


Configuration

In your app, import the leanbase library and set your project API key and host before making any calls.

Note: As a rule of thumb, we do not recommend having API keys in plaintext. Setting it as an environment variable is best.

You can find your project API key and instance address in the project setting page in Leanbase.

To debug, you can toggle debug mode:

To make sure no calls happen during tests, you can disable PostHog, like so:


Capturing events

Send custom events using capture:

Tip: We recommend using a [object] [verb] format for your event names, where [object] is the entity that the behavior relates to, and [verb] is the behavior itself. For example, project created, user signed up, or invite sent.


Setting event properties

Optionally, you can include additional information with the event by including a properties object:


Sending page views

If you're aiming for a backend-only implementation of PostHog and won't be capturing events from your frontend, you can send pageviews from your backend like so:


Person profiles and properties

The Python SDK captures identified events if the current context is identified or if you pass a distinct ID explicitly. These create person profiles. To set person properties in these profiles, include them when capturing an event:

To capture anonymous events without person profiles, set the event's $process_person_profile property to False. Events captured with no context or explicit distinct_id are marked as personless, and will have an auto-generated distinct_id:


Alias

To associate multiple distinct IDs with the same user:


Contexts

Contexts manage shared state (like user ID or session ID) across events. You can enter a context using the with statement:

Contexts are persisted across function calls. If you enter one and then call a function and capture an event in the called function, it uses the context tags and session ID set in the parent context:

Contexts are nested, so tags added to a parent context are inherited by child contexts. If you set the same tag in both a parent and child context, the child context's value overrides the parent's at event capture (but the parent context won't be affected). This nesting also applies to session IDs and distinct IDs.

You can disable this nesting behavior by passing fresh=True to new_context:

Note: Distinct IDs, session IDs, and properties passed directly to calls to capture and related functions override context state in the final event captured.


Contexts and user identification

Contexts can be associated with a distinct ID by calling posthog.identify_context:

Within a context associated with a distinct ID, all events captured are associated with that user. You can override the distinct ID for a specific event by passing a distinct_id argument to capture:

It's recommended to pass the currently active distinct ID from the frontend to the backend, using the X-POSTHOG-DISTINCT-ID header. If you're using our Django middleware, this is extracted and associated with the request handler context automatically.

Contexts and sessions

Contexts can be associated with a session ID by calling posthog.set_context_session. Session IDs must be UUIDv7 strings.

f you're using the Leanbase JavaScript Web SDK on your frontend, it generates a session ID for you and you can retrieve it by calling Leanbase.get_session_id(). You then need to pass that session ID to your backend by setting the X-Leanbase-SESSION-ID header on each fetch request. Alternatively, you can enable '__add_tracing_headers' in your config and the header is set automatically.

You need to extract the header in your request handler (if you're using our Django middleware integration, this happens automatically).

If you associate a context with a session, you'll be able to do things like:

  • See backend events on the session timeline when viewing session replays

  • View session replays for users that triggered a backend exception in error tracking

Exception capture

By default exceptions raised within a context are captured and available in the error tracking dashboard. You can override this behavior by passing capture_exceptions=False to new_context:

Decorating functions

The SDK exposes a function decorator. It takes the same arguments as new_context and provides a handy way to mark a whole function as being in a new context. For example:

GeoIP properties

As of leanbase-python v3.0, GeoIP properties are not added by default to avoid using your server’s IP address.
You can go back to previous behaviour by doing setting the disable_geoip argument in your initialization to False:

The list of properties that this overrides:

  1. $geoip_city_name

  2. $geoip_country_name

  3. $geoip_country_code

  4. $geoip_continent_name

  5. $geoip_continent_code

  6. $geoip_postal_code

  7. $geoip_time_zone

You can also explicitly chose to enable or disable GeoIP for a single capture request like so:


Historical migrations

You can use the Leanbase Python SDK to migrate historical data. To do so, set the historical_migration option to true when initializing the client:


Serverless environments (Render, Lambda, etc.)

By default, the library buffers events before sending them to the capture endpoint, for better performance. This can lead to lost events in serverless environments, if the Python process is terminated by the platform before the buffer is fully flushed. To avoid this, you can either:

  • Ensure that leanbase.shutdown() is called after processing every request by adding a middleware to your server. This allows leanbase.capture() to remain asynchronous for better performance. leanbase.shutdown() is blocking.

  • Enable the sync_mode option when initializing the client, so that all calls to leanbase.capture() become synchronous.


Alternative package name

As our open source project Leanbase shares the same module name, we created a special leanbaseanalytics package, mostly for internal use to avoid module collision. It is the exact same.