Book Image

Python Microservices Development – 2nd edition - Second Edition

By : Simon Fraser, Tarek Ziadé
Book Image

Python Microservices Development – 2nd edition - Second Edition

By: Simon Fraser, Tarek Ziadé

Overview of this book

The small scope and self-contained nature of microservices make them faster, cleaner, and more scalable than code-heavy monolithic applications. However, building microservices architecture that is efficient as well as lightweight into your applications can be challenging due to the complexity of all the interacting pieces. Python Microservices Development, Second Edition will teach you how to overcome these issues and craft applications that are built as small standard units using proven best practices and avoiding common pitfalls. Through hands-on examples, this book will help you to build efficient microservices using Quart, SQLAlchemy, and other modern Python tools In this updated edition, you will learn how to secure connections between services and how to script Nginx using Lua to build web application firewall features such as rate limiting. Python Microservices Development, Second Edition describes how to use containers and AWS to deploy your services. By the end of the book, you’ll have created a complete Python application based on microservices.
Table of Contents (14 chapters)
12
Other Books You May Enjoy
13
Index

A microservice skeleton

So far in this chapter, we have looked at how Quart works, and at most of the built-in features it provides—all of which we will be using throughout this book. One topic we have not yet covered is how to organize the code in your projects, and how to instantiate your Quart app. Every example so far has used a single Python module and the app.run() call to run the service.

Having everything in a module is possible, but will create a lot of headaches unless your code is just a few lines. Since we will want to release and deploy the code, it's better to have it inside a Python package so that we can use standard packaging tools such as pip and setuptools.

It is also a good idea to organize views into blueprints, and have one module per blueprint. This lets us keep better track of what each bit of code does, and re-use code whenever possible.

Lastly, the run() call can be removed from the code since Quart provides a generic run command that looks for an application using information from the QUART_APP environment variable. Using that runner offers extra options, such as the ability to configure the host and port that will be used to run the app without going into the settings each time.

The microservice project on GitHub was created for this book and is a generic Quart project that you can use to start a microservice. It implements a simple layout, which works well for building microservices. You can install and run, and then modify it. The project can be found at https://github.com/PythonMicroservices/microservice-skeleton.

The microservice project skeleton contains the following structure:

  • setup.py: Distutils' setup file, which is used to install and release the project.
  • Makefile: A Makefile that contains a few useful targets to make, build, and run the project.
  • settings.yml: The application default settings in a YAML file.
  • requirements.txt: The project dependencies following the pip format produced by pip freeze.
  • myservices/: The actual package
    • __init__.py
    • app.py: The app module, which contains the app itself
    • views/: A directory containing the views organized in blueprints
      • __init__.py
      • home.py: The home blueprint, which serves the root endpoint
    • tests/: The directory containing all the tests
      • __init__.py
      • test_home.py: Tests for the home blueprint views

In the following code, the app.py file instantiates a Quart app using a helper function called create_app to register the blueprints and update the settings:

import os
from myservice.views import blueprints
from quart import Quart
_HERE = os.path.dirname(__file__)
_SETTINGS = os.path.join(_HERE, "settings.ini")
def create_app(name=__name__, blueprints=None, settings=None):
    app = Quart(name)
    # load configuration
    settings = os.environ.get("QUART_SETTINGS", settings)
    if settings is not None:
        app.config.from_pyfile(settings)
    # register blueprints
    if blueprints is not None:
        for bp in blueprints:
            app.register_blueprint(bp)
    return app
app = create_app(blueprints=blueprints, settings=_SETTINGS)

The home.py view uses a blueprint to create a simple route that doesn't return anything:

from quart import Blueprint
home = Blueprint("home", __name__)
@home.route("/")
def index():
    """Home view.
    This view will return an empty JSON mapping.
    """
    return {}

This example application can run via Quart's built-in command line, using the package name:

$ QUART_APP=myservice quart run
 * Serving Quart app 'myservice.app'
 * Environment: production
 * Please use an ASGI server (e.g. Hypercorn) directly in production
 * Debug mode: False
 * Running on http://localhost:5000 (CTRL + C to quit)
[2020-12-06 20:17:28,203] Running on http://127.0.0.1:5000 (CTRL + C to quit)

From there, building JSON views for your microservice consists of adding modules to microservices/views, and their corresponding tests.