Come usare Hub di notifica da PythonHow to use Notification Hubs from Python

Per accedere a tutte le funzionalità di Hub di notifica da un back-end Java/PHP/Ruby, è possibile usare l'interfaccia REST di Hub di notifica come descritto nell'argomento API REST degli hub di notificain MSDN.You can access all Notification Hubs features from a Java/PHP/Python/Ruby back-end using the Notification Hub REST interface as described in the MSDN topic Notification Hubs REST APIs.

Nota

Di seguito è riportato un esempio di riferimento per l'implementazione degli invii di notifiche in Python. Non si tratta dell'SDK Python di Hub di notifica.This is a sample reference implementation for implementing the notification sends in Python and is not the officially supported Notifications Hub Python SDK.

L'esempio è scritto in Python 3.4.This sample is written using Python 3.4.

Questo argomento illustra come:In this topic we show how to:

  • Compilare un client REST per le funzionalità di Hub di notifica in Python.Build a REST client for Notification Hubs features in Python.
  • Inviare notifiche tramite l'interfaccia di Python alle API REST di Hub di notifica.Send notifications using the Python interface to the Notification Hub REST APIs.
  • Eseguire un dump della richiesta/risposta HTTP REST a scopo didattico/di debug.Get a dump of the HTTP REST request/response for debugging/educational purpose.

Completare l' esercitazione introduttiva per la piattaforma mobile preferita, implementando la parte del back-end in Python.You can follow the Get started tutorial for your mobile platform of choice, implementing the back-end portion in Python.

Nota

L'ambito dell'esempio è limitato all'invio di notifiche. Non viene eseguita alcuna gestione delle registrazioni.The scope of the sample is only limited to send notifications and it doesn't do any registration management.

Interfaccia del clientClient interface

L'interfaccia principale del client può fornire gli stessi metodi disponibili nell' SDK di Hub di notifica per .NET.The main client interface can provide the same methods that are available in the .NET Notification Hubs SDK. Questo consentirà di convertire direttamente tutte le esercitazioni e gli esempi disponibili in questo sito e a cui hanno contribuito i membri della community su Internet.This will allow you to directly translate all the tutorials and samples currently available on this site, and contributed by the community on the internet.

Tutto il codice disponibile è incluso nell' esempio di wrapper REST Python.You can find all the code available in the [Python REST wrapper sample].

Ad esempio, per creare un client:For example, to create a client:

isDebug = True
hub = NotificationHub("myConnectionString", "myNotificationHubName", isDebug)

Per inviare una notifica di tipo avviso popup di Windows:To send a Windows toast notification:

wns_payload = """<toast><visual><binding template=\"ToastText01\"><text id=\"1\">Hello world!</text></binding></visual></toast>"""
hub.send_windows_notification(wns_payload)

ImplementazioneImplementation

Se non è già stato fatto, seguire l' esercitazione introduttiva fino all'ultima sezione in cui è necessario implementare il back-end.If you did not already, please follow our [Get started tutorial] up to the last section where you have to implement the back-end.

Tutti i dettagli per implementare un wrapper REST completo sono disponibili in MSDN.All the details to implement a full REST wrapper can be found on MSDN. In questa sezione viene illustrata l'implementazione Python dei passaggi principali necessari per accedere agli endpoint REST di Hub di notifica e inviare notifiche:In this section we will describe the Python implementation of the main steps required to access Notification Hubs REST endpoints and send notifications

  1. Analizzare la stringa di connessioneParse the connection string
  2. Generare il token di autorizzazioneGenerate the authorization token
  3. Inviare una notifica tramite l'API REST HTTPSend a notification using HTTP REST API

Analizzare la stringa di connessioneParse the connection string

Questa è la classe principale che implementa il client, il cui costruttore analizza la stringa di connessione:Here is the main class implementing the client, whose constructor parses the connection string:

