Python >> Tutoriel Python >  >> Python

Utilisation de Django et AssemblyAI pour des transcriptions d'appels Twilio plus précises

L'enregistrement d'appels téléphoniques avec un ou plusieurs participants est facile avec l'API vocale programmable de Twilio, mais la précision de la parole en texte peut être médiocre, en particulier pour la transcription de mots de domaines de niche tels que la santé et l'ingénierie. L'API de transcription d'AssemblyAI offre une précision beaucoup plus élevée par défaut et via listes de mots clés facultatifs.précision pour les enregistrements.

Dans ce didacticiel, nous allons enregistrer un enregistrement d'appel Twilio sortant vers l'API d'AssemblyAI pour obtenir une sortie parole-texte beaucoup plus précise.

Prérequis du didacticiel

Assurez-vous que Python 3 est installé, car Python 2 a atteint sa fin de vie au début de 2020 et n'est plus pris en charge. De préférence, vous devriez avoir Python 3.7 ou supérieur installé dans votre environnement de développement. Ce tutoriel utilisera également :

Nous utiliserons les dépendances suivantes pour terminer ce didacticiel :

  • Django version 3.1.x, où x est la dernière version de sécurité
  • Un compte Twilio et la bibliothèque d'aide Python Twilio version 6.45.2 ou ultérieure
  • demande la version 2.24.0
  • Un compte AssemblyAI, auquel vous pouvez vous inscrire pour obtenir une clé d'accès gratuite à l'API ici

Tout le code de cet article de blog est disponible en open source sous licence MIT sur GitHub sous le répertoire django-accurate-twilio-voice-transcriptions du référentiel blog-code-examples. Utilisez le code source comme vous le souhaitez pour vos propres projets.

Configuration de notre environnement de développement

Accédez au répertoire dans lequel vous conservez vos environnements virtuels Python.Créez un nouvel environnement virtuel pour ce projet à l'aide de la commande suivante.

Démarrez le projet Django en créant un nouvel environnement virtuel à l'aide de la commande suivante. Je recommande d'utiliser un répertoire séparé tel que ~/venvs/ (le tilde est un raccourci pour le home de votre utilisateur répertoire) afin que vous sachiez toujours où se trouvent tous vos environnements virtuels.

python3 -m venv ~/venvs/djtranscribe

Activez le virtualenv avec le activate script shell :

source ~/venvs/djtranscribe/bin/activate

Une fois la commande ci-dessus exécutée, l'invite de commande changera de sorte que le nom de virtualenv soit ajouté au format d'invite de commande d'origine, donc si votre invite est juste $ , il ressemblera maintenant à ceci :

(djtranscribe) $

N'oubliez pas que vous devez activer votre environnement virtuel dans chaque nouvelle fenêtre de terminal où vous souhaitez utiliser des dépendances dans l'environnement virtuel.

Nous pouvons maintenant installer le Djangopackage dans le virtualenv activé mais autrement vide.

pip install django==3.1.3 requests==2.24.0 twilio==6.45.2

Recherchez une sortie similaire à la suivante pour confirmer que les packages appropriés ont été correctement installés à partir de PyPI.

(djtranscribe) $ pip install django==3.1.3 requests==2.24.0 twilio=6.45.2
pip install django requests twilio
Collecting django
  Downloading Django-3.1.3-py3-none-any.whl (7.8 MB)
     |████████████████████████████████| 7.8 MB 2.6 MB/s 
Collecting requests
  Using cached requests-2.24.0-py2.py3-none-any.whl (61 kB)
Collecting twilio
  Downloading twilio-6.47.0.tar.gz (460 kB)
     |████████████████████████████████| 460 kB 19.6 MB/s 
Collecting sqlparse>=0.2.2
  Downloading sqlparse-0.4.1-py3-none-any.whl (42 kB)
     |████████████████████████████████| 42 kB 4.8 MB/s 
Collecting pytz
  Downloading pytz-2020.4-py2.py3-none-any.whl (509 kB)
     |████████████████████████████████| 509 kB 31.0 MB/s 
Collecting asgiref<4,>=3.2.10
  Downloading asgiref-3.3.0-py3-none-any.whl (19 kB)
Collecting chardet<4,>=3.0.2
  Using cached chardet-3.0.4-py2.py3-none-any.whl (133 kB)
