Usage¶
First, you have to create a project with zemfrog:
$ zemfrog create frog
Project Layouts¶
The application structure is as follows:
frog (root directory)
├── apis
├── commands
├── extensions
├── middlewares
├── models
├── tasks
├── static
├── templates
├── templates/emails
├── config.py
├── Procfile
├── README.rst
├── requirements.txt
└── wsgi.py
apis- This directory is for all REST API resources.commands- This directory is for the commands that will be registered in the flask command.extensions- This directory is for a list of flask extensions.handlers- This directory is for error handlers.middlewares- This directory is a list of middleware.models- This directory is for a list of sqlalchemy ORM models.tasks- This directory is for the celery task list.static- Static files.templates- Templates folder.templates/emails- This directory is for the list of email templates.config.py- Flask application configuration file.Procfile- Configuration file for deploying on heroku.README.rst- A short description of how to run zemfrog applications.requirements.txt- List of application dependencies.wsgi.py- Flask application here.
Assume if you already installed virtualenv and go run the application:
$ cd frog
$ virtualenv venv
$ source venv/bin/activate
$ pip install -r requirements.txt
$ flask run
Configuration¶
There are several configurations in the zemfrog application, including:
EXTENSIONS- List your flask extensions here.COMMANDS- List your commands here.BLUEPRINTS- List your blueprint here.ERROR_HANDLERS- List of error handlers.MIDDLEWARES- List of middleware here.APIS- List your REST API resources here.API_DOCS- Configuration for automation creates REST API documentation usingflask-smorest. Default value isTrue.CREATE_DB- Configuration for automation creates tables of all models. Default value isTrue, but I will remove this configuration in the future.API_PREFIX- URL prefix for all endpoints in theapisdirectory.API_SECURITY_DEFINITIONS- Follow this https://swagger.io/docs/specification/authentication/.API_SECURITY_PARAMS- Follow this https://swagger.io/docs/specification/authentication/API_SPEC_OPTIONS- See here https://flask-smorest.readthedocs.io/en/latest/openapi.html#populate-the-root-document-objectAPPS- List of sub applications.TASKS- Celery task list.STATICFILES- List of static files to serve.
Yep! that’s all the configuration for the zemfrog application. However, you can also add configurations for celery and other flask extensions in config.py :)
Routes¶
Note
The route format specification is (url, view, methods).
Example:
# urls.py
routes = [
('/', views.index, ['GET']),
]
Commands¶
In the flask application there is a feature to add “own commands” to flask commands. However, these are not automatically added by flask. Don’t worry, this behavior will be handled by zemfrog automatically.
Let’s create a boilerplate command:
$ flask command new foo
Now you have foo.py in the commands directory and you will see the command variable in the file foo.py.
This variable will be imported and added to the flask command by zemfrog automatically.
Then add a command to the COMMANDS configuration in config.py:
COMMANDS = ['foo']
Now you can see the command foo is registered in the application:
$ flask foo
Error Handling¶
In zemfrog you can handle errors easily, you just need to make a boilerplate handler. Like this:
$ flask handler new not_found
And in the handlers/not_found.py module there is a handler function which zemfrog will import automatically.
Now register to the ERROR_HANDLERS configuration. Like this:
ERROR_HANDLERS = {
404: "not_found"
}
Note
The format of the error handler is {code_or_exception: "error handler"}
Multiple Static Files¶
You can add more static files to serve via the STATICFILES configuration, like this:
STATICFILES = [
("/assets", "assets", "assets")
]
Static file format values are (path, endpoint, static_folder, static_host).
Note
the static_host value is optional
Background Tasks¶
In zemfrog, it is integrated with Celery for background tasks. So you need to understand about celery. See here https://docs.celeryproject.org/en/stable/getting-started/introduction.html for more details.
And how do I make a background task?
All background tasks are in the tasks directory of the project layouts.
And in the tasks directory, a sample background task is also available.
from zemfrog.globals import celery
from zemfrog.globals import mail
@celery.task
def send_email(*args, **kwds):
mail.send_message(*args, **kwds)
Note
If you want to create a background task, you have to use the celery app from the zemfrog.globals.
Like the sample above.
Blueprints¶
Make a boilerplate blueprint:
$ flask blueprint new account
The blueprint structure will look like this:
account
├── __init__.py
├── routes.py
├── urls.py
└── views.py
routes.py- Your blueprint is here.urls.py- All your endpoints are here.views.py- All your view functions here.
Let’s create 2 view functions:
# account/views.py
def login():
return "login"
def logout():
return "logout"
Register the view function to the blueprint, otherwise your view function will not be in the blueprint.
# account/urls.py
routes = [
('/login', views.login, ['POST']),
('/logout', views.logout, ['POST'])
]
Now all views will be listed on the blueprint. However, you need to register your blueprints in the flask app.
Add your blueprint name to the BLUEPRINTS configuration in config.py:
BLUEPRINTS = ['account']
And, now you can see the blueprint account has been registered in the flask application:
$ flask routes
Middlewares¶
In this section, I will explain how easy it is to create middleware. Let’s start by creating the boilerplate middleware:
$ flask middleware new auth
The above command will create an auth.py file to the middlewares directory and in the auth.py file there is a function init_middleware.
This function is to register your middleware in the flask application.
And register your middleware to config file:
MIDDLEWARES = ["auth"]
API¶
zemfrog is specially designed for building REST APIs quickly. In zemfrog you can create a basic CRUD or just boilerplate API.
All API resources are located in the apis directory.
Let’s start by creating an API resource:
$ flask api new article
Now you have the article API resource:
apis
├── article.py
├── __init__.py
The following are the variables in the API article (on the last line):
tag- API name (which is the name of the blueprint).description- API description.url_prefix- URL prefix for the API resource.routes- All of your API endpoints.
Now, we will create a basic REST API.
Note
You cannot create a REST API if you don’t have an ORM model for that API.
Let’s create a Product model.
Change the file models/__init__.py to be like this:
from zemfrog.globals import db
from sqlalchemy import Column, String, Integer
class Product(db.Model):
id = Column(Integer, primary_key=True)
name = Column(String)
Warning
Keep in mind, you have to create an API with the same name as your ORM model.
And don’t forget to add the --crud option.
And we can create a REST API:
$ flask api new Product --crud
This REST API will not work if you haven’t added it to the APIS config.
Let’s add it to the config:
APIS = ['Product']
Multiple Application¶
In zemfrog you can easily create sub applications.
Let’s start by creating a sub application as below:
$ flask app new sub
And add your sub-application to the APPS configuration in the config.py file:
APPS = ["sub"]
You can also add sub-applications using a dictionary:
APPS = [
{
"name": "sub", # Your application name.
"path": "/sub-app", # Application URL prefix. (optional)
"help": "Sub app command" # Help messages for your app commands. (optional)
}
]
To manage nested applications you just need to use the sub command:
$ flask sub