Catalog PyPI
Back to packageRELEASE DETAILS

0.0.28

PyPI

aaiclick

Data orchestration framework on ClickHouse: plain-Python pipelines, dynamic task graphs, containerized runs, lineage over MCP

analyticsbigclickhousedatalineagemcporchestrationpipelineprocessing
Published3 Oct 2026
Direct dependencies30
Transitive dependenciesNot calculated

README

Version 0.0.28 documentation
aaiclick logo

aaiclick

aaiclick is a data orchestration framework built to make distributed computing easy, with five principles in mind:

  1. Simplicity — Plain Python, no SQL. Decorate functions into tasks and jobs, run with zero setup on your laptop, scale out unchanged.
  2. Dynamic Graphs — Tasks spawn tasks. The pipeline shapes itself to the data while it runs instead of being declared up front.
  3. Performance — Data lives and computes in ClickHouse. Python only orchestrates; nothing is shuffled through Python memory.
  4. Containerized Runs — Pin a container image, by tag or git SHA, per job or per task. Host and container tasks mix in one pipeline.
  5. Lineage over MCP — Every operation is recorded. Your coding agent (Claude Code, Codex, any MCP client) answers "how did this value get here?" straight from the lineage.

Early stage — looking for early adopters to join the ride and provide feedback.

Installation

The base install includes embedded chdb and SQLite — no external servers needed:

pip install aaiclick
python -m aaiclick setup

For a distributed deployment (remote ClickHouse server + PostgreSQL):

pip install "aaiclick[distributed]"

For lineage triage with your coding agent (Claude Code, Codex, any MCP client):

pip install "aaiclick[server]"   # or all extras: pip install "aaiclick[all]"
python -m aaiclick local start   # REST + MCP server on http://127.0.0.1:5255

Then point the agent at http://127.0.0.1:5255/mcp — see the Lineage guide.

Orchestration

Define tasks and jobs with decorators — all data operations execute as ClickHouse queries:

from aaiclick import create_object_from_value
from aaiclick.orchestration import job, task

@task
async def load_sales():
    return await create_object_from_value({
        "region": ["US", "EU", "US", "EU", "US"],
        "amount": [500, 300, 150, 200, 80],
    })

@task
async def analyze(sales) -> dict:
    # GROUP BY + SUM runs as a single ClickHouse query; return a plain dict
    by_region = await sales.group_by("region").sum("amount")
    return await by_region.data()  # → {'region': ['US', 'EU'], 'amount': [730, 500]}

@task
async def report(summary: dict):
    # receives the plain Python dict returned by analyze()
    print(f"Regions: {summary['region']}")  # → Regions: ['US', 'EU']
    print(f"Amounts: {summary['amount']}")  # → Amounts: [730, 500]
    print(f"Total:   {sum(summary['amount'])}")  # → Total: 1230

@job("sales_pipeline")
def sales_pipeline():
    sales = load_sales()                # a Task, not data — nothing runs yet
    summary = analyze(sales=sales)      # gets the sales task's return value at runtime
    return report(summary=summary)      # the dict flows to report()

if __name__ == "__main__":
    from aaiclick.orchestration import job_test
    job_test(sales_pipeline)  # runs all tasks locally for debugging
python sales_pipeline.py

Data Operation Only Mode

Use data_context() directly for interactive work without orchestration. Decorate an async function to wrap its whole body in a context:

import asyncio
from aaiclick import create_object_from_value
from aaiclick.data.data_context import data_context

@data_context()
async def main():
    prices = await create_object_from_value([10.0, 20.0, 30.0])

    total = prices * 1.1                         # LazyOperator — no DB call yet
    print(await total.data())                    # → [11.0, 22.0, 33.0]
    print(await total.mean().data())             # → 22.0

asyncio.run(main())

data_context() also works as an async with block when you only need part of a function inside the context.

Documentation

aaiclick.readthedocs.io

License

MIT License - see LICENSE for details.

Downloads & popularity

Awaiting observations

No metric observations yet

Download counts and popularity will appear here as the collector receives them.

Declared dependencies 31

