Lars Cornelissen


How to Make a Simple Backend in Python with a Database

Profile Picture Lars Cornelissen
Lars Cornelissen • Follow
CEO at Datastudy.nl, Data Engineer at Alliander N.V.

4 min read


black flat screen computer monitor

Introduction

Introduction

Welcome to this comprehensive guide on building a custom backend using Python! In this blog, we'll dive into a step-by-step process to help you understand the intricacies and benefits of creating a custom backend.

Why is creating a custom backend essential? Well, think of it this way: opting for a pre-built solution is like buying a one-size-fits-all jacket. Sure, it might fit, but it won't suit your unique style and preferences. A custom backend, on the other hand, is like a tailor-made jacket, perfectly designed to meet your specific needs.

So, what makes Python the ideal choice for this? For starters, Python enjoys widespread popularity thanks to its clean and readable syntax. It allows you to write less code compared to other languages like Java or C++, without sacrificing functionality. Also, with frameworks like Django and Flask, Python offers robust solutions that make backend development a breeze. Whether you're designing a simple API or managing more complex server-side logic, Python has got you covered.

Let's not forget about database integration. No backend is complete without a solid database. With Python, integrating databases is seamless. You'll find libraries and frameworks that support various databases like PostgreSQL, MySQL, and even NoSQL databases like MongoDB. Trust me, once you get the hang of it, integrating and managing your database will feel like second nature.

Exciting, right? Stick with me as we move forward to explore the nitty-gritty details of custom backend development with Python. From setting up your environment to deploying your application, we're going to cover it all. I promise to sprinkle in some useful tips and tricks along the way. Let's get started!

Setting Up Your Python Environment

Setting Up Your Python Environment

Alright, let's roll up our sleeves and get started with setting up your Python development environment. Think of this as setting up your workspace; the more organized and equipped it is, the smoother your development process will go. Here's how to get everything up and running.

1. Installing Python

First things first, you need to have Python installed on your machine. Head over to the official Python website and download the latest stable version of Python. Follow the installation prompts. Make sure to check the box that says

Creating a Basic Backend Application

Creating a Basic Backend Application

Now that you have your Python environment set up, it's time to dive into creating a basic backend application. We have two popular frameworks to choose from: Flask and Django. For simplicity, I'll walk you through setting up a basic application using Flask. Don't worry, if you're a Django fan, the concepts will be quite similar.

First, let's get Flask installed. Run the following command in your terminal:

pip install Flask

With Flask installed, let's create a simple REST API that supports CRUD (Create, Read, Update, Delete) operations. We'll set up a basic application for managing a list of books.

Setting Up the Flask Application

Create a new directory for your project and navigate into it. Then, create a file named app.py and open it in your favorite text editor. Insert the following code:

from flask import Flask, jsonify, request

app = Flask(__name__)

books = [
    {'id': 1, 'title': '1984', 'author': 'George Orwell'},
    {'id': 2, 'title': 'To Kill a Mockingbird', 'author': 'Harper Lee'}
]

@app.route('/books', methods=['GET'])
def get_books():
    return jsonify({'books': books})

@app.route('/books/<int:book_id>', methods=['GET'])
def get_book(book_id):
    book = next((book for book in books if book['id'] == book_id), None)
    if book is None:
        return jsonify({'error': 'Book not found'}), 404
    return jsonify(book)

@app.route('/books', methods=['POST'])
def create_book():
    if not request.json or not 'title' in request.json:
        return jsonify({'error': 'Invalid input'}), 400
    new_book = {
        'id': books[-1]['id'] + 1,
        'title': request.json['title'],
        'author': request.json.get('author', '')
    }
    books.append(new_book)
    return jsonify(new_book), 201

@app.route('/books/<int:book_id>', methods=['PUT'])
def update_book(book_id):
    book = next((book for book in books if book['id'] == book_id), None)
    if book is None:
        return jsonify({'error': 'Book not found'}), 404
    if not request.json:
        return jsonify({'error': 'Invalid input'}), 400
    book['title'] = request.json.get('title', book['title'])
    book['author'] = request.json.get('author', book['author'])
    return jsonify(book)

@app.route('/books/<int:book_id>', methods=['DELETE'])
def delete_book(book_id):
    book = next((book for book in books if book['id'] == book_id), None)
    if book is None:
        return jsonify({'error': 'Book not found'}), 404
    books.remove(book)
    return jsonify({'result': True})

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

Explanation

Let's break down what this code does: - GET /books: Retrieves the list of books. - GET /books/: Retrieves a single book by ID. - POST /books: Creates a new book. The book data is expected to be in JSON format. - PUT /books/: Updates an existing book by ID. You can change the title and/or author. - DELETE /books/: Deletes a book by ID.

Running the Application

To run your Flask application, simply execute the following command in your terminal:

python app.py

You should see output indicating that the server is running on http://127.0.0.1:5000/. Open your browser and go to this URL to see your API in action.

Testing Your Endpoints

You can use tools like Postman or curl for testing your API endpoints. Here are some example commands using curl:

# Get list of books
curl http://127.0.0.1:5000/books

# Get a book by ID
curl http://127.0.0.1:5000/books/1

# Create a new book
curl -X POST -H "Content-Type: application/json" -d '{"title": "The Great Gatsby", "author": "F. Scott Fitzgerald"}' http://127.0.0.1:5000/books

# Update a book
curl -X PUT -H "Content-Type: application/json" -d '{"title": "Brave New World", "author": "Aldous Huxley"}' http://127.0.0.1:5000/books/1

# Delete a book
curl -X DELETE http://127.0.0.1:5000/books/1

Congratulations! You've just created a basic backend application using Flask. This simple REST API demonstrates how CRUD operations are handled, and it's a solid foundation for more complex functionality.

In the next chapters, we'll dive deeper into more advanced topics like database integration, user authentication, and deployment strategies. But for now, give yourself a pat on the back for setting up your first backend application. Trust me, it only gets more exciting from here!

Integrating a Database

Integrating a Database

Alright, we've got our basic backend application running with Flask—awesome job on that! Now, let's take it a notch higher by integrating a database. After all, hardcoding data is not scalable. We'll explore different database options and then get into integrating one with our application. Spoiler: it involves some code, but it's more fun than pulling teeth, I promise!

Choosing a Database

Choosing the right database is like choosing the right pair of shoes. You need the right fit for the right occasion. Here are some popular ones to consider:

For this guide, we'll stick with PostgreSQL. Why? It offers robustness and scalability, making it suitable for various application sizes.

Step-by-Step Integration with PostgreSQL

1. Install PostgreSQL

Before anything else, you'll need PostgreSQL installed on your machine. You can download it from the official PostgreSQL website. Follow the instructions based on your operating system.

2. Installing psycopg2

psycopg2 is the PostgreSQL adapter for Python. You can install it using pip:

pip install psycopg2-binary

3. Setting Up PostgreSQL

Create a new PostgreSQL database and user. You can use the psql command-line client or any GUI tool like pgAdmin.

Here's an example using psql:

# Start psql
psql

# Create database
CREATE DATABASE mydb;

# Create user
CREATE USER myuser WITH PASSWORD 'mypassword';

# Grant all privileges on the database to the user
GRANT ALL PRIVILEGES ON DATABASE mydb TO myuser;

4. Configuring Flask to Use PostgreSQL

In your Flask application, you need to configure the database connection. Below is how you can do it.

First, install SQLAlchemy, a SQL toolkit, and Object-Relational Mapping (ORM) library for Python:

pip install SQLAlchemy
pip install Flask-SQLAlchemy

Then update your app.py file to include the database configuration:

from flask import Flask, jsonify, request
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)

