Come creare un service¶
È possibile creare un service personalizzato all’interno di un qualsiasi package creando un file nomedelservice.py all’interno della cartella resources > services > service_type
. Ad esempio:
packages > genrobot > resources > services > telegram > telegram.py
Il file del service deve necessariamente contenere una classe Main, che eredita da GnrBaseService, e una classe ServiceParameters, che servirà a raccogliere eventuali parametri per il funzionamento del service. Vediamo innanzitutto come specificare i parametri del service.
I parametri del Service¶
Esistono due modalità di definizione dei parametri del service, strettamente legata alla modalità di funzionamento del service :
all’interno dell’applicativo Genropy, per service funzionanti in modo «attivo», tramite la definizione della classe ServiceParameters
nel file instanceconfig.xml, per service funzionanti in modo «passivo»
Nel primo caso è possibile ridefinire nel file del service la classe ServiceParameters e il metodo service_parameters al suo interno:
class ServiceParameters(BaseComponent):
def service_parameters(self, pane, datapath=None, **kwargs):
cp = pane.borderContainer(region='center').contentPane(region='top')
fb = cp.formbuilder(datapath=datapath)
fb.textbox(value='^.access_token', lbl='Access Token')
fb.textbox(value='^.verify_token', lbl='Verify Token')
In questo caso inseriamo un normale Formbuilder che ha lo scopo di permettere all’utente di inserire le sue credenziali (un access_token
e un verify_token
). Questo metodo fornirà al Main questi parametri per l’utilizzo nei metodi successivi.
Suggerimento
Questo modo di identificare i parametri è strettamente legato al fatto che l’istanza sia attiva e il service venga «invocato» manualmente. Diverso è il caso seguente, in cui invece il service è sempre attivo e in ascolto a prescindere dalla presenza o meno di un’istanza attiva, grazie al processo gnrserviceworker
Nel secondo caso, invece, in caso di service che operano anche a istanza inattiva e sono sempre in ascolto, gli eventuali parametri devono essere inseriti nel file instanceconfig.xml dell’istanza o alternativamente nell’instanceconfig di default di Genropy (.gnr/instance/default.xml
):
<api_keys>
<telegram api_id="XXXXXXX" api_hash="8b1cfd24...........15f4c" />
</api_keys>
In questo secondo caso le api_keys così definite saranno sempre reperibili in self.site.getApiKeys('telegram')
La classe Main del Service¶
La classe Main deve definire le azioni che eseguirà il service (es: istanziamento client, azioni get/post, ecc). Ad esempio:
class Main(GnrBaseService):
def __init__(self, site, access_token=None, verify_token=None, **kwargs):
self.site = site
self.api_keys = self.site.getApiKeys('telegram')
self.access_token = access_token
self.verify_token = verify_token
Nell’esempio, all’interno del metodo __init__, metodo obbligatorio eseguito automaticamente dal Main, stiamo istanziando il service con le credenziali necessarie al suo funzionamento, in particolare:
recuperiamo le ApiKeys dall’istanza, specificate nel file instanceconfig.xml
rendiamo disponibili ApiKeys e i parametri
access_token
everify_token
(specificati nei parameters) per gli altri metodi che eseguiranno le varie azioni del service.
A questo punto sarà possibile definire altri metodi a piacere nel Main per specificare le azioni da eseguire. Ad esempio:
@public_method
def publishPost(self, access_token=None, page_id_code=None, message=None, **kwargs):
with self.client(bot_token=access_token) as c:
text = message
c.send_message(page_id_code, text)
return message
Il service sarà già attivo e funzionante in modalità «attiva». Per il funzionamento in modalità passiva, sarà invece necessario creare un altro file service.py nella lib
.
Service passivi: file nella lib¶
Per i soli service passivi è necessario creare anche un file dal generico nome service.py all’interno della lib
di Genropy, in una cartella che chiameremo con il service_type, ad esempio:
packages > genrobot > lib > services > telegram > service.py
Questo file è quello che verrà contattato dal processo gnrserviceworker per l’avvio del service. Conterrà quindi necessariamente una classe Service e un metodo __init__:
from gnr.web.gnrwsgisite import GnrWsgiSite
class Service(object):
def __init__(self, instance_name=None, service_name=None, **kwargs):
self.site = GnrWsgiSite(instance_name)
self.service = self.site.getService('telegram', service_name)
All’interno di questo metodo __init__, utilizzando la getService
, esattamente come nel caso di funzionamento attivo del service, individuiamo il service e lo istanziamo. È possibile poi anche in questo caso aggiungere altri metodi a piacere per il compimento delle diverse azioni di interesse.
Autore della sezione: Davide Paci