Python SDK for Legnext AI API - Professional image and video generation using Midjourney models
Project description
Legnext Python SDK
Official Python client library for the Legnext Midjourney API - Professional image and video generation.
Installation
pip install legnext
Quick Start
from legnext import Client
# Initialize client
client = Client(api_key="your-api-key")
# Generate an image
response = client.midjourney.diffusion(
text="a beautiful sunset over mountains"
)
# Wait for completion
result = client.tasks.wait_for_completion(response.job_id)
print(result.output.image_urls)
API Methods
Image Generation
diffusion(text, callback=None)
Create a new text-to-image generation task.
response = client.midjourney.diffusion(
text="a serene mountain landscape at sunset",
callback="https://your-domain.com/webhook" # Optional
)
Parameters:
text(str): Text prompt for image generation (1-8192 characters)callback(str, optional): Webhook URL for completion notification
Returns: TaskResponse with job_id and status
variation(job_id, image_no, type, remix_prompt=None, callback=None)
Create variations of a generated image.
response = client.midjourney.variation(
job_id="original-job-id",
image_no=0, # Image index (0-3)
type=1, # 0=Subtle, 1=Strong
remix_prompt="add more clouds", # Optional
callback="https://your-domain.com/webhook" # Optional
)
Parameters:
job_id(str): ID of the original image generation taskimage_no(int): Image number to vary (0-3)type(int): Variation intensity (0=Subtle, 1=Strong)remix_prompt(str, optional): Additional prompt for guided variationcallback(str, optional): Webhook URL
upscale(job_id, image_no, type, callback=None)
Upscale a generated image.
response = client.midjourney.upscale(
job_id="original-job-id",
image_no=0, # Image index (0-3)
type=1, # 0=Subtle, 1=Creative
callback="https://your-domain.com/webhook" # Optional
)
Parameters:
job_id(str): ID of the original image generation taskimage_no(int): Image number to upscale (0-3)type(int): Upscaling type (0=Subtle, 1=Creative)callback(str, optional): Webhook URL
reroll(job_id, callback=None)
Re-generate with the same prompt to get new variations.
response = client.midjourney.reroll(
job_id="original-job-id",
callback="https://your-domain.com/webhook" # Optional
)
Parameters:
job_id(str): ID of the task to rerollcallback(str, optional): Webhook URL
Image Composition
blend(img_urls, aspect_ratio, callback=None)
Blend 2-5 images together.
response = client.midjourney.blend(
img_urls=[
"https://example.com/image1.png",
"https://example.com/image2.png"
],
aspect_ratio="1:1", # Required: "2:3", "1:1", or "3:2"
callback="https://your-domain.com/webhook" # Optional
)
Parameters:
img_urls(list[str]): 2-5 image URLs to blendaspect_ratio(str): Aspect ratio - "2:3", "1:1", or "3:2"callback(str, optional): Webhook URL
describe(img_url, callback=None)
Generate text descriptions from an image.
response = client.midjourney.describe(
img_url="https://example.com/image.png",
callback="https://your-domain.com/webhook" # Optional
)
Parameters:
img_url(str): URL of image to describecallback(str, optional): Webhook URL
shorten(prompt, callback=None)
Optimize and shorten a prompt.
response = client.midjourney.shorten(
prompt="a very detailed and long prompt text that needs optimization",
callback="https://your-domain.com/webhook" # Optional
)
Parameters:
prompt(str): Prompt to shorten (1-8192 characters)callback(str, optional): Webhook URL
Image Extension
pan(job_id, image_no, direction, scale, remix_prompt=None, callback=None)
Extend an image in a specific direction.
response = client.midjourney.pan(
job_id="original-job-id",
image_no=0, # Image index (0-3)
direction=0, # 0=UP, 1=DOWN, 2=LEFT, 3=RIGHT
scale=1.5, # Extension scale (1.1-3.0)
remix_prompt="add mountains", # Optional
callback="https://your-domain.com/webhook" # Optional
)
Parameters:
job_id(str): ID of the original imageimage_no(int): Image number to extend (0-3)direction(int): Direction to extend (0=UP, 1=DOWN, 2=LEFT, 3=RIGHT)scale(float): Extension scale ratio (1.1-3.0)remix_prompt(str, optional): Text prompt for the extended areacallback(str, optional): Webhook URL
outpaint(job_id, image_no, scale, remix_prompt=None, callback=None)
Expand an image in all directions.
response = client.midjourney.outpaint(
job_id="original-job-id",
image_no=0, # Image index (0-3)
scale=1.3, # Extension scale (1.1-2.0)
remix_prompt="add forest background", # Optional
callback="https://your-domain.com/webhook" # Optional
)
Parameters:
job_id(str): ID of the original imageimage_no(int): Image number to extend (0-3)scale(float): Extension scale ratio (1.1-2.0)remix_prompt(str, optional): Text prompt for the extended areascallback(str, optional): Webhook URL
Image Editing
inpaint(job_id, image_no, mask, remix_prompt=None, callback=None)
Edit specific regions of an image using a mask.
with open("mask.png", "rb") as f:
mask_data = f.read()
response = client.midjourney.inpaint(
job_id="original-job-id",
image_no=0, # Image index (0-3)
mask=mask_data, # PNG mask file
remix_prompt="add a rainbow in the sky", # Optional
callback="https://your-domain.com/webhook" # Optional
)
Parameters:
job_id(str): ID of the original imageimage_no(int): Image number to edit (0-3)mask(bytes): Mask image (PNG) indicating regions to modifyremix_prompt(str, optional): Text prompt for the edited region (1-8192 characters)callback(str, optional): Webhook URL
remix(job_id, image_no, remix_prompt, mode=None, callback=None)
Transform an image with a new prompt.
response = client.midjourney.remix(
job_id="original-job-id",
image_no=0, # Image index (0-3)
remix_prompt="turn into a watercolor painting",
mode=0, # Optional: 0=Low, 1=High
callback="https://your-domain.com/webhook" # Optional
)
Parameters:
job_id(str): ID of the original imageimage_no(int): Image number to remix (0-3)remix_prompt(str): New prompt for remix (1-8192 characters)mode(int, optional): Remix mode (0=Low, 1=High)callback(str, optional): Webhook URL
edit(job_id, image_no, canvas, img_pos, remix_prompt, mask=None, callback=None)
Edit specific areas of an image with canvas positioning.
from legnext.types import Canvas, CanvasImg, Mask, Polygon
response = client.midjourney.edit(
job_id="original-job-id",
image_no=0,
canvas=Canvas(width=1024, height=1024),
img_pos=CanvasImg(width=512, height=512, x=256, y=256),
remix_prompt="change the sky to sunset colors",
mask=Mask(areas=[
Polygon(width=1024, height=1024, points=[100, 100, 500, 100, 500, 500, 100, 500])
]),
callback="https://your-domain.com/webhook" # Optional
)
Parameters:
job_id(str): ID of the original imageimage_no(int): Image number to edit (0-3)canvas(Canvas): Target canvas dimensionsimg_pos(CanvasImg): Image position and size on canvasremix_prompt(str): Edit instructions (1-8192 characters)mask(Mask, optional): Areas to repaint (polygon areas or mask URL)callback(str, optional): Webhook URL
upload_paint(img_url, canvas, img_pos, remix_prompt, mask, callback=None)
Advanced painting on uploaded images with canvas positioning.
from legnext.types import Canvas, CanvasImg, Mask
response = client.midjourney.upload_paint(
img_url="https://example.com/image.png",
canvas=Canvas(width=1024, height=1024),
img_pos=CanvasImg(width=768, height=768, x=128, y=128),
remix_prompt="add magical effects",
mask=Mask(url="https://example.com/mask.png"),
callback="https://your-domain.com/webhook" # Optional
)
Parameters:
img_url(str): URL of the image to editcanvas(Canvas): Target canvas dimensionsimg_pos(CanvasImg): Image position and size on canvasremix_prompt(str): Painting instructions (1-8192 characters)mask(Mask): Areas to edit (required - polygon areas or mask URL)callback(str, optional): Webhook URL
Image Enhancement
retexture(img_url, remix_prompt, callback=None)
Change textures and surfaces of an image.
response = client.midjourney.retexture(
img_url="https://example.com/image.png",
remix_prompt="metallic and shiny surfaces",
callback="https://your-domain.com/webhook" # Optional
)
Parameters:
img_url(str): URL of the image to retextureremix_prompt(str): Texture description (1-8192 characters)callback(str, optional): Webhook URL
remove_background(img_url, callback=None)
Remove the background from an image.
response = client.midjourney.remove_background(
img_url="https://example.com/image.png",
callback="https://your-domain.com/webhook" # Optional
)
Parameters:
img_url(str): URL of the image to processcallback(str, optional): Webhook URL
enhance(job_id, image_no, callback=None)
Enhance image quality (draft to high-res).
response = client.midjourney.enhance(
job_id="draft-job-id",
image_no=0, # Image index (0-3)
callback="https://your-domain.com/webhook" # Optional
)
Parameters:
job_id(str): ID of the draft mode imageimage_no(int): Image number to enhance (0-3)callback(str, optional): Webhook URL
Video Generation
video_diffusion(prompt, video_type=None, callback=None)
Generate a video from text prompt with image URL.
# Generate video with image URL in prompt
response = client.midjourney.video_diffusion(
prompt="https://example.com/image.png a flowing river through mountains",
video_type=1, # Optional: 0=480p, 1=720p
callback="https://your-domain.com/webhook" # Optional
)
Parameters:
prompt(str): Video generation prompt. Format: "[image_url] your prompt text" (1-8192 characters)video_type(int, optional): Video quality type (0: 480p, 1: 720p)callback(str, optional): Webhook URL
extend_video(job_id, video_no, prompt=None, callback=None)
Extend an existing video.
response = client.midjourney.extend_video(
job_id="original-video-job-id",
video_no=0, # Video index (0 or 1)
prompt="continue with dramatic lighting", # Optional
callback="https://your-domain.com/webhook" # Optional
)
Parameters:
job_id(str): ID of the original video taskvideo_no(int): Video number to extend (0 or 1)prompt(str, optional): Text prompt to guide the extension (1-8192 characters)callback(str, optional): Webhook URL
video_upscale(job_id, video_no, callback=None)
Upscale a video to higher resolution.
response = client.midjourney.video_upscale(
job_id="original-video-job-id",
video_no=0, # Video index (0 or 1)
callback="https://your-domain.com/webhook" # Optional
)
Parameters:
job_id(str): ID of the original video taskvideo_no(int): Video number to upscale (0 or 1)callback(str, optional): Webhook URL
Task Management
tasks.get(job_id)
Get the current status of a task.
task = client.tasks.get(job_id="job-123")
print(f"Status: {task.status}")
if task.status == "completed":
print(f"Images: {task.output.image_urls}")
tasks.wait_for_completion(job_id, timeout=300, poll_interval=3, on_progress=None)
Wait for a task to complete with automatic polling.
def show_progress(task):
print(f"Status: {task.status}")
result = client.tasks.wait_for_completion(
job_id="job-123",
timeout=600, # Max wait time in seconds
poll_interval=5, # Check every 5 seconds
on_progress=show_progress # Optional callback
)
print(f"Completed! Images: {result.output.image_urls}")
Parameters:
job_id(str): The job ID to wait fortimeout(float, optional): Maximum time to wait in seconds (default: 300)poll_interval(float, optional): Time between status checks in seconds (default: 3)on_progress(callable, optional): Callback function called on each status check
Async Support
All methods are available in async form using AsyncClient:
import asyncio
from legnext import AsyncClient
async def main():
async with AsyncClient(api_key="your-api-key") as client:
# Generate image
response = await client.midjourney.diffusion(
text="a futuristic cityscape"
)
# Wait for completion
result = await client.tasks.wait_for_completion(response.job_id)
print(result.output.image_urls)
asyncio.run(main())
Batch Processing
async def generate_multiple():
async with AsyncClient(api_key="your-api-key") as client:
# Start multiple tasks
tasks = [
client.midjourney.diffusion(text=f"image prompt {i}")
for i in range(5)
]
responses = await asyncio.gather(*tasks)
# Wait for all completions
results = await asyncio.gather(*[
client.tasks.wait_for_completion(r.job_id)
for r in responses
])
return results
Error Handling
from legnext import Client, LegnextAPIError, RateLimitError, ValidationError
client = Client(api_key="your-api-key")
try:
response = client.midjourney.diffusion(text="a beautiful landscape")
except ValidationError as e:
print(f"Invalid parameters: {e.message}")
except RateLimitError as e:
print(f"Rate limit exceeded: {e.message}")
except LegnextAPIError as e:
print(f"API error: {e.message} (status: {e.status_code})")
Exception Types:
ValidationError(400): Invalid request parametersAuthenticationError(401): Invalid API keyNotFoundError(404): Resource not foundRateLimitError(429): Rate limit exceededServerError(5xx): Server errorsLegnextAPIError: Base exception for all API errors
Requirements
- Python 3.10+
- httpx >= 0.27.0
- pydantic >= 2.0.0
Support
For questions or issues, please contact:
- Email: support@legnext.ai
- Website: https://legnext.ai
License
Apache License 2.0 - See LICENSE for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file legnext-0.2.4.tar.gz.
File metadata
- Download URL: legnext-0.2.4.tar.gz
- Upload date:
- Size: 69.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
796db0a95682542af1a45ee5735330af729498041aa56ead4e892b7b34adc66a
|
|
| MD5 |
51fc3c257b1e3b1c405ecf757da39d3c
|
|
| BLAKE2b-256 |
76542fdeb96e3ca037b6c1ef1688e56f5666fc53fcacd6b4df65557d82a10b13
|
File details
Details for the file legnext-0.2.4-py3-none-any.whl.
File metadata
- Download URL: legnext-0.2.4-py3-none-any.whl
- Upload date:
- Size: 30.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
17f0dfa37aa99b5d7b81e2ad6545faef16ced09fbfe987c0b2d058a01c9efe67
|
|
| MD5 |
353db93271bf37878dc2090c0ad244b4
|
|
| BLAKE2b-256 |
c95e6bc5ec7bf3cb8c3940ef5df765beb49463f3415dc996419751a091a884d5
|