Skip to main content

cashio-client

Python client for the Cashio Client API (transactions and purchase payments).

Install in other projects with pip install cashio-client (after publishing) or from a local path / git URL.

کلاینت پایتون برای API کلاینت Cashio (تراکنش‌ها و پرداخت‌های خرید). قابل استفاده در پروژه‌های دیگر و قابل انتشار روی PyPI.

Install

pip install cashio-client

From this repo (editable):

pip install -e .

Quick start

from cashio_client import CashioClient

client = CashioClient("http://127.0.0.1:8000", token="YOUR_TOKEN")

result = client.transactions.create(
    amount=1500000,
    type="income",
    description="from rahkarmelk",
    date="1405-06-22",
)
print(result.ok, result.id)

Token comes from Cashio Settings → Client API Config. There is no session login.

If that config has a default fund (and category), you can omit fund / category.

Authentication

The token is sent with one method (default: Bearer header):

Method How
bearer (default) Authorization: Bearer <token>
token Authorization: Token <token>
x-api-token X-Api-Token: <token>
body JSON/form field "token": "<token>"
from cashio_client import AuthMethod, CashioClient, CashioSettings

settings = CashioSettings(
    "http://127.0.0.1:8000",
    token="YOUR_TOKEN",
    auth_method=AuthMethod.X_API_TOKEN,
)
client = CashioClient(settings)

base_url is the Cashio host (http://127.0.0.1:8000). A trailing /a/api is stripped if present. Requests go to {base_url}/a/api/....

Create a transaction

POST /a/api/transaction/create

result = client.transactions.create(
    amount=250000,
    transaction_type="expense",
    fund=15,
    category=3,
    description="rent",
    payment_type="full_payment",
)

Aliases from the API are accepted: type for transaction_type, fund_id for fund, category_id for category, holder_id for holder.

With files (multipart)

result = client.transactions.create(
    amount=1500000,
    type="income",
    attached_file=["/path/to/receipt.pdf", "/path/to/photo.jpg"],
)

attached_file may be a path, a file object, a (filename, fileobj) tuple, or a list of those.

Fields

Field Type Required
amount number / Decimal yes
transaction_type / type income or expense yes
fund / fund_id int if no default fund
category / category_id int no (client default)
description str no
date str Jalali YYYY-MM-DD no
reference_number str no
payment_type full_payment, part_payment, completed_parts no (API default full_payment)
holder / holder_id int no
transaction_linked int no
fee number no (creates a linked expense)
attached_file file(s) no

Constants: TransactionType.INCOME, TransactionType.EXPENSE, PaymentType.FULL_PAYMENT, …

Purchase payments

Two kinds: direct (already paid, invoice documents required, created as completed) and indirect (accountant pays later, documents optional, created as unseen).

from cashio_client import PurchaseKind, PurchasePaymentStatus

# direct: documents required
result = client.purchases.create_direct(
    amount=1500000,
    documents=["/path/to/invoice.jpg"],
    description="stationery",
    payment_date="1405-06-22",   # optional Jalali date, defaults to today
    request_id="INV-1",          # optional, unique per client
    lines=[
        {"description": "A4 paper", "quantity": 2, "unit": "box", "unit_price": 750000},
        {"description": "pen", "quantity": 10},
    ],
)
print(result.id, result.status)  # 11 completed

# indirect: documents optional
result = client.purchases.create_indirect(amount=300000, description="taxi", request_id="INV-2")

# read
payment = client.purchases.get(result.id)               # by id
payment = client.purchases.get(request_id="INV-2")      # by your own reference
payments = client.purchases.list(status=PurchasePaymentStatus.IN_REVIEW, kind=PurchaseKind.INDIRECT)
payment.status, payment.amount, payment.lines, payment.documents, payment.transaction_id

# lines, documents, history
client.purchases.lines(payment.id)
client.purchases.add_lines(payment.id, {"description": "stapler", "quantity": 1})        # one
client.purchases.add_lines(payment.id, [{"description": "a", "quantity": 1}, ...])      # many
client.purchases.documents(payment.id)
client.purchases.add_documents(payment.id, ["/path/to/receipt.pdf"])
client.purchases.statuses(payment.id)
Method Endpoint
purchases.create_direct(...) POST /a/api/purchase/direct/create
purchases.create_indirect(...) POST /a/api/purchase/indirect/create
purchases.list(status=, kind=) GET /a/api/purchase/list
purchases.get(id) / get(request_id=) GET /a/api/purchase/<id>/status / purchase/status?request_id=
purchases.lines(id) / add_lines(id, ...) GET / POST /a/api/purchase/<id>/lines
purchases.documents(id) / add_documents(id, files) GET / POST /a/api/purchase/<id>/documents
purchases.statuses(id) GET /a/api/purchase/<id>/statuses
  • Statuses: unseen, seen, in_review, completed (PurchasePaymentStatus).
  • Line units: piece (default), kilogram, gram, liter, meter, box, pack, set, other (PurchaseLineUnit).
  • Lines and documents of a completed payment cannot be changed (CashioAPIError).
  • Money values are returned as Decimal; dates and timestamps stay strings as sent by the API.
  • Files accept the same inputs as attached_file above.

Errors

from cashio_client import (
    CashioAuthError,
    CashioNotFoundError,
    CashioValidationError,
    CashioAPIError,
)

try:
    client.transactions.create(amount=10, type="income")
except CashioAuthError as exc:
    print(exc.status_code, exc.payload)   # 401
except CashioValidationError as exc:
    print(exc.errors)                     # {"fund": ["This field is required."]}
except CashioNotFoundError as exc:
    print(exc.status_code)                # 404 (e.g. unknown purchase payment); subclass of CashioAPIError
except CashioAPIError as exc:
    print(exc.status_code, exc.payload)   # 400 detail / 405 / other

Publish to PyPI

pip install -e ".[dev]"
python -m build
twine upload dist/*

Use TestPyPI first: twine upload --repository testpypi dist/*.

License

MIT

Metadata

Release files for cashio-client 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cashio-client 0.2.0
File Size Uploaded Provenance Actions
cashio_client-0.2.0.tar.gz 23.7 kB Without provenance Details for cashio_client-0.2.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for cashio-client 0.2.0
File Interpreter ABI Platform Actions
cashio_client-0.2.0-py3-none-any.whl Python 3 none any Details for cashio_client-0.2.0-py3-none-any.whl

Total release size: 38.6 kB

Release files / cashio_client-0.2.0.tar.gz

Download URL cashio_client-0.2.0.tar.gz
Size 23.7 kB
Tags Source
SHA-256 checksum
How to use checksums
e46f878927385d9dd0ed21b32022147e8dd80320e741dca55ee91cc11f2a0c88
BLAKE2b-256 checksum
How to use checksums
92f1dc86755d5d29d421f134e216e65b859062ee9188d16eb1f6ef702d1825d9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.4

Release files / cashio_client-0.2.0-py3-none-any.whl

Download URL cashio_client-0.2.0-py3-none-any.whl
Size 15.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
76696e69ff3447acf093865ba76518a7d46cebc5d5d74d1ba9c53fbdafb46050
BLAKE2b-256 checksum
How to use checksums
0ab80f21f2f8f75bfb02e32d45c966e8f37863b17669ab7271d6e03139f67d45
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.4

Security for cashio-client 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page