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")

# Check account balance
balance = client.account.balance()
print(f"Available Points: {balance.available_points}")

# 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

Account Management

account.balance()

Get account balance and quota information.

balance = client.account.balance()
print(f"Account ID: {balance.account_id}")
print(f"Balance USD: {balance.balance_usd}")
print(f"Available Points: {balance.available_points}")
print(f"Available Credits: {balance.available_credits}")
print(f"Alert Threshold: {balance.alert_threshold}")
print(f"Low Balance Alert: {balance.low_balance_alert}")

Returns: BalanceResponse with account information

Response Fields:

  • account_id (int): Your account ID
  • balance_usd (float): Account balance in USD
  • available_points (int): Available points for API usage
  • available_credits (int): Available credits
  • alert_threshold (int): Low balance alert threshold
  • low_balance_alert (bool): Whether low balance alert is enabled
  • updated_at (str): Last update timestamp

Example:

from legnext import Client

client = Client(api_key="your-api-key")
balance = client.account.balance()

if balance.available_points < 100:
    print(f"⚠️  Low balance: {balance.available_points} points remaining")
else:
    print(f"✅ Balance: {balance.balance_usd} USD ({balance.available_points} points)")

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:
        # Check balance
        balance = await client.account.balance()
        print(f"Balance: {balance.balance_usd} USD")
        
        # 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.3.0.tar.gz (74.9 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.3.0-py3-none-any.whl (31.3 kB view details)

Uploaded Python 3

File details

Details for the file legnext-0.3.0.tar.gz.

File metadata

  • Download URL: legnext-0.3.0.tar.gz
  • Upload date:
  • Size: 74.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for legnext-0.3.0.tar.gz
Algorithm Hash digest
SHA256 7203555b78aaea0b5031fdd8d5e421cd03f006337c07c69a2e9c98a09a6e33fe
MD5 8dae314b11fe1c554b58f62b1df75bc4
BLAKE2b-256 5a8ef00e64a4bac854008d5ea9fe8f3360c825ab9fd77af6e1991353b076c40d

See more details on using hashes here.

File details

Details for the file legnext-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: legnext-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 31.3 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.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3a10a2501ece2d37a837cf9ca3b7e6251eb2422fd81ff99885c7ce12d794a4d2
MD5 88b0468bf8a5517dbe830a77d0ca5a9b
BLAKE2b-256 8826754f2795d097fbabd5c7894dd63aed35fca9888d76c7a25896e2e8020619

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