Skip to content

Instantly share code, notes, and snippets.

@schtibe
Last active May 29, 2024 06:09
Show Gist options
  • Save schtibe/e6c32e2d31e544691194cde0d326ada9 to your computer and use it in GitHub Desktop.
Save schtibe/e6c32e2d31e544691194cde0d326ada9 to your computer and use it in GitHub Desktop.
Framework Evaluation

PB-514 Framework Survey

General Overview

  • Django is a general purpose Framework for building websites. Django is very feature complete and has a rich ecosystem.
  • Flask is a general purpose Framework for building websites. It is very lightweight.
  • FastAPI is a light weight Framework built for creating (REST? evaluate) APIs.
Framework Auth API DB
Django Built-In 3rd Party needed like DRF or Ninja Integrated ORM, Good Migrations, Admin-Backend
Flask 3rd party needed OK, but no built-in evaluation (?) 3rd party needed like SQLAlchemy
FastAPI evaluate Core-Functionality 3rd Party needed like SQLAlchemy

AWS Cognito

Integration Possibilities of the different FWs to AWS Cognito

Django

There's a package. The package seems a bit stale, the last commit is 3yrs ago, issues aren't answered since 2021. It has 176 stars.

There's also this very recent howto for integrating JWT manually with djangorestframework-jwt. In case Ninja is used, there's a fork of that which seems very active. Otherwise, Ninja has built-in JWT Auth.

django rest framework

The library installs itself as an auth backend and works by specifying required authentication in the views.

class ExampleView(APIView):
    authentication_classes = [JWTAuthentication]

django-ninja

verify The library installs as an auth backend. The required authentication can be specified globally, per route or per endpoint:

api = NinjaAPI(auth=GlobalAuth())

api.add_router("/events/", events_router, auth=BasicAuth())

@api.get("/pets", auth=django_auth)
def pets(request):
    return f"Authenticated user {request.auth}"

Flask

There is a package which is fairly active (last commit 5 months ago, 94 starts, 13 contributors). Documentation doesn't seem to be very extensive.

The library works by annotating the different endpoints.

@route('/api/private')
@cognito_auth_required
def api_private():
    pass

FastAPI

There is a package that seems fairly active. Last commit is 3 weeks old, it has 39 stars, the maintainer seems active in the issues/PRs.

The library works by specifying params to the endpoints which denote the requirement of authentication.

from fastapi_cognito import cognitotoken
from fastapi import depends

@app.get("/")
def hello_world(auth: cognitotoken = depends(cognito_eu.auth_required)):
    return {"message": "hello world"}

Django vs SQLAlchemy

  • Django seems more intuitive.
  • SQLAlchemy seems more flexible.
  • Django has migrations, SQLAlchemy not.
  • SQLAlchemy is better with complex DBs.
  • SQLAlchemy is a requirement for Flask and FastAPI

Some further reading:

Differences in usage (not taken into account as it seems mostly a preference of style):

For SQLAlchemy migrations there seem to be 3rd party libraries:

TODO We should maybe take into account what kind of Data that we want to push. If simple CRUD is enough, Django ORM seems simpler.

DRF vs Ninja-API

Django Ninja tries to be FastAPI for Django.

From what I see with quickly testing Django Ninja vs. having used DRF for years is the following:

  • Ninja is way simpler
  • The documentation is better
  • For simple CRUD, Ninja might be more verbose, but it is also more explicit (fitting to the Python Zen)
  • It is very easy to have different schemas for input and output of views, which is weird in DRF
  • It is very easy to do side effects in the views, which in DRF requires weird overwriting of the mixin's default method implementations
  • Ninja provides Swagger by default, DRF needs 3rd party (and annotations I believe)
  • Ninja has built-in pagination support
  • Ninja has built-in flattening support
  • Schemas are written in Pydantic

Whereas DRF falls short if

  • You need different serializers for input and output
  • You want to do side effects
  • You want to have additional fields (ones that don't exist on the model)
  • You want to have computed fields

Honestly, I don't see any reason for DRF.

AWS Amplify

AWS Amplify is a Framework for developing Full Stack applications with Typescript. As it seems, the emphasis is heavily on full stack, and the list of "what can you build with Amplify" lists

  • SSR Web Apps
  • Single page web apps and static websites
  • Native mobile applications
  • Cross-platform applications

Since we (I believe) want to mainly build an API, and since none of us has any experience with neither TS Backend development nor Amplify, I don't see so much of a reason to invest more time in the

What would speak for the use of Amplify is probably the native integration into AWS cognito.

(Also, AWS Amplify has usage costs, but maybe those are equaled out by the hosting costs of a Django/fastAPI App).

Considerations in the BGDI Env

We might want to consider the existing usage and knowledge in said technologies.

Conclusions

  • If it's only API, then decide between FastAPI and Django
  • If it's Django, use Ninja-API
  • If we want to play it safe (from my POV) we should use Django with Ninja
  • If we want to be more lightweight and innovative, FastAPI

further reading

https://www.turing.com/kb/fastapi-vs-flask-a-detailed-comparison

@adk-swisstopo
Copy link

I would have liked to see some words about debugability/observability. When I want to track down a request, profile memory or CPU usage, or generally figure out what's going on, how comparatively easy is it to do with the different options?

@schtibe
Copy link
Author

schtibe commented May 28, 2024

@adk-swisstopo Good point. I don't really know our Observerability landscape, maybe you have some pointers for me as to what technologies should be integrated in that regard (Sentry? Grafana? Prometheus? ..?)

@adk-swisstopo
Copy link

From my understanding our plan is to get everything on Elastic/ELK. @ltflb-bgdi knows the details.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment