Beispiel #1
0
async def _PGConfigurationFactory(key, dbconfig, loop=None,
                                  storage_factory=PostgresqlStorage):
    if isinstance(dbconfig['dsn'], str):
        dsn = dbconfig['dsn']
    else:
        dsn = _convert_dsn(dbconfig['dsn'])

    partition_object = None
    if 'partition' in dbconfig:
        partition_object = resolve_dotted_name(dbconfig['partition'])

    dbconfig.update({
        'dsn': dsn,
        'name': key,
        'partition': partition_object,
        'pool_size': dbconfig.get('pool_size', 13)
    })

    connection_options = _get_connection_options(dbconfig)

    aps = storage_factory(**dbconfig)
    if loop is not None:
        await aps.initialize(loop=loop, **connection_options)
    else:
        await aps.initialize(**connection_options)

    if 'transaction_manager' in dbconfig:
        transaction_manager = resolve_dotted_name(dbconfig['transaction_manager'])
    else:
        transaction_manager = TransactionManager
    db = Database(key, aps, transaction_manager)
    await db.initialize()
    return db
Beispiel #2
0
def load_contenttype(_context, contenttype):
    conf = contenttype['config']
    klass = contenttype['klass']
    if 'schema' in conf:
        classImplements(klass, conf['schema'])

    Factory = resolve_dotted_name(
        conf.get('factory', 'guillotina.content.ResourceFactory')
    )

    factory = Factory(
        klass,
        title='',
        description='',
        type_name=conf['type_name'],
        schema=resolve_dotted_name(conf.get('schema', Interface)),
        behaviors=[resolve_dotted_name(b) for b in conf.get('behaviors', []) or ()],
        add_permission=conf.get('add_permission') or DEFAULT_ADD_PERMISSION,
        allowed_types=conf.get('allowed_types', None)
    )
    component.utility(
        _context,
        provides=IResourceFactory,
        component=factory,
        name=conf['type_name'],
    )
Beispiel #3
0
def make_aiohttp_application():
    middlewares = [resolve_dotted_name(m) for m in app_settings.get('middlewares', [])]
    router_klass = app_settings.get('router', TraversalRouter)
    router = resolve_dotted_name(router_klass)()
    return GuillotinaAIOHTTPApplication(
        router=router,
        middlewares=middlewares,
        **app_settings.get('aiohttp_settings', {}))
Beispiel #4
0
def load_service(_context, service):
    # prevent circular import
    from guillotina.security.utils import protect_view

    service_conf = service['config']
    factory = resolve_dotted_name(service['klass'])

    permission = service_conf.get(
        'permission', app_settings.get('default_permission', None))

    protect_view(factory, permission)

    method = service_conf.get('method', 'GET')
    default_layer = resolve_dotted_name(
        app_settings.get('default_layer', IDefaultLayer))
    layer = service_conf.get('layer', default_layer)
    name = service_conf.get('name', '')
    content = service_conf.get('context', Interface)
    logger.debug('Defining adapter for '  # noqa
                 '{0:s} {1:s} {2:s} to {3:s} name {4:s}'.format(
        content.__identifier__,
        app_settings['http_methods'][method].__identifier__,
        layer.__identifier__,
        str(factory),
        name))

    if not getattr(factory, '__route__', None):
        factory.__route__ = routes.Route(name)
    else:
        factory.__route__.service_configuration = service_conf

    component.adapter(
        _context,
        factory=(factory,),
        provides=app_settings['http_methods'][method],
        for_=(content, layer),
        name=factory.__route__.view_name
    )

    api = app_settings['api_definition']
    ct_name = content.__identifier__
    if ct_name not in api:
        api[ct_name] = OrderedDict()
    ct_api = api[ct_name]
    if name:
        if 'endpoints' not in ct_api:
            ct_api['endpoints'] = OrderedDict()
        if name not in ct_api['endpoints']:
            ct_api['endpoints'][name] = OrderedDict()
        ct_api['endpoints'][name][method] = OrderedDict(service_conf)
    else:
        ct_api[method] = OrderedDict(service_conf)
Beispiel #5
0
def load_subscriber(_context, subscriber):
    conf = subscriber['config']
    conf['handler'] = resolve_dotted_name(conf.get('handler') or subscriber['klass'])
    _component_conf(conf)
    component.subscriber(
        _context,
        **conf
    )
