Code Monkey home page Code Monkey logo

flask-template's Introduction

Flask Starter Template

A simple Flask app starter template. This is my preference to bootstrap my Flask projects and not a must follow structure, feel free to change whatever you dislike to fit what you are comfortable with.

Features

Here is a list of the available features:

  • Scalable Folder Structure: The application employs an isolated app directory structure to ensure code maintainability and readability.

  • API Ready: The template includes a ready-to-use API structure.

  • Web UI: The template includes a basic web user interface.

  • User Authentication: The template integrates Flask-Login for user authentication. It allows users to register, log in, and log out. It provides session management, secure password hashing, and user session tracking.

  • Rate Limiting: To protect your application from abuse, rate limiting is enforced.

  • CORS: Cross-origin resource sharing (CORS) is configured to manage the server's shared resources.

  • CACHING: The template includes caching to optimize performance and reduce server load. Caching stores frequently requested data temporarily, leading to faster API responses. It enhances user experience and helps handle high traffic efficiently.

  • Logging: The application includes logging capabilities to record relevant events, errors, and messages. Logging helps in monitoring and troubleshooting the application during development and production.

  • Tests: Unit tests are included to ensure the application's functionality and robustness.

  • Docker Support: A Dockerfile is included for building a Docker image of your application, facilitating easy deployment and scaling.

Getting Started

Running The Application

1.Clone the repository to your local machine:

git clone https://github.com/riad-azz/flask-template && cd flask-template

2.Install the required dependencies:

pip install -r requirements.txt

3.The application can be run with the following command:

python server.py

4.To enable the Ratelimit and Cache features make sure to copy the .env.example content and create a .env file:

# Flask Variables
SECRET_KEY="YOUR-SECRET-KEY"
# Flask Ratelimit
RATELIMIT_ENABLED="True"
RATELIMIT_STORAGE_URI="memory://" # or redis://localhost:6379/0
# Flask Cache
CACHE_ENABLED="True"
CACHE_TYPE="SimpleCache" # or RedisCache
CACHE_STORAGE_URL="YOUR-REDIS-URL" # Required only for CACHE_TYPE RedisCache

Note: for development you need to create a .env.dev file.

Running Tests

You can write tests in flask-template/tests, where you will also find some examples.

To run the tests simply use the command:

python -m pytest

You can switch between running the tests from .env.dev (development environment) or .env (production environment) by going to flask-template/tests/__init__.py and changing the value of FLASK_DEBUG:

import os

# Set 'False' to test with .env
# Set 'True' to test with .env.dev
os.environ["FLASK_DEBUG"] = "True"

Dockerize The Application

To run the application in Docker follow these steps:

1.Install Docker on your machine.

2.Build the Docker image for the application:

docker build -t my-flask-image .

3.Run the Docker image:

docker run -p 5000:5000 --name my-flask-container my-flask-image

Open your browser and visit http://localhost:5000 to see the website.

Flask API

This is how I like to set up my API in Flask. You might want to change this with flask-restful or whatever library that suits you.

You can check app/routes/api/tests.py to get an idea of how the API should work.

API Schemas

All the schemas served with the API that are passed to the success_response must be json serializable. In this example we use BaseModel from pydantic which allows us to turn the model into a dict using the model_dump function:

from pydantic import BaseModel


class TestModel(BaseModel):
    title: str
    content: str
# Flask modules
from flask import Blueprint

# Local modules
from app.schemas.test import TestModel
from app.utils.api import success_response

tests_bp = Blueprint("tests", __name__, url_prefix="/tests")


@tests_bp.route("/success", methods=['GET'])
def test_api_success():
    data = TestModel(title="riad-azz", content="Successful API response")
    data_dict = data.model_dump()
    return success_response(data_dict, 200)

Error handling

For API error handling use werkzeug.exceptions exception classes, and if you would like to create custom exceptions make sure that your exceptions inherit from HTTPException.

The API error handler can be found in app/routes/api/__init__.py:

# Flask modules
from flask import Blueprint
from werkzeug.exceptions import HTTPException
from flask_limiter.errors import RateLimitExceeded

