Skip to main content

Flask framework with out of the box Logging, MongoDB, JWT, CORs, Sentry and Docker support

Project description

Flongo Framework

A framework for rapid application development on Flask. Includes:

  • Built-in easy HTTP request/response management and error handling
  • Built-in query string and response body parsing / normalization
  • Built-in request and response payload validation using JSONSchema
  • Built-in CORS handling and request origin configuration
  • Built-in endpoint permissions handling with cookie-based JWT
  • Built-in bindings for MongoDB including fixtures and index management
  • Built-in automatic CRUD handling for endpoints given a MongoDB collection name
  • Built-in detailed logging and fine-tuneable configurations
  • Built-in Sentry integration with detailed spans for request tracing
  • Built-in Gmail utility
  • Dockerfile/Docker Compose to easily build and run the application

Sample App

# app
from flongo_framework.application import Application

# routing
from flongo_framework.api.routing import App_Routes, Route, Route_Schema, \
    Route_Handler, Default_Route_Handler, Route_Permissions

# utils
from flongo_framework.api.routing.utils import Authentication_Util

# responses
from flongo_framework.api.responses import API_JSON_Response, API_Message_Response
from flongo_framework.api.responses.errors import API_Error_Message, API_Error_Response

# database
from flongo_framework.database.mongodb.index import MongoDB_Indices, MongoDB_Index
from flongo_framework.database.mongodb.fixture import MongoDB_Fixtures, MongoDB_Fixture

# settings
from flongo_framework.config.settings import App_Settings, Flask_Settings, MongoDB_Settings

# enums
from flongo_framework.config.enums.logs.log_levels import LOG_LEVELS

# typing
from typing import Any
from bson import ObjectId
from datetime import datetime


# Method that throws a sample error
def throw(exception_type:type, msg:Any): 
    raise exception_type(msg)

# Simple sample application
routes = App_Routes(
    Route(
        # Route that demonstrates built-in basic request handling
        url='/request',
        handler=Route_Handler(
            GET=lambda request: API_Message_Response("Sample GET request"),
            POST=lambda request: API_JSON_Response({'sample_record': f'{request.payload["_id"]}', 'created': True}, 201),
            PUT=lambda request: API_JSON_Response({'payload': request.payload}),
            DELETE=lambda request: API_JSON_Response({'date': datetime.now(), 'deleted': True}),
        ),
        # Demonstrates HTTP method based schema validation
        request_schema=Route_Schema(
            POST={
                'type': 'object',
                'additionalProperties': False,
                'properties': {
                    '_id': {'type': 'integer'}
                },
                'required': ['_id']
            }
        ),
        response_schema=Route_Schema(
            PUT={
                'type': 'object',
                'additionalProperties': False,
                'properties': {
                    'payload': {'type': 'object'}
                },
                'required': ['payload']
            }
        ),
        log_level=LOG_LEVELS.DEBUG
    ),
    Route(
        # Route that demonstrates built-in basic error handling
        url='/error',
        handler=Route_Handler(
            GET=lambda request: throw(ValueError, "Oh no! A value error!"),
            POST=lambda request: throw(API_Error_Message, "Oh no! An API error!"),
            PUT=lambda request:  throw(API_Error_Response, {'data': request.payload, 'error': 'Oh no!'}),
        ),
        log_level=LOG_LEVELS.DEBUG
    ),
    Route(
        # Route that demonstrates built-in database handling
        url='/database',
        handler=Route_Handler(
            # Custom handlers allow a POST request or a GET request to create different errors
            POST=lambda request: API_Message_Response(request.collection.insert_one(request.payload) if request.collection != None else 'No collection!'),
            GET=lambda request: API_Message_Response(request.collection.find_one(request.payload) if request.collection != None else 'No collection!')
        ),
        log_level=LOG_LEVELS.DEBUG,
        collection_name='sample'
    ),
    Route(
        # Route that demonstrates built-in default CRUD handling
        url='/default',
        handler=Default_Route_Handler(),
        log_level=LOG_LEVELS.DEBUG,
        collection_name='default'
    ),
    Route(
        # Route that demonstrates built-in permissions handling
        url='/permissions',
        handler=Default_Route_Handler(
            # Authentication route that sets the JWT in response cookies
            GET=lambda request: Authentication_Util.set_identity_cookies(
                response=API_Message_Response("Authenticated!"),
                _id="1234",
                username="test",
                roles="user"
            ),
            # De-authentication route that removes the JWT in response cookies
            DELETE=lambda request: Authentication_Util.unset_identity_cookies(
                response=API_Message_Response("Logged out!"),
            )
        ),
        log_level=LOG_LEVELS.DEBUG,
        collection_name='permissions',
        permissions=Route_Permissions(POST='user', PUT='admin')
    ),
)

 # Application settings
