Lyricize: Eine Flask-App zum Erstellen von Texten mit Markov-Ketten

Lyricize: Eine Flask-App zum Erstellen von Texten mit Markov-Ketten

Neue Codierer are looking http://www.reddit.com/r/learnpython/comments/1a9yie/worked_with_python_for_almost_a_year_now_to: reddit.com/r/learnpython/comments/1iqv3c/please_help_me_prepare_a_roadmap_as_to_what_i/[new] http://www.reddit.com/r/learnpython/comments/1czbfw/kinda_lostwhat_to_do_ Das Erstellen eines eigenen side-Projekts ist nicht nur der beste Weg, um praktische Erfahrungen zu sammeln, sondern auch, wenn Sie den Schritt von einem machen möchten Hobby zu einem Beruf, dann sind Nebenprojekte eine großartige Möglichkeit, um ein Portfolio von Arbeiten aufzubauen.

Von der Idee zum MVP

In diesem Beitrag werden wir den Prozess der Einführung eines (absoluten) MVP durcharbeiten, von der ersten Konzeption der Idee bis hin zu einem gemeinsam nutzbaren Prototyp. Am Ende haben Sie Ihre eigene Version von http://lyricize.herokuapp.com [Lyricize] erstellt, einer kleinen App, die die Texte eines Künstlers oder einer Band verwendet, um basierend auf Wahrscheinlichkeiten „neue“ ähnlich klingende Texte zu generieren. Anstatt das typische Tutorial "Hier erfahren Sie, wie Sie den gesamten Code replizieren" zu präsentieren, werden wir Schritt für Schritt durch den Prozess gehen, um zu zeigen, was tatsächlich am Denkprozess und an der Erstellung beteiligt ist.

_ Beachten Sie, dass es nicht unbedingt darum geht, das nächste Killer-Startup zu erstellen. Wir suchen nur nach einem Projekt, das 1) eine unterhaltsame Lernmöglichkeit und 2) mit anderen geteilt werden kann. _

*Bevor wir beginnen, schauen Sie sich das Beispiel http://lyricize.herokuapp.com [App] an, um zu sehen, was Sie erstellen werden.* Im Wesentlichen können Sie mithilfe von Markov-Ketten neue Texte basierend auf den Texten eines bestimmten Künstlers generieren. Versuchen Sie beispielsweise, nach „Bob Dylan“ zu suchen, und ändern Sie die Anzahl der Zeilen in drei. Ziemlich cool, oder? Ich habe gerade die gleiche Suche ausgeführt, die zu folgenden Ergebnissen führte:
*Dort drüben steht dein Versprechen für alle und Boote* + *Ich bin bereit für die Schlucht* + *Ich bin ein Haken*

So tief. Wie auch immer, fangen wir an …​

Finden Sie ein Thema von Interesse

Schritt 1: Suchen Sie ein Thema, über das Sie mehr erfahren möchten. Die folgende App wurde von einer alten college Assignment (zugegebenermaßen nicht die häufigste Inspirationsquelle) inspiriert, die Markov verwendet Ketten, um „echt aussehenden“ Text zu generieren, wenn ein Beispieltext vorhanden ist. Markov-Modelle tauchen in http://en.wikipedia.org/wiki/Markov_chain#Applications[Alle Arten von Szenarien auf. (Wir werden in Kürze untersuchen, was ein Markov-Modell ist.) Ich fand die Idee der wahrscheinlichkeitsbasierten Texterzeugung besonders interessant. Insbesondere habe ich mich gefragt, was passieren würde, wenn Sie Songtexte als Beispieltext verwenden würden, um „neue“ Texte zu generieren.

In das Internet! Eine schnelle Websuche zeigt einige Markov-basierte Lyric Generator-Sites, aber nichts, was ich mir vorgestellt habe. Außerdem ist es nicht sehr effektiv, den fertigen Code eines anderen zu entfernen, um zu erfahren, wie Markov-Generatoren tatsächlich funktionieren. Lassen Sie uns unsere eigenen bauen.

