199 lines
11 KiB
Plaintext
199 lines
11 KiB
Plaintext
---
|
|
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. |