How to Write Microservices in Python

Explore microservices in other languages

Writing Microservices in Python

Python is a very well-known language in many areas of software development, primarily in AI and data analysis and visualization. The tools developed by the community and its simple syntax make it perfect for non-developers with scientific backgrounds to use it for their purposes in an efficient way.

However, that doesn’t mean we can’t also use it for more traditional tasks, such as creating microservices using Python. While there are several frameworks to help with this task, in this article, we’re going to review the benefits of using Python to create microservices and how you can get started quickly.

So let’s get cracking!

Pros and cons of building microservices with Python

There are no proverbial silver bullets when picking the right  programming language for a task. While Python is quite popular in some industries within the IT world, it’s also ignored in others. In the case of microservices, Python definitely has some strengths and, also, some weaknesses that we should explore before making our final decision.

So let’s take a quick look at the “pros” and “cons” of using this language for microservice-based projects:

  • Simplicity and Readability: Python’s clean and easy-to-read syntax makes it straightforward to write and maintain code. While some developers might not enjoy the indentation-based scoping, it is required to compile the code and helps to keep the code structured reducing the cognitive load required to understand it. This is especially handy when you’re dealing with the smaller, more focused nature of microservices.

  • Large Community: Python has a mighty big and welcoming community. This means there are plenty of libraries, frameworks, and resources to help you build and scale your microservices.

  • Scalability: Python’s performance has improved over the years, and it’s well-suited for building scalable microservices, especially when combined with async frameworks like FastAPI.

  • RESTful APIs: Building RESTful APIs is a piece of cake with Python. Libraries like Flask and Django make it simple to create APIs that can communicate with other microservices or clients.

  • Great Documentation: Python’s documentation is top-notch, so you won’t be left in the dark when you’re trying to figure something out. And if that wasn’t enough, the already-mentioned sizable community will definitely give you a hand if you can’t figure something out. Googling for answers around problems with Python will usually yield responses in the form of StackOverflow posts, detailed articles, or even already-made solutions in the form of pip packages.

  • Testing and Debugging: Python has strong testing and debugging support, which is crucial when you’re dealing with microservices that need to be reliable and easy to troubleshoot.

When it comes to building microservices with Python there are a few “cons”, especially related to scalability and performance. Let’s take a look at some of the major issues with this language:

  • GIL (Global Interpreter Lock): This is probably one of the major cons of Python, and it’s the fact that by default it can make it tricky to utilize multiple CPU cores effectively. This lock can limit the performance of multi-threaded applications, which might be a concern for certain microservices.

     

  • Compatibility between major versions: Python 2 and Python 3 have some incompatibilities between them, and if you’re dealing with older codebases, transitioning can be a bit of a headache. Of course, this is only a problem if you’re going through the process of moving from one version to the other, but it’s also true that many other languages don’t suffer from this problem between major version jumps.

     

  • Scalability Challenges: When dealing with massive, high-traffic microservices, Python’s scalability might become a concern. The GIL (already covered) makes it hard to vertically scale (by adding more cores), leaving only horizontal scaling as an option. This translates to you needing to invest more in infrastructure to handle the load.

Monolithic vs microservices-based business process automation platforms

Building Scalable Business Automation with Microservices

As you can see, the list is not long but significant. This leads to the conclusion that while Python is definitely a valid option for building microservices, it’s also not the “best” given certain requirements (specifically performance and scalability). If your project doesn’t have a strong emphasis on those points and your dev team is already familiar with the language, then Python is the perfect choice.

If that’s not the case, then you might want to look into other alternatives (such as Go or TypeScript).

Let’s now take a look at what building an actual microservice looks like in Python.

Python microservices example

In this hands-on example, we’ll create a simplified product catalog microservice using Python and Flask. This microservice will expose RESTful endpoints for managing product information.

Step 1: Project setup

There are many options out there to create a working RESTful API with Python as we mentioned, but we’re going to go with a very popular one: Flask.

The first step is to go into your project’s folder and install our framework through pip, which you should have installed if you already have Python.

