Affichage de JSON en commande en ligne

Souvent lorsque l’on télécharge un fichier JSON celui-ci s’affiche sur une ligne.
On peut faire un affichage plus sympa à l’aide de python.
Voici ce que l’on trouve dans la documentation python

$ echo '{"json":"obj"}' | python -mjson.tool
{
    "json": "obj"
}
$ echo '{ 1.2:3.4}' | python -mjson.tool
Expecting property name: line 1 column 2 (char 2)

On pourra bien sur combiner cette commande avec du wget ou du curl.

$ wget -q -O - http://colas.sebastien.free.fr/projets/infos.json | python3 -m json.tool
{
    "site": "http://colas.sebastien.free.fr",
    "Author": "Sebastien Colas",
    "articles": [
        {
            "title": "UNIX and Linux Essentials Ed 2",
            "url": "http://colas.sebastien.free.fr/index.php/unix-and-linux-essentials-ed-2/"
        },
        {
            "title": "Petit utilitaire en JavaScript",
            "url": "http://colas.sebastien.free.fr/index.php/petit-utilitaire-en-javascript/"
        }
    ]
}

Utilisation des WebSockets en python

Voici un exemple de code permettant une diffusion de message avec les WebSocket.
La démonstration est composé de 3 programmes:

  • Le serveur WebSocket en python qui accepte les connexion
  • Un client WebSocket en python qui emet des messages
  • Un client WebSocket en Javascipt dans une page html qui affiche les messages

Les clients se connectent sur les différentes URL:

  • ws://127.0.0.1:5678/broadcast/read : Pour lire les messages diffusés
  • ws://127.0.0.1:5678/broadcast/write : Pour diffuser un message

Le serveur:

#!/usr/bin/env python3

import asyncio
import datetime
import random
import websockets

connected = set()

async def pub_sub(websocket, path):
    global connected
    if path == '/broadcast/read' :        
        connected.add(websocket)
        print("READER "+str(websocket.remote_address)+"    connected")
        while True:
            await asyncio.sleep(100)
    elif path == '/broadcast/write' :
        print("WRITER "+str(websocket.remote_address)+"    connected")
        try :
            while True:
                data = await websocket.recv()
                print("MULTICAST: "+data)
                still_connected = set()
                for ws in connected :
                    if ws.open:
                        still_connected.add(ws)
                        await asyncio.wait([ws.send(data)])
                    else:
                        print("READER "+str(ws.remote_address)+" disconnected")
                connected=still_connected
        except:
            print("WRITER "+str(websocket.remote_address)+" disconnected")
            
start_server = websockets.serve(pub_sub, '127.0.0.1', 5678)

asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()

Le client python qui emet des messages

#!/usr/bin/env python3

import asyncio
import websockets

async def hello():
    async with websockets.connect('ws://localhost:5678/broadcast/write') as websocket:
        while True:
            name = input("Message ? ")
            await websocket.send(name)

asyncio.get_event_loop().run_until_complete(hello())

La ou les pages html qui recoivent les messages:

<!DOCTYPE html>
<html>
    <head>
        <title>WebSocket demo</title>
    </head>
    <body>
        <script>
            var ws = new WebSocket("ws://127.0.0.1:5678/broadcast/read"),
                messages = document.createElement('ul');
            ws.onmessage = function (event) {
                var messages = document.getElementsByTagName('ul')[0],
                    message = document.createElement('li'),
                    content = document.createTextNode(event.data);
                message.appendChild(content);
                messages.appendChild(message);
            };
            document.body.appendChild(messages);
        </script>
    </body>
</html>