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):
Programmatic configuration (passed to constructors)
Environment variables
.envfileConfiguration file (if loaded)
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