Beispiel #6
0
def optimize_settings(settings):
    '''
    pre-render settings that come in as strings but are used by the app
    '''
    for name in _dotted_name_settings:
        if name not in settings:
            continue
        val = settings[name]
        if isinstance(val, str):
            settings[name] = resolve_dotted_name(val)
        elif isinstance(val, list):
            new_val = []
            for v in val:
                if isinstance(v, str):
                    v = resolve_dotted_name(v)
                new_val.append(v)
            settings[name] = resolve_dotted_name(new_val)
Beispiel #7
0
def load_utility(_context, _utility):
    conf = _utility['config']
    if 'factory' in conf:
        conf['factory'] = resolve_dotted_name(conf['factory'])
    elif 'component' in conf:
        conf['component'] = resolve_dotted_name(conf['component'])
    else:
        # use provided klass
        klass = _utility['klass']
        if isinstance(klass, type):
            # is a class type, use factory setting
            conf['factory'] = klass
        else:
            # not a factory
            conf['component'] = klass
    component.utility(
        _context,
        **conf
    )
Beispiel #8
0
async def delete_behavior(context, behavior):
    factory = get_cached_factory(context.type_name)
    behavior_class = resolve_dotted_name(behavior)
    if behavior_class is not None:
        if behavior_class in factory.behaviors:
            return Response(content={
                'reason': 'Behaviors defined on this type must be present and cannot be dynamically removed'
            }, status=412)
    if behavior not in context.__behaviors__:
        return Response(content={
            'reason': 'Not in behaviors'
        }, status=412)
    context.remove_behavior(behavior)
    return {}
Beispiel #9
0
def load_adapter(_context, adapter):
    conf = adapter['config']
    klass = resolve_dotted_name(adapter['klass'])
    factory = conf.pop('factory', None) or klass
    _component_conf(conf)
    if 'provides' in conf and isinstance(klass, type):
        # not sure if this is what we want or not for sure but
        # we are automatically applying the provides interface to
        # registered class objects
        classImplements(klass, conf['provides'])
    component.adapter(
        _context,
        factory=(factory,),
        **conf
    )
Beispiel #10
0
    def configure_application(self, module_name):
        if module_name in self.configured:
            return

        module = resolve_dotted_name(module_name)
        if hasattr(module, 'app_settings') and app_settings != module.app_settings:
            # load dependencies if necessary
            for dependency in module.app_settings.get('applications') or []:
                if dependency not in self.configured and module_name != dependency:
                    self.configure_application(dependency)

        self.config.begin(module_name)
        self.load_application(module)
        self.config.execute_actions()
        self.config.commit()

        self.configured.append(module_name)
Beispiel #11
0
def command_runner():
    parser = argparse.ArgumentParser(
        description='Guillotina command runner',
        add_help=False)
    parser.add_argument('command', nargs='?')
    parser.add_argument('-c', '--configuration',
                        default='config.yaml', help='Configuration file')
    parser.add_argument('-h', '--help', action='store_true',
                        dest='help', help='Help', default=False)

    arguments, _ = parser.parse_known_args()
    settings = get_settings(arguments.configuration)
    _commands = app_settings['commands'].copy()
    _commands.update(settings.get('commands', {}))
    for module_name in settings.get('applications', []):
        load_commands(module_name, _commands)

    if not arguments.command and arguments.help:
        # for other commands, pass through and allow those parsers to print help
        parser.print_help()
        return print('''
Available commands:
{}\n\n'''.format('\n  - '.join(c for c in _commands.keys())))

    if not arguments.command:
        # default to serve command
        arguments.command = 'serve'

    if arguments.command not in _commands:
        return print('''Invalid command "{}".

Available commands:
{}\n\n'''.format(arguments.command, '\n  - '.join(c for c in _commands.keys())))

    app_settings['_command'] = arguments.command
    Command = resolve_dotted_name(_commands[arguments.command])
    if Command is None:
        return print('Could not resolve command {}:{}'.format(
            arguments.command, _commands[arguments.command]
        ))

    app_settings['__run_command__'] = arguments.command
    # finally, run it...
    command = Command()
    command.run_command()
Beispiel #12
0
def get_configurations(module_name, type_=None, excluded=None):
    results = []
    for reg_type, registration in _registered_configurations:
        if type_ is not None and reg_type != type_:
            continue
        config = registration['config']
        module = config.get('module', registration.get('klass'))
        normalized_name = get_module_dotted_name(resolve_dotted_name(module))

        if (normalized_name + '.').startswith(module_name + '.'):
            valid = True
            for excluded_module in excluded or []:
                if (normalized_name + '.').startswith(excluded_module + '.'):
                    valid = False
                    break
            if valid:
                results.append((reg_type, registration))
    return results