# Database configuration
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://myuser:mypassword@localhost/mydb'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

db = SQLAlchemy(app)

class Book(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(80), nullable=False)
    author = db.Column(db.String(120), nullable=True)

    def __repr__(self):
        return f'<Book {self.title}>'

# Create the database tables
with app.app_context():
    db.create_all()

# ... (Rest of your code remains the same)

# Updating CRUD operations to use the database
@app.route('/books', methods=['GET'])
def get_books():
    books = Book.query.all()
    return jsonify({'books': [{ 'id': book.id, 'title': book.title, 'author': book.author} for book in books]})

@app.route('/books/<int:book_id>', methods=['GET'])
def get_book(book_id):
    book = Book.query.get(book_id)
    if book is None:
        return jsonify({'error': 'Book not found'}), 404
    return jsonify({'id': book.id, 'title': book.title, 'author': book.author})

@app.route('/books', methods=['POST'])
def create_book():
    if not request.json or not 'title' in request.json:
        return jsonify({'error': 'Invalid input'}), 400
    new_book = Book(title=request.json['title'], author=request.json.get('author', ''))
    db.session.add(new_book)
    db.session.commit()
    return jsonify({'id': new_book.id, 'title': new_book.title, 'author': new_book.author}), 201

# ... (similar updates for PUT and DELETE operations)

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

5. Running the Updated Application

With everything set up, run your Flask application again:

python app.py

Now your application should be hooked up to PostgreSQL for data storage. Head over to http://127.0.0.1:5000/books to test your setup. If you see your book data, congratulations—your database integration is successful!

Testing Database Operations

Feel free to repeat the curl commands from earlier to test CRUD operations. You should find that everything behaves as expected, with data being persisted to your PostgreSQL database.

Why PostgreSQL?

Here are a few reasons why PostgreSQL is an excellent choice:

With your backend now integrated with a robust database, your application is significantly more scalable. In the upcoming chapters, we'll take this even further by exploring user authentication and deploying your application. Stay tuned!

Testing and Deployment

Testing and Deployment

You've done a fantastic job so far, setting up a Flask application and integrating a PostgreSQL database. Now comes a crucial part that's often overlooked: testing. Trust me, you don't want to skip this step unless you love debugging at 2 AM. Once we're confident everything works as expected, we'll move on to deploying your application. Let's dive in!

Why Test Your Backend?

Imagine driving a car without ever testing if the brakes work. Scary, right? Similarly, deploying an untested backend can lead to disastrous outcomes like data loss or security breaches. Testing ensures everything runs smoothly and catches bugs before your users do.

Testing Tools and Methods

Wondering how to test your backend? Here are some popular tools and techniques:

Writing Unit Tests with Unittest

Let's write some unit tests for our Flask application using Python's built-in unittest library. Create a new file called test_app.py and add the following code:

import unittest
from app import app, db, Book
import json

class BasicTestCase(unittest.TestCase):
    def setUp(self):
        app.config['TESTING'] = True
        app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///:memory:'
        self.app = app.test_client()
        db.create_all()
        self.populate_data()

    def tearDown(self):
        db.session.remove()
        db.drop_all()

    def populate_data(self):
        book1 = Book(title='1984', author='George Orwell')
        book2 = Book(title='To Kill a Mockingbird', author='Harper Lee')
        db.session.add(book1)
        db.session.add(book2)
        db.session.commit()

    def test_get_books(self):
        response = self.app.get('/books')
        self.assertEqual(response.status_code, 200)
        data = json.loads(response.data)
        self.assertEqual(len(data['books']), 2)

    def test_create_book(self):
        new_book = {'title': 'The Great Gatsby', 'author': 'F. Scott Fitzgerald'}
        response = self.app.post('/books', data=json.dumps(new_book), content_type='application/json')
        self.assertEqual(response.status_code, 201)
        data = json.loads(response.data)
        self.assertEqual(data['title'], 'The Great Gatsby')

