The application has been refactored into a modular, scalable architecture following Flask best practices:
sentiment-analysis/
├── app/ # Main application package
│ ├── __init__.py # Package initialization
│ ├── factory.py # Application factory
│ ├── config.py # Configuration management
│ ├── api/ # API layer
│ │ ├── __init__.py
│ │ └── routes.py # API endpoints
│ ├── services/ # Business logic layer
│ │ ├── __init__.py
│ │ ├── sentiment_analyzer.py # Core sentiment analysis
│ │ └── visualization.py # Data visualization
│ ├── middleware/ # Middleware components
│ │ ├── __init__.py
│ │ └── error_handler.py # Centralized error handling
│ └── utils/ # Utility functions
│ ├── __init__.py
│ └── logger.py # Logging configuration
├── templates/ # HTML templates
│ └── index.html
├── app.py # Application entry point
├── requirements.txt # Dependencies
├── test_api.py # API tests
└── README.md # Main documentation
- API Layer (
app/api/): Handles HTTP requests/responses - Service Layer (
app/services/): Contains business logic - Middleware (
app/middleware/): Cross-cutting concerns - Utils (
app/utils/): Shared utilities
- Configuration is injected into services
- Services are initialized with their dependencies
- Loose coupling between components
- Each class has one clear responsibility
TextPreprocessor: Text cleaningTextBlobAnalyzer: TextBlob-specific analysisVaderAnalyzer: VADER-specific analysisTransformerAnalyzer: Transformer-specific analysisEnsembleAnalyzer: Combines multiple analyzers
- Environment-based configuration
- Centralized settings in
config.py - Support for development, production, and testing environments
- Centralized error handling middleware
- Consistent error response format
- Proper logging of errors
- Structured logging throughout the application
- Configurable log levels
- Consistent log formatting
# Environment-based configuration
config = get_config('production') # or 'development', 'testing'
# Access configuration
max_length = config.MAX_TEXT_LENGTH
model_config = config.get_model_config()# Create application with specific configuration
app = create_app('production')- Modular analyzers: Each model has its own analyzer class
- Ensemble approach: Combines multiple models intelligently
- Error resilience: Graceful fallbacks when models fail
- Blueprint-based routing: Organized API endpoints
- Input validation: Proper request validation
- Error responses: Consistent error handling
from app.factory import create_app
# Development
app = create_app('development')
app.run(debug=True)
# Production
app = create_app('production')
# Use with gunicorn: gunicorn -w 4 app:appfrom app.services.sentiment_analyzer import EnsembleAnalyzer
from app.config import get_config
config = get_config()
analyzer = EnsembleAnalyzer(config)
# Single analysis
result = analyzer.analyze_single("I love this product!")
# Batch analysis
results = analyzer.analyze_batch(["Great!", "Terrible!", "Okay"])import os
os.environ['FLASK_ENV'] = 'production'
os.environ['SECRET_KEY'] = 'your-secret-key'
os.environ['LOG_LEVEL'] = 'WARNING'
app = create_app() # Will use production config- Clear separation of concerns
- Easy to locate and modify specific functionality
- Consistent code organization
- Services can be tested independently
- Mock dependencies easily
- Clear interfaces between components
- Easy to add new sentiment analysis models
- Modular components can be scaled independently
- Configuration-driven behavior
- Environment-specific configurations
- Easy to swap implementations
- Plugin-like architecture for analyzers
- Proper error handling and logging
- Security considerations
- Performance optimizations
- Create analyzer class in
app/services/sentiment_analyzer.py - Implement the required interface
- Add to
EnsembleAnalyzer - Update configuration if needed
- Add tests
- Add route to
app/api/routes.py - Implement business logic in services
- Add error handling
- Update tests
- Update
app/config.pywith new settings - Set environment variables as needed
- Update documentation
The modular architecture makes testing straightforward:
# Test individual components
def test_textblob_analyzer():
config = get_config('testing')
analyzer = TextBlobAnalyzer(config)
result = analyzer.analyze("Great product!")
assert result['sentiment'] == 'positive'
# Test services
def test_ensemble_analyzer():
config = get_config('testing')
analyzer = EnsembleAnalyzer(config)
result = analyzer.analyze_single("I love this!")
assert 'final_sentiment' in resultpython app.pyexport FLASK_ENV=production
export SECRET_KEY=your-production-secret
gunicorn -w 4 -b 0.0.0.0:5000 app:appThis architecture provides a solid foundation for a production-ready sentiment analysis application that's maintainable, testable, and scalable.