Also… wie funktionieren Markov-Generatoren? Grundsätzlich wird eine Markov-Kette aus einem Text basierend auf der Häufigkeit des Auftretens bestimmter Muster generiert. Betrachten Sie als Beispiel die folgende Zeichenfolge als Beispieltext:

bobby

Wir werden das einfachste Markov-Modell aus diesem Text erstellen, bei dem es sich um ein Markov-Modell von order 0 handelt, um die Wahrscheinlichkeit des Auftretens eines bestimmten Buchstabens vorherzusagen. Dies ist eine einfache Häufigkeitstabelle:

b: 3/5
o: 1/5
y: 1/5

Dies ist jedoch ein ziemlich schlechtes Sprachmodell. Neben der Häufigkeit, mit der Buchstaben insgesamt vorkommen, möchten wir auch untersuchen, wie häufig ein bestimmter Buchstabe im vorherigen Buchstaben vorkommt. Da wir von einem vorherigen Buchstaben abhängig sind, handelt es sich um ein Markov-Modell der Ordnung 1:

given "b":
  "b" is next: 1/3
  "o" is next: 1/3
  "y" is next: 1/3
given "o":
  "b" is next: 1
given "y":
  [terminates]: 1

Von hier aus könnten Sie sich Markov-Modelle höherer Ordnung vorstellen; Ein Modell der Ordnung 2 würde damit beginnen, die Häufigkeit jedes Buchstabens zu messen, der nach der aus zwei Buchstaben bestehenden Zeichenfolge „bo“ usw. auftritt. Durch Erhöhen der Reihenfolge erhalten wir ein Modell, das eher wie echte Sprache aussieht. Zum Beispiel würde ein Markov-Modell der Ordnung 5, dem viele Beispieleingaben einschließlich des Wortes „Python“ gegeben wurden, sehr wahrscheinlich auf die Zeichenfolge „Python“ mit einem „n“ folgen, während ein Modell mit viel niedrigerer Ordnung möglicherweise entwickelt wurde einige kreative Worte.

Beginnen Sie mit der Entwicklung

Wie würden wir eine grobe Annäherung an ein Markov-Modell erstellen? Im Wesentlichen handelt es sich bei der oben beschriebenen Struktur mit den Modellen höherer Ordnung um ein Wörterbuch mit Wörterbüchern. Sie können sich ein + model + Wörterbuch mit verschiedenen Wortfragmenten (d. H. "Bo") als Schlüssel vorstellen. Jedes dieser Fragmente würde dann der Reihe nach auf ein Wörterbuch verweisen, wobei diese inneren Wörterbücher die einzelnen nächsten Buchstaben ("y") als Schlüssel mit ihren jeweiligen Häufigkeiten als Werte enthalten.

Beginnen wir mit einer + generateModel () + -Methode, die Beispieltext und eine Markov-Modellreihenfolge enthält, und geben dann dieses Wörterbuch der Wörterbücher zurück:

def generateModel(text, order):
    model = {}
    for i in range(0, len(text) - order):
        fragment = text[i:i+order]
        next_letter = text[i+order]
        if fragment not in model:
            model[fragment] = {}
        if next_letter not in model[fragment]:
            model[fragment][next_letter] = 1
        else:
            model[fragment][next_letter] += 1
    return model

Wir haben den gesamten verfügbaren Text durchlaufen und sind bis zum letzten verfügbaren vollständigen Fragment + nächsten Buchstaben gegangen, um nicht am Ende der Zeichenfolge zu verlaufen. Wir haben unsere + Fragment + Wörterbücher mit jedem + Fragment + zum + Modell + hinzugefügt Halten eines Wörterbuchs mit den Gesamtfrequenzen + next_letter +.

Kopieren Sie diese Funktion in eine Python-Shell und probieren Sie sie aus:

>>>

>>> generateModel("bobby", 1)
{'b': {'y': 1, 'b': 1, 'o': 1}, 'o': {'b': 1}}

Das wird gehen! Wir haben Zählungen von Frequenzen anstelle von relativen Wahrscheinlichkeiten, aber wir können damit arbeiten; Es gibt keinen Grund, jedes Wörterbuch zu normalisieren, um Wahrscheinlichkeiten von 100% zu erhöhen.

