Skip to content

ogpu.ipfs

Publish and fetch off-chain content. IPFS is how the OGPU protocol keeps transactions cheap — only URLs go on-chain, the actual content (source metadata, task configs, response payloads, model weights, images) lives off-chain on IPFS.

Most SDK workflows use these functions internally:

  • client.publish_source(info) uploads source metadata for you.
  • client.publish_task(info) uploads the task config.
  • Source.get_metadata() / Task.get_metadata() fetch them back.
  • Response.fetch_data() fetches confirmed response payloads.

You only need to call publish_to_ipfs or fetch_ipfs_json directly when you're producing real response payloads as a provider or want direct fetch control. Both functions are re-exported at the top level:

from ogpu import publish_to_ipfs, fetch_ipfs_json

The publish endpoint is OGPU-specific (capi.ogpuscan.io/file/create) and cannot be overridden. Fetching works against any IPFS gateway URL. See the IPFS guide for the workflow.


ogpu.ipfs.publish.publish_to_ipfs

publish_to_ipfs(data: str | dict[str, Any], filename: str = 'data.json', content_type: str = 'application/json') -> str

Publish data to IPFS via the OGPU pinning service.

Accepts either a dict (JSON-serialized before upload) or a raw string (uploaded as-is). Returns a gateway URL pointing at the pinned content — typically something like https://cipfs.ogpuscan.io/ipfs/Qm....

The upload target is OGPU's own pinning endpoint; you cannot point this at a different IPFS gateway. If you need custom pinning, use your own HTTP client and pass the resulting URL to the SDK wherever it expects a data URL field.

Parameters:

Name Type Description Default
data str | dict[str, Any]

The content to upload. A dict is JSON-serialized before sending. A string is uploaded unchanged — use this if you already have a JSON string or want to upload plain text.

required
filename str

Filename to send in the multipart form. Only affects how the pinning service labels the upload; the returned URL does not include this name.

'data.json'
content_type str

MIME type to send with the upload. Defaults to application/json.

'application/json'

Returns:

Type Description
str

Gateway URL (string) pointing at the pinned content.

Raises:

Type Description
IPFSFetchError

Network error, connection refused, DNS failure, or malformed response body.

IPFSGatewayError

The endpoint responded with a non-success status code, or the response JSON is missing the link field.

Example
from ogpu import publish_to_ipfs

# Upload a dict as JSON
url = publish_to_ipfs(
    {"result": "cat", "confidence": 0.97},
    filename="response.json",
)
print(url)
# 'https://cipfs.ogpuscan.io/ipfs/Qm...'

# Upload a raw string
url = publish_to_ipfs(
    "plain text content",
    filename="note.txt",
    content_type="text/plain",
)

ogpu.ipfs.fetch.fetch_ipfs_json

fetch_ipfs_json(url: str) -> dict[str, Any]

GET an IPFS gateway URL and parse the body as JSON.

Used by Source.get_metadata, Task.get_metadata, and Response.fetch_data internally, but exposed here so you can fetch any IPFS JSON content directly — e.g. inspecting a task config URL from chain state, or decoding a response payload you discovered through some other path.

Only handles JSON responses. If the content is binary (model weights, images, video), fetch it with your own HTTP client — Response.get_data() returns the raw URL string that you can feed to requests.get(url).content or similar.

Works against any HTTP gateway URL, not just OGPU's — use it with https://cipfs.ogpuscan.io/..., https://ipfs.io/..., or your own node.

Parameters:

Name Type Description Default
url str

The gateway URL to fetch. Must respond with JSON.

required

Returns:

Type Description
dict[str, Any]

The parsed JSON body as a dict.

Raises:

Type Description
IPFSFetchError

Network error, connection timeout, or invalid JSON in the response body.

IPFSGatewayError

The gateway returned a non-200 status code.

Example
from ogpu import fetch_ipfs_json

metadata = fetch_ipfs_json(
    "https://cipfs.ogpuscan.io/ipfs/QmAbC...",
)
print(metadata["name"])
# 'sentiment-analyzer'

# Same pattern from inside a Response instance — but
# Response.fetch_data() is the more typical entry point:
response = Response.load("0x...")
payload = response.fetch_data()