Skip to main content

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_time
  • InvalidGranularityError: 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 bounds
  • PeriodTooLargeError: 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 granularity
  • period_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 exception
  • InvalidIntervalError – Invalid time interval
  • PeriodTooLargeError – Period exceeds constraints
  • InvalidGranularityError – 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 units
  • period_length = end_id - start_id
  • period_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


Download files

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

Source Distribution

artip-0.1.2.tar.gz (50.2 kB view details)

Uploaded Source

Built Distribution

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

artip-0.1.2-py3-none-any.whl (9.3 kB view details)

Uploaded Python 3

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

Hashes for artip-0.1.2.tar.gz
Algorithm Hash digest
SHA256 8deb14c324e731f157ff2636a664e9bc922c0061380326777822ea06496afa68
MD5 120a4495f7f3813e4ef361317f8fa03e
BLAKE2b-256 13ab4b90baf4e24f68144a1413775b6afae19b31c799bd5177ab89c302522c74

See more details on using hashes here.

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

Hashes for artip-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 6696f096a9a4784b0fc26db311a6287b7b01a00f22bbb7266d0a771e199f14d6
MD5 aa19faa3fbd8e5d416fd4ff118224465
BLAKE2b-256 5a3f5a17b4549126262b07e4d796461785b567b7b5535d07233e8871e64bee13

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