Skip to main content

Flagsmith's common library

Project description

flagsmith-common

Coverage

Flagsmith's common library

Local development

The project assumes the following tools installed:

To list available Makefile targets, run make help.

To set up local development environment, run make install.

To run linters, run make lint.

To run tests, run make test.

Usage

Installation

  1. Install all runtime packages: uv add flagsmith-common[common-core,task-processor]

  2. To enable the Pytest fixtures, run uv add --G dev flagsmith-common[test-tools]. Skipping this step will make Pytest collection fail due to missing dependencies.

  3. Make sure "common.core" is in the INSTALLED_APPS of your settings module. This enables the manage.py flagsmith commands.

  4. Add "common.gunicorn.middleware.RouteLoggerMiddleware" to MIDDLEWARE in your settings module. This enables the route label for Prometheus HTTP metrics.

  5. To enable the /metrics endpoint, set the PROMETHEUS_ENABLED setting to True.

Pre-commit hooks

This repo provides a flagsmith-lint-tests hook that enforces test conventions:

  • FT001: No module-level Test* classes — use function-based tests
  • FT002: No import unittest / from unittest import TestCase — use pytest (unittest.mock is fine)
  • FT003: Test names must follow test_{subject}__{condition}__{expected}
  • FT004: Test bodies must contain # Given, # When, and # Then comments

To use in your repo, add to .pre-commit-config.yaml:

- repo: https://github.com/Flagsmith/flagsmith-common
  rev: main
  hooks:
    - id: flagsmith-lint-tests

Use # noqa: FT003 (or any code) inline to suppress individual violations.

Test tools

Fixtures

assert_metric

To test your metrics using the assert_metric fixture:

from common.test_tools import AssertMetricFixture

def test_my_code__expected_metrics(assert_metric: AssertMetricFixture) -> None:
    # When
    my_code()

    # Then
    assert_metric(
        name="flagsmith_distance_from_earth_au_sum",
        labels={"engine_type": "solar_sail"},
        value=1.0,
    )
saas_mode

The saas_mode fixture makes all common.core.utils.is_saas calls return True.

enterprise_mode

The enterprise_mode fixture makes all common.core.utils.is_enterprise calls return True.

Markers

pytest.mark.saas_mode

Use this mark to auto-use the saas_mode fixture.

pytest.mark.enterprise_mode

Use this mark to auto-use the enterprise_mode fixture.

OpenTelemetry

Flagsmith supports exporting traces and structured logs over OTLP.

Configuration

OTel instrumentation is opt-in, controlled by environment variables:

Variable Description Default
OTEL_EXPORTER_OTLP_ENDPOINT Base OTLP endpoint (e.g. http://collector:4318). If unset, no OTel setup occurs. (disabled)
OTEL_SERVICE_NAME The service.name resource attribute. Defaults to flagsmith-task-processor when running the task processor. flagsmith-api
OTEL_TRACING_EXCLUDED_URL_PATHS Comma-separated URL paths to exclude from tracing (e.g. health/liveness,health/readiness). (none)

Standard OTEL_* env vars (e.g. OTEL_RESOURCE_ATTRIBUTES, OTEL_EXPORTER_OTLP_HEADERS) are also respected by the OTel SDK.

What gets configured

When OTEL_EXPORTER_OTLP_ENDPOINT is set, ensure_cli_env() sets up:

  • Tracing: TracerProvider with OTLP/HTTP span export, W3C TraceContext + Baggage propagation, and auto-instrumentation for:
    • Django (DjangoInstrumentor): creates a root span per HTTP request with span names formatted as {METHOD} {route_template} (e.g. GET /api/v1/projects/{pk}/).
    • psycopg2 (Psycopg2Instrumentor): creates child spans for each SQL query with db.system, db.statement, and db.name attributes. SQL commenter is enabled, adding trace context as SQL comments for database-side correlation.
    • Redis (RedisInstrumentor): creates child spans for each Redis command with db.system and db.statement attributes.
  • Structured log export: A structlog processor that emits each log event as both an OTLP log record and a span event (when an active span exists).
  • Task processor trace propagation: When a task is enqueued via TaskHandler.delay(), the current W3C trace context (including baggage) is serialized into the task's trace_context field. When the task processor executes the task, the context is extracted and a child span is created, linking the task execution back to the originating request trace. Span attributes (task_identifier, task_type, result) match the Prometheus metric labels for cross-signal correlation.

Emitting OTel log events via structlog

Use structlog as usual. The OTel processor captures events and maps them to OTLP log records:

import structlog

log = structlog.get_logger("code_references")
log.info("scan-created", code_references__count=3, feature__count=2)

This produces:

  1. An OTLP log record with:

    • Body: scan-created
    • EventName: code_references.scan_created (logger name + inflection.underscore of the event)
    • Severity: INFO
    • Attributes: code_references.count=3, feature.count=2 (double underscores are converted to dots)
    • W3C Baggage entries from the current OTel context are copied into log attributes (e.g. amplitude.device_id, amplitude.session_id).
  2. A span event on the active span (if one exists) with the same name and attributes. This makes structlog events visible in trace backends (e.g. SigNoz's "Events" tab) without requiring separate log correlation. When no span is active (e.g. during startup or management commands), only the OTLP log record is emitted.

Metrics

Flagsmith uses Prometheus to track performance metrics.

The following default metrics are exposed:

Common metrics

  • flagsmith_build_info: Has the labels version and ci_commit_sha.
  • flagsmith_http_server_request_duration_seconds: Histogram labeled with method, route, and response_status.
  • flagsmith_http_server_requests_total: Counter labeled with method, route, and response_status.
  • flagsmith_http_server_response_size_bytes: Histogram labeled with method, route, and response_status.
  • flagsmith_task_processor_enqueued_tasks_total: Counter labeled with task_identifier.

Task Processor metrics

  • flagsmith_task_processor_finished_tasks_total: Counter labeled with task_identifier, task_type ("recurring", "standard") and result ("success", "failure").
  • flagsmith_task_processor_task_duration_seconds: Histogram labeled with task_identifier, task_type ("recurring", "standard") and result ("success", "failure").

Guidelines

Try to come up with meaningful metrics to cover your feature with when developing it. Refer to Prometheus best practices when naming your metric and labels.

As a reasonable default, Flagsmith metrics are expected to be namespaced with the "flagsmith_" prefix.

Define your metrics in a metrics.py module of your Django application — see example. Contrary to Prometheus Python client examples and documentation, please name a metric variable exactly as your metric name.

It's generally a good idea to allow users to define histogram buckets of their own. Flagsmith accepts a PROMETHEUS_HISTOGRAM_BUCKETS setting so users can customise their buckets. To honour the setting, use the common.prometheus.Histogram class when defining your histograms. When using prometheus_client.Histogram directly, please expose a dedicated setting like so:

import prometheus_client
from django.conf import settings

flagsmith_distance_from_earth_au = prometheus_client.Histogram(
    "flagsmith_distance_from_earth_au",
    "Distance from Earth in astronomical units",
    labels=["engine_type"],
    buckets=settings.DISTANCE_FROM_EARTH_AU_HISTOGRAM_BUCKETS,
)

For testing your metrics, refer to assert_metric documentation.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

flagsmith_common-3.10.0.tar.gz (59.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

flagsmith_common-3.10.0-py3-none-any.whl (96.8 kB view details)

Uploaded Python 3

File details

Details for the file flagsmith_common-3.10.0.tar.gz.

File metadata

  • Download URL: flagsmith_common-3.10.0.tar.gz
  • Upload date:
  • Size: 59.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for flagsmith_common-3.10.0.tar.gz
Algorithm Hash digest
SHA256 a3dfca3b6c1770c8fb32d7650024a83810a0aa0b8c521117e9d81828563124fc
MD5 cafa3ca7534ff4fe66d4acf46e09dc86
BLAKE2b-256 4214b22f1ab8f19c51bd1d7c8ce571ccb411d8f89958b47e71b1ccac6e4ca943

See more details on using hashes here.

Provenance

The following attestation bundles were made for flagsmith_common-3.10.0.tar.gz:

Publisher: publish.yml on Flagsmith/flagsmith-common

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file flagsmith_common-3.10.0-py3-none-any.whl.

File metadata

File hashes

Hashes for flagsmith_common-3.10.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0a08d2d17f70b576bb6580a8dcd448f0566e3fb979d789b9270279ff2081a00a
MD5 9fe87c7105b5b75a6307f2a340e26ddf
BLAKE2b-256 34bd4a0a3dd3b293528c0fd5447eb10566d6e892133d6b751594a4e16f3f51f3

See more details on using hashes here.

Provenance

The following attestation bundles were made for flagsmith_common-3.10.0-py3-none-any.whl:

Publisher: publish.yml on Flagsmith/flagsmith-common

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page