Difference between revisions of "Python API Wrapper Tutorial"

[unchecked revision][unchecked revision]
Line 1: Line 1:
 
__NOTOC__
 
__NOTOC__
  
This document introduces the Python API library which allows you to administer your MailStore Server via Python.
+
This document explains the installation and usage of the Python API Wrapper  library, which is meant to be an example implementation of a MailStore Server Administration API client. The Administration API allows you to develop scripts for administration of MailStore Server.
 +
 
 +
<p class=msnote>'''Please note:''' It is strongly recommended to use a non-productive test environment for this tutorial as well as for script development in general, in order to prevent loss of data or other problems. For example, the 30-day-trial version of MailStore Server is perfectly suited for this.</p>
  
 
= Installation =
 
= Installation =
Line 7: Line 9:
 
The API library is tested against Python 3.2 to Python 3.4. It is compatible with the 32bit and the 64bit versions of Python.  
 
The API library is tested against Python 3.2 to Python 3.4. It is compatible with the 32bit and the 64bit versions of Python.  
  
You can get your Python binary from the [http://www.python.org/download/ Python download page] or you can install it using the package manager of you distribution.
+
You can get Python binaries for various operating systems from the [http://www.python.org/download/ Python download page] or you can install it using the package manager of your Linux distribution.
  
 
Additionally you need the [ftp://ftp.mailstore.com/pub/Scripts/Python/Python-MailStore-API-Wrapper.zip MailStore API library] which has to be installed in your Python's site-packages ''mailstore'' directory.  The location of the site-packages directory can be found with the following command
 
Additionally you need the [ftp://ftp.mailstore.com/pub/Scripts/Python/Python-MailStore-API-Wrapper.zip MailStore API library] which has to be installed in your Python's site-packages ''mailstore'' directory.  The location of the site-packages directory can be found with the following command
Line 16: Line 18:
 
= Log in =
 
= Log in =
  
The library can be imported with
+
Before the API library can be used to it must first be imported with
 +
 
 
<source lang="python" smart-tabs="true" toolbar="false" gutter="false">
 
<source lang="python" smart-tabs="true" toolbar="false" gutter="false">
 
  import mailstore
 
  import mailstore
 
</source>
 
</source>
and now you are able to instantiate the the ''mailstore.server.Client'' class  
+
 
 +
Now you are able to instantiate the ''mailstore.server.Client'' class  
 
<source lang="python" smart-tabs="true" toolbar="false" gutter="false">
 
<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)
 
  serverClient = mailstore.server.Client(username="admin", password="admin", host="127.0.0.1", port=8463)
 
</source>
 
</source>
  
Default values can be omitted. The admin/admin credentials are only valid when connecting from the MailStore Server server itself and connecting to ''localhost''.
+
Default values can be omitted. The admin/admin credentials are only valid when connecting from the MailStore Server computer itself to ''localhost''.
 +
Find a listing of all default values in the following table:
 +
 
 +
{| class="wikitable"
 +
! width="250px" |Parameter
 +
! Default Value
 +
|-
 +
| username
 +
| admin
 +
|-
 +
| password
 +
| admin
 +
|-
 +
| host
 +
| 127.0.0.1
 +
|-
 +
| port
 +
| 8463
 +
|-
 +
| autoHandleToken
 +
| True
 +
|-
 +
| waitTime
 +
| 1
 +
|-
 +
| logLevel
 +
| 2
 +
|}
  
The available log in arguments and default values are
+
If ''autoHandleToken'' is enabled, you do not have to care about long running processes, instead you just have to wait for the result. When this value is set to ''False'', a status token is returned and you have to handle the token yourself. Further details about long running processes will be give later in this document.
<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>
 
When autoHandleToken is enabled, you do not have to care about long running processes, you just have to wait for the result. When this value is set to ''False'', then the status token is returned and you have to handle the token manually. More about this later.
 
  
 
The ''waitTime'' value specifies the value that is passed to the ''get-status'' call. When you call a long running method like ''VerifyStore'', this is the amount of seconds you have to wait for a status update.
 
The ''waitTime'' value specifies the value that is passed to the ''get-status'' call. When you call a long running method like ''VerifyStore'', this is the amount of seconds you have to wait for a status update.
  
''logLevel'' has to be in the range ''0'' to ''4''. The loglevels are defined as following
+
''logLevel'' has to be in the range ''0'' to ''4'' where loglevel 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''.
0 : "NONE"
 
1 : "ERROR"
 
2 : "WARNING"
 
3 : "INFO"
 
4 : "DEBUG"
 
  
 
Log entries will be printed to ''stdout''.
 
Log entries will be printed to ''stdout''.
  
= Simple calls =
+
= Invoking Simple Calls =
 +
 
 +
Simple calls will always return immediately and not token handling is required.
  
Simple calls will return immediately
 
 
<source lang="python" smart-tabs="true" toolbar="false" gutter="false">
 
<source lang="python" smart-tabs="true" toolbar="false" gutter="false">
 
  print(serverClient.GetServerInfo())
 
  print(serverClient.GetServerInfo())
Line 58: Line 75:
 
  {'machineName': 'WIN2012MS', 'version': '8.1.2.9268'}
 
  {'machineName': 'WIN2012MS', 'version': '8.1.2.9268'}
 
</source>
 
</source>
When the call was succesfull the information is stored in the returned Python dictionary. When the has failed, an HTTP error will be thrown.
 
  
== Exception handling ==
+
When the call was successful the information is stored in the returned Python dictionary. When it failed, an HTTP error will be thrown.
  
When there are no HTTP errors, the returned value is always a python dictionary.
+
== Examples ==
 
 
When an error happens, the call will raise an ''Exception''. All MailStore Exceptions are derived from ''mailstore.errors.MailStoreBaseError'' which itself is derived from ''Exception''.
 
<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>
 
  
= Simple examples =
+
To get detailed information of all users you could use the following snippet:
  
To get all user's detailed information you could
 
 
<source lang="python" smart-tabs="true" toolbar="false" gutter="false">
 
<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)
 
  serverClient = mailstore.server.Client(username="admin", password="admin", host="127.0.0.1", port=8463)
Line 84: Line 88:
 
</source>
 
</source>
  
A list with all assigned email address can be retrieved with
+
A list with all assigned email address can be retrieved as follows:
 +
 
 
<source lang="python" smart-tabs="true" toolbar="false" gutter="false">
 
<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)
 
  serverClient = mailstore.server.Client(username="admin", password="admin", host="127.0.0.1", port=8463)
Line 93: Line 98:
 
</source>
 
</source>
  
= Long running calls =
 
  
Long running calls like ''VerifyStore'' are running asynchronous on the server. When ''autoHandleToken'' is set to ''True'' (default), the library polls the status in the background automatically and will return the final result when the process has ended. Set ''autoHandleToken'' to ''False'' to get the token. In this case you have to handle the token by yourself. There are helper methods available.
+
 
 +
= Long Running Calls =
 +
 
 +
Long running calls like ''VerifyStore'' are running asynchronously on the server. With the Python API Library you can either decide to let the library deal with this polling the status or whether you want to handle it on you own.
 +
 
 +
== Invoking ==
 +
When ''autoHandleToken'' is set to ''True'' (default), the library polls the status in the background automatically and will return the final result when the process has ended. Set ''autoHandleToken'' to ''False'' to get the token. In this case you have to handle the token by yourself. Helper methods for token handling are available.
 +
 
 
<source lang="python" smart-tabs="true" toolbar="false" gutter="false">
 
<source lang="python" smart-tabs="true" toolbar="false" gutter="false">
 
  serverClient = mailstore.server.Client(autoHandleToken=True)
 
  serverClient = mailstore.server.Client(autoHandleToken=True)
Line 104: Line 115:
 
</source>
 
</source>
  
You are able to update the status manually by passing the token to the ''GetStatus'' method. The main call has finished, when the ''status'' has changed from ''running'' to something else.
+
You are able to update the status manually by passing the token to the ''GetStatus'' method. The main call has finished when the ''status'' has changed from ''running'' to something else.
 +
 
 
<source lang="python" smart-tabs="true" toolbar="false" gutter="false">
 
<source lang="python" smart-tabs="true" toolbar="false" gutter="false">
 
  import time
 
  import time
Line 123: Line 135:
 
  {'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'}
 
  {'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>
 
</source>
One could pass the token to the ''HandleToken'' method, then the behavior is exactly the same, as when you would have set ''autoHandleToken=True''.
+
 
 +
Pass the token to the ''HandleToken'' method will behave exactly as if  ''autoHandleToken=True'' would have been set.
 +
 
 
<source lang="python" smart-tabs="true" toolbar="false" gutter="false">
 
<source lang="python" smart-tabs="true" toolbar="false" gutter="false">
 
  serverClient = mailstore.server.Client(autoHandleToken=False)
 
  serverClient = mailstore.server.Client(autoHandleToken=False)
Line 132: Line 146:
 
</source>
 
</source>
  
You are able to set the token handling behavior globally and locally. When you instantiate the client with ''autoHandleToken=True'' you still are able to call every long running method with ''autoHandleToken=False'' and vice versa. Methods that do not return a token, do not accecpt the ''autoHandleToken'' parameter.
+
You are able to set the token handling behavior globally and locally. When you instantiate the client with ''autoHandleToken=True'' you still are able to call every long running method with ''autoHandleToken=False'' and vice versa. Methods that do not return a token, do not accept the ''autoHandleToken'' parameter.
 +
 
 
<source lang="python" smart-tabs="true" toolbar="false" gutter="false">
 
<source lang="python" smart-tabs="true" toolbar="false" gutter="false">
 
  serverClient = mailstore.server.Client(autoHandleToken=False)
 
  serverClient = mailstore.server.Client(autoHandleToken=False)
Line 142: Line 157:
 
</source>
 
</source>
  
= Cancelling long running calls =
+
== Cancelling ==
  
 
Currently long running calls cannot be cancelled. This is not a limitation of the Python wrapper, but of the Management API itself. This will be changed in the next major release of MailStore Server.
 
Currently long running calls cannot be cancelled. This is not a limitation of the Python wrapper, but of the Management API itself. This will be changed in the next major release of MailStore Server.
  
= Pretty Printing the output =
+
= Exception Handling =
 +
 
 +
When there are no HTTP errors, the returned value is always a python dictionary.
 +
 
 +
In case an error occured, the call will raise an ''Exception''. All MailStore Exceptions are derived from ''mailstore.errors.MailStoreBaseError'' which itself is derived from ''Exception''.
 +
 
 +
<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>
 +
 
 +
= Pretty Printing the Output =
  
 
There is a helper function that formats the returned values in more readable manner.
 
There is a helper function that formats the returned values in more readable manner.
 +
 
<source lang="python" smart-tabs="true" toolbar="false" gutter="false">
 
<source lang="python" smart-tabs="true" toolbar="false" gutter="false">
 
  mailstore.pprint(serverClient.GetUserInfo("admin"))
 
  mailstore.pprint(serverClient.GetUserInfo("admin"))
Line 160: Line 192:
 
</source>
 
</source>
  
= Function overview =
+
= Methods Overview=
 
 
All the methods listed in [[MailStore_Server_Administration_API_Commands|the method overview]] are implemented.
 
  
== Additional methods ==
+
All the methods listed in [[MailStore_Server_Administration_API_Commands|the method overview]] are implemented in the Python API library.
  
There are additional methods available. Please see the source code for further details.
+
Additional (helper) methods available. Please see the source code for further details about these methods.
  
 
[[de:Python API-Wrapper Tutorial]]
 
[[de:Python API-Wrapper Tutorial]]
 
[[en:Python API Wrapper Tutorial]]
 
[[en:Python API Wrapper Tutorial]]

Revision as of 09:00, 17 April 2014


This document explains the installation and usage of the Python API Wrapper library, which is meant to be an example implementation of a MailStore Server Administration API client. The Administration API allows you to develop scripts for administration of MailStore Server.

Please note: It is strongly recommended to use a non-productive test environment for this tutorial as well as for script development in general, in order to prevent loss of data or other problems. For example, the 30-day-trial version of MailStore Server is perfectly suited for this.

Installation

The API library is tested against Python 3.2 to Python 3.4. It is compatible with the 32bit and the 64bit versions of Python.

You can get Python binaries for various operating systems from the Python download page or you can install it using the package manager of your Linux distribution.

Additionally you need the MailStore API library which has to be installed in your Python's site-packages mailstore directory. The location of the site-packages directory can be found with the following command

 python -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())"

Log in

Before the API library can be used to it must first be imported with

 import mailstore

Now you are able to instantiate the mailstore.server.Client class

 serverClient = mailstore.server.Client(username="admin", password="admin", host="127.0.0.1", port=8463)

Default values can be omitted. The admin/admin credentials are only valid when connecting from the MailStore Server computer itself to localhost. Find a listing of all default values in the following table:

Parameter Default Value
username admin
password admin
host 127.0.0.1
port 8463
autoHandleToken True
waitTime 1
logLevel 2

If autoHandleToken is enabled, you do not have to care about long running processes, instead you just have to wait for the result. When this value is set to False, a status token is returned and you have to handle the token yourself. Further details about long running processes will be give later in this document.

The waitTime value specifies the value that is passed to the get-status call. When you call a long running method like VerifyStore, this is the amount of seconds you have to wait for a status update.

logLevel has to be in the range 0 to 4 where loglevel 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 be printed to stdout.

Invoking Simple Calls

Simple calls will always return immediately and not token handling is required.

 print(serverClient.GetServerInfo())
 
 {'machineName': 'WIN2012MS', 'version': '8.1.2.9268'}

When the call was successful the information is stored in the returned Python dictionary. When it failed, an HTTP error will be thrown.

Examples

To get detailed information of all users you could use the following snippet:

 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"]))

A list with all assigned email address can be retrieved as follows:

 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)


