├── README.md ├── midjourney_api.py ├── requirements.txt └── ship_readme.png /README.md: -------------------------------------------------------------------------------- 1 | # Midjourney Python API (Unofficial) 2 | 3 | Welcome aboard the unofficial Midjourney API 🎈🚀. A Python wrapper around the midjourney software to generate AI-based images. 4 | 5 | ![Example Image](ship_readme.png) 6 | 7 | ## Setup & Installation 8 | 9 | To get started, follow the steps below to run it on your machine: 10 | 11 | 1. Clone the repository: 12 | ```shell 13 | git clone https://github.com/yachty66/unofficial_midjourney_python_api.git 14 | ``` 15 | 2. Install the required packages from `requirements.txt`. 16 | 17 | 3. If your folder structure resembles the one shown below and you wish to use the API in a file named `main.py`: 18 | ```shell 19 | project_directory 20 | │ main.py 21 | │ 22 | └───unofficial_midjourney_python_api 23 | │ midjourney_api.py 24 | ``` 25 | Then, you can import the API in `main.py` as follows: 26 | ```python 27 | from unofficial_midjourney_python_api.midjourney_api import MidjourneyApi 28 | ``` 29 | 30 | 4. If you haven't subscribed to midjourney yet, you should do so now. 31 | 32 | 5. With the same Discord account you used for your midjourney subscription, create a new server (name isn't crucial) and add the midjourney bot from midjourney to this server. 33 | 34 | 6. Next, you need to gather specific information to call the API appropriately - prompt, application_id, guild_id, channel_id, version, id, and authorization. 35 | 36 | 7. Navigate to your discord server, open your developer console (on mac, you can use fn+f12), and open the network tab. 37 | 38 | 8. Activate the midjourney bot with the slash command `/imagine` followed by an arbitrary prompt, then click on the `interactions` option. 39 | 40 | 9. Firstly, visit the `Headers` tab and note down your `Authorization` key. Then, navigate to the `Payload` window and save the application_id, guild_id, channel_id, version, id, and authorization values from the JSON. 41 | 42 | 10. In your project root, create a new folder named `images`. Any image created by the API will be saved here. 43 | 44 | 11. Invoke the API as follows: 45 | ```python 46 | midjourney = MidjourneyApi(prompt="prompt", application_id="application_id", guild_id="guild_id", channel_id="channel_id", version="version", id="id", authorization="authorization") 47 | ``` 48 | Wait for about 1-2 minutes, and you should find your generated image within the `images` folder. 49 | 50 | ## Showcase of Projects Built with This API 51 | 52 | - [CelebrityDiffusion](https://twitter.com/celebritydiff) 53 | 54 | Have you created an exciting project using the API? DM me the details at [Twitter](https://twitter.com/MaxHager66)! 55 | 56 | Happy journeying with Midjourney API! 57 | -------------------------------------------------------------------------------- /midjourney_api.py: -------------------------------------------------------------------------------- 1 | import requests 2 | from urllib.parse import urlparse 3 | import os 4 | import random 5 | import time 6 | import json 7 | 8 | class MidjourneyApi(): 9 | def __init__(self, prompt, application_id, guild_id, channel_id, version, id, authorization): 10 | self.application_id = application_id 11 | self.guild_id = guild_id 12 | self.channel_id = channel_id 13 | self.version = version 14 | self.id = id 15 | self.authorization = authorization 16 | self.prompt = prompt 17 | self.message_id = "" 18 | self.custom_id = "" 19 | self.image_path_str = "" 20 | self.send_message() 21 | self.get_message() 22 | self.choose_images() 23 | self.download_image() 24 | 25 | def send_message(self): 26 | url = "https://discord.com/api/v9/interactions" 27 | data = { 28 | "type": 2, 29 | "application_id": self.application_id, 30 | "guild_id": self.guild_id, 31 | "channel_id": self.channel_id, 32 | "session_id": "cannot be empty", 33 | "data": { 34 | "version": self.version, 35 | "id": self.id, 36 | "name": "imagine", 37 | "type": 1, 38 | "options": [ 39 | { 40 | "type": 3, 41 | "name": "prompt", 42 | "value": self.prompt 43 | } 44 | ], 45 | "application_command": { 46 | "id": self.id, 47 | "application_id": self.application_id, 48 | "version": self.version, 49 | "default_member_permissions": None, 50 | "type": 1, 51 | "nsfw": False, 52 | "name": "imagine", 53 | "description": "Create images with Midjourney", 54 | "dm_permission": True, 55 | "contexts": None, 56 | "options": [ 57 | { 58 | "type": 3, 59 | "name": "prompt", 60 | "description": "The prompt to imagine", 61 | "required": True 62 | } 63 | ] 64 | }, 65 | "attachments": [] 66 | }, 67 | } 68 | headers = { 69 | 'Authorization': self.authorization, 70 | 'Content-Type': 'application/json', 71 | } 72 | response = requests.post(url, headers=headers, json=data) 73 | 74 | def get_message(self): 75 | headers = { 76 | 'Authorization': self.authorization, 77 | "Content-Type": "application/json", 78 | } 79 | for i in range(3): 80 | time.sleep(30) 81 | try: 82 | response = requests.get(f'https://discord.com/api/v9/channels/{self.channel_id}/messages', headers=headers) 83 | messages = response.json() 84 | most_recent_message_id = messages[0]['id'] 85 | self.message_id = most_recent_message_id 86 | components = messages[0]['components'][0]['components'] 87 | buttons = [comp for comp in components if comp.get('label') in ['U1', 'U2', 'U3', 'U4']] 88 | custom_ids = [button['custom_id'] for button in buttons] 89 | random_custom_id = random.choice(custom_ids) 90 | self.custom_id = random_custom_id 91 | break 92 | except: 93 | ValueError("Timeout") 94 | 95 | def choose_images(self): 96 | url = "https://discord.com/api/v9/interactions" 97 | headers = { 98 | "Authorization": self.authorization, 99 | "Content-Type": "application/json", 100 | } 101 | data = { 102 | "type": 3, 103 | "guild_id": self.guild_id, 104 | "channel_id": self.channel_id, 105 | "message_flags": 0, 106 | "message_id": self.message_id, 107 | "application_id": self.application_id, 108 | "session_id": "cannot be empty", 109 | "data": { 110 | "component_type": 2, 111 | "custom_id": self.custom_id, 112 | } 113 | } 114 | response = requests.post(url, headers=headers, data=json.dumps(data)) 115 | 116 | def download_image(self): 117 | headers = { 118 | 'Authorization': self.authorization, 119 | "Content-Type": "application/json", 120 | } 121 | for i in range(3): 122 | time.sleep(30) 123 | try: 124 | response = requests.get(f'https://discord.com/api/v9/channels/{self.channel_id}/messages', headers=headers) 125 | messages = response.json() 126 | most_recent_message_id = messages[0]['id'] 127 | self.message_id = most_recent_message_id 128 | image_url = messages[0]['attachments'][0]['url'] 129 | image_response = requests.get(image_url) 130 | a = urlparse(image_url) 131 | image_name = os.path.basename(a.path) 132 | self.image_path_str = f"images/{image_name}" 133 | with open(f"images/{image_name}", "wb") as file: 134 | file.write(image_response.content) 135 | break 136 | except: 137 | raise ValueError("Timeout") 138 | 139 | def image_path(self): 140 | return self.image_path_str 141 | 142 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | certifi==2023.5.7 2 | charset-normalizer==3.1.0 3 | idna==3.4 4 | requests==2.31.0 5 | urllib3==2.0.2 6 | -------------------------------------------------------------------------------- /ship_readme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yachty66/unofficial_midjourney_python_api/6309d1543de337098be815ba130ecd67a32290e1/ship_readme.png --------------------------------------------------------------------------------