Collecting idna<3,>=2.5
  Using cached idna-2.10-py2.py3-none-any.whl (58 kB)
Collecting certifi>=2017.4.17
  Using cached certifi-2020.6.20-py2.py3-none-any.whl (156 kB)
Collecting urllib3!=1.25.0,!=1.25.1,<1.26,>=1.21.1
  Downloading urllib3-1.25.11-py2.py3-none-any.whl (127 kB)
     |████████████████████████████████| 127 kB 24.5 MB/s 
Collecting six
  Using cached six-1.15.0-py2.py3-none-any.whl (10 kB)
Collecting PyJWT>=1.4.2
  Using cached PyJWT-1.7.1-py2.py3-none-any.whl (18 kB)
Using legacy 'setup.py install' for twilio, since package 'wheel' is not installed.
Installing collected packages: sqlparse, pytz, asgiref, django, chardet, idna, certifi, urllib3, requests, six, PyJWT, twilio
    Running setup.py install for twilio ... done
Successfully installed PyJWT-1.7.1 asgiref-3.3.0 certifi-2020.6.20 chardet-3.0.4 django-3.1.3 idna-2.10 pytz-2020.4 requests-2.24.0 six-1.15.0 sqlparse-0.4.1 twilio-6.47.0 urllib3-1.25.11

Nous pouvons commencer à coder l'application maintenant que toutes nos dépendances requises sont installées.

Démarrer notre projet Django

Commençons à coder notre application.

Nous pouvons utiliser le Django django-admin outil pour créer la structure de code passe-partout pour lancer notre projet. Allez dans le répertoire où vous développez vos applications. Par exemple, j'utilise généralement /Users/matt/devel/py/ pour tous les projets myPython. Exécutez ensuite la commande suivante pour démarrer un projet Django nommé djtranscribe :

django-admin.py startproject djtranscribe

Notez que dans ce didacticiel, nous utilisons le même nom pour le répertoire du projet virtualenv et Django, mais ils peuvent avoir des noms différents si vous préférez cela pour organiser vos propres projets.

Le django-admin la commande crée un répertoire nommé djtranscribe ainsi que plusieurs sous-répertoires que vous devriez connaître si vous avez déjà travaillé avec Django.

Modifiez les répertoires dans le nouveau projet.

cd djtranscribe

Créer une nouvelle application Django dans djtranscribe nommé caller .

python manage.py startapp caller

Django va générer un nouveau dossier nommé caller dans le projet. Nous devons mettre à jour les URL afin que l'application soit accessible avant d'écrire notre views.py code.

Ouvrez djtranscribe/djtranscribe/urls.py . Ajoutez les lignes en surbrillance pour que le résolveur d'URL vérifie le caller apppour des routes supplémentaires à faire correspondre avec les URL qui sont demandées à cette application Django.

# djtranscribe/djtranscribe/urls.py
from django.conf.urls import include
from django.contrib import admin
from django.urls import path


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

Économisez djtranscribe/djtranscribe/urls.py et ouvrezdjtranscribe/djtranscribe/settings.py .Ajouter le caller application à settings.py en insérant la ligne en surbrillance :

# djtranscribe/djtranscribe/settings.py
# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'caller',
]

Assurez-vous de changer le DEBUG par défaut et SECRET_KEY valeurs en settings.py avant de déployer du code en production. Sécurisez correctement votre application avec les informations des checklists de déploiement Djangoproduction afin de ne pas ajouter votre projet à la liste des applications piratées sur le web.

Enregistrez et fermez settings.py .

Prochain changement dans le djtranscribe/caller annuaire. Créez un nouveau fichier nommé urls.py pour contenir les routes pour le caller application.

Ajoutez toutes ces lignes au djtranscribe/caller/urls.py vide fichier.

# djtranscribe/caller/urls.py
from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'', views.index, name="index"),
]

Économisez djtranscribe/caller/urls.py . Ouvrirdjtranscribe/caller/views.py pour ajouter les deux lignes en surbrillance suivantes.

# djtranscribe/caller/views.py
from django.http import HttpResponse


def index(request):
    return HttpResponse('Hello, world!', 200)

