Skip to main content

common facilities to be used by Prima services

Project description

TracApp - the common libraries

This is the prima package that provides common facilities for Prima Control Tower, Prima Engine, and future Prima packages.

The package provides:

  1. A mechanism for reading project settings from the environment and .env files.
  2. A logging object log that follows the standard logging interface.
  3. An OAuth client for authenticating users.
  4. A JWT library for creating and verifying JSON Web Tokens.

where the last two features will be implemented shortly.

The prima package is intentionally opinionated and minimal, sacrificing flexibility for ease of use and consistency across Prima packages.

Installation

The tracapp distribution wheel will be published to PyPI as package tracapp so can be installed with

uv add tracapp

or directly from this repository with

uv add git+ssh://git@github.com/esimplicityinc/prima-tracapp.git

Using the TracApp logger

You already know how to use it:

from tracapp.logger import log
log.info("This is an info message")
log.error("This is an error message")

Log messages are sent to the process console and either or both of:

  • An OpenTelemetry collector if the OTEL_EXPORTER_OTLP_ENDPOINT environment variable is set.
  • The logfire.dev service if the LOGFIRE_TOKEN environment variable is set.

Logfire is a paid service from Pydantic that provides a sophisticated OpenTelemetry trace and log view. It has very generous free tier limits and has really helped with AiOx development.

FastAPI instrumentation

Because the prima logger is likely to be instantiated early you'll need to add Logfire instrumentation to your FastAPI app manually after it is instantiated:

from fastapi import FastAPI
from prima.logger import log, logfire
app = FastAPI()
logfire.instrument_fastapi(app)

Pydantic-AI, Celery and HTTPX instrumentations are automatically enabled when the prima logger is instantiated. There are a slew of Logfire supported instrumentations that can be added if wanted.

Using settings

The TracApp settings system uses Pydantic Settings to define, import, and validate settings. The prima.settings mechanism enforces a strict hierarchy of configuration sources:

  1. Environment variables (os.environ)
  2. A .env file in the current working directory
  3. Defaults defined in the Settings class

and the filling of them are in that order. This means that an Environment variable if present will always override a value in the .env file, and only if neither is present will the default value be used. Note that empty environment or .env values are affirmatively ignored because they are almost always wrong. For example:

export AIOX_PORT=

will not override the default value of 8001. Also be aware that quoting in docker-compose.yml files is tricky. Use

environment:
  - AIOX_REDIS_BASE=redis://redis:6379

without quotes around the value. This is a YAML weirdness which does crop up in the tracapp.settings context.

This hierarchy is just what you want for Dockerized and host-based execution. For example, you can have a .env file containing

AIOX_REDIS_BASE=redis://localhost:6379

and a docker-compose.yml file containing

environment:
  - AIOX_REDIS_BASE=redis://redis:6379

which will supersede the .env file, making obvious and deterministic where the application can find Redis.

TracApp global settings

You must define the TRACAPP_PACKAGE_NAME environment variable or .env entry to be the name of the package using TracApp. This is used to

  1. determine the package version which is available as tracapp.settings.package_version.
  2. name the service in OpenTelemetry traces.

for example, in Prima Engine this is

TRACAPP_PACKAGE_NAME=aiox

The logging level is set as TRACAPP_LOGLEVEL which defaults to "INFO" but can be overridden in the environment or .env file.

To send logs and traces to an OpenTelemetry collector, set the OTEL_EXPORTER_OTLP_ENDPOINT environment variable to the collector URL. The default is None.

An optional LOGFIRE_TOKEN (default: None) if set will allow @mwartell to use his developer Logfire account to see his logs. This is useful if you are him, and possibly if you are not him and want to use Logfire.

Application specific settings

There is a prima.settings.PrimaSettings class that defines the common behavior requiring an application to only define its own settings. Here is an example from Prima Engine:

from tracapp.settings import PrimaSettings

class AioxSettings(PrimaSettings):
    """Application settings for aiox service."""

    # if we don't override, this will be "prima"
    logfire_service_name: str = "aiox"

    # the defaults here will be used if not overridden in os.environ or .env
    # this makes minimal .env files possible
    aiox_port: int = 8000
    aiox_redis_base: str = "redis://localhost:6379"

    celery_task_timeout: float = 30.0  # seconds to wait for task result
    llm_task_queue: str = "llm"  # Redis pub/sub channel for LLM tasks

settings = AioxSettings()

The last line instantiates the settings object at import time so that member values are available immediately.

from aiox.config import settings
print(settings.aiox_port)

Because every element here has a default value, aiox can be usefully run with neither an .env file nor environment variables. The variables are fully type validated by Pydantic; indeed AioxSettings is an instance of pydantic.BaseModel. All of these could be overridden in a .env file and if there are entries in os.environ their values win.

PrimaSettings does not currently handle command line arguments, but by virtue of Pydantic-settings, it easily could.

For those who like shouting members are also available as uppercase like settings.AIOX_PORT.

I recommend that application settings be prefixed with an application name like AIOX_ or TOWER_. This could be enforced but I've chosen not to currently because it adds complexity and semantic noise.

Building a wheel

You can build a wheel for the tracapp package by running

uv build --wheel tracapp

in the prima-tracapp root directory. The wheel will be placed in the dist directory.

Project details


Download files

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

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

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

tracapp-0.4.7-py3-none-any.whl (7.3 kB view details)

Uploaded Python 3

File details

Details for the file tracapp-0.4.7-py3-none-any.whl.

File metadata

  • Download URL: tracapp-0.4.7-py3-none-any.whl
  • Upload date:
  • Size: 7.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.8.17

File hashes

Hashes for tracapp-0.4.7-py3-none-any.whl
Algorithm Hash digest
SHA256 e357550b6279aa9607b6c078b7c5386eb56766644cec780517b5a5d4dd67cfe6
MD5 fbe4b5f47ad39a51e63aeb578b96c421
BLAKE2b-256 173ecaa878a9d451457e1e08e370553ec9d4a7405a453e4a05c9186f5f5ee0fb

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