Skip to main content

Opinionated InfluxDB client

Project description

Grafane

A very opinionated InfluxDB client inspired by Grafana's query builder.

Setup

Installation

pip install grafane        # InfluxDB v2 (default)
pip install grafane[v1]    # Add InfluxDB v1 support

Or with poetry:

poetry add grafane             # InfluxDB v2 (default)
poetry add grafane --extras v1 # Add InfluxDB v1 support

Configuration

Grafane supports multi-database setups with a Django-style configuration system.

Recommended: Create a settings module in your project:

# myproject/settings.py
INFLUXDB_SETTINGS = {
    'default': {
        'version': 2,
        'url': 'http://localhost:8086',
        'token': 'my-api-token',
        'org': 'my-org',
        'bucket': 'my-bucket',
        'metrics': [],
    },
}

Then configure Grafane:

import grafane
grafane.configure('myproject.settings')

Alternatively, set the environment variable:

export GRAFANE_SETTINGS_MODULE=myproject.settings

Environment Variables (Default Configuration)

If no settings module is configured, Grafane uses these environment variables for a single default InfluxDB v2 database:

Variable Default Description
INFLUXDB_V2_URL http://localhost:8086 InfluxDB v2 URL
INFLUXDB_V2_TOKEN my-super-secret-token API token
INFLUXDB_V2_ORG my-org Organization
INFLUXDB_V2_BUCKET metrics Bucket name
TESTING 0 If set, appends -testing to metric names

For multi-database setups, use a settings module instead (see Configuration above).

Quick Start

import grafane

# Configure with your settings module (optional if using env vars)
grafane.configure('myproject.settings')

# Create a client for a metric
c = grafane.Grafane(metric='temperature')

# Write
c.report({'value': 23.5}, {'room': 'living'})

# Read
results = c.select(fields='value').filter_by('room', '=', 'living').execute_query()

Multi-Database Setup

Configure multiple InfluxDB buckets in your settings module:

# myproject/settings.py
INFLUXDB_SETTINGS = {
    'default': {
        'version': 2,
        'url': 'http://localhost:8086',
        'token': 'my-api-token',
        'org': 'my-org',
        'bucket': 'metrics',
        'metrics': [],  # Empty = fallback for unmatched metrics
    },
    'analytics': {
        'version': 2,
        'url': 'http://analytics.example.com:8086',
        'token': 'analytics-token',
        'org': 'my-org',
        'bucket': 'analytics',
        'metrics': ['page_views', 'sessions', 'events'],
    },
}

v2 Configuration Keys

Key Type Required Description
version int Yes Set to 2 for InfluxDB v2
url str Yes InfluxDB v2 URL
token str Yes API token
org str Yes Organization
bucket str Yes Bucket name
metrics list No Metrics routed to this bucket (empty = fallback)

Legacy InfluxDB v1 Support

Note: InfluxDB v1 requires the v1 extra: pip install grafane[v1]

INFLUXDB_SETTINGS = {
    'default': {
        'host': 'localhost',
        'port': 8086,
        'database': 'metrics',
        'username': 'admin',
        'password': 'secret',
        'metrics': [],
    },
}

v1 Configuration Keys:

Key Type Required Description
host str Yes InfluxDB host
port int Yes InfluxDB port
database str Yes Database name
username str Yes Username
password str Yes Password
metrics list No Metrics routed to this database (empty = fallback)

Mixed v1/v2 Setup

You can configure both v1 and v2 databases in the same settings (requires pip install grafane[v1]):

INFLUXDB_SETTINGS = {
    'legacy': {
        'host': 'localhost',
        'port': 8086,
        'database': 'metrics_v1',
        'username': 'admin',
        'password': 'secret',
        'metrics': ['cpu', 'memory'],
    },
    'modern': {
        'version': 2,
        'url': 'http://localhost:8086',
        'token': 'my-token',
        'org': 'my-org',
        'bucket': 'metrics_v2',
        'metrics': ['events', 'traces'],
    },
}

Metric Routing

Grafane automatically routes metrics to the correct database based on the metrics list:

from grafane import Grafane

# Routes to 'analytics' (has 'page_views' in metrics list)
c = Grafane('page_views')

# Routes to 'monitoring' (has 'cpu' in metrics list)
c = Grafane('cpu')

# Routes to 'default' (fallback - empty metrics list)
c = Grafane('unknown_metric')