Nous pouvons tester que cette simple réponse passe-partout est correcte avant de commencer à ajouter la viande de la fonctionnalité au projet. Allez dans le répertoire de base de votre projet Django où se trouve le manage.py fichier est localisé. Exécutez le serveur de développement avec la commande suivante :

python manage.py runserver

Le serveur de développement Django devrait démarrer sans problème autre qu'un avertissement de migrations non appliquées.

Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).

November 15, 2020 - 14:07:03
Django version 3.1.3, using settings 'djtranscribe.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

Ouvrez un navigateur Web et accédez à localhost:8000 .

Vous devriez voir "Hello, world!" rendu dans le navigateur. Cela signifie que tout fonctionne correctement jusqu'à présent et que nous pouvons maintenant ajouter les capacités de numérotation, d'enregistrement et de transcription à notre projet Django.

Ajout de Twilio au projet Django

Il est temps d'ajouter l'API vocale de Twilio dans le mix afin que nous puissions passer un appel téléphonique depuis notre projet Django et en faire un enregistrement.

Commencez par ouvrir djtranscribe/djtranscribe/settings.py et en le modifiant avec le import os en surbrillance suivant ligne :

# djtranscribe/djtranscribe/settings.py
import os
from pathlib import Path


# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent

Puis en bas du settings.py fichier, ajoutez les lignes en surbrillance suivantes, qui seront des paramètres extraits des variables d'environnement que nous configurerons plus tard.

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.1/howto/static-files/

STATIC_URL = '/static/'


BASE_URL = os.getenv("BASE_URL")
TWIML_INSTRUCTIONS_URL = "{}/record/".format(BASE_URL)
TWILIO_PHONE_NUMBER = os.getenv("TWILIO_PHONE_NUMBER")

Enregistrer settings.py et changez en caller Répertoire des applications Django.

Mettre à jour djtranscribe/caller/urls.py avec le nouveau code suivant :

# djtranscribe/caller/urls.py
from django.conf.urls import url 
from . import views

urlpatterns = [ 
    url(r'dial/(\d+)/$', views.dial, name="dial"),
    url(r'record/$', views.record_twiml, name="record-twiml"),
    url(r'get-recording-url/([A-Za-z0-9]+)/$', views.get_recording_url,
        name='recording-url'),
]

Ensuite, ouvrez djtranscribe/views.py et mettez-le à jour avec le code suivant, en remplaçant ce qui existe déjà dans le fichier :

# djtranscribe/caller/views.py
from django.conf import settings
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt

from twilio.rest import Client
from twilio.twiml.voice_response import VoiceResponse


def dial(request, phone_number):
    """Dials an outbound phone call to the number in the URL. Just
    as a heads up you will never want to leave a URL like this exposed
    without authentication and further phone number format verification.
    phone_number should be just the digits with the country code first,
    for example 14155559812."""
    # pulls credentials from environment variables
    twilio_client = Client()
    call = twilio_client.calls.create(
            to='+{}'.format(phone_number),
            from_=settings.TWILIO_PHONE_NUMBER,
            url=settings.TWIML_INSTRUCTIONS_URL,
    )   
    print(call.sid)
    return HttpResponse("dialing +{}. call SID is: {}".format(
                            phone_number, call.sid))


@csrf_exempt
def record_twiml(request):
    """Returns TwiML which prompts the caller to record a message"""
    # Start our TwiML response
    response = VoiceResponse()

    # Use <Say> to give the caller some instructions
    response.say('Ahoy! Call recording starts now.')

    # Use <Record> to record the caller's message
    response.record()

    # End the call with <Hangup>
    response.hangup()

    return HttpResponse(str(response), content_type='application/xml')


def get_recording_url(request, call_sid):
    """Returns an HttpResponse with plain text of the link to one or more
    recordings from the specified Call SID."""
    # pulls credentials from environment variables
    twilio_client = Client()
    recording_urls = ""
    call = twilio_client.calls.get(call_sid)
    for r in call.recordings.list():
        recording_urls="\n".join([recording_urls, "".join(['https://api.twilio.com', r.uri])])
    return HttpResponse(str(recording_urls), 200)

