Observed since 20 Oct, 16:56 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
aaiclick
Data orchestration framework on ClickHouse: plain-Python pipelines, dynamic task graphs, containerized runs, lineage over MCP
aaiclick is a data orchestration framework built to make distributed computing easy, with five principles in mind:
Early stage — looking for early adopters to join the ride and provide feedback.
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.
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
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.
MIT License - see LICENSE for details.
Download counts and popularity will appear here as the collector receives them.
| Package / target | Requirement | Relationship |
|---|---|---|
pyarrowEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | pyarrow>=23.0.0 | runtime |
python-dotenvEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | python-dotenv>=1.2.0 | runtime |
pyyamlEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | pyyaml>=6.0.3 | runtime |
pydanticEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | pydantic>=2.12.0 | runtime |
sqlmodelEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | sqlmodel>=0.0.38 | runtime |
alembicEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | alembic>=1.18.0 | runtime |
chdbEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | chdb>=4.3.0 | runtime |
aiosqliteEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | aiosqlite>=0.22.0 | runtime |
greenletEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | greenlet>=3.0.0 | runtime |
croniterEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | croniter>=6.0.0 | runtime |
bcryptEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | bcrypt>=4.2.0 | runtime |
pyjwtEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | pyjwt>=2.10.0 | runtime |
clickhouse-connectEnvironment{
"extras": "",
"marker": "extra == \"distributed\"",
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | clickhouse-connect>=1.0.1; extra == "distributed" | runtime |
aiohttpEnvironment{
"extras": "",
"marker": "extra == \"distributed\"",
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | aiohttp>=3.9.0; extra == "distributed" | runtime |
asyncpgEnvironment{
"extras": "",
"marker": "extra == \"distributed\"",
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | asyncpg>=0.31.0; extra == "distributed" | runtime |
psycopg2-binaryEnvironment{
"extras": "",
"marker": "extra == \"distributed\"",
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | psycopg2-binary>=2.9.11; extra == "distributed" | runtime |
fastapiEnvironment{
"extras": "",
"marker": "extra == \"server\"",
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | fastapi>=0.115.0; extra == "server" | runtime |
uvicornEnvironment{
"extras": "standard",
"marker": "extra == \"server\"",
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | uvicorn[standard]>=0.30.0; extra == "server" | runtime |
fastmcpEnvironment{
"extras": "",
"marker": "extra == \"server\"",
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | fastmcp>=2.12.0; extra == "server" | runtime |
aaiclickEnvironment{
"extras": "distributed,server",
"marker": "extra == \"all\"",
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | aaiclick[distributed,server]; extra == "all" | runtime |
httpxEnvironment{
"extras": "",
"marker": "extra == \"test\"",
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | httpx>=0.27.0; extra == "test" | runtime |
pytestEnvironment{
"extras": "",
"marker": "extra == \"test\"",
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | pytest>=9.0.0; extra == "test" | runtime |
pytest-asyncioEnvironment{
"extras": "",
"marker": "extra == \"test\"",
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | pytest-asyncio>=1.3.0; extra == "test" | runtime |
pytest-covEnvironment{
"extras": "",
"marker": "extra == \"test\"",
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | pytest-cov>=7.1.0; extra == "test" | runtime |
pytest-xdistEnvironment{
"extras": "",
"marker": "extra == \"test\"",
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | pytest-xdist>=3.8.0; extra == "test" | runtime |
pytest-splitEnvironment{
"extras": "",
"marker": "extra == \"test\"",
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | pytest-split>=0.10.0; extra == "test" | runtime |
mkdocsEnvironment{
"extras": "",
"marker": "extra == \"docs\"",
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | mkdocs>=1.6.1; extra == "docs" | runtime |
mkdocs-materialEnvironment{
"extras": "",
"marker": "extra == \"docs\"",
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | mkdocs-material>=9.7.0; extra == "docs" | runtime |
aaiclickEnvironment{
"extras": "all,test",
"marker": "extra == \"dev\"",
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | aaiclick[all,test]; extra == "dev" | runtime |
playwrightEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | playwright>=1.56.0; extra == "dev" | runtime |
pre-commitEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.10",
"evaluation": "NOT_EVALUATED"
} | pre-commit>=4.0; extra == "dev" | runtime |
bdist_wheel · 988.78 KB · Python py3
sdist · 1,733.69 KB · Python source
Observed since 20 Oct, 16:56 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package_version:27583fc6ff8371f44bfc3a4827f090cc5ffed0db8793667991c66b5f583b140f