Python SDK for SeaCloud AI generation APIs.
Project description
seacloudai-sdk
English | 简体中文
Python SDK for SeaCloud AI generation APIs.
SeaCloud SDK is a multimodal task execution SDK designed for agents and developers. With one SeaCloud API key, it provides LLM chat through chat.send and image, video, audio, 3D, and other queue generation through run / run_sync; supports model search, contract queries, task execution, and result tracking; and helps discover and manage professional skills for creative workflows through SkillHub.
Chinese operation manual: docs/SDK_OPERATION_MANUAL.zh-CN.md.
If you are new to Python, start with docs/PYTHON_LEARNING_NOTES.zh-CN.md. It explains the Python syntax and code flow used in this project file by file.
Install
pip install seacloudai-sdk
For local development in this repository:
python -m venv .venv
.venv/bin/python -m pip install -e '.[dev]'
Server-Side Usage
Use this SDK from trusted server-side Python code. Do not put the API key in browser code. For browser apps, call your own backend route and let that route use seacloudai-sdk.
import os
from seacloud_sdk import SeaCloud, getSeaCloudDocs, isSeaCloudError
docs = getSeaCloudDocs()
print(docs["quickStart"]["content"])
client = SeaCloud(api_key=os.environ["SEACLOUD_API_KEY"])
try:
result = await client.run_sync("gpt_image_2", {
"prompt": "Generate cute cats programming",
"n": 1,
"size": "1024x1024",
"output_format": "png",
"quality": "auto",
"moderation": "auto",
})
print(result.get("output", {}).get("urls"))
except Exception as error:
if isSeaCloudError(error):
print(error.type, str(error), error.hint)
Overview
seacloudai-sdk is a pure code SDK. It exposes typed Python methods, returns data objects, and never reads apiKey from environment variables by itself. Callers must pass api_key or the compatible apiKey parameter explicitly.
Service Endpoints and Environment Overrides
The SDK ships with production service endpoints, so application code can create a client with only an explicit api_key. Runtime service endpoints are generated from .env.prod into src/seacloud_sdk/core/default_base_urls.py; API keys are never read from env by the SDK.
Maintainers who need local-only endpoints can create an ignored .env.local file with the same keys and run:
python scripts/generate_base_urls.py .env.local
.env.local is intentionally not tracked and must not be pushed.
Quick Start
from seacloud_sdk import SeaCloud, getSeaCloudDocs
docs = getSeaCloudDocs()
print([method["name"] for method in docs["methods"]])
client = SeaCloud(api_key="sk-...", timeout=600_000)
text = await client.chat.send("gpt-5.5", [
{"role": "user", "content": "Hello"},
])
task = await client.run("gpt_image_2", {
"prompt": "Generate cute cats programming",
"n": 1,
"size": "1024x1024",
"output_format": "png",
"quality": "auto",
"moderation": "auto",
})
print(task["id"], task.get("statusUrl"), task.get("responseUrl"))
result = await client.run_sync("gpt_image_2", {
"prompt": "Generate cute cats programming",
"n": 1,
"size": "1024x1024",
"output_format": "png",
"quality": "auto",
"moderation": "auto",
})
print(result.get("output", {}).get("urls", [None])[0])
API Overview
| Module | Method | Purpose |
|---|---|---|
| Docs | getSeaCloudDocs() |
Read the offline SDK operation manual and agent / skill usage guide |
| Client | SeaCloud(options) / SeaCloud(api_key=...) |
Create a client with an explicit apiKey |
| Chat | client.chat.send(model, messages, options) |
Send a text chat request |
| Generation | client.run(model_id, params, options) |
Create a contract-aware queue task and return a task handle immediately |
| Generation | client.run_sync(model_id, params, options) |
Create a contract-aware queue task and wait for the final response |
| Models | client.models.list(options) |
List available models |
| Models | client.models.get_spec(model_id) |
Read the model contract used for generation planning |
| Tasks | client.tasks.get(task_id, {"endpoint": model_id}) |
Read queue task status |
| Tasks | client.tasks.get_response(task_id, {"responseUrl": url}) |
Read the final queue task response |
| Skills | client.skills.find(query, options) |
Search SkillHub skills |
| Skills | client.skills.list(options) |
List SkillHub skills |
| Version | client.version() |
Read the SDK version |
Client Options
client = SeaCloud(
api_key="sk-...",
timeout=600_000,
fetch=my_async_fetch,
)
api_key is required and has no default value. The SDK also accepts apiKey as an equivalent parameter for compatibility with camelCase call conventions. timeout can be set at the client level or overridden for a single method call. fetch is optional and is useful for proxies, tests, or special runtimes.
Offline Docs
getSeaCloudDocs() does not initialize a client, does not require apiKey, and does not make network requests. It is suitable for agents, LLM tool calls, and test pages that need to inspect public SDK usage.
docs = getSeaCloudDocs()
zh_docs = getSeaCloudDocs({"locale": "zh-CN"})
print(docs["operationManual"]["content"])
print(docs["agentSkillUsage"]["content"])
print([method["name"] for method in docs["methods"]])
Generation Parameters
Generation methods use fixed syntax:
client.run(model_id, params, options)
client.run_sync(model_id, params, options)
client.runSync(model_id, params, options) # compatibility alias
model_idis the first positional argument. By default, the SDK reads the model contract, resolves the queue submit endpoint, and falls back to/model/v1/queue/{model_id}when the contract is unavailable in auto mode.paramsis the second positional argument and must be a dict. The SDK sends Python dicts as queue JSON; string flag syntax is not accepted.options["timeout"]overrides the timeout for this request or synchronous wait.options["dryRun"]or thedry_run=Truekeyword plans and previews the request without submitting a task, polling, or reading the final response.options["contract"]is optional and defaults to"auto"."auto"tries to read the contract and can fall back to raw queue passthrough."strict"requires the contract to be readable and plannable."off"explicitly disables contract reads and submitsparamsas raw queue JSON.- There is no
onProgress. The current backend lifecycle APIs do not provide trustworthy progress, so the SDK does not invent progress events.
By default, run and run_sync read the model contract to resolve protocol, body mode, queue submit endpoint, and contract headers. If input_schema.required is a non-empty array, the SDK only checks that those top-level required fields are present before submitting. It does not validate types, formats, ranges, defaults, or mutual-exclusion rules; those model-specific rules are handled by the API. If the contract cannot be read in "auto" mode, the SDK falls back to raw JSON submission at /model/v1/queue/{model_id}. The SDK accepts Python dict objects, does not accept shell-style parameter strings, and does not auto-upload local files.
Contract-aware generation flow:
| Step | SDK behavior |
|---|---|
| 1 | client.models.get_spec(model_id), client.run(), and client.run_sync() read GET https://sea-cloud-admin-web.real-cloud.seaart.ai/api/v1/skill/model-contracts/{modelId} when contract mode is enabled. |
| 2 | If input_schema.required is non-empty, the SDK only checks that those top-level required fields are present; otherwise it does not block. |
| 3 | For protocol=queue and body_mode=raw_json, the SDK resolves spec.endpoints.submit.path against the queue base URL and submits the caller-provided JSON body. |
| 4 | client.run_sync() polls statusUrl and reads responseUrl; client.run() returns the task handle for manual tasks.get() / tasks.get_response(). |
flowchart TD
User["User calls run/run_sync"] --> ValidateInput["Validate model_id and params dict"]
ValidateInput --> ContractMode{"Use contract mode?"}
ContractMode -- default auto/strict --> ReadContract["Read model contract"]
ContractMode -- off --> PlanRaw["Use raw queue request"]
ReadContract --> PlanContract["Plan protocol, bodyMode, queue endpoint, headers"]
ReadContract -- auto unavailable --> PlanRaw
PlanRaw --> DryRun{"dryRun / dry_run?"}
PlanContract --> DryRun
DryRun -- yes --> Preview["Return planned request preview"]
DryRun -- no --> Submit["POST queue submit request"]
Submit --> Task["Return task handle"]
Task --> Sync{"run_sync?"}
Sync -- no --> Done["Caller polls manually with tasks.get/get_response"]
Sync -- yes --> Poll["Poll statusUrl"]
Poll --> Response["GET responseUrl"]
Response --> Result["Return normalized RunSyncResult"]
run: Create an Async Task
run reads the model contract in default contract mode, then submits the planned queue request:
POST https://cloud.seaart.ai/model/v1/queue/{modelId}
task = await client.run("gpt_image_2", {
"prompt": "Generate cute cats programming",
"n": 1,
"size": "1024x1024",
"output_format": "png",
"quality": "auto",
"moderation": "auto",
})
Task handle:
{
"id": "mmsu_...",
"status": "queued",
"model": "gpt_image_2",
"statusUrl": "...",
"responseUrl": "...",
"cancelUrl": "...",
"queuePosition": 0,
}
Async mode does not return output, because the final generation result does not exist when the task is created.
run_sync: Wait for Final Result
run_sync creates a task, polls statusUrl, requests responseUrl after completion, and wraps the real response in a stable structure.
result = await client.run_sync("gpt_image_2", {
"prompt": "Generate cute cats programming",
"n": 1,
"size": "1024x1024",
"output_format": "png",
"quality": "auto",
"moderation": "auto",
})
Return shape:
{
"id": "mmsu_...",
"status": "completed",
"model": "gpt_image_2",
"output": {
"urls": ["https://..."],
"raw": {"request_id": "mmsu_..."},
},
}
Mapping rules:
id: prefersrequest_id, thenid, then the task creation ID.status: success states normalize tocompleted; failed states normalize tofailed.output.urls: recursively extracts allurlfields from the real response.output.raw: keeps the real response so model-specific fields are not lost.error: maps task failures from the real response. Failed results do not inventoutput.
dry_run
preview = await client.run("gpt_image_2", {
"prompt": "a cinematic photo of a cat astronaut",
"n": 1,
}, {"dryRun": True})
preview = await client.run("gpt_image_2", {"prompt": "cat"}, dry_run=True)
dry_run returns modelId, protocol, bodyMode, endpoint, method, redacted headers, the planned request body, and validation, but it does not submit a generation task. With contract mode on, it may read the model contract and only checks input_schema.required top-level fields locally.
Manual Task Lookup After run
status = await client.tasks.get(task["id"], {
"endpoint": "gpt_image_2",
"statusUrl": task.get("statusUrl"),
})
result = await client.tasks.get_response(task["id"], {
"endpoint": "gpt_image_2",
"responseUrl": status.get("responseUrl") or task.get("responseUrl"),
})
get_response returns the same structure as run_sync: successful results include output.urls and output.raw; failed results include error and do not invent output.
Service Endpoints
| Capability | Endpoint |
|---|---|
| Chat | POST https://cloud.seaart.ai/llm/chat/completions |
| Model list | GET https://sea-cloud-admin-web.real-cloud.seaart.ai/api/v1/skill/models |
| Queue submit | POST https://cloud.seaart.ai/model/v1/queue/{modelId} |
| Queue status | GET https://cloud.seaart.ai/model/v1/queue/{modelId}/requests/{request_id}/status |
| Queue response | GET https://cloud.seaart.ai/model/v1/queue/{modelId}/requests/{request_id}/response |
| Model contract | GET https://sea-cloud-admin-web.real-cloud.seaart.ai/api/v1/skill/model-contracts/{modelId} |
| SkillHub search | GET https://skill-hub.vtrix.ai/api/v1/search |
| SkillHub list | GET https://skill-hub.vtrix.ai/api/v1/skills |
Naming Compatibility
Python code should prefer snake_case: run_sync, models.get_spec, tasks.get_response, api_key, and dry_run. The SDK also keeps camelCase compatibility aliases: runSync, models.getSpec, tasks.getResponse, apiKey, and dryRun. Returned data uses the public protocol's camelCase fields, such as statusUrl, responseUrl, queuePosition, pageSize, and totalPages.
Development
.venv/bin/python -m pip install -e '.[dev]'
.venv/bin/python -m pytest
.venv/bin/ruff check .
.venv/bin/mypy src
Architecture
src/seacloud_sdk/
client.py SeaCloud facade and resource assembly
__init__.py Public exports
core/ Runtime config, HTTP client, errors, version
domain/ Model aliases, response mapping, task result normalization
resources/ One aggregate resource class per SDK capability
types/ Public typed contracts grouped by capability
utils/ Small shared objects and URL helpers
skills/ Project-local agent skills for SDK usage
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file seacloudai_sdk-0.1.3.tar.gz.
File metadata
- Download URL: seacloudai_sdk-0.1.3.tar.gz
- Upload date:
- Size: 50.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c8920f940c11891cb75682c4d21a4efe3d47fd839339cf6a42785c1e9399a735
|
|
| MD5 |
1b704f01adbec579305fc6f725e97d4e
|
|
| BLAKE2b-256 |
2925bd9279db3928bad288b0a6a979c1062a94c789a5bc5f04c60f751e095a94
|
File details
Details for the file seacloudai_sdk-0.1.3-py3-none-any.whl.
File metadata
- Download URL: seacloudai_sdk-0.1.3-py3-none-any.whl
- Upload date:
- Size: 71.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f2467312dfd96b458317bd28ee952d72f537007520e4668e48d11c19f3056ff8
|
|
| MD5 |
87536b450fd36e209d3b4dff0049b8d4
|
|
| BLAKE2b-256 |
8731bfe47525b001a2c48e52660db9456a16927485a2cf52ac0c36ebbd876985
|