Beispiel #13
0
    async def __call__(self):
        if self.key is _marker:
            # No option to write the root of registry
            return ErrorResponse('InvalidRequest', 'Needs the registry key', status=412)

        data = await self.request.json()
        if 'value' in data:
            value = data['value']
        else:
            value = data

        assert '.' in self.key, 'Registry key must be dotted.iface.name.fieldname'  # noqa
        iface, name = self.key.rsplit('.', 1)
        iface = resolve_dotted_name(iface)

        assert iface is not None, 'Must provide valid registry interface'  # noqa
        try:
            field = iface[name]
        except KeyError:
            return ErrorResponse(
                'DeserializationError',
                'Invalid field name {}'.format(str(name)),
                status=412)

        try:
            new_value = get_adapter((field), IJSONToValue, args=[value, self.context])
        except ComponentLookupError:
            return ErrorResponse(
                'DeserializationError',
                'Cannot deserialize type {}'.format(str(self.field)),
                status=412)

        try:
            self.request.container_settings[self.key] = new_value
        except DeserializationError as e:
            return ErrorResponse(
                'DeserializationError',
                str(e),
                exc=e,
                status=412)

        return Response(status=204)
Beispiel #14
0
    def run_command(self, settings=None, loop=None):
        if loop is not None:
            self.loop = loop
        if settings is None:
            settings = get_settings(self.arguments.configuration, self.arguments.override)
        if settings.get('loop_policy'):
            loop_policy = resolve_dotted_name(settings['loop_policy'])
            asyncio.set_event_loop_policy(loop_policy())

        app = self.make_app(settings)

        if self.arguments.line_profiler:
            if not HAS_LINE_PROFILER:
                sys.stderr.write(
                    'You must first install line_profiler for the --line-profiler option to work.\n'
                    'Use `pip install line_profiler` to install line_profiler.\n'
                )
                return 1
            self.line_profiler = line_profiler.LineProfiler()
            for func in profile.get_profilable_functions():
                if fnmatch(get_dotted_name(func), self.arguments.line_profiler_matcher or '*'):
                    self.line_profiler.add_function(func)
            self.line_profiler.enable_by_count()

        run_func = self.__run
        if self.arguments.monitor:
            if not HAS_AIOMONITOR:
                sys.stderr.write(
                    'You must install aiomonitor for the '
                    '--monitor option to work.\n'
                    'Use `pip install aiomonitor` to install aiomonitor.\n')
                return 1
            run_func = self.__run_with_monitor

        if self.arguments.profile:
            self.profiler = cProfile.Profile()
            self.profiler.runcall(run_func, app, settings)
        else:
            run_func(app, settings)
Beispiel #15
0
async def default_patch(context, request):
    data = await request.json()
    behavior = data.get('behavior', None)
    try:
        behavior_class = resolve_dotted_name(behavior)
    except ModuleNotFoundError:
        behavior_class = None
    if behavior_class is None:
        return Response(content={
            'reason': 'Could not find behavior'
        }, status=404)
    factory = get_cached_factory(context.type_name)
    if behavior_class in factory.behaviors:
        return Response(content={
            'reason': 'Already in behaviors'
        }, status=412)
    if behavior in context.__behaviors__:
        return Response(content={
            'reason': 'Already in behaviors'
        }, status=412)
    context.add_behavior(behavior)
    return {}
Beispiel #16
0
    def run_command(self, settings=None, loop=None):
        if loop is not None:
            self.loop = loop
        if settings is None:
            settings = get_settings(self.arguments.configuration)
        if settings.get('loop_policy'):
            loop_policy = resolve_dotted_name(settings['loop_policy'])
            asyncio.set_event_loop_policy(loop_policy())
        app = self.make_app(settings)

        if self.arguments.line_profiler:
            if not HAS_LINE_PROFILER:
                sys.stderr.write(
                    'You must first install line_profiler for the --line-profiler option to work.\n'
                    'Use `pip install line_profiler` to install line_profiler.\n'
                )
                return 1
            self.line_profiler = line_profiler.LineProfiler()
            for func in profile.get_profilable_functions():
                if fnmatch(get_dotted_name(func), self.arguments.line_profiler_matcher or '*'):
                    self.line_profiler.add_function(func)
            self.line_profiler.enable_by_count()

        run_func = self.__run
        if self.arguments.monitor:
            if not HAS_AIOMONITOR:
                sys.stderr.write(
                    'You must install aiomonitor for the '
                    '--monitor option to work.\n'
                    'Use `pip install aiomonitor` to install aiomonitor.\n')
                return 1
            run_func = self.__run_with_monitor

        if self.arguments.profile:
            self.profiler = cProfile.Profile()
            self.profiler.runcall(run_func, app, settings)
        else:
            run_func(app, settings)
