Configuration

This module provides configuration classes using Pydantic for validation and environment variable support.

PIConfig

class pipolars.PIConfig[source]

Bases: BaseSettings

Main configuration class for PIPolars library.

This class aggregates all configuration sections and provides a unified interface for configuration management.

Example

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

The main configuration class that aggregates all settings.

Class Methods

classmethod from_file(path)[source]

Load configuration from a TOML or JSON file.

Parameters:

path (str | Path) – Path to the configuration file

Returns:

PIConfig instance with loaded configuration

Return type:

PIConfig

to_dict()[source]

Convert configuration to a dictionary.

Sensitive fields like passwords are masked.

model_config = {'arbitrary_types_allowed': True, 'case_sensitive': False, 'cli_avoid_json': False, 'cli_enforce_required': False, 'cli_exit_on_error': True, 'cli_flag_prefix_char': '-', 'cli_hide_none_type': False, 'cli_ignore_unknown_args': False, 'cli_implicit_flags': False, 'cli_kebab_case': False, 'cli_parse_args': None, 'cli_parse_none_str': None, 'cli_prefix': '', 'cli_prog_name': None, 'cli_shortcuts': None, 'cli_use_class_docs_for_groups': False, 'enable_decoding': True, 'env_file': '.env', 'env_file_encoding': None, 'env_ignore_empty': False, 'env_nested_delimiter': '__', 'env_nested_max_split': None, 'env_parse_enums': None, 'env_parse_none_str': None, 'env_prefix': 'PIPOLARS_', 'extra': 'ignore', 'json_file': None, 'json_file_encoding': None, 'nested_model_default_partial_update': False, 'protected_namespaces': ('model_validate', 'model_dump', 'settings_customise_sources'), 'secrets_dir': None, 'toml_file': None, 'validate_default': True, 'yaml_config_section': None, 'yaml_file': None, 'yaml_file_encoding': None}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

server: PIServerConfig
af: AFServerConfig
cache: CacheConfig
query: QueryConfig
polars: PolarsConfig
debug: bool
log_level: str
classmethod from_file(path)[source]

Load configuration from a TOML or JSON file.

Parameters:

path (str | Path) – Path to the configuration file

Returns:

PIConfig instance with loaded configuration

Return type:

PIConfig

to_dict()[source]

Convert configuration to a dictionary.

Sensitive fields like passwords are masked.

Usage:

from pipolars import PIConfig
from pipolars.core.config import PIServerConfig, CacheConfig, CacheBackend

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

# From file
config = PIConfig.from_file("pipolars.toml")

PIServerConfig

class pipolars.core.config.PIServerConfig[source]

Bases: BaseSettings

Configuration for PI Data Archive connection.

host

PI Server hostname or IP address

Type:

str

port

PI Server port (default: 5450)

Type:

int

timeout

Connection timeout in seconds

Type:

int

auth_method

Authentication method to use

Type:

AuthMethod

username

Username for explicit authentication

Type:

str | None

password

Password for explicit authentication

Type:

SecretStr | None

Configuration for PI Data Archive connection.

host: str

PI Server hostname or IP address. Required.

port: int = 5450

PI Server port.

timeout: int = 30

Connection timeout in seconds.

auth_method: AuthMethod = AuthMethod.WINDOWS

Authentication method.

username: str | None = None

Username for explicit authentication.

password: SecretStr | None = None

Password for explicit authentication.

model_config = {'arbitrary_types_allowed': True, 'case_sensitive': False, 'cli_avoid_json': False, 'cli_enforce_required': False, 'cli_exit_on_error': True, 'cli_flag_prefix_char': '-', 'cli_hide_none_type': False, 'cli_ignore_unknown_args': False, 'cli_implicit_flags': False, 'cli_kebab_case': False, 'cli_parse_args': None, 'cli_parse_none_str': None, 'cli_prefix': '', 'cli_prog_name': None, 'cli_shortcuts': None, 'cli_use_class_docs_for_groups': False, 'enable_decoding': True, 'env_file': '.env', 'env_file_encoding': None, 'env_ignore_empty': False, 'env_nested_delimiter': None, 'env_nested_max_split': None, 'env_parse_enums': None, 'env_parse_none_str': None, 'env_prefix': 'PI_SERVER_', 'extra': 'ignore', 'json_file': None, 'json_file_encoding': None, 'nested_model_default_partial_update': False, 'protected_namespaces': ('model_validate', 'model_dump', 'settings_customise_sources'), 'secrets_dir': None, 'toml_file': None, 'validate_default': True, 'yaml_config_section': None, 'yaml_file': None, 'yaml_file_encoding': None}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

host: str
port: int
timeout: int
auth_method: AuthMethod
username: str | None
password: SecretStr | None
validate_explicit_auth()[source]

Validate that username/password are provided 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

class pipolars.core.config.AFServerConfig[source]

Bases: BaseSettings

Configuration for AF Server connection.

host

AF Server hostname (if different from PI Server)

Type:

str | None

database

Default AF Database name

Type:

str | None

timeout

Connection timeout in seconds

Type:

int

Configuration for AF Server connection.

host: str | None = None

AF Server hostname (defaults to PI Server).

database: str | None = None

Default AF Database name.

timeout: int = 30

Connection timeout in seconds.

model_config = {'arbitrary_types_allowed': True, 'case_sensitive': False, 'cli_avoid_json': False, 'cli_enforce_required': False, 'cli_exit_on_error': True, 'cli_flag_prefix_char': '-', 'cli_hide_none_type': False, 'cli_ignore_unknown_args': False, 'cli_implicit_flags': False, 'cli_kebab_case': False, 'cli_parse_args': None, 'cli_parse_none_str': None, 'cli_prefix': '', 'cli_prog_name': None, 'cli_shortcuts': None, 'cli_use_class_docs_for_groups': False, 'enable_decoding': True, 'env_file': '.env', 'env_file_encoding': None, 'env_ignore_empty': False, 'env_nested_delimiter': None, 'env_nested_max_split': None, 'env_parse_enums': None, 'env_parse_none_str': None, 'env_prefix': 'AF_SERVER_', 'extra': 'ignore', 'json_file': None, 'json_file_encoding': None, 'nested_model_default_partial_update': False, 'protected_namespaces': ('model_validate', 'model_dump', 'settings_customise_sources'), 'secrets_dir': None, 'toml_file': None, 'validate_default': True, 'yaml_config_section': None, 'yaml_file': None, 'yaml_file_encoding': None}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

host: str | None
database: str | None
timeout: int

Environment variables:

AF_SERVER_HOST=my-af-server
AF_SERVER_DATABASE=MyDatabase

CacheConfig

class pipolars.core.config.CacheConfig[source]

Bases: BaseSettings

Configuration for data caching.

backend

Cache storage backend to use

Type:

CacheBackend

path

Path for file-based cache backends

Type:

Path

max_size_mb

Maximum cache size in megabytes

Type:

int

ttl_hours

Time-to-live for cached data in hours

Type:

int

compression

Enable compression for cached data

Type:

bool

Configuration for data caching.

backend: CacheBackend = CacheBackend.NONE

Cache storage backend.

path: Path = ~/.pipolars/cache

Path for file-based cache backends.

max_size_mb: int = 1024

Maximum cache size in megabytes.

ttl_hours: int = 24

Time-to-live for cached data in hours.

compression: bool = True

Enable compression for cached data.

property ttl: timedelta

Get TTL as a timedelta.

model_config = {'arbitrary_types_allowed': True, 'case_sensitive': False, 'cli_avoid_json': False, 'cli_enforce_required': False, 'cli_exit_on_error': True, 'cli_flag_prefix_char': '-', 'cli_hide_none_type': False, 'cli_ignore_unknown_args': False, 'cli_implicit_flags': False, 'cli_kebab_case': False, 'cli_parse_args': None, 'cli_parse_none_str': None, 'cli_prefix': '', 'cli_prog_name': None, 'cli_shortcuts': None, 'cli_use_class_docs_for_groups': False, 'enable_decoding': True, 'env_file': '.env', 'env_file_encoding': None, 'env_ignore_empty': False, 'env_nested_delimiter': None, 'env_nested_max_split': None, 'env_parse_enums': None, 'env_parse_none_str': None, 'env_prefix': 'PIPOLARS_CACHE_', 'extra': 'ignore', 'json_file': None, 'json_file_encoding': None, 'nested_model_default_partial_update': False, 'protected_namespaces': ('model_validate', 'model_dump', 'settings_customise_sources'), 'secrets_dir': None, 'toml_file': None, 'validate_default': True, 'yaml_config_section': None, 'yaml_file': None, 'yaml_file_encoding': None}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

backend: CacheBackend
path: Path
max_size_mb: int
ttl_hours: int
compression: bool
property ttl: timedelta

Get TTL as a timedelta.

Environment variables:

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

QueryConfig

class pipolars.core.config.QueryConfig[source]

Bases: BaseSettings

Configuration for PI queries.

max_points_per_query

Maximum number of points in a single query

Type:

int

default_page_size

Default page size for paginated queries

Type:

int

max_values_per_request

Maximum values per request

Type:

int

parallel_requests

Number of parallel requests for bulk operations

Type:

int

retry_attempts

Number of retry attempts for failed requests

Type:

int

retry_delay

Delay between retries in seconds

Type:

float

Configuration for PI queries.

max_points_per_query: int = 1000

Maximum number of points in a single query.

default_page_size: int = 10000

Default page size for paginated queries.

max_values_per_request: int = 150000

Maximum values per request.

parallel_requests: int = 4

Number of parallel requests for bulk operations.

retry_attempts: int = 3

Number of retry attempts for failed requests.

retry_delay: float = 1.0

Delay between retries in seconds.

model_config = {'arbitrary_types_allowed': True, 'case_sensitive': False, 'cli_avoid_json': False, 'cli_enforce_required': False, 'cli_exit_on_error': True, 'cli_flag_prefix_char': '-', 'cli_hide_none_type': False, 'cli_ignore_unknown_args': False, 'cli_implicit_flags': False, 'cli_kebab_case': False, 'cli_parse_args': None, 'cli_parse_none_str': None, 'cli_prefix': '', 'cli_prog_name': None, 'cli_shortcuts': None, 'cli_use_class_docs_for_groups': False, 'enable_decoding': True, 'env_file': '.env', 'env_file_encoding': None, 'env_ignore_empty': False, 'env_nested_delimiter': None, 'env_nested_max_split': None, 'env_parse_enums': None, 'env_parse_none_str': None, 'env_prefix': 'PIPOLARS_QUERY_', 'extra': 'ignore', 'json_file': None, 'json_file_encoding': None, 'nested_model_default_partial_update': False, 'protected_namespaces': ('model_validate', 'model_dump', 'settings_customise_sources'), 'secrets_dir': None, 'toml_file': None, 'validate_default': True, 'yaml_config_section': None, 'yaml_file': None, 'yaml_file_encoding': None}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

max_points_per_query: int
default_page_size: int
max_values_per_request: int
parallel_requests: int
retry_attempts: int
retry_delay: float

Environment variables:

PIPOLARS_QUERY_MAX_POINTS_PER_QUERY=1000
PIPOLARS_QUERY_PARALLEL_REQUESTS=4

PolarsConfig

class pipolars.core.config.PolarsConfig[source]

Bases: BaseSettings

Configuration for Polars DataFrame output.

timestamp_column

Name of the timestamp column

Type:

str

value_column

Name of the value column

Type:

str

quality_column

Name of the quality column

Type:

str

tag_column

Name of the tag column (for multi-tag queries)

Type:

str

include_quality

Include quality column by default

Type:

bool

timezone

Default timezone for timestamps

Type:

str

Configuration for Polars DataFrame output.

timestamp_column: str = "timestamp"

Name of the timestamp column.

value_column: str = "value"

Name of the value column.

quality_column: str = "quality"

Name of the quality column.

tag_column: str = "tag"

Name of the tag column (for multi-tag queries).

include_quality: bool = False

Include quality column by default.

timezone: str = "UTC"

Default timezone for timestamps.

model_config = {'arbitrary_types_allowed': True, 'case_sensitive': False, 'cli_avoid_json': False, 'cli_enforce_required': False, 'cli_exit_on_error': True, 'cli_flag_prefix_char': '-', 'cli_hide_none_type': False, 'cli_ignore_unknown_args': False, 'cli_implicit_flags': False, 'cli_kebab_case': False, 'cli_parse_args': None, 'cli_parse_none_str': None, 'cli_prefix': '', 'cli_prog_name': None, 'cli_shortcuts': None, 'cli_use_class_docs_for_groups': False, 'enable_decoding': True, 'env_file': '.env', 'env_file_encoding': None, 'env_ignore_empty': False, 'env_nested_delimiter': None, 'env_nested_max_split': None, 'env_parse_enums': None, 'env_parse_none_str': None, 'env_prefix': 'PIPOLARS_POLARS_', 'extra': 'ignore', 'json_file': None, 'json_file_encoding': None, 'nested_model_default_partial_update': False, 'protected_namespaces': ('model_validate', 'model_dump', 'settings_customise_sources'), 'secrets_dir': None, 'toml_file': None, 'validate_default': True, 'yaml_config_section': None, 'yaml_file': None, 'yaml_file_encoding': None}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

timestamp_column: str
value_column: str
quality_column: str
tag_column: str
include_quality: bool
timezone: str
classmethod validate_timezone(v)[source]

Validate that the timezone is valid.

Environment variables:

PIPOLARS_POLARS_TIMEZONE=America/New_York
PIPOLARS_POLARS_INCLUDE_QUALITY=true

Enumerations

AuthMethod

class pipolars.core.config.AuthMethod[source]

Bases: str, Enum

Authentication methods for PI System connection.

Authentication methods for PI System connection.

WINDOWS = "windows"

Use Windows integrated authentication (NTLM/Kerberos).

EXPLICIT = "explicit"

Use explicit username/password authentication.

WINDOWS = 'windows'

Use Windows integrated authentication (NTLM/Kerberos).

EXPLICIT = 'explicit'

Use explicit username/password authentication.

__new__(value)

CacheBackend

class pipolars.core.config.CacheBackend[source]

Bases: str, Enum

Cache storage backends.

Cache storage backends.

NONE = "none"

No caching.

MEMORY = "memory"

In-memory cache (lost on restart).

SQLITE = "sqlite"

SQLite database cache.

ARROW = "arrow"

Apache Arrow IPC file cache.

NONE = 'none'

No caching.

MEMORY = 'memory'

In-memory cache (lost on restart).

SQLITE = 'sqlite'

SQLite database cache.

ARROW = 'arrow'

Apache Arrow IPC file cache.

__new__(value)

Configuration File Format

TOML Format

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

[af]
database = "MyDatabase"

[cache]
backend = "sqlite"
max_size_mb = 1024
ttl_hours = 24

[query]
parallel_requests = 4
retry_attempts = 3

[polars]
timezone = "UTC"

debug = false
log_level = "INFO"

JSON Format

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

See Also