Verwenden wir nun dieses + Modell + in einer + getNextCharacter () + -Methode, die anhand eines Modells und eines Fragments unter Berücksichtigung der Wahrscheinlichkeiten des Modells über einen geeigneten nächsten Buchstaben entscheidet:

from random import choice
def getNextCharacter(model, fragment):
    letters = []
    for letter in model[fragment].keys():
        for times in range(0, model[fragment][letter]):
            letters.append(letter)
    return choice(letters)

Es ist nicht das effizienteste Setup, aber es ist einfach zu erstellen und funktioniert vorerst. Wir haben einfach eine Liste von Buchstaben erstellt, deren Häufigkeit nach dem Fragment insgesamt vorkommt, und zufällig aus dieser Liste ausgewählt.

Alles, was bleibt, ist die Verwendung dieser beiden Methoden in einer dritten Methode, die tatsächlich Text mit einer bestimmten Länge generiert. Dazu müssen wir das aktuelle Textfragment, das wir erstellen, im Auge behalten, während wir neue Zeichen hinzufügen:

def generateText(text, order, length):
    model = generateModel(text, order)

    currentFragment = text[0:order]
    output = ""
    for i in range(0, length-order):
        newCharacter = getNextCharacter(model, currentFragment)
        output += newCharacter
        currentFragment = currentFragment[1:] + newCharacter
    print output

Machen wir daraus ein vollständig ausführbares Skript, das eine Markov-Reihenfolge verwendet und die Textlänge als Argumente ausgibt:

from random import choice
import sys

def generateModel(text, order):
    model = {}
    for i in range(0, len(text) - order):
        fragment = text[i:i+order]
        next_letter = text[i+order]
        if fragment not in model:
            model[fragment] = {}
        if next_letter not in model[fragment]:
            model[fragment][next_letter] = 1
        else:
            model[fragment][next_letter] += 1
    return model

def getNextCharacter(model, fragment):
    letters = []
    for letter in model[fragment].keys():
        for times in range(0, model[fragment][letter]):
            letters.append(letter)
    return choice(letters)

def generateText(text, order, length):
    model = generateModel(text, order)
    currentFragment = text[0:order]
    output = ""
    for i in range(0, length-order):
        newCharacter = getNextCharacter(model, currentFragment)
        output += newCharacter
        currentFragment = currentFragment[1:] + newCharacter
    print output

text = "some sample text"
if __name__ == "__main__":
    generateText(text, int(sys.argv[1]), int(sys.argv[2]))

Im Moment generieren wir Beispieltext über die sehr wissenschaftliche Methode, einen String direkt in den Code zu werfen, basierend auf einigen kopierten und eingefügten Alanis Morisette-Texten.

Test

Speichern Sie das Skript und versuchen Sie es:

$ python markov.py 2 100
I wounts
You ho's humortel whime
 mateend I wass
How by Lover
$ python markov.py 4 100
stress you to cosmic tears
All they've cracked you (honestly) at the filler in to like raise
$ python markov.py 6 100
tress you place the wheel from me
Please be philosophical
Please be tapped into my house

Das war einfach wertvoll. Die letzten beiden Versuche sind anständig repräsentativ für ihre Texte (obwohl das erste Beispiel von Ordnung 2 eher wie Björk aussieht). Diese Ergebnisse sind ermutigend genug für eine schnelle Codeskizze. Lassen Sie uns dieses Ding also in ein echtes Projekt verwandeln.

Nächste Iteration

Erste Hürde: Wie können wir automatisieren, viele Texte zu bekommen? Eine Möglichkeit wäre, selektiv Inhalte von einer Lyrics-Site zu entfernen, aber das klingt nach viel Aufwand für wahrscheinlich minderwertige Ergebnisse sowie einer potenziellen rechtlichen Grauzone angesichts der Schattigkeit der meisten Lyrics-Aggregatoren und des Drakonismus der Musikindustrie. Lassen Sie uns stattdessen prüfen, ob offene APIs vorhanden sind. Unter programmableweb.com finden wir tatsächlich 14 verschiedene Lyrics-APIs. Diese Einträge sind jedoch nicht immer die aktuellsten. Lassen Sie uns also nach den zuletzt aufgelisteten suchen.

