--- description: This rule provides comprehensive best practices for developing Flask applications, covering code structure, security, performance, and testing. globs: *.py --- - ## Code Organization and Structure: - **Directory Structure Best Practices:** - Follow a modular and organized project structure. A common structure is: project_root/ ├── app/ │ ├── __init__.py │ ├── models.py │ ├── views.py # Or controllers.py │ ├── forms.py │ ├── utils.py # Helper functions │ ├── api/ │ │ ├── __init__.py │ │ ├── routes.py │ ├── templates/ │ │ └── ... │ ├── static/ │ │ └── ... ├── tests/ │ ├── __init__.py │ ├── conftest.py # Fixtures for tests │ ├── test_models.py │ ├── test_views.py ├── migrations/ │ └── ... # Alembic migrations ├── venv/ # Virtual environment ├── .env # Environment variables (use with caution, not for sensitive data in production) ├── config.py # Application configuration ├── requirements.txt or pyproject.toml # Dependencies ├── run.py # Application entry point - Use Blueprints to organize routes and views into logical modules. Blueprints promote reusability and maintainability. - **File Naming Conventions:** - Use descriptive and consistent file names. - Examples: `models.py`, `views.py`, `forms.py`, `utils.py`, `routes.py`, `test_*.py`. - Maintain consistency throughout the project. - **Module Organization:** - Group related functionality into modules. For instance, database models in `models.py`, user authentication logic in `auth.py`, and utility functions in `utils.py`. - Use `__init__.py` files to make directories packages, allowing you to import modules within the directory using relative paths. - **Component Architecture:** - Design components with clear responsibilities and interfaces. - Consider using a layered architecture (e.g., presentation, business logic, data access) to separate concerns. - Use dependency injection to decouple components. - **Code Splitting Strategies:** - Decompose large modules into smaller, more manageable files. - Extract reusable code into separate modules or packages. - Employ lazy loading for modules that are not immediately needed. - ## Common Patterns and Anti-patterns: - **Design Patterns Specific to Flask:** - **Application Factory:** Use the application factory pattern to create Flask application instances. This allows for different configurations for different environments (development, testing, production). python def create_app(config_name): app = Flask(__name__) app.config.from_object(config[config_name]) config[config_name].init_app(app) # Initialize extensions (e.g., db, mail) here db.init_app(app) mail.init_app(app) # Register blueprints from .main import main as main_blueprint app.register_blueprint(main_blueprint) return app - **Blueprints:** Organize application functionality into reusable blueprints. python from flask import Blueprint bp = Blueprint('my_blueprint', __name__, url_prefix='/my_blueprint') @bp.route('/route') def my_route(): return 'Hello from my_blueprint' - **Recommended Approaches for Common Tasks:** - **Database Interactions:** Use Flask-SQLAlchemy or another ORM for database interactions. Define models to represent database tables. - **Form Handling:** Use Flask-WTF for form handling. This provides CSRF protection and simplifies form validation. - **Authentication:** Use Flask-Login for user authentication. It provides utilities for managing user sessions and protecting routes. - **API Development:** Use Flask-RESTful or Flask-API for building RESTful APIs. Consider using Marshmallow for serializing and deserializing data. - **Anti-patterns and Code Smells to Avoid:** - **Global State:** Avoid using global variables to store application state. Use the `g` object or session variables instead. - **Tight Coupling:** Design components with loose coupling to improve maintainability and testability. - **Fat Models/Views:** Keep models and views focused on their primary responsibilities. Move complex business logic to separate modules. - **Hardcoding Configuration:** Avoid hardcoding configuration values. Use environment variables or a configuration file. - **State Management Best Practices:** - Use the Flask `session` object to store user-specific data across requests. - For application-wide state, consider using a database or a caching mechanism. - Avoid storing sensitive data in the session without proper encryption. - **Error Handling Patterns:** - Use `try...except` blocks to handle exceptions gracefully. - Implement custom error handlers for specific exceptions. Return appropriate HTTP status codes and error messages. - Use logging to record errors and warnings. - Use Flask's `abort()` function to raise HTTP exceptions. - ## Performance Considerations: - **Optimization Techniques:** - **Caching:** Implement caching to reduce database queries and improve response times. Use Flask-Caching or Redis. - **Database Optimization:** Optimize database queries and use indexes to improve performance. - **Profiling:** Use a profiler to identify performance bottlenecks in your code. - **Memory Management:** - Avoid memory leaks by properly closing database connections and releasing resources. - Use generators to process large datasets efficiently. - **Rendering Optimization:** - Minimize the number of database queries in templates. - Use template caching to reduce rendering time. - **Bundle Size Optimization:** - For larger front-end applications, use a bundler like Webpack or Parcel to optimize JavaScript and CSS files. Minify and compress assets. - **Lazy Loading Strategies:** - Implement lazy loading for images and other assets to improve initial page load time. - Use code splitting to load only the necessary JavaScript code for each page. - ## Security Best Practices: - **Common Vulnerabilities and How to Prevent Them:** - **Cross-Site Scripting (XSS):** Prevent XSS by escaping user input in templates. Use Jinja2's autoescaping feature. - **SQL Injection:** Prevent SQL injection by using parameterized queries or an ORM. - **Cross-Site Request Forgery (CSRF):** Protect against CSRF attacks by using Flask-WTF, which provides CSRF protection. - **Authentication and Authorization Issues:** Implement secure authentication and authorization mechanisms. Use strong passwords and protect user credentials. - **Input Validation:** - Validate all user input to prevent malicious data from entering your application. - Use Flask-WTF for form validation. - **Authentication and Authorization Patterns:** - Use Flask-Login for user authentication. - Implement role-based access control (RBAC) to restrict access to certain resources. - Use JWT (JSON Web Tokens) for API authentication. - **Data Protection Strategies:** - Encrypt sensitive data at rest and in transit. - Use HTTPS to secure communication between the client and the server. - Store passwords securely using a strong hashing algorithm (e.g., bcrypt). - **Secure API Communication:** - Use HTTPS for all API communication. - Implement authentication and authorization for API endpoints. - Validate API requests and responses. - Use rate limiting to prevent abuse. - ## Testing Approaches: - **Unit Testing Strategies:** - Write unit tests to verify the functionality of individual components. - Use pytest or unittest for writing and running tests. - Mock external dependencies to isolate components during testing. - **Integration Testing:** - Write integration tests to verify the interaction between different components. - Test the integration between the application and the database. - **End-to-End Testing:** - Write end-to-end tests to simulate user interactions with the application. - Use Selenium or Cypress for end-to-end testing. - **Test Organization:** - Organize tests into separate directories based on functionality. - Use descriptive test names. - Follow the Arrange-Act-Assert pattern in your tests. - **Mocking and Stubbing:** - Use mocking and stubbing to isolate components during testing. - Use the `unittest.mock` module or a third-party mocking library like `mock`. - ## Common Pitfalls and Gotchas: - **Frequent Mistakes Developers Make:** - **Not using a virtual environment:** Always use a virtual environment to isolate project dependencies. - **Not handling exceptions properly:** Handle exceptions gracefully to prevent application crashes. - **Exposing sensitive data:** Avoid exposing sensitive data in logs or error messages. - **Edge Cases to Be Aware Of:** - **Handling Unicode correctly:** Be aware of Unicode encoding issues when working with text data. - **Dealing with time zones:** Use a consistent time zone throughout the application. - **Version-Specific Issues:** - Be aware of compatibility issues when upgrading Flask or its dependencies. - Consult the Flask documentation for version-specific information. - **Compatibility Concerns:** - Ensure that your application is compatible with different browsers and operating systems. - Test your application on different devices. - **Debugging Strategies:** - Use the Flask debugger to identify and fix errors. - Use logging to record errors and warnings. - Use a profiler to identify performance bottlenecks. - ## Tooling and Environment: - **Recommended Development Tools:** - **Virtual Environment Manager:** `virtualenv`, `venv`, or `conda` - **Package Manager:** `pip` or `pipenv` or `poetry` - **IDE/Text Editor:** VS Code, PyCharm, Sublime Text - **Debugger:** `pdb` or `ipdb` - **Profiler:** `cProfile` - **Build Configuration:** - Use a `requirements.txt` or `pyproject.toml` file to specify project dependencies. - Use a build system like `setuptools` or `poetry` to package your application. - **Linting and Formatting:** - Use a linter like `flake8` or `pylint` to enforce code style guidelines. - Use a formatter like `black` or `autopep8` to automatically format your code. - **Deployment Best Practices:** - Use a production-ready WSGI server like Gunicorn or uWSGI. - Use a reverse proxy like Nginx or Apache to serve static files and handle SSL termination. - Deploy your application to a cloud platform like AWS, Google Cloud, or Azure. - **CI/CD Integration:** - Use a CI/CD pipeline to automate testing, building, and deployment. - Use tools like Jenkins, Travis CI, or GitHub Actions.