Passa ai contenuti principali

Protocollo JSON-RPC per Python3

Ho pubblicato su Google code un protocollo simile a JSON-RPC che ho sviluppato per Python3. Segue una breve descrizione del progetto che trovate qui: https://github.com/kronwiz/krpc.

INTRODUZIONE

Il protocollo krpc è stato scritto per Python3. L'idea che sta alla base è quella di avere un protocollo che sia facile da usare anche tramite un'interfaccia web, così è stato naturale scegliere qualcosa basato sulle richieste POST e su JSON come formato di comunicazione. Che io sappia, ad ora non c'è qualcosa di analogo per Python3 per cui ne ho scritto uno da zero. Il protocollo krpc è basato sulle specifiche di JSON-RPC ma differisce per alcuni aspetti:

  • supporta upload di file;
  • per supportare l'upload di file utilizza una richiesta POST standard per chiamare i metodi: l'invocazione del metodo utilizza la sintassi JSON per il passaggio dei parametri e i file da caricare sono contenuti nelle varie parti di un messaggio di tipo multipart;
  • non è supportata l'invocazione di più metodi in una sola richiesta.

INSTALLAZIONE e LICENZA

Tutta l'implementazione è contenuta in un solo file che, quindi, è possibile includere facilmente nei propri progetti. Tuttavia nel pacchetto c'è il solito script setup.py che può essere utilizzato per installare il file nei site-packages.

La libreria è sotto la licenza GNU LESSER GENERAL PUBLIC LICENSE Version 3. Per maggiori informazioni il documento da consultare è http://www.gnu.org/copyleft/lesser.html.

ESEMPI

Prima di addentrarci nei dettagli occorre notare che se usate Python anche per il client il funzionamento è completamente nascosto e chiamare un metodo remoto è del tutto simile a chiamare un metodo su un oggetto locale.
Iniziamo con il solito esempio "hello world". Questo è un semplice client:

  #!/usr/bin/env python3
  # -*- coding: utf8 -*-

  from krpc import KRPCClient, KRPCClientException

  def main ():
          c = KRPCClient ( "localhost", 8080 )

          try:
                  result = c.echo ( "hello world" )
                  print ( result )

          except KRPCClientException as e:
                  print ( "error: %s\nmessage: %s\ndata: %s\n" % ( e.code, e.message, e.info ) )

  main ()

Potete connettervi al server creando un'istanza della classe KRPCClient specificando host e porta del server:

  c = KRPCClient ( "localhost", 8080 )

I metodi remoti si invocano come se fossero metodi dell'istanza di KRPCClient che avete creato:

  result = c.echo ( "hello world" )

Se qualcosa va storto viene sollevata una eccezione di classe KRPCClientException che contiene in alcuni attributi il codice di errore, la descrizione e (se presenti) ulteriori informazioni sull'errore.
Se uno dei parametri passati al metodo è un oggetto di tipo file allora il protocollo si occupa dietro le quinte di trasferire il file al server, cosicché lato server il metodo riceve come parametro un oggetto file che punta al file appena caricato. Non ci sono limiti alla dimensione dei file che possono essere trasferiti.

Questo è tutto quello che serve sapere per quanto riguarda il client. E per quanto riguarda il server? Quello che segue è il server che implementa il metodo "echo" richiamato dal nostro client di esempio:

  #!/usr/bin/env python3
  # -*- coding: utf8 -*-

  from krpc import KRPCServer

  class TestClass ( object ):
          def echo ( self, msg ):
                  return msg

  def main ():
          server = KRPCServer ( "localhost", 8080 )

          test_instance = TestClass ()
          server.register_instance ( test_instance )

          print ( 'Starting server, use <Ctrl-C> to stop' )
          #server.serve_forever ()

          quit = False
          while not quit:
                  server.handle_request ()


  main ()

Per creare un server occorre creare un'istanza della classe KRPCServer specificando l'host e la porta su cui il server rimane in attesa delle richieste:

  server = KRPCServer ( "localhost", 8080 )

Il server pubblica tutti i metodi contenuti nell'oggetto che viene passato al metodo register_instance :

  server.register_instance ( class_instance )

Nell'esempio precedente l'oggetto passato è un'istanza di TestClass contenente soltanto il metodo "echo" che restituisce esattamente il valore che gli viene passato (non è molto utile come metodo ma è semplice da capire).
Il server si avvia chiamando il suo metodo serve_forever oppure, se è necessario svolgere delle operazioni tra una richiesta e l'altra, scrivendo un ciclo in cui viene chiamato il metodo handle_request che attende e gestisce una sola richiesta.
A proposito: il protocollo crea un nuovo processo per ogni richiesta che riceve, quindi le richieste sono gestite in parallelo.
Maggiore documentazione è contenuta nella directory "docs" del progetto.

Commenti

Post popolari in questo blog

Nuovo sito "Creare programmando" con una sezione per la didattica

Ho organizzato i miei tutorial, fatti con Scratch o altri linguaggi, in un nuovo sito che si chiama "Creare programmando" e che dovrebbe rendere più agevole lo scarico degli stessi. Questo sito contiene anche una sezione dedicata alla didattica tramite il computer in cui voglio raccogliere idee e tutorial che possono trovare applicazione nelle scuole oltre che nei CoderDojo, magari semplicemente perché forniscono degli spunti agli insegnanti sugli argomenti che si possono sviluppare (nel vero senso della parola) tramite il computer. Ho inaugurato la sezione didattica con un nuovo tutorial in Scratch dedicato alle regioni italiane. Cliccate qui per andarlo a vedere.

Un tutorial software per allenarsi all'uso dei sensori hardware

Durante l'ultima sessione di CoderDojo MXP abbiamo proposto ai ragazzi un tutorial che ha lo scopo di impratichirli nei ragionamenti che si rendono necessari quanto ci si trova a dover impostare la traiettoria di una macchinina utilizzando solo un sensore in grado di rilevare il colore della traccia visibile sul pavimento (in scala di grigi). Non avendo (ancora) a disposizione macchinine e sensori "reali" abbiamo iniziato a simulare la situazione disegnando una pista con Scratch utilizzando quattro diversi colori. Il compito dei ragazzi era di riuscire a fare in modo che lo sprite dell'automobilina seguisse la pista senza uscire di strada: le correzioni alla traiettoria avvenivano utilizzando il blocco "sta toccando il colore..." come se ci fosse un sensore in grado di vedere il colore della traccia sotto all'automobile. E se ne sono viste di tutti i colori perché il compito non era facile. Alla fine, per stimolare un po' di competizione tr

Sed: caratteri speciali che si possono usare nel lato destro delle sostituzioni

Il titolo è lungo, ma serve semplicemente per dire che nelle sostituzioni tramite la sed , ovvero quelle realizzate con il comando s/// , è possibile utilizzare alcune sequenze di escape oltre ai soliti backreference dei gruppi "catturati" con le parentesi nell'espressione regolare di sinistra. Nella parte destra dell'espressione (cioè quella dopo la seconda barra /) si possono usare: - \L per trasformare in minuscolo tutto  quello che segue (la L sta per "lowercase"); - \l (è una elle minuscola) per trasformare in minuscolo solo il carattere seguente; - \U per trasformare in maiuscolo tutto  quello che segue (la U sta per "uppercase"); - \u per traformare in maiuscolo solo il carattere seguente; - \E per marcare la fine della trasformazione dei caratteri. Gli "operatori" \L e \U agiscono fino alla fine dell'espressione (delimitata dalla barra / finale) oppure fino alla \E successiva. Quindi, per esempio, per trasformare sol