LYRICSnMUSIC bietet eine kostenlose RESTful API unter Verwendung von JSON, um bis zu 150 Zeichen Songtexte zurückzugeben. Dies klingt perfekt für unseren Anwendungsfall, insbesondere angesichts der Wiederholung der meisten Songs. Es ist nicht erforderlich, vollständige Texte zu sammeln, wenn nur ein Beispiel ausreicht. Holen Sie sich einen new key, damit Sie auf deren API zugreifen können.

Probieren wir ihre API aus, bevor wir uns endgültig für diese Quelle entscheiden. Basierend auf ihrer Dokumentation können wir eine Musteranfrage wie folgt stellen:

http://api.lyricsnmusic.com/songs?api_key=[YOUR_API_KEY_HERE]&artist=coldplay

Die JSON-Ergebnisse, die in einem Browser zurückgegeben werden, sind etwas schwer zu lesen. durch sie in einem formatter, um einen besseren Blick zu werfen. Es sieht so aus, als würden wir erfolgreich eine Liste von Wörterbüchern zurückbekommen, die auf Coldplay-Songs basieren:

[
  {
     "title":"Don't Panic",
     "url":"http://www.lyricsnmusic.com/coldplay/don-t-panic-lyrics/4294612",
     "snippet":"Bones sinking like stones \r\nAll that we've fought for \r\nHomes, places we've grown \r\nAll of us are done for \r\n\r\nWe live in a beautiful world \r\nYeah we ...",
     "context":null,
     "viewable":true,
     "instrumental":false,
     "artist":{
        "name":"Coldplay",
        "url":"http://www.lyricsnmusic.com/coldplay"
     }
  },
  {
     "title":"Shiver",
     "url":"http://www.lyricsnmusic.com/coldplay/shiver-lyrics/4294613",
     "snippet":"So I look in your direction\r\nBut you pay me no attention, do you\r\nI know you don't listen to me\r\n'Cause you say you see straight through me, don't you...",
     "context":null,
     "viewable":true,
     "instrumental":false,
     "artist":{
        "name":"Coldplay",
        "url":"http://www.lyricsnmusic.com/coldplay"
     }
  },
  ...
]

Es gibt keine Möglichkeit, die Antwort einzuschränken, aber wir sind nur an jedem bereitgestellten "Snippet" interessiert, was für dieses Projekt gut aussieht.

Unsere vorläufigen Experimente mit Markov-Generatoren waren lehrreich, aber unser aktuelles Modell ist nicht am besten für die Aufgabe geeignet, Texte zu generieren. Zum einen sollten wir wahrscheinlich einzelne Wörter als Zeichen verwenden, anstatt die Dinge Charakter für Charakter zu nehmen. Es macht Spaß, die Sprache selbst zu verspotten, aber um gefälschte Texte zu generieren, wollen wir uns an echtes Englisch halten. Das klingt jedoch schwieriger und wir haben einen langen Weg zurückgelegt, um zu verstehen, wie Markov-Ketten funktionieren. Dies war das ursprüngliche Ziel dieser Übung. An diesem Punkt erreichen wir einen Scheideweg: Erfinden Sie das metaphorische Rad neu, um mehr zu lernen (es könnte eine großartige Codierungspraxis sein), oder sehen Sie, was andere bereits geschaffen haben.

Ich entschied mich für den faulen Ausweg und ging zurück, um die inneren Netze zu durchsuchen. Eine freundliche Seele auf GitHub hat bereits implemented eine einfache Markov-Kette auf Einzelwortbasis implementiert und sie sogar auf hochgeladen PyPI. Bei einem kurzen Spaziergang durch code scheint dieses Modell nur in der Größenordnung 0 zu sein. Dies wäre wahrscheinlich schnell genug gewesen, um selbstständig aufzubauen, während ein Modell höherer Ordnung möglicherweise erheblich mehr Arbeit bedeutet. Lassen Sie uns zunächst mit dem vorverpackten Rad eines anderen fahren. Mindestens ein Modell der Ordnung 0 klingt nicht wie Björk, wenn wir ganze Wörter verwenden.

