[PYTHON] Création d'une API qui renvoie des résultats d'inférence négatifs-positifs à l'aide de BERT dans le framework Django REST

Cet article est l'article du 20e jour du "Calendrier de l'Avent Django 2019 - Qiita".

C'est siny.

Dans cet article, j'ai résumé les défis de la création d'une API Rest qui renvoie des résultats d'inférence négatifs-positifs à l'aide du ** Django REST framework ** et du ** BERT model **.

introduction

Cet article ne couvre pas les parties liées à l'implémentation du modèle BERT car Django est l'objectif principal. Pour la mise en œuvre et l'apprentissage du modèle BERT à l'aide de l'ensemble de données japonais utilisé dans cet article, voir [** Natural Language Processing Advent Calendar 2019 Day 25 (Creation of Negative-Positive Classifier Using BERT) **]( Veuillez consulter https://qiita.com/ysiny/items/b01250228e0c5cc0e647) ".

Tout d'abord, il s'agit d'un diagramme schématique du traitement global de l'environnement DRF supposé cette fois.

drf_bert.png

Ce que vous faites est simple, c'est une API REST qui déduit (classification binaire) si la phrase donnée en entrée est négative ou positive avec un modèle BERT et renvoie le résultat côté client.

[Vidéo de démonstration de l'API] BERT_DRF.gif

Les modules implémentés dans cet article peuvent être trouvés dans ce référentiel git, veuillez donc les télécharger et les utiliser comme il convient.

Concernant BERT, [Livre "Apprendre en créant! Apprentissage en profondeur développé par PyTorch"](https://www.amazon.co.jp/%E3%81%A4%E3%81%8F%E3%82%8A % E3% 81% AA% E3% 81% 8C% E3% 82% 89% E5% AD% A6% E3% 81% B6-PyTorch% E3% 81% AB% E3% 82% 88% E3% 82% 8B % E7% 99% BA% E5% B1% 95% E3% 83% 87% E3% 82% A3% E3% 83% BC% E3% 83% 97% E3% 83% A9% E3% 83% BC% E3 % 83% 8B% E3% 83% B3% E3% 82% B0-% E5% B0% 8F% E5% B7% 9D% E9% 9B% 84% E5% A4% AA% E9% 83% 8E / dp / Il a été créé en référence à 4839970254). Dans le livre ci-dessus, la classification négative / positive du modèle BERT était basée sur des données anglaises, nous l'avons donc améliorée afin qu'elle puisse être classée comme négative / positive dans l'ensemble de données japonais basé sur le livre.

table des matières

  1. Prémisse
  2. Construction de l'environnement
  3. Création d'un framework Django REST
  4. Inférence à l'aide de l'API REST
  5. Outil simple
  6. Résumé
  7. Ouvrages de référence

1. Prémisse

Il a été confirmé que le contenu de cet article fonctionne dans les environnements suivants.

Environnement local

article sens
OS Ubuntu sur Windows 10
Modèle BERT Publié par l'Université de Kyotopytorch-pretrained-Modèle BERTLe réglage fin est effectué en fonction de.
Analyse morphologique Juman++ (v2.0.0-rc2) or (v2.0.0-rc3)
Django 2.2.5
djangorestframework 3.10.3

2. Construction de l'environnement

Cette fois, nous allons créer un DRF qui fonctionne dans l'environnement Ubuntu de Windows 10. Tout d'abord, créez un environnement virtuel et installez les modules nécessaires avec conda.

Installation de divers modules


conda create -n drf python=3.6
conda activate drf
conda install pytorch=0.4 torchvision -c pytorch
conda install pytorch=0.4 torchvision cudatoolkit -c pytorch
conda install pandas scikit-learn django

Si conda ne fonctionne pas, installez-le avec pip.


pip install mojimoji
pip install attrdict
pip install torchtext
pip install pyknp
pip install djangorestframework

Installation de Juman ++

Le modèle pré-entraîné japonais BERT utilisé cette fois utilise Human ++ (v2.0.0-rc2) pour l'analyse morphologique du texte d'entrée, de sorte que cet article fait également correspondre l'outil d'analyse morphologique à ** Human ++ **. La procédure d'installation de Juman ++ est résumée dans un article séparé, veuillez donc vous référer à ce qui suit.

[** Résumé de la procédure d'installation de JUMAN ++ **] https://sinyblog.com/deaplearning/juman/

Après avoir installé Juman ++, il est OK si l'analyse morphologique est disponible dans l'environnement local comme suit.

#Contrôle du fonctionnement JUMAN
from pyknp import Juman					
text = "J'apprends le traitement du langage naturel."					
juman = Juman()					
result =juman.analysis(text)					
result = [mrph.midasi for mrph in result.mrph_list()]					
print(text)
J'apprends le traitement du langage naturel.
print(result)
['La nature', 'Langue', 'En traitement', 'À', 'sur', 'Apprentissage', 'Pendant ~', 'est', '。']			

3. Création d'un framework Django REST

Création de projet

Tout d'abord, créez un projet django. (Nom du projet: drf)

django-admin startproject drf

Création d'applications

Ensuite, créez une application (nom de l'application: appv1)

cd drf
python manage.py startapp appv1

Personnalisation de settings.py

Ajoutez rest_framework et application (appv1) à INSTALLED_APPS dans settings.py.

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',                #add
    'appv1.apps.Appv1Config',        #add

]

Placement des modules liés à BERT

Créez les dossiers suivants directement sous le dossier de l'application (appv1) et placez les modules comme spécifié.

Nom de dossier Module de placement Utilisation
vocab vocab.txt Fichier de dictionnaire de lexique BERT
weights bert_config.json Fichier de configuration BERT
weights pytorch_model.bin HP publié par l'Université de KyotoFichiertéléchargédepuis(modèleentraîné)
weights bert_fine_tuning_chABSA.pth BERT modèle formé au réglage fin
data **.4 fichiers tsv Données d'entraînement, données de test, etc.

Placez les fichiers suivants directement sous l'application (appv1).

nom de fichier sens
config.py Divers fichiers de paramètres
dataloader.py fichier de génération du chargeur de données torchtext
predict.py Pour raisonner
tokenizer.py Shell associé à la séparation de mots BERT
bert.py Définition du modèle BERT

Démarrez le mode shell de Django et générez un fichier de données de lexique à utiliser pour l'inférence.

python manage.py shell
from appv1.config import *
from appv1.predict import create_vocab_text
TEXT = create_vocab_text()

L'exécution de ce qui précède générera appv1 / data / text.pkl.

La structure générale des répertoires est la suivante.

├─drf
│  │  db.sqlite3
│  │  manage.py
│  │
│  ├─appv1
│  │  │  admin.py
│  │  │  apps.py
│  │  │  bert.py           #Définition du modèle BERT
│  │  │  config.py         #Divers fichiers de paramètres
│  │  │  dataloader.py     #fichier de génération du chargeur de données torchtext
│  │  │  models.py
│  │  │  predict.py        #Pour raisonner
│  │  │  serializers.py    #Sérialiseur
│  │  │  tests.py
│  │  │  tokenizer.py      #Shell associé à la séparation de mots BERT
│  │  │  views.py
│  │  ├─data

│  │  │      test_dumy.tsv  #Données factices
│  │  │      train_dumy.tsv #Données factices
│  │  │      text.pkl    #Données de Wordbook utilisées pour l'inférence
│  │  │
│  │  ├─vocab
│  │  │      vocab.txt   #Données du lexique de Bert
│  │  │
│  │  ├─weights
│  │  │      bert_config.json
│  │  │      bert_fine_tuning_chABSA.pth  #Modèle Bert ajusté
│  │  │      pytorch_model.bin
│  │  │
│  ├─drf
│  │  │  settings.py
│  │  │  urls.py
│  │  │  wsgi.py

Confirmation de l'opération d'inférence

Assurez-vous que le processus d'inférence fonctionne correctement en utilisant le modèle entraîné par BERT sur l'environnement django.

Après avoir démarré le mode shell de Django, exécutez la commande suivante pour donner des exemples de données de texte et confirmer qu'un jugement négatif ou positif peut être fait.

python manage.py shell
-----------------------------------------------------------------------------
#Mode Shell à partir d'ici
In [1]: from appv1.config import *
In [2]: from appv1.predict import predict2, create_vocab_text, build_bert_model
In [3]: from appv1.bert import get_config, BertModel,BertForchABSA, set_learned_params
In [4]: import torch
In [5]: config = get_config(file_path=BERT_CONFIG)  #Chargement des paramètres de configuration BERT
In [6]: net_bert = BertModel(config)   #Génération de modèles BERT
In [7]: net_trained = BertForchABSA(net_bert)   #Combinez le classificateur négatif / positif avec le modèle BERT
In [8]: net_trained.load_state_dict(torch.load(MODEL_FILE, map_location='cpu'))  #Faible poids appris
   ...:Faire
Out[8]: IncompatibleKeys(missing_keys=[], unexpected_keys=[])
In [9]: net_trained.eval()   #Mettre en mode inférence
Out[9]:
BertForchABSA(
  (bert): BertModel(
    (embeddings): BertEmbeddings(
      (word_embeddings): Embedding(32006, 768, padding_idx=0)
      (position_embeddings): Embedding(512, 768)
      (token_type_embeddings): Embedding(2, 768)
      (LayerNorm): BertLayerNorm()
      (dropout): Dropout(p=0.1)
    )
    (encoder): BertEncoder(
      (layer): ModuleList(
        (0): BertLayer(
          (attention): BertAttention(
            (selfattn): BertSelfAttention(
              (query): Linear(in_features=768, out_features=768, bias=True)
              (key): Linear(in_features=768, out_features=768, bias=True)
              (value): Linear(in_features=768, out_features=768, bias=True)
              (dropout): Dropout(p=0.1)
            )

 ~~Comme il existe de nombreux résultats de sortie, certains sont omis.

    (pooler): BertPooler(
      (dense): Linear(in_features=768, out_features=768, bias=True)
      (activation): Tanh()
    )
  )
  (cls): Linear(in_features=768, out_features=2, bias=True)
)

In [10]: input_text = "En termes de résultat, le résultat ordinaire est dû à une baisse des intérêts sur prêts et des gains sur cessions de titres.
    ...:Il a diminué de 7 273 millions de yens à 67 413 millions de yens."
In [11]: result = predict2(input_text, net_trained).numpy()[0]  #Exécuter l'inférence(La valeur de retour est négative ou positive
    ...:Tib)
['[UNK]', 'surface', 'À', 'OK je', 'sans parler de', 'Est', '、', '[UNK]', 'Revenu', 'Est', '、', 'Prêt', 'Argent', 'Intérêt', 'Ou', 'De valeur', 'Titres', 'vente', 'Profit', 'de', 'Diminution', 'À', 'Que', '、', 'Premier mandat', 'rapport', '[UNK]', 'Cercle', 'Diminution', 'de', '[UNK]', 'Cercle', 'Quand', 'Nari', 'Était']
[2, 1, 534, 8, 7779, 26207, 9, 6, 1, 7919, 9, 6, 15123, 306, 28611, 34, 27042, 4190, 3305, 8995, 5, 1586, 8, 52, 6, 4523, 2460, 1, 387, 1586, 5, 1, 387, 12, 105, 4561, 3]
In [12]: print(result)
0

Comme mentionné ci-dessus, si une valeur négative (0) ou positive (1) est renvoyée comme valeur de retour dans la variable de résultat sans aucune erreur, l'opération est OK.

Créer un sérialiseur

Ensuite, créez un sérialiseur DRF. En outre, la sérialisation et la désérialisation dans DRF sont les processus suivants.

En traitement sens
Sérialiser Conversion de chaînes JSON, etc. en objets de modèle Django
Désérialiser Conversion d'un objet de modèle au format JSON, etc.

Dans ce cas, le modèle de Django n'est pas géré, donc la conversion en objet modèle n'est pas effectuée. Au lieu de cela, créez un sérialiseur qui dit "** Recevez le texte d'entrée que vous voulez faire un jugement négatif / positif, entrez-le dans le modèle entraîné par BERT et sortez le résultat de l'inférence **".

Il existe trois principaux types de sérialiseurs DRF, mais cette fois, nous voulons implémenter un traitement personnalisé qui ne dépend pas du modèle, nous allons donc utiliser la ** classe Serializer ** de rest_framework.

|traitement du sérialiseur|sens| |:--|:--|:--|  | ModelSerializer       |Utiliser un seul objet modèle| |Serializer|Gérez une seule ressource ou implémentez un traitement personnalisé indépendant du modèle| |ListSerializer|Gérez plusieurs ressources|

Créez un fichier appelé serializers.py directement sous appv1 et ajoutez le code suivant.

appv1\serializers.py

from rest_framework import serializers
from appv1.config import *	
from appv1.predict import predict2
from appv1.bert import get_config, BertModel,BertForchABSA	
import torch		


class BertPredictSerializer(serializers.Serializer):
    """Sérialiseur pour obtenir des résultats de classification BERT négatifs / positifs"""

    input_text = serializers.CharField()
    neg_pos = serializers.SerializerMethodField()

    def get_neg_pos(self, obj):
        config = get_config(file_path=BERT_CONFIG)  #Chargement du fichier de configuration de bert
        net_bert = BertModel(config)  #Génération de modèles BERT
        net_trained = BertForchABSA(net_bert) # #Combinez le classificateur négatif / positif avec le modèle BERT
        net_trained.load_state_dict(torch.load(MODEL_FILE, map_location='cpu'))  #Charger les poids appris
        net_trained.eval()  #Mettre en mode inférence
        label = predict2(obj['input_text'], net_trained).numpy()[0]  #Obtenir le résultat de l'inférence
        return label

Tout d'abord, créez un sérialiseur appelé ** BertPredictSerializer ** en héritant de ** serializers.Serializer ** de rest_framework.

class BertPredictSerializer(serializers.Serializer):
    """Sérialiseur pour obtenir des résultats de classification BERT négatifs / positifs"""

    input_text = serializers.CharField()
    neg_pos = serializers.SerializerMethodField()

Un type de chaîne CharField est défini comme entrée (** input_text **). La sortie étant une valeur dynamique (résultat de l'inférence), la valeur du champ peut être déterminée par le résultat de la méthode. ** serializers.SerializerMethodField () ** est utilisé pour définir le champ ** neg_pos **. ..

Lorsque vous utilisez SerializerMethodField (), définissez le nom de la méthode appliquée comme ** get_ + field name **. Dans ce cas, nous définissons la méthode ** get_neg_pos **.

Si vous définissez un tel sérialiseur, la méthode get_neg_pos sera exécutée lorsque le texte d'entrée est POSTé dans la vue API à l'aide de BertPredictSerializer, et le résultat du traitement sera renvoyé sous forme de chaîne de caractères JSON.

Cette fois, nous voulons donner les données de phrase d'entrée au modèle d'apprentissage BERT et obtenir le résultat du jugement négatif / positif, le traitement suivant est donc décrit dans la méthode get_neg_pos.

    def get_neg_pos(self, obj):
        config = get_config(file_path=BERT_CONFIG)  #Chargement du fichier de configuration de bert
        net_bert = BertModel(config)  #Génération de modèles BERT
        net_trained = BertForchABSA(net_bert) # #Combinez le classificateur négatif / positif avec le modèle BERT
        net_trained.load_state_dict(torch.load(MODEL_FILE, map_location='cpu'))  #Charger les poids appris
        net_trained.eval()  #Mettre en mode inférence
        label = predict2(obj['input_text'], net_trained).numpy()[0]  #Obtenir le résultat de l'inférence
        return label

Vous pouvez voir ce que nous faisons en regardant les commentaires, mais je l'ajouterai ci-dessous.

Les quatre classes de méthodes ci-dessus sont définies dans ** bert.py **. Chargez les paramètres du modèle entraîné avec ** net_trained.load_state_dict **. La méthode ** predict2 ** est définie dans ** predict.py **, et si vous passez la phrase d'entrée ** dans le premier argument et l'instance de modèle entraîné ** dans le deuxième argument, ** infer C'est une méthode ** qui renvoie le résultat (0 ou 1).

Ceci termine la création du sérialiseur.

Créer une vue

La vue DRF peut être implémentée sous la forme d'une vue basée sur une classe ou d'une vue basée sur une fonction.

Cette fois, j'ai essayé d'utiliser une vue basée sur les classes appelée GenericAPIView.

from django.shortcuts import render
from rest_framework import generics, status
from rest_framework.response import Response
from appv1.serializers import BertPredictSerializer


class BertPredictAPIView(generics.GenericAPIView):
    """Classe de prédiction de classification négative / positive BERT"""
    serializer_class = BertPredictSerializer

    def post(self, request, *args, **kwargs):     

        serializer = self.get_serializer(request.data)
        return Response(serializer.data, status=status.HTTP_200_OK)

Il hérite de ** GenericAPIView ** et définit ** BertPredictAPIView **. Spécifiez la classe de sérialisation (BertPredictSerialzer) définie dans serializer.py dans l'attribut ** serializer_class **. Définissez ensuite la méthode ** post ** dans BertPredictAPIView et utilisez en interne la méthode ** get_serializer ** de GenericAPIView pour obtenir l'instance de sérialiseur utilisée pour la validation. Spécifiez ** request.data ** comme argument.

serializer = self.get_serializer(request.data)

** request.data ** fonctionne avec les méthodes "POST", "PUT" et "PATCH" pour traiter des données arbitraires. (Fonction similaire à request.POST) Enfin, spécifiez ** serializer.data ** comme argument de ** Response ** pour terminer la vue qui renvoie le résultat de l'inférence.

Définition de urls.py

Enfin, ajoutez la définition d'URL dans drf \ urlspy.

from django.contrib import admin
from django.urls import path
from appv1 import views  #add


urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/v1/predict/', views.BertPredictAPIView.as_view()),   #add
]

La vue d'API BertPredict définie dans views.py est définie comme un modèle d'URL appelé api / v1 / predict. Vous avez maintenant défini ** http://127.0.0.1/api/v1/predict ** comme point de terminaison de l'API Rest.

À ce stade, exécutez une fois la migration de djagno et exécutez runserver.

python manage.py migrate
python manage.py runserver

Après cela, lorsque vous accédez à ** http://127.0.0.1:8000/api/v1/predict/**, l'écran suivant s'affiche.

drf_bert_02.png

Entrez le texte que vous souhaitez juger négatif / positif dans "** input text **" en bas de l'écran et appuyez sur le bouton ** POST ** pour faire une inférence en utilisant le modèle entraîné de BERT et renvoyer le résultat. ..

L'écran suivant montre le résultat de la saisie de la phrase «Dans Tokyu Community Co., Ltd., le stock de gestion a augmenté pour les appartements et les immeubles, ce qui entraîne une augmentation des ventes et des bénéfices» et en appuyant sur le bouton POST.

drf_bert_03.png

En tant que valeur de retour, ** input_text ** et ** neg_pos (0 ou 1) ** représentant négatif / positif sont renvoyés.

Dans l'exemple ci-dessus, positif (= 1) est renvoyé comme résultat de l'inférence.

4. Inférence à l'aide de l'API REST

Ensuite, essayez d'appeler l'API REST créée à partir du client local et recevez le résultat de l'inférence. Cette fois, le client et le serveur sont simplement exécutés sur le même PC.

Après avoir démarré le serveur de développement avec python manage.py runserver, ouvrez l'écran DOS etc. dans une autre fenêtre et exécutez la commande python pour permettre d'exécuter le code python et d'exécuter le code suivant.

import urllib.request
import urllib.parse
import json
def predict(input_text):
    URL = "http://127.0.0.1:8000/api/v1/predict/"
    values = {
        "format": "json",
        "input_text": input_text,
        }
    data = urllib.parse.urlencode({'input_text': input_text}).encode('utf-8')
    request = urllib.request.Request(URL, data)
    response = urllib.request.urlopen(request)
    result= json.loads(response.read())
    return result

input_text = "En termes de résultat, le revenu ordinaire a diminué de 7 273 millions de yens par rapport à l'exercice précédent pour s'établir à 67 413 millions de yens en raison d'une baisse des intérêts sur les prêts et des gains sur les ventes de titres."
result = predict(input_text)
print(result)
{'input_text': 'En termes de résultat, le revenu ordinaire a diminué de 7 273 millions de yens par rapport à l'exercice précédent pour s'établir à 67 413 millions de yens en raison d'une baisse des intérêts sur les prêts et des gains sur les ventes de titres.', 'neg_pos': 0}
print(result['input_text'])
En termes de résultat, le revenu ordinaire a diminué de 7 273 millions de yens par rapport à l'exercice précédent pour s'établir à 67 413 millions de yens en raison d'une baisse des intérêts sur les prêts et des gains sur les ventes de titres.
print(result['neg_pos'])
0

Spécifiez ** "http://127.0.0.1:8000/api/v1/predict/"** comme point de terminaison. Donnez json comme format et input_text comme données d'entrée aux valeurs de variable de type dictionnaire.

Après cela, si vous le lancez avec la méthode POST avec les données de phrase encodées pour le point de terminaison à l'aide de urllib.request.Request, la classe BertPredictAPIView définie dans views.py sera appelée et le processus se déplacera dans le flux de sérialisation → exécution de l'inférence Aller. Je vais convertir le résultat du traitement avec json.loads afin qu'il puisse être traité comme des données de type dictionnaire du côté python.

Ensuite, il sera converti en données de type dictionnaire comme indiqué ci-dessous, afin que vous puissiez accéder aux informations souhaitées par nom de clé (input_text, neg_pos).

{'input_text': 'En termes de résultat, le revenu ordinaire a diminué de 7 273 millions de yens par rapport à l'exercice précédent pour s'établir à 67 413 millions de yens en raison d'une baisse des intérêts sur les prêts et des gains sur les ventes de titres.', 'neg_pos': 0}

5. Outil simple

Enfin, créez une commande simple qui envoie automatiquement une grande quantité de données d'entrée à l'API REST et génère le résultat de l'inférence. Les fichiers csv et les programmes utilisés ci-dessous sont sous django-drf-dl / drf / tools / dans git repository.

Préparez le fichier test.csv suivant que vous souhaitez prédire. (Le nom de la colonne est INPUT)

bert_testdata.png

Placez predict.py avec le code suivant dans le même dossier que test.csv.

import pandas as pd
import numpy as np
import urllib.request
import urllib.parse
import json

def predict(input_text):
    URL = "http://127.0.0.1:8000/api/v1/predict/"
    values = {
        "format": "json",
        "input_text": input_text,
            }
    data = urllib.parse.urlencode({'input_text': input_text}).encode('utf-8')
    request = urllib.request.Request(URL, data)
    response = urllib.request.urlopen(request)
    result= json.loads(response.read())
    return result['neg_pos'][1]	

if __name__ == '__main__':
    print("Start if __name__ == '__main__'")
    print('load csv file ....')
    df = pd.read_csv("test.csv", engine="python", encoding="utf-8-sig")
    df["PREDICT"] = np.nan   #Ajouter une colonne de prédiction
    print('Getting prediction results ....')
    for index, row in df.iterrows():
        df.at[index, "PREDICT"] = predict(row['INPUT'])
    print('save results to csv file')
    df.to_csv("predicted_test .csv", encoding="utf-8-sig", index=False)
    print('Processing terminated normally.')

Lorsque vous démarrez l'écran DOS et exécutez la commande suivante, test.csv est lu ligne par ligne et renvoyé à l'API REST pour recevoir le résultat de l'inférence.

python predict.py
----------------------------------
Start if __name__ == '__main__'
load csv file ....
Getting prediction results ....
save results to csv file
Processing terminated normally.

Lorsque les dernières données sont complétées, le fichier predicted_test.csv avec le résultat de l'inférence sera généré dans le même dossier.

bert_predict.png

6. Résumé

Cette fois, j'ai créé une API REST qui juge les négatifs et les positifs simples à l'aide d'un modèle de classification binaire de DRF et BERT dans l'environnement local. À l'avenir, j'aimerais créer une API REST sur la plate-forme Azure et l'appliquer à des tâches telles que la multi-classification et la FAQ au lieu de la classification binaire.

7. Ouvrages de référence

Le DRF créé dans cet article a été créé en appliquant un peu basé sur le contenu du manuel Django REST Framework qui peut être utilisé sur le terrain. J'ai appris DRF avec ce livre pour la première fois cette fois, mais c'est un livre très utile, donc il est recommandé pour ceux qui veulent apprendre DRF à partir de maintenant.

Demain, c'est l'article du 21e jour du "Calendrier de l'Avent Django 2019 - Qiita" par ssh22. Je vous remercie!

Recommended Posts

Création d'une API qui renvoie des résultats d'inférence négatifs-positifs à l'aide de BERT dans le framework Django REST
Je souhaite créer une API qui retourne un modèle avec une relation récursive dans Django REST Framework
[Django Rest Framework] Personnalisez la fonction de filtre à l'aide de Django-Filter
Comment écrire une validation personnalisée dans Django REST Framework
Comment réinitialiser le mot de passe via l'API à l'aide du framework Rest Django
Créez une application qui recherche uniquement à l'aide de l'API de recherche personnalisée Google avec Python 3.3.1 dans Bottle
Créer une API qui renvoie les données d'un modèle à l'aide de turicreate
Implémentation de la fonction d'authentification JWT dans Django REST Framework à l'aide de djoser
Implémentation de CRUD à l'aide de l'API REST avec Python + Django Rest framework + igGrid
Créer une API REST qui renvoie l'heure actuelle avec Python3 + Falcon
Créer une API REST pour faire fonctionner dynamodb avec le Framework Django REST
Développement et déploiement de l'API REST en Python à l'aide de Falcon Web Framework
Comment créer une application à partir du cloud à l'aide du framework Web Django
Essayez d'utiliser l'API Wunderlist en Python
Suppression logique dans Django, DRF (Django REST Framework)
Comprendre la commodité de Django Rest Framework
Essayez d'utiliser l'API Kraken avec Python
Notes diverses sur le framework Django REST
Tweet à l'aide de l'API Twitter en Python
Créer une application à l'aide de l'API Spotify
Essayez d'accéder à l'API Spotify dans Django.
Créez une API REST à l'aide du modèle appris dans Lobe et TensorFlow Serving.
Solution lorsque Not Found apparaît lors de la frappe de l'API de Django REST Framework de l'extérieur
Créez une application qui fonctionne bien avec les rapports des utilisateurs à l'aide de l'API COTOHA
Pour envoyer automatiquement des e-mails avec des pièces jointes à l'aide de l'API Gmail en Python
Bibliothèques à inclure lors de la création d'API dans l'environnement Django Rest Frakework, extensions vscode, etc. (pour les débutants)
Essayez d'utiliser l'API BitFlyer Ligntning en Python
Implémenter la fonctionnalité de connexion JWT dans le framework Django REST
Comment créer une API Rest dans Django
Implémentation de la fonction d'authentification dans Django REST Framework à l'aide de djoser
Essayez d'utiliser l'API DropBox Core avec Python
Développer une API Web qui renvoie les données stockées dans DB avec Django et SQLite