runapi-midjourney 0.1.0__py3-none-any.whl
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.
- runapi/midjourney/__init__.py +24 -0
- runapi/midjourney/client.py +25 -0
- runapi/midjourney/contract_gen.py +58 -0
- runapi/midjourney/py.typed +0 -0
- runapi/midjourney/resources/__init__.py +7 -0
- runapi/midjourney/resources/edit_image.py +29 -0
- runapi/midjourney/resources/get_seed.py +18 -0
- runapi/midjourney/resources/image_to_prompt.py +18 -0
- runapi/midjourney/resources/image_to_video.py +29 -0
- runapi/midjourney/resources/text_to_image.py +29 -0
- runapi/midjourney/types.py +44 -0
- runapi_midjourney-0.1.0.dist-info/METADATA +51 -0
- runapi_midjourney-0.1.0.dist-info/RECORD +14 -0
- runapi_midjourney-0.1.0.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"""Midjourney client for RunAPI."""
|
|
2
|
+
|
|
3
|
+
from runapi.core import (
|
|
4
|
+
AuthenticationError,
|
|
5
|
+
InsufficientCreditsError,
|
|
6
|
+
NotFoundError,
|
|
7
|
+
RateLimitError,
|
|
8
|
+
TaskFailedError,
|
|
9
|
+
TaskTimeoutError,
|
|
10
|
+
ValidationError,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
from .client import MidjourneyClient
|
|
14
|
+
|
|
15
|
+
__all__ = [
|
|
16
|
+
"MidjourneyClient",
|
|
17
|
+
"AuthenticationError",
|
|
18
|
+
"RateLimitError",
|
|
19
|
+
"InsufficientCreditsError",
|
|
20
|
+
"NotFoundError",
|
|
21
|
+
"ValidationError",
|
|
22
|
+
"TaskFailedError",
|
|
23
|
+
"TaskTimeoutError",
|
|
24
|
+
]
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"""Midjourney client."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Optional
|
|
4
|
+
|
|
5
|
+
from runapi.core import ClientOptions, HttpClient, resolve_api_key
|
|
6
|
+
|
|
7
|
+
from .resources.edit_image import EditImage
|
|
8
|
+
from .resources.get_seed import GetSeed
|
|
9
|
+
from .resources.image_to_prompt import ImageToPrompt
|
|
10
|
+
from .resources.image_to_video import ImageToVideo
|
|
11
|
+
from .resources.text_to_image import TextToImage
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class MidjourneyClient:
|
|
15
|
+
"""Midjourney image generation, editing, image-to-video, and helper client."""
|
|
16
|
+
|
|
17
|
+
def __init__(self, api_key: Optional[str] = None, **options: Any) -> None:
|
|
18
|
+
resolved_api_key = resolve_api_key(api_key)
|
|
19
|
+
client_options = ClientOptions(api_key=resolved_api_key, **options)
|
|
20
|
+
http = client_options.http_client or HttpClient(client_options)
|
|
21
|
+
self.text_to_image = TextToImage(http)
|
|
22
|
+
self.edit_image = EditImage(http)
|
|
23
|
+
self.image_to_video = ImageToVideo(http)
|
|
24
|
+
self.image_to_prompt = ImageToPrompt(http)
|
|
25
|
+
self.get_seed = GetSeed(http)
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
CONTRACT = {
|
|
2
|
+
"edit-image": {
|
|
3
|
+
"models": ["midjourney-edit-image"],
|
|
4
|
+
"fields_by_model": {
|
|
5
|
+
"midjourney-edit-image": {
|
|
6
|
+
"prompt": {
|
|
7
|
+
"required": True
|
|
8
|
+
},
|
|
9
|
+
"source_image_url": {
|
|
10
|
+
"required": True
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"get-seed": {
|
|
16
|
+
"models": [],
|
|
17
|
+
"fields_by_model": {
|
|
18
|
+
"_": {
|
|
19
|
+
"image_id": {
|
|
20
|
+
"required": True
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"image-to-prompt": {
|
|
26
|
+
"models": [],
|
|
27
|
+
"fields_by_model": {
|
|
28
|
+
"_": {
|
|
29
|
+
"source_image_url": {
|
|
30
|
+
"required": True
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"image-to-video": {
|
|
36
|
+
"models": ["midjourney-image-to-video"],
|
|
37
|
+
"fields_by_model": {
|
|
38
|
+
"midjourney-image-to-video": {
|
|
39
|
+
"output_resolution": {
|
|
40
|
+
"enum": ["480p"]
|
|
41
|
+
},
|
|
42
|
+
"source_image_url": {
|
|
43
|
+
"required": True
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"text-to-image": {
|
|
49
|
+
"models": ["midjourney-v8.1"],
|
|
50
|
+
"fields_by_model": {
|
|
51
|
+
"midjourney-v8.1": {
|
|
52
|
+
"prompt": {
|
|
53
|
+
"required": True
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
from .edit_image import EditImage
|
|
2
|
+
from .get_seed import GetSeed
|
|
3
|
+
from .image_to_prompt import ImageToPrompt
|
|
4
|
+
from .image_to_video import ImageToVideo
|
|
5
|
+
from .text_to_image import TextToImage
|
|
6
|
+
|
|
7
|
+
__all__ = ["TextToImage", "EditImage", "ImageToVideo", "ImageToPrompt", "GetSeed"]
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""Midjourney edit-image resource."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict, Optional
|
|
4
|
+
|
|
5
|
+
from runapi.core import RequestOptions, Resource
|
|
6
|
+
|
|
7
|
+
from ..contract_gen import CONTRACT
|
|
8
|
+
from ..types import CompletedImageTaskResponse, ImageTaskResponse
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class EditImage(Resource):
|
|
12
|
+
ENDPOINT = "/api/v1/midjourney/edit_image"
|
|
13
|
+
RESPONSE_CLASS = ImageTaskResponse
|
|
14
|
+
COMPLETED_RESPONSE_CLASS = CompletedImageTaskResponse
|
|
15
|
+
|
|
16
|
+
def run(self, options: Optional[RequestOptions] = None, **params: Any) -> Any:
|
|
17
|
+
task = self.create(options=options, **params)
|
|
18
|
+
return self._poll_until_complete(lambda: self.get(task.id, options=options))
|
|
19
|
+
|
|
20
|
+
def create(self, options: Optional[RequestOptions] = None, **params: Any) -> Any:
|
|
21
|
+
compacted = self._compact_params(params)
|
|
22
|
+
self._validate_params(compacted)
|
|
23
|
+
return self._request("post", self.ENDPOINT, body=compacted, options=options)
|
|
24
|
+
|
|
25
|
+
def get(self, id: str, options: Optional[RequestOptions] = None) -> Any:
|
|
26
|
+
return self._request("get", f"{self.ENDPOINT}/{id}", options=options)
|
|
27
|
+
|
|
28
|
+
def _validate_params(self, params: Dict[str, Any]) -> None:
|
|
29
|
+
self._validate_contract(CONTRACT["edit-image"], params)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"""Midjourney get-seed resource."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Optional
|
|
4
|
+
|
|
5
|
+
from runapi.core import RequestOptions, Resource
|
|
6
|
+
|
|
7
|
+
from ..contract_gen import CONTRACT
|
|
8
|
+
from ..types import GetSeedResponse
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class GetSeed(Resource):
|
|
12
|
+
ENDPOINT = "/api/v1/midjourney/get_seed"
|
|
13
|
+
RESPONSE_CLASS = GetSeedResponse
|
|
14
|
+
|
|
15
|
+
def run(self, options: Optional[RequestOptions] = None, **params: Any) -> Any:
|
|
16
|
+
compacted = self._compact_params(params)
|
|
17
|
+
self._validate_contract(CONTRACT["get-seed"], compacted)
|
|
18
|
+
return self._request("post", self.ENDPOINT, body=compacted, options=options)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"""Midjourney image-to-prompt resource."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict, Optional
|
|
4
|
+
|
|
5
|
+
from runapi.core import RequestOptions, Resource
|
|
6
|
+
|
|
7
|
+
from ..contract_gen import CONTRACT
|
|
8
|
+
from ..types import ImageToPromptResponse
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ImageToPrompt(Resource):
|
|
12
|
+
ENDPOINT = "/api/v1/midjourney/image_to_prompt"
|
|
13
|
+
RESPONSE_CLASS = ImageToPromptResponse
|
|
14
|
+
|
|
15
|
+
def run(self, options: Optional[RequestOptions] = None, **params: Any) -> Any:
|
|
16
|
+
compacted = self._compact_params(params)
|
|
17
|
+
self._validate_contract(CONTRACT["image-to-prompt"], compacted)
|
|
18
|
+
return self._request("post", self.ENDPOINT, body=compacted, options=options)
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""Midjourney image-to-video resource."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict, Optional
|
|
4
|
+
|
|
5
|
+
from runapi.core import RequestOptions, Resource
|
|
6
|
+
|
|
7
|
+
from ..contract_gen import CONTRACT
|
|
8
|
+
from ..types import CompletedVideoTaskResponse, VideoTaskResponse
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ImageToVideo(Resource):
|
|
12
|
+
ENDPOINT = "/api/v1/midjourney/image_to_video"
|
|
13
|
+
RESPONSE_CLASS = VideoTaskResponse
|
|
14
|
+
COMPLETED_RESPONSE_CLASS = CompletedVideoTaskResponse
|
|
15
|
+
|
|
16
|
+
def run(self, options: Optional[RequestOptions] = None, **params: Any) -> Any:
|
|
17
|
+
task = self.create(options=options, **params)
|
|
18
|
+
return self._poll_until_complete(lambda: self.get(task.id, options=options))
|
|
19
|
+
|
|
20
|
+
def create(self, options: Optional[RequestOptions] = None, **params: Any) -> Any:
|
|
21
|
+
compacted = self._compact_params(params)
|
|
22
|
+
self._validate_params(compacted)
|
|
23
|
+
return self._request("post", self.ENDPOINT, body=compacted, options=options)
|
|
24
|
+
|
|
25
|
+
def get(self, id: str, options: Optional[RequestOptions] = None) -> Any:
|
|
26
|
+
return self._request("get", f"{self.ENDPOINT}/{id}", options=options)
|
|
27
|
+
|
|
28
|
+
def _validate_params(self, params: Dict[str, Any]) -> None:
|
|
29
|
+
self._validate_contract(CONTRACT["image-to-video"], params)
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"""Midjourney text-to-image resource."""
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict, Optional
|
|
4
|
+
|
|
5
|
+
from runapi.core import RequestOptions, Resource
|
|
6
|
+
|
|
7
|
+
from ..contract_gen import CONTRACT
|
|
8
|
+
from ..types import CompletedImageTaskResponse, ImageTaskResponse
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class TextToImage(Resource):
|
|
12
|
+
ENDPOINT = "/api/v1/midjourney/text_to_image"
|
|
13
|
+
RESPONSE_CLASS = ImageTaskResponse
|
|
14
|
+
COMPLETED_RESPONSE_CLASS = CompletedImageTaskResponse
|
|
15
|
+
|
|
16
|
+
def run(self, options: Optional[RequestOptions] = None, **params: Any) -> Any:
|
|
17
|
+
task = self.create(options=options, **params)
|
|
18
|
+
return self._poll_until_complete(lambda: self.get(task.id, options=options))
|
|
19
|
+
|
|
20
|
+
def create(self, options: Optional[RequestOptions] = None, **params: Any) -> Any:
|
|
21
|
+
compacted = self._compact_params(params)
|
|
22
|
+
self._validate_params(compacted)
|
|
23
|
+
return self._request("post", self.ENDPOINT, body=compacted, options=options)
|
|
24
|
+
|
|
25
|
+
def get(self, id: str, options: Optional[RequestOptions] = None) -> Any:
|
|
26
|
+
return self._request("get", f"{self.ENDPOINT}/{id}", options=options)
|
|
27
|
+
|
|
28
|
+
def _validate_params(self, params: Dict[str, Any]) -> None:
|
|
29
|
+
self._validate_contract(CONTRACT["text-to-image"], params)
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"""Midjourney response models."""
|
|
2
|
+
|
|
3
|
+
from runapi.core import BaseModel, TaskResponse, optional, required
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class MediaUrl(BaseModel):
|
|
7
|
+
url = optional(str)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class ImageTaskResponse(TaskResponse):
|
|
11
|
+
id = required(str)
|
|
12
|
+
status = optional(str, enum=lambda: TaskResponse.Status.ALL)
|
|
13
|
+
images = optional([lambda: MediaUrl])
|
|
14
|
+
image_id = optional(str)
|
|
15
|
+
actions = optional([str])
|
|
16
|
+
progress = optional(int)
|
|
17
|
+
error = optional(str)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class CompletedImageTaskResponse(ImageTaskResponse):
|
|
21
|
+
images = required([lambda: MediaUrl])
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class VideoTaskResponse(TaskResponse):
|
|
25
|
+
id = required(str)
|
|
26
|
+
status = optional(str, enum=lambda: TaskResponse.Status.ALL)
|
|
27
|
+
videos = optional([lambda: MediaUrl])
|
|
28
|
+
video_id = optional(str)
|
|
29
|
+
progress = optional(int)
|
|
30
|
+
error = optional(str)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class CompletedVideoTaskResponse(VideoTaskResponse):
|
|
34
|
+
videos = required([lambda: MediaUrl])
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class ImageToPromptResponse(BaseModel):
|
|
38
|
+
prompts = required([str])
|
|
39
|
+
error = optional(str)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class GetSeedResponse(BaseModel):
|
|
43
|
+
seed = optional(int)
|
|
44
|
+
error = optional(str)
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: runapi-midjourney
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: RunAPI Midjourney SDK for image generation, editing, image-to-video, and image helper workflows in JavaScript, Python, Ruby, Go, Java, and PHP
|
|
5
|
+
Project-URL: Homepage, https://runapi.ai/models/midjourney
|
|
6
|
+
Project-URL: Documentation, https://runapi.ai/docs#sdk-midjourney
|
|
7
|
+
Project-URL: Source, https://github.com/runapi-ai/midjourney-sdk
|
|
8
|
+
Project-URL: Issues, https://github.com/runapi-ai/midjourney-sdk/issues
|
|
9
|
+
Author-email: RunAPI <contact@runapi.ai>
|
|
10
|
+
License-Expression: Apache-2.0
|
|
11
|
+
Keywords: api,golang,gradle,image-generation,java,maven,midjourney,midjourney-api,python,ruby,runapi,runapi-ai,sdk,typescript,video-generation
|
|
12
|
+
Requires-Python: >=3.9
|
|
13
|
+
Requires-Dist: runapi-core>=0.1.5
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
|
|
16
|
+
# Midjourney Python SDK for RunAPI
|
|
17
|
+
|
|
18
|
+
Use `runapi-midjourney` for Midjourney image generation, editing, image-to-video, image-to-prompt, and seed lookup in Python applications and workers.
|
|
19
|
+
|
|
20
|
+
## Install
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pip install runapi-midjourney
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Quick Start
|
|
27
|
+
|
|
28
|
+
```python
|
|
29
|
+
from runapi.midjourney import MidjourneyClient
|
|
30
|
+
|
|
31
|
+
client = MidjourneyClient()
|
|
32
|
+
result = client.text_to_image.run(
|
|
33
|
+
model="midjourney-v8.1",
|
|
34
|
+
prompt="A cobalt blue ceramic vase on white marble",
|
|
35
|
+
)
|
|
36
|
+
print(result.images[0].url)
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Use `create`, `get`, and `run` for `text_to_image`, `edit_image`, and `image_to_video`. Use `run` directly for `image_to_prompt` and `get_seed`. Generated media URLs are temporary and should be stored in durable storage.
|
|
40
|
+
|
|
41
|
+
## Links
|
|
42
|
+
|
|
43
|
+
- Model page: https://runapi.ai/models/midjourney
|
|
44
|
+
- Product docs: https://runapi.ai/docs#midjourney
|
|
45
|
+
- SDK docs: https://runapi.ai/docs#sdk-midjourney
|
|
46
|
+
- V8.1 details: https://runapi.ai/models/midjourney/v8.1
|
|
47
|
+
- Image editing details: https://runapi.ai/models/midjourney/edit-image
|
|
48
|
+
- Image-to-video details: https://runapi.ai/models/midjourney/image-to-video
|
|
49
|
+
- Repository: https://github.com/runapi-ai/midjourney-sdk
|
|
50
|
+
|
|
51
|
+
Licensed under the Apache License, Version 2.0.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
runapi/midjourney/__init__.py,sha256=iPY4zP3scqZkAww0dSwpjdOdFp-bu2tSJ6sDpNgAVzk,472
|
|
2
|
+
runapi/midjourney/client.py,sha256=mVbOpvFaN1s2okMgC04KWKhJ5CCSoBzm0oQ26j4DAUk,981
|
|
3
|
+
runapi/midjourney/contract_gen.py,sha256=txhBp5ZdXELAujJM0bkadJAdTtGhSeXIz47JXyOyftI,1380
|
|
4
|
+
runapi/midjourney/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
|
+
runapi/midjourney/types.py,sha256=7sp4W5F9eQ_yArcwZjSE1SvGviTdTg40tf2gvav6ao0,1075
|
|
6
|
+
runapi/midjourney/resources/__init__.py,sha256=mkM4BH6-gZRQx8ol13fp9gRheBjvte7dyPGtHxFOXxQ,271
|
|
7
|
+
runapi/midjourney/resources/edit_image.py,sha256=gzR-dD4CL-zu4YCsb4DWaOVClNO3C1iekS6PnI9bQfQ,1174
|
|
8
|
+
runapi/midjourney/resources/get_seed.py,sha256=lI1jTtob1kSsv--meNjbVSuGDLvBc3hLsIjfSmQcY5s,585
|
|
9
|
+
runapi/midjourney/resources/image_to_prompt.py,sha256=06FERJCEkIoOVdQhULmFDbNNS_ZmD4EbzC8oBD-KfbY,630
|
|
10
|
+
runapi/midjourney/resources/image_to_video.py,sha256=ovIa4keZ1Yk1bD4zF0ptDHEaXwxU56mJbcpAvRP-W40,1189
|
|
11
|
+
runapi/midjourney/resources/text_to_image.py,sha256=hSC9Tax-uPw4RNbkVGZu8i4RvV4rxbitasDXx0aVPKE,1185
|
|
12
|
+
runapi_midjourney-0.1.0.dist-info/METADATA,sha256=RimxtPh2-bsnNzvGESCdttGC3eM18lVGVojWd6oPHzA,1984
|
|
13
|
+
runapi_midjourney-0.1.0.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
|
|
14
|
+
runapi_midjourney-0.1.0.dist-info/RECORD,,
|