Skip to main content

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: Stable (1.0.0). WFirmaClient supports 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 for WFirmaClient
  • get_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 verification
  • OAuth2Auth: best when you need upstream read/write scope control and user authorization flows
  • OAuth1Auth: 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.md before tagging or publishing

Stability Policy

  • 1.0rc1 started the API freeze, and 1.0.0 ships within that contract
  • the freeze covers import paths, auth constructors, exception semantics, client defaults, and CLI command names and flags

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

python_wfirma-1.0.0.tar.gz (229.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

python_wfirma-1.0.0-py3-none-any.whl (173.1 kB view details)

Uploaded Python 3

File details

Details for the file python_wfirma-1.0.0.tar.gz.

File metadata

  • Download URL: python_wfirma-1.0.0.tar.gz
  • Upload date:
  • Size: 229.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch 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

Hashes for python_wfirma-1.0.0.tar.gz
Algorithm Hash digest
SHA256 336efac0ac4984a07b0263503a2ea74df2cdd0b67bc5aeab0c247d06162e887d
MD5 2bcc8448eb95c155b36e5b8df517a694
BLAKE2b-256 04de5714da83328a03797984a8b2c9e9e1b85363e631955228961d469bdb4c47

See more details on using hashes here.

File details

Details for the file python_wfirma-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: python_wfirma-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 173.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch 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

Hashes for python_wfirma-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e41e616807f9f589bb2d41bf3b44401d3bfcbcb4748d92948dfb8ff531cd48fe
MD5 7bde334c7c0505ba4ecdcb0082ce1559
BLAKE2b-256 b7562af759f54b40ac52ae5d092a0c4a16569afec4d69b536bf25dbe4919b68a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page