> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://docs.videogen.io/libraries/python/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.videogen.io/_mcp/server. # Python > Install and configure the videogen Python package. Covers sync and async clients, video workflows, tool execution polling, file uploads/downloads, and webhook verification. ## Install ```bash pip install videogen ``` ## Create a client ```python from videogen import VideoGen vg = VideoGen(api_key="sk_videogen_live_...") ``` The client reads from the `VIDEOGEN_API_KEY` environment variable when no `api_key` is provided. ### Async client ```python from videogen import AsyncVideoGen vg = AsyncVideoGen(api_key="sk_videogen_live_...") ``` ## Generate a video from a script Workflows turn a script into a finished video asynchronously. Prefer `script_to_video_and_wait` when you can block: ```python from videogen import VideoGen vg = VideoGen(api_key="sk_videogen_live_...") run = vg.workflows.script_to_video_and_wait( script=( "Staying hydrated keeps your body and mind running at their best. " "Drinking enough water boosts your energy, focus, and mood. " "Keep a water bottle nearby and sip throughout the day." ), visual_style={ "type": "AI_IMAGE", "ai_style": "Loose watercolor illustration, visible brushstrokes, soft color bleeds, paper texture, muted palette. A clear uncluttered subject centered in the frame, occupying only the middle half of the image, with generous empty margins on all four sides, no background clutter.", }, quality="HIGH", auto_export=True, remix_actions=[ {"type": "ENABLE_CAPTIONS"}, { "type": "CONVERT_IMAGES_TO_VIDEOS", "motion_prompt": "slow cinematic push-in", "mute_output_videos": True, "quality": "HIGH", }, ], ) print(run.get("download_url") or run.get("downloadUrl")) ``` Use `project_id` for export, remix, and other API calls. `project_url` (also on the response) is optional: a link to open the project in the VideoGen editor for manual review (team members and project collaborators only). Request kwargs use snake\_case (and nested dict keys); the client serializes body/query keys to camelCase for the API. Responses are plain dicts with snake\_case keys. For start-then-poll yourself, call `script_to_video` then `poll_workflow_run(vg, workflow_run_id)`. For the async client, use `script_to_video_and_wait` on `AsyncVideoGen` (or `async_poll_workflow_run`): ```python from videogen import AsyncVideoGen vg = AsyncVideoGen(api_key="sk_videogen_live_...") run = await vg.workflows.script_to_video_and_wait( script="Staying hydrated keeps your body and mind running at their best.", visual_style={ "type": "AI_IMAGE", "ai_style": "Loose watercolor illustration, visible brushstrokes, soft color bleeds, paper texture, muted palette. A clear uncluttered subject centered in the frame, occupying only the middle half of the image, with generous empty margins on all four sides, no background clutter.", }, quality="HIGH", auto_export=True, remix_actions=[ {"type": "ENABLE_CAPTIONS"}, { "type": "CONVERT_IMAGES_TO_VIDEOS", "motion_prompt": "slow cinematic push-in", "mute_output_videos": True, "quality": "HIGH", }, ], ) print(run.get("download_url") or run.get("downloadUrl")) ``` ### Options | Option | Type | Default | Description | | ------------------ | ----------------- | --------- | ------------------------------------------------- | | `poll_interval_ms` | `int` | `1500` | Milliseconds between polls. | | `timeout_ms` | `int` | `3600000` | Maximum wait time before raising. | | `cancel_event` | `threading.Event` | (none) | Cancel sync polling early (`PollCancelledError`). | For the async client, pass `asyncio.Event` as `cancel_event` to `*_and_wait` methods and async poll helpers (`async_poll_workflow_run`, `async_poll_executed_tool`, `async_poll_project_export`, `async_poll_public_preview`). ## Run a standalone tool All tool endpoints are asynchronous. Prefer `generate_image_and_wait` (and the other tool `*_and_wait` methods). Use `create_public_preview` when you need a shareable preview URL: ```python from videogen import VideoGen, create_public_preview vg = VideoGen(api_key="sk_videogen_live_...") execution = vg.tools.generate_image_and_wait( prompt="A sunset over a calm ocean, cinematic lighting", ) print(execution["status"]) # "succeeded" file_id = execution["results"][0]["file_id"] preview = create_public_preview(vg, file_id) ``` ## Upload a file ```python from videogen import VideoGen, upload_file vg = VideoGen(api_key="sk_videogen_live_...") with open("input.mp4", "rb") as f: file = upload_file(vg, f, display_name="input.mp4", type="VIDEO") print(file["file_id"]) # "vg_file_..." ``` ## Download a file ```python from videogen import VideoGen, download_file vg = VideoGen(api_key="sk_videogen_live_...") download_file(vg, "vg_file_...", output_path="output.mp4") ``` ## Verify a webhook ```python from videogen import verify_webhook_signature payload = verify_webhook_signature( raw_body=raw_body, headers=headers, secret=signing_secret, ) if payload["event"] == "tool_execution.succeeded": print(payload["results"]) ``` ## Links * [PyPI: videogen](https://pypi.org/project/videogen/) * [GitHub: videogen-python-sdk](https://github.com/video-gen/videogen-python-sdk) * [REST API Reference](/rest-api-reference) > HTTP API with TypeScript and Python SDKs for generating image, video, and audio assets with VideoGen.