class NotificationHub:
    API_VERSION = "?api-version=2013-10"
    DEBUG_SEND = "&test"

    def __init__(self, connection_string=None, hub_name=None, debug=0):
        self.HubName = hub_name
        self.Debug = debug

        # Parse connection string
        parts = connection_string.split(';')
        if len(parts) != 3:
            raise Exception("Invalid ConnectionString.")

        for part in parts:
            if part.startswith('Endpoint'):
                self.Endpoint = 'https' + part[11:]
            if part.startswith('SharedAccessKeyName'):
                self.SasKeyName = part[20:]
            if part.startswith('SharedAccessKey'):
                self.SasKeyValue = part[16:]

Creare il token di sicurezzaCreate security token

I dettagli della creazione del token di sicurezza sono disponibili qui.The details of the security token creation are available here. È necessario aggiungere i metodi seguenti alla classe NotificationHub per creare il token in base all'URI della richiesta corrente e delle credenziali estratte dalla stringa di connessione.The following methods have to be added to the NotificationHub class to create the token based on the URI of the current request and the credentials extracted from the connection string.

@staticmethod
def get_expiry():
    # By default returns an expiration of 5 minutes (=300 seconds) from now
    return int(round(time.time() + 300))

@staticmethod
def encode_base64(data):
    return base64.b64encode(data)

def sign_string(self, to_sign):
    key = self.SasKeyValue.encode('utf-8')
    to_sign = to_sign.encode('utf-8')
    signed_hmac_sha256 = hmac.HMAC(key, to_sign, hashlib.sha256)
    digest = signed_hmac_sha256.digest()
    encoded_digest = self.encode_base64(digest)
    return encoded_digest

def generate_sas_token(self):
    target_uri = self.Endpoint + self.HubName
    my_uri = urllib.parse.quote(target_uri, '').lower()
    expiry = str(self.get_expiry())
    to_sign = my_uri + '\n' + expiry
    signature = urllib.parse.quote(self.sign_string(to_sign))
    auth_format = 'SharedAccessSignature sig={0}&se={1}&skn={2}&sr={3}'
    sas_token = auth_format.format(signature, expiry, self.SasKeyName, my_uri)
    return sas_token

Inviare una notifica tramite l'API REST HTTPSend a notification using HTTP REST API

Definire innanzitutto una classe che rappresenta la notifica.First, let use define a class representing a notification.

class Notification:
    def __init__(self, notification_format=None, payload=None, debug=0):
        valid_formats = ['template', 'apple', 'gcm', 'windows', 'windowsphone', "adm", "baidu"]
        if not any(x in notification_format for x in valid_formats):
            raise Exception(
                "Invalid Notification format. " +
                "Must be one of the following - 'template', 'apple', 'gcm', 'windows', 'windowsphone', 'adm', 'baidu'")

        self.format = notification_format
        self.payload = payload

        # array with keynames for headers
        # Note: Some headers are mandatory: Windows: X-WNS-Type, WindowsPhone: X-NotificationType
        # Note: For Apple you can set Expiry with header: ServiceBusNotification-ApnsExpiry
        # in W3C DTF, YYYY-MM-DDThh:mmTZD (for example, 1997-07-16T19:20+01:00).
        self.headers = None

Questa classe è un contenitore per un corpo di notifica nativo oppure un set di proprietà nel caso di una notifica modello e un set di intestazioni che contengono il formato (modello o piattaforma nativa) e proprietà specifiche della piattaforma (come la proprietà di scadenza e le intestazioni WNS di Apple).This class is a container for a native notification body or a set of properties in case of a template notification, a set of headers which contains format (native platform or template) and platform-specific properties (like Apple expiration property and WNS headers).

Per tutte le opzioni disponibili fare riferimento alla documentazione delle API REST di Hub di notifica e ai formati delle piattaforme di notifica specifiche.Please refer to the Notification Hubs REST APIs documentation and the specific notification platforms' formats for all the options available.

