Skip to content

Python API

Use the Python API when you want to construct requests programmatically, integrate jobs into an analysis, or work directly with returned datasets. This walkthrough uses the local test service. Its complete source is examples/guides/api.py. Importing the example does not connect or submit work.

Create a client

Use the S2GOS factory functions so the client uses the S2GOS configuration namespace and defaults. Import the request and status models used below:

from gavicore.models import JobResults, JobStatus, ProcessRequest

from s2gos_client import Client, create_client

def connect() -> Client:
    return create_client(api_url="http://127.0.0.1:8008", auth={"auth_type": "none"})

connect() explicitly selects the local server and disables authentication. For hosted work, replace its body with return create_client() after configuring your S2GOS profile, or use create_client(config_path="s2gos-client.yaml") for a separate profile. Use client.login() when interactive authentication is needed. Creating the client itself does not log in or submit a request.

Discover the process contract

def inspect_process(client: Client, process_id: str) -> None:
    print(client.get_processes().model_dump_json(indent=2))
    print(client.get_process(process_id).model_dump_json(indent=2))

The process list is a catalogue. The individual description gives you input names, types, defaults, required values, constraints, and output descriptions. Read it before constructing requests, particularly for deployed scene-generation processes whose parameters may change between versions.

The returned objects are Pydantic models. Their attributes are convenient in Python; model_dump_json(indent=2) produces readable JSON for inspection. client.get_capabilities() and client.get_conformance() provide service-level metadata when you need to identify a deployment or inspect its OGC capabilities.

Submit once and keep the ID

def submit(client: Client, process_id: str, request: ProcessRequest) -> str:
    job = client.execute_process(process_id, request=request)
    print(job.model_dump_json(indent=2))
    return job.jobID

Input values belong inside ProcessRequest(inputs={...}). They are not top-level fields of the request. The process ID is supplied separately to execute_process. For the prime-number example, min_val=10 and max_val=80 request the primes in that range.

The returned JobInfo.jobID identifies this execution. Always retain that server-generated value. A response with accepted or running means the job still needs monitoring. Do not repeat the submission to refresh its status.

Check status before requesting results

def inspect_results(client: Client, job_id: str) -> JobResults | None:
    job = client.get_job(job_id)
    print(job.model_dump_json(indent=2))
    if job.status in (JobStatus.accepted, JobStatus.running):
        print("Check this job ID again later; do not submit another job.")
        return None
    if job.status != JobStatus.successful:
        print("Job did not succeed. Read its status and message before retrying.")
        return None
    results = client.get_job_results(job_id)
    print(results.model_dump_json(indent=2))
    return results

This helper checks once. Call it again with the same job ID later if the job is still active. In an automated workflow, poll at an interval suitable for the computation and set an overall waiting limit. A client-side timeout does not cancel the server job.

For a successful prime-number job, the results contain a return_value output with a list starting at 11 and ending at 79. For a scene-generation job, results may instead contain links to files or datasets. Retrieving result metadata does not necessarily download the data; see Working with results.

Run the complete session

After defining the functions above, run this session:

def main() -> str:
    client = connect()
    try:
        process_id = "primes_between"
        inspect_process(client, process_id)
        request = ProcessRequest(inputs={"min_val": 10, "max_val": 80})
        job_id = submit(client, process_id, request)
        inspect_results(client, job_id)
        print(f"Keep this job ID: {job_id}")
        return job_id
    finally:
        client.close()



job_id = main()

The finally block releases network resources even if discovery or submission fails. Closing the client leaves submitted server jobs running. To revisit the job, create a new client for the same service and pass the saved ID to inspect_results(client, job_id), then close that client too.

You can also run the maintained example directly from the repository root:

python -m examples.guides.api

Each invocation submits one new job. If you only want to check an existing job, use the helper with its saved ID or the CLI's get-job command instead.

Failures and cancellation

A transport or HTTP error raises ClientError. A process that fails after submission is represented by a job with status failed; inspect its message. For a controlled local failure, submit sleep_a_while with ProcessRequest(inputs={"duration": 2, "fail": True}), retain the returned ID, and check that job after a few seconds.

To dismiss a selected job, call client.dismiss_job(job_id). Dismissal can cancel work or remove access to a completed job's results, depending on the backend. Use only the ID of the job you intend to dismiss. Avoid dismissal loops over all jobs, especially on a shared service.

Asynchronous clients and Airflow-backed services

create_async_client() uses the same S2GOS settings and provides asynchronous server calls. Await operations such as get_processes(), execute_process(), get_job(), and close(). This is useful when your application already has an event loop; it does not change the server job lifecycle. The synchronous client also submits jobs for asynchronous execution on the service.

An Airflow-backed deployment exposes the same OGC interface through the S2GOS gateway. Connect to the gateway's API URL, not the Airflow web UI, and discover the processes it advertises. Your client does not need Airflow administrator credentials. Operators configure the gateway's backend connection using the Server CLI. See the Client API reference for the full client interface.