A sophisticated web application for automatically detecting and annotating form fields and hyperlinks in HTML email templates, with an interactive editor and PDF export functionality.
- Production: html-annotator-production.up.railway.app
- Multi-file Upload: Process multiple HTML email templates simultaneously
- Automatic Detection:
- Form fields (input, textarea, select, button elements)
- Hyperlinks (a tags with href attributes)
- Email links (mailto: links)
- Interactive Editor:
- Real-time HTML preview with highlighted annotations
- Drag-and-drop annotation reordering
- Click-to-add new annotations
- Edit existing annotations
- Delete unwanted annotations
- PDF Export: Generate annotated PDFs with margin notes (similar to your original PDF annotator style)
- Selective Download: Choose which files to include in the final ZIP archive
- Visual annotation overlays in preview
- Color-coded annotations (blue for form fields, red for hyperlinks)
- Zoom controls for HTML preview
- Redis-based session management for reliable multi-instance deployment
- Professional UI with drag-and-drop support
-
Clone the repository:
git clone https://github.com/NinoMandelaB/html-annotator.git cd html-annotator -
Install Redis (for session storage):
macOS:
brew install redis brew services start redis
Ubuntu/Debian:
sudo apt-get install redis-server sudo systemctl start redis
Windows:
- Download from Redis Windows
- Or use WSL2 with Ubuntu installation
-
Install Python dependencies:
pip install -r requirements.txt
-
Run the application:
python app.py
-
Open your browser:
http://localhost:5000
-
Add Redis to your Railway project:
- Go to your Railway dashboard
- Click "+ New" β "Database" β "Add Redis"
- Railway automatically creates the
REDIS_URLenvironment variable
-
Push to GitHub:
git add . git commit -m "Deploy with Redis session support" git push origin main
-
Railway Configuration:
- Railway automatically detects your Flask app
- Redis connection is established via
REDIS_URLenvironment variable - The app uses the
PORTenvironment variable for web binding - Sessions persist across container restarts using Redis
-
Deploy:
- Railway deploys automatically on push
- Your app will be available at:
https://your-app.up.railway.app
The application uses Redis for distributed session storage, which provides:
- β Persistent sessions across container restarts
- β Horizontal scalability with multiple app instances
- β Fast in-memory access for session data
- β Automatic expiration (2-hour session lifetime)
- β Production-ready for cloud deployments
Session data (uploaded files, annotations) is stored in Redis instead of filesystem, making the app compatible with ephemeral container environments like Railway.
html-annotator/
βββ app.py # Main Flask application with Redis session config
βββ html_parser.py # HTML parsing and annotation detection
βββ pdf_generator.py # HTML to PDF conversion
βββ requirements.txt # Python dependencies (includes Redis)
βββ templates/
β βββ index.html # Upload page
β βββ editor.html # Annotation editor
βββ static/
β βββ css/
β β βββ editor.css # Editor styling
β βββ js/
β βββ editor.js # Editor JavaScript logic
βββ README.md # This file
- Flask 2.3.2: Web framework
- Flask-Session 0.6.0: Server-side session management
- Redis 5.0.1: In-memory data store for sessions
- BeautifulSoup4 4.12.2: HTML parsing
- lxml 5.3.0: XML/HTML parser backend
- pdfkit 1.0.0: HTML to PDF conversion
- Werkzeug 2.3.6: WSGI utilities
SECRET_KEY=your_secret_key_here # Flask secret key for sessions
PORT=5000 # Port to run the application
REDIS_URL=redis://localhost:6379 # Redis connection URL (auto-set on Railway)The app is configured with secure session settings:
- Session Type: Redis-backed
- Session Lifetime: 2 hours
- Cookie Security: HTTPS-only (in production)
- Cookie HttpOnly: Yes
- Cookie SameSite: Lax
Local Development:
# Check if Redis is running
redis-cli ping
# Should return: PONG
# Start Redis if not running
# macOS: brew services start redis
# Linux: sudo systemctl start redisRailway Deployment:
- Ensure Redis service is added to your Railway project
- Check that
REDIS_URLenvironment variable is set - View Railway logs for connection errors
If sessions are lost between requests:
- Verify Redis is running and accessible
- Check
REDIS_URLenvironment variable is correct - Ensure Flask-Session is properly initialized
- Check Railway logs for Redis connection errors
- β¨ Switched to Redis-based session storage for production reliability
- β¨ Added support for horizontal scaling with multiple app instances
- β¨ Implemented automatic session expiration (2-hour TTL)
- π Fixed session persistence issues on Railway deployment
- π Updated documentation with Redis setup instructions
- Complete rewrite from PDF to HTML processing
- Added interactive annotation editor
- Implemented drag-and-drop annotation management
- Added click-to-add annotation feature
- Improved UI with three-panel layout
- Added zoom controls for preview
- Enhanced annotation detection algorithm
- PDF export with margin notes (original style preserved)
- PDF link annotator with automatic URL detection
- Red box annotations with margin text
Traditional filesystem-based sessions don't work on cloud platforms with ephemeral storage (like Railway). Redis solves this by:
- Persistence: Data survives container restarts
- Speed: In-memory storage provides microsecond latency
- Scalability: Multiple app instances can share session data
- TTL Support: Automatic cleanup of expired sessions
- Production-Ready: Used by major companies for session management
User uploads files β Flask processes β Stores in Redis
β
Session ID in cookie
β
User navigates to editor β Flask reads session ID β Retrieves data from Redis
All session management is transparent to the application code - Flask-Session handles the Redis interaction automatically.
This project is open source and available under the MIT License.
Developed by NinoMandelaB