Skip to main content

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 task
  • image_no (int): Image number to vary (0-3)
  • type (int): Variation intensity (0=Subtle, 1=Strong)
  • remix_prompt (str, optional): Additional prompt for guided variation
  • callback (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 task
  • image_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 reroll
  • callback (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 blend
  • aspect_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 describe
  • callback (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 image
  • image_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 area
  • callback (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 image
  • image_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 areas
  • callback (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 image
  • image_no (int): Image number to edit (0-3)
  • mask (bytes): Mask image (PNG) indicating regions to modify
  • remix_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 image
  • image_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 image
  • image_no (int): Image number to edit (0-3)
  • canvas (Canvas): Target canvas dimensions
  • img_pos (CanvasImg): Image position and size on canvas
  • remix_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 edit
  • canvas (Canvas): Target canvas dimensions
  • img_pos (CanvasImg): Image position and size on canvas
  • remix_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 retexture
  • remix_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 process
  • callback (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 image
  • image_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 task
  • video_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 task
  • video_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 for
  • timeout (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 parameters
  • AuthenticationError (401): Invalid API key
  • NotFoundError (404): Resource not found
  • RateLimitError (429): Rate limit exceeded
  • ServerError (5xx): Server errors
  • LegnextAPIError: 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:


License

Apache License 2.0 - See LICENSE for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

legnext-0.2.4.tar.gz (69.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

legnext-0.2.4-py3-none-any.whl (30.2 kB view details)

Uploaded Python 3

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

Hashes for legnext-0.2.4.tar.gz
Algorithm Hash digest
SHA256 796db0a95682542af1a45ee5735330af729498041aa56ead4e892b7b34adc66a
MD5 51fc3c257b1e3b1c405ecf757da39d3c
BLAKE2b-256 76542fdeb96e3ca037b6c1ef1688e56f5666fc53fcacd6b4df65557d82a10b13

See more details on using hashes here.

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

Hashes for legnext-0.2.4-py3-none-any.whl
Algorithm Hash digest
SHA256 17f0dfa37aa99b5d7b81e2ad6545faef16ced09fbfe987c0b2d058a01c9efe67
MD5 353db93271bf37878dc2090c0ad244b4
BLAKE2b-256 c95e6bc5ec7bf3cb8c3940ef5df765beb49463f3415dc996419751a091a884d5

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page