Skip to main content

python-fotoware-client

tests pre-commit

A thin, read-only Python client for the FotoWare API (FotoWeb). It does what the API does and shows what that costs; it knows nothing about any particular archive's fields.

Not affiliated with or endorsed by FotoWare AS. "FotoWare" and "FotoWeb" are their trademarks.

What it does

  • One call is one request. search_assets returns one page; next_page and iter_search follow paging.next. Nothing is batched or asked again behind the caller's back. The only exception are the rendition downloads, which poll until FotoWare has prepared the file.
  • Refuses a query FotoWare would answer wrongly. Over FotoWare's size limit a search comes back as a 500 or, worse, as an empty list that looks exactly like "no hits". search_assets estimates the query first and raises QueryTooLargeError over the budget, without sending it. estimate_query_size is public, so callers can batch to stay under it.
  • Retries what is transient. urllib3's Retry on the session retries 429 (honouring Retry-After) and 502/503/504, twice by default. A 500 is not retried: it was always caused by the query.
  • Counts the cost. cost_snapshot() reports requests, retries, errors, search pages and empty search pages.
  • OAuth client credentials with automatic token refresh; context manager.
  • Takes hrefs as FotoWare gives them. Answers carry paths on the tenant; every call that takes an href accepts a path or a full URL.

FotoWare's limits

Measured on 2026-10-23 against FotoWeb 8.1.1223.0; details and edges in fotoware_client/limits.py.

Limit Value
Assets per search answer 25, with pageSize ignored. FotoWare guarantees no page size, so the client follows paging.next and counts nothing
Cost of an answer ~0.4 s with hits whether 1 or 25 assets; 130–220 ms empty
Search size about 2,000 by estimate_query_size; budget 1,500

So the cheapest search asks for as many terms as fit the budget and fills whole pages.

Two search settings of an installation (Site Configuration › Searching) are out of the client's sight:

  • Maximum number of hits caps a result set. A search with more hits ends early, without saying so.
  • Search string modification decides how plain words without an operator are combined (AND, OR or as a phrase). Write AND/OR explicitly, and the setting does not matter.

Settings of an installation

What a FotoWare installation may set differently, the client takes as ServerSettings; the defaults are FotoWeb's:

from fotoware_client import FotoWareClient, ServerSettings

settings = ServerSettings(
    original_rendition_name="Originaldatei",  # display names are configurable
    download_timeout=300,  # seconds per download or rendition
    rendition_poll_interval=0.5,  # first wait while a rendition is made
    query_size_budget=1200,  # if the installation's limit is lower
)
client = FotoWareClient.from_env(settings=settings)

Also: oauth_token_path, api_descriptor_path, rendition_poll_interval_max and term_overhead. See fotoware_client/settings.py.

Credentials

Pass them to the constructor, or let FotoWareClient.from_env() find them:

  1. the environment: FOTOWARE_TENANT_URL, FOTOWARE_CLIENT_ID, FOTOWARE_CLIENT_SECRET;
  2. else the credentials file ~/.config/fotoware/credentials ($XDG_CONFIG_HOME/fotoware/credentials), one NAME=value per line, refused unless only its owner may read it (chmod 600).

Never on a command line, where a secret lands in the process list and the shell history.

Usage

from fotoware_client import FotoWareClient

with FotoWareClient.from_env() as client:
    archive = next(
        a for a in client.list_archives() if a.href.startswith("/fotoweb/archives/5000-")
    )
    query = "(631:4000000000001 OR 631:4000000000002) AND (dt:image OR dt:graphic)"
    for page in client.iter_search(archive.href, query):
        for asset in page.assets:
            print(asset.filename)
    print(client.cost_snapshot())

Other calls: get_asset, get_field_labels, get_rendition_url, download_original, download_original_to_file, download_rendition_to_file, download_bytes.

Errors

All derive from FotoWareError:

Error When
QueryTooLargeError the query is over the size budget; nothing sent
RateLimitError a 429 outlasted the retries
RetryExhaustedError a 502/503/504, connection error or timeout outlasted the retries
NotFoundError a 404
APIError any other error status, a 500 among them
AuthenticationError the token could not be fetched
ConfigurationError the client was set up wrongly

Install

pip install python-fotoware-client

Development

make venv
make lint type test

Pre-commit hooks: pip install pre-commit && pre-commit install.

License

MIT, see LICENSE.

Metadata

Release files for python-fotoware-client 0.2.1

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

Source distribution (sdist)

Source distribution for python-fotoware-client 0.2.1
File Size Uploaded Provenance
python_fotoware_client-0.2.1.tar.gz 35.6 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for python-fotoware-client 0.2.1
File Interpreter ABI Platform
python_fotoware_client-0.2.1-py3-none-any.whl Python 3 none any Details

Total release size: 62.7 kB

Release files / python_fotoware_client-0.2.1.tar.gz

Download URL python_fotoware_client-0.2.1.tar.gz
Size 35.6 kB
Tags Source
SHA-256 checksum
How to use checksums
7ffe4feb6bfba496700a35a5be414cd2dca16c83bafdcbd4ec44c206980563b7
BLAKE2b-256 checksum
How to use checksums
1e1ccf233d32d252bc57b8e22468efac1383772aa5115de0b1229a0d30f159e5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

Release files / python_fotoware_client-0.2.1-py3-none-any.whl

Download URL python_fotoware_client-0.2.1-py3-none-any.whl
Size 27.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6303f78bc0a2d36c7cd1810f1ca477ce4bc2e7aa1725ec76df3d10fb608d1892
BLAKE2b-256 checksum
How to use checksums
6dd519d9bb2f20816157b3ba80bf58494ac277dbc3ae4b3d89a3432b01452b38
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

Security for python-fotoware-client 0.2.1

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.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for python_fotoware_client-0.2.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

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.

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