Observed since 20 Oct, 15:35 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
Framework for 3phi project
Utility classes for DB access, S3 interactions, and data processing via Controller Classes.
Distributed on PyPi.
Install name:
3phi-framework
Import package:threephi_framework
Used by: 3-Phase-Insight Data Platform
pip install 3phi-framework
Development builds are generated for each pull request and attached as workflow artifacts.
It will contain files like:
dist/ 3phi_framework-.whl 3phi_framework-.tar.gz
From the extracted directory:
pip install dist/3phi_framework-*.whl
Alternatively, install the source distribution:
pip install dist/3phi_framework-*.tar.gz
Notes: Wheels are preferred and install faster. Make sure you are using Python ≥ 3.12 (project requirement). Dev builds are temporary and may be deleted after 7 days.
The framework is set up for local development as well as for being used in a deployment. To set up your environment for local development, follow these steps:
execute_data_app.sh expects a virtual environment to be set up under [.venv]. See the python docs on how to set it up.
The database schema is provisioned automatically from the canonical sqitch migrations, so you do not need to supply it. Seed data is optional:
make up-seeded.Navigate to docker and run
make up # schema only (empty tables)
make up-seeded # schema + load docker/db/seed/seed.sql if present
This brings up a local Postgres (schema deployed from the canonical sqitch migrations) and a MinIO Object Storage. See docker/README.md for details.
Use the utility script execute_data_app.sh and pass the data app name as an argument, e.g.:
./execute_data_app.sh sm_classifier
In case the script is not executable, make it executable:
chmod +x execute_data_app.sh
The script will install the dependencies in requirements.txt in your virtual environment, set up environment variables as they are listed in .env and execute the data app as a python module.
The framework abstracts object storage behind BaseConnector so data apps are decoupled from the underlying storage backend. Two implementations are provided out of the box.
Every data app works against a single connector, resolved in this order:
BaseConnector instance to the data app:
from threephi_framework import AzureBlobConnector, SMClassifier
connector = AzureBlobConnector(data_dir_path="phase_measurements/raw")
with SMClassifier(config, connector=connector) as app:
app.run()
object_storage_backend: "s3" | "azure" in the data app config (e.g. in a DAG's YAML); the connector is built by create_connector().OBJECT_STORAGE_BACKEND (same values), useful to switch a whole deployment."s3".The connector is rooted at config["data_dir_path"] (default phase_measurements/raw) and shared by the data app's DataExtractor and TimeSeriesController. Functions that run on Dask workers reconstruct the connector from the backend name carried in their config, so backends swap consistently across the cluster.
For AWS S3 or any S3-compatible storage (the default local dev setup uses MinIO).
from threephi_framework import S3Connector
connector = S3Connector(data_dir_path="timeseries/ready")
| Environment variable | Required | Description |
|---|---|---|
S3_ENDPOINT_URL | Yes | Full URL of the S3 endpoint, e.g. http://localhost:19000 for MinIO |
S3_ACCESS_KEY | Yes | Access key / username |
S3_SECRET_KEY | Yes | Secret key / password |
The bucket name is fixed to 3phi. All paths are rooted at s3://3phi/<data_dir_path>.
For Azure Blob Storage. Requires the adlfs package (pip install adlfs).
from threephi_framework import AzureBlobConnector
connector = AzureBlobConnector(data_dir_path="timeseries/ready")
| Environment variable | Required | Description |
|---|---|---|
AZURE_STORAGE_ACCOUNT_NAME | Yes | Azure Storage Account name |
AZURE_STORAGE_CONTAINER_NAME | Yes | Blob container name (equivalent to the S3 bucket) |
AZURE_STORAGE_ACCOUNT_KEY | No | Account key for key-based auth. If omitted, DefaultAzureCredential is used automatically |
All paths are rooted at az://<container>/<data_dir_path>.
Authentication — when AZURE_STORAGE_ACCOUNT_KEY is not set, the connector falls back to DefaultAzureCredential, which transparently supports managed identity, service principal (via environment variables), and az login for local development. No code changes are needed between environments.
Subclass BaseConnector and implement all abstract methods. The connector is injected into TimeSeriesController at construction time, so any conforming implementation works as a drop-in replacement:
from threephi_framework.object_storage.base_connector import BaseConnector
class MyConnector(BaseConnector):
...
controller = TimeSeriesController(connector=MyConnector(data_dir_path="..."))
The currently assumed datamodel is illustrated in the diagram below:
pypistats · 65 observations shown. Missing days are unknown. Source category: overall: without mirrors.
| Date / source period | Value | Observed at |
|---|---|---|
| 2026-10-19 – 2026-10-19 | 1 | 2026-10-20T16:04:00.3613865Z |
| 2026-10-18 – 2026-10-18 | 2 | 2026-10-20T16:04:00.3613865Z |
| 2026-10-17 – 2026-10-17 | 1 | 2026-10-20T16:04:00.3613865Z |
| 2026-10-15 – 2026-10-15 | 2 | 2026-10-20T16:04:00.3613865Z |
| 2026-10-13 – 2026-10-13 | 1 | 2026-10-20T16:04:00.3613865Z |
| 2026-10-12 – 2026-10-12 | 1 | 2026-10-20T16:04:00.3613865Z |
| 2026-10-11 – 2026-10-11 | 2 | 2026-10-20T16:04:00.3613865Z |
| 2026-10-10 – 2026-10-10 | 9 | 2026-10-20T16:04:00.3613865Z |
| 2026-10-09 – 2026-10-09 | 3 | 2026-10-20T16:04:00.3613865Z |
| 2026-10-08 – 2026-10-08 | 9 | 2026-10-20T16:04:00.3613865Z |
| 2026-10-07 – 2026-10-07 | 5 | 2026-10-20T16:04:00.3613865Z |
| 2026-10-06 – 2026-10-06 | 1 | 2026-10-20T16:04:00.3613865Z |
| 2026-10-05 – 2026-10-05 | 1 | 2026-10-20T16:04:00.3613865Z |
| 2026-10-04 – 2026-10-04 | 1 | 2026-10-20T16:04:00.3613865Z |
| 2026-10-01 – 2026-10-01 | 1 | 2026-10-20T16:04:00.3613865Z |
| 2026-09-30 – 2026-09-30 | 9 | 2026-10-20T16:04:00.3613865Z |
| 2026-09-29 – 2026-09-29 | 4 | 2026-10-20T16:04:00.3613865Z |
| 2026-09-28 – 2026-09-28 | 8 | 2026-10-20T16:04:00.3613865Z |
| 2026-09-27 – 2026-09-27 | 3 | 2026-10-20T16:04:00.3613865Z |
| 2026-09-26 – 2026-09-26 | 2 | 2026-10-20T16:04:00.3613865Z |
| 2026-09-25 – 2026-09-25 | 3 | 2026-10-20T16:04:00.3613865Z |
| 2026-09-24 – 2026-09-24 | 6 | 2026-10-20T16:04:00.3613865Z |
| 2026-09-23 – 2026-09-23 | 1 | 2026-10-20T16:04:00.3613865Z |
| 2026-09-22 – 2026-09-22 | 2 | 2026-10-20T16:04:00.3613865Z |
| 2026-09-21 – 2026-09-21 | 2 | 2026-10-20T16:04:00.3613865Z |
| 2026-09-18 – 2026-09-18 | 16 | 2026-10-20T16:04:00.3613865Z |
| 2026-09-16 – 2026-09-16 | 2 | 2026-10-20T16:04:00.3613865Z |
| 2026-09-12 – 2026-09-12 | 7 | 2026-10-20T16:04:00.3613865Z |
| 2026-09-10 – 2026-09-10 | 1 | 2026-10-20T16:04:00.3613865Z |
| 2026-09-09 – 2026-09-09 | 2 | 2026-10-20T16:04:00.3613865Z |
| 2026-09-07 – 2026-09-07 | 4 | 2026-10-20T16:04:00.3613865Z |
| 2026-09-06 – 2026-09-06 | 8 | 2026-10-20T16:04:00.3613865Z |
| 2026-09-05 – 2026-09-05 | 3 | 2026-10-20T16:04:00.3613865Z |
| 2026-09-04 – 2026-09-04 | 1 | 2026-10-20T16:04:00.3613865Z |
| 2026-09-03 – 2026-09-03 | 4 | 2026-10-20T16:04:00.3613865Z |
| 2026-09-01 – 2026-09-01 | 2 | 2026-10-20T16:04:00.3613865Z |
| 2026-08-31 – 2026-08-31 | 7 | 2026-10-20T16:04:00.3613865Z |
| 2026-08-29 – 2026-08-29 | 4 | 2026-10-20T16:04:00.3613865Z |
| 2026-08-28 – 2026-08-28 | 7 | 2026-10-20T16:04:00.3613865Z |
| 2026-08-27 – 2026-08-27 | 1 | 2026-10-20T16:04:00.3613865Z |
| 2026-08-24 – 2026-08-24 | 15 | 2026-10-20T16:04:00.3613865Z |
| 2026-08-23 – 2026-08-23 | 7 | 2026-10-20T16:04:00.3613865Z |
| 2026-08-22 – 2026-08-22 | 2 | 2026-10-20T16:04:00.3613865Z |
| 2026-08-21 – 2026-08-21 | 1 | 2026-10-20T16:04:00.3613865Z |
| 2026-08-20 – 2026-08-20 | 2 | 2026-10-20T16:04:00.3613865Z |
| 2026-08-19 – 2026-08-19 | 2 | 2026-10-20T16:04:00.3613865Z |
| 2026-08-18 – 2026-08-18 | 56 | 2026-10-20T16:04:00.3613865Z |
| 2026-08-17 – 2026-08-17 | 8 | 2026-10-20T16:04:00.3613865Z |
| 2026-08-16 – 2026-08-16 | 1 | 2026-10-20T16:04:00.3613865Z |
| 2026-08-15 – 2026-08-15 | 1 | 2026-10-20T16:04:00.3613865Z |
| 2026-08-14 – 2026-08-14 | 4 | 2026-10-20T16:04:00.3613865Z |
| 2026-08-13 – 2026-08-13 | 5 | 2026-10-20T16:04:00.3613865Z |
| 2026-08-09 – 2026-08-09 | 6 | 2026-10-20T16:04:00.3613865Z |
| 2026-08-06 – 2026-08-06 | 1 | 2026-10-20T16:04:00.3613865Z |
| 2026-08-04 – 2026-08-04 | 9 | 2026-10-20T16:04:00.3613865Z |
| 2026-08-03 – 2026-08-03 | 16 | 2026-10-20T16:04:00.3613865Z |
| 2026-08-02 – 2026-08-02 | 1 | 2026-10-20T16:04:00.3613865Z |
| 2026-08-01 – 2026-08-01 | 1 | 2026-10-20T16:04:00.3613865Z |
| 2026-07-30 – 2026-07-30 | 2 | 2026-10-20T16:04:00.3613865Z |
| 2026-07-29 – 2026-07-29 | 14 | 2026-10-20T16:04:00.3613865Z |
| 2026-07-27 – 2026-07-27 | 5 | 2026-10-20T16:04:00.3613865Z |
| 2026-07-25 – 2026-07-25 | 2 | 2026-10-20T16:04:00.3613865Z |
| 2026-07-24 – 2026-07-24 | 4 | 2026-10-20T16:04:00.3613865Z |
| 2026-07-23 – 2026-07-23 | 5 | 2026-10-20T16:04:00.3613865Z |
| 2026-07-22 – 2026-07-22 | 8 | 2026-10-20T16:04:00.3613865Z |
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 0.4.0 | 11 Jun 2026 | 1 |
This describes our collected data; it is not a security assessment.
Observed since 20 Oct, 15:35 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:1066926604ee97b6b97497bdb25cbb9849f6011e8e28033724311f16ebcea025