Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v4
uses: actions/setup-python@v5
with:
python-version: '3.9'

Expand All @@ -36,15 +36,15 @@ jobs:

- name: Setup Pages
if: github.ref == 'refs/heads/main'
uses: actions/configure-pages@v3
uses: actions/configure-pages@v5

- name: Upload artifact
if: github.ref == 'refs/heads/main'
uses: actions/upload-pages-artifact@v2
uses: actions/upload-pages-artifact@v3
with:
path: 'docs/_build/html'

- name: Deploy to GitHub Pages
if: github.ref == 'refs/heads/main'
id: deployment
uses: actions/deploy-pages@v2
uses: actions/deploy-pages@v4
75 changes: 73 additions & 2 deletions segmind/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,19 @@
Usage:
import segmind

# Run a model
# Run a model (sync v1)
response = segmind.run("seedream-v3-text-to-image", prompt="A sunset")
with open("image.jpg", "wb") as f:
f.write(response.content)

# Run a model (v2 async — submit + poll until done)
result = segmind.run_async("seedance-1-pro", prompt="A sunset", timeout=300)

# Or split the submit / wait for finer control
job = segmind.submit_async("seedance-1-pro", prompt="A sunset")
print(job.request_id)
result = job.wait(timeout=300)

# Upload files
result = segmind.files.upload("image.png")
print(result["file_urls"])
Expand All @@ -22,6 +30,13 @@
from typing import Optional

from segmind.client import SegmindClient
from segmind.v2 import (
DEFAULT_POLL_INTERVAL_S,
DEFAULT_POLL_TIMEOUT_S,
AsyncJob,
InferenceFailed,
InferenceTimeout,
)
Comment on lines +33 to +39

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Exposing SegmindError at the package level (segmind.SegmindError) is highly recommended so that users of the SDK can easily import and catch the base exception class without needing to import from internal modules. This also avoids workarounds in the test suite.

Suggested change
from segmind.v2 import (
DEFAULT_POLL_INTERVAL_S,
DEFAULT_POLL_TIMEOUT_S,
AsyncJob,
InferenceFailed,
InferenceTimeout,
)
from segmind.exceptions import SegmindError
from segmind.v2 import (
DEFAULT_POLL_INTERVAL_S,
DEFAULT_POLL_TIMEOUT_S,
AsyncJob,
InferenceFailed,
InferenceTimeout,
)


__version__ = "1.0.0"

Expand All @@ -38,7 +53,7 @@ def _get_client() -> SegmindClient:


def run(slug: str, **params):
"""Run a model inference request.
"""Run a sync (v1) model inference request.

Args:
slug: Model slug/identifier
Expand All @@ -56,6 +71,55 @@ def run(slug: str, **params):
return _get_client().run(slug, **params)


def submit_async(slug: str, **params) -> AsyncJob:
"""Submit a v2 async inference request and return a job handle.

The handle exposes `.wait()`, `.status()`, and `.result()`. Use `.wait()`
to block until COMPLETED or FAILED. Useful when you want to track the
request_id, run other work in parallel, or batch many submissions.

Args:
slug: Model slug/identifier.
**params: Parameters to pass to the model.

Example:
import segmind
job = segmind.submit_async("seedance-1-pro", prompt="A sunset")
print(job.request_id)
result = job.wait(timeout=300)
"""
return _get_client().submit_async(slug, **params)


def run_async(
slug: str,
*,
timeout: float = DEFAULT_POLL_TIMEOUT_S,
interval: float = DEFAULT_POLL_INTERVAL_S,
**params,
) -> dict:
"""Run a v2 async inference request to completion (submit + poll).

Args:
slug: Model slug/identifier.
timeout: Hard deadline in seconds (default 600s).
interval: Status-poll cadence (default 1.0s).
**params: Parameters to pass to the model.

Returns:
The final response body once the task reaches COMPLETED.

Raises:
segmind.InferenceFailed: server returned FAILED.
segmind.InferenceTimeout: timeout elapsed before terminal state.

Example:
import segmind
result = segmind.run_async("seedance-1-pro", prompt="A sunset", timeout=300)
"""
return _get_client().run_async(slug, timeout=timeout, interval=interval, **params)


# Namespace proxies
class _Files:
def upload(self, file_paths):
Expand Down Expand Up @@ -123,11 +187,18 @@ def recent(self, model_name):
generations = _Generations()

__all__ = [
"DEFAULT_POLL_INTERVAL_S",
"DEFAULT_POLL_TIMEOUT_S",
"AsyncJob",
"InferenceFailed",
"InferenceTimeout",
Comment on lines +190 to +194

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Add SegmindError to all to explicitly export it as part of the public API.

Suggested change
"DEFAULT_POLL_INTERVAL_S",
"DEFAULT_POLL_TIMEOUT_S",
"AsyncJob",
"InferenceFailed",
"InferenceTimeout",
"DEFAULT_POLL_INTERVAL_S",
"DEFAULT_POLL_TIMEOUT_S",
"AsyncJob",
"InferenceFailed",
"InferenceTimeout",
"SegmindError",

"SegmindClient",
"files",
"generations",
"models",
"pixelflows",
"run",
"run_async",
"submit_async",
"webhooks",
]
40 changes: 40 additions & 0 deletions segmind/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import httpx

from segmind import v2 as _v2
from segmind.accounts import Accounts
from segmind.exceptions import raise_for_status
from segmind.files import Files
Expand Down Expand Up @@ -72,6 +73,45 @@ def run(self, slug: str, **params) -> httpx.Response:
raise_for_status(response)
return response

def submit_async(self, slug: str, **params) -> "_v2.AsyncJob":
"""Submit a v2 async inference request and return a job handle.

The handle exposes `wait()`, `status()`, and `result()`. Use `wait()`
to block until COMPLETED or FAILED. Default poll interval 1.0s,
timeout 600s — override per-call for very slow models.

Args:
slug: Model slug/identifier.
**params: Parameters to pass to the model.

Returns:
AsyncJob handle wrapping the submit response.
"""
return _v2.submit(self, slug, **params)

def run_async(
self,
slug: str,
*,
timeout: float = _v2.DEFAULT_POLL_TIMEOUT_S,
interval: float = _v2.DEFAULT_POLL_INTERVAL_S,
**params,
) -> dict:
"""One-shot v2 async inference: submit + wait. Returns the final
response body (the same dict you'd get from polling to COMPLETED).

Args:
slug: Model slug/identifier.
timeout: Hard deadline in seconds (default 600s).
interval: Status-poll cadence (default 1.0s).
**params: Parameters to pass to the model.

Raises:
v2.InferenceFailed: server returned FAILED.
v2.InferenceTimeout: timeout elapsed before terminal state.
"""
return _v2.run(self, slug, timeout=timeout, interval=interval, **params)

def stream(self, slug: str, **params) -> httpx.Response:
"""Stream a model inference request (not implemented).

Expand Down
Loading
Loading