Configuration - PIPolars 0.1.0 documentation

Skip to content
Back to top
View this page
Edit this page

# Configuration

PIPolars uses Pydantic for configuration management, supporting environment variables, configuration files, and programmatic configuration.

## Configuration Classes

PIPolars has a hierarchical configuration structure:

    PIConfig
    ├── server: PIServerConfig    # PI Server connection settings
    ├── af: AFServerConfig        # AF Server settings
    ├── cache: CacheConfig        # Caching configuration
    ├── query: QueryConfig        # Query behavior settings
    ├── polars: PolarsConfig      # DataFrame output settings
    ├── debug: bool               # Debug mode
    └── log_level: str            # Logging level

## PIConfig

The main configuration class that aggregates all settings:

    from pipolars import PIConfig
    from pipolars.core.config import (
        PIServerConfig, AFServerConfig, CacheConfig,
        QueryConfig, PolarsConfig, CacheBackend
    )

    config = PIConfig(
        server=PIServerConfig(host="my-pi-server"),
        cache=CacheConfig(backend=CacheBackend.SQLITE),
        debug=True,
        log_level="DEBUG",
    )

    with PIClient(config=config) as client:
        df = client.snapshot("SINUSOID")

## PIServerConfig

PI Data Archive connection settings:

    from pipolars.core.config import PIServerConfig, AuthMethod

    server_config = PIServerConfig(
        host="my-pi-server",    # Required: hostname or IP
        port=5450,              # Optional: default 5450
        timeout=30,             # Optional: connection timeout (seconds)
        auth_method=AuthMethod.WINDOWS,  # Authentication method
        username=None,          # For explicit auth
        password=None,          # For explicit auth
    )

Environment variables:

    PI_SERVER_HOST=my-pi-server
    PI_SERVER_PORT=5450
    PI_SERVER_TIMEOUT=30
    PI_SERVER_AUTH_METHOD=windows

## AFServerConfig

AF Server connection settings:

    from pipolars.core.config import AFServerConfig

    af_config = AFServerConfig(
        host="my-af-server",    # Optional: defaults to PI server
        database="MyDatabase",  # Optional: default AF database
        timeout=30,             # Connection timeout
    )

Environment variables:

    AF_SERVER_HOST=my-af-server
    AF_SERVER_DATABASE=MyDatabase
    AF_SERVER_TIMEOUT=30

## CacheConfig

Caching behavior settings:

    from pathlib import Path
    from pipolars.core.config import CacheConfig, CacheBackend

    cache_config = CacheConfig(
        backend=CacheBackend.SQLITE,  # none, memory, sqlite, arrow
        path=Path("~/.pipolars/cache").expanduser(),
        max_size_mb=1024,             # Maximum cache size
        ttl_hours=24,                 # Cache time-to-live
        compression=True,             # Compress cached data
    )

Environment variables:

    PIPOLARS_CACHE_BACKEND=sqlite
    PIPOLARS_CACHE_PATH=~/.pipolars/cache
    PIPOLARS_CACHE_MAX_SIZE_MB=1024
    PIPOLARS_CACHE_TTL_HOURS=24
    PIPOLARS_CACHE_COMPRESSION=true

## QueryConfig

Query behavior settings:

    from pipolars.core.config import QueryConfig

    query_config = QueryConfig(
        max_points_per_query=1000,     # Max tags per query
        default_page_size=10000,       # Pagination size
        max_values_per_request=150000, # Max values per request
        parallel_requests=4,           # Parallel bulk operations
        retry_attempts=3,              # Retry on failure
        retry_delay=1.0,               # Delay between retries
    )

Environment variables:

    PIPOLARS_QUERY_MAX_POINTS_PER_QUERY=1000
    PIPOLARS_QUERY_PARALLEL_REQUESTS=4
    PIPOLARS_QUERY_RETRY_ATTEMPTS=3

## PolarsConfig

DataFrame output settings:

    from pipolars.core.config import PolarsConfig

    polars_config = PolarsConfig(
        timestamp_column="timestamp",  # Name of timestamp column
        value_column="value",          # Name of value column
        quality_column="quality",      # Name of quality column
        tag_column="tag",              # Name of tag column
        include_quality=False,         # Include quality by default
        timezone="UTC",                # Output timezone
    )