if __name__ == '__main__':
    unittest.main()

Running Your Unit Tests

To run your tests, execute the following command in your terminal:

python test_app.py

If everything is set up correctly, you should see output indicating that your tests have passed. Congratulations, you now have automated tests for your backend!

Deployment

Testing was the easy part. Now let's deploy your backend to the cloud. We’ll use Heroku for this guide, but platforms like AWS or Google Cloud are also great options.

Deploying to Heroku

1. Install Heroku CLI

If you haven't already, install the Heroku Command Line Interface (CLI) from the official site.

2. Log In to Heroku

Run the following command to log in to Heroku:

heroku login

A browser window will open for you to enter your credentials.

3. Create a Heroku App

Navigate to your project directory and create a new Heroku app:

heroku create

4. Prepare Your App for Deployment

Make sure you have a Procfile and requirements.txt in your project directory. Here's an example of what they should contain:

Procfile

web: python app.py

requirements.txt

Flask==2.0.1
Flask-SQLAlchemy==2.5.1
psycopg2-binary==2.9.1
# Add other dependencies here

5. Deploy Your App

Commit your changes and push to Heroku:

git init
git add .
git commit -m "Initial commit"
heroku git:remote -a <your-heroku-app-name>
git push heroku master

6. Set Up Your App's Database

Heroku makes it convenient to set up a PostgreSQL database. Use the following commands to add the Heroku Postgres add-on and run database migrations:

heroku addons:create heroku-postgresql:hobby-dev
heroku run python
>>> from app import db
>>> db.create_all()
>>> exit()

7. Visit Your Deployed App

Open your browser and go to the URL provided by Heroku. Your Flask application is now live on the internet!

Summary Table

Here’s a quick summary to guide you through the deployment steps:

Step Command
Log in to Heroku heroku login
Create Heroku App heroku create
Add files to Git git add .
Commit Changes git commit -m "Initial commit"
Set Heroku remote heroku git:remote -a <app-name>
Push to Heroku git push heroku master
Add PostgreSQL add-on heroku addons:create heroku-postgresql:hobby-dev
Database Migration heroku run python

Congratulations! You’ve not only built a custom backend but also tested and deployed it. Your application is now live and accessible to the world.

Stay tuned for the next chapters where we'll explore user authentication and more advanced features. For now, go ahead and relish this moment—you deserve it!

Conclusion

Conclusion

Wow, you've made it to the end! Let's pause for a second and take stock of everything we've covered. From setting up your Python environment to deploying your application on Heroku, we've walked through essential steps to build a custom backend using Python. The best part? You've got a functional, scalable backend that you can continue to build upon. So, what have we specifically achieved?

Summary of Steps

  1. Introduction: We began by understanding the importance of a custom backend and why Python is an excellent choice for the task.
  2. Setting Up Your Python Environment: We installed Python and set up a clean workspace to prepare for development.
  3. Creating a Basic Backend Application: Using Flask, we set up a simple REST API to manage a list of books.
  4. Integrating a Database: We integrated PostgreSQL for persistent data storage, learning how to configure and use it with Flask.
  5. Testing and Deployment: We wrote unit tests to ensure our application runs smoothly and then deployed it to Heroku, making it publicly accessible.

Encouragement to Experiment

Now that you've got the basics down, I highly encourage you to experiment further. Here are some ideas to extend your backend application:

Don't be afraid to break things. That's how you learn and become a better developer. Remember, every bug you encounter is just another learning opportunity in disguise.

Additional Resources

If you're itching for more, here are some excellent resources to check out:

Thank you for sticking with me through this journey. Building a custom backend is no small feat, but with Python and the right tools, it's more than achievable. Keep pushing the boundaries, and soon enough, you'll be creating backend systems that are as intricate as they are efficient.

Happy coding!


Python

backend development

database

programming tutorial