Scalar temporal period identifiers for Power BI
Project description
Artip – Scalar Temporal Period Identifiers for Power BI
Artip is a Python library that generates unique, scalar integer identifiers for temporal periods, optimized for storage and filtering in Power BI's Vertipaq engine.
Features
- Scalar Period IDs: Encode temporal periods as 64-bit integers for efficient Power BI representation
- Flexible Granularity: Support for year, month, day, hour, minute, and second-level periods
- Period Constraints: Optional maximum period size enforcement
- Calendar Generation: Automatic generation of periodic calendar tables for Power BI filtering
- Type-Safe: Full Python type hints for IDE integration and runtime checks
- No Global State: Thread-safe with all state encapsulated in Artip instances
Installation
pip install artip
Quick Start
from datetime import date
from artip import Artip
# Create an Artip instance
artip = Artip(
min_time=date(2024, 1, 1),
max_time=date(2024, 12, 31),
granularity='day'
)
# Generate a period identifier
period_id = artip.make_period_id(
start=date(2024, 1, 1),
end=date(2024, 1, 31)
)
print(f"Period ID: {period_id}") # Output: Period ID: 101
# Retrieve the time range for a period
start, end = artip.get_period_range(period_id)
print(f"Period range: {start} to {end}")
# Generate a calendar table for Power BI
calendar = artip.make_calendar_table()
print(calendar)
Use Cases
ETL Pipeline Integration
Use Artip in Python ETL pipelines to generate period identifiers for facts tables:
from datetime import date
import polars as pl
from artip import Artip
# Setup period encoding
artip = Artip(
min_time=date(2020, 1, 1),
max_time=date(2030, 12, 31),
granularity='month'
)
# Process fact records
facts = pl.DataFrame({
'transaction_date': [date(2024, 3, 15), date(2024, 5, 20)],
'amount': [100.0, 250.0]
})
def add_period_id(record):
return artip.make_period_id(record['transaction_date'], record['transaction_date'])
facts = facts.with_columns(
period_id=facts['transaction_date'].map_elements(
lambda d: artip.make_period_id(d, d).value
)
)
Calendar Table for Power BI
Generate a calendar table to enable period-based filtering:
calendar_table = artip.make_calendar_table()
# Save to CSV for Power BI import
calendar_table.write_csv('period_calendar.csv')
API Reference
Artip Class
Constructor
Artip(
min_time: Union[date, datetime],
max_time: Union[date, datetime],
granularity: str = 'day',
period_max_size: Optional[int] = None
)
Parameters:
min_time: Minimum time boundary (inclusive)max_time: Maximum time boundary (inclusive)granularity: Temporal granularity ('year', 'month', 'day', 'hour', 'minute', 'second')period_max_size: Maximum allowed period length in granularity units (None = unlimited)
Raises:
InvalidIntervalError: If min_time >= max_timeInvalidGranularityError: If granularity is not supported
make_period_id(start, end) -> PeriodId
Generate a unique identifier for a temporal period.
Parameters:
start: Period start time (inclusive)end: Period end time (inclusive)
Returns: PeriodId object
Raises:
InvalidIntervalError: If start > end or period outside boundsPeriodTooLargeError: If period exceeds period_max_size
get_period_range(period_id) -> Tuple[datetime, datetime]
Retrieve the time range for a period identifier.
Parameters:
period_id: A PeriodId generated by this instance
Returns: Tuple of (start_time, end_time)
Raises:
InvalidIntervalError: If period_id not generated by this instance
make_calendar_table() -> pl.DataFrame
Generate a periodic calendar table for Power BI filtering.
Returns: Polars DataFrame with columns:
date: The timepoint at the specified granularityperiod_id: The PeriodId value (Int64)label: Relationship to period ('starts', 'ends', 'in')
PeriodId Class
Lightweight dataclass representing a period identifier.
Attributes:
value: int– The encoded period identifier
Methods:
__str__()– Returns string representation__eq__(other)– Equality comparison__hash__()– Hashable for use in sets/dicts
Exceptions
ArtipError– Base exceptionInvalidIntervalError– Invalid time intervalPeriodTooLargeError– Period exceeds constraintsInvalidGranularityError– Unsupported granularity
Design Rationale
Artip encodes periods as composite integers:
PeriodId = (start_id) * 10^period_size + period_length
Where:
start_id= offset from min_time in granularity unitsperiod_length= end_id - start_idperiod_size= number of digits allocated for period_length
This design ensures:
- Efficient storage in 64-bit integers
- Fast period range queries
- Compatible filtering in Power BI
Requirements
- Python 3.10+
- Polars 0.20.0+
License
MIT
Contributing
Contributions are welcome! Please ensure:
- All tests pass:
pytest - Code is type-checked:
mypy - Code adheres to style:
ruff
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file artip-0.1.2.tar.gz.
File metadata
- Download URL: artip-0.1.2.tar.gz
- Upload date:
- Size: 50.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8deb14c324e731f157ff2636a664e9bc922c0061380326777822ea06496afa68
|
|
| MD5 |
120a4495f7f3813e4ef361317f8fa03e
|
|
| BLAKE2b-256 |
13ab4b90baf4e24f68144a1413775b6afae19b31c799bd5177ab89c302522c74
|
File details
Details for the file artip-0.1.2-py3-none-any.whl.
File metadata
- Download URL: artip-0.1.2-py3-none-any.whl
- Upload date:
- Size: 9.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6696f096a9a4784b0fc26db311a6287b7b01a00f22bbb7266d0a771e199f14d6
|
|
| MD5 |
aa19faa3fbd8e5d416fd4ff118224465
|
|
| BLAKE2b-256 |
5a3f5a17b4549126262b07e4d796461785b567b7b5535d07233e8871e64bee13
|