Chacune des fonctions d'affichage ci-dessus effectue l'une des étapes nécessaires pour créer un enregistrement d'appel d'un appel téléphonique composé par Twilio, puis le récupérer sous forme de fichier. dial lance par programmation l'appel sortant, record_twiml renvoie des instructions pour lire un message indiquant que l'appel est en cours d'enregistrement, l'enregistre, puis raccroche lorsque l'appel est terminé. get_recording_url ne renvoie que l'emplacement de l'URL de l'appel téléphonique enregistré afin qu'à l'étape suivante, nous puissions envoyer le fichier à AssemblyAI.

Les modifications de notre projet Django sont terminées. Ensuite, nous devons utiliser deux services, Twilio et Ngrok, pour permettre à une partie de la machine de passer des appels téléphoniques et d'exécuter l'application depuis notre machine locale.

Identifiants Twilio et variables d'environnement

Inscrivez-vous à Twilio ou connectez-vous à votre compte existant. Une fois dans la console Twilio, vous pouvez obtenir votre TWILIO_ACCOUNT_SID et TWILIO_AUTH_TOKEN sur le côté droit de la page :

Lorsque vous vous inscrivez, un numéro de téléphone doit être attribué à votre compte. Vous pouvez l'utiliser ou acheter un nouveau numéro de téléphone à utiliser.

Définissez trois variables d'environnement avec les noms TWILIO_ACCOUNT_SID ,TWILIO_AUTH_TOKEN , et TWILIO_PHONE_NUMBER en utilisant le export commande dans votre terminal. Assurez-vous de remplacer les valeurs par vos propres SID de compte, jeton d'authentification et numéro de téléphone Twilio.

export TWILIO_ACCOUNT_SID=xxxxxxxxxxxxx    # found in twilio.com/console
export TWILIO_AUTH_TOKEN=yyyyyyyyyyyyyy    # found in twilio.com/console
export TWILIO_PHONE_NUMBER=+17166382453    # replace with your Twilio number

Notez que vous devez utiliser le export commande dans chaque fenêtre de ligne de commande pour laquelle vous souhaitez que cette clé soit accessible. Les scripts que nous écrivons ne pourront pas accéder aux API Twilio si vous n'avez pas exporté les jetons dans l'environnement où vous exécutez le script.

Il reste une variable d'environnement à définir avant de pouvoir exécuter app.py .Nous devons utiliser Ngrok comme tunnel localhost afin que le webhook de Twilio puisse envoyer une requête HTTP POST à ​​notre application Django exécutée sur notre environnement de développement local.

Exécutez Ngrok dans une nouvelle fenêtre de terminal, car vous devrez continuer à l'exécuter pendant que nous exécutons notre autre code Python :

./ngrok http 8000

Copiez la version HTTPS de l'URL "Transfert" et définissez le BASE_URL la valeur de la variable d'environnement. Par exemple, dans cette capture d'écran, vous définiriez BASE_URL à https://7764c1810ad3.ngrok.io à l'aide de la commande suivante :

export BASE_URL=https://7764c1810ad3.ngrok.io    # use your ngrok URL, or domain. no trailing slash

Nous devons également mettre à jour djtranscribe/djtranscribe/settings.py estALLOWED_HOSTS liste pour inclure l'URL de transfert Ngrok, sinon le webhook de Twilio demandant des instructions sur la façon de gérer l'appel téléphonique échouera. Ouvrez le settings.py fichier et mettre à jour le ALLOWED_HOSTS avec votre nom d'hôte Ngrok Forwarding, indiquez ce qui suit :

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.getenv('SECRET_KEY', 'development key')

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = ['7764c1810ad3.ngrok.io','127.0.0.1','localhost']


# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'caller',
]

D'accord, nous pouvons enfin relancer notre application Web Django. Assurez-vous que Ngrok est toujours en cours d'exécution dans une fenêtre différente, que votre virtualenv est actif et que dans ce terminal vous avez défini vos quatre variables d'environnement, puis exécutez le runserver commande dans le répertoire racine du projet où manage.py est situé :

python manage.py runserver

Faisons sonner notre téléphone en testant l'application.

Test de l'enregistrement vocal programmable Twilio

Nous pouvons tester notre application en allant sur localhost sur le port 8000. Allez sur cette URL dans votre navigateur web, en remplaçant le "14155551234" par le numéro de téléphone que vous souhaitez appeler, où la personne en ligne sera enregistrée :http://localhost :8000/composer/14155551234.