Da wir unsere Kreation einfach mit Freunden und Familie teilen möchten, ist es sinnvoll, sie in eine Webanwendung umzuwandeln. Wählen Sie nun ein Webframework aus. Persönlich bin ich mit Django bei weitem am vertrautesten, aber das scheint hier übertrieben zu sein. Schließlich brauchen wir nicht einmal eine eigene Datenbank. Probieren wir Flask aus.

Flasche hinzufügen

Https://realpython.com/python-virtual-environments-a-primer/[Starten Sie eine virtuelle Umgebung] - falls Sie dies noch nicht getan haben! Wenn dies kein vertrauter Prozess ist, lesen Sie einige unserer previous posts, um zu erfahren, wie Sie Einstellungen vornehmen oben.

$ mkdir lyricize
$ cd lyricize
$ virtualenv --no-site-packages venv
$ source venv/bin/activate

Installieren Sie auch wie gewohnt die erforderlichen Anforderungen und werfen Sie sie in eine Datei require.txt:

$ pip install PyMarkovChain flask requests
$ pip freeze > requirements.txt

Wir haben auch die Bibliothek requests hinzugefügt, damit wir Webanfragen an die Lyrics-API stellen können.

Nun, um die App zu machen. Der Einfachheit halber teilen wir es in zwei Seiten auf: Auf der Hauptseite wird dem Benutzer eine Grundform für die Auswahl eines Künstlernamens und einer Reihe von zu generierenden Textzeilen angezeigt, während auf einer zweiten Seite mit den Texten die Seite angezeigt wird Ergebnisse. Beginnen wir mit einer Barebone-Flask-Anwendung namens app.py , die eine index.html -Vorlage verwendet:

from flask import Flask, render_template

app = Flask(__name__)
app.debug = True

@app.route('/', methods=['GET'])
def index():
    return render_template('index.html')

if __name__ == '__main__':
    app.run()

Alle diese App wird bisher den Inhalt einer index.html-Vorlage laden. Machen wir es zu einer Grundform:

<html>
 <body>
  <form action="#" method="post" class="lyrics">
    Artist or band name: <input name="artist" type="text"/><br/>
    Number of lines:
    <select name="lines">
      {% for n in range(1,11) %}
        <option value="{{n}}">{{n}}</option>
      {% endfor %}
    </select>
    <br/><br/>
    <input class="button" type="submit" value="Lyricize">
  </form>
 </body>
</html>

Speichern Sie diese index.html in einem separaten Ordner mit dem Namen templates, damit Flask sie finden kann. Hier verwenden wir die Jinja2-Vorlage von Flask, um ein Dropdown-Menü "Auswahl" zu erstellen, das auf einer Schleife basiert, die die Zahlen 1 bis 10 abdeckt. Bevor wir etwas hinzufügen, starten Sie diese Seite, um sicherzustellen, dass wir richtig eingerichtet sind:

$ python app.py
 *Running on http://127.0.0.1:5000/

Sie sollten jetzt in der Lage sein, http://127.0.0.1:5000/in einem Browser zu besuchen und das schöne Formular zu sehen.

Lassen Sie uns nun entscheiden, was auf der Ergebnisseite angezeigt werden soll, damit wir wissen, was wir an die Ergebnisseite weitergeben müssen:

<html>
 <body>
  <div align="center" style="padding-top:20px;">
   <h2>
   {% for line in result %}
     {{ line }}<br/>
   {% endfor %}
   </h2>
   <h3>{{ artist }}</h3>
   <br/>
   <form action="{{ url_for('index') }}">
    <input type="submit" value="Do it again!"/>
   </form>
  </div>
 </body>
</html>

Hier haben wir Zeile für Zeile ein* Ergebnis -Array durchlaufen und jede Zeile separat angezeigt. Darunter zeigen wir den ausgewählten Künstler *und verlinken zurück zur Homepage. Speichern Sie dies als lyrics.html in Ihrem Verzeichnis/templates.

