def on_config(self, confobj): conf = self.parse_config(confobj) params = [Parameter(name=key, value=conf[key]) for key in conf] conf = configuration(category('collectd_config', *params)) self.apply_configuration(conf=conf)
def test_config_values(self): logconf = Configurable.get_annotations(self.logger)[0] expected_log_format = 'log' expected_log_level = 'debug' expected_log_filter = {'foo': 'bar'} conf = category( 'LOGGING', Parameter(name='log_format', value=expected_log_format), Parameter(name='log_level', value=expected_log_level), Parameter(name='log_filter', value=expected_log_filter)) logconf.configure(conf=conf) self.assertEqual(self.logger.log_format, expected_log_format) self.assertEqual(self.logger.log_level, expected_log_level) self.assertEqual(self.logger.log_filter, expected_log_filter)
def on_config(self, confobj): conf = self.parse_config(confobj) params = [ Parameter(name=key, value=conf[key]) for key in conf ] conf = configuration( category( 'collectd_config', *params ) ) self.apply_configuration(conf=conf)
def test_config_values(self): logconf = Configurable.get_annotations(self.logger)[0] expected_log_format = 'log' expected_log_level = 'debug' expected_log_filter = {'foo': 'bar'} conf = category( 'LOGGING', Parameter(name='log_format', value=expected_log_format), Parameter(name='log_level', value=expected_log_level), Parameter(name='log_filter', value=expected_log_filter) ) logconf.configure(conf=conf) self.assertEqual(self.logger.log_format, expected_log_format) self.assertEqual(self.logger.log_level, expected_log_level) self.assertEqual(self.logger.log_filter, expected_log_filter)
# -*- coding: utf-8 -*- from b3j0f.conf import Configurable, category from link.json.exceptions import JsonValidationError from link.json.resolver import JsonResolver from link.json import CONF_BASE_PATH from jsonschema import validate, ValidationError from six import string_types, raise_from @Configurable( paths='{0}/schema.conf'.format(CONF_BASE_PATH), conf=category('JSONSCHEMA') ) class JsonSchema(object): """ Helper class used to validate data with the JSON Schema specification. See: http://json-schema.org """ def validate(self, schema_or_url, data): """ Validate data against schema. :param schema_or_url: Schema used for validation, or URL pointing to it :type schema_or_url: dict or str :param data: Data to validate
from riak.security import SecurityCreds from riak import RiakClient, RiakObject from riak.datatypes import Datatype from six import raise_from @Configurable( paths='{0}/driver.conf'.format(CONF_BASE_PATH), conf=category( 'RIAK', Parameter(name='default_bucket', value='default'), Parameter(name='protocol', value='http'), Parameter(name='pkey'), Parameter(name='cert'), Parameter(name='cacert'), Parameter(name='crl'), Parameter(name='ciphers'), Parameter(name='sslver', ptype=int) ) ) @addfeatures([RiakSearch2]) @register_middleware class RiakDriver(Driver): __protocols__ = ['riak'] def __init__( self, default_bucket=None,
from b3j0f.conf import Configurable, configuration, category, Parameter from b3j0f.utils.path import lookup from link.utils.logging import LoggingObject from link.etcd.driver import EtcdConfDriver from link.collectd import CONF_BASE_PATH from six import string_types @Configurable(paths='{0}/plugin.conf'.format(CONF_BASE_PATH), conf=category('COLLECTDPLUGIN', Parameter('interval', ptype=int), Parameter('init_callback'), Parameter('read_callback'), Parameter('shutdown_callback'), Parameter('write_callback'), Parameter('flush_callback'), Parameter('log_callback'), Parameter('notification_callback')), drivers=(EtcdConfDriver(), ) + Configurable.DEFAULT_DRIVERS) class CollectDPlugin(LoggingObject): """ Configurable Python plugin for CollectD. """ @property def interval(self): if not hasattr(self, '_interval'): self.interval = None return self._interval
# -*- coding: utf-8 -*- from b3j0f.conf import Configurable, category from link.wsgi import CONF_BASE_PATH @Configurable( paths='{0}/middleware.conf'.format(CONF_BASE_PATH), conf=category('MIDDLEWARE') ) class Middleware(object): """ Middleware class. Applied before and after requests are handled. """ def before(self, req, resp, handler): """ Called before request is handled. :param req: request that will be handled :type req: link.wsgi.req.Request :param resp: response that will be returned :type resp: link.wsgi.resp.Response :param handler: handler that will be used :type handler: callable :return: True to abort request handling
# -*- coding: utf-8 -*- from b3j0f.conf import Configurable, category, Parameter from link.wsgi import CONF_BASE_PATH from link.wsgi.url import parse_qs from six.moves.urllib.parse import unquote from six import string_types from posixpath import normpath @Configurable( paths='{0}/request.conf'.format(CONF_BASE_PATH), conf=category( 'REQUEST', Parameter(name='charsets', ptype=list) ) ) class Request(object): """ Request object encapsulating WSGI environ dict. """ @property def charsets(self): if not hasattr(self, '_charsets'): self.charsets = None return self._charsets @charsets.setter
from link.rest.exceptions import MissingLinkError from link.rest.exceptions import MultipleLinksMatchingError from link.rest.exceptions import RequestValidationError from link.rest.exceptions import ResponseValidationError from link.rest.message import RestMessage from link.rest.core import SchemaApi from link.rest import CONF_BASE_PATH from link.json.collection import generate_collection_response from link.json.resolver import JsonResolver @Configurable( paths='{0}/wrapper.conf'.format(CONF_BASE_PATH), conf=category( 'RESTWRAPPER', Parameter(name='schemas') ) ) class RestWrapper(object): DEFAULT_SCHEMAS = {} @property def schemas(self): if not hasattr(self, '_schemas'): self.schemas = None return self._schemas @schemas.setter def schemas(self, value):
def filter(self, record): if self.log_filter is not None: document = logrecord_to_dict(record) return self.log_filter.match(document) else: return super(LogFilter, self).filter(record) cls = logging.getLoggerClass() if not hasattr(cls, '__configurable__') or not cls.__configurable__: @Configurable(paths='{0}/logging.conf'.format(CONF_BASE_PATH), conf=category('LOGGING', Parameter(name='log_format'), Parameter(name='log_level'), Parameter(name='log_filter', ptype=dict))) class ConfigurableLogger(cls): """ Configurable logger. """ __configurable__ = True @property def log_format(self): if not hasattr(self, '_log_format'): self.log_format = None return self._log_format
def getparser(cls): return lambda svalue, **_: cls.get_middleware_by_uri(svalue) @DriverLoader( paths='{0}/manager.conf'.format(CONF_BASE_PATH), conf=category( 'GRAPHMANAGER', Parameter( name='parallel_backend', parser=getparser(MapReduceMiddleware), svalue='mapreduce+parallel:///graph' ), Parameter( name='nodes_storage', parser=getparser(KeyValueStore), svalue='kvstore:///nodes/default' ), Parameter( name='relationships_storage', parser=getparser(KeyValueStore), svalue='kvstore:///relationships/default' ) ) ) class GraphManager(object): """ Process request and manage access to graph storage. """ def __init__(self, *args, **kwargs):
from etcd import Client, EtcdKeyNotFound import os @Configurable( paths='{0}/middleware.conf'.format(CONF_BASE_PATH), conf=category( 'ETCD', Parameter(name='host', value='localhost'), Parameter(name='port', ptype=int, value=4001), Parameter(name='srv_domain', value=None), Parameter(name='version_prefix', value='/v2'), Parameter(name='read_timeout', ptype=int, value=60), Parameter(name='allow_redirect', ptype=bool, value=True), Parameter(name='protocol', value='http'), Parameter(name='cert', value=None), Parameter(name='ca_cert', value=None), Parameter(name='username', value=None), Parameter(name='password', value=None), Parameter(name='allow_reconnect', ptype=bool, value=False), Parameter(name='use_proxies', ptype=bool, value=False), Parameter(name='expected_cluster_id', value=None), Parameter(name='per_host_pool_size', ptype=int, value=10) ) ) class EtcdMiddleware(ConnectableMiddleware): """ Middleware that connects to **etcd**. The following operations are available:
from prompt_toolkit.layout.lexers import PygmentsLexer from prompt_toolkit.styles import style_from_pygments from prompt_toolkit.token import Token from prompt_toolkit.keys import Keys from prompt_toolkit import prompt from pygments.styles import get_style_by_name from six import print_ @Configurable( paths=CONF_PATH, conf=category( CATEGORY, Parameter(name='color_scheme', svalue='default'), Parameter(name='tab_width', ptype=int, svalue='4') ) ) class GraphCLI(object): def __init__(self, graphuri, *args, **kwargs): super(GraphCLI, self).__init__(*args, **kwargs) self.graph = GraphMiddleware.get_middleware_by_uri(graphuri) self.kbmgr = KeyBindingManager.for_prompt() self.histmgr = HistoryManager() self.register_shortcuts() def register_shortcuts(self): self.kbmgr.registry.add_binding(Keys.ControlJ)(self.newline_or_execute)
# -*- coding: utf-8 -*- from b3j0f.conf import Configurable, category, Parameter from link.json.schema import JsonSchema from link.json import CONF_BASE_PATH DEFAULT_SCHEMA = 'http://hyperschema.org/mediatypes/collection-json.json' @Configurable( paths='{0}/collection.conf'.format(CONF_BASE_PATH), conf=category( 'JSONCOLLECTION', Parameter(name='version', value='1.0'), Parameter(name='schema', value=DEFAULT_SCHEMA) ) ) class CollectionJSONResponse(object): """ Helper class used to generate valid Collection+JSON objects. """ ITEM_ID = 'id' def __init__( self, href, links=None, items=None,
from b3j0f.conf.driver.file.base import FileConfDriver from b3j0f.utils.runtime import singleton_per_scope from link.utils.grammar import codegenerator from link.graph import CONF_BASE_PATH import os @Configurable( paths='{0}/dsl/generator.conf'.format(CONF_BASE_PATH), conf=category( 'DSLGEN', Parameter( name='grammar', value='{0}/dsl/grammar.bnf'.format(CONF_BASE_PATH) ), Parameter(name='modname', value='graph_dsl_generated') ) ) class GraphDSLGenerator(object): MODEL_PREFIX = 'GraphDSL' class Error(Exception): pass @property def grammar(self): return self._grammar
# -*- coding: utf-8 -*- from b3j0f.conf import Configurable, category from link.wsgi import CONF_BASE_PATH from link.wsgi.router import Router from link.wsgi.req import Request from link.wsgi.resp import Response import logging @Configurable( paths='{0}/app.conf'.format(CONF_BASE_PATH), conf=category('APPLICATION') ) class Application(object): """ WSGI Application class. """ def __init__(self, *args, **kwargs): super(Application, self).__init__(*args, **kwargs) self.router = Router() self.logger = logging.getLogger('link.wsgi.app') def __call__(self, environ, start_response): """ WSGI application handler. :param environ: WSGI environ dict
from time import time import os try: import sqlite3 HAVE_SQLITE = True except ImportError: HAVE_SQLITE = False @Configurable( paths=CONF_PATH, conf=category( CATEGORY, Parameter(name='history_size', ptype=int, svalue='200') ) ) class HistoryManager(object): def __init__(self, *args, **kwargs): super(HistoryManager, self).__init__(*args, **kwargs) self._history = None self.last_cmd = None self.db = None if HAVE_SQLITE: dbpath = os.path.join( save_cache_path('graphcli'), 'history.db' )
from b3j0f.conf import Configurable as BaseConfigurable from b3j0f.conf import category, Parameter, Array from b3j0f.utils.path import lookup from link.graph import CONF_BASE_PATH from six import string_types, raise_from from types import ModuleType @BaseConfigurable( paths='{0}/drivers.conf'.format(CONF_BASE_PATH), conf=category( 'DRIVERS', Parameter(name='parallel', ptype=Array(str)), Parameter(name='kvstore', ptype=Array(str)) ) ) class DriverLoader(BaseConfigurable): @property def parallel(self): if not hasattr(self, '_parallel'): self.parallel = None return self._parallel @parallel.setter def parallel(self, value): if value is None: value = []
# -*- coding: utf-8 -*- from b3j0f.conf import Configurable, category from link.middleware.core import Middleware from link.json import CONF_BASE_PATH from jsonschema import RefResolver from jsonpointer import resolve_pointer import json @Configurable( paths='{0}/resolver.conf'.format(CONF_BASE_PATH), conf=category('JSONRESOLVER') ) class JsonResolver(RefResolver): """ Resolve JSON references. See: https://tools.ietf.org/html/draft-pbryan-zyp-json-ref-03 """ def __init__(self, base_uri='', referrer=None, **kwargs): if base_uri is None: base_uri = '' super(JsonResolver, self).__init__(base_uri, referrer, **kwargs) # Just make required parameters optionnal
from link.middleware.connectable import ConnectableMiddleware from link.etcd import CONF_BASE_PATH from etcd import Client, EtcdKeyNotFound import os @Configurable(paths='{0}/middleware.conf'.format(CONF_BASE_PATH), conf=category( 'ETCD', Parameter(name='host', value='localhost'), Parameter(name='port', ptype=int, value=4001), Parameter(name='srv_domain', value=None), Parameter(name='version_prefix', value='/v2'), Parameter(name='read_timeout', ptype=int, value=60), Parameter(name='allow_redirect', ptype=bool, value=True), Parameter(name='protocol', value='http'), Parameter(name='cert', value=None), Parameter(name='ca_cert', value=None), Parameter(name='username', value=None), Parameter(name='password', value=None), Parameter(name='allow_reconnect', ptype=bool, value=False), Parameter(name='use_proxies', ptype=bool, value=False), Parameter(name='expected_cluster_id', value=None), Parameter(name='per_host_pool_size', ptype=int, value=10))) class EtcdMiddleware(ConnectableMiddleware): """ Middleware that connects to **etcd**. The following operations are available: .. code-block:: python
if self.log_filter is not None: document = logrecord_to_dict(record) return self.log_filter.match(document) else: return super(LogFilter, self).filter(record) cls = logging.getLoggerClass() if not hasattr(cls, '__configurable__') or not cls.__configurable__: @Configurable( paths='{0}/logging.conf'.format(CONF_BASE_PATH), conf=category( 'LOGGING', Parameter(name='log_format'), Parameter(name='log_level'), Parameter(name='log_filter', ptype=dict) ) ) class ConfigurableLogger(cls): """ Configurable logger. """ __configurable__ = True @property def log_format(self): if not hasattr(self, '_log_format'): self.log_format = None
# -*- coding: utf-8 -*- from b3j0f.conf import Configurable, category from link.json.exceptions import JsonTransformationError from link.json.resolver import JsonResolver from link.json.schema import JsonSchema from link.json import CONF_BASE_PATH from jsonpatch import JsonPatch, JsonPatchException from six import string_types, raise_from @Configurable( paths='{0}/transform.conf'.format(CONF_BASE_PATH), conf=category('JSONTRANSFORM') ) class JsonTransform(object): """ Apply a transformation on data. A schema is used to validate the input data, and the output data. A JSON Patch is used to apply the transformation. See: http://jsonpatch.com """ @property def source(self): return self._source
from link.utils.logging import LoggingObject from link.etcd.driver import EtcdConfDriver from link.collectd import CONF_BASE_PATH from six import string_types @Configurable( paths='{0}/plugin.conf'.format(CONF_BASE_PATH), conf=category( 'COLLECTDPLUGIN', Parameter('interval', ptype=int), Parameter('init_callback'), Parameter('read_callback'), Parameter('shutdown_callback'), Parameter('write_callback'), Parameter('flush_callback'), Parameter('log_callback'), Parameter('notification_callback') ), drivers=(EtcdConfDriver(),) + Configurable.DEFAULT_DRIVERS ) class CollectDPlugin(LoggingObject): """ Configurable Python plugin for CollectD. """ @property def interval(self): if not hasattr(self, '_interval'):
from link.riak.features.fulltext import RiakSearch2 from link.riak import CONF_BASE_PATH from link.feature import addfeatures from riak.security import SecurityCreds from riak import RiakClient, RiakObject from riak.datatypes import Datatype from six import raise_from @Configurable(paths='{0}/driver.conf'.format(CONF_BASE_PATH), conf=category('RIAK', Parameter(name='default_bucket', value='default'), Parameter(name='protocol', value='http'), Parameter(name='pkey'), Parameter(name='cert'), Parameter(name='cacert'), Parameter(name='crl'), Parameter(name='ciphers'), Parameter(name='sslver', ptype=int))) @addfeatures([RiakSearch2]) @register_middleware class RiakDriver(Driver): __protocols__ = ['riak'] def __init__(self, default_bucket=None, protocol=None, pkey=None, cert=None, cacert=None,
from b3j0f.conf import Configurable, category, Parameter from b3j0f.utils.path import lookup from link.wsgi import CONF_BASE_PATH from inspect import isclass from re import match import traceback import logging @Configurable( paths='{0}/router.conf'.format(CONF_BASE_PATH), conf=category( 'ROUTER', Parameter(name='urlpatterns', ptype=dict), Parameter(name='middlewares', ptype=list) ) ) class Router(object): """ Request dispatcher. Contains URL patterns as dict: - a regex to match the URL as key - a dict associated HTTP methods to Python callable objects Also contains list of middlewares (Python classes) to apply. Example of configuration: