Construisez un serveur léger en Python et écoutez les extensions HTTP de Scratch 2

Pourquoi existe-t-il un serveur HTTP léger?

À titre d'exemple de l'explication ici, la méthode d'utilisation de la synthèse vocale et de la reconnaissance vocale dans la version hors ligne Scratch 2 est résumée ci-dessous.

Mettez également le code qui apparaît dans la description ci-dessous sur github.

Ajouter des blocs dans le fichier s2e Scratch 2

PDF d'explication Dans Page d'extension Scratch Si vous lisez HTTP-9-11.pdf), cela indique que vous pouvez ajouter des blocs en créant un fichier au format JSON avec l'extension .s2e et en le lisant. (L'extension n'a pas d'importance, mais il semble que vous devriez utiliser .s2e.) Ci-dessous, je vais essayer d'utiliser l'exemple donné dans cette explication.

test.s2e


{ "extensionName": "Extension Example",
    "extensionPort": 12345,
    "blockSpecs": [
        [" ", "beep", "playBeep"],
        [" ", "set beep volume to %n", "setVolume", 5],
        ["r", "beep volume", "volume"],
    ]
}

Enregistrez-le dans un fichier appelé test.s2e. Si vous maintenez Shift et sélectionnez [File] dans Scratch, [Load Experimental HTTP Extension] sera affiché, donc si vous sélectionnez et chargez test.s2e enregistré ici, il bloquera certainement. Sera ajouté!

extension_example_empty-s.png

cette? Le cercle à côté de «Exemple d'extension» est rouge.

Selon le PDF d'explication, Scratch demande un sondage environ 30 fois par seconde GET / poll J'envoie à l'assistant, mais il semble devenir rouge s'il n'y a pas de réponse. S'il y a une réaction de l'assistant, il deviendra vert.

Serveur HTTP léger avec Python

Partie 1: Réagissez à GET / sondage

Installez aiohttp avec $ pip install aiohttp et créez le programme suivant (testhelper.py).

testhelper.py


from aiohttp import web

async def handle_poll(request):
    return web.Response(text="OK")

app = web.Application()
app.router.add_get('/poll', handle_poll)

web.run_app(app, host='127.0.0.1', port=12345)

Je vais essayer.

> python testhelper.py
======== Running on http://127.0.0.1:12345 ========
(Press CTRL+C to quit)

Au fait, quand je regarde l'écran de Scratch ... Oh, il est devenu vert!

extension_example_polling-s.png

Juste au cas où, essayez GET from bash avec nc.

$ nc localhost 12345
GET /poll HTTP/1.1

Si vous appuyez sur retour avec ceci ...

HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Content-Length: 2
Date: Tue, 19 Sep 2017 13:41:21 GMT
Server: Python/3.5 aiohttp/2.1.0

OK

Il semble que aiohttp répond.

Partie 2: envoyer une commande à partir de zéro (bloc de commandes)

Commençons par implémenter le bloc beep comme révision. Le bloc qui envoie des commandes de Scratch à l'assistant est appelé un "bloc de commande". Si vous regardez s2e, vous pouvez voir qu'il est associé au nom de commande playBeep. A ce moment, GET / playBeep est envoyé à l'assistant, et l'assistant doit prendre cela et faire quelque chose. Essayez de faire sonner la cloche avec «\ 007».

async def handle_beep(request):
    print("play beep!")
    print("\007")
    return web.Response(text="OK")

#réduction

app.router.add_get('/playBeep', handle_beep)

web.run_app(app, host='127.0.0.1', port=12345)

Appuyer sur le bloc «bip» sur Scratch 2 fait un son.

Ensuite, essayez d'implémenter le bloc de commande définir le volume du bip sur (...) qui envoie la valeur. Dans l'exemple suivant, vol a une valeur, vous pouvez donc la récupérer avec request.match_info ['vol'].

async def handle_setvolume(request):
    volume = int(request.match_info['vol'])
    if volume >= 0 and volume <= 10:
        
        print("set volume= " + str(volume))
    else:
        print("out of range: " + str(volume))
    return web.Response(text="OK")

#réduction

app.router.add_get('/setVolume/{vol}', handle_setvolume)

web.run_app(app, host='127.0.0.1', port=12345)

