A Streamlit application for creating and refining prompts in a comprehensive picture book generation workflow using OpenRouter APIs.
This app implements a complete 5-step picture book creation process:
- Story & Characters Generation - Create character bible and story outline using GPT-5
- Character Pack Creation - Generate character reference sheets using Gemini-2.5-Flash-Image
- Story Expansion - Expand text and refine image prompts with character consistency
- Page Art Generation - Create final illustrations with proper character references
- Final Output - Compile everything into a complete picture book JSON
- Python 3.8 or higher
- OpenRouter API account and API key
- Streamlit
-
Clone or download this project
cd Streamlit_Prompts_OpenRouter_ChildBook -
Install dependencies
pip install -r requirements.txt
-
Configure API Keys
Edit
.streamlit/secrets.tomland add your OpenRouter API key:[openrouter] api_key = "your_actual_openrouter_api_key_here" base_url = "https://openrouter.ai/api/v1"
Get your API key from: https://openrouter.ai/
-
Run the application
streamlit run app.py
-
Open your browser to
http://localhost:8501
This project also includes REST API endpoints for programmatic access to the picture book creation functionality.
-
Unified API (
unified_api.py) - Port 8000- Create Story Endpoint:
POST /create-story- Creates story foundation with characters - Generate References Endpoint:
POST /generate-references- Generates character reference sheets
- Create Story Endpoint:
-
Story Expansion API (
story_expansion.py) - Port 8001- Expand Story Endpoint:
POST /expand-story- Expands story outline into full prose with detailed image prompts
- Expand Story Endpoint:
- Page Art API - Port 8002 - Generate final page illustrations
- Final Output API - Port 8003 - Compile complete picture book
-
Set up environment variables
cd "Streamlit_Prompts_OpenRouter_ChildBook/REST API" python setup_env.py
-
Install API dependencies
pip install -r requirements.txt
-
Start the APIs
python run_apis.py
-
Test the APIs
# Test unified API python test_unified_api.py # Test story expansion API python test_story_expansion.py
- Unified API: http://localhost:8000/docs
- Story Expansion API: http://localhost:8001/docs
Create Story:
curl -X POST "http://localhost:8000/create-story" \
-H "Content-Type: application/json" \
-d '{
"topic": "Why do we need to brush our teeth",
"child_age": "3-4 years",
"style": "educational",
"custom_style": "",
"context": "Include a friendly dentist character"
}'Generate References:
curl -X POST "http://localhost:8000/generate-references" \
-H "Content-Type: application/json" \
-d '{
"character": {
"id": "character_1",
"name": "Dr. Sparkle",
"species_or_type": "human",
"age": "friendly adult",
"core_traits": ["kind", "patient", "knowledgeable"],
"signature_features": {
"outfit": "white coat with colorful dental tools",
"props": ["magical toothbrush", "shiny mirror"],
"colors": ["#FFFFFF", "#4ECDC4"]
},
"expression_range": ["smiling", "encouraging", "gentle", "proud", "helpful"]
},
"style_guide": {
"visual_style_tags": ["watercolor", "soft", "friendly", "bright"],
"palette": {
"primary": "#FF6B6B",
"secondary": "#4ECDC4",
"accents": ["#45B7D1", "#96CEB4", "#FFEAA7"]
},
"lighting_mood": "warm and inviting",
"do": ["use soft rounded shapes", "include warm colors", "show expressive faces"],
"dont": ["use scary imagery", "include sharp edges", "use dark themes"]
},
"sheet_types": ["turnaround", "expression"],
"reference_images": []
}'Expand Story:
curl -X POST "http://localhost:8001/expand-story" \
-H "Content-Type: application/json" \
-d '{
"story_data": {
"story": {
"title": "Why Do We Brush Our Teeth?",
"topic": "Dental hygiene for children",
"style": "educational",
"content": [
{
"type": "paragraph",
"page": 1,
"text": "Introduction to brushing teeth"
},
{
"type": "image",
"page": 2,
"prompt": "Child brushing teeth"
}
]
},
"characters": [
{
"id": "character_1",
"name": "Dr. Sparkle",
"species_or_type": "human",
"age": "friendly adult"
}
],
"style_guide": {
"visual_style_tags": ["watercolor", "soft", "friendly"],
"palette": {
"primary": "#FF6B6B",
"secondary": "#4ECDC4"
}
},
"target_age": "3-4 years"
},
"character_references": [
{
"character_id": "character_1",
"turnaround_url": "https://example.com/turnaround.png",
"expression_url": "https://example.com/expression.png"
}
],
"tone_preference": "Keep original style",
"detail_level": "Standard detail"
}'import requests
# Create story
response = requests.post("http://localhost:8000/create-story", json={
"topic": "Why do we need to brush our teeth",
"child_age": "3-4 years",
"style": "educational",
"custom_style": "",
"context": "Include a friendly dentist character"
})
story_data = response.json()
# Generate references
response = requests.post("http://localhost:8000/generate-references", json={
"character": {
"id": "character_1",
"name": "Dr. Sparkle",
"species_or_type": "human",
"age": "friendly adult",
"core_traits": ["kind", "patient", "knowledgeable"],
"signature_features": {
"outfit": "white coat with colorful dental tools",
"props": ["magical toothbrush", "shiny mirror"],
"colors": ["#FFFFFF", "#4ECDC4"]
},
"expression_range": ["smiling", "encouraging", "gentle", "proud", "helpful"]
},
"style_guide": {
"visual_style_tags": ["watercolor", "soft", "friendly", "bright"],
"palette": {
"primary": "#FF6B6B",
"secondary": "#4ECDC4",
"accents": ["#45B7D1", "#96CEB4", "#FFEAA7"]
},
"lighting_mood": "warm and inviting",
"do": ["use soft rounded shapes", "include warm colors", "show expressive faces"],
"dont": ["use scary imagery", "include sharp edges", "use dark themes"]
},
"sheet_types": ["turnaround", "expression"],
"reference_images": []
})
references_data = response.json()
# Expand story
response = requests.post("http://localhost:8001/expand-story", json={
"story_data": story_data["story_data"],
"character_references": [
{
"character_id": "character_1",
"turnaround_url": references_data["reference_sheets"]["turnaround"]["image_url"],
"expression_url": references_data["reference_sheets"]["expression"]["image_url"]
}
],
"tone_preference": "Keep original style",
"detail_level": "Standard detail"
})
expanded_story = response.json()- Unified API:
GET http://localhost:8000/health - Story Expansion API:
GET http://localhost:8001/health
- Enter your book topic (e.g., "Why do we need to brush our teeth")
- Select target age group
- Choose visual style (simple, adventure, educational, gentle, or custom)
- Add any additional context
- Generate and review the initial prompt
- Click "Send to API" to create your story outline and character bible
- Review the generated characters
- Select which reference sheet types to create (turnaround, expression, pose)
- Generate character reference sheets for visual consistency
- Expand the draft story into full prose
- Refine image prompts with character references and consistency tags
- Review and edit the expansion prompt before generating
- Generate illustrations for each page using the refined prompts
- Character references are automatically included for consistency
- Review and customize art prompts before generation
- Compile all elements into a complete picture book JSON
- Download the complete book data or a simplified summary
- View statistics about your generated book
The app allows you to review and edit all prompts before sending them to the API. You can:
- Modify the generated prompts in the text areas
- Add specific instructions or constraints
- Adjust the tone or style requirements
All prompt templates are defined in utils/prompts.py and can be customized:
get_initial_story_prompt()- Initial story and character generationget_character_pack_prompt()- Character reference sheet creationget_story_expansion_prompt()- Story expansion and image refinementget_page_art_prompt()- Final illustration generation
The OpenRouter API client is configured in utils/llm.py:
- Model selection (GPT-4o is used as GPT-5 may not be available)
- Token limits and temperature settings
- Error handling and response validation
Streamlit_Prompts_OpenRouter_ChildBook/
βββ .streamlit/
β βββ secrets.toml # API key configuration
βββ utils/
β βββ llm.py # OpenRouter API client
β βββ prompts.py # Prompt templates and validation
βββ app.py # Main Streamlit application
βββ requirements.txt # Python dependencies
βββ README.md # This file
- Text Generation:
openai/gpt-4o(as GPT-5 proxy) - Image Generation:
google/gemini-2.0-flash-exp
The app maintains state across steps:
story_data- Generated story and characterscharacter_pack- Character reference sheetsexpanded_story- Expanded text with refined promptsgenerated_images- Final page illustrations
-
API Connection Failed
- Verify your OpenRouter API key in
.streamlit/secrets.toml - Check your internet connection
- Ensure you have credits in your OpenRouter account
- Verify your OpenRouter API key in
-
JSON Parsing Errors
- The AI sometimes generates malformed JSON
- Review the raw response in the error display
- Try regenerating with a more specific prompt
-
Character Consistency Issues
- Ensure character pack is generated before story expansion
- Check that character references are properly included in image prompts
- Adjust consistency tags for better results
-
Missing Dependencies
pip install --upgrade -r requirements.txt
- Use Step navigation to work on specific parts
- Save intermediate results by downloading JSON outputs
- Clear session data if needed using the sidebar button
Feel free to contribute by:
- Improving prompt templates
- Adding new features or models
- Enhancing the UI/UX
- Fixing bugs or adding error handling
This project is open source. Please check with OpenRouter for their API usage terms and conditions.
Happy Picture Book Creating! πβ¨