Authorization Flow 2.0

iiisight supports the metadata and non-interactive parts of the IIIF Auth Flow 2.0: it describes a resource’s auth services and can probe access and exchange for a token where the token service is directly callable. The interactive login step (opening a login window and reading the token via postMessage) is inherently the host application’s job and is out of scope — iiisight gives you the service metadata to drive it.

Discovering the probe service

probe = iiisight.find_probe_service(manifest.canvases[0])
if probe is None:
    ...  # the resource is not access-controlled

find_probe_service accepts a canvas (it searches its images’ services), a ContentResource, or a Service. It returns a ProbeService with the full parsed tree — access services, and their token/logout services:

access = probe.access_services[0]
print(access.profile, str(access.label), str(access.heading))
print(probe.token_service.id)      # convenience: first token service

The non-interactive flow

Probe for access; if denied and a token service is available, exchange for a token (non-interactively) and probe again:

async with iiisight.AsyncClient() as client:
    result = await client.probe(probe)
    if not result.accessible and probe.token_service:
        token = await client.access_token(probe.token_service)
        if token.ok:
            result = await client.probe(probe, token=token.access_token)
    print("accessible" if result.accessible else f"denied, see {result.location}")
with iiisight.Client() as client:
    result = client.probe(probe)
    if not result.accessible and probe.token_service:
        token = client.access_token(probe.token_service)
        if token.ok:
            result = client.probe(probe, token=token.access_token)
    print("accessible" if result.accessible else f"denied, see {result.location}")

ProbeResult carries status, accessible, location, heading, and note. TokenResult carries access_token, expires_in, ok, and error.

Note

access_token() performs a direct GET of the token service, which works for non-interactive profiles (e.g. external, relying on cookies). For active profiles that require a user to log in through a browser, drive the interactive step in your application using access service metadata, then pass the resulting token to client.probe(probe, token=…).