Beispiel #17
0
    async def __call__(self):
        if self.key is _marker:
            # No option to write the root of registry
            return ErrorResponse('InvalidRequest',
                                 'Needs the registry key',
                                 status=412)

        data = await self.request.json()
        if 'value' in data:
            value = data['value']
        else:
            value = data

        assert '.' in self.key, 'Registry key must be dotted.iface.name.fieldname'  # noqa
        iface, name = self.key.rsplit('.', 1)
        iface = resolve_dotted_name(iface)
        field = iface[name]

        try:
            new_value = get_adapter((field),
                                    IJSONToValue,
                                    args=[value, self.context])
        except ComponentLookupError:
            return ErrorResponse('DeserializationError',
                                 'Cannot deserialize type {}'.format(
                                     str(self.field)),
                                 status=412)

        try:
            self.request.container_settings[self.key] = new_value
        except DeserializationError as e:
            return ErrorResponse('DeserializationError',
                                 str(e),
                                 exc=e,
                                 status=412)

        return Response(status=204)
Beispiel #18
0
    async def __call__(self):
        user = get_authenticated_user()
        self.policy = get_security_policy(user)
        definition = copy.deepcopy(app_settings["swagger"]["base_configuration"])
        vhm = self.request.headers.get("X-VirtualHost-Monster")

        if not app_settings["swagger"].get("base_url"):
            if vhm:
                parsed_url = urlparse(vhm)
                host = parsed_url.netloc
                scheme = parsed_url.scheme
                base_path = parsed_url.path
            else:
                host = self.request.host
                scheme = get_request_scheme(self.request)
                base_path = ""
            url = os.path.join(f"{scheme}://{host}", base_path)
        else:
            url = app_settings["swagger"]["base_url"]

        definition["servers"][0]["url"] = url

        if "version" not in definition["info"]:
            definition["info"]["version"] = pkg_resources.get_distribution("guillotina").version

        api_defs = app_settings["api_definition"]

        path = get_full_content_path(self.context)

        for dotted_iface in api_defs.keys():
            iface = resolve_dotted_name(dotted_iface)
            if iface.providedBy(self.context):
                iface_conf = api_defs[dotted_iface]
                self.get_endpoints(iface_conf, path, definition["paths"])

        definition["components"]["schemas"] = app_settings["json_schema_definitions"]
        return definition
Beispiel #19
0
    async def _build_security_query(
            self,
            container,
            query,
            doc_type=None,
            size=10,
            request=None,
            scroll=None):
        if query is None:
            query = {}
        build_security_query = resolve_dotted_name(
            app_settings['elasticsearch']['security_query_builder'])

        permission_query = await build_security_query(container, request)
        result = {
            'body': merge_dicts(query, permission_query),
            'size': size
        }

        if scroll:
            result['scroll'] = scroll

        logger.debug(result)
        return result
