Security News
Research
Data Theft Repackaged: A Case Study in Malicious Wrapper Packages on npm
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
The quickest and easiest way to build large web apps and APIs with Flask and SQLAlchemy
Flask Unchained is a Flask extension, a pluggable application factory, and a set of mostly optional "bundles" that together create a modern, fully integrated, and highly customizable web framework for Flask and its extension ecosystem. Flask Unchained aims to stay true to the spirit and API of Flask, while making it significantly easier to quickly build large web apps and APIs with Flask and SQLAlchemy.
Flask Unchained introduces "bundles" to Flask: bundles are Python packages that integrate functionality with Flask, Flask Unchained, and other bundles. That could mean anything from integrating vanilla Flask extensions to being full-blown apps your app can integrate, customize, and extend (like say, a blog or web store). Unlike vanilla Flask extensions, bundles are both consistent and highly extensible and customizable. Once you figure out how something works in one bundle, it's the same in every other bundle. They are conceptually similar to Django's "apps", but I think you'll find bundles are even more powerful and flexible.
The architecture of how Flask Unchained and its bundles work is inspired by the Symfony Framework, which is awesome, aside from the fact that it isn't Python ;)
pytest
and factory_boy
A silly (more verbose than it needs to be) example looks about like this:
# project-root/app.py
import random
from flask_unchained import FlaskUnchained, AppBundle, Service, injectable
from flask_unchained import Controller, route, param_converter, url_for
from flask_unchained.pytest import HtmlTestClient
BUNDLES = ['flask_unchained.bundles.controller']
class App(AppBundle):
def before_init_app(self, app: FlaskUnchained) -> None:
pass
def after_init_app(self, app: FlaskUnchained) -> None:
pass
class RandomService(Service):
def get_name(self) -> str:
return random.choice(['Alice', 'Bob', 'Grace', 'Judy'])
class SiteController(Controller):
class Meta:
url_prefix = '/'
random_service: RandomService = injectable
@route('/')
@param_converter(name=str)
def index(self, name: str = None):
name = name or self.random_service.get_name()
return f'Hello {name} from Flask Unchained!'
class TestSiteController:
def test_index(self, client: HtmlTestClient):
r = client.get(url_for('site_controller.index', name='World'))
assert r.status_code == 200
assert r.html == 'Hello World from Flask Unchained!'
You can run it like so:
pip install "flask-unchained[dev]"
export UNCHAINED="app"
pytest app.py
flask urls
flask run
A larger application structure might look about like this:
/home/user/dev/project-root
├── app # your app bundle package
│ ├── admins # Flask-Admin model admins
│ ├── commands # Click CLI groups/commands
│ ├── extensions # vanilla Flask extensions
│ ├── models # SQLAlchemy models
│ ├── fixtures # SQLAlchemy model fixtures (for seeding the dev db)
│ ├── serializers # Marshmallow serializers (aka schemas)
│ ├── services # dependency-injectable services
│ ├── tasks # Celery tasks
│ ├── templates # Jinja2 templates
│ ├── views # Controllers, Resources and views
│ ├── __init__.py
│ ├── config.py # app config
│ └── routes.py # declarative routes
├── assets # static assets to be handled by Webpack
│ ├── images
│ ├── scripts
│ └── styles
├── bundles # custom bundles and/or bundle extensions/overrides
│ └── security # a customized/extended Security Bundle
│ ├── models
│ ├── serializers
│ ├── services
│ ├── templates
│ └── __init__.py
├── db
│ └── migrations # Alembic (SQLAlchemy) migrations (generated by Flask-Migrate)
├── static # static assets (Webpack compiles to here, and Flask
│ # serves this folder at /static (by default))
├── templates # the top-level templates folder
├── tests # your pytest tests
├── webpack # Webpack configs
└── unchained_config.py # the Flask Unchained config
To learn how to build such an app, check out the official tutorial. (NOTE: The tutorial is still a work-in-progress.) You can also check out Flask Unchained React SPA
The docs are on Read the Docs, as is the official tutorial.
NOTE: Some bundles are still a work-in-progress. Parts of the documentation need improvement or are missing. Some corners of the code are still alpha-quality. Things work for me, but there are probably a few bugs lurking, and some parts of the API are potentially subject to change.
Contributions are more than welcome! This is a big project with a lot of different things that need doing. There's a TODO file in the project root, or if you've got an idea, open an issue or a PR and let's chat!
MIT
FAQs
The quickest and easiest way to build large web apps and APIs with Flask and SQLAlchemy
We found that flask-unchained demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
The Socket Research Team breaks down a malicious wrapper package that uses obfuscation to harvest credentials and exfiltrate sensitive data.
Research
Security News
Attackers used a malicious npm package typosquatting a popular ESLint plugin to steal sensitive data, execute commands, and exploit developer systems.
Security News
The Ultralytics' PyPI Package was compromised four times in one weekend through GitHub Actions cache poisoning and failure to rotate previously compromised API tokens.