L'affichage change selon que vous entrez une valeur de 0 à 10 et appuyez sur le bloc, ou si vous entrez une autre valeur. (Il est également nécessaire de vérifier ʻisintegra () avant ʻint (), mais de l'omettre.)

Partie 3: Recevoir la valeur dans Scratch (bloc reporter)

Enfin, retournons la valeur de l'assistant à Scratch. Dans Scratch, le bloc qui peut recevoir cette valeur est appelé le bloc reporter, et quand il reçoit un nombre ou une chaîne, il est préfixé avec «" r "» dans le fichier s2e. Par contre, lors de la réception d'une valeur booléenne, ajoutez «b» pour la distinguer.

Pour renvoyer une valeur dans le bloc reporter, utilisez la réponse à GET / poll. beep volume est associé au nom" volume ", donc si vous renvoyez volume 10 à GET / poll, le bloc reporter sera rempli.

Dans ce qui suit, la valeur spécifiée par «régler le volume du bip sur (...)» sera renvoyée telle quelle. Voici le code complet jusqu'à présent.

testhelper.py


from aiohttp import web

volume = 0

async def handle_poll(request):
    text = "volume " + str(volume) + "\n"
    return web.Response(text=text)

async def handle_beep(request):
    print("play beep!")
    print("\007")
    return web.Response(text="OK")

async def handle_setvolume(request):
    global volume  #N'oublie pas
    tmp_volume = int(request.match_info['vol']) #Une fois à une autre variable
    if tmp_volume >= 0 and tmp_volume <= 10:
        volume = tmp_volume
        print("set volume= " + str(volume))
    else:
        print("out of range: " + str(tmp_volume))
    return web.Response(text="OK")

app = web.Application()
app.router.add_get('/poll', handle_poll)
app.router.add_get('/playBeep', handle_beep)
app.router.add_get('/setVolume/{vol}', handle_setvolume)

web.run_app(app, host='127.0.0.1', port=12345)

Il semble préférable d'en faire une classe et d'y accéder comme self.volume. Est-ce que c'est comme ça en classe?

Essayez-le avec Scratch. Commencez par vérifier la valeur à côté du bloc rapporteur «volume du bip» pour afficher la valeur. Ensuite, lorsque vous entrez un nombre dans le bloc de commande définir le volume du bip sur (...) et que vous l'exécutez (cliquez sur le bloc), la valeur du bloc de rapport `` volume du bip '' passe à la valeur spécifiée dans le bloc de commande. Tu peux voir ça.

command_and_reporter.png

S'il y a plusieurs blocs de reporters, renvoyez la réponse séparée par le code de saut de ligne «0A».

Autres: Bloc de commande en attente, etc.

Certains blocs de commandes attendent d'être exécutés et sont spécifiés en préfixant «" w "» dans s2e. Pour implémenter ce bloc, vous devez indiquer à Scratch que la commande est en cours d'exécution.

Par exemple, si vous ajoutez «w» à «régler le volume du bip sur (...)», ce qui était «GET / setVolume / 5» devient l'ID de commande comme «GET / setVolume / 2574/5». Est ajouté (2574 est un exemple, en fait la valeur sera différente pour chaque demande de commande). L'ajout de cet ID de commande à la réponse à l'interrogation indique au côté Scratch quel bloc est en cours d'exécution. À ce stade, ajoutez-le au format «_busy 2574». Si vous devez renvoyer plusieurs ID de commande, séparez-les par un espace.

