runapi-seedream 0.2.2__tar.gz → 0.2.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,18 +1,18 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: runapi-seedream
3
- Version: 0.2.2
3
+ Version: 0.2.3
4
4
  Summary: RunAPI Seedream SDK for text-to-image and edit-image workflows in JavaScript, Python, Ruby, Go, Java, and PHP
5
5
  Project-URL: Homepage, https://runapi.ai/models/seedream
6
6
  Project-URL: Documentation, https://runapi.ai/docs/resources/sdks
7
7
  Project-URL: Source, https://github.com/runapi-ai/seedream-sdk
8
8
  Project-URL: Issues, https://github.com/runapi-ai/seedream-sdk/issues
9
9
  Project-URL: Changelog, https://github.com/runapi-ai/seedream-sdk/blob/main/CHANGELOG.md
10
- Project-URL: Release Notes, https://github.com/runapi-ai/seedream-sdk/releases/tag/python%2Fv0.2.2
10
+ Project-URL: Release Notes, https://github.com/runapi-ai/seedream-sdk/releases/tag/python%2Fv0.2.3
11
11
  Author-email: RunAPI <contact@runapi.ai>
12
12
  License-Expression: Apache-2.0
13
13
  Keywords: api,golang,gradle,image-api,image-generation,java,maven,python,ruby,runapi,runapi-ai,sdk,seedream,seedream-api,text-to-image,typescript
14
14
  Requires-Python: >=3.9
15
- Requires-Dist: runapi-core>=0.5.0
15
+ Requires-Dist: runapi-core>=0.5.1
16
16
  Description-Content-Type: text/markdown
17
17
 
18
18
  # Seedream Python SDK for RunAPI
@@ -74,11 +74,11 @@ RunAPI-generated file URLs are temporary. Download and store generated images, v
74
74
 
75
75
  ## Seedream 5 Pro
76
76
 
77
- Use `seedream-5-pro-text-to-image` for generation and `seedream-5-pro-edit` for image editing. Both accept `output_quality`, optional `output_format`, and optional content safety checking; editing accepts up to 10 source image URLs.
77
+ Use `seedream-5-pro-text-to-image` for generation, `seedream-5-pro-edit` for image editing, and `seedream-5-pro-layer-decomposition` to separate one image into a base image and ordered transparent layers.
78
78
 
79
79
  ## Language notes
80
80
 
81
- Pass parameters as keyword arguments and catch the `runapi.seedream` error classes when building image jobs or scripts. The available resources are `text_to_image` and `edit_image`. Keep `RUNAPI_API_KEY` in the environment or your secret manager; never commit API keys or callback secrets.
81
+ Pass parameters as keyword arguments and catch the `runapi.seedream` error classes when building image jobs or scripts. The available resources are `text_to_image`, `edit_image`, and `decompose_layers`. Keep `RUNAPI_API_KEY` in the environment or your secret manager; never commit API keys or callback secrets.
82
82
 
83
83
  ## Links
84
84
 
@@ -57,11 +57,11 @@ RunAPI-generated file URLs are temporary. Download and store generated images, v
57
57
 
58
58
  ## Seedream 5 Pro
59
59
 
60
- Use `seedream-5-pro-text-to-image` for generation and `seedream-5-pro-edit` for image editing. Both accept `output_quality`, optional `output_format`, and optional content safety checking; editing accepts up to 10 source image URLs.
60
+ Use `seedream-5-pro-text-to-image` for generation, `seedream-5-pro-edit` for image editing, and `seedream-5-pro-layer-decomposition` to separate one image into a base image and ordered transparent layers.
61
61
 
62
62
  ## Language notes
63
63
 
64
- Pass parameters as keyword arguments and catch the `runapi.seedream` error classes when building image jobs or scripts. The available resources are `text_to_image` and `edit_image`. Keep `RUNAPI_API_KEY` in the environment or your secret manager; never commit API keys or callback secrets.
64
+ Pass parameters as keyword arguments and catch the `runapi.seedream` error classes when building image jobs or scripts. The available resources are `text_to_image`, `edit_image`, and `decompose_layers`. Keep `RUNAPI_API_KEY` in the environment or your secret manager; never commit API keys or callback secrets.
65
65
 
66
66
  ## Links
67
67
 