Wir müssen auch die Formularaktion von index.html aktualisieren, um auf diese Ergebnisseite zu verweisen:

<form action="{{ url_for('lyrics') }}" method="post" class="lyrics">

Um nun eine Route für die resultierende Textseite zu schreiben:

@app.route('/lyrics', methods=['POST'])
def lyrics():
    artist = request.form['artist']
    lines = int(request.form['lines'])

    if not artist:
        return redirect(url_for('index'))

    return render_template('lyrics.html', result=['hello', 'world'], artist=artist)

Diese Seite nimmt eine POST-Anfrage aus dem Formular entgegen und analysiert den angegebenen* Künstler und die Anzahl der Zeilen *. Wir generieren noch keine Texte, sondern geben der Vorlage lediglich eine Dummy-Liste mit Ergebnissen. Wir müssen auch die erforderlichen Flask-Funktionen hinzufügen - + url_for + und + redirect + - auf die wir uns verlassen haben:

from flask import Flask, render_template, url_for, redirect

Testen Sie es, um sicherzustellen, dass noch nichts kaputt ist:

$ python app.py

Großartig, jetzt für das wahre Fleisch des Projekts. Lassen Sie uns in lyrics () eine Antwort von LYRICSnMUSIC erhalten, die auf unserem übergebenen Künstlerparameter basiert:

# Get a response of sample lyrics from the provided artist
uri = "http://api.lyricsnmusic.com/songs"
params = {
    'api_key': API_KEY,
    'artist': artist,
}
response = requests.get(uri, params=params)
lyric_list = response.json()

Mithilfe von Anforderungen rufen wir eine bestimmte URL ab, die ein Wörterbuch mit Parametern enthält: den angegebenen Künstlernamen und unseren API-Schlüssel. Dieser private API-Schlüssel sollte nicht in Ihrem Code erscheinen. Schließlich möchten Sie diesen Code mit anderen teilen. Erstellen wir stattdessen eine separate Datei, um diesen Wert als Variable zu speichern:

$ echo "API_KEY=[youractualapikeygoeshere]" > .env

Wir haben eine spezielle "Umgebungs" -Datei erstellt, die Flask jetzt einlesen kann, wenn wir oben in unserer App nur Folgendes hinzufügen:

import os
API_KEY = os.environ.get('API_KEY')

Und zum Schluss fügen wir die Markov-Kettenfunktionalität hinzu. Jetzt, da wir das Paket eines anderen verwenden, ist dies ziemlich trivial. Fügen Sie zunächst den Import oben hinzu:

from pymarkovchain import MarkovChain

Nachdem wir eine Lyrics -Antwort von der API erhalten haben, erstellen wir einfach eine MarkovChain, laden die Lyrics-Daten und generieren eine Liste mit Sätzen:

mc = MarkovChain()
mc.generateDatabase(lyrics)

result = []
for line in range(0, lines):
    result.append(mc.generateString())

Insgesamt sollte app.py nun also ungefähr so ​​aussehen:

from flask import Flask, url_for, redirect, request, render_template
import requests
from pymarkovchain import MarkovChain
import os

API_KEY = os.environ.get('API_KEY')

app = Flask(__name__)
app.debug = True

@app.route('/', methods=['GET'])
def index():
    return render_template('index.html')

@app.route('/lyrics', methods=['POST'])
def lyrics():
    artist = request.form['artist']
    lines = int(request.form['lines'])

    if not artist:
        return redirect(url_for('index'))

    # Get a response of sample lyrics from the artist
    uri = "http://api.lyricsnmusic.com/songs"
    params = {
        'api_key': API_KEY,
        'artist': artist,
    }
    response = requests.get(uri, params=params)
    lyric_list = response.json()

    # Parse results into a long string of lyrics
    lyrics = ''
    for lyric_dict in lyric_list:
        lyrics += lyric_dict['snippet'].replace('...', '') + ' '

    # Generate a Markov model
    mc = MarkovChain()
    mc.generateDatabase(lyrics)

    # Add lines of lyrics
    result = []
    for line in range(0, lines):
        result.append(mc.generateString())

    return render_template('lyrics.html', result=result, artist=artist)

if __name__ == '__main__':
    app.run()

Versuch es! Alles sollte vor Ort funktionieren. Nun, um es mit der Welt zu teilen …​

In Heroku bereitstellen

Lassen Sie uns auf Heroku hosten, da wir dies (für diese Mindestanforderungen) kostenlos tun können. Dazu müssen wir einige kleinere Änderungen am Code vornehmen. Fügen Sie zunächst eine Procfile hinzu, die Heroku mitteilt, wie die App bereitgestellt werden soll:

$ echo "web: python app.py" > Procfile

Da Heroku einen zufälligen Port angibt, an dem die Anwendung ausgeführt werden soll, müssen Sie oben eine Portnummer eingeben:

PORT = int(os.environ.get('PORT', 5000))

app = Flask(__name__)
app.config.from_object(__name__)

Wenn die App ausgeführt wird, müssen Sie diesen Port übergeben

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=PORT)

Wir mussten auch den Host "0.0.0.0" angeben, da Flask standardmäßig privat auf dem lokalen Computer ausgeführt wird, während die App auf Heroku unter einer öffentlich verfügbaren IP-Adresse ausgeführt werden soll.

Entfernen Sie schließlich "+ app.debug = True +" aus Ihrem Code, damit Benutzer Ihre vollständigen Stacktrace-Fehler nicht sehen können, wenn etwas schief geht.

Initialisieren Sie ein Git-Repository (falls Sie dies noch nicht getan haben), erstellen Sie eine neue Heroku-App und übertragen Sie Ihren Code darauf!

$ git init
$ git add .
$ git commit -m "First commit"
$ heroku create
$ git push heroku master

Weitere Informationen zu diesem Bereitstellungsprozess finden Sie in den Heroku-Dokumenten. Stellen Sie sicher, dass Sie Ihre API_KEY-Variable in Heroku hinzufügen:

$ heroku config:set API_KEY=[youractualapikeygoeshere]

Und wir sind fertig! Zeit, deine Kreation mit der Welt zu teilen - oder sie weiter zu hacken :)

Fazit & Nächste Schritte

Wenn Ihnen dieser Inhalt gefallen hat, könnten Sie an unseren https://realpython.com [aktuellen Kursen] zum Erlernen der Webentwicklung oder an unserem neuesten Kickstarter interessiert sein, der fortgeschrittenere Techniken behandelt. Oder - spielen Sie einfach mit der App http://lyricize.herokuapp.com [hier] herum.

*Mögliche nächste Schritte:*
  • Dieser HTML-Code scheint in den frühen 90er Jahren geschrieben worden zu sein. Verwenden Sie Bootstrap oder nur ein einfaches CSS für das Styling

  • Fügen Sie dem Code einige Kommentare hinzu, bevor Sie vergessen, was er tut! (Dies bleibt als Übung für den Leser: o)

  • Abstrakt den Code in der Lyrics-Route als einzelne Methode (dh eine Methode zum Zurückgeben von Antworten von der Lyrics-API und eine andere separate Methode zum Generieren des Markov-Modells); Dadurch wird der Code mit zunehmender Größe und Komplexität leichter zu warten und zu testen

  • Erstellen Sie einen Markov-Generator, der höhere Aufträge verwenden kann

  • Verwenden Sie Flask-WTF, um die Formulare und die Formularvalidierung zu verbessern

  • Apropos: Machen Sie es sicherer! Im Moment könnte jemand möglicherweise unangemessene POST-Anfragen senden, seinen eigenen Code in die Seite einfügen oder die Site mit vielen schnell wiederholten Anfragen bearbeiten. Fügen Sie eine solide Eingabevalidierung und eine grundlegende Ratenbegrenzung hinzu

  • Bessere Fehlerbehandlung hinzufügen; Was ist, wenn ein API-Aufruf zu lange dauert oder aus irgendeinem Grund fehlschlägt?

  • Werfen Sie die Ergebnisse in eine text-to-speech Engine, lernen Sie, die Tonhöhenmuster mit einem anderen Markov-Modell zu variieren, und stellen Sie einen Takt ein. Bald bist du ganz oben in den Charts!