Ce numéro devrait maintenant recevoir un appel téléphonique de votre Twilionumber. Décrochez, enregistrez un message que vous souhaitez utiliser pour tester la transcription, puis raccrochez.

Si vous obtenez une erreur, assurez-vous que toutes vos variables d'environnement sont définies. Vous pouvez vérifier les valeurs en utilisant la commande echo comme ceci :

echo $BASE_URL

Lorsque l'appel est terminé, copiez l'émission SID d'appel sur les pages Web afin que nous puissions l'utiliser pour rechercher où le fichier audio d'enregistrement est stocké.

Allez dans "localhost:8000/get-recording-url/" avec le SID d'appel à la fin. Par exemple,"localhost:8000/get-recording-url/CAda3f2f49ff4e8ef2be6b726edb998c92".

Copiez l'intégralité de la sortie à l'exception du ".json" à la fin, puis collez-la dans la barre d'URL du navigateur Web, précédée de "api.twilio.com". Par exemple, "https://api.twilio.com/2010- 04-01/Accounts/ACe3737affa0d2e17561ad44c9d190e70c/Recordings/RE3b42cf470bef829c3680ded961a09300 ". Copiez l'intégralité de l'URL et nous l'utiliserons comme entrée dans le service AssemblyAI.

Transcrire avec l'API AssemblyAI

Nous pouvons maintenant utiliser l'API AssemblyAI pour la transcription de la parole en texte sur l'enregistrement de l'appel qui vient d'être effectué.

Créez un compte AssemblyAI et connectez-vous au tableau de bord AssemblyAI, puis copiez "Votre jeton API" comme indiqué dans cette capture d'écran :

Nous devons exporter notre clé API AssemblyAI en tant que variables d'environnement afin que notre application Python puisse l'utiliser pour s'authentifier auprès de son API. Nous devons également transmettre l'URL accessible au public pour l'enregistrement, nous allons donc également la définir comme variable d'environnement.

# make sure to replace this URL with the one for your recording
export ASSEMBLYAI_KEY=your-api-key-here
export RECORDING_URL=https://api.twilio.com/2010-04-01/Accounts/ACe3737affa0d2e17561ad44c9d190e70c/Recordings/RE3b42cf470bef829c3680ded961a09300

Créez un nouveau fichier nommé transcribe.py et écrivez-y le code suivant :

import os
import requests

endpoint = "https://api.assemblyai.com/v2/transcript"

json = {
  "audio_url": os.getenv("RECORDING_URL")
}

headers = {
    "authorization": os.getenv("ASSEMBLYAI_KEY"),
    "content-type": "application/json"
}

response = requests.post(endpoint, json=json, headers=headers)

print(response.json())

Le code ci-dessus appelle le service de transcription AssemblyAI à l'aide de la clé secrète et lui transmet l'URL avec l'enregistrement du fichier. Le script imprime la réponse JSON du service, qui contiendra un ID de transcription que nous utiliserons pour accéder aux résultats une fois le traitement terminé. .

Exécutez le script en utilisant le python commande :

python transcribe.py

Vous récupérerez du JSON en sortie, similaire à ce que vous voyez ici :

{'audio_end_at': None, 'acoustic_model': 'assemblyai_default', 'text': None, 'audio_url': 'https://api.twilio.com/2010-04-01/Accounts/ACe3737affa0d2e17561ad44c9d190e70c/Recordings/RE3b42cf470bef829c3680ded961a09300', 'speed_boost': False, 'language_model': 'assemblyai_default', 'redact_pii': False, 'confidence': None, 'webhook_status_code': None, 'id': 'zibe9vwmx-82ce-476c-85a7-e82c09c67daf', 'status': 'queued',
'boost_param': None, 'words': None, 'format_text': True, 'webhook_url': None, 'punctuate': True, 'utterances': None, 'audio_duration': None, 'auto_highlights': False, 'word_boost': [], 'dual_channel': None, 'audio_start_from': None}

Trouver la valeur contenue avec le id champ de la réponse JSON. Nous avons besoin de cette valeur pour rechercher le résultat final de notre transcription. Copiez l'ID de transcription et définissez-le comme variable d'environnement à utiliser comme entrée par le script final :

# replace with what's found within `id` from the JSON response
export TRANSCRIPTION_ID=aksd19vwmx-82ce-476c-85a7-e82c09c67daf

