Metadata-Version: 2.4
Name: a-ledger
Version: 0.3.0
Summary: Application-neutral double-entry ledger SDK backed by SQLite
Author: realqiyan
License-Expression: MIT
Project-URL: Homepage, https://github.com/realqiyan/a-ledger
Project-URL: Repository, https://github.com/realqiyan/a-ledger
Project-URL: Issues, https://github.com/realqiyan/a-ledger/issues
Keywords: ledger,accounting,double-entry,sqlite,bookkeeping
Classifier: Development Status :: 4 - Beta
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Office/Business :: Financial :: Accounting
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: SQLAlchemy<2.1,>=2.0
Provides-Extra: dev
Requires-Dist: build>=1; extra == "dev"
Requires-Dist: pytest>=8; extra == "dev"
Requires-Dist: twine>=5; extra == "dev"
Dynamic: license-file

# a-ledger

Embedded Python accounting SDK for a-options and a-trader. It owns balanced
journal facts, correction history, lot computation, reservations and batch reads.
Applications own business data and compose it through explicit ledger identifiers.

## Use

```python
from sqlalchemy import create_engine, event
from a_ledger import Ledger
from a_ledger.schema import install

engine = create_engine("sqlite:///accounts.db")

@event.listens_for(engine, "connect")
def configure_sqlite(dbapi_connection, _):
    dbapi_connection.isolation_level = None
    dbapi_connection.execute("PRAGMA foreign_keys=ON")

@event.listens_for(engine, "begin")
def begin_sqlite(connection):
    connection.exec_driver_sql("BEGIN")

with engine.begin() as connection:
    install(connection)  # Explicit installation on an empty/current store.
    ledger = Ledger(connection)
    ledger.accounts.create_portfolio("main", code="main", currency="CNY")
    ledger.accounts.create_account(
        "cash", portfolio_id="main", code="cash", category="ASSET"
    )
```

The caller owns the connection and outer transaction. Use the same connection
for application writes and SDK calls; the SDK never commits that transaction.
All posting, replacement and reversal commands use `ledger.journal`.

- [Public contracts](docs/sdk-interface-design.md)
- [Data model and business references](docs/ledger-data-model.md)
- [Ledger page queries](docs/ledger-page-design.md)
- [Whole-source option booking](docs/options-booking-design.md)
- [Domain terminology](CONTEXT.md)

## Verification

Run `.venv/bin/python -m pytest`. Source and test modules are limited to 500
physical lines. Tests use synthetic data and public accounting interfaces.
Normal startup and restore support the current schema; historical audit evidence
and command identities remain immutable.
