Skip to content

ogpu.client

Client-role workflow layer. These functions are the top-level entry points most application code uses — publish a source, publish a task, confirm a response, cancel a task. Internally they build the on-chain parameter tuples, upload metadata to IPFS when needed, and delegate to the protocol layer.

Every call accepts a private_key= keyword. When omitted, the SDK reads the CLIENT_PRIVATE_KEY environment variable; if that's not set either, you get a typed MissingSignerError. You can also pass an eth_account.LocalAccount as private_key= to use hardware wallets or KMS signers.

Publishing functions (publish_source, publish_task) return live instance classesSource and Task — not string addresses. Every method on the returned instance hits the chain fresh, so you can inspect state right after publishing without a round-trip through your own code. See reading state for the full instance-class API.

State-changing functions return typed Receipt dataclasses (for cancel_task, update_source, inactivate_source) or hex tx-hash strings (for confirm_response, set_agent). This inconsistency is historical — future versions will unify on Receipt.


Publishing

ogpu.client.publish_source

publish_source(source_info: SourceInfo, private_key: str | None = None, **_ignored: Any) -> Source

Publish a new source to the OGPU network.

Uploads the source metadata to IPFS, calls Nexus.publishSource via TxExecutor, and wraps the new source address in a Source instance.

Parameters:

Name Type Description Default
source_info SourceInfo

User-facing SourceInfo with display fields, image URLs, payment config, and delivery method.

required
private_key str | None

Client signer. Falls back to CLIENT_PRIVATE_KEY environment variable when omitted. May also be a LocalAccount.

None

Returns:

Type Description
Source

A Source instance bound to the new contract address. You

Source

can call .get_status(), .get_params(), etc. on it

Source

immediately.

Raises:

Type Description
MissingSignerError

If no signer is available.

IPFSGatewayError / IPFSFetchError

If the metadata upload fails.

TxRevertError or a typed subclass

If the Nexus call reverts.

Example
from web3 import Web3
from ogpu.client import (
    publish_source, SourceInfo, ImageEnvironments, DeliveryMethod,
)

source = publish_source(SourceInfo(
    name="sentiment-analyzer",
    description="DistilBERT classifier",
    logoUrl="https://example.com/logo.png",
    imageEnvs=ImageEnvironments(cpu="https://.../compose.yml"),
    minPayment=Web3.to_wei(0.01, "ether"),
    minAvailableLockup=0,
    maxExpiryDuration=86400,
    deliveryMethod=DeliveryMethod.FIRST_RESPONSE,
))
print(source.address, source.get_status())

ogpu.client.publish_task

publish_task(task_info: TaskInfo, private_key: str | None = None, **_ignored: Any) -> Task

Publish a new task to the OGPU network.

Uploads the task config (a TaskInput) to IPFS, calls Controller.publishTask via TxExecutor, and wraps the new task address in a Task instance.

Parameters:

Name Type Description Default
task_info TaskInfo

User-facing TaskInfo with source address, TaskInput config, expiry time, and payment.

required
private_key str | None

Client signer. Falls back to CLIENT_PRIVATE_KEY.

None

Returns:

Type Description
Task

A Task instance bound to the new contract address.

Raises:

Type Description
MissingSignerError

If no signer is available.

SourceInactiveError

If the target source has been inactivated.

InsufficientBalanceError

If the client's vault balance is insufficient to cover the task payment.

IPFSGatewayError / IPFSFetchError

If the config upload fails.

Example
import time
from web3 import Web3
from ogpu.client import publish_task, TaskInfo, TaskInput

task = publish_task(TaskInfo(
    source="0xSOURCE",
    config=TaskInput(function_name="predict", data={"text": "hi"}),
    expiryTime=int(time.time()) + 3600,
    payment=Web3.to_wei(0.01, "ether"),
))
print(task.address, task.get_status())

Response operations

ogpu.client.get_task_responses

get_task_responses(task_address: str, lower: int = 0, upper: int | None = None) -> list[Response]

List all responses submitted for a task, as Response instances.

Thin forwarder to Task(task_address).get_responses(lower, upper). Useful when you don't want to hold a Task instance — e.g. one-off inspection scripts, dashboards iterating many task addresses.

Parameters:

Name Type Description Default
task_address str

Task contract address.