Beispiel #20
0
def make_app(config_file=None, settings=None, loop=None, server_app=None):
    app_settings.update(_delayed_default_settings)

    if loop is None:
        loop = asyncio.get_event_loop()

    loop.set_task_factory(aiotask_context.task_factory)

    if config_file is not None:
        with open(config_file, 'r') as config:
            settings = json.load(config)
    elif settings is None:
        raise Exception('Neither configuration or settings')

    # Create root Application
    root = ApplicationRoot(config_file)
    provide_utility(root, IApplication, 'root')

    # Initialize global (threadlocal) ZCA configuration
    config = root.config = ConfigurationMachine()

    import guillotina
    import guillotina.db.factory
    import guillotina.db.writer
    import guillotina.db.db
    configure.scan('guillotina.translation')
    configure.scan('guillotina.renderers')
    configure.scan('guillotina.api')
    configure.scan('guillotina.content')
    configure.scan('guillotina.registry')
    configure.scan('guillotina.auth')
    configure.scan('guillotina.json')
    configure.scan('guillotina.behaviors')
    configure.scan('guillotina.languages')
    configure.scan('guillotina.permissions')
    configure.scan('guillotina.security.security_local')
    configure.scan('guillotina.security.policy')
    configure.scan('guillotina.auth.participation')
    configure.scan('guillotina.catalog.index')
    configure.scan('guillotina.catalog.catalog')
    configure.scan('guillotina.framing')
    configure.scan('guillotina.files')
    configure.scan('guillotina.annotations')
    configure.scan('guillotina.constraintypes')
    configure.scan('guillotina.subscribers')
    configure.scan('guillotina.db.strategies')
    configure.scan('guillotina.db.cache')
    load_application(guillotina, root, settings)
    config.execute_actions()
    config.commit()

    for module_name in settings.get('applications', []):
        config.begin(module_name)
        load_application(resolve_dotted_name(module_name), root, settings)
        config.execute_actions()
        config.commit()

    # XXX we clear now to save some memory
    # it's unclear to me if this is necesary or not but it seems to me that
    # we don't need things registered in both components AND here.
    configure.clear()

    # update *after* plugins loaded
    update_app_settings(settings)

    if 'logging' in app_settings:
        logging.config.dictConfig(app_settings['logging'])

    # Make and initialize aiohttp app
    if server_app is None:
        server_app = make_aiohttp_application()
    root.app = server_app
    server_app.root = root
    server_app.config = config

    content_type = ContentNegotiatorUtility('content_type',
                                            app_settings['renderers'].keys())
    language = ContentNegotiatorUtility('language',
                                        app_settings['languages'].keys())

    provide_utility(content_type, IContentNegotiation, 'content_type')
    provide_utility(language, IContentNegotiation, 'language')

    for database in app_settings['databases']:
        for key, dbconfig in database.items():
            factory = get_utility(IDatabaseConfigurationFactory,
                                  name=dbconfig['storage'])
            if asyncio.iscoroutinefunction(factory):
                future = asyncio.ensure_future(factory(key, dbconfig,
                                                       server_app),
                                               loop=loop)

                loop.run_until_complete(future)
                root[key] = future.result()
            else:
                root[key] = factory(key, dbconfig)

    for key, file_path in list_or_dict_items(app_settings['static']):
        path = resolve_path(file_path).resolve()
        if not path.exists():
            raise Exception('Invalid static directory {}'.format(file_path))
        if path.is_dir():
            root[key] = StaticDirectory(path)
        else:
            root[key] = StaticFile(path)
    for key, file_path in list_or_dict_items(app_settings['jsapps']):
        path = resolve_path(file_path).resolve()
        if not path.exists() or not path.is_dir():
            raise Exception('Invalid jsapps directory {}'.format(file_path))
        root[key] = JavaScriptApplication(path)

    root.set_root_user(app_settings['root_user'])

    if RSA is not None and not app_settings.get('rsa'):
        key = RSA.generate(2048)
        pub_jwk = {'k': key.publickey().exportKey('PEM')}
        priv_jwk = {'k': key.exportKey('PEM')}
        app_settings['rsa'] = {'pub': pub_jwk, 'priv': priv_jwk}

    # Set router root
    server_app.router.set_root(root)

    for utility in get_all_utilities_registered_for(IAsyncUtility):
        # In case there is Utilties that are registered
        if hasattr(utility, 'initialize'):
            task = asyncio.ensure_future(lazy_apply(utility.initialize,
                                                    app=server_app),
                                         loop=loop)
            root.add_async_task(utility, task, {})
        else:
            logger.warn(f'No initialize method found on {utility} object')

    server_app.on_cleanup.append(close_utilities)

    for util in app_settings['utilities']:
        root.add_async_utility(util, loop=loop)

    # Load cached Schemas
    load_cached_schema()

    optimize_settings(app_settings)

    return server_app
Beispiel #21
0
def load_commands(module_name, commands):
    module = resolve_dotted_name(module_name)
    if hasattr(module, 'app_settings') and app_settings != module.app_settings:
        commands.update(module.app_settings.get('commands', {}))
        for dependency in module.app_settings.get('applications') or []:
            load_commands(dependency, commands)
