Source code for zot.services.api

# zot/plugs/api.py
#
#

""" Object Copy API. """

__copyright__ = "Copyright 2015, B.H.J Thate"

## IMPORTS

from zot.utils import run_thr, error, get_exception, list_files, j, get_source
from zot.object import Object
from zot.defaults import cfg_api
from zot.runtime import kernel, cfg
from zot import __version__

import urllib.parse
import urllib
import logging
import select
import socket
import time
import http
import cgi
import sys
import os

from http.server import HTTPServer, BaseHTTPRequestHandler

## DEFINES

port = 10102
server = None

## HANDLERS

handlers = Object()

## APIServer class

[docs]class API(HTTPServer, Object): """ API server """ allow_reuse_address = True daemon_thread = True def __init__(zelf, *args, **kwargs): """ start the API server. """ HTTPServer.__init__(zelf, *args, **kwargs) Object.__init__(zelf) zelf.host = args[0] zelf._status = "init" zelf._last = time.time() zelf._start = time.time()
[docs] def exit(zelf): """ shutdown API. """ logging.warn("# exit API.") zelf._status = "" time.sleep(0.2) zelf.shutdown()
[docs] def start(zelf, *args, **kwargs): """ serving requests. """ logging.warn("# start API at http://%s:%s" % zelf.host) zelf._status = "running" zelf.ready() zelf.serve_forever()
[docs] def handle_request(zelf): zelf._last = time.time()
[docs] def handle_error(zelf, request, addr): """ log the error """ ex = get_exception() logging.warn('%s - %s' % (addr, ex)) ## RestReqeustHandler class
[docs]class APIHandler(BaseHTTPRequestHandler): """ timeserver request handler class """
[docs] def setup(zelf): """ called on each incoming request. """ BaseHTTPRequestHandler.setup(zelf) zelf._ip = zelf.client_address[0] zelf._size = 0
[docs] def write_header(zelf, type='text/plain'): """ write headers to the client. """ zelf.send_response(200) zelf.send_header('Content-type', '%s; charset=%s ' % (type, "utf-8")) zelf.send_header('Server', __version__) zelf.end_headers()
[docs] def handle_request(zelf): """ handle a REST request. """ zelf.parsed = urllib.parse.urlparse(zelf.path) path = "/" + zelf.parsed[2].split("/")[1] try: for functor in handlers[path]: result = functor.func(zelf, zelf.request) except KeyError as ex: logging.info("# missing %s" % str(ex)) except: error()
do_DELETE = do_PUT = do_GET = do_POST = handle_request
[docs] def log_request(zelf, code): """ log the request """ try: ua = zelf.headers['user-agent'] except: ua = "-" try: rf = zelf.headers['referer'] except: rf = "-" logging.warn('# %s %s %s' % (zelf.address_string(), code, zelf.path))
[docs]def api_home(handler, request): server, port = handler.server.host handler.write_header() handler.wfile.write(bytes("ZOTBOT API INTERFACE\n\n", "utf-8")) for func in handlers.keys(): handler.wfile.write(bytes("http://%s:%s%s\n" % (server, port, func), "utf-8")) handler.wfile.flush()
[docs]def api_all(handler, request): o = Object() nr = 0 server, port = handler.server.host root = kernel.get_root() for fn in list_files(root): o[nr] = "http://%s:%s/get%s" % (server, port, fn.split(root)[-1]) nr += 1 handler.write_header() handler.wfile.write(bytes(o.json(indent=2), "utf-8")) handler.wfile.flush()
[docs]def api_get(handler, request): fn = os.sep.join(handler.path.split("/")[2:]) root = kernel.get_root() path = os.path.normpath(os.path.expanduser(j(root, fn))) o = Object() o.load(path) txt = o.json(indent=2, ensure_ascii=False, sort_keys=True) handler.write_header() handler.wfile.write(bytes(txt, "utf-8")) handler.wfile.flush()
[docs]def api_show(handler, request): fn = os.path.join(handler.path.split("/")[2:]) root = kernel.get_root() path = os.path.normpath(j(root, *fn)) o = Object() o.load(path) txt = o.pretty(indent=2, sort_keys=True) txt = txt.replace("\\n", "\n") txt = txt.replace("\\t", "\t") handler.write_header() handler.wfile.write(bytes(txt, "utf-8")) handler.wfile.flush()
[docs]def init(*args, **kwargs): from zot.runtime import kernel api = API((cfg_api.hostname, int(cfg.port or cfg_api.port)), APIHandler) handlers.register("/", api_home) handlers.register("/all", api_all) handlers.register("/get", api_get) handlers.register("/show", api_show) kernel.put(api.start)