Describe a shot in plain English — Claude writes the production-ready prompt
Day 18 of 80
A command-line tool called prompt_generator.py that:
Not a tutorial toy. Not a "hello world" exercise. After today you'll have a Python script you could open tomorrow morning and use for actual work — generating AI video prompts faster than you could write them yourself, with platform-specific formatting built in. That's the point of this course: every build day produces something worth keeping.
Create a new file called prompt_generator.py in your project folder. Copy this code in — then read the annotations below each section before running it.
import anthropic
import json
from dotenv import load_dotenv
load_dotenv()
client = anthropic.Anthropic()
load_dotenv() reads your .env file before anything else happens — the API key has to be in the environment before you create the client. anthropic.Anthropic() creates a client instance that automatically picks up ANTHROPIC_API_KEY from the environment. You don't pass the key anywhere explicitly — this is intentional. It's the safest pattern.
print("=== DVP Prompt Generator ===\n")
shot = input("Describe your shot in plain English: ")
platform = input("Target platform (Kling / Runway / Veo): ")
print("\nGenerating...")
input() pauses the script and waits for the user to type something and press Enter. The string argument is the prompt shown to the user. The value they type is returned and stored in the variable. This is how all command-line tools collect user input. The \n in the print statement adds a blank line — purely cosmetic, but it makes the output easier to read.
message = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=300,
system="You are an expert AI video prompt engineer who writes concise, "
"production-ready prompts for AI video generation platforms.",
messages=[
{
"role": "user",
"content": f"""Write a production-ready {platform} prompt for this shot:
{shot}
Requirements:
- Include camera movement, lighting, mood, and style details
- Match {platform}'s prompt style and strengths
- Keep it under 100 words
- Return ONLY the prompt text, nothing else"""
}
]
)
system= sets Claude's role. It's an expert prompt engineer — not a general assistant. This shapes every response.messages=[{"role": "user", "content": ...}] is the conversation. Always a list of dictionaries. Each dict has a role ("user" or "assistant") and content (the text).f"""...""") lets you write a multi-line prompt with variables. {platform} and {shot} are replaced at runtime.generated_prompt = message.content[0].text
print(f"\n--- Generated {platform} Prompt ---")
print(generated_prompt)
print(f"\n(Used {message.usage.input_tokens} input + "
f"{message.usage.output_tokens} output tokens)")
message.content[0].text — the path you memorized yesterday. Store it in a variable (generated_prompt) so you can use it multiple times without re-drilling into the object. Printing token usage is a good habit: it tells you how "expensive" each call is, and if output_tokens equals your max_tokens, Claude hit your limit and the response may be cut off.
save = input("\nSave to your prompt library? (y/n): ")
if save.lower() == "y":
try:
with open("prompts.json", "r") as f:
prompts = json.load(f)
except FileNotFoundError:
prompts = []
prompts.append({
"platform": platform,
"shot": shot,
"prompt": generated_prompt
})
with open("prompts.json", "w") as f:
json.dump(prompts, f, indent=2)
print(f"Saved! Library now has {len(prompts)} prompts.")
FileNotFoundError), start with an empty list instead. This makes the script work on both first run and subsequent runs without any extra setup.prompts.append({...}) adds the new prompt as a dictionary to the list.indent=2 makes the JSON human-readable when you open it in a text editor.save.lower() == "y" means "y", "Y", "yes", "YES" all work — .lower() normalizes the input before comparing.$ python prompt_generator.py
=== DVP Prompt Generator ===
Describe your shot in plain English: aerial pull back from a golfer at sunrise
Target platform (Kling / Runway / Veo): Kling
Generating...
--- Generated Kling Prompt ---
Aerial drone shot slowly pulling back from a lone golfer mid-swing at golden
hour. Sun crests the horizon behind rolling fairways. Warm orange and amber
light silhouettes the figure. Shallow depth of field. Cinematic, 4K, slow
motion 60fps.
(Used 87 input + 64 output tokens)
Save to your prompt library? (y/n): y
Saved! Library now has 1 prompts.
Open prompts.json in Cursor. You'll see your prompt stored as structured JSON. Run the script again with a different shot and platform — save that one too. Run it a third time. Watch the library grow. This is your data, on your machine, in a format that's easy to read and process programmatically. You just built a real AI tool.
| Error | What it means | Fix |
|---|---|---|
AuthenticationError |
API key is wrong or missing | Check your .env file — make sure the key is correct and there are no extra spaces |
ModuleNotFoundError: anthropic |
SDK not installed | Run pip install anthropic in the same terminal you're using to run the script |
| Output looks cut off | Hit max_tokens limit |
Increase max_tokens from 300 to 500 and run again |
.env not loading |
load_dotenv() can't find the file |
Make sure .env is in the same folder as prompt_generator.py |
prompt_generator.py runs without errorsprompts.json exists and contains your saved promptstry/except FileNotFoundError is thereYou extend this into a multi-platform comparison tool — one shot description, three simultaneous Claude calls (Kling, Runway, Veo), all displayed side by side. You'll learn to wrap API calls in functions and loop over a list. The code gets more sophisticated, but the core pattern stays the same.