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.3

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.3
File Size Uploaded Provenance
python_fotoware_client-0.2.3.tar.gz 37.0 kB With provenance Details

Built distribution (wheel)

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

Total release size: 64.7 kB

Release files / python_fotoware_client-0.2.3.tar.gz

Download URL python_fotoware_client-0.2.3.tar.gz
Size 37.0 kB
Tags Source
SHA-256 checksum
How to use checksums
6e1b344e996774c32fd91a8759083b0561f3a2b2f49d5faab76635baaab5dcf6
BLAKE2b-256 checksum
How to use checksums
d89d0491493374ca7fe2b8879415c52404a33ac16c93ee35d240358ad23968ba
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.3-py3-none-any.whl

Download URL python_fotoware_client-0.2.3-py3-none-any.whl
Size 27.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
97575af22b0cfe8ab93680e4a43113276ac9053650a6627f7cbfbd6bb7cd3887
BLAKE2b-256 checksum
How to use checksums
5174690999fc7c62b11b41f7fa06006a5bd60e52bb6faac8edc81731abe97b5f
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.3

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.3.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