Una volta definita questa classe, è possibile scrivere i metodi di notifica all'interno della classe NotificationHub .Now with this class, we can write the send notification methods inside of the NotificationHub class.

def make_http_request(self, url, payload, headers):
    parsed_url = urllib.parse.urlparse(url)
    connection = http.client.HTTPSConnection(parsed_url.hostname, parsed_url.port)

    if self.Debug > 0:
        connection.set_debuglevel(self.Debug)
        # adding this querystring parameter gets detailed information about the PNS send notification outcome
        url += self.DEBUG_SEND
        print("--- REQUEST ---")
        print("URI: " + url)
        print("Headers: " + json.dumps(headers, sort_keys=True, indent=4, separators=(' ', ': ')))
        print("--- END REQUEST ---\n")

    connection.request('POST', url, payload, headers)
    response = connection.getresponse()

    if self.Debug > 0:
        # print out detailed response information for debugging purpose
        print("\n\n--- RESPONSE ---")
        print(str(response.status) + " " + response.reason)
        print(response.msg)
        print(response.read())
        print("--- END RESPONSE ---")

    elif response.status != 201:
        # Successful outcome of send message is HTTP 201 - Created
        raise Exception(
            "Error sending notification. Received HTTP code " + str(response.status) + " " + response.reason)

    connection.close()

def send_notification(self, notification, tag_or_tag_expression=None):
    url = self.Endpoint + self.HubName + '/messages' + self.API_VERSION

    json_platforms = ['template', 'apple', 'gcm', 'adm', 'baidu']

    if any(x in notification.format for x in json_platforms):
        content_type = "application/json"
        payload_to_send = json.dumps(notification.payload)
    else:
        content_type = "application/xml"
        payload_to_send = notification.payload

    headers = {
        'Content-type': content_type,
        'Authorization': self.generate_sas_token(),
        'ServiceBusNotification-Format': notification.format
    }

    if isinstance(tag_or_tag_expression, set):
        tag_list = ' || '.join(tag_or_tag_expression)
    else:
        tag_list = tag_or_tag_expression

    # add the tags/tag expressions to the headers collection
    if tag_list != "":
        headers.update({'ServiceBusNotification-Tags': tag_list})

    # add any custom headers to the headers collection that the user may have added
    if notification.headers is not None:
        headers.update(notification.headers)

    self.make_http_request(url, payload_to_send, headers)

def send_apple_notification(self, payload, tags=""):
    nh = Notification("apple", payload)
    self.send_notification(nh, tags)

def send_gcm_notification(self, payload, tags=""):
    nh = Notification("gcm", payload)
    self.send_notification(nh, tags)

def send_adm_notification(self, payload, tags=""):
    nh = Notification("adm", payload)
    self.send_notification(nh, tags)

def send_baidu_notification(self, payload, tags=""):
    nh = Notification("baidu", payload)
    self.send_notification(nh, tags)

def send_mpns_notification(self, payload, tags=""):
    nh = Notification("windowsphone", payload)

    if "<wp:Toast>" in payload:
        nh.headers = {'X-WindowsPhone-Target': 'toast', 'X-NotificationClass': '2'}
    elif "<wp:Tile>" in payload:
        nh.headers = {'X-WindowsPhone-Target': 'tile', 'X-NotificationClass': '1'}

    self.send_notification(nh, tags)

def send_windows_notification(self, payload, tags=""):
    nh = Notification("windows", payload)

    if "<toast>" in payload:
        nh.headers = {'X-WNS-Type': 'wns/toast'}
    elif "<tile>" in payload:
        nh.headers = {'X-WNS-Type': 'wns/tile'}
    elif "<badge>" in payload:
        nh.headers = {'X-WNS-Type': 'wns/badge'}

    self.send_notification(nh, tags)

def send_template_notification(self, properties, tags=""):
    nh = Notification("template", properties)
    self.send_notification(nh, tags)