# Explicit database selection (bypasses routing)
c = Grafane('any_metric', db='analytics')

Routing rules:

  1. If db= parameter is provided, use that database
  2. If metric is in exactly one database's metrics list, use that database
  3. If metric is in multiple databases' metrics lists, raises error (use db= to resolve)
  4. If metric is not found, use the fallback database (database with empty metrics list)
  5. If no fallback exists, raises error

Write

report()

c.report(fields, tags, timestamp=False)

report_points()

c.report_points([
    {'fields': {'value': 1.2}, 'tags': {'tag1': 'a'}},
    {'fields': {'value': 1.8}, 'tags': {'tag1': 'b'}},
])

If no timestamp is provided, defaults to datetime.now(pytz.utc).

Read

Chainable Query API

All query methods return self and can be chained:

results = (
    c.select(fields=['value', 'value2'], aggregation='mean')
    .filter_by('tag1', '=', 'value1')
    .time_block('1h')
    .fill_with('none')
    .execute_query()
)

select()

# Single field
c.select(fields='value')

# Multiple fields
c.select(fields=['value', 'value2'])

# With aggregation
c.select(fields='value', aggregation='sum')

# Multiple fields with different aggregations
c.select(fields=['value', 'value2'], aggregation=['sum', 'mean'])

filter_by()

Filter by tag with an operator:

c.filter_by('tag1', '=', 'value1')

Supported operators: =, !=, <, >, <=, >=, =~ (regex)

filter_value_in()

Match tags against multiple values:

c.filter_value_in('tag1', ['value1', 'value2'])

filter_time_range()

from datetime import datetime

time_range = (datetime(2024, 1, 1), datetime(2024, 1, 31))
c.filter_time_range(time_range)

Accepts tuple or list of datetime objects. Order doesn't matter.

time_block()

Group results by time intervals:

c.select(fields='value', aggregation='mean').time_block('1h')

fill_with()

Fill empty time blocks:

c.fill_with('none')

Options: none, null, 0, previous, linear

group_by()

Group by tag values (requires aggregation):

c.select(fields='value', aggregation='sum').group_by('tag1')

Iteration, Length, and Boolean

# Iterate directly
for row in c.select(fields='value'):
    print(row)

# Check result count
count = len(c.select(fields='value'))

# Boolean check
if c.select(fields='value').filter_by('tag1', '=', 'x'):
    print("Has results")

Drop Measurement

c = Grafane(metric='test')
c.drop_measurement()

Development

Docker Setup

Start services:

ahoy docker up

Services:

Jupyter Notebooks

ahoy notebooks run

Notebooks are stored in .notebooks/ directory.

Environment Files

Copy .env.copy to .env:

cp .env.copy .env

Contents:

INFLUXDB_DATA_ENGINE=tsm1
INFLUXDB_DB=metrics
INFLUXDB_USER=admin
INFLUXDB_PASSWORD=admin123

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

grafane-2.1.0.tar.gz (29.8 kB view details)

Uploaded Source

Built Distribution

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

grafane-2.1.0-py3-none-any.whl (33.4 kB view details)

Uploaded Python 3

File details

Details for the file grafane-2.1.0.tar.gz.

File metadata

  • Download URL: grafane-2.1.0.tar.gz
  • Upload date:
  • Size: 29.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.1.3 CPython/3.13.11 Darwin/25.3.0

File hashes

Hashes for grafane-2.1.0.tar.gz
Algorithm Hash digest
SHA256 cdcd40f031c5b8e75bb1e397832dc01b8bf60b48b159f89960e8632b4f74f811
MD5 3850930db0a1d664eb693bd116b08e21
BLAKE2b-256 8b679fd014b237661897e5df4cbbfd9fa72a6581a568fd0629a77d7b1fe2ac30

See more details on using hashes here.

File details

Details for the file grafane-2.1.0-py3-none-any.whl.

File metadata

  • Download URL: grafane-2.1.0-py3-none-any.whl
  • Upload date:
  • Size: 33.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.1.3 CPython/3.13.11 Darwin/25.3.0

File hashes

Hashes for grafane-2.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e925eb0a2cdd52116b5681f11aa9318f0292386d625b45857fdf9a263356a2b6
MD5 cf2a9dcaf3ea026b6f3340c436e74419
BLAKE2b-256 35255cfbbf2da3126709fd77c39a4f8a9b4b0bfdd471351da2b0df058ec05cc3

See more details on using hashes here.

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