Skip to main content

Self-hosted data ingestion framework — extract, transform, and load data from anywhere.

Project description

🪷 Lotos

Self-hosted data ingestion framework — extract, transform, and load data from anywhere.

Lotos is a lightweight, YAML-driven ETL framework built with Python. Define pipelines as configuration, not code.


Features

  • YAML-based pipelines — declarative, version-controlled, easy to read
  • Pluggable architecture — connectors, transforms, and sinks are auto-discovered via a registry
  • Source connectors — SQL databases, REST APIs, local/remote files (CSV, JSON, Parquet)
  • Transform chain — select, rename, cast, filter, deduplicate, flatten, SQL transforms, computed columns, custom expressions, and schema validation
  • Destination sinks — local files, Azure Blob Storage, Azure Data Lake Storage Gen2
  • Secret resolution — reference environment variables or .env values with ${SECRET:KEY} syntax
  • Incremental loading — watermark-based extraction for processing only new/changed rows
  • Structured logging — powered by structlog with JSON or console output
  • CLI interface — run, validate, inspect, and scaffold pipelines from the terminal

Installation

pip install -e .

With optional dependencies:

pip install -e ".[azure]"       # Azure Blob / ADLS Gen2
pip install -e ".[postgres]"    # PostgreSQL
pip install -e ".[mysql]"       # MySQL
pip install -e ".[all]"         # Everything
pip install -e ".[dev]"         # Dev tools (pytest, ruff)

Requires Python 3.11+


Quick Start

1. Generate a pipeline template

lotos init my_pipeline --source sql

2. Edit the YAML

pipeline:
  name: my_pipeline
  description: "Extract customers and clean data"
  version: "1.0"

source:
  connector: sql
  config:
    connection_string: "mysql+pymysql://user:pass@localhost:3306/mydb"
    query: "SELECT * FROM customers"

transforms:
  - type: select_columns
    config:
      columns: [id, name, email, created_at]

  - type: deduplicate
    config:
      subset: [id]
      keep: last

sink:
  connector: file
  config:
    path: "output/customers.parquet"
    format: parquet
  write_mode: overwrite

3. Run it

lotos run pipelines/my_pipeline.yaml --log-level INFO

CLI Commands

Command Description
lotos run <file> Run a pipeline
lotos validate <file> Validate YAML without running
lotos inspect <file> Show pipeline details
lotos init <name> Generate a pipeline template
lotos list connectors List available source connectors
lotos list transforms List available transforms
lotos list sinks List available destination sinks
lotos list all List everything

Run options

--output, -o       Save result to file (csv/json/parquet)
--format, -f       Output format (default: parquet)
--dry-run          Extract + transform only, skip sink
--log-level, -l    DEBUG, INFO, WARNING, ERROR
--log-format       console or json

Connectors

Name Type Description
sql Source Any SQLAlchemy-compatible database
rest_api Source REST APIs with pagination & auth
file Source CSV, JSON, Parquet (local or Azure Blob)
file Sink Write to local files or Azure Blob
adls_gen2 Sink Azure Data Lake Storage Gen2 / Blob Storage

ADLS Gen2 Sink

The adls_gen2 sink supports both Azure storage modes via the hierarchical_namespace option:

sink:
  connector: adls_gen2
  config:
    account_name: "mystorageaccount"
    container_name: "mycontainer"
    directory_path: "data/output"
    file_name: "results"
    format: parquet
    hierarchical_namespace: false  # false = Blob API, true = Data Lake (DFS) API
    account_key: "${SECRET:ADLS_KEY}"
  write_mode: overwrite

Transforms

Name Description
select_columns Keep only specified columns
rename_columns Rename columns via a mapping
cast_types Cast column data types
filter_rows Filter rows by conditions
deduplicate Remove duplicate rows
flatten Flatten nested structs/lists
sql Run SQL queries (Polars SQL — no DB needed)
computed Add computed columns with expressions
custom Apply a custom Python expression
validate_schema Validate column types and constraints

Project Structure

lotos/
├── cli.py                  # CLI (Typer)
├── config/                 # Settings, logging, secrets
├── connectors/             # Source connectors (SQL, REST, file)
├── core/                   # Pipeline engine, models, registry
├── sinks/                  # Destination sinks (file, ADLS Gen2)
├── transforms/             # Transform plugins
└── monitoring/             # Monitoring (placeholder)
pipelines/                  # Pipeline YAML definitions
tests/                      # Test suite

Development

pip install -e ".[dev]"
pytest
ruff check .

License

Artefact

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

lotos-0.1.0.tar.gz (44.4 kB view details)

Uploaded Source

Built Distribution

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

lotos-0.1.0-py3-none-any.whl (45.4 kB view details)

Uploaded Python 3

File details

Details for the file lotos-0.1.0.tar.gz.

File metadata

  • Download URL: lotos-0.1.0.tar.gz
  • Upload date:
  • Size: 44.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.0

File hashes

Hashes for lotos-0.1.0.tar.gz
Algorithm Hash digest
SHA256 6a48b738a6c1a477c0c777650ac4b69555b558adf49b21e4dde8cb97db7a8edb
MD5 5ca58214ec3509134443bf766076eddc
BLAKE2b-256 c5c4470e4d8389488a9b36400a75bfc183d2883a3434e0c1260a2e0074e0984c

See more details on using hashes here.

File details

Details for the file lotos-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: lotos-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 45.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.0

File hashes

Hashes for lotos-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 cb074c10cfefd7a75102e23de3065de408733d2002185547d1451873dae84051
MD5 ffc499e69a8d4bd2585935cba7de9b5e
BLAKE2b-256 6fb8a83c499fbe331f36aef4b13ad0b1da9f4a2e626eaa2d125791006ae469dd

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