# Other modules
import logging

# Local modules
from app.utils.api import error_response

api_bp = Blueprint("api", __name__, url_prefix="/api")


@api_bp.errorhandler(Exception)
def handle_error(error):
    if isinstance(error, RateLimitExceeded):
        current_limit = error.limit.limit
        return error_response(f"Too many requests: {current_limit}", 429)
    elif isinstance(error, HTTPException):
        return error_response(error.description, error.code)
    else:
        logging.error(error)
        return error_response()

If the exception is unknown the API will return a Internal Server Error by default from the error_response function.

API Response Examples

Run the server and visit the following paths to check the API responses:

Contributing

Contributions to improve this Flask app template are welcome. Please feel free to fork the repository, make changes, and submit a pull request.

License

This project is licensed under the terms of the MIT license. For more details, see the LICENSE file in the repository.

flask-template's People

Contributors

riad-azz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

flask-template's Issues

Error after running test

(venvT) karim@Karims-MacBook-Pro flask-template % python3 -m pytest
========================================================= test session starts =========================================================
platform darwin -- Python 3.10.8, pytest-7.4.3, pluggy-1.3.0
rootdir: /Users/karim/Documents/MASTER M2/ML/flask-template
collected 10 items

tests/flask/test_api.py ..F.... [ 70%]
tests/flask/test_cache.py F [ 80%]
tests/flask/test_cors.py . [ 90%]
tests/flask/test_ratelimiter.py E [100%]

=============================================================== ERRORS ================================================================
_________________________________________________ ERROR at setup of test_rate_limiter _________________________________________________

@pytest.fixture
def app():
    app = create_app()

    limiter.enabled = True
  limiter.reset()

tests/flask/test_ratelimiter.py:15:


venvT/lib/python3.10/site-packages/flask_limiter/extension.py:805: in reset
self.storage.reset()


self = <flask_limiter.extension.Limiter object at 0x105b99ff0>

@property
def storage(self) -> Storage:
    """
    The backend storage configured for the rate limiter
    """
  assert self._storage

E AssertionError

venvT/lib/python3.10/site-packages/flask_limiter/extension.py:815: AssertionError
============================================================== FAILURES ===============================================================
_________________________________________________________ test_api_ratelimit __________________________________________________________

app = <Flask 'app'>

def test_api_ratelimit(app):
    with app.test_client() as client:
        success_response = client.get("/api/tests/ratelimit")
        limited_response = client.get("/api/tests/ratelimit")

    assert success_response.status_code == 200
    assert success_response.json["status"] == "success"
    assert success_response.json["data"]["title"] == "riad-azz"
    assert success_response.json["data"]["content"] == "Rate limit API response"
  assert limited_response.status_code == 429

E assert 200 == 429
E + where 200 = <WrapperTestResponse streamed [200 OK]>.status_code

tests/flask/test_api.py:41: AssertionError
___________________________________________________________ test_api_cache ____________________________________________________________

app = <Flask 'app'>

def test_api_cache(app):
    request_url = "/api/tests/cached"
    with app.test_client() as client:
        response = client.get(request_url)
        assert response.status_code == 200
        assert response.headers.get("Is-Cached-Response") is None
        assert response.json["status"] == "success"
        assert response.json["data"]["title"] == "riad-azz"
        assert response.json["data"]["content"] == "Cached API response"

    request = response.request
    is_cached = get_cached_response(request)
  assert bool(is_cached) is True

E assert False is True
E + where False = bool(None)

tests/flask/test_cache.py:29: AssertionError
======================================================= short test summary info =======================================================
FAILED tests/flask/test_api.py::test_api_ratelimit - assert 200 == 429
FAILED tests/flask/test_cache.py::test_api_cache - assert False is True
ERROR tests/flask/test_ratelimiter.py::test_rate_limiter - AssertionError
================================================ 2 failed, 7 passed, 1 error in 1.46s =================================================
(venvT) karim@Karims-MacBook-Pro flask-template %

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.