@@ -4,14 +4,14 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "runapi-seedream"
7
- version = "0.2.2"
7
+ version = "0.2.3"
8
8
  description = "RunAPI Seedream SDK for text-to-image and edit-image workflows in JavaScript, Python, Ruby, Go, Java, and PHP"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
11
11
  license = "Apache-2.0"
12
12
  authors = [{ name = "RunAPI", email = "contact@runapi.ai" }]
13
13
  keywords = ["runapi", "runapi-ai", "seedream", "api", "sdk", "typescript", "python", "ruby", "golang", "java", "maven", "gradle", "image-generation", "text-to-image", "image-api", "seedream-api"]
14
- dependencies = ["runapi-core>=0.5.0"]
14
+ dependencies = ["runapi-core>=0.5.1"]
15
15
 
16
16
  [project.urls]
17
17
  Homepage = "https://runapi.ai/models/seedream"
@@ -19,7 +19,7 @@ Documentation = "https://runapi.ai/docs/resources/sdks"
19
19
  Source = "https://github.com/runapi-ai/seedream-sdk"
20
20
  Issues = "https://github.com/runapi-ai/seedream-sdk/issues"
21
21
  Changelog = "https://github.com/runapi-ai/seedream-sdk/blob/main/CHANGELOG.md"
22
- "Release Notes" = "https://github.com/runapi-ai/seedream-sdk/releases/tag/python%2Fv0.2.2"
22
+ "Release Notes" = "https://github.com/runapi-ai/seedream-sdk/releases/tag/python%2Fv0.2.3"
23
23
 
24
24
  [tool.hatch.build.targets.wheel]
25
25
  packages = ["src/runapi"]
@@ -7,6 +7,7 @@ from typing import Any, Optional
7
7
  from runapi.core import ProviderClient
8
8
 
9
9
  from .resources.edit_image import EditImage
10
+ from .resources.decompose_layers import DecomposeLayers
10
11
  from .resources.text_to_image import TextToImage
11
12
 
12
13
 
@@ -26,3 +27,4 @@ class SeedreamClient(ProviderClient):
26
27
  http = self._http
27
28
  self.text_to_image = TextToImage(http)
28
29
  self.edit_image = EditImage(http)
