Add file input, timing, and export to the batch generator.
Day 64 of 80
Yesterday's batch generator works but has one limitation: you have to type shots manually. Today you add:
Add a batch_from_file() function and update main() to support both interactive and file modes:
# Add these imports at the top:
import time
from pathlib import Path
async def batch_from_file(shots_file, output_file=None):
"""Load shots from a JSON file and batch generate.
shots_file: path to a JSON array of strings
["Wide establishing shot", "Close-up hands", "Aerial reveal"]
"""
shots_path = Path(shots_file)
if not shots_path.exists():
print(f"File not found: {shots_file}")
return
with open(shots_path, "r") as f:
shots = json.load(f)
if not isinstance(shots, list):
print("Error: JSON file must contain a list of strings")
return
print(f"Loaded {len(shots)} shots from {shots_file}")
start = time.time()
results = await batch_generate(shots)
elapsed = time.time() - start
successful = [r for r in results if r["status"] == "success"]
failed = [r for r in results if r["status"] != "success"]
print(f"\nResults: {len(successful)} successful, {len(failed)} failed")
print(f"Time: {elapsed:.1f}s ({elapsed/len(results):.2f}s per prompt)")
# Group results by shot for display and export
grouped = {}
for r in successful:
shot = r["shot"]
if shot not in grouped:
grouped[shot] = []
grouped[shot].append({
"platform": r["platform"],
"prompt": r["prompt"],
})
# Display
print()
for shot, prompts in grouped.items():
print(f"SHOT: {shot}")
for p in prompts:
print(f" [{p['platform']}] {p['prompt'][:70]}...")
print()
# Export to file
if output_file:
output = [
{"shot": shot, "prompts": prompts}
for shot, prompts in grouped.items()
]
with open(output_file, "w") as f:
json.dump(output, f, indent=2)
print(f"Exported to {output_file}")
return grouped
async def main():
"""Run in interactive or file mode based on command-line args."""
import sys
if len(sys.argv) > 1:
# File mode: python batch_generator.py shots.json [output.json]
shots_file = sys.argv[1]
output_file = sys.argv[2] if len(sys.argv) > 2 else "batch_output.json"
await batch_from_file(shots_file, output_file)
else:
# Interactive mode: enter shots manually
print("=== DVP Batch Prompt Generator ===\n")
print("Enter shots one per line. Type 'done' when finished.\n")
print("Tip: you can also run with a shots file:")
print(" python batch_generator.py my_shots.json output.json\n")
shots = []
while True:
shot = input(f" Shot {len(shots) + 1} (or 'done'): ")
if shot.strip().lower() == "done":
break
if shot.strip():
shots.append(shot.strip())
if not shots:
print("No shots entered.")
return
start = time.time()
results = await batch_generate(shots)
elapsed = time.time() - start
successful = [r for r in results if r["status"] == "success"]
print(f"\n{len(successful)} of {len(results)} prompts in {elapsed:.1f}s\n")
for r in results:
if r["status"] == "success":
print(f" [{r['platform']}] {r['shot'][:40]}")
print(f" {r['prompt'][:70]}...\n")
if __name__ == "__main__":
asyncio.run(main())
Create my_shots.json:
[
"Wide establishing shot, golf course at sunrise, mist rising",
"Close-up hands gripping club, shallow depth of field",
"Slow motion golf swing follow-through, backlit",
"Aerial drone pull-back revealing the full course",
"Crowd reaction in slow motion, bokeh background"
]
Then run:
python batch_generator.py my_shots.json output.json
You'll generate 15 prompts (5 shots × 3 platforms) in one batch. Open output.json and see the structured results.
python batch_generator.py shots.json output.jsonDay 65 adds an async /generate endpoint to your FastAPI app — so you can generate prompts for all platforms from a single API call.