Ceci est un résumé du savoir-faire lors de la construction d'une base de connaissances + API Web avec NoSQL et PaaS.
Lors de la mise en œuvre d'une architecture appelée «base de connaissances des graphes non dirigés orientés balises de chaînes» Un exemple construit avec Heroku + Redis + FastAPI, Voici un exemple créé avec AWS (DynamoDB + Lambda + API Gateway).
Toutes les parties de code utilisent Python3.8.0
.
Il existe différentes définitions de la base de connaissances, mais dans cet article Désigne «une base de données qui stocke les connaissances dans un format lisible par ordinateur». Elle est également appelée «base de connaissances» «base de connaissances» KB ».
C'est la base de connaissances à construire à titre d'exemple cette fois. Je pense que c'est difficile à comprendre uniquement par le nom, j'ai donc préparé un diagramme d'image. (La visualisation n'étant pas implémentée, créez avec Mind Map Tool coggle)
En répétant l'opération simple de "stockage de deux chaînes de caractères" Il s'agit de former un système de connaissances de type dictionnaire (connaissance collective).
Et vous avez besoin d'une API Web pour la développer à une vitesse explosive.
Cette base de connaissances ne traite que des données de chaîne (et de son ensemble) Traitez toutes les chaînes comme des balises.
Dans l'exemple ci-dessus,
Nom du service Web```ID de compte
ʻURL titre de l'article` `concept
langage de programmation`
Chaque chaîne de caractères telle que est traitée comme une balise.
En raison des spécifications, la chaîne de caractères n'inclut pas d'espaces ni de caractères de saut de ligne.
Dans cette base de connaissances, nous essayons de connecter des balises associées.
Par exemple, la balise framework
Rails
Laravel
Django
Flask
Vous pouvez obtenir les données auxquelles le tag est lié,
Par exemple, les balises «Qiita» et «Python» sont liées.
https://qiita.com/1ntegrale9/items/94ec4437f763aa623965
Vous pouvez obtenir les données comme la balise (URL de l'article de Qiita sur Python).
Dans la figure ci-dessus, les sommets (chaînes de caractères) représentent les balises et les côtés représentent les relations. Et comme il ne convient pas, les deux peuvent être mentionnés. De plus, il n'y a pas de pondération car la relation d'inclusion n'est pas prise en compte.
Article de référence: Basics of Graph Theory --Qiita
Cette architecture n'est pas en circulation Inspiré de GraphQL, il a été conçu à l'origine.
C'est juste une enquête légère avec des mots-clés par GraphDB, donc Peut-être que cela existe déjà.
Si vous souhaitez l'utiliser facilement et gratuitement, utilisez-le.
Les paramètres initiaux de Heroku et les opérations de base de Redis sont expliqués ici. Introduction à NoSQL DB à partir de Heroku x Redis x Python --Qiita
KVS est en mémoire et rapide à lire et à écrire. Il prend également en charge la persistance. Je souhaite associer plusieurs balises à une seule balise, je n'utilise donc que le type collectif.
Comme il est géré par Python, utilisez redis-py.
python3 -m pip install redis hiredis
hiredis-py est un wrapper d'analyseur rapide pour l'implémentation C. Le côté redis-py détectera hiredis et basculera l'analyseur, alors mettez-le.
Initialisez la connexion avec le code suivant.
Utilisez la variable d'environnement REDIS_URL
que Heroku Redis définit automatiquement.
import redis, os
conn = redis.from_url(os.environ['REDIS_URL'], decode_responses=True)
Par défaut, il y a un problème avec l'affichage japonais, donc
decode_responses = True
est obligatoire.
Obtenez-le en utilisant keys ()
.
def get_all_tags():
return sorted(conn.keys())
Il est pratique de voir les balises dans une liste, alors soyez prêt. Cependant, veuillez noter que la charge augmente à mesure que l'échelle augmente.
Obtenez-le en utilisant smembers (key)
.
def get_related_tags(tag):
r.smembers(tag) if r.exists(tag) else []
Par précaution, si une balise qui n'existe pas est spécifiée, un tableau vide sera renvoyé. Utilisez ʻexists (key) `pour vérifier l'existence.
Utilisez sadd (clé, valeur)
pour stocker des données agrégées.
Je veux les lier dans les deux sens, donc j'échange les valeurs-clés et l'exécute deux fois.
def set_relation_tags(tag1, tag2):
return conn.pipeline().sadd(t1, t2).sadd(t2, t1).execute()
Redis prend en charge les transactions, pour redis-py
En chaînant de pipeline ()
à ʻexecute () `
L'exécution par lots dans une transaction est possible.
De plus, l'exécution atomique par la méthode pipeline semble être plus rapide que l'exécution individuelle. Utilisation efficace de Redis en Python (pour améliorer les performances de redis-py) - [Dd] enzow (ill)? Avec DB et Python / 08/212059)
FastAPI est l'un des frameworks Web de Python Vous pouvez implémenter une API Web simple avec moins de code La caractéristique est que le document API est généré automatiquement sans aucun paramètre.
Flask Répondeur Starlette DRF etc. sont au-dessus des spécifications, Au contraire, Bottle manquait de fonction, et l'API Fast était parfaite.
python3 -m pip install fastapi uvicorn email-validator
Uvicorn est un serveur ASGI rapide. Utilisé pour démarrer FastAPI. Ce n'est pas une faute de frappe dans Gunicorn.
Si vous n'incluez pas email-validator, vous vous fâcherez au démarrage. Pourquoi?
C'est très simple.
main.py
from fastapi import FastAPI
app = FastAPI()
Si vous définissez les arguments title
et discription
,
Le titre et la description seront reflétés dans le document API généré automatiquement comme l'image ci-dessus.
main.py
app = FastAPI(
title='collective-intelligence',
description='Base de connaissances de type graphique non orienté orienté balise de chaîne',
)
Vous pouvez également modifier l'URL du document API en spécifiant docs_url
.
La valeur par défaut est / docs
, mais c'est une bonne idée de la conserver en tant que root.
main.py
app = FastAPI(docs_url='/')
Écrivez simplement la méthode HTTP (GET), l'URL et la valeur de retour. Vous pouvez obtenir une réponse JSON en renvoyant une liste ou un dictionnaire.
main.py
@app.get('/api')
def read_all_tags():
return get_all_tags()
Cette définition est automatiquement reflétée dans le document API. Vous pouvez également exécuter la requête à partir de «Try it out» en haut à droite.
La balise est censée être une chaîne de caractères arbitraire comprenant des symboles, Étant donné que la chaîne de requête ne peut pas le gérer, laissez-le comme POST.
main.py
@app.post('/api/pull')
def read_related_tags(tag: str):
return get_related_tags(tag)
Le tag: str
spécifié dans l'argument est accepté à partir du corps de la requête.
L'annotation de type est jointe et elle est utilisée pour valider la demande.
S'il ne correspond pas, la réponse sera «422 Validation Error».
FastAPI s'appelle pydantic Contient une bibliothèque pour l'utilisation des annotations de type. Utilisez-le pour définir votre propre type et l'utiliser pour la validation.
main.py
from pydantic import BaseModel
class Tags(BaseModel):
tag1: str
tag2: str
@app.post('/api/push')
def create_tags_relationship(tags: Tags):
set_tags_relationship(tags.tag1, tags.tag2)
return {tag: get_related_tags(tag) for _, tag in tags}
Le type défini est reflété dans le document API en tant que schéma.
Commencez par l'Uvicorn introduit plus tôt.
Si vous avez initialisé avec ʻapp dans
main.py, spécifiez
main: app. Avec l'option
--reload`, il sera rechargé et reflété lorsque le fichier sera modifié.
$ uvicorn main:app --reload
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [57749]
INFO: Started server process [57752]
INFO: Waiting for application startup.
INFO: Application startup complete.
Lorsque vous accédez à http: //127.0.0.1: 8000
ou http: //127.0.0.1: 8000 / docs
,
Vous pouvez voir que le document API est affiché.
PaaS qui vous permet de déployer facilement des applications Web. Il prend en charge de nombreux langages et frameworks. PostgreSQL et Redis hébergent également jusqu'à une certaine limite gratuitement.
Tout d'abord, les étapes suivantes sont requises.
--Enregistrement du compte Heroku | Inscription
Vous aurez besoin des fichiers suivants: Ayez ceci dans votre référentiel GitHub.
$ tree
.
├── main.py #application
├── Procfile #Fichier de définition de commande d'exécution de processus
├── requirements.txt #Fichier de définition de bibliothèque dépendant
└── runtime.txt #Fichier de définition de version Python
Procfile
web: uvicorn main:app --host 0.0.0.0 --port $PORT
requirements.txt
fastapi
email-validator
uvicorn
redis
hiredis
runtime.txt
python-3.8.0
[Répertoire actuel](1ntegrale9 / collective-intelligence at heroku ) Reportez-vous également à.
Effectuez le déploiement à partir de l'onglet Déployer du tableau de bord.
Liez le référentiel en coopération avec GitHub et exécutez Manual Deploy
.
Si vous définissez également ʻAutomatic deploys`, il sera déployé automatiquement lorsque vous pousser vers master.
Une fois la construction terminée avec succès
Gardez le processus enregistré activé à partir de Configurer Dynos
.
Vous pouvez voir l'application déployée depuis «Ouvrir l'application» en haut à droite du tableau de bord.
Si vous êtes conscient de l'évolutivité, utilisez ceci. Il est également possible de modifier de manière flexible la structure des données.
Premier développement d'API utilisant Lambda et DynamoDB-Qiita API Gateway + Lambda + DynamoDB - Qiita
Comme avec RDB, une table et une clé primaire sont de base. La clé primaire est une clé qui identifie de manière unique les données et est soit une "clé de partition", soit Cela signifie "clé composite de la clé de partition et de la clé de tri". Vous pouvez assouplir les restrictions uniques sur les clés de partition en ajoutant des clés de tri.
Comment démarrer --Amazon DynamoDB | AWS Développement de la première application sans serveur - Créer une table dans DynamoDB- | Developers.IO Comprendre la capacité de DynamoDB à faire de votre mieux dans le cadre libre - Deux épées de l'informatique et de l'entraînement musculaire
Clé de partition: balise Clé de tri: horodatage
Développement de la première application sans serveur - Obtenir la valeur de DynamoDB avec Lambda- | Developers.IO Déploiement automatique sur AWS Lambda à l'aide d'actions GitHub (version détaillée + procédure de démonstration) --Qiita
La fonction lambda_handler est exécutée lors de l'appel de Lambda
import boto3, time
from decimal import Decimal
def lambda_handler(event, context):
timestamp = Decimal(time.time())
table = boto3.resource('dynamodb').Table('collective-intelligence')
with table.batch_writer() as batch: #Lot lorsque plusieurs met_Utiliser un écrivain
batch.put_item(Item={
'tag': event['tag1'],
'related_tag': event['tag2'],
'timestamp': timestamp
})
batch.put_item(Item={
'tag': event['tag2'],
'related_tag': event['tag1'],
'timestamp': timestamp
})
return {'statusCode': 201}
import boto3
from boto3.dynamodb.conditions import Key
def lambda_handler(event, context):
table = boto3.resource('dynamodb').Table('collective-intelligence')
response = table.query(KeyConditionExpression=Key('tag').eq(event['tag'])) #Recherche par spécification de balise
tags = set(item['related_tag'] for item in response['Items']) #Stocker dans le type d'ensemble et supprimer les doublons
return {'statusCode': 200, 'body': list(tags)} #Diffuser le type de liste pour la réponse JSON
Crée et gère des API Web
Développement du premier Lambda appelant une application sans serveur à partir d'API Gateway- | Developers.IO Création d'un environnement API Gateway pour apprendre tout en créant à partir de zéro | Developers.IO Tutoriel Amazon API Gateway - Amazon API Gateway
Créer un POST avec / push et / pull
Jouer avant d'exécuter Lambda peut réduire les coûts
--Définition du modèle (schéma JSON) --Settings-> Définir "Vérifier le corps" dans la validation de la demande
JSON Schema Tool Créer des modèles de mappage de demande et de réponse et des modèles de mappage - Amazon API Gateway (https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/models-mappings.html) J'ai essayé la nouvelle fonction Request Validation of API Gateway --MTI Engineer Blog
Vérifiez à partir de la facture sur l'écran de facturation.
Il n'est pas encore en production, À la suite de l'envoi et de la réception de centaines de demandes / réponses dans le test, il était de 0 yen, donc Il semble que vous ne devriez pas avoir peur de l'utiliser à des fins d'essai.
GCP vs AWS
J'étais inquiet pour GCP (Firestore) et AWS (DynamoDB), mais j'ai adopté DynamoDB.
Si vous choisissez du côté GCP, vous serez perturbé par les quatre services de stockage de données, Si vous l'utilisez comme passe-temps, je pense que vous devriez choisir Firestore. Sélectionnez une base de données: Cloud Firestore ou Realtime Database | Firebase
Ce sont principalement des auto-études, Je pense que les compétences pour acquérir de nouvelles compétences ont été acquises dans l'environnement moderne de l'entreprise. C'est une grande expérience pour un ingénieur fort de pouvoir travailler dans le domaine où les nouvelles technologies sont utilisées intensément.
De plus, la configuration côté Heroku est ouverte au public. Les données sont vides au moment de la publication, mais n'hésitez pas à y toucher. https://collective-intelligence.herokuapp.com/
Recommended Posts