Metadata-Version: 2.4
Name: teaql
Version: 0.3.1
Summary: TeaQL Runtime and Data Service for Python
Author: TeaQL
License-Expression: Apache-2.0
Project-URL: Homepage, https://teaql.io
Project-URL: Documentation, https://teaql.io/docs
Project-URL: Repository, https://github.com/teaql/teaql-python
Project-URL: Issues, https://github.com/teaql/teaql-python/issues
Keywords: teaql,query,database,orm
Classifier: Development Status :: 3 - Alpha
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Typing :: Typed
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: pydantic>=2.0.0
Requires-Dist: aiosqlite>=0.19.0
Requires-Dist: aiomysql>=0.2.0
Requires-Dist: asyncpg>=0.29.0
Requires-Dist: httpx>=0.24.0
Requires-Dist: cryptography>=42.0.0
Provides-Extra: telemetry
Requires-Dist: opentelemetry-api<2,>=1.44.0; extra == "telemetry"
Requires-Dist: opentelemetry-sdk<2,>=1.44.0; extra == "telemetry"
Requires-Dist: opentelemetry-exporter-otlp-proto-http<2,>=1.44.0; extra == "telemetry"
Requires-Dist: opentelemetry-instrumentation-logging<0.66,>=0.65b0; extra == "telemetry"
Provides-Extra: test
Requires-Dist: pytest>=7.0.0; extra == "test"
Requires-Dist: pytest-asyncio>=0.21.0; extra == "test"
Requires-Dist: mypy>=1.0.0; extra == "test"
Requires-Dist: opentelemetry-sdk<2,>=1.44.0; extra == "test"
Requires-Dist: opentelemetry-instrumentation-logging<0.66,>=0.65b0; extra == "test"
Dynamic: license-file

# TeaQL Python

An AI-native library and runtime for building reviewable business applications in Python.

TeaQL gives coding agents business-shaped APIs, model-aware guidance and
software checks. People review the business operation instead of reconstructing
pages of query-building, relationship-loading and persistence code.

Automatic execution logs make those operations easier to debug and operate,
without adding logging statements to every business method.

[Try with your coding agent](#try-it-with-your-coding-agent) ·
[Run the local example](#run-the-local-example) ·
[See automatic logs](#automatic-logs-without-handwritten-logging-code)

## Why this is an AI native library

AI-native does not mean the library was written by AI, or that every query
calls an LLM. It means the APIs, knowledge delivery and verification workflow
are designed for how coding agents work: limited context, incomplete knowledge
of a project and a tendency to guess unfamiliar operations.

The semantic model describes your business objects, fields, relationships and
states. A generated domain library turns those words into language-native
**Q** queries, **E** expressions and mutation methods. This repository provides
the reusable, domain-independent **runtime** that executes them through
metadata, Context, Checker, Policy and database providers.

The application workspace keeps business code and concise project guidance
together. Progressive **Assist** supplies the exact API guidance needed for
the next operation, instead of asking the agent to explore the entire generated
library. Compilation, runtime checks and tests provide feedback beyond a prompt.

## Less code for a reviewer to reconstruct

The benefit is visible in the application code: the query, data access path
and audited change stay together, while shared mechanics live in the library
and runtime.

| Application code to review | Shared work handled by TeaQL |
| --- | --- |
| A composed Q request | SQL construction and selected relation loading |
| An E access path | Loaded-field checks and explicit NULL handling |
| A mutation with an audit reason | Change tracking, Checker and configured Policy execution |
| Business intent and audit reason | Automatic execution logs and trace context without per-operation logging code |

Reviewers still decide whether the requested data, business rules and
authorization policy are correct. They have less application plumbing to
trace before making that decision; reuse does not make business logic correct
automatically.

**Token savings have not yet been measured in a controlled comparison.**
We make no numerical token-saving claim. Loading guidance only when needed
is a context-management strategy; the smaller application review surface is
visible in the examples, not a measured percentage reduction in review time.

## See a business operation execute

The [Robot Task Board showcase](https://teaql.io/blog/robot-task-board-showcase/)
makes the idea concrete: move a task and follow the state change, generated
SQL, field-level audit and refreshed board.

![TeaQL Robot Task Board](https://teaql.io/img/003-task-board.png)

Explore the [open-source demo](https://github.com/teaql/robot-task-board).
The showcase is a Rust application; the examples below use this repository's
own Python APIs.

## Q API composes business queries

These application-code excerpts assume the example's generated imports, trusted
Context and an existing object identity. `Q` and `E` belong to the generated
domain library, not a generic runtime object with arbitrary field strings.
See the [application source](examples/school-management/app/main.py) for complete setup.

```python
def school_type_details():
    return Q.school_types_minimal().select_name().select_code()

school = await (
    Q.schools().with_id_is(school_id)
    .select_platform_with(Q.platforms_minimal().select_name().select_base_url())
    .select_school_type_with(school_type_details())
    .comment("what: load the school and its reference data")
    .purpose("why: review a school before editing")
    .execute_for_one(context)
)
if school is None:
    raise ValueError("School not found")
```

The child request is a query in its own right. Give it a business name,
extract it into a helper and compose it into other requests like a Lego brick.
The reviewer can see which relationships are loaded without following a
separate set of SQL loops. `comment` describes **what**; `purpose` describes
**why**. Both must be non-empty, even when logging is disabled.

## E API protects business reads

```python
type_code = E.school(school).school_type().code().eval()
```

E reads the loaded graph without implicitly querying the database. A loaded
NULL and a field that was **NotLoaded** are different facts. A business rule
must not conclude that a value is absent merely because the query never
requested it.

The access path is explicit, so the reviewer checks whether Q loaded the
required data and whether the code handles a real NULL appropriately.
Unloaded access produces the language-specific diagnostic; a NULL fallback
is not permission to ignore an unloaded property.

## Mutation API keeps changes behind one Save boundary

The application declares the change and its reason instead of writing its own
persistence loop. A graph can stage additions, updates and deletions before Save.

Load the complete scalar fields of every persisted object you actually modify.
A display-only partial projection is not a complete mutation input. Unmodified
reference objects do not have to become fully loaded just to save their parent.

```python
school.update_name("Riverside Academy")
await school.audit_as("Rename the reviewed school").save(context)
```

Save traverses the reached mutation graph, runs Checker/Fix and the configured
customer Mutation Policy, then uses the provider transaction boundary.
An explicit policy denial blocks persistence. Missing customer policy or exact
approval emits a warning; it is not automatic rejection. Marking for deletion
stages a change—the audited Save performs it. Atomicity is provider/route scoped,
not a distributed transaction across unrelated databases.

## Automatic logs without handwritten logging code

**Debuggability and operability are core design goals.** The Q and Save
examples above contain no logging calls: you declare the business intent,
and the runtime produces the execution diagnostics and trace context.
Configured audit sinks receive change events without each application
method having to construct its own field-level diff.

The intent declarations already belong to the business operation:

- `comment` describes what the query does.
- `purpose` explains why it runs.
- `audit_as` gives the reason for a saved change.

No-code logging means no handwritten logger calls in each business method,
not an application without code or intent declarations. Runtime startup
still configures any required sink; custom formats and destinations use the
logging extension points rather than edits to every business operation.

- **Debugging:** connect a query's intent to generated SQL, execution outcome
  and the trace path when a screen or business operation behaves unexpectedly.
- **Operations:** follow query and mutation activity and use audit reasons
  and safely exposed changes to investigate incidents.
- **Review:** inspect the business operation without separately checking
  that every TeaQL execution path has a matching application logging statement.

Query and Mutation diagnostic logs are enabled by default and can be switched
off independently. Logging off does not disable intent validation or Policy.

Illustrative, shortened view of the rename operation, not a literal logger
format or a captured test result; the SQL excerpt omits additional selected fields:

```text
query entity=School comment="load the reviewed object" purpose="edit form" outcome=success
SQL: SELECT id, version, name FROM school_data WHERE id = 42;
trace: School -> request -> sqlite -> select
mutation entity=School auditReason="Rename the reviewed school" outcome=committed
change: name "Riverside Primary School" -> "Riverside Academy"
lineage: School#42("Rename the reviewed school")
```

The declarations explain **why**; SQL and audit evidence show **what happened**.
Together they help locate the relevant operation without reconstructing the
entire call path from scattered application code.

SQL execution stays parameterized. Diagnostic SQL has parameters substituted
after field-aware masking; it is not a question-mark template you must manually
reconstruct. Ordinary bindings stay visible, sensitive bindings use the shared
mask algorithm, and credentials/unknown bindings stay hidden. A masked statement
is labeled `MASKED; NOT REPLAYABLE`; SQL that cannot be safely rendered is omitted.
Application mutation audits are delivered after commit and discarded on rollback.
This is not a durable audit outbox. Do not put secrets in comment or purpose.

## Discover only the API needed next

A coding agent does not need every generated method in its context. Start with
the generated application's `AGENTS.md` and workspace guidance, request an
entity/action Assist, then ask for field-specific help only for the field
being used.

For a model in `models/`, the Python query path is:

```bash
cargo teaql python-assist-query/school --input models/
cargo teaql python-assist-query/school.established_date --input models/
```

These commands call the model-aware service; the model must match the generated
library. Assist uses canonical KSML entity and field names, even when the
language-native API uses a different naming style. Cargo TeaQL is a service
client for multiple languages, not just Rust.

Use Assist to discover operations instead of reading generated library source
or guessing names. If the required operation is missing, report
`MISSING_ASSIST` rather than inventing an API. The
[Agent Kit](https://github.com/teaql/teaql-agent-kit) defines this progressive
workflow. Library and runtime maintenance are separate from application coding.

## Software checks complement agent instructions

AI proposes the model and application logic; software checks the parts that
can be verified mechanically. The library is one part of the TeaQL harness,
not a replacement for business review.

| Stage | TeaQL support | Feedback to inspect |
| --- | --- | --- |
| Model and repair | Semantic model evaluation | Errors, warnings and repair guidance |
| Generate | Domain library combined with this runtime | Language tooling checks the generated API contract |
| Customize the workspace | Progressive Assist, Q, E and mutation APIs | Build diagnostics, Checker and configured Policy results |
| Verify and operate | Tests, runtime startup, intent and audit evidence | Actual outcomes, remaining failures and execution paths |

Python annotations describe the API but are not a Rust-style compile-time
guarantee. Runtime checks and tests must verify the application's behavior.
A prompt, successful generation or a clean build alone does not prove the
finished application correct.

## Try it with your coding agent

You can start with an agent you already use. Paste this prompt:

```text
Follow the current instructions at https://github.com/teaql/teaql-agent-kit.
Build a small school-management application in Python using SQLite.
Evaluate and repair the model, generate the domain library and prepare a runnable
application workspace. Verify Q, E, Checker and audited Save.
Finish with a report of commands, results and
remaining frictions. Include Q/E examples and relevant intent/audit logs.
Do not claim token savings without a measured comparison.
```

The [Agent Kit](https://github.com/teaql/teaql-agent-kit) guides modeling,
evaluation/repair, generation and application customization. It may install
toolchains and download dependencies; review installation permissions and the
final execution report. It is a workflow, not a guarantee of unattended correctness.

## Run the local example

Python 3.10+; Python 3.12+ is recommended. Async SQL execution uses the selected provider driver. From a checkout of this repository:

```bash
python -m venv .venv
. .venv/bin/activate
python -m pip install -e .
export PYTHONPATH="$PWD/src"
(cd examples/school-management && python -m app.main)
```

The [School example](examples/school-management/README.md)
exercises SQLite schema/bootstrap and generated application APIs against this
repository's local runtime. No external database server or generator is needed
to run the retained generated example. Use only the example's test database;
reset/repeated-run behavior is documented in its README.

## Optional standard OpenTelemetry module

The local standard-module changes are not yet released. Install the optional
SDK dependencies from this checkout when testing telemetry:

```bash
python -m pip install -e '.[telemetry]'
export TEAQL_TELEMETRY_ENABLED=true
export TEAQL_TELEMETRY_SERVICE_NAME=my-application
export TEAQL_TELEMETRY_OTLP_ENDPOINT=http://localhost:4318
```

`UserContext` initializes the standard module automatically. Without enablement,
startup prints support and the three variable names without importing the SDK.
Enabled telemetry records supported operations without percentage sampling,
using private providers that do not replace customer globals. Expanded SQL uses
the existing masking rules. Disabling ordinary SQL logging does not disable
telemetry or committed audit. Queues and export lifetimes are bounded; failed
export does not fail business operations.

The [standard Order example](examples/trace-chain/standard-order/main.py)
uses generated Q and E to load a bounded list, forward detail, reverse previews,
full child counts and status facets. Explicit count is optional; both variants
use `execute_for_list(context)` and one root through entity construction.
Its gate runs twice on one SQLite file and verifies audited, idempotent bootstrap:

```bash
PYTHONDONTWRITEBYTECODE=1 bash scripts/verify-examples.sh
```

The [standard graph example](examples/trace-chain/standard_graph.py) saves six
related entities, performs five updates and one deletion, then verifies rollback
and retry. One automatic graph root covers the transaction, committed audit and
cleanup; each SQL completion carries its actual execution span. Child comments
remain local or inherit the root. No application SDK setup or manual spans are
needed. The example keeps ordinary SQL logging off and preserves the original
business error without exporting its message.

```bash
bash examples/trace-chain/verify-standard-graph.sh
```

Current local qualification passes 844 tests with eight configured skips, all
eleven example groups and fresh-generation checks. The migrated TraceChain and
Order libraries use ordinary list execution, isolated row ledgers and reached-only
graph adoption. Runtime-owned original scalar snapshots protect log/audit intent
after changes or deletion.

Ten actual OTLP response scenarios qualify failed export, partial acceptance,
warnings and invalid acknowledgements across traces, logs and metrics. Official
protobuf encoding/decoding uses private HTTP connections, with no change to
customer log settings. Requests have a three-second attempt budget, no retry or
redirect, and four-MiB response limits. Remote status/header/body text does not
leak even under DEBUG. Failed MetricData objects and receiver-rejected metric
points are counted separately. Cumulative health metrics follow record settlement
and include a final shutdown snapshot; export failure preserves business and audit.
Default span/log admission counts queued and exporting records in one 2,048-record
budget, with visible overflow. Successful handoffs define the flush prefix;
later completions cannot replace older accepted work. Real generated Q/E pressure
qualifies recovery and backlog shutdown in about six seconds, separating failed
attempts from queued retirement. Post-shutdown reads stay functional and late
completions are counted without fake SQL correlation. Generated streams explicitly
close their owned cursor, rather than relying on garbage collection.
The [standard scalar-stream example](examples/trace-chain/standard_stream.py)
verifies complete delivery of three rows, early close after one row with chunk
size two, an independent query between suspended cursors and an unpolled stream.
Runtime owns the logical root, actual SQL correlation and delivered cardinality;
activation exists only during poll/close. Neither idle nor unpolled streams
capture unrelated work. Generated requests retain creation-time query semantics.

```bash
bash examples/trace-chain/verify-standard-stream.sh
```

Actual failure/cancellation backend variants, advanced concurrency/lifecycle and
internal-artifact qualification remain separate gates. Relation/facet-enhanced
streaming is explicitly unsupported.

Current qualification uses local source, not an installed public artifact.

## Use the published runtime

Current documented runtime: **0.3.0**. Keep domain-library and runtime
versions compatible; regenerate older libraries when their provider or graph
adapter SPI has changed.

```bash
python -m pip install teaql==0.3.0
```

Generation is a separate service; see the [Agent Kit](https://github.com/teaql/teaql-agent-kit)
for producing the application-specific library and workspace. Repository examples
use local source; isolated released-package regression is a separate gate.

## Supported scope

Python provides asynchronous local SQL execution and a TFP client, not a public TFP server endpoint. Generated classes and expressions expose model-aware APIs; Python annotations are not a Rust-style compile-time guarantee. Provider and advanced-feature coverage is tracked explicitly in conformance.

One semantic model can produce language-native applications across
[Java](https://github.com/teaql/teaql-java),
[Rust](https://github.com/teaql/teaql-rs),
[TypeScript](https://github.com/teaql/teaql-ts),
[Go](https://github.com/teaql/teaql-golang),
[Swift](https://github.com/teaql/teaql-swift),
[.NET](https://github.com/teaql/teaql-dotnet) and
[Python](https://github.com/teaql/teaql-python).
That does not imply identical APIs, providers or complete cross-language feature parity.
The semantic model defines business objects, fields, relationships and states;
it is not the language model used by a coding agent.
The [conformance matrices](https://github.com/teaql/teaql-conformance)
distinguish implemented source, executed examples, artifact verification and release.

## Verification and customization

```bash
python -m pip install -e '.[test]'
PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=src python -m pytest -q
PYTHONDONTWRITEBYTECODE=1 bash scripts/verify-examples.sh
```

The full example gate is the acceptance entry point for local runtime changes.
External-provider tests need their configured services; skips are not live-provider
evidence. A committed-operation error after audit delivery failure must not be
retried as if the business transaction rolled back.

Install application-owned policies, ID/business-ID services, logging sinks,
transports and other supported SPIs through trusted runtime/Context setup.
Request JSON is not allowed to replace those trusted capabilities.

- [Runtime guide: modules, SPI and advanced verification](RUNTIME_GUIDE.md)
- [Modules and providers](RUNTIME_GUIDE.md#3-available-modules)
- [Mutation Policy example](examples/mutation-policy)
- [Facet example](examples/facet-trace/README.md)
- [Opaque reference example](examples/opaque-entity-reference)

## Safe troubleshooting

Default diagnostics do not authorize plaintext sensitive data. Controlled
debugging requires the exact acknowledgement below and any sensitive sink
required by the runtime:

```bash
export TEAQL_ALLOW_SENSITIVE_PLAINTEXT_LOGS=I_UNDERSTAND_SENSITIVE_DATA_MAY_BE_WRITTEN_TO_DISK
```

Debug output is explicitly labeled. Credentials and unknown bindings remain
protected; the flag does not erase old files or govern application/driver
prints outside TeaQL. Restrict access and retention, then unset it and restart.
See the [runtime guide](RUNTIME_GUIDE.md) for log switches and extension details.