Long Running Calls

Long running calls like VerifyStore are running asynchronously on the server. With the Python API Library you can either decide to let the library deal with this polling the status or whether you want to handle it on you own.

Invoking

When autoHandleToken is set to True (default), the library polls the status in the background automatically and will return the final result when the process has ended. Set autoHandleToken to False to get the token. In this case you have to handle the token by yourself. Helper methods for token handling are available.

 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'}]}

You are able to update the status manually by passing the token to the GetStatus method. The main call has finished when the status has changed from running to something else.

 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'}

Pass the token to the HandleToken method will behave exactly as if autoHandleToken=True would have been set.

 serverClient = mailstore.server.Client(autoHandleToken=False)
 storeID = 2
 token = serverClient.VerifyStore(storeID)
 print(token)
 print(serverClient.HandleToken(token))

You are able to set the token handling behavior globally and locally. When you instantiate the client with autoHandleToken=True you still are able to call every long running method with autoHandleToken=False and vice versa. Methods that do not return a token, do not accept the autoHandleToken parameter.

 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}

Cancelling

Currently long running calls cannot be cancelled. This is not a limitation of the Python wrapper, but of the Management API itself. This will be changed in the next major release of MailStore Server.

Exception Handling

When there are no HTTP errors, the returned value is always a python dictionary.

In case an error occured, the call will raise an Exception. All MailStore Exceptions are derived from mailstore.errors.MailStoreBaseError which itself is derived from Exception.

 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

Pretty Printing the Output

There is a helper function that formats the returned values in more readable manner.

 mailstore.pprint(serverClient.GetUserInfo("admin"))

 authentication integrated
 distinguishedName 
 privileges
    admin
 fullName Administrator
 userName admin

Methods Overview

All the methods listed in the method overview are implemented in the Python API library.

Additional (helper) methods available. Please see the source code for further details about these methods.