Python API development

In this article, we will talk about basic Python API development.

Python API development

Install python3. Download from its official website and install.

Create API by first installing following modules:

pip3 install fastapi
pip3 install uvicorn

Create a file named api.py and write the following code in it:

from fastapi import FastAPI
app = FastAPI()

@app.get("/my-first-api")
def hello():
	return ("Hello world !")

if __name__ == "__main__":
	uvicorn.run(app, port=8000, host="127.0.0.1")

Run the following command in terminal to start the API:

uvicorn api:app --reload

Access it from browser:

http://127.0.0.1:8000/my-first-api

CORS error

If you are having CORS error, you can make the following changes in your code:

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

app.add_middleware(
	CORSMiddleware,
	allow_origins=["*"]
)

Connect Python with Mongo DB

To connect your Python application with Mongo DB, first install pymongo in your server by running the following command:

> pip3 install pymongo

Then you need to import it in your file:

from pymongo import MongoClient

MONGO_CONNECTING_STRING = "mongodb://localhost:27017"
client = MongoClient(MONGO_CONNECTING_STRING)
db = client["your_database_name"]

To insert a document in collection, write the following line:

db["your_collection"].insert_one({
	"name": "Adnan"
})

Form data

Let’s say you have a Javascript code that sends an AJAX request to your Python server.

const formData = new FormData()
formData.append("website", "adnan-tech.com")

Then, in order to get it in your Python API, first you need to run the following command to install “python-multipart” module:

pip3 install python-multipart

Then include the “Form” and “Annotated” module.

from fastapi import FastAPI, Form
from typing_extensions import Annotated

Then in your post API method parameter, define each form data value and its type.

@app.post("/my-api")
async def my_api(website: Annotated[str, Form()]):

	print(url)

Installing Django framework

For Python API development you can also use Django framework. First, you need to install Django framework in your project’s root directory:

pip3 install django

Then you can verify it by checking the version:

python3 -m django --version

You can also verify the version from following command as well:

django-admin --version

Then we will create our django application:

django-admin startproject ecommerce-website

A new folder will be created named “ecommerce-website”. If you go inside this folder, you will find files named “manage.py” and other files along with a directory named same as “ecommerce-website”.

Now enter in the directory “ecommerce-website” and run the following command:

python3 manage.py startapp ecommerce

It will create a directory named “ecommerce”. Now run the following command to start the server:

python3 manage.py runserver

Now you can access your website by running the following URL in the browser:

http://127.0.0.1:8000/

You can access admin panel from:

http://127.0.0.1:8000/admin

It will ask for username and password. You can set it by first running the migration:

python3 manage.py migrate

Then you can create a super user.

python3 manage.py createsuperuser

Create app in Django

Run the following command at the root of your project:

python3 manage.py startapp pages

This will create a folder named “pages”.

Now open “ecommerce/settings.py” and add our app to the “INSTALLED_APPS” array.

INSTALLED_APPS = [
    ...
    "pages"
]

You can get your app name by opening the file “pages/apps.py”.

To create a view, open “pages/views.py” and add the following lines in it:

from django.shortcuts import render
from django.http import HttpResponse

# Create your views here.

def index(request):
	return HttpResponse("<h1>Hello world</h1>")

To configure the URL, create a file named “urls.py” inside “pages” folder and write the following code in it:

from django.urls import path
from . import views

urlpatterns = [
	path("", views.index, name="index")
]

Now open your project’s root “ecommerce/urls.py” and add the following line in it:

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path("", include("pages.urls")),
    path('admin/', admin.site.urls),
]

If you check your browser now at: http://127.0.0.1:8000/, you will see your message “Hello world” in it.

Creating models in Django

To create a model, open your app’s “models.py” file. In my case, it is “pages/models.py”. And write the following code in it:

class Page(models.Model):
	title = models.CharField(max_length = 255)
	content = models.TextField("Content", blank = True)

	def __str__(self):
		return self.title

It will create 2 fields (title and content). The “__str__” function is created to display the page title on admin panel where page listing is displayed.

Then you have to create its migration and migrate it. So run the following commands one-by-one:

python3 manage.py makemigrations pages
python3 manage.py migrate

Then in order to display it on admin panel, open your “pages/admin.py” file and add the following code in it:

from .models import Page

class PageAdmin(admin.ModelAdmin):
	list_display = ("title", "content",)
	ordering = ("title",)
	search_fields = ("title", "content",)

# Register your models here.
admin.site.register(Page, PageAdmin)

