Python library for wFirma API with synchronous and asynchronous support
Project description
python-wfirma
Python client for the wFirma accounting API. Supports both synchronous and asynchronous usage.
Status: Release candidate (
1.0rc2).WFirmaClientsupports API Key, OAuth 2.0, and OAuth 1.0a in this release.
Installation
pip install python-wfirma
Or with uv:
uv add python-wfirma
Usage
Safe Read-Only Start
from wfirma.sync.auth import APIKeyAuth
from wfirma.sync.client import WFirmaClient
auth = APIKeyAuth(
access_key="your_access_key",
secret_key="your_secret_key",
app_key="your_app_key",
)
with WFirmaClient(auth=auth, company_id=123) as client:
company = client.company.get()
terms = client.terms.find()
print(company.name)
print(len(terms))
CLI Read-Only Verification
wfirma company show
wfirma tags list
wfirma terms list
wfirma warehouses list
Write Operations
These examples mutate real production data. Do not run them casually.
from wfirma.sync.auth import APIKeyAuth
from wfirma.sync.client import WFirmaClient
auth = APIKeyAuth(
access_key="your_access_key",
secret_key="your_secret_key",
app_key="your_app_key",
)
with WFirmaClient(auth=auth, company_id=123) as client:
contractor = client.contractors.add(name="ACME Sp. z o.o.", nip="1234567890")
invoice = client.invoices.add(
invoice={
"contractor_id": contractor.id,
"type": "normal",
"paid": "0",
}
)
Async
import asyncio
from wfirma.async_.auth import APIKeyAuth
from wfirma.async_.client import WFirmaClient
async def main() -> None:
auth = APIKeyAuth(
access_key="your_access_key",
secret_key="your_secret_key",
app_key="your_app_key",
)
async with WFirmaClient(auth=auth, company_id=123) as client:
contractor = await client.contractors.add(
name="ACME Sp. z o.o.", nip="1234567890"
)
invoices = await client.invoices.find()
asyncio.run(main())
OAuth 2.0
from wfirma.sync.auth import OAuth2Auth
from wfirma.sync.client import WFirmaClient
from wfirma.config import Environment
oauth = OAuth2Auth(
client_id="your_client_id",
client_secret="your_client_secret",
redirect_uri="https://yourapp.example.com/callback",
environment=Environment.PRODUCTION,
)
# Step 1: redirect user to authorization URL
url = oauth.build_authorization_url(scope="invoices-read")
# Step 2: exchange the code from callback
token = oauth.exchange_code(code="authorization_code_from_callback")
# Step 3: use the client
with WFirmaClient(auth=oauth, company_id=123) as client:
invoices = client.invoices.find()
Configuration
The library has two different environment-driven helpers:
APIKeyAuth.from_env()reads API key credentials forWFirmaClientget_config()/WFirmaConfig.from_env()read shared application settings
API key authentication from environment:
# .env
WFIRMA_APP_KEY=your_app_key
WFIRMA_ACCESS_KEY=your_access_key
WFIRMA_SECRET_KEY=your_secret_key
WFIRMA_ENVIRONMENT=production
WFIRMA_COMPANY_ID=123
from wfirma.sync.auth import APIKeyAuth
auth = APIKeyAuth.from_env()
Shared configuration helper:
# .env
WFIRMA_APP_KEY=your_app_key
WFIRMA_APP_SECRET=your_app_secret
WFIRMA_ENVIRONMENT=production
WFIRMA_COMPANY_ID=123
from wfirma import get_config
config = get_config()
print(config.base_url) # https://api2.wfirma.pl
Custom API base URL override (useful for local simulators):
# .env
WFIRMA_BASE_URL=http://localhost:18088
from wfirma.sync.auth import APIKeyAuth
from wfirma.sync.client import WFirmaClient
auth = APIKeyAuth(
access_key="your_access_key",
secret_key="your_secret_key",
app_key="your_app_key",
)
with WFirmaClient(
auth=auth,
company_id=123,
base_url="http://localhost:18088",
) as client:
company = client.company.get()
Choosing Auth Mode
APIKeyAuth: best for service integrations and manual CLI verificationOAuth2Auth: best when you need upstream read/write scope control and user authorization flowsOAuth1Auth: supported for upstream compatibility, but use it only when the target workflow requires it
Handling API Errors
from wfirma.exceptions import APIError
try:
with WFirmaClient(auth=auth, company_id=123) as client:
company = client.company.get()
except APIError as exc:
print(exc.to_dict())
Production Use Checklist
- use least-privilege credentials
- prefer read-only verification first (
company,tags,terms,warehouses) - treat write examples as production mutations
- run the CLI after install, not only from the repository checkout
- follow
RELEASING.mdbefore tagging or publishing
Stability Policy
1.0rc1started the API freeze, and1.0rc2stays within that contract- the freeze is expected to cover import paths, auth constructors, exception semantics, client defaults, and CLI command names and flags
1.0.0should not ship until the RC checklist is clean
Supported Resources
The client exposes the following wFirma API resources. Each resource provides methods matching the upstream API (typically add, find, get, edit, delete):
Core: invoices, contractors, goods, payments, expenses, documents
Company: company, company_accounts, company_packs
Declarations: declaration_countries, declaration_body_jpkvat, declaration_body_pit
Warehouse: warehouses, warehouse documents (PW, PZ, R, RW, WZ, ZD, ZPD, ZPM)
Reference data: tags, series, terms, term_groups, vat_codes, translation_languages, taxregisters, interests, ledger_accountant_years, ledger_operation_schemas
Users & misc: users, user_companies, vehicles, vehicle_run_rates, payment_cashboxes, invoice_deliveries, invoice_descriptions, notes, webhooks
Development
Requires Python 3.12+. The project uses uv for dependency management.
git clone https://github.com/dekoza/python-wfirma.git
cd python-wfirma
uv venv && uv sync --extra dev
uv run pre-commit install
Tests
uv run pytest # all tests
uv run pytest --cov=wfirma --cov-report=html # with coverage
uv run pytest -m integration # opt-in live integration tests
CLI
The package now ships a small read-only CLI for manual API verification.
Required environment variables:
export WFIRMA_APP_KEY='...'
export WFIRMA_ACCESS_KEY='...'
export WFIRMA_SECRET_KEY='...'
export WFIRMA_COMPANY_ID='123'
Examples:
wfirma company show
wfirma company show --json
wfirma tags list
wfirma terms list
wfirma term-groups list --json
wfirma warehouses list
wfirma vat-codes list
Default list output uses ID and Label. company show uses ID and Name.
Linting & type-checking
uv run ruff format src tests
uv run ruff check --fix src tests
uv run mypy src
Contributing
See CONTRIBUTING.md.
License
MIT — see LICENSE.
This library is not affiliated with wFirma. It is an independent project. Built on httpx, Pydantic, and authlib.
Project details
Release history Release notifications | RSS feed
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 python_wfirma-1.0rc2.tar.gz.
File metadata
- Download URL: python_wfirma-1.0rc2.tar.gz
- Upload date:
- Size: 217.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.10 {"installer":{"name":"uv","version":"0.10.10","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Manjaro Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b35952ee36ac85951aad7e945c4f0b43528e557473332359279cf7e187e6b999
|
|
| MD5 |
eeaa96ed6559fde37eae98224c92927a
|
|
| BLAKE2b-256 |
7e3a627eee509760829a3a93de2bd880f666de3ed1b519d113d3780d6779fc80
|
File details
Details for the file python_wfirma-1.0rc2-py3-none-any.whl.
File metadata
- Download URL: python_wfirma-1.0rc2-py3-none-any.whl
- Upload date:
- Size: 156.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.10 {"installer":{"name":"uv","version":"0.10.10","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Manjaro Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
edeba6518e96b38bb8574b512bd06d0eb02d656d2ac41d76b4d30e1806009786
|
|
| MD5 |
27d501a042523ede7dd693e87e43612f
|
|
| BLAKE2b-256 |
58aad52c3c8a96a6310167990f00973887bc69dcd970a46057759a2f8a04e11c
|