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.
@@ -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,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.31.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any