All Integrations
Languagespip package

Flask Integration

Instrument Flask applications with one pip install. WSGI request tracing, SQLAlchemy query capture, Celery task monitoring, and Redis cache spans — zero configuration.

Setup

How It Works

01

Install the pip Package

Run pip install tigerops or add tigerops to requirements.txt. The package includes the opentelemetry-instrumentation-flask SDK, SQLAlchemy instrumentation, Celery task hooks, and OTLP exporters preconfigured for TigerOps endpoints.

02

Initialize Before app.run()

Call TigerOps.init_app(app) after creating your Flask application instance. For application factory patterns, call TigerOps.init_app(app) inside the factory function after all extensions are registered. Works with Flask-SQLAlchemy and Flask-Migrate.

03

Set Environment Variables

Set TIGEROPS_API_KEY, TIGEROPS_SERVICE_NAME, and TIGEROPS_ENVIRONMENT in your environment or .env file. Flask's config system is supported: app.config["TIGEROPS_API_KEY"] = os.environ["TIGEROPS_API_KEY"]. python-dotenv is compatible.

04

Traces, SQL & Celery Tasks Flow

Within seconds TigerOps receives Flask request spans with route rules and view function names, SQLAlchemy query spans with normalized SQL and row counts, Celery task execution spans, and Redis or Memcached cache operation traces.

Capabilities

What You Get Out of the Box

WSGI Request Tracing

Every Flask HTTP request creates a root span with URL rule, view function name, HTTP method, status code, and response time. Before-request and after-request hook execution times are captured as child spans. Works with Gunicorn and uWSGI.

SQLAlchemy Query Spans

All SQLAlchemy Core and ORM queries are instrumented. Each span includes normalized SQL text, database URL (sanitized), execution time, and row count. N+1 query patterns are detected and flagged in the TigerOps dashboard.

Celery Task Visibility

Celery task publish and worker execution create linked spans with trace context propagated through the broker. Task name, queue, retry count, execution time, and exception tracebacks are captured. Queue depth is reported as a metric.

Flask-RESTful & Flask-RESTX

Resource class method execution is auto-instrumented. Request parser validation time, marshalling duration, and namespace routing are captured as child spans. API versioning and blueprint prefixes appear in span route attributes.

Redis & Cache Instrumentation

Flask-Caching and direct redis-py operations are traced as child spans with command name, key pattern, and execution time. Cache hit/miss ratios are emitted as metrics. Redis pipeline batches appear as a single grouped span.

Error Tracking & Exception Spans

Unhandled exceptions in Flask views are captured with full Python traceback, request context (URL, method, user agent), and any active span attributes. HTTP 4xx and 5xx responses are tagged with error=true for quick filtering.

Configuration

Install & Initialize

One pip install and one init_app call. Full Flask observability.

terminal + app.py
# Install the TigerOps Flask package
pip install tigerops

# Set environment variables
export TIGEROPS_API_KEY="your-api-key"
export TIGEROPS_SERVICE_NAME="my-flask-app"
export TIGEROPS_ENVIRONMENT="production"

# app.py — application factory pattern
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from tigerops.contrib.flask import TigerOps

db = SQLAlchemy()
tigerops = TigerOps()

def create_app(config_name="production"):
    app = Flask(__name__)
    app.config["SQLALCHEMY_DATABASE_URI"] = os.environ["DATABASE_URL"]
    app.config["TIGEROPS_API_KEY"] = os.environ["TIGEROPS_API_KEY"]
    app.config["TIGEROPS_SERVICE_NAME"] = "my-flask-app"
    app.config["TIGEROPS_TRACE_CELERY"] = True
    app.config["TIGEROPS_TRACE_CACHE"] = True
    app.config["TIGEROPS_SLOW_QUERY_MS"] = 100

    db.init_app(app)
    tigerops.init_app(app)  # <-- add after all extensions

    from .api import api_bp
    app.register_blueprint(api_bp, url_prefix="/api/v1")
    return app

# Custom span in a view
from tigerops import span

@api_bp.route("/orders/<order_id>", methods=["GET"])
def get_order(order_id):
    with span("order.fetch") as s:
        s.set_attribute("order.id", order_id)
        order = Order.query.get_or_404(order_id)

    with span("order.enrich") as s:
        enriched = enrich_with_inventory(order)
        s.set_attribute("sku.count", len(enriched.items))

    return jsonify(enriched.to_dict())
FAQ

Common Questions

Which Flask and Python versions are supported?

Flask 2.x and 3.x are fully supported. Python 3.9, 3.10, 3.11, and 3.12 are supported. The package works with both synchronous WSGI Flask and async ASGI Flask via asgiref. Flask-SQLAlchemy 3.x and standalone SQLAlchemy 1.4+ and 2.x are both supported.

How does TigerOps handle Flask application factory patterns?

Call TigerOps.init_app(app) inside your create_app() factory function after registering all blueprints and extensions. The TigerOps object supports the same lazy initialization pattern as Flask-SQLAlchemy and other Flask extensions.

Does TigerOps work with Flask running behind a reverse proxy?

Yes. TigerOps reads the X-Forwarded-For and X-Real-IP headers to capture the real client IP. For W3C trace context propagation from an upstream proxy or API gateway, set ProxyFix in your WSGI middleware stack before the TigerOps middleware.

Can I trace Flask CLI commands and background scripts?

Yes. Wrap CLI commands with the @tigerops.trace_command decorator. For standalone scripts that import your Flask app, call TigerOps.init_app(app) once and use the tigerops.span() context manager around the work you want to trace.

How are Celery task spans linked to the originating Flask request?

When a Flask request publishes a Celery task, TigerOps serializes the active trace context into the task headers. The Celery worker deserializes the context and creates a child span linked to the original request span, giving you end-to-end trace continuity.

Get Started

Full Flask Observability in One pip Install

WSGI traces, SQLAlchemy spans, Celery task visibility, and cache instrumentation — no code changes required.