Si posso davvero realizzare delle Rest API perfettamente funzionanti con tanto di autenticazione in soli 30 minuti con Python. Le nostre url di accesso prevederanno un’autenticazione tramite Basic Auth, accetteranno chiamate GET, POST, PUT, DELETE ognuna delle quali avrà la sua specifica funzione di lettura, inserimento, modifica, rimozione.
In questo specifico caso utilizzeremo Django e la libreria Rest framework, non mi soffermerò in parti di spiegazione su django e neanche su Python stesso, perchè questo mini tutorial prevede già una minima conoscenza delle parti. Quello che analizzeremo è la libreria rest framework

Setup del progetto
Per prima cosa creeremo il nostro nuovo progetto python Api, installeremo le dipendenze necessarie e poi inizializzeremo un’App chiamata products
mkdir tutorial
cd tutorial
# Crea un ambiente virtuale per isolare localmente le dipendenze dei nostri pacchetti
python3 -m venv env
source env/bin/activate # Su windows usare `env\Scripts\activate`
# Installare Django e Django REST framework nell'ambiente virtuale
pip install django
pip install djangorestframework
# Inizializziamo il nostro progetto e la nostra applicazione
django-admin startproject api . # Nota, non dimenticate '.'
django-admin startapp products
A questo punto, effettuiamo la nostra prima migration
python manage.py migrate
Successivamente creiamo il nostro utente super user admin con password Password123
python manage.py createsuperuser --email admin@example.com --username admin
Spostiamoci nella nostra applicazione products/ e creiamo il nostro primo modello. Editiamo il file products/models.py in questo modo
from django.db import models
# Create your models here.
class Product(models.Model):
title = models.CharField(max_length=255)
description = models.TextField()
price = models.DecimalField(max_digits=9, decimal_places=2)
def __str__(self):
return self.title

Prepariamo la nostra nuova migration. Aggiungiamo in api/settings.py la nostra applicazione, salviamo il file ed eseguiamo il comando per generare la nuova migrations
# settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'products.apps.ProductsConfig'
]
python manage.py makemigrations products
Ora eseguiamo la migration con migrate
python manage.py migrate
Rest Framework: Serializers
La prima cosa di cui abbiamo bisogno per inizializzare la nostra API è fornire un modo per serializzare e deserializzare le istanze in formato JSON. Per fare questo, creiamo un file serializers.py all’interno della root ./products, importiamo il modello creato in precedenza e definiamo i campi
from products.models import Product
from rest_framework import serializers
class ProductSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Product
fields = [
'url',
'title',
'description',
'price',
]
Nota: abbiamo utilizzato il sistema di relazioni basato su collegamenti ipertestuali – url – con il metodo HyperlinkedModelSerializer fornito dal modulo serializers
La vista
Apriamo ed editiamo il file views.py in ./products come segue
from products.models import Product
from rest_framework import viewsets
from rest_framework import permissions
from products.serializers import ProductSerializer
class ProductViewSet(viewsets.ModelViewSet):
"""
API endpoint per la visualizzazione, inserimento, modifica o rimozione dei prodotti.
"""
queryset = Product.objects.all()
serializer_class = ProductSerializer
permission_classes = [permissions.IsAuthenticated]

A differenza delle normali views fornite da Django, qui stiamo utilizzando il modulo viewsets fornito da rest_framework perchè ci tornerà molto utile in fase di creazione delle url come vedremo a breve.
Nota: viene utilizzato anche il modulo permissions così da garantire l’accesso alla nostra api esclusivamente tramite credenziali attraverso l’utilizzo del metodo IsAuthenticated
Le URL
Abbiamo quasi completato, dobbiamo solamente dire alla nostra applicazione quali sono le url di accesso. Apriamo ed editiamo il file urls.py che troviamo in ./api
from django.urls import include, path
from rest_framework import routers
from products import views
router = routers.DefaultRouter()
router.register(r'products', views.ProductViewSet)
# Aggiungiamo la nostra API al router.
# Ed in aggiunta, includiamo un URL di login via browser.
urlpatterns = [
path('', include(router.urls)),
path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
]
Poiché stiamo utilizzando il modulo viewsets invece del normale modulo views di django, possiamo generare automaticamente le configurazioni URL per la nostra API, semplicemente registrando le nostre viste al modulo routers fornito da rest_framework.
Nota: ho aggiunto un end-point extra: api-auth/.
Questo perchè il framework che stiamo utilizzando permette di default la consultazione delle nostre api. Quindi se vogliamo visualizzare o testare la nostra API via Browser, avremmo bisogno di un accesso tramite un form di login. Questo passaggio è del tutto facoltativo.
Salviamo il file.
Andiamo ad aggiungere il framework e la possibilità di paginare i risultati ed abbiamo finito la nostra API. Editiamo il file settings.py in ./api come segue:
# settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'products.apps.ProductsConfig',
'rest_framework', # aggiungiamo il framework
]
Posizioniamoci in fondo allo stesso file, ed aggiungiamo:
# settings.py
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 10
}
Salviamo ed andiamo a testare la nostra applicazione utilizzando il comando:
python manage.py runserver
Testare la nostra applicazione
Da riga di comando, eseguiamo una chiamata curl:
curl --location --request GET 'http://127.0.0.1:8000/products/' \
--header 'Authorization: Basic YWRtaW46UGFzc3dvcmQxMjM='
{
"count": 2,
"next": null,
"previous": null,
"results": [
{
"url": "http://127.0.0.1:8000/products/1/",
"title": "Prova",
"description": "lorem ipsum dolor sit amet",
"price": "12.50"
},
{
"url": "http://127.0.0.1:8000/products/2/",
"title": "Prova 2",
"description": "lorem ipsum dolor sit amet",
"price": "30.35"
}
]
}
Questo: YWRtaW46UGFzc3dvcmQxMjM= è il nostro base64 di admin:Password123 (le credenziali create come superuser)
Possiamo anche navigare le nostre API via Browser accedendo all’indirizzo: http://localhost:8000


One Comment
Giacomo
Bene, quanto meno sono riuscito a seguire e capire tutti i vari passaggi… adesso il difficile è familiarizzare con questa cosa e modificarla a piacimento.
Domanda:
ma se devo esporre semplicemente delle api di tipo get per fornire informazioni (no modifiche e cancellazioni) conviene usare comunque djangorestframework oppure mi semplifico la vita creando delle semplici viste che restituiscono un json con i dati richiesti?
Grazie