Beispiel #22
0
def load_behavior(_context, behavior):
    conf = behavior['config']
    klass = resolve_dotted_name(behavior['klass'])
    factory = conf.get('factory') or klass
    real_factory = resolve_dotted_name(factory)
    if IInterface.providedBy(real_factory):
        # create concret class to register for behavior
        schema = real_factory
        from guillotina.behaviors.instance import AnnotationBehavior

        class real_factory(AnnotationBehavior):
            __annotations_data_key__ = conf.get('data_key', 'default')
            auto_serialize = conf.get('auto_serialize', True)
    else:
        schema = resolve_dotted_name(conf['provides'])
    classImplements(real_factory, schema)

    name = conf.get('name')
    name_only = conf.get('name_only', False)
    title = conf.get('title', '')
    for_ = resolve_dotted_name(conf.get('for_'))
    marker = resolve_dotted_name(conf.get('marker'))

    if marker is None and real_factory is None:
        marker = schema

    if marker is not None and real_factory is None and marker is not schema:
        raise ConfigurationError(
            u"You cannot specify a different 'marker' and 'provides' if "
            u"there is no adapter factory for the provided interface."
        )
    if name_only and name is None:
        raise ConfigurationError(
            u"If you decide to only register by 'name', a name must be given."
        )

    # Instantiate the real factory if it's the schema-aware type. We do
    # this here so that the for_ interface may take this into account.
    if factory is not None and IBehaviorSchemaAwareFactory.providedBy(factory):
        factory = factory(schema)

    registration = BehaviorRegistration(
        title=conf.get('title', ''),
        description=conf.get('description', ''),
        interface=schema,
        marker=marker,
        factory=real_factory,
        name=name,
        for_=for_
    )
    if not name_only:
        # behavior registration by provides interface identifier
        component.utility(
            _context,
            provides=IBehavior,
            name=schema.__identifier__,
            component=registration
        )

    if name is not None:
        # for convinience we register with a given name
        component.utility(
            _context,
            provides=IBehavior,
            name=name,
            component=registration
        )

    if factory is None:
        if for_ is not None:
            logger.warning(
                u"Specifying 'for' in behavior '{0}' if no 'factory' is given "
                u"has no effect and is superfluous.".format(title)
            )
        # w/o factory we're done here
        return

    if for_ is None:
        # Attempt to guess the factory's adapted interface and use it as
        # the 'for_'.
        # Fallback to '*' (=Interface).
        adapts = getattr(factory, '__component_adapts__', None) or [Interface]
        if len(adapts) != 1:
            raise ConfigurationError(
                u"The factory can not be declared as multi-adapter."
            )
        for_ = adapts[0]

    adapter_factory = BehaviorAdapterFactory(registration)

    component.adapter(
        _context,
        factory=(adapter_factory,),
        provides=schema,
        for_=(for_,)
    )
Beispiel #23
0
def load_subscriber(_context, subscriber):
    conf = subscriber['config']
    conf['handler'] = resolve_dotted_name(
        conf.get('handler') or subscriber['klass'])
    _component_conf(conf)
    component.subscriber(_context, **conf)
Beispiel #24
0
def load_subscriber(_context, subscriber):
    conf = subscriber["config"]
    conf["handler"] = resolve_dotted_name(
        conf.get("handler") or subscriber["klass"])
    _component_conf(conf)
    component.subscriber(_context, **conf)
Beispiel #25
0
 async def _connect(self):
     klass = resolve_dotted_name(self._settings["driver"])
     self._driver = await klass.get_driver()
     await self._driver.initialize(self._loop)
     self._initialized = True
Beispiel #26
0
def load_commands(module_name, commands):
    module = resolve_dotted_name(module_name)
    if hasattr(module, 'app_settings') and app_settings != module.app_settings:
        commands.update(module.app_settings.get('commands', {}))
        for dependency in module.app_settings.get('applications') or []:
            load_commands(dependency, commands)