Native requirements
30 direct targetsNot calculated transitive count
Package / targetRequirementRelationship
pyarrow
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
pyarrow>=23.0.0runtime
python-dotenv
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
python-dotenv>=1.2.0runtime
pyyaml
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
pyyaml>=6.0.3runtime
pydantic
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
pydantic>=2.12.0runtime
sqlmodel
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
sqlmodel>=0.0.38runtime
alembic
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
alembic>=1.18.0runtime
chdb
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
chdb>=4.3.0runtime
aiosqlite
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
aiosqlite>=0.22.0runtime
greenlet
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
greenlet>=3.0.0runtime
croniter
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
croniter>=6.0.0runtime
bcrypt
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
bcrypt>=4.2.0runtime
pyjwt
Environment
{
  "extras": "",
  "marker": null,
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
pyjwt>=2.10.0runtime
clickhouse-connect
Environment
{
  "extras": "",
  "marker": "extra == \"distributed\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
clickhouse-connect>=1.0.1; extra == "distributed"runtime
aiohttp
Environment
{
  "extras": "",
  "marker": "extra == \"distributed\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
aiohttp>=3.9.0; extra == "distributed"runtime
asyncpg
Environment
{
  "extras": "",
  "marker": "extra == \"distributed\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
asyncpg>=0.31.0; extra == "distributed"runtime
psycopg2-binary
Environment
{
  "extras": "",
  "marker": "extra == \"distributed\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
psycopg2-binary>=2.9.11; extra == "distributed"runtime
fastapi
Environment
{
  "extras": "",
  "marker": "extra == \"server\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
fastapi>=0.115.0; extra == "server"runtime
uvicorn
Environment
{
  "extras": "standard",
  "marker": "extra == \"server\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
uvicorn[standard]>=0.30.0; extra == "server"runtime
fastmcp
Environment
{
  "extras": "",
  "marker": "extra == \"server\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
fastmcp>=2.12.0; extra == "server"runtime
aaiclick
Environment
{
  "extras": "distributed,server",
  "marker": "extra == \"all\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
aaiclick[distributed,server]; extra == "all"runtime
httpx
Environment
{
  "extras": "",
  "marker": "extra == \"test\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
httpx>=0.27.0; extra == "test"runtime
pytest
Environment
{
  "extras": "",
  "marker": "extra == \"test\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
pytest>=9.0.0; extra == "test"runtime
pytest-asyncio
Environment
{
  "extras": "",
  "marker": "extra == \"test\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
pytest-asyncio>=1.3.0; extra == "test"runtime
pytest-cov
Environment
{
  "extras": "",
  "marker": "extra == \"test\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
pytest-cov>=7.1.0; extra == "test"runtime
pytest-xdist
Environment
{
  "extras": "",
  "marker": "extra == \"test\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
pytest-xdist>=3.8.0; extra == "test"runtime
pytest-split
Environment
{
  "extras": "",
  "marker": "extra == \"test\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
pytest-split>=0.10.0; extra == "test"runtime
mkdocs
Environment
{
  "extras": "",
  "marker": "extra == \"docs\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
mkdocs>=1.6.1; extra == "docs"runtime
mkdocs-material
Environment
{
  "extras": "",
  "marker": "extra == \"docs\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
mkdocs-material>=9.7.0; extra == "docs"runtime
aaiclick
Environment
{
  "extras": "all,test",
  "marker": "extra == \"dev\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
aaiclick[all,test]; extra == "dev"runtime
playwright
Environment
{
  "extras": "",
  "marker": "extra == \"dev\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
playwright>=1.56.0; extra == "dev"runtime
pre-commit
Environment
{
  "extras": "",
  "marker": "extra == \"dev\"",
  "requires_python": ">=3.10",
  "evaluation": "NOT_EVALUATED"
}
pre-commit>=4.0; extra == "dev"runtime

Distribution files

2 collected
aaiclick-0.0.28-py3-none-any.whl

bdist_wheel · 988.78 KB · Python py3

Source file
aaiclick-0.0.28.tar.gz

sdist · 1,733.69 KB · Python source

Source file

Repository

PENDING
kolodkin/aaiclick

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 16:56 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package_version:27583fc6ff8371f44bfc3a4827f090cc5ffed0db8793667991c66b5f583b140f

Other collected versions

View all collected versions →