Python API-Wrapper Tutorial: Unterschied zwischen den Versionen

[unmarkierte Version][gesichtete Version]
 
(20 dazwischenliegende Versionen von 3 Benutzern werden nicht angezeigt)
Zeile 1: Zeile 1:
__NOTOC__
+
{{raw::en:Python API Wrapper Tutorial}}
  
Dieses Dokument stellt die Python API Bibliothek vor, mit der sich der MailStore Server administrieren lässt.
+
[[de:Python API-Wrapper Tutorial]]
 
+
[[en:Python API Wrapper Tutorial]]
= Installation =
 
 
 
Die API Bibliothek wurde mit den Python Versionen 3.2 bis 3.4 getestet. Sie ist kompatibel mit der 32-Bit sowie der 64-Bit Version von Python.
 
 
 
Das Python Installationspaket kann von [http://www.python.org/download/ der Python Download Seite] heruntergeladen werden. Alternativ kann Python über den Paket Manager der Distribution installiert werden.
 
 
 
Zusätzlich wird die [ftp://ftp.mailstore.com/pub/Scripts/Python/Python-MailStore-API-Wrapper.zip MailStore Python API Bibliothek] benötigt. Diese muss in das ''mailstore''-Verzeichnis des ''site-packages''-Verzeichnisses der Python-Installation kopiert werden. Der Ort des ''site-packages''-Verzeichnisses lässt sich mittels
 
<source lang="python" smart-tabs="true" toolbar="false" gutter="false">
 
python -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())"
 
</source>
 
herausfinden.
 
 
 
= Log in =
 
 
 
Die Bibiliothek kann mittels
 
<source lang="python" smart-tabs="true" toolbar="false" gutter="false">
 
import mailstore
 
</source>
 
importiert werden. Nun kann die ''mailstore.server.Client'' Klasse instanziiert werden.
 
<source lang="python" smart-tabs="true" toolbar="false" gutter="false">
 
serverClient = mailstore.server.Client(username="admin", password="admin", host="127.0.0.1", port=8463)
 
</source>
 
 
 
Standardwerte können ausgelasen werden.
 
 
 
Die verfügbaren Parameter und die Standardwerte sind
 
<source lang="python" smart-tabs="true" toolbar="false" gutter="false">
 
username = "admin"
 
password = "admin"
 
host = "127.0.0.1"
 
port = 8463
 
autoHandleToken = True
 
waitTime = 1
 
logLevel = 2
 
</source>
 
 
 
Wenn ''autoHandleToken'' aktiviert ist, muss man sich nicht manuell um die Verarbeitung des zurückgegebenen Tokens kümmern. Die Bibliothek kümmert sich darum. Nach Beendigung der Methode wird das Ergebnis zurückgeliefert. Wenn ''autoHandleToken'' deaktiviert ist, wird das Token zurückgegeben, welches den Aufruf identifiziert. Mehr dazu später.
 
 
 
Der ''waitTime'' Wert gibt die Zeit in Sekunden an, die die Bibliothek zwischen zwei aufrufen von ''get-status'' wartet. ''get-status'' wird aufgerufen, wenn der Status einer Methode abgerufen werden soll, die ein Token zurückgeliefert hat.
 
 
 
''logLevel'' muss im Bereich von ''0'' bis ''4'' liegen. Die Loglevel sind wie folgt definiert
 
0 : "NONE"
 
1 : "ERROR"
 
2 : "WARNING"
 
3 : "INFO"
 
4 : "DEBUG"
 
 
 
Log-Einträge werden auf ''stdout'' ausgegeben.
 
 
 
= Einfache Aufrufe =
 
 
 
Einfache Aufrufe liefern das Ergebnis sofort zurück
 
<source lang="python" smart-tabs="true" toolbar="false" gutter="false">
 
print(serverClient.GetServerInfo())
 
 
{'machineName': 'WIN2012MS', 'version': '8.1.2.9268'}
 
</source>
 
Wenn der Aufruf erfolgreich war, wird der Ergebnis in Form eines Python Dictionarys zurückgegeben. Wenn der Aufruf misslang, wird ein HTTP Fehler geworfen.
 
 
 
== Fehlerbehandlung ==
 
 
 
Wenn ein Fehler auftrit, wirft die aufrufende Methode eine ''Exception''. Alle MailStore Fehlerklassen sind von der Basisklasse ''mailstore.errors.MailStoreBaseError'' abgeleitet, welche ihrerseits von ''Exception'' abgeleitet ist.
 
<source lang="python" smart-tabs="true" toolbar="false" gutter="false">
 
try:
 
    print(serverClient.GetUserInfo("not_such_user"))
 
except mailstore.errors.MailStoreBaseError as e:
 
    print(e)
 
 
ERROR ('internal MailStore Server error',)
 
500 Internal Server Error https://127.0.0.1:8463/JSON/Invoke/GetUserInfo POST userName=not_such_user Command in MethodList: True
 
</source>
 
 
 
= Einfache Beispiele =
 
 
 
Um die detaillierten Informationen aller Benutzer zu erhalten:
 
<source lang="python" smart-tabs="true" toolbar="false" gutter="false">
 
serverClient = mailstore.server.Client(username="admin", password="admin", host="127.0.0.1", port=8463)
 
for user in serverClient.GetUserList():
 
    print(serverClient.GetUserInfo(user["userName"]))
 
</source>
 
 
 
Eine Liste aller zugewiesenen E-Mail-Adressen erhält man mit:
 
<source lang="python" smart-tabs="true" toolbar="false" gutter="false">
 
serverClient = mailstore.server.Client(username="admin", password="admin", host="127.0.0.1", port=8463)
 
emailaddresses = list()
 
for user in serverClient.GetUserList():
 
    emailaddresses += serverClient.GetUserInfo(user["userName"])['emailAddresses']
 
print(emailaddresses)
 
</source>
 
 
 
= Lang laufende Methoden =
 
 
 
Lang laufende Methoden wie ''VerifyStore'' laufen asynchron im Hintergrund auf dem Server. Wenn ''autoHandleToken'' auf ''True'' (Standardwert) gesetzt ist, fragt die Bibliothek den Server automatisch, periodisch nach Statusänderungen ab und gibt das Ergebnis zurück, sobald dieses vorliegt. Ist ''autoHandleToken'' deaktiviert, wird das Token zurückgegeben. In diesem Fall muss man sich um die Statusaktuelisierungen manuell kümmern. Dafür existieren Hilfsmethoden.
 
 
 
''autoHandleToken'' ist aktiviert:
 
<source lang="python" smart-tabs="true" toolbar="false" gutter="false">
 
serverClient = mailstore.server.Client(autoHandleToken=True)
 
storeID = 1
 
print(serverClient.VerifyStore(storeID))
 
 
{'status': 'succeeded', 'progressPercentage': 100, 'messages': [{'text': 'Verifying file group #2...', 'type': 'line'}, {'text': 'Creating a list of messages to be verified...', 'type': 'line'}, {'text': '234 messages are about to be verified.', 'type': 'line'}, {'text': 'Verifying...', 'type': 'line'}, {'text': '  100 messages verified...', 'type': 'line'}, {'text': '  200 messages verified...', 'type': 'line'}, {'text': '  234 messages verified.', 'type': 'line'}, {'text': 'Finished. No errors have been found.', 'type': 'line'}]}
 
</source>
 
 
 
Es ist möglich, die Statusaktualisierung manuell durchzuführen, dazu muss das Token an die ''GetStatus'' Methode übergeben werden. Der Aufruf ist beendet wenn der ''status'' nicht mehr ''running'' ist. Der im Beispiel gezeigte Wartezeitraum (time.sleep(1)) entspricht dem ''waitTime''-Wert, der der Klasse mitgegeben werden kann.
 
<source lang="python" smart-tabs="true" toolbar="false" gutter="false">
 
import time
 
 
 
serverClient = mailstore.server.Client(autoHandleToken=False) 
 
storeID = 2
 
token = serverClient.VerifyStore(storeID)
 
print(token)
 
while True:
 
    time.sleep(1)
 
    status = serverClient.GetStatus(token)
 
    print(status)
 
    if status["status"] != "running":
 
        break
 
 
 
{'statusUrl': '/JSON/Status/243fc983-89c3-19ef-196a-dbe082894cc5', 'statusToken': '243fc983-89c3-19ef-196a-dbe082894cc5'}
 
{'progressPercentage': 0, 'messages': [{'type': 'line', 'text': 'Verifying file group #2...'}, {'type': 'line', 'text': 'Creating a list of messages to be verified...'}, {'type': 'line', 'text': '234 messages are about to be verified.'}, {'type': 'line', 'text': 'Verifying...'}, {'type': 'line', 'text': '  100 messages verified...'}], 'status': 'running'}
 
{'progressPercentage': 100, 'messages': [{'type': 'line', 'text': 'Verifying file group #2...'}, {'type': 'line', 'text': 'Creating a list of messages to be verified...'}, {'type': 'line', 'text': '234 messages are about to be verified.'}, {'type': 'line', 'text': 'Verifying...'}, {'type': 'line', 'text': '  100 messages verified...'}, {'type': 'line', 'text': '  200 messages verified...'}, {'type': 'line', 'text': '  234 messages verified.'}, {'type': 'line', 'text': 'Finished. No errors have been found.'}], 'status': 'succeeded'}
 
</source>
 
Man kann das Token an die ''HandleToken''-Methode übergeben. In diesem Fall entspricht das Verhalten exakt dem, als wenn man ''autoHandleToken'' auf ''True'' gesetzt hätte..
 
<source lang="python" smart-tabs="true" toolbar="false" gutter="false">
 
serverClient = mailstore.server.Client(autoHandleToken=False)
 
storeID = 2
 
token = serverClient.VerifyStore(storeID)
 
print(token)
 
print(serverClient.HandleToken(token))
 
</source>
 
 
 
Das Verhalten des Token-Handlings kann global und lokal gesetzt werden. Wenn die Klasse mit ''autoHandleToken=True'' instanziiert wird, von einzelne Methoden jedoch das Token benötigt wird, kann der Methode der zusätzliche Parameter ''autoHandleToken=False'' übergeben werden. Umgekehrt ist dies genauso möglich. Die Klasse wird mit ''autoHandleToken=False'' instanziiert, die einzene Methode kann dennoch mit dem Parameter ''autoHandleToken=True'' aufgerufen werden. Methoden die nicht lang laufend sind, akzeptieren den ''autoHandleToken''-Parameter nicht.
 
<source lang="python" smart-tabs="true" toolbar="false" gutter="false">
 
serverClient = mailstore.server.Client(autoHandleToken=False)
 
storeID = 2
 
token = serverClient.VerifyStore(storeID, autoHandleToken=True)
 
print(token)
 
 
 
{'status': 'succeeded', 'messages': [{'text': 'Verifying file group #2...', 'type': 'line'}, {'text': 'Creating a list of messages to be verified...', 'type': 'line'}, {'text': '234 messages are about to be verified.', 'type': 'line'}, {'text': 'Verifying...', 'type': 'line'}, {'text': '  100 messages verified...', 'type': 'line'}, {'text': '  200 messages verified...', 'type': 'line'}, {'text': '  234 messages verified.', 'type': 'line'}, {'text': 'Finished. No errors have been found.', 'type': 'line'}], 'progressPercentage': 100}
 
</source>
 
 
 
= Abbrechen lang laufender Methoden =
 
 
 
Aktuell können lang laufende Methoden nicht abgebrochen werden. Dies ist keine Limitierung der Python Bibliothek sondern der Management API als solches. Dieser Umstand wird in der nächsten MailStore Server Hauptversion behoben werden.
 
 
 
= Formatierung der Ausgabe =
 
 
 
Es gibt eine Hilfsfunktion, die die zurückgelieferten ''Dictionarys'' formatiert ausgeben kann.
 
<source lang="python" smart-tabs="true" toolbar="false" gutter="false">
 
mailstore.pprint(serverClient.GetUserInfo("admin"))
 
 
 
authentication integrated
 
distinguishedName
 
privileges
 
    admin
 
fullName Administrator
 
userName admin
 
</source>
 
 
 
= Funktionsübersicht =
 
 
 
Alle Methoden die in der [[MailStore_Server_Administration_API_Commands|Übersicht]] aufgelistet sind, sind auch implementiert.
 
 
 
== Zusätzliche Methoden ==
 
 
 
Zusätzliche Methoden sind verfügbar. Bitte schauen Sie in den Quellcode der Bibliothek, um mehr Details zu erfahren.
 

Aktuelle Version vom 23. Februar 2016, 14:51 Uhr

Important notice: The Python API wrapper for the MailStore Server Administration API provided on this website, represents an example implementation of an API client. This wrapper should help system administrators and developers to quickly understand how the Administration API of MailStore Server works and how to use it in own scripts. Please understand that beyond this documentation no further support for the Python API wrapper is provided. Unless stated otherwise, the Python API wrapper as well as all related example scripts are released under the terms an conditions of the MIT License.

This document explains the installation and usage of the Python API wrapper for the MailStore Server Administration API. In order to prevent loss of data, service interruption or other problems, it is highly recommended to use a non-productive test environment for this tutorial as well as for script development in general. The 30-day-trial version of MailStore Server is perfectly suited for this.

Installation

The API wrapper library is tested against Python 3.6 and newer and is compatible with 32bit and 64bit versions of Python.

Python binaries for various operating systems can be downloaded from the Python download page or installed using the package manager of most Linux distributions.

Additionally create a folder "mailstore" in the Python's site-packages directory and extract the files from the Python API Wrapper into this folder.

In a UNIX like operating system the location of the site-packages directory can be found by executing the following command in a shell:

python3 -c "import site; print(site.getsitepackages())"

In Windows the location of the site-packages directory can be found by opening a cmd, navigating in the Python3 installation directory and executing the following command:

python -c "import site; print(site.getsitepackages())"

Instantiating the API Client

Before the API wrapper library can be used, it must first be imported with:

 import mailstore

Now the mailstore.mgmt.ServerClient class can be instantiated as follows:

serverClient = mailstore.mgmt.ServerClient(username="admin", password="admin", host="127.0.0.1", port=8463)

Default values can be omitted. The default admin credentials (username and password set to admin) are only usable when connecting from the MailStore Server computer itself to localhost. Find a listing of all default values in the following table:

Parameter Default Value Description
username admin Username used for connecting to the API.
password admin Password used for connecting to the API.
host 127.0.0.1 Hostname or IP address of the MailStore Server computer.
port 8463 TCP port on which MailStore Server is listening for API requests.
autoHandleToken True If set to True, the caller does not need to handle tokens of long running tasks, but instead has to wait for the result. When set to False and the statusCode is running, a status token is returned and must be handled appropriately by the caller of the method. Further details about token handling is described the corresponding section Automatic Token Handling of this document.
waitTime 1000 Specifies the number of milliseconds the API should wait for a final result. Otherwise the process is treated as running, in which case token handling as defined by the status of autoHandleToken becomes necessary.
callback None A callback function to which interim statuses of long running tasks should be passed. This allows keeping track of the tasks' progress even if autoHandleToken is enabled. This can be quite useful in order to notify users about the progress without having to deal with the token logic as a whole.
logLevel 2 Has to be in the range 0 to 4, where 0 (NONE) has the lowest verbosity and 4 (DEBUG) the highest. The loglevels are defined in the following order (low to high verbosity) NONE, ERROR, WARNING, INFO and DEBUG. Log entries will always be printed to stdout.
ignoreInvalidSSLCerts False Has to be set to True or False. Has to be enabled if untrusted certificates are used, otherwise an error occurs.

Invoking API Method

After the API client has been successfully instantiated, API methods can easily be invoked. When the method call was successful, the statusCode is succeeded and the result is stored in the dictionary result as shown in the following example:

print(serverClient.GetServerInfo())
 
{'logOutput': None, 'statusText': None, 'error': None, 'percentProgress': None, 'token': None, 'result': {'machineName': 'WIN-2012-R2-X64', 'version': '9.0.3.9857'}, 'statusVersion': 2, 'statusCode': 'succeeded'}

If autoHandleToken was set to False and the statusCode returns running, manual token handling is required as described in the Automatic Token Handling section.

For any other statusCode value than succeeded and running the occurrence of an error has to be assumed, in which further information such as the error message and error details are available in the dictionary error as shown below:

userInfo = serverClient.GetUserInfo("john.doe")

if userInfo["statusCode"] == 'succeeded':
    print(userInfo["result"]["emailAddresses"])
else:
    print(userInfo["error"]["message"])

Examples

Create and print a list of all email addresses assigned to MailStore users.

serverClient = mailstore.mgmt.ServerClient()
addresses = list()
for user in serverClient.GetUsers()["result"]:
	addresses += serverClient.GetUserInfo(user["userName"])["result"]["emailAddresses"]
print("\n".join(sorted(set(addresses))))

Create and print a list of all regular users archive privileges

serverClient = mailstore.mgmt.ServerClient()

privileges_map = dict()
for user in serverClient.GetUsers()["result"]:
    user_info = serverClient.GetUserInfo(user["userName"])["result"]
    if "privilegesOnFolders" in user_info:
        for privilege in user_info["privilegesOnFolders"]:
            if privilege["folder"] not in privileges_map:
                privileges_map[privilege["folder"]] = {user["userName"]: privilege["privileges"]}
            else:
                privileges_map[privilege["folder"]].update({user["userName"]: privilege["privileges"]})

for archive, user_dict in privileges_map.items():
    print("Archive: {}".format(archive))
    for username, priv in user_dict.items():
        print("\tUser: {}: {}".format(username, ", ".join(priv)))

Create and print a list of all admin users.

serverClient = mailstore.mgmt.ServerClient()
admins = list()

for user in serverClient.GetUsers()["result"]:
    if "admin" in serverClient.GetUserInfo(user["userName"])["result"]["privileges"]:
        admins.append(user["userName"])

print("\n".join(admins))

Long Running Tasks

The execution of certain API methods like VerifyStore may take several minutes or even hours until it finishes. There are different options available to deal with these long running tasks:

  1. Automatic Token Handling
  2. Automatic Token Handling with Callback Function
  3. Manual Token Handling

Generally it is recommended to expect that every method call can become a long running task, as this depends on the waitTime value, the called method but also the overall load on the server. Thus it is not advisable to globally turn off automatic token handling when instantiating the API client.

If desired, automatic token handling can be enabled or disabled for each invoked method by adding autoHandleToken=True/False to the method's argument list.

Once a method has been invoked with manual token handling or a callback function, it can be cancelled by using the CancelAsync method as described in Cancelling Long Running Tasks.

Automatic Token Handling

When autoHandleToken is set to True (default), the wrapper polls the status of long running tasks automatically in the background and will return the final result when the process has ended.

Code

import mailstore

serverClient = mailstore.mgmt.ServerClient(autoHandleToken=True)
storeID = 1
print(serverClient.VerifyStore(storeID))

Output

{'logOutput': None, 'statusText': None, 'error': None, 'percentProgress': 100, 'token': 'd242d822a59bd4db308eef8b85af7d2a', 'result': None, 'statusVersion': 71, 'statusCode': 'succeeded'}

Automatic Token Handling with Callback Function

If a caller wants to keep track of the progress of a long running task (i.e. to inform the user about the progress), although automatic token handling was enabled, he could pass a function as callback argument to the instance of the API client.

Code

import mailstore

def showProgress(progress):
   print(progress["logOutput"], end="", flush=True)

serverClient = mailstore.mgmt.ServerClient(autoHandleToken=True, callback=showProgress)
storeID = 3
print(serverClient.VerifyStore(storeID))

Output

Verifying file group #3...
Creating a list of messages to be verified...
1249 messages are about to be verified.
Verifying...
  100 messages verified...
  200 messages verified...
  300 messages verified...
  400 messages verified...
  500 messages verified...
  600 messages verified...
  700 messages verified...
  800 messages verified...
  900 messages verified...
  1000 messages verified...
  1100 messages verified...
  1200 messages verified...
  1249 messages verified.
Finished. No errors have been found.
{'error': None, 'result': None, 'logOutput': '  1000 messages verified...\r\n  1100 messages verified...\r\n  1200 messages verified...\r\n  1249 messages verified.\r\nFinished. No errors have been found.\r\n', 'token': 'c56f032d9db263133c1a413f79744b84', 'statusVersion': 71, 'statusText': None, 'percentProgress': 100, 'statusCode': 'succeeded'}

Manual Token Handling

If autoHandleToken is set to False the caller must handle long running tasks and the corresponding tokens all by itself. To poll for status updates, the GetStatus method must be called periodically passing the last returned result as parameter. GetStatus will extract the status token itself, poll for the latest update and return the received data to the caller again. The main call has finished when the statusCode changes to something different than running. Calling GetStatus without passing a status token will result in an exception.

Code

import mailstore
import time

serverClient = mailstore.mgmt.ServerClient(autoHandleToken=False)
storeID = 3
status = serverClient.VerifyStore(storeID)

while True:
    if status["statusCode"] != "running":
        break
    print(status["logOutput"], end="", flush=True)
    status = serverClient.GetStatus(status)
    time.sleep(1)

Output

Verifying file group #3...
Creating a list of messages to be verified...
1249 messages are about to be verified.
Verifying...
  100 messages verified...
  200 messages verified...
  300 messages verified...
  400 messages verified...
  500 messages verified...
  600 messages verified...
  700 messages verified...
  800 messages verified...
  900 messages verified...
  1000 messages verified...
  1100 messages verified...
  1200 messages verified...
  1249 messages verified.
Finished. No errors have been found.

Cancelling Long Running Tasks

Tasks invoked by using the callback method or manual token handling, can be canceled at any time by using the CancelAsync method. Please notice that the API does not acknowledge the success of the cancellation request. Instead the caller must continue to monitor the statusCode of the canceled method.

Code

import mailstore
import time

serverClient = mailstore.mgmt.ServerClient(autoHandleToken=False)
storeID = 3
status = serverClient.VerifyStore(storeID)

while True:
    if status["statusCode"] != "running":
        break
    print(status["logOutput"], end="")
    status = serverClient.GetStatus(status)
    time.sleep(1)
    serverClient.CancelAsync(status)

Output

Verifying file group #3...
Creating a list of messages to be verified...
1249 messages are about to be verified.
Verifying...
  100 messages verified...
  200 messages verified...
  300 messages verified...
  400 messages verified...
  500 messages verified...
  600 messages verified...
  700 messages verified...
  800 messages verified...
  900 messages verified...
  1000 messages verified...
  1100 messages verified...

Methods Overview

All methods listed in the function reference are implemented in the Python API library. Use

 pydoc3 mailstore.mgmt.ServerClient

to access the build in documentation, which also includes an overview of all methods and their parameters.