Beispiel #27
0
    def api(self, path, method='get', file_type_name=None, **kwargs):
        if path != '/':
            path = path.rstrip('/')

        print('Getting {} {}'.format(method, path))
        kwargs['auth'] = ('root', 'root')
        kwargs['headers'] = DEFAULT_HEADERS.copy()
        kwargs['headers'].update(kwargs.get('headers', {}))

        url = self._base_url + path
        response = getattr(requests, method)(url, **kwargs)
        self._store_type_name(response, url, kwargs)

        service = self.get_service_def(path, method.upper())
        # path scheme used for things like traversing to registry value...
        name = service.get('name')
        path_scheme = kwargs.pop('path_scheme', name)

        iface = resolve_dotted_name(self.get_service_type_name(path)[-1])
        dotted = get_dotted_name(iface)
        responses = self._function_swagger_param(service.get('responses'), url)
        parameters = self._function_swagger_param(service.get('parameters'),
                                                  url)
        data = {
            'path': path,
            'path_scheme': path_scheme,
            'method': method,
            'options': kwargs,
            'request': self.dump_request(response.request),
            'response': self.dump_response(response),
            'service': {
                'name': service.get('name'),
                'title': service.get('title'),
                'summary': service.get('summary'),
                'parameters': parameters,
                'responses': responses,
                'method': service.get('method', 'GET'),
                'context': get_dotted_name(iface),
                'permission': service.get('permission')
            }
        }

        if file_type_name is None:
            file_type_name = dotted.split('.')[-1][1:].lower()

        filepath = '{}/{}-{}'.format(self._output_dir, file_type_name,
                                     method.lower())

        if path_scheme != name:
            # use special name here...
            name, _, rest = path_scheme.partition('/')
            filepath += '-{}:{}'.format(
                name.replace('@', ''),
                ''.join([l for l in rest.split(':')[0] if l not in '[]():-']))
        elif service.get('name'):
            filepath += '-' + service.get('name').replace('@', '')

        filepath += '.json'
        fi = open(filepath, 'w')
        fi.write(json.dumps(data, indent=4, sort_keys=True))
        fi.close()
Beispiel #28
0
def load_behavior(_context, behavior):
    conf = behavior['config']
    klass = resolve_dotted_name(behavior['klass'])
    factory = conf.get('factory') or klass
    real_factory = resolve_dotted_name(factory)
    if IInterface.providedBy(real_factory):
        # create concret class to register for behavior
        schema = real_factory
        from guillotina.behaviors.instance import AnnotationBehavior

        class real_factory(AnnotationBehavior):
            __annotations_data_key__ = conf.get('data_key', 'default')
            auto_serialize = conf.get('auto_serialize', True)
    else:
        schema = resolve_dotted_name(conf['provides'])
    classImplements(real_factory, schema)

    name = conf.get('name')
    name_only = conf.get('name_only', False)
    title = conf.get('title', '')
    for_ = resolve_dotted_name(conf.get('for_'))
    marker = resolve_dotted_name(conf.get('marker'))

    if marker is None and real_factory is None:
        marker = schema

    if marker is not None and real_factory is None and marker is not schema:
        raise ConfigurationError(
            u"You cannot specify a different 'marker' and 'provides' if "
            u"there is no adapter factory for the provided interface."
        )
    if name_only and name is None:
        raise ConfigurationError(
            u"If you decide to only register by 'name', a name must be given."
        )

    # Instantiate the real factory if it's the schema-aware type. We do
    # this here so that the for_ interface may take this into account.
    if factory is not None and IBehaviorSchemaAwareFactory.providedBy(factory):
        factory = factory(schema)

    registration = BehaviorRegistration(
        title=conf.get('title', ''),
        description=conf.get('description', ''),
        interface=schema,
        marker=marker,
        factory=real_factory,
        name=name,
        for_=for_
    )
    if not name_only:
        # behavior registration by provides interface identifier
        component.utility(
            _context,
            provides=IBehavior,
            name=schema.__identifier__,
            component=registration
        )

    if name is not None:
        # for convinience we register with a given name
        component.utility(
            _context,
            provides=IBehavior,
            name=name,
            component=registration
        )

    if factory is None:
        if for_ is not None:
            logger.warning(
                u"Specifying 'for' in behavior '{0}' if no 'factory' is given "
                u"has no effect and is superfluous.".format(title)
            )
        # w/o factory we're done here
        return

    if for_ is None:
        # Attempt to guess the factory's adapted interface and use it as
        # the 'for_'.
        # Fallback to '*' (=Interface).
        adapts = getattr(factory, '__component_adapts__', None) or [Interface]
        if len(adapts) != 1:
            raise ConfigurationError(
                u"The factory can not be declared as multi-adapter."
            )
        for_ = adapts[0]

    adapter_factory = BehaviorAdapterFactory(registration)

    component.adapter(
        _context,
        factory=(adapter_factory,),
        provides=schema,
        for_=(for_,)
    )