De plus, il existe différents sujets tels que comment faire une sélection de bloc dans un menu déroulant sans entrer de valeur, comment recevoir une chaîne de caractères, comment réinitialiser, politique interdomaine, etc. [Explication PDF](https: // wiki. Il est mentionné dans scratch.mit.edu/w/images/ExtensionsDoc.HTTP-9-11.pdf).

en conclusion

La méthode ci-dessus peut être une connexion à Scratch 3 (je ne sais pas ce qu'il advient de la version hors ligne de Scratch 3 et comment l'étendre), mais avec Python, il y a diverses choses telles que OpenCV, l'apprentissage automatique, le calcul numérique, etc. Puisque la bibliothèque est prête à être utilisée, il semble qu'elle puisse être étendue assez librement.

Bien sûr, Node.js peut également configurer un serveur léger avec des E / S asynchrones similaires, donc si vous n'êtes pas particulièrement attentif aux modules Python, vous pouvez l'écrire en JavaScript. (J'ai résumé cet article)

Si vous souhaitez conserver l'extension HTTP dans Scratch 3 (et si elle est en cours de suppression), vous pouvez également modifier Scratch 3.

Recommended Posts

Construisez un serveur léger en Python et écoutez les extensions HTTP de Scratch 2
Serveur HTTP simple pour python
Créer un environnement Python et transférer des données vers le serveur
<Python> Construisez un serveur dédié pour l'analyse des données Jupyter Notebook
Bibliothèque pour spécifier un serveur de noms en python et dig
Créez un environnement python sur CentOS 7.7 pour votre serveur domestique
Ecrire un serveur HTTP / 2 en Python
Créer et tester un environnement CI pour plusieurs versions de Python
Obtenez un jeton pour conoha avec python
Créez un environnement CentOS Linux 8 avec Docker et démarrez Apache HTTP Server
Créez rapidement un environnement python pour le Deep Learning / Data Science (Windows)
Mettez Docker dans Windows Home et exécutez un serveur Web simple avec Python
Configurer un serveur HTTPS simple avec Python 3
Organisez les modules et les packages Python dans le désordre
J'ai écrit une classe en Python3 et Java
Configurez un serveur SMTP de test en Python.
Lancer un serveur Web avec Python et Flask
Configurer un serveur SMTP simple en Python
Automatisez la suppression de l'arrière-plan pour les derniers portraits dans un répertoire avec Python et API
Construisez un serveur API pour vérifier le fonctionnement de l'implémentation frontale avec python3 et Flask
Causes et solutions lorsque la compilation de Python Sam échoue dans un environnement Cloud9 nouvellement créé
Je ne peux pas dormir tant que je n'ai pas construit un serveur !! (Introduction au serveur Python faite en un jour)
Janken Poi en Python pour les débutants (réponses et explications)
Créez un environnement interactif pour l'apprentissage automatique avec Python
Création d'un environnement de travail Docker R et Python
Construire l'extension Python E-Cell 4 sur Windows 7 (64 bits)
Créez un environnement python pour chaque répertoire avec pyenv-virtualenv
Préférences pour jouer à Wave dans Python PyAudio et PortAudio
Essayez de rechercher un profil d'un million de caractères en Python
Problèmes et contre-mesures pour le débordement de la binarisation d'Otsu en Python
Créer un serveur HTTP Apache et Wildfly sur Oracle Linux 8
Serveur HTTP facile et paramètres de démarrage automatique de Systemd dans Go
Créez un environnement virtuel python avec virtualenv et virtualenvwrapper
Créer un serveur Web en langage Go (net / http) (1)
Recherche récursive de fichiers et de répertoires en Python et sortie
Créez un faux serveur Minecraft en Python avec Quarry
Définir le proxy pour Python pip (décrit dans pip.ini)
Requête HTTP en Python
Recherche d'un moyen unifié d'attendre et d'obtenir les changements d'état de Selenium pour les éléments Python
Analysez l'API Researchmap avec Python et créez automatiquement un fichier Word pour la liste des succès
[Sakura Rental Server] (Pour les débutants) Comment créer un environnement pour Python, pyenv et Flask. | Pour csh
Liste des informations sur les arguments de méthode pour les classes et les modules en Python
Créer un compte enfant de connect with Stripe en Python
[Python] Créer une liste de dates et d'heures pour une période spécifiée
Comment spécifier un serveur HTTP simple Python de répertoire public
Créer un environnement de développement Python avec Eclipse (ajouter un éditeur HTML)
Procédure d'installation pour Python et Ansible avec une version spécifique
Un moyen simple d'éviter plusieurs boucles for en Python
Conseils pour coder courts et faciles à lire en Python
Un moyen standard de développer et de distribuer des packages en Python
Vitesse explosive! Utilisation de Python Simple HTTP Server pour le développement Kintone
Astuces utiles liées à la liste et aux instructions en Python
Créez le code qui renvoie "A et prétendant B" en python
J'ai créé une classe en Python et essayé de taper du canard
Construire l'extension Python E-Cell 4 sur Mac OSX (Yosemite)
Problèmes et solutions à la demande de MySQL db dans Python 3
Essayez simplement de recevoir un webhook avec ngrok et Python