Environment variables:

    PIPOLARS_POLARS_TIMESTAMP_COLUMN=timestamp
    PIPOLARS_POLARS_VALUE_COLUMN=value
    PIPOLARS_POLARS_TIMEZONE=America/New_York
    PIPOLARS_POLARS_INCLUDE_QUALITY=false

## Configuration Files

### TOML Configuration

Create a `pipolars.toml` file:

    [server]
    host = "my-pi-server"
    port = 5450
    timeout = 30
    auth_method = "windows"

    [af]
    host = "my-af-server"
    database = "MyDatabase"

    [cache]
    backend = "sqlite"
    path = "~/.pipolars/cache"
    max_size_mb = 1024
    ttl_hours = 24

    [query]
    parallel_requests = 4
    retry_attempts = 3

    [polars]
    timezone = "UTC"
    include_quality = false

    [general]
    debug = false
    log_level = "INFO"

Load from file:

    from pipolars import PIConfig

    config = PIConfig.from_file("pipolars.toml")
    with PIClient(config=config) as client:
        df = client.snapshot("SINUSOID")

### JSON Configuration

You can also use JSON:

    {
        "server": {
            "host": "my-pi-server",
            "port": 5450,
            "timeout": 30
        },
        "cache": {
            "backend": "sqlite",
            "max_size_mb": 1024
        },
        "debug": false
    }

    config = PIConfig.from_file("pipolars.json")

## Environment File (.env)

PIPolars can load from `.env` files:

    # .env file
    PI_SERVER_HOST=my-pi-server
    PI_SERVER_PORT=5450
    PIPOLARS_CACHE_BACKEND=sqlite
    PIPOLARS_CACHE_TTL_HOURS=24

PIPolars automatically loads `.env` from the current directory.

## Configuration Precedence

Configuration values are resolved in this order (highest priority first):

1. Programmatic configuration (passed to constructors)

2. Environment variables

3. `.env` file

4. Configuration file (if loaded)

5. Default values

    # Environment: PI_SERVER_PORT=5451

    config = PIServerConfig(
        host="my-server",
        port=5450,  # This takes precedence over env var
    )
    print(config.port)  # 5450

    config2 = PIServerConfig(
        host="my-server",
        # port not specified, uses env var
    )
    print(config2.port)  # 5451

## Viewing Configuration

    config = PIConfig(
        server=PIServerConfig(host="my-pi-server"),
        cache=CacheConfig(backend=CacheBackend.SQLITE),
    )

    # View as dictionary (sensitive values masked)
    print(config.to_dict())

    # Access individual settings
    print(config.server.host)
    print(config.cache.backend)
    print(config.cache.ttl)  # Returns timedelta

## Validation

Configuration is validated using Pydantic:

    from pydantic import ValidationError

    try:
        config = PIServerConfig(
            host="my-server",
            port=99999,  # Invalid port
        )
    except ValidationError as e:
        print(e)
        # port: Input should be less than or equal to 65535

    try:
        config = PIServerConfig(
            host="my-server",
            auth_method="explicit",
            # Missing username/password for explicit auth
        )
    except ValidationError as e:
        print(e)
        # Username and password are required for explicit authentication

## Complete Example

    from pipolars import PIClient, PIConfig
    from pipolars.core.config import (
        PIServerConfig, AFServerConfig, CacheConfig,
        QueryConfig, PolarsConfig, CacheBackend, AuthMethod
    )
    from pathlib import Path

    # Full configuration
    config = PIConfig(
        server=PIServerConfig(
            host="prod-pi-server",
            port=5450,
            timeout=60,
            auth_method=AuthMethod.WINDOWS,
        ),
        af=AFServerConfig(
            host="prod-af-server",
            database="Production",
        ),
        cache=CacheConfig(
            backend=CacheBackend.SQLITE,
            path=Path("/data/pipolars_cache"),
            max_size_mb=4096,
            ttl_hours=48,
            compression=True,
        ),
        query=QueryConfig(
            parallel_requests=8,
            retry_attempts=3,
            retry_delay=2.0,
        ),
        polars=PolarsConfig(
            timezone="America/New_York",
            include_quality=True,
        ),
        debug=False,
        log_level="WARNING",
    )

    with PIClient(config=config) as client:
        df = client.recorded_values("SINUSOID", "*-1d", "*")

## Next Steps

- Caching - Detailed caching configuration

- Advanced Usage - Advanced usage patterns

- Configuration - Configuration API reference