required
lower int

Start index (inclusive). Defaults to 0.

0
upper int | None

End index (exclusive). Defaults to all responses.

None

Returns:

Type Description
list[Response]

List of Response instances.

Example
from ogpu.client import get_task_responses
for r in get_task_responses("0xTASK"):
    print(r.address, r.get_status())

ogpu.client.confirm_response

confirm_response(response_address: str, private_key: str | None = None, **_ignored: Any) -> str

Confirm a response to finalize the parent task and release payment.

Calls Controller.confirmResponse via TxExecutor and returns the transaction hash as a string. Only meaningful for MANUAL_CONFIRMATION delivery — tasks using FIRST_RESPONSE finalize automatically on the first submit.

Parameters:

Name Type Description Default
response_address str

The response contract to confirm.

required
private_key str | None

Client signer. Falls back to CLIENT_PRIVATE_KEY.

None

Returns:

Type Description
str

Transaction hash as a 0x-prefixed hex string.

Raises:

Type Description
NotTaskOwnerError

Caller isn't the task's client.

ResponseAlreadyConfirmedError

Already confirmed.

MissingSignerError

If no signer is available.

Example
from ogpu.client import confirm_response
tx_hash = confirm_response("0xRESPONSE")
print(tx_hash)
# '0x...'

Task operations

ogpu.client.cancel_task

cancel_task(task: str | Task, private_key: str | None = None, **_ignored: Any) -> Receipt

Cancel a task (only works before any provider attempts).

Accepts either a task address string or a Task instance. Returns a Receipt instead of a tx hash string.

Parameters:

Name Type Description Default
task str | Task

Task contract address or Task instance.

required
private_key str | None

Client signer. Falls back to CLIENT_PRIVATE_KEY.

None

Returns:

Type Description
Receipt

Receipt for the cancellation.

Raises:

Type Description
NotTaskOwnerError

If the signer isn't the task's client.

TaskAlreadyFinalizedError

If the task is past NEW state.

Example
from ogpu.client import cancel_task
receipt = cancel_task("0xTASK")
print(receipt.tx_hash, receipt.gas_used)

Source operations

ogpu.client.update_source

update_source(source: str | Source, new_info: SourceInfo, private_key: str | None = None, **_ignored: Any) -> Receipt

Update a source's on-chain parameters.

Builds a fresh SourceParams from new_info (re-uploading the metadata to IPFS) and calls Nexus.updateSource. Must be called by the source's owner.

Parameters:

Name Type Description Default
source str | Source

Source contract address or Source instance.

required
new_info SourceInfo

New SourceInfo with the updated fields.

required
private_key str | None

Client signer. Falls back to CLIENT_PRIVATE_KEY.

None

Returns:

Type Description
Receipt

Receipt for the update.

Raises:

Type Description
NotSourceOwnerError

If the signer isn't the source's owner.

ogpu.client.inactivate_source

inactivate_source(source: str | Source, private_key: str | None = None, **_ignored: Any) -> Receipt

Inactivate a source (one-way; no reactivation).

Calls Nexus.inactivateSource. After this, publishing new tasks against the source reverts with SourceInactiveError. Existing tasks continue their natural lifecycle.

Parameters:

Name Type Description Default
source str | Source

Source contract address or Source instance.

required
private_key str | None

Client signer. Falls back to CLIENT_PRIVATE_KEY.

None

Returns:

Type Description
Receipt

Receipt for the inactivation.

Raises:

Type Description
NotSourceOwnerError

If the signer isn't the source's owner.

Agent

ogpu.client.set_agent

set_agent(agent_address: str, value: bool, private_key: str | None = None, **_ignored: Any) -> str

Authorize (or revoke) an agent for client-side operations.

Client-role wrapper over Terminal.setAgent. Use this when you want to delegate client-side calls (publish_task, confirm_response) to an agent address — the agent's key can then sign on your behalf.

For master-side agent setup (delegating provider operations), use Master(master_addr).set_agent(...) instead.

Parameters:

Name Type Description Default
agent_address str

Agent to authorize/revoke.

required
value bool

True to authorize, False to revoke.

required
private_key str | None

Client signer. Falls back to CLIENT_PRIVATE_KEY.

None

Returns:

Type Description
str

Transaction hash as a hex string.