Welcome! I'm excited to share the Viral Story Generator, a project that sits at the intersection of automated content creation and cutting-edge AI. This isn't just a tool; it's a demonstration of how sophisticated systems can be engineered to tackle creative challenges, transforming ideas into engaging short-form video content.
Imagine effortlessly generating compelling story scripts, complete with voiceovers and detailed storyboards, all powered by a local LLM and integrated with services like ElevenLabs. This project showcases the ability to design, build, and deploy complex applications that streamline creative workflows. If you're looking for innovative solutions and expertise in AI-driven automation, you've come to the right place. Let's explore what's possible! 🎉
This project was a little vision I had when AI was first becoming a big thing (2022). I wanted to create something that can make viral videos or stories for me, just by providing it a link or a topic and letting it do its thing. Working on this has thought me many things about LLMs and how to work them (lol).
If you have something you would like to create, implement, or integrate, please feel free to reach out to me at princeboachie@gmail.com.
- Story Script Generation: Automatically generates creative story scripts with video descriptions using a local LLM (cloud coming soon).
- Audio TTS: Converts the narrative into high-quality MP3 audio using ElevenLabs TTS. 🔊
- Storyboard Creation: Produces detailed JSON-formatted storyboards for video planning and production.
- Source Cleansing & Summarization: Merges and summarizes content from multiple web sources or provided text to form a coherent narrative base.
- Web Scraping: Utilizes Crawl4AI to efficiently extract content from web URLs.
- RESTful API: Provides HTTP endpoints for seamless integration and interaction.
- Task Queue Management: Employs Redis for robust background task processing.
- Containerized Deployment: Docker and Docker Compose for easy setup, development, and production deployment.
- Scalable Architecture: Designed with separate, scalable worker services for different tasks (API, scraping, generation).
- Monitoring: Integrated Prometheus and Grafana for production observability.
- Viral Story Generator 🚀✨
- Features
- Table of Contents
- Project Overview
- Architecture
- Program Flow
- Core Technologies & Tools
- Codebase Structure
- Installation
- Configuration
- Setting Up Your Environment
- Local Development & Testing
- Usage
- Docker Setup 🐳
- Key Modules and Functionality
- Dependencies & Citations
- Contributing
- License
- Changelog
The Viral Story Generator is a comprehensive system designed to automate the creation of short, engaging video scripts. It leverages a local Large Language Model (LLM) for content generation, ElevenLabs for realistic Text-to-Speech (TTS) audio, and Crawl4AI for web content extraction. The system is architected as a set of microservices, orchestrated with Docker, and managed via a RESTful API. This makes it a powerful tool for content creators looking to streamline their production pipeline.
The system is built upon a microservices architecture to ensure scalability, maintainability, and separation of concerns. Key components communicate via a Redis message queue for asynchronous task processing.
-
FastAPI Application (
api.py):- Serves as the main entry point for user requests.
- Handles HTTP request validation (using Pydantic models).
- Enqueues tasks (e.g., story generation, scraping) into Redis.
- Provides endpoints for status checking and retrieving results.
-
Worker Processes (
worker_runner.py,api_worker.py,scrape_worker.py,queue_worker.py):scrape_worker.py: Dedicated to web scraping tasks. It consumes URLs from a queue, uses Crawl4AI to fetch and parse content, and stores the results for further processing.api_worker.py/queue_worker.py: These workers handle the core story generation pipeline. They:- Dequeue tasks from Redis.
- Orchestrate calls to the LLM for script generation.
- Invoke ElevenLabs for TTS audio creation.
- Trigger storyboard generation.
- Manage data storage and status updates.
-
LLM Integration (
llm.py):- Provides an interface to the configured local Large Language Model.
- Manages prompt engineering (using templates from
prompts/) for generating story scripts and video descriptions.
-
ElevenLabs TTS (
elevenlabs_tts.py):- Integrates with the ElevenLabs API to convert text narratives into high-quality MP3 audio files.
-
Storyboard Generation (
storyboard.py):- Takes the generated script and produces a structured JSON storyboard, detailing scenes, dialogues, and visual cues.
-
Redis:
- Acts as a robust message broker for asynchronous task queuing between the API and worker services.
- Potentially used for caching and managing shared state or job metadata.
-
Storage (
storage/directory &data/):- Persistent local file storage for:
- Generated audio files (
.mp3). - Story scripts (
.txt). - Storyboard files (
.json). - Scraped source content.
- Job metadata.
- Generated audio files (
- Persistent local file storage for:
-
Docker & Docker Compose:
- Containerizes each service (API, workers, Redis, monitoring tools) for consistent environments.
- Simplifies deployment, scaling, and management of the entire application stack.
-
Monitoring (Prometheus & Grafana -
monitoring/):- Prometheus scrapes metrics from the application services.
- Grafana provides dashboards for visualizing these metrics, offering insights into system health and performance (primarily for production).
graph TD
subgraph "User Interaction & API Layer (main.py, api.py, api_handlers.py)"
direction LR
User["👤 User"] -- HTTP Request (URLs, Config, Topic) --> MAIN_PY["main.py (FastAPI App via uvicorn)"]
MAIN_PY --> API_PY["api.py (FastAPI Router)"]
API_PY -- "/generate, /stories" --> AH_CREATE["api_handlers.py: create_story_task()"]
AH_CREATE -- Returns Task ID --> API_PY
API_PY -- HTTP Response (Task ID) --> User
User -- HTTP Request (Task ID) --> JobStatusEndpoint_Combined["GET /api/stories/{task_id}<br/>(api.py)"]
JobStatusEndpoint_Combined -- Calls --> ApiGetStatus_Combined["api_handlers.get_task_status()"]
ApiGetStatus_Combined -- Returns Status --> JobStatusEndpoint_Combined
JobStatusEndpoint_Combined -- HTTP Response (Status, Asset URLs) --> User
User -- HTTP Request (Asset URL) --> DownloadResultEndpoint_Combined["GET /api/stories/{task_id}/download/...<br/>(api.py)"]
DownloadResultEndpoint_Combined -- Serves File --> User
end
subgraph "Task Queuing (Redis)"
AH_CREATE -- "Publishes 'generate_story' job" --> RedisQueue["📦 Redis Stream/Queue (api_jobs)"]
ApiGetStatus_Combined -- Reads from --> RedisQueue
ApiGetStatus_Combined -- "Reads final status/paths from" --> JobResult_Combined["📝 Job Result/Metadata (in Redis/Storage)"]
end
subgraph "Scraping Worker (scrape_worker.py)"
ScrapeWorker_Combined[🕷️ Scrape Worker]
Crawl4AI_Combined[🕸️ Crawl4AI Module]
Internet_Combined["🌐 Internet (for Crawl4AI)"]
ScrapedData_Combined["📄 Scraped Content"]
Screenshots_Combined["🖼️ Screenshots"]
RedisQueue -- Dequeues Scrape Job --> ScrapeWorker_Combined
ScrapeWorker_Combined -- Uses --> Crawl4AI_Combined
Crawl4AI_Combined -- Fetches Content --> Internet_Combined
ScrapeWorker_Combined -- Stores --> Screenshots_Combined
ScrapeWorker_Combined -- Stores --> ScrapedData_Combined
ScrapeWorker_Combined -- Updates Job Status in --> JobResult_Combined
ScrapeWorker_Combined -- Publishes Generation Job (refs ScrapedData/Screenshots) --> RedisQueue
end
%% Combined Content Generation Process to match large yellow block in image
subgraph "Content Generation Process (Workers, LLM, Prompts)"
direction TB
subgraph "B1. Queue Worker (via worker_runner.py, queue_worker.py)"
WR_RUNNER["worker_runner.py: main()"] -- "cmd: worker --worker-type queue" --> QW_MAIN["queue_worker.py: main()"]
QW_MAIN --> QW_RUN_WORKER["queue_worker.py: run_worker()"]
QW_RUN_WORKER --> QW_PRELOAD_Q["queue_worker.py: preload_components()"]
QW_RUN_WORKER --> QW_CONSUME["queue_worker.py: run_api_job_consumer()"]
QW_CONSUME -- "Consumes 'generate_story' job from" --> RedisQueue
QW_CONSUME -- "For each job" --> QW_PROCESS_SINGLE["queue_worker.py: process_single_api_job()"]
QW_PROCESS_SINGLE --> UTIL_PROC_JOB["utils.api_job_processor.py: process_api_job()"]
end
subgraph "B2. API Worker (via api_worker.py)"
AW_MAIN["api_worker.py: main()"] --> AW_RUN_WORKER["api_worker.py: run_worker()"]
AW_RUN_WORKER --> AW_PRELOAD_A["api_worker.py: preload_components()"]
AW_RUN_WORKER --> AW_PROCESS_JOBS["api_worker.py: process_api_jobs()"]
AW_PROCESS_JOBS -- "Consumes 'generate_story' job from" --> RedisQueue
AW_PROCESS_JOBS -- "For each job" --> UTIL_PROC_JOB
end
subgraph "C. Core Job Processing & LLM Orchestration (utils.api_job_processor.py)"
UTIL_PROC_JOB -- "Retrieves" --> ScrapedData_Combined
UTIL_PROC_JOB -- "Retrieves" --> Screenshots_Combined
UTIL_PROC_JOB -- "If cleaning markdown" --> LLM_CLEAN["llm.py: clean_markdown_with_llm()"]
UTIL_PROC_JOB -- "If generating story script" --> LLM_PROCESS["llm.py: process_with_llm()"]
LLM_CLEAN -- "Outputs Cleaned Markdown" --> UTIL_PROC_JOB
LLM_PROCESS -- "Outputs Generated Script" --> UTIL_PROC_JOB
UTIL_PROC_JOB -- "Produces/Updates" --> StoryScript_Combined["📜 Generated Story Script"]
UTIL_PROC_JOB -- Updates Job Status/Result --> JobResult_Combined
end
subgraph "D. LLM Markdown Cleaning Logic (llm.py)"
LLM_CLEAN --> LLM_PRE_PROCESS["llm.py: _pre_process_markdown()"]
LLM_CLEAN --> LLM_GEN_CLEAN_PROMPT["llm.py: _generate_cleaning_prompt()"]
LLM_GEN_CLEAN_PROMPT --> PROMPTS_CLEAN["prompts.py: get_clean_markdown_prompt()"]
LLM_CLEAN --> LLM_MAKE_REQUEST["llm.py: _make_llm_request(...)"]
LLM_CLEAN --> LLM_POST_PROCESS["llm.py: _post_process_llm_output()"]
end
subgraph "E. LLM Story Generation Logic (llm.py)"
LLM_PROCESS --> PROMPTS_SYS["prompts.py: get_system_instructions()"]
LLM_PROCESS --> PROMPTS_USER["prompts.py: get_user_prompt()"]
LLM_PROCESS --> LLM_MAKE_REQUEST
LLM_PROCESS --> LLM_CHECK_FORMAT["llm.py: _check_format()"]
LLM_PROCESS -- "If format issue" --> LLM_REFORMAT["llm.py: _reformat_text()"]
LLM_REFORMAT --> PROMPTS_FIX["prompts.py: get_fix_prompt()"]
LLM_REFORMAT --> LLM_MAKE_REQUEST
LLM_PROCESS --> LLM_EXTRACT_COT["llm.py: _extract_chain_of_thought()"]
end
subgraph "External LLM Interaction"
LLM_MAKE_REQUEST --> ExternalLLMService["🧠 External LLM API (e.g. OpenAI, Anthropic)"]
LocalLLM_Combined["🧠 Local LLM (if _make_llm_request uses local)"]
LLM_MAKE_REQUEST --> LocalLLM_Combined
end
end
subgraph "TTS Generation (elevenlabs_tts.py)"
TTS_Orchestrator_Combined["TTS Orchestrator"]
TTS_Core_Combined["elevenlabs_tts.generate_elevenlabs_audio"]
TTS_InputValidator_Combined["Input Validation"]
TTS_RequestBuilder_Combined["Build Request"]
TTS_APICall_Combined["HTTP POST to ElevenLabs"]
TTS_ResponseHandler_Combined["Process Response"]
ElevenLabsAPI_Combined[🗣️ ElevenLabs API Service]
AudioFile_Combined["🔊 Generated Audio File (.mp3)"]
StoryScript_Combined -- "Text Input" --> TTS_Orchestrator_Combined
TTS_Orchestrator_Combined -- "Invokes Core TTS" --> TTS_Core_Combined
TTS_Core_Combined --> TTS_InputValidator_Combined
TTS_InputValidator_Combined --> TTS_RequestBuilder_Combined
TTS_RequestBuilder_Combined --> TTS_APICall_Combined
TTS_APICall_Combined -- Request --> ElevenLabsAPI_Combined
ElevenLabsAPI_Combined -- Audio Data --> TTS_APICall_Combined
TTS_APICall_Combined --> TTS_ResponseHandler_Combined
TTS_ResponseHandler_Combined -- Saves MP3 --> AudioFile_Combined
TTS_Core_Combined -- Returns Path --> TTS_Orchestrator_Combined
end
subgraph "Audio Retry Flow"
LocalAudioQueueDir_Combined["📁 Local FS Queue for Failed Audio"]
ProcessAudioQueue_Combined["process_audio_queue()"]
TTS_Orchestrator_Combined -- "On Failure, queues for retry" --> LocalAudioQueueDir_Combined
ProcessAudioQueue_Combined -- "Scans" --> LocalAudioQueueDir_Combined
ProcessAudioQueue_Combined -- "Retries TTS via" --> TTS_Core_Combined
end
subgraph "Storyboard / Video Generation"
StoryboardGen_Combined["🎬 Storyboard Generator"]
StoryboardFile_Combined["🎞️ Generated Storyboard/Video File"]
StoryScript_Combined -- Input --> StoryboardGen_Combined
AudioFile_Combined -- Input --> StoryboardGen_Combined
Screenshots_Combined -- Input --> StoryboardGen_Combined
StoryboardGen_Combined -- Creates --> StoryboardFile_Combined
StoryboardGen_Combined -- Updates result in --> JobResult_Combined
end
subgraph "Storage & Final Results Access"
StorageMgr_Combined["🗄️ Storage Manager"]
StorageMgr_Combined -- Manages --> ScrapedData_Combined
StorageMgr_Combined -- Manages --> Screenshots_Combined
StorageMgr_Combined -- Manages --> StoryScript_Combined
StorageMgr_Combined -- Manages --> AudioFile_Combined
StorageMgr_Combined -- Manages --> StoryboardFile_Combined
StorageMgr_Combined -- Manages/Hosts --> JobResult_Combined
DownloadResultEndpoint_Combined -- Uses --> StorageMgr_Combined
StorageMgr_Combined -- Retrieves --> AudioFile_Combined
StorageMgr_Combined -- Retrieves --> StoryboardFile_Combined
end
subgraph "Monitoring (Production)"
Prometheus_Combined[📊 Prometheus]
Grafana_Combined[📈 Grafana]
MAIN_PY -- Metrics --> Prometheus_Combined
API_PY -- Metrics --> Prometheus_Combined
ScrapeWorker_Combined -- Metrics --> Prometheus_Combined
QW_MAIN -- Metrics --> Prometheus_Combined
AW_MAIN -- Metrics --> Prometheus_Combined
Prometheus_Combined -- Data Source --> Grafana_Combined
end
%% Styling from new diagram + adaptations
classDef entrypoint fill:#87CEEB,stroke:#333,stroke-width:2px
classDef api fill:#A9DFBF,stroke:#333,stroke-width:2px
classDef worker fill:#F9E79F,stroke:#333,stroke-width:2px
classDef util fill:#D5F5E3,stroke:#333,stroke-width:2px
classDef llm fill:#EBDEF0,stroke:#333,stroke-width:2px
classDef prompt fill:#FEF9E7,stroke:#333,stroke-width:2px
classDef queue fill:#FADBD8,stroke:#333,stroke-width:2px
classDef storage fill:#AED6F1,stroke:#333,stroke-width:2px
classDef external fill:#E8DAEF,stroke:#333,stroke-width:2px
classDef monitoring fill:#F5B7B1,stroke:#333,stroke-width:2px
class MAIN_PY,WR_RUNNER,AW_MAIN entrypoint;
class API_PY,AH_CREATE,JobStatusEndpoint_Combined,DownloadResultEndpoint_Combined api;
class QW_MAIN,QW_RUN_WORKER,QW_PRELOAD_Q,QW_CONSUME,QW_PROCESS_SINGLE,AW_RUN_WORKER,AW_PRELOAD_A,AW_PROCESS_JOBS,ScrapeWorker_Combined,TTS_Orchestrator_Combined worker;
class UTIL_PROC_JOB,TTS_Core_Combined,TTS_InputValidator_Combined,TTS_RequestBuilder_Combined,TTS_APICall_Combined,TTS_ResponseHandler_Combined,Crawl4AI_Combined,StoryboardGen_Combined util;
class LLM_CLEAN,LLM_PROCESS,LLM_PRE_PROCESS,LLM_GEN_CLEAN_PROMPT,LLM_MAKE_REQUEST,LLM_POST_PROCESS,LLM_CHECK_FORMAT,LLM_REFORMAT,LLM_EXTRACT_COT llm;
class PROMPTS_CLEAN,PROMPTS_SYS,PROMPTS_USER,PROMPTS_FIX prompt;
class RedisQueue,LocalAudioQueueDir_Combined queue;
class StorageMgr_Combined,ScrapedData_Combined,Screenshots_Combined,StoryScript_Combined,AudioFile_Combined,StoryboardFile_Combined,JobResult_Combined storage;
class Internet_Combined,ElevenLabsAPI_Combined,LocalLLM_Combined,ExternalLLMService external;
class Prometheus_Combined,Grafana_Combined monitoring;
class User fill:#D6EAF8,stroke:#333,stroke-width:2px;
The generation of a viral story follows a well-defined sequence of steps, orchestrated by the API and background workers.
- Initiation: A user (or an external system) sends a POST request to an API endpoint (e.g.,
/api/v1/stories/generate). The request payload typically includes a topic, source URLs, or direct text content. - Validation & Queuing: The FastAPI application validates the incoming request against Pydantic models. If valid, a unique job ID is generated, and a task is created and enqueued into a specific Redis queue (e.g.,
scrape_tasksorgeneration_tasks). The API immediately returns the job ID to the user for status tracking. - Scraping (If Applicable):
- If source URLs are provided, a
scrape_workerpicks up the scraping task. - It uses Crawl4AI to fetch content from the specified URLs.
- The extracted text content is cleaned, potentially summarized, and stored in the
storage/sources/directory, linked to the job ID.
- If source URLs are provided, a
- Content Processing & Story Generation:
- An
api_worker(orqueue_worker) picks up the main generation task. - It retrieves the scraped content (if any) or uses directly provided text.
- Source Cleansing: If multiple sources, they are merged and summarized.
- LLM Interaction: The worker sends the processed content and a relevant prompt (from
prompts/prompts.py) to the local LLM viallm.pyto generate the story script and video scene descriptions. - The generated script is saved to
storage/stories/.
- An
- Audio Generation (TTS):
- The narrative part of the script is sent to the ElevenLabs API via
elevenlabs_tts.py. - The resulting MP3 audio file is saved to
storage/audio/.
- The narrative part of the script is sent to the ElevenLabs API via
- Storyboard Creation:
- The script (with scene descriptions) is processed by
storyboard.pyto create a JSON-formatted storyboard. - The storyboard is saved to
storage/storyboards/.
- The script (with scene descriptions) is processed by
- Metadata & Status Update:
- All generated artifact paths, job status (e.g., "completed"), and other metadata are saved in
storage/metadata/as a JSON file associated with the job ID. The status in Redis might also be updated.
- All generated artifact paths, job status (e.g., "completed"), and other metadata are saved in
- Result Retrieval: The user can poll a status endpoint (e.g.,
/api/v1/stories/{job_id}/status) using the job ID. Once the status is "completed", they can retrieve the final results (script, audio URL/file, storyboard JSON) from another endpoint (e.g.,/api/v1/stories/{job_id}/results).
sequenceDiagram
participant User
participant API
participant RedisQueue as Redis Queue
participant ScrapeWorker as Scraper
participant MainWorker as Content Gen. Worker
participant LLMService as LLM Service
participant ElevenLabsService as ElevenLabs
participant StoryboardService as Storyboard Gen.
participant Storage
User->>+API: POST /generate or /stories (URLs, Config, Topic)
API->>API: Validate Request, Create Task ID
API->>+RedisQueue: Enqueue 'generate_story' job (Task ID, URLs, Config, Topic)
API-->>-User: HTTP Response { task_id: "XYZ" }
opt Scraping (if URLs provided in job)
RedisQueue-->>+ScrapeWorker: Dequeues 'generate_story' job
Note over ScrapeWorker: Uses Crawl4AI, Fetches from Internet
ScrapeWorker->>Storage: Store Scraped Content (text)
ScrapeWorker->>Storage: Store Screenshots
ScrapeWorker->>Storage: Update Job Metadata in Redis/Storage (status: scraping_complete, paths to content/screenshots)
ScrapeWorker->>-RedisQueue: Publishes 'generate_story' job (now referencing scraped data)
%% Alternatively, ScrapeWorker updates status and MainWorker picks up the same job ID later
end
RedisQueue-->>+MainWorker: Dequeues 'generate_story' job
Note over MainWorker: This worker encapsulates queue_worker.py, api_worker.py, and utils.api_job_processor.py logic
MainWorker->>Storage: Retrieve Scraped Content & Screenshots (if available for this Task ID)
MainWorker->>Storage: Update Job Metadata (status: processing_script)
opt Markdown Cleaning (if applicable)
MainWorker->>+LLMService: clean_markdown_with_llm(scraped_text)
LLMService-->>-MainWorker: Cleaned Markdown
end
MainWorker->>+LLMService: process_with_llm(cleaned_text/topic, prompt)
LLMService-->>-MainWorker: Generated Story Script
MainWorker->>Storage: Save Generated Story Script
MainWorker->>Storage: Update Job Metadata (status: script_generated, script_path)
MainWorker->>+ElevenLabsService: Generate Audio (story_script_text)
Note over MainWorker, ElevenLabsService: Handles retries for TTS failures (via LocalAudioQueueDir)
ElevenLabsService-->>-MainWorker: Audio Data (MP3)
MainWorker->>Storage: Save Audio File
MainWorker->>Storage: Update Job Metadata (status: audio_generated, audio_path)
MainWorker->>+StoryboardService: Generate Storyboard (script, audio_file, screenshots)
StoryboardService-->>-MainWorker: Storyboard File/Data
MainWorker->>Storage: Save Storyboard File
MainWorker->>Storage: Update Job Metadata (status: completed, storyboard_path, other asset paths)
%% MainWorker implicitly acks message from RedisQueue upon successful processing
MainWorker->>-RedisQueue: (Implicit Ack of Job)
User->>+API: GET /api/stories/{task_id}
API->>API: api_handlers.get_task_status()
API->>Storage: Read Job Result/Metadata (from Redis/Storage)
%% API might also check RedisQueue for very early states, as per Mermaid
API-->>-User: HTTP Response { status: "completed", asset_urls: [...] }
User->>+API: GET /api/stories/{task_id}/download/{asset_filename}
API->>Storage: Retrieve Asset File (audio, storyboard, script) via Storage Manager
API-->>-User: Serves File Data
This project leverages a modern stack of technologies to deliver its functionalities:
- Primary Language: Python (3.10+)
- Core Frameworks & Libraries:
- FastAPI: For building high-performance RESTful APIs.
- Pydantic: For data validation and settings management.
- Requests: For making HTTP requests to external services (like ElevenLabs).
- python-dotenv: For managing environment variables.
- Crawl4AI: For LLM-friendly web scraping and content extraction.
- ElevenLabs Python SDK: For interacting with the ElevenLabs Text-to-Speech API.
- Redis-py: Python client for Redis, used for task queuing.
- Artificial Intelligence:
- Local LLM: (User-configurable) For natural language processing and content generation.
- Prompt Engineering: Custom prompts located in
viralStoryGenerator/prompts/.
- Infrastructure & Orchestration:
- Docker & Docker Compose: For containerization, service management, and reproducible environments.
- Redis: As an in-memory data structure store, used as a message broker and for caching.
- Development & Testing:
- Git & GitHub: For version control and collaboration.
- Pytest: For writing and running automated tests.
- Setuptools: For packaging and distribution.
- Monitoring (Production):
- Prometheus: For metrics collection and alerting.
- Grafana: For visualizing metrics and creating dashboards.
The project is organized as follows:
viralStoryGenerator/– Main package directorysrc/– Core source codeapi.py– FastAPI application and endpointsworker_runner.py– Unified entry point for running API and worker processesapi_worker.py,queue_worker.py,scrape_worker.py– Worker process scriptslogger.py– Logging configurationllm.py,elevenlabs_tts.py,storyboard.py,source_cleanser.py(if applicable) – Main features and utilities
utils/– Utility modules (config, Redis, storage, etc.)models/– Data modelsprompts/– Prompt templates for LLM
tests/– Test suitedocker-compose.yml,Dockerfile*– Containerization and orchestrationREADME.md,requirements.txt,setup.py– Documentation and dependencies
Install the package using Python's setuptools:
python setup.py installYou can install these via pip if needed:
pip install .Copy the sample environment file to a new file named .env and update the values as needed:
LOG_LEVEL(e.g., DEBUG, INFO, etc.)LLM_ENDPOINT– Local LLM API endpoint.LLM_MODEL– Model name for story generation.ELEVENLABS_API_KEY– Your ElevenLabs API key.ELEVENLABS_VOICE_ID– ElevenLabs voice ID.- And more options in the provided .env.sample. 🔧
- Create a Virtual Environment:
Open your terminal and run:
python -m venv venv
- Activate the Virtual Environment:
- On Windows:
venv\Scripts\activate
- On macOS/Linux:
source venv/bin/activate
- On Windows:
- Copy the .env Example:
Copy the sample file to create your environment configuration:
cp .env.sample .env
- Edit the .env File:
Open
.envin your favorite text editor and adjust the configuration values to match your setup.
For local development and testing, follow these steps:
-
Clone the repository:
git clone https://github.com/yourusername/ViralStoryGenerator.git cd ViralStoryGenerator -
Install in development mode:
pip install -e .This installs the package in "editable" mode, allowing you to modify the code and see changes immediately without reinstalling.
-
Set up environment variables:
cp .env.sample .env
Edit the
.envfile with your local configuration.
-
Execute the test suite:
python -m pytest tests/
-
Run specific test files:
python -m pytest tests/test_main.py
-
Run with verbose output:
python -m pytest -v tests/
-
Start the API server locally:
python -m viralStoryGenerator.src.worker_runner api --port 8000 --reload
The
--reloadflag enables auto-reloading when code changes are detected. -
Access the API documentation: Open your browser and navigate to:
http://localhost:8000/docsThis provides an interactive Swagger UI for testing endpoints.
-
Test individual components:
# Test LLM processing python -c "from viralStoryGenerator.src.llm import process_with_llm; print(process_with_llm('Sample topic', 'Sample content', 0.7))" # Test audio generation python -c "from viralStoryGenerator.src.elevenlabs_tts import generate_audio; print(generate_audio('This is a test audio generation'))"
- Set
LOG_LEVEL=DEBUGin your.envfile for detailed logging - Use Python's debugger:
python -m pdb -c continue -m viralStoryGenerator api
The Viral Story Generator is now available as an HTTP service. You can interact with it using the REST API endpoints.
Access the service through the following endpoints:
- Generate a story: Send a POST request to the story generation endpoint with your topic
- Check status: Monitor the progress of your story generation task
- Retrieve results: Get your completed story, audio, and storyboard
For detailed API documentation, refer to the API documentation when the server is running.
To run the application in a development environment using Docker:
-
Build and start the containers:
docker-compose up -d
-
Check the status of the containers:
docker-compose ps
-
View logs:
docker-compose logs -f
-
Stop the containers:
docker-compose down
- Scraper Worker:
python3 -m viralStoryGenerator.src.worker_runner worker --worker-type scrape
- Queue Worker:
python3 -m viralStoryGenerator.src.worker_runner worker --worker-type queue
For production deployment with scaling and monitoring:
-
Copy and customize environment variables:
cp .env.sample .env
-
Deploy with production configuration:
docker-compose -f docker-compose.prod.yml up -d
-
Scale services as needed:
docker-compose -f docker-compose.prod.yml up -d --scale scraper=5 --scale backend=3
-
Access monitoring dashboards:
- Grafana: http://localhost:3000 (default credentials: admin/admin)
- Prometheus: http://localhost:9090
This project uses a containerized architecture with separate services:
- Redis: Queue management and shared state
- Backend: Main application for story generation
- Scraper: Worker processes for crawl4ai web scraping
- Monitoring: Prometheus and Grafana for observability (production only)
Each service is independently scalable to handle increased load.
viralStoryGenerator/src/api.py: Defines all FastAPI endpoints, handles request validation using Pydantic models, and enqueues tasks to Redis.viralStoryGenerator/src/worker_runner.py: A CLI entry point (likely using Typer or Click) to start different types of workers (API server, scrape worker, queue worker).viralStoryGenerator/src/api_worker.py: The main worker responsible for orchestrating the story generation pipeline: fetching data, calling LLM, TTS, and storyboard services.viralStoryGenerator/src/scrape_worker.py: A specialized worker that handles web scraping tasks using Crawl4AI, processing URLs from a queue.viralStoryGenerator/src/queue_worker.py: Potentially a more generic worker for other background tasks, or could be merged withapi_worker.py.viralStoryGenerator/src/llm.py: Contains the logic for interacting with the local Large Language Model, including loading prompts and processing responses.viralStoryGenerator/src/elevenlabs_tts.py: Manages communication with the ElevenLabs API for generating speech from text.viralStoryGenerator/src/storyboard.py: Responsible for creating structured JSON storyboards from the generated script and scene descriptions.viralStoryGenerator/src/source_cleanser.py(or similar logic within workers): Handles the merging, cleaning, and summarization of input content before LLM processing.viralStoryGenerator/utils/config.py: Loads and provides access to application settings and environment variables (e.g., API keys, LLM endpoints).viralStoryGenerator/utils/redis_utils.py(or similar): Provides utility functions for connecting to and interacting with Redis.viralStoryGenerator/utils/storage_utils.py(or similar): Manages file system operations for saving and retrieving generated artifacts.viralStoryGenerator/models/: Contains Pydantic models defining the structure of API requests, responses, and internal data objects.viralStoryGenerator/prompts/prompts.py: Stores and manages the various prompt templates used to guide the LLM's content generation.docker-compose.yml&Dockerfile*: Define the services, networks, and build instructions for containerizing the application and its dependencies.
This project uses Crawl4AI for web scraping:
@software{crawl4ai2024,
author = {UncleCode},
title = {Crawl4AI: Open-source LLM Friendly Web Crawler & Scraper},
year = {2024},
publisher = {GitHub},
journal = {GitHub Repository},
howpublished = {\url{https://github.com/unclecode/crawl4ai}}
}Contributions and feedback are welcome! Feel free to open issues or submit pull requests to help improve the project. 🤝
For inquiries or feedback, please reach out at princeboachie@gmail.com.
This project is licensed as specified in the LICENSE file.
Enjoy creating viral stories and engaging content! 💥🔥
Updates:
-
Environment & Configuration:
- Added a new configuration class in
utils/config.pyto load environment variables from.env. - Updated
.env.samplewith parameters such asHTTP_TIMEOUTandLLM_MAX_TOKENS.
- Added a new configuration class in
-
API & HTTP Service:
- Migrated from CLI-based to HTTP service architecture.
- Implemented REST API endpoints in
src/api.pyfor story generation and retrieval. - Added worker processes with Redis queue support in
src/api_worker.py.
-
Dependency Management:
- Pinned dependency versions in
setup.py(e.g.,requests==2.32.3andpython-dotenv==1.1.0).
- Pinned dependency versions in
-
Prompts & Story Generation:
- Enhanced prompt instructions in
prompts/prompts.pyto enforce proper formatting of story scripts and video descriptions.
- Enhanced prompt instructions in
-
Logging:
- Updated the logging configuration in
src/logger.pyto prevent duplicate logs and include file logging in production.
- Updated the logging configuration in
-
Docker & Containerization:
- Added Docker configuration for development and production environments.
- Included scalable services for backend, scraper, and Redis.
- Implemented monitoring with Prometheus and Grafana.
-
Documentation:
- Significantly enhanced README with detailed Architecture, Program Flow, Core Technologies, and Key Modules sections.
- Added Mermaid diagrams for System Architecture and Program Flow.
- Included a Table of Contents for easier navigation.