settings = App_Settings(
    flask=Flask_Settings(
        env="local", 
        debug_mode=True, 
        log_level=LOG_LEVELS.DEBUG,
        config_log_level=LOG_LEVELS.DEBUG
    ),
    mongodb=MongoDB_Settings(
        log_level=LOG_LEVELS.DEBUG
    )
)

# Application Database Indices
indices = MongoDB_Indices(
    MongoDB_Index("sample", "name")
)

# Application Database Fixtures
fixtures = MongoDB_Fixtures(
    MongoDB_Fixture("sample", {"_id": ObjectId("652790328c73b750984aee34"), "name": "Peter"})
)

# Create application
app = Application(routes=routes, settings=settings, indices=indices, fixtures=fixtures)

# Binding directly to Flask for Gunicorn or VSCode
def get_app():
    return app.app

if __name__ == '__main__':
    # Run application
    app.run()

Running With Docker

Building

From the root directory run:

docker build -t <your_image_name> -f docker/Dockerfile .

Running

Run the server image on port 8080 from the Docker GUI or with

docker run -p 8080:8080 <your_image_name>

Note: that MongoDB must be configured on the same Docker network as the app (Use Docker Compose to do this automatically)

Running With Docker Compose

Since the server might depend on MongoDB, you can use Docker Compose to start the Dockerized application in conjuction with a Dockerized MongoDB instance

Building the Server Container

From the docker/ directory containing docker-compose.yml, run:

docker-compose build

Running the Server + MongoDB

From the docker/ directory containing docker-compose.yml, run the following to start the server on port 8080 and MongoDB on port 27017:

docker-compose up --force-recreate

If you are running the application with the environment configured to sandbox or higher, the application will run using gunicorn. If you are running with it configured in a lower environment, the application will run via Flask directly and will allow hot-reloads when code is changed

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

flongo_framework-0.3.33.tar.gz (45.4 kB view details)

Uploaded Source

Built Distribution

flongo_framework-0.3.33-py3-none-any.whl (67.9 kB view details)

Uploaded Python 3

File details

Details for the file flongo_framework-0.3.33.tar.gz.

File metadata

  • Download URL: flongo_framework-0.3.33.tar.gz
  • Upload date:
  • Size: 45.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.9.18

File hashes

Hashes for flongo_framework-0.3.33.tar.gz
Algorithm Hash digest
SHA256 6f3b1508a82535b53828edb4193c7fd6956a5a263c4640d0e5a3b5b51d134ffa
MD5 4affe9407ecb96cb4d2009800e4664ad
BLAKE2b-256 145fb48dd9ad6c70958d7b017f7ec0050a43942e99e10dde232eb924c6a6926e

See more details on using hashes here.

File details

Details for the file flongo_framework-0.3.33-py3-none-any.whl.

File metadata

File hashes

Hashes for flongo_framework-0.3.33-py3-none-any.whl
Algorithm Hash digest
SHA256 c67a158a2de2ee465fa0f45512d3eb96205dd9bf8a506efc1c8919526ad15954
MD5 b436de9ec3da6f16963e1ca88fe5f4d0
BLAKE2b-256 68587471f55d6b878c99831c7e73664662f79ca942d61d44fd814ccb74261874

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page