As a note, I’ll be using Python 3.x, if you’re using Python 2.x there might be certain things that don’t fully work.

pip install Flask

That’s all you need, we’ll now start writing our code.

Step 2: Define the data model

For our “data model”, we’ll create a Python class to define the structure of our products. We’ll also define a simple Python list to hold the data we create, that’s going to be our “data layer”. Keep in mind that for this example we’ll be saving this code into a file called “models.py”

				
					# A list to store our products (in memory)
products = []

# Product "Model"
class Product:
    def __init__(self, id, name, description, price):
        self.id = id
        self.name = name
        self.description = description
        self.price = price

				
			

We’ll be using this class across the rest of our code to properly define the “shape” of our data.

Step 3: Implement RESTful endpoints

Since we’re using Flask, we’re going to define our endpoints through a Flask Blueprint.

For the example to work, the following code should be saved into a file called “routes.py” inside the same folder as the previous step

				
					from flask import Blueprint, request, jsonify
from models import Product, products

routes = Blueprint('routes', __name__)

@routes.route('/products', methods=['POST'])
def add_product():
  name = request.json['name']
  description = request.json['description']
  price = request.json['price']
  id = len(products) + 1
  new_product = Product(id, name, description, price)

  products.append(new_product.__dict__)

  return jsonify(new_product.__dict__)

@routes.route('/products', methods=['GET'])
def get_products():
  return jsonify(products)

@routes.route('/products/<id>', methods=['GET'])
def get_product(id):
    for product in products:
        if product['id'] == int(id):
            return jsonify(product)
    return jsonify({"message": "Product not found"}), 404

				
			

Here we’ve defined our 3 endpoints:

  • GET /products: which will return the full list of products. As you can see there, it simply returns the JSON version of our list.
  • GET /products/<id>: This endpoint will return a single product if the ID is valid, otherwise, it’ll return a 404 status code with a JSON response.
  • POST  /products: This endpoint will receive the data for our product, and it’ll instantiate a new object using the Product class. Notice how afterward, I’m “saving” the product into our list of products as a Dict, that’s because when it’s time to return its JSON representation (in either one of the GET endpoints), we won’t be able to natively turn our class Product into a JSON. However, the Dict class is already prepared for that.

As I already hinted at, the “data layer” is nothing more than a list, so we don’t really have to worry about it at this time. Granted, if you wanted to do this “right”, you’d need to also include some form of database access.

Step 4: Final set up

The last thing to worry about is to get everything going. That’s where the “main.py” file comes in (you can call it however you want).

This file will create the Flask application and it’ll kick off the parsing and understanding of all the setup we’ve been doing until now with the routes and our data model.

Here’s the file’s code:

				
					from flask import Flask
from routes import routes

# Init app
app = Flask(__name__)

# Register routes
app.register_blueprint(routes)

# Run Server
if __name__ == '__main__':
    app.run(debug=True)

				
			

This is just initializing the application and running it in debug mode.

You can execute it with python main.py and it will be listening, by default, on port 5000.

Congrats! You now have your own working microservice written in Python using Flask. Clearly, this is a simple example, and it could be extended by adding authentication, error handling, and other common features in production-ready microservices. But we’ll leave that up to you!

Orchestrating microservices with Camunda

For your Python microservices, Camunda provides an orchestration platform that complements Python’s reputation for rapid development and simplicity. 

Managing microservices workflows becomes more intuitive as Camunda bridges the gap between technical implementation and business logic. The platform’s ability to model processes in BPMN and execute them efficiently fits hand-in-glove with Python’s dynamic and expressive syntax. 

This combination facilitates seamless automation and error handling without encumbering the loose coupling and autonomy that are key aspects of microservices-based architectures

Python developers can particularly appreciate Camunda’s flexibility, which allows for quick iterations and deployment, keeping the development cycle lean while not losing sight of end-to-end reliability and performance metrics.

Curious to see how Camunda can help you with microservice orchestration? Check out this article about the top 6 benefits of setting up an event-driven process orchestration, and then dive right into Camunda with a free account.

Start orchestrating your microservices with Camunda