Django TOConline
A Django integration and complete OpenAPI client for Portugal's TOConline commercial API.
The package persists OAuth2 tokens and exposes a complete spec-driven OpenAPI client. It returns Pydantic models for documented successful response schemas and raw JSON when the OpenAPI document does not provide a response schema. An opt-in resource view also flattens recognised JSON:API responses for concise application code.
Official sources:
Compatibility
| Django | Python |
|---|---|
| 5.2 | 3.10–3.14 |
| 6.0 | 3.12–3.14 |
Django 6.0 itself requires Python 3.12 or newer. The package retains Django 5.2 support so applications still on Python 3.10 or 3.11 have a supported upgrade path.
Installation
python -m pip install django-toconline
Add the application to INSTALLED_APPS and run migrations:
INSTALLED_APPS = [
# ...
"toconline",
]
python manage.py migrate
Configuration
Keep all credentials in environment-backed settings. TOConline supplies the API URL and OAuth URL with the integration credentials for each company.
import os
TOCONLINE_BASE_URL = os.environ["TOCONLINE_BASE_URL"]
TOCONLINE_OAUTH_BASE_URL = os.environ.get(
"TOCONLINE_OAUTH_BASE_URL",
f"{TOCONLINE_BASE_URL}/oauth",
)
TOCONLINE_OAUTH_CLIENT_ID = os.environ["TOCONLINE_OAUTH_CLIENT_ID"]
TOCONLINE_OAUTH_CLIENT_SECRET = os.environ[
"TOCONLINE_OAUTH_CLIENT_SECRET"
]
TOCONLINE_OAUTH_REDIRECT_URI = os.environ.get(
"TOCONLINE_OAUTH_REDIRECT_URI",
"https://oauth.pstmn.io/v1/callback",
)
TOCONLINE_TIMEOUT = 10
TOCONLINE_BASE_URL is the API host URL without /api.
TOCONLINE_OAUTH_BASE_URL is the OAuth service URL; it defaults to
<TOCONLINE_BASE_URL>/oauth for backward compatibility.
TOConline test tenants can expose those services on different hosts. In that
case configure both explicitly, for example an api10.toconline.pt API host
and an app10.toconline.pt OAuth host. Do not point TOCONLINE_BASE_URL at
the OAuth host: the client appends /api to that setting.
Complete v2 API client
Version 2.0.1 implements all 120 operations published in TOConline's OpenAPI 1.0.0 document. The v2 client is exposed lazily from the configured Django OAuth transport, so it uses the same secure token persistence, timeout, and host validation.
from toconline.services import toconline
from toconline.api import models
document = toconline.api.sales.create_sales_document(
body=models.ApiV1CommercialSalesDocumentsPostRequest(
date="2026-07-22",
document_type="FT",
customer_tax_registration_number="999999990",
lines=[],
)
)
Body dictionaries are accepted and validated too:
purchase = toconline.api.purchases.finalize_purchase_document(
id="purchase-document-id",
body={},
)
Available namespaces are company, catalog, sales, purchases,
documents, and auxiliaries. Every endpoint has one English, typed method
name, for example toconline.api.company.list_customers(). Each method accepts
params= for documented query filters.
See the v2 OpenAPI client guide for the complete developer guide: Django and standalone setup, token storage, extending transports, basic API operations, financial/document workflows, errors, testing, generated models, endpoint registry, and regeneration.
Package maintainers should read the OpenAPI generation and maintenance guide before changing the vendored specification or generated client files.
Without Django
For a CLI, worker, or another Python framework, use the included in-memory OAuth transport instead of writing one:
from toconline.api import DefaultTransport, TocOnlineCredentials
transport = DefaultTransport(
base_url="https://api10.toconline.pt",
oauth_base_url="https://app10.toconline.pt/oauth",
credentials=TocOnlineCredentials(
client_id="...",
client_secret="...",
redirect_uri="https://oauth.pstmn.io/v1/callback",
),
)
customers = transport.api.company.list_customers()
DefaultTransport keeps the OAuth token in memory and refreshes it when
needed. The Django TocOnline service extends this class and only replaces
the token storage with the TocOnlineToken model.
Ergonomic JSON:API resources
transport.api preserves the OpenAPI response exactly. For recognised
JSON:API responses, use transport.resources to access fields directly:
services = transport.resources.catalog.list_services()
services[0].accounting_number
customers = transport.resources.company.list_customers()
customers[0].business_name
It can also create known JSON:API envelopes and infer their resource type:
customer = transport.resources.company.create_customer(
attributes={
"business_name": "Example, Lda.",
"tax_registration_number": "999999990",
}
)
Non-JSON:API results, such as regular objects, PDF bytes, URLs, and empty responses, remain unchanged. See the v2 OpenAPI client guide for request rules, collection endpoints, and the distinction from typed generated models.
Authentication is automatic. The first request obtains and stores a token in
TocOnlineToken; subsequent requests refresh it before expiry. Token values
are deliberately hidden from Django admin, but the application database and
its backups must still be treated as sensitive.
Development and tests
The test suite is deterministic and does not contact TOConline or use real credentials.
The OpenAPI transport contract test covers all 120 published operations. An additional opt-in live test exercises every GET operation through the real v2 client without saving OAuth tokens or sending request bodies. It is deliberately off by default and must use a disposable tenant:
cp .env.example .env
# Edit .env with disposable-tenant credentials.
make test-live
make test-live safely loads the key/value pairs from .env only for that
test process; it never executes .env as shell code. .env is ignored by
Git; .env.example is the versioned template. Do not place production
credentials in either local live-test configuration.
Set TOCONLINE_LIVE_CASH_ACCOUNT_ID as well when the tenant has no existing
cash account but you need to exercise GET /api/cash_accounts/{id}. Mutating
operations remain covered by deterministic contract tests; their live safety
policy is enforced by test_live_openapi.py. Do not enable live mutations on a
production tenant, or send e-mail / communicate documents to the Tax Authority
without a separately approved sandbox workflow.
make requirements-test
make test
To regenerate the checked-in OpenAPI models and endpoint registry after an intentional spec update:
python -m pip install -r requirements-dev.txt
python scripts/generate_openapi_artifacts.py
python scripts/generate_openapi_artifacts.py --check
To expose deprecation warnings during framework upgrades:
.venv/bin/python -Wa manage.py test tests
CI covers the lower supported Python/Django pair, Django 6 on its minimum Python version, and the newest supported Python/Django pair.
Upgrade notes for 2.0.0
- The package version is now 2.0.0 because the new v2 API has typed OpenAPI response semantics instead of the legacy JSON:API-unwrapping behavior.
- All 120 operations in the vendored TOConline OpenAPI 1.0.0 document are
available under
toconline.apiand protected by a spec-coverage test. pydantic>=2.12,<3.0is now a runtime dependency.
Breaking changes in 2.0.0
- The legacy
toconline.resourcesmodule and genericTocOnlineCRUD, document, and raw-request helpers were removed. - Use the complete generated client under
toconline.apifor every published TOConline operation. Applications that require the legacy surface must keep using a 1.x release.
Upgrade notes from 1.0.x
- The supported Django range is now
>=5.2,<7.0, which permits Django 6. - OAuth and API hosts may be configured separately.
- Test settings no longer contain credential-like values, and tests no longer mutate a live TOConline account.
License
MIT. See LICENSE.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file django_toconline-2.0.1.tar.gz.
File metadata
- Download URL: django_toconline-2.0.1.tar.gz
- Upload date:
- Size: 96.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b5ca007326f7a74fba221229f4a56aafe6aac65c47e9264e185db9b55ea0f475
|
|
| MD5 |
f46444b49083b0015f02f8d4fde342d6
|
|
| BLAKE2b-256 |
7b20b85adcbb92ca88de9a6df7e0ad32b061ca85eaffdd0a22c3ec23480abf3b
|
File details
Details for the file django_toconline-2.0.1-py3-none-any.whl.
File metadata
- Download URL: django_toconline-2.0.1-py3-none-any.whl
- Upload date:
- Size: 50.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6b2966379c7c1350b4a75377d340f4e589a70157d18ade95df39296450b56cc0
|
|
| MD5 |
2211354e6df1159a2d2aec4e7d84b0e2
|
|
| BLAKE2b-256 |
f0cd44b4f757d176c1b86a2741cc9e0c7b8ecf79135e675d2128914668f1286d
|