I metodi sopra indicati inviano una richiesta POST HTTP all'endpoint /messages dell'hub di notifica, contenenti il corpo e le intestazioni corrette per l'invio della notifica.The above methods send an HTTP POST request to the /messages endpoint of your notification hub, with the correct body and headers to send the notification.

Uso di proprietà di debug per abilitare la registrazione dettagliataUsing debug property to enable detailed logging

L'abilitazione della proprietà di debug durante l'inizializzazione di Hub di notifica consente la scrittura di informazioni di registrazione dettagliate sulla richiesta HTTP e sul dump di risposta, nonché del risultato dettagliato dell'invio del messaggio di notifica.Enabling debug property while initializing the Notification Hub will write out detailed logging information about the HTTP request and response dump as well as detailed Notification message send outcome. È stata recentemente aggiunta la proprietà Notification Hubs TestSend che restituisce informazioni dettagliate sul risultato dell'invio della notifica.We recently added this property called Notification Hubs TestSend property which returns detailed information about the notification send outcome. Per usarle, inizializzarle con le seguenti operazioni:To use it - initialize using the following:

hub = NotificationHub("myConnectionString", "myNotificationHubName", isDebug)

L'URL HTTP della richiesta di invio a Hub di notifica viene aggiunto con una querystring "test" come risultato.The Notification Hub Send request HTTP URL gets appended with a "test" querystring as a result.

Completare l'esercitazioneComplete the tutorial

È ora possibile completare l'esercitazione introduttiva inviando la notifica da un back-end Python.Now you can complete the Get Started tutorial by sending the notification from a Python back-end.

Inizializzare il client di Hub di notifica, sostituendo la stringa di connessione e il nome hub come indicato nell'esercitazione esercitazione introduttiva:Initialize your Notification Hubs client (substitute the connection string and hub name as instructed in the [Get started tutorial]):

hub = NotificationHub("myConnectionString", "myNotificationHubName")

Aggiungere quindi il codice di invio a seconda della piattaforma mobile di destinazione.Then add the send code depending on your target mobile platform. In questo esempio vengono aggiunti anche metodi di livello più elevato per abilitare l'invio di notifiche in base alla piattaforma, ad esempio send_windows_notification per Windows o send_apple_notification per Apple e così via.This sample also adds higher level methods to enable sending notifications based on the platform e.g. send_windows_notification for windows; send_apple_notification (for apple) etc.

Windows Store e Windows Phone 8.1 (non Silverlight)Windows Store and Windows Phone 8.1 (non-Silverlight)

wns_payload = """<toast><visual><binding template=\"ToastText01\"><text id=\"1\">Test</text></binding></visual></toast>"""
hub.send_windows_notification(wns_payload)

Windows Phone 8.0 e 8.1 SilverlightWindows Phone 8.0 and 8.1 Silverlight

hub.send_mpns_notification(toast)

iOSiOS

alert_payload = {
    'data':
        {
            'msg': 'Hello!'
        }
}
hub.send_apple_notification(alert_payload)

AndroidAndroid

gcm_payload = {
    'data':
        {
            'msg': 'Hello!'
        }
}
hub.send_gcm_notification(gcm_payload)

Kindle FireKindle Fire

adm_payload = {
    'data':
        {
            'msg': 'Hello!'
        }
}
hub.send_adm_notification(adm_payload)

BaiduBaidu

baidu_payload = {
    'data':
        {
            'msg': 'Hello!'
        }
}
hub.send_baidu_notification(baidu_payload)

Eseguendo il codice Python dovrebbe essere visualizzata una notifica sul dispositivo di destinazione.Running your Python code should produce a notification appearing on your target device.

Esempi:Examples:

Abilitazione della proprietà di debugEnabling debug property

Quando si abilita il flag di debug durante l'inizializzazione di Hub di notifica, verranno visualizzati una richiesta HTTP dettagliata e un dump di risposta, nonché un risultato di notifica simile a quello riportato di seguito, dove è possibile comprendere quali intestazioni HTTP vengono passate e quale risposta HTTP è stata ricevuta da Hub di notifica: When you enable debug flag while initializing the NotificationHub then you will see detailed HTTP request and response dump as well as NotificationOutcome like the following where you can understand what HTTP headers are passed in the request and what HTTP response was received from the Notification Hub:

verrà visualizzato il risultato dettagliato di Hub di notifica, ad esempio:You will see detailed Notification Hub result e.g.

  • quando il messaggio viene inviato correttamente al servizio di notifica push.when the message is successfully sent to the Push Notification Service.

      <Outcome>The Notification was successfully sent to the Push Notification System</Outcome>
    
  • Se non fosse possibile trovare destinazioni per qualsiasi notifica push, probabilmente nella risposta verrà visualizzato quanto segue, dove viene indicato che non è stata trovata alcuna registrazione per recapitare la notifica perché nelle registrazioni erano presenti alcuni tag non corrispondenti.If there were no targets found for any push notification then you are likely going to see the following in the response (which indicates that there were no registrations found to deliver the notification probably because the registrations had some mismatched tags)

      '<NotificationOutcome xmlns="http://schemas.microsoft.com/netservices/2010/10/servicebus/connect" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><Success>0</Success><Failure>0</Failure><Results i:nil="true"/></NotificationOutcome>'
    

Trasmettere notifiche di tipo avviso popup a WindowsBroadcast toast notification to Windows

Notare le intestazioni che vengono inviate quando si inoltra una notifica di tipo popup al client Windows.Notice the headers that get sent out when you are sending a broadcast toast notification to Windows client.

hub.send_windows_notification(wns_payload)

Inviare la notifica specificando un tag (o un'espressione tag)Send notification specifying a tag (or tag expression)

Si noti l'intestazione HTTP Tags che viene aggiunta alla richiesta HTTP (nell'esempio seguente viene inviata la notifica solo alle registrazioni con payload 'sports')Notice the Tags HTTP header which gets added to the HTTP request (in the example below, we are sending the notification only to registrations with 'sports' payload)

hub.send_windows_notification(wns_payload, "sports")

Inviare la notifica specificando più tagSend notification specifying multiple tags

Si noti come l'intestazione HTTP Tags cambia quando vengono inviati più tag.Notice how the Tags HTTP header changes when multiple tags are sent.

tags = {'sports', 'politics'}
hub.send_windows_notification(wns_payload, tags)

Notifica basata su modelliTemplated notification

Si noti che l'intestazione HTTP Format cambia e che il corpo del payload viene inviato come parte del corpo della richiesta HTTP:Notice that the Format HTTP header changes and the payload body is sent as part of the HTTP request body:

Lato client - modello registratoClient side - registered template

    var template =
                    @"<toast><visual><binding template=""ToastText01""><text id=""1"">$(greeting_en)</text></binding></visual></toast>";

Lato server - invio del payloadServer side - sending the payload

    template_payload = {'greeting_en': 'Hello', 'greeting_fr': 'Salut'}
    hub.send_template_notification(template_payload)

Passaggi successiviNext Steps

Questo argomento ha illustrato come creare un semplice client REST Python per Hub di notifica.In this topic we showed how to create a simple Python REST client for Notification Hubs. A questo punto è possibile:From here you can:

  • Scaricare l'intero esempio di wrapper REST Python, che contiene tutto il codice sopra indicato.Download the full [Python REST wrapper sample], which contains all the code above.
  • Visualizzare altre informazioni sulla funzionalità di aggiunta tag di Hub di notifica nell' esercitazione sull'invio delle ultime notizieContinue learning about Notification Hubs tagging feature in the [Breaking News tutorial]
  • Per altre informazioni sulla funzionalità relativa ai modelli di Hub di notifica, vedere l' esercitazione sull'invio di notizie localizzateContinue learning about Notification Hubs Templates feature in the [Localizing News tutorial]