This will first import our Page model. Then it will create a class to handle it on admin panel. We will display 2 columns (title and content) on admin panel listing.

The ordering will be done by title field only.

And a search field will be displayed, from where user can search pages by their title or content.

At the end, we are registering both of these classes (Page and PageAdmin) to the admin panel.

Now if you go to your admin panel, you will see an option to manage pages.

Templating

First create a folder named “templates” in your “myEcommerce” folder.

Then goto your project’s “settings.py” file and first import the os module at the top of it.

import os

Then search for array “TEMPLATES”. Add your templates folder path in the DIRS array:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, "myEcommerce/templates")],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

Also, add the following array after the STATIC_URL variable:

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "myEcommerce/static")
]

In your templates folder, create a file named “base.html”.

Write the following code in your base.html file:

{% load static %}

<link rel="stylesheet" type="text/css" href="{% static 'main.css' %}" />

<h1>My template loaded</h1>

Then in your “myEcommerce/static” folder, create a filed named “main.css” and write the following code in it:

h1 {
	color: red;
}

And finally, change your “def index(request)” function inside “pages/views.py” to the following:

def index(request):
	return render(request, "base.html")

If you run the browser now, you will see your content from base.html file. And also it will load css from main.css file.

Template inheritance

You can create child template that extends from parent template. This will be helpful while creating header, footers or sidebars etc.

For that, add the following code in your “base.html” file:

{% block content %}

{% endblock content %}

You can set any name to your block. Now create a folder named “pages” inside “pages/templates” folder. This is necessary because Django will search for your files inside the “templates” folder.

Then create a file named “index.html” in your “pages/templates/pages” folder. Following will be the code of this file:

{% extends "base.html" %}

{% block content %}

<p>Hi</p>

{% endblock content %}

It first extends from base template. So the content of “base.html” will be display on top and “block content” will be displayed where it is mentioned in “base.html” file.

Finally, in your “pages/views.py” make the following changes:

# return render(request, "base.html")
return render(request, "pages/index.html")

If you refresh your page now, you will first see the content of base template. Then of your “pages/index.html” file.

Model to view (Overriding the view)

To fetch data from model and pass it to view, first goto “pages/urls.py” and comment out the previous path() function we created earlier in this post.

And add the following 2 paths, one for home page and one for other pages appending in the URL.

path("", views.index, {
	"pagename": 1
}, name="home"),
path("<str:pagename>", views.index, name="index")

This will pass variable named “pagename” to the view from the URL. So we need to catch that variable.

Open “pages/views.py” and change your index function to the following:

from django.shortcuts import render
from django.http import HttpResponse
from . models import Page

# Create your views here.

def index(request, pagename):
	page = Page.objects.get(id = pagename)
	context = {
		"title": page.title,
		"content": page.content
	}
	return render(request, "pages/index.html", context)

We have added “pagename” as an argument in the index function definition. Then we are getting the record from Page model using ID. And finally we are passing the page object from database to our view render function.

Then in our “pages/templates/pages/index.html”, we can display these values:

<h2>{{ title }}</h2>

<p>{{ content }}</p>

If your content contains HTML tags, then Django by default will escape them to prevent you from attacker’s attempts to inject executable code into your website.

You can render HTML tags by disabling the auto-escaping like this:

{% autoescape off %}

<p>{{ content }}</p>

{% endautoescape %}

If you run “http://127.0.0.1:8000” in your browser now, you will see the first page. Because its ID is 1.

But if you try “http://127.0.0.1:8000/2”, you will see second page. Because now it matches with ID.

Creating menus

To display all pages as menu hyperlinks, first we need to fetch all pages from database. So in your “pages/views.py”, change the context variable to the following:

context = {
	"title": page.title,
	"content": page.content,
	"pages": Page.objects.all()
}

Then in your “myEcommerce/templates/base.html” file, create a block where the child will render it:

{% block pages %}

{% endblock pages %}

And finally in your “pages/templates/pages/index.html”, you can render them as following:

{% block pages %}

<ul>
	{% for page in pages %}

		<li>
			<a href="{{ page.id }}">
				{{ page.title }}
			</a>
		</li>

	{% endfor %}
</ul>

{% endblock pages %}

If you refresh the browser now, you will see a list of all pages created from admin panel. On clicking any, will display the content of that page.

So these are all the basics for Python API development. You can move advance from here. But this is enough to get you started in API development using Python.

For frontend, you can use Vue JS. You can get our list of tutorials on Vue JS as well.