30
+ self.decompose_layers = DecomposeLayers(http)
@@ -1,4 +1,24 @@
1
1
  CONTRACT = {
2
+ "decompose-layers": {
3
+ "models": ["seedream-5-pro-layer-decomposition"],
4
+ "fields_by_model": {
5
+ "seedream-5-pro-layer-decomposition": {
6
+ "image_url": {
7
+ "required": True
8
+ },
9
+ "output_format": {
10
+ "enum": ["png", "jpeg"]
11
+ },
12
+ "prompt": {
13
+ "max": 5000,
14
+ "length": True
15
+ },
16
+ "size": {
17
+ "enum": ["auto", "1K", "1.5K", "2K"]
18
+ }
19
+ }
20
+ }
21
+ },
2
22
  "edit-image": {
3
23
  "models": ["seedream-4.5-edit", "seedream-5-lite-edit", "seedream-5-pro-edit", "seedream-v4-edit"],
4
24
  "fields_by_model": {
@@ -0,0 +1,5 @@
1
+ from .edit_image import EditImage
2
+ from .decompose_layers import DecomposeLayers
3
+ from .text_to_image import TextToImage
4
+
5
+ __all__ = ["TextToImage", "EditImage", "DecomposeLayers"]
@@ -0,0 +1,30 @@
1
+ """Seedream layer decomposition resource."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any, Optional
6
+
7
+ from runapi.core import RequestOptions, Resource
8
+
9
+ from ..contract_gen import CONTRACT
10
+ from ..types import CompletedDecomposeLayersResponse, DecomposeLayersResponse
11
+
12
+
13
+ class DecomposeLayers(Resource):
14
+ """Separate one image into a base image and independent layers."""
15
+
16
+ ENDPOINT = "/api/v1/seedream/decompose_layers"
17
+ RESPONSE_CLASS = DecomposeLayersResponse
18
+ COMPLETED_RESPONSE_CLASS = CompletedDecomposeLayersResponse
19
+
20
+ def run(self, options: Optional[RequestOptions] = None, **params: Any) -> Any:
21
+ task = self.create(options=options, **params)
22
+ return self._poll_until_complete(lambda: self.get(task.id, options=options))
23
+
24
+ def create(self, options: Optional[RequestOptions] = None, **params: Any) -> Any:
25
+ compacted = self._compact_params(params)
26
+ self._validate_contract(CONTRACT["decompose-layers"], compacted)
27
+ return self._request("post", self.ENDPOINT, body=compacted, options=options)
28
+
29
+ def get(self, id: str, options: Optional[RequestOptions] = None) -> Any:
30
+ return self._request("get", f"{self.ENDPOINT}/{id}", options=options)
@@ -37,3 +37,20 @@ class CompletedTextToImageResponse(TextToImageResponse):
37
37
 
38
38
 
39
39
  CompletedEditImageResponse = CompletedTextToImageResponse
40
+
41
+
42
+ class DecomposeLayersResponse(TaskResponse):
43
+ """Seedream layer decomposition task status response."""
44
+
45
+ id = required(str)
46
+ status = optional(str, enum=lambda: TaskResponse.Status.ALL)
47
+ base_image = optional(lambda: Image)
48
+ layers = optional([lambda: Image])
49
+ error = optional(str)
50
+
51
+
52
+ class CompletedDecomposeLayersResponse(DecomposeLayersResponse):
53
+ """Narrowed response once layer decomposition completes."""
54
+
55
+ base_image = required(lambda: Image)
56
+ layers = required([lambda: Image])
@@ -4,8 +4,9 @@ from runapi.core import config
4
4
  from runapi.core.errors import AuthenticationError, ValidationError
5
5
  from runapi.seedream import SeedreamClient
6
6
  from runapi.seedream.resources.edit_image import EditImage
7
+ from runapi.seedream.resources.decompose_layers import DecomposeLayers
7
8
  from runapi.seedream.resources.text_to_image import TextToImage
8
- from runapi.seedream.types import CompletedTextToImageResponse, TextToImageResponse
9
+ from runapi.seedream.types import DecomposeLayersResponse, CompletedTextToImageResponse, TextToImageResponse
9
10
 
10
11
 
11
12
  class FakeHttp:
@@ -57,12 +58,45 @@ def test_uses_injected_http_client():
57
58
  client = SeedreamClient(api_key="k", http_client=fake)
58
59
  assert client.text_to_image._http is fake
59
60
  assert client.edit_image._http is fake
61
+ assert client.decompose_layers._http is fake
60
62
 
61
63
 
62
64
  def test_exposes_resource_accessors():
63
65
  client = SeedreamClient(api_key="k", http_client=FakeHttp())
64
66
  assert isinstance(client.text_to_image, TextToImage)
65
67
  assert isinstance(client.edit_image, EditImage)
68
+ assert isinstance(client.decompose_layers, DecomposeLayers)
69
+
70
+
71
+ def test_decompose_layers_create_get_and_completed_response():
72
+ fake = FakeHttp(
73
+ {"id": "layers-1", "status": "processing"},
74
+ {
75
+ "id": "layers-1",
76
+ "status": "completed",
77
+ "base_image": {"url": "https://file.runapi.ai/base.jpeg"},
78
+ "layers": [{"url": "https://file.runapi.ai/layer.png"}],
79
+ },
80
+ )
81
+ client = SeedreamClient(api_key="k", http_client=fake)
82
+ created = client.decompose_layers.create(
83
+ model="seedream-5-pro-layer-decomposition",
84
+ image_url="https://cdn.runapi.ai/public/samples/image.jpg",
85
+ output_format="jpeg",
86
+ )
87
+ result = client.decompose_layers.get(created.id)
88
+
89
+ assert fake.calls[0] == (
90
+ "post",
91
+ "/api/v1/seedream/decompose_layers",
92
+ {
93
+ "model": "seedream-5-pro-layer-decomposition",
94
+ "image_url": "https://cdn.runapi.ai/public/samples/image.jpg",
95
+ "output_format": "jpeg",
96
+ },
97
+ )
98
+ assert isinstance(result, DecomposeLayersResponse)
99
+ assert result.base_image.url == "https://file.runapi.ai/base.jpeg"
66
100
 
67
101
 
68
102
  # --- request shapes -------------------------------------------------------
@@ -1,4 +0,0 @@
1
- from .edit_image import EditImage
2
- from .text_to_image import TextToImage
3
-
4
- __all__ = ["TextToImage", "EditImage"]