First, define the location of the Adama server.
The official server is:
For a development environment the URL may differ (for example: http://localhost/community/v0.3
). Use a URL such that URL/status
reaches the status
endpoint of your server.
In [29]:
API = 'http://192.168.35.10/community/v0.3'
The official Adama server requires a bearer token, but other test services may not need it. Leave it empty in such case.
In [30]:
TOKEN = 'mytoken'
Create an adama
object bound to the API server:
In [31]:
import adamalib
reload(adamalib.adamalib)
adama = adamalib.Adama(API, token=TOKEN)
Check that the object is correctly linked by asking the status of the server. This is equivalent to performing a GET
request to the endpoint API/status
. It should return a dictionary of the form:
{u'api': u'Adama v0.3',
u'hash': u'...',
u'status': u'success'}
In [32]:
adama.status
Out[32]:
Namespaces are accessed with the property namespaces
. It returns a list of namespace objects, each of them can be queried for its information:
In [33]:
adama.namespaces
Out[33]:
Let's create a new random namespace.
First, a detour for a simple function to generate random names, so we don't overwrite existing ones (not likely, at least):
In [34]:
import requests
import string
import random
lorem = requests.get('http://loripsum.net/api/plaintext').text
WORDS = [word.lower()
for word in filter(lambda c: c not in string.punctuation, lorem).split()]
def random_words(n=2):
return '_'.join(random.choice(WORDS) for i in range(n))
Create a namespace with a random name:
In [35]:
namespace = adama.namespaces.add(name=random_words())
namespace
Out[35]:
The new namespace should appear if we ask again:
In [36]:
adama.namespaces
Out[36]:
A particular namespace, say foo
, can be accessed directly as adama.foo
.
List the services contained in a namespace with:
In [37]:
namespace.services
Out[37]:
The result should be the empty list, since we just created a new namespace.
Let's create a simple service that prints the local time. adamalib
provides functions to initialize an empty service in the local machine, and then to register it in the remote API server.
The following command creates a service with a random name, creating a directory with the same name and with the bare minimum information necessary to register the service.
In [38]:
SERVICE = random_words(n=1)
adama.utils.create(SERVICE, 'query')
SERVICE
Out[38]:
The metadata file created contains only the most basic information. Consult the docs for the full list of fields.
In [46]:
!cat $SERVICE/metadata.yml
The following function is an example of a very basic service, which just prints an argument, and the localtime.
The first line (%%writefile ...
) is a "magic" command to save the cell to the newly created service.
In [39]:
%%writefile {SERVICE}/main.py
import json
import datetime
def search(args, adama):
print(json.dumps({'name': args.get('name', 'no name given')}))
print('---')
print(json.dumps({'localtime': datetime.datetime.now().isoformat(' ')}))
Import the module just created:
In [40]:
import importlib
service_module = importlib.import_module(SERVICE+'.main')
reload(service_module)
Out[40]:
It can be tested immediately:
In [41]:
service_module.search({'name': 'foo'}, adama)
The last three cells can be edited and re-evaluated until satisfied with the output of the service.
Next, we proceed to register the service. We use adamalib
to add the module to the services
list of the proper namespace. adamalib
takes care of uploading any other module needed by service_module
, including the file metadata.yml
.
In [42]:
service = namespace.services.add(service_module)
service
Out[42]:
The basic operation on the service of type query
is to perform a search. The following command performs a GET
request to the /search
endpoint of the service:
In [43]:
service.search(name='bar')
Out[43]:
To tidy things up, we delete the service and the namespace:
In [44]:
service.delete()
namespace.delete()