Nous avons juste besoin d'un peu plus de Python qui recherche le résultat et nous aurons fini.

Récupérer la transcription AssemblyAI

AssemblyAI sera occupé à transcrire l'enregistrement. Selon la taille du fichier, cela peut prendre de quelques secondes à quelques minutes pour que le travail soit terminé. Nous pouvons utiliser le code suivant pour voir si le travail est toujours en cours ou s'il est terminé. Si la transcription est terminée, les résultats seront imprimés sur le terminal.

Créez un nouveau fichier nommé print_transcription.py avec le code suivant :

import os
import requests

endpoint = "https://api.assemblyai.com/v2/transcript/{}".format(os.getenv("TRANSCRIPTION_ID"))

headers = {
    "authorization": os.getenv("ASSEMBLYAI_KEY"),
}

response = requests.get(endpoint, headers=headers)

print(response.json())
print("\n\n")
print(response.json()['text'])

Le code ci-dessus en print_transcription.py est très similaire au code du précédent transcribe.py fichier source. importe os (système d'exploitation) de la bibliothèque standard Python, comme nous l'avons fait dans les deux fichiers précédents, pour obtenir le TRANSCRIPTION_ID et ASSEMBLYAI_KEY valeurs des variables d'environnement.

Le endpoint est le point de terminaison de l'API AssemblyAI pour la récupération des transcriptions. Nous définissons le authorization approprié header et faire l'appel API en utilisant le requests.get fonction. Nous imprimons ensuite la réponse JSON ainsi que le texte qui a été transcrit.

Il est temps de tester ce troisième fichier. Exécutez la commande suivante dans le terminal :

python print_transcription.py

Votre sortie sera différente en fonction de votre enregistrement, mais vous devriez voir un résultat dans le terminal similaire à ce qui suit :

{'audio_end_at': None, 'acoustic_model': 'assemblyai_default', 'auto_highlights_result': None, 'text': 'An object relational mapper is a code library that automates the transfer of data stored in a relational database tables into objects that are more commonly used in application. Code or MS provide a high level abstraction upon a relational database that allows the developer to write Python code. Instead of sequel to create read update and delete data and schemas in their database developers can use the programming language that they are comfortable with comfortable to work with the database instead of writing sequel statements or short procedures.', 'audio_url': 'https://api.twilio.com/2010-04-01/Accounts/ACe3737affa0d2e17561ad44c9d190e70c/Recordings/RE3b42cf470bef829c3680ded961a09300', 'speed_boost': False, 'language_model': 'assemblyai_default', 'id': 'zibe9vwmx-82ce-476c-85a7-e82c09c67daf', 'confidence': 0.931797752808989, 'webhook_status_code': None, 'status': 'completed', 'boost_param': None, 'redact_pii': False, 'words': [{'text': 'An', 'confidence': 1.0, 'end': 90, 'start': 0}, {'text': 'object', 'confidence': 0.94, 'end': 570, 'start': 210}, {'text': 'relational', 'confidence': 0.89, 'end': 1080, 'start': 510}, {'text': 'mapper', 'confidence': 0.97, 'end': 1380, 'start': 1020}, {'text': 'is', 'confidence': 0.88, 'end': 1560, 'start': 1350}, {'text': 'a', 'confidence': 0.99, 'end': 1620, 'start': 1500}, {'text': 'code', 'confidence': 0.93, 'end': 1920, 'start': 1620}, {'text': 'library', 'confidence': 0.94, 'end': 2250, 'start': 1860}, {'text': 'that', 'confidence': 0.99, 'end': 2490, 'start': 2220}, {'text': 'automates', 'confidence': 0.93, 'end': 2940, 'start': 2430}, {'text': 'the', 'confidence': 0.95, 'end': 3150, 'start': 2910}, {'text': 'transfer', 'confidence': 0.98, 'end': 3510, 'start': 3090}, {'text': 'of', 'confidence':
0.99, 'end': 3660, 'start': 3480}, {'text': 'data', 'confidence': 0.84, 'end': 3960, 'start': 3630}, {'text': 'stored', 'confidence': 0.89, 'end': 4350, 'start': 3900}, {'text': 'in', 'confidence': 0.98, 'end': 4500, 'start': 4290}, {'text': 'a', 'confidence': 0.85, 'end': 4560, 'start': 4440}, {'text': 'relational', 'confidence': 0.87, 'end': 5580, 'start': 4500}, {'text': 'database', 'confidence': 0.92, 'end':
6030, 'start': 5520}, {'text': 'tables', 'confidence': 0.93, 'end': 6330, 'start': 5970}, {'text': 'into', 'confidence': 0.92, 'end': 7130, 'start': 6560}, {'text': 'objects', 'confidence': 0.96, 'end': 7490, 'start': 7100}, {'text': 'that', 'confidence': 0.97, 'end': 7700, 'start': 7430}, {'text': 'are', 'confidence': 0.9, 'end': 7850, 'start': 7640}, {'text': 'more', 'confidence': 0.97, 'end': 8030, 'start': 7790}, {'text': 'commonly', 'confidence': 0.92, 'end': 8480, 'start': 7970}, {'text': 'used', 'confidence': 0.86, 'end': 8750, 'start': 8420}, {'text': 'in', 'confidence': 0.94, 'end': 9050, 'start': 8840}, {'text': 'application.', 'confidence': 0.98, 'end': 9860, 'start': 9110}, {'text': 'Code', 'confidence': 0.93, 'end': 10040, 'start': 9830}, {'text': 'or', 'confidence': 1.0, 'end': 11210, 'start': 10220}, {'text': 'MS', 'confidence': 0.83, 'end': 11480, 'start': 11180}, {'text': 'provide', 'confidence': 0.94, 'end': 11870, 'start': 11510}, {'text': 'a', 'confidence': 1.0, 'end': 11960, 'start': 11840}, {'text': 'high', 'confidence': 1.0, 'end': 12200, 'start': 11930}, {'text': 'level', 'confidence': 0.94, 'end': 12440, 'start': 12170}, {'text': 'abstraction', 'confidence': 0.95, 'end': 12980, 'start': 12410}, {'text':
'upon', 'confidence': 0.94, 'end': 13220, 'start': 12950}, {'text': 'a', 'confidence': 1.0, 'end': 13280, 'start': 13160}, {'text': 'relational', 'confidence': 0.94, 'end': 13820, 'start': 13280}, {'text': 'database', 'confidence': 0.95, 'end': 14210, 'start': 13790}, {'text': 'that', 'confidence': 0.96, 'end': 14420, 'start': 14150}, {'text': 'allows', 'confidence': 0.99, 'end': 14720, 'start': 14360}, {'text':
'the', 'confidence': 0.56, 'end': 14870, 'start': 14690}, {'text': 'developer', 'confidence': 0.98, 'end': 15290, 'start': 14810}, {'text': 'to', 'confidence': 0.94, 'end': 15410, 'start': 15230}, {'text': 'write', 'confidence': 0.96, 'end': 15680, 'start': 15380}, {'text': 'Python', 'confidence': 0.94, 'end': 16070, 'start': 15620}, {'text': 'code.', 'confidence': 0.98, 'end': 16310, 'start': 16070}, {'text': 'Instead', 'confidence': 0.97, 'end': 17160, 'start': 16500}, {'text': 'of', 'confidence': 0.93, 'end': 17340, 'start': 17130}, {'text': 'sequel', 'confidence': 0.86, 'end': 17820, 'start': 17280}, {'text': 'to', 'confidence': 0.91, 'end': 18090, 'start': 17880}, {'text': 'create', 'confidence': 0.89, 'end': 18450, 'start': 18090}, {'text': 'read', 'confidence': 0.88, 'end': 18840, 'start': 18480}, {'text': 'update', 'confidence': 0.92, 'end': 19290, 'start': 18870}, {'text': 'and', 'confidence': 0.94, 'end': 19590, 'start': 19230}, {'text': 'delete', 'confidence': 0.89, 'end': 19920, 'start': 19530}, {'text': 'data',
'confidence': 0.95, 'end': 20190, 'start': 19890}, {'text': 'and', 'confidence': 0.92, 'end': 20490, 'start': 20250}, {'text': 'schemas', 'confidence': 0.86, 'end': 21000, 'start': 20430}, {'text': 'in', 'confidence': 0.94, 'end': 21210, 'start': 21000}, {'text': 'their', 'confidence': 0.98, 'end': 21510, 'start': 21150}, {'text': 'database', 'confidence': 0.97, 'end': 21900, 'start': 21450}, {'text': 'developers', 'confidence': 0.83, 'end': 23200, 'start': 22420}, {'text': 'can', 'confidence': 0.95, 'end': 23440, 'start': 23200}, {'text': 'use', 'confidence': 0.97, 'end': 23650, 'start': 23410}, {'text': 'the', 'confidence': 0.99, 'end': 23890, 'start': 23590}, {'text': 'programming', 'confidence': 0.97, 'end': 24370, 'start': 23830}, {'text': 'language', 'confidence': 1.0, 'end': 24700, 'start': 24310}, {'text': 'that', 'confidence': 1.0, 'end': 24880, 'start': 24640}, {'text': 'they', 'confidence': 0.99, 'end': 25060, 'start': 24820}, {'text': 'are', 'confidence': 0.85, 'end': 25210, 'start': 25000}, {'text': 'comfortable', 'confidence': 0.92, 'end': 25780, 'start': 25180}, {'text': 'with', 'confidence': 1.0, 'end': 25960, 'start': 25720}, {'text': 'comfortable', 'confidence': 0.94, 'end': 29090, 'start': 28090}, {'text': 'to', 'confidence': 0.84, 'end': 29840, 'start': 29180}, {'text': 'work', 'confidence': 0.95, 'end': 30050, 'start': 29780}, {'text': 'with', 'confidence': 0.98, 'end': 30290, 'start': 30020}, {'text': 'the', 'confidence': 0.69, 'end': 30440, 'start': 30230}, {'text': 'database', 'confidence': 0.98, 'end': 30860, 'start': 30380}, {'text': 'instead', 'confidence': 1.0, 'end': 32780, 'start': 31780}, {'text': 'of', 'confidence': 0.98, 'end': 32900, 'start': 32720}, {'text': 'writing', 'confidence': 0.87, 'end': 33320, 'start': 32870}, {'text': 'sequel', 'confidence': 0.88, 'end': 33860, 'start': 33290}, {'text': 'statements', 'confidence': 0.95, 'end': 34310, 'start': 33800}, {'text': 'or', 'confidence': 0.9, 'end': 34460, 'start': 34250}, {'text': 'short', 'confidence': 0.9, 'end': 34790, 'start': 34430}, {'text': 'procedures.', 'confidence': 0.98, 'end': 35270, 'start': 34760}], 'format_text': True, 'webhook_url': None, 'punctuate': True, 'utterances': None, 'audio_duration': 36.288, 'auto_highlights': False, 'word_boost': [],
'dual_channel': None, 'audio_start_from': None}


An object relational mapper is a code library that automates the transfer of data stored in a relational database tables into objects that are more commonly used in application. Code or MS provide a high level abstraction upon a relational database that allows the developer to write Python code. Instead of sequel to create read update and delete data and schemas in their database developers can use the programming language that they are comfortable with comfortable to work with the database instead of writing sequel statements or short procedures.

C'est beaucoup de sortie. La première partie contient les résultats de la transcription et la confiance dans l'exactitude de chaque mot transcrit. La deuxième partie est juste la sortie en texte brut de la transcription.

Vous pouvez maintenant utiliser ce code de base et l'ajouter à toute application nécessitant une transcription de synthèse vocale de haute qualité. Si les résultats ne vous conviennent pas encore, consultez ce didacticiel sur l'amélioration de la précision des mots clés ou des expressions.

Ressources supplémentaires

Nous venons de terminer la création d'une application de transcription extrêmement précise pour les enregistrements.

Ensuite, essayez quelques-uns de ces autres tutoriels Django connexes :

  • Utilisation de Sentry pour gérer les exceptions Python dans les projets Django
  • Suivre les données utilisateur quotidiennes dans Django avec django-user-visit
  • Comment utiliser rapidement Bootstrap 4 dans un modèle Django avec un CDN

Des questions? Faites-le moi savoir via un ticket de problème GitHub sur le référentiel Full Stack Python, sur Twitter@fullstackpython ou @mattmakai.Vous voyez quelque chose qui ne va pas avec ce message ? La source de cette page sur GitHuband soumet une pull request.