#!/usr/bin/env python # -*- coding: utf-8 -*- """ UJS REST-v1 Beispiel für Python ohne externe Abhängigkeiten. Kompatibel mit Python 2.7 und Python 3.x. Einbindung in ein Projekt: from example_python import UjsClient client = UjsClient('https://dev.jsonstorage.de', 'TOKEN', 'testmodul') result = client.store('test_note', 'TEST-1001', {'title': 'Hallo'}) Direkt ausführen: python example_python.py """ from __future__ import print_function import json import os import sys import time try: from urllib.parse import urlencode from urllib.request import Request, urlopen from urllib.error import HTTPError, URLError except ImportError: # Python 2.7 from urllib import urlencode from urllib2 import Request, urlopen, HTTPError, URLError # Zugangsdaten für den Beispielaufruf. # Einen echten Token hier nur lokal eintragen, nicht in eine öffentlich # abrufbare Datei schreiben. UJS_BASE_URL = 'https://dev.jsonstorage.de' UJS_MODULE = 'testmodul' UJS_TOKEN = '2618a9dd9eba3515b50c427d66e5635b1bda91cf443e51ce' class UjsClient(object): def __init__(self, base_url, token, module_slug): self.base_v1 = base_url.rstrip('/') + '/api/v1' self.token = token self.module_slug = module_slug def whoami(self): return self.request('GET', '/whoami') def list_entries(self, query=None): return self.request('GET', '/modules/%s/entries' % self.module_slug, query or {}) def store(self, type_, customer_no, data, tags=None): return self.request('POST', '/modules/%s/entries' % self.module_slug, body={ 'type': type_, 'customer_no': customer_no, 'data': data, 'tags': tags or [], }) def get(self, id_): return self.request('GET', '/modules/%s/entries/%s' % (self.module_slug, int(id_))) def update(self, id_, patch, if_version=None): headers = {} if if_version is not None: headers['If-Match'] = '"v%s"' % int(if_version) return self.request('PUT', '/modules/%s/entries/%s' % (self.module_slug, int(id_)), body=patch, extra_headers=headers) def history(self, id_, limit=100, offset=0): return self.request('GET', '/modules/%s/entries/%s/history' % (self.module_slug, int(id_)), { 'limit': int(limit), 'offset': int(offset), }) def aggregate(self, query): return self.request('GET', '/modules/%s/aggregate' % self.module_slug, query) def delete(self, id_): return self.request('DELETE', '/modules/%s/entries/%s' % (self.module_slug, int(id_))) def request(self, method, path, query=None, body=None, extra_headers=None): query = query or {} extra_headers = extra_headers or {} clean_query = {} for key, value in query.items(): if value is not None and value != '': clean_query[key] = value url = self.base_v1 + path if clean_query: url += '?' + urlencode(clean_query) raw_body = b'' if body is not None: raw_text = json.dumps(body, ensure_ascii=False) raw_body = raw_text.encode('utf-8') headers = { 'Authorization': 'Bearer ' + self.token, 'X-Request-ID': 'example-%s-%s' % (int(time.time()), os.getpid()), } if body is not None: headers['Content-Type'] = 'application/json' headers.update(extra_headers) request = Request(url, data=raw_body if raw_body else None, headers=headers) request.get_method = lambda: method try: response = urlopen(request, timeout=30) status = response.getcode() raw_response = response.read() except HTTPError as exc: status = exc.code raw_response = exc.read() except URLError as exc: return {'success': False, 'error': str(exc), '_status': 0} if not isinstance(raw_response, str): raw_response = raw_response.decode('utf-8') try: out = json.loads(raw_response) if raw_response else {} except ValueError: out = {'raw': raw_response} out['_status'] = status return out def print_step(title, data): print('\n=== %s ===' % title) print(json.dumps(data, indent=2, ensure_ascii=False)) def main(): base_url = os.environ.get('UJS_BASE_URL', UJS_BASE_URL) module = os.environ.get('UJS_MODULE', UJS_MODULE) token = os.environ.get('UJS_TOKEN', UJS_TOKEN) if not token: print('Bitte oben UJS_TOKEN setzen oder per Umgebungsvariable übergeben.', file=sys.stderr) return 1 client = UjsClient(base_url, token, module) print_step('Token prüfen', client.whoami()) created = client.store('test_note', 'TEST-1001', { 'title': 'UJS Testeintrag', 'status': 'open', 'created_by': 'example_python.py', 'amount': 129.90, }, ['testmodul', 'python']) print_step('Eintrag erstellen', created) entry = created.get('entry') or {} id_ = entry.get('id') if id_: print_step('Eintrag lesen', client.get(id_)) print_step('Liste filtern', client.list_entries({ 'customer_no': 'TEST-1001', 'q[data.status]': 'open', 'limit': 10, })) print_step('Eintrag aktualisieren', client.update(id_, { 'data': { 'title': 'UJS Testeintrag', 'status': 'done', 'created_by': 'example_python.py', 'amount': 129.90, }, 'tags': ['testmodul', 'python', 'done'], }, entry.get('version'))) print_step('Historie', client.history(id_)) print_step('Aggregation', client.aggregate({ 'agg': 'sum', 'field': 'amount', 'group_by': 'customer_no', })) if os.environ.get('UJS_DELETE_AFTER') == '1': print_step('Eintrag löschen', client.delete(id_)) return 0 if __name__ == '__main__': sys.exit(main())