コード例 #1
0
ファイル: bootstrap.py プロジェクト: uvicore/framework
    def __call__(self, event: OnAppBooted):
        """Bootstrap the Database after the Application is Booted"""

        # Gather all connections, models, tables
        # No need to gather seeder classes, I get those in the ./uvicore db seed command
        connections = Dict()
        models = []; tables = []
        last_default = None; app_default = None
        for package in uvicore.app.packages.values():
            if not 'database' in package: continue

            # Get last defined default connection
            if package.database.connection_default: last_default = package.database.connection_default

            # Get running app default connection
            if package.main and package.database.connection_default: app_default = package.database.connection_default

            # Append connections
            connections.merge(package.database.connections)

            # Append models
            models.extend(package.database.models or [])

            # Append tables
            tables.extend(package.database.tables or [])

        # Initialize Database with all connections at once
        uvicore.db.init(app_default or last_default, connections)

        # Dynamically Import models, tables and seeders
        for model in models: load(model)
        for table in tables: load(table)
コード例 #2
0
 def subscribe(self, listener: Union[str, Callable]) -> None:
     """Add a subscription class which handles both registration and listener callbacks"""
     try:
         if type(listener) == str:
             module.load(listener).object().subscribe(uvicore.events)
         else:
             listener.subscribe(uvicore.events)
     except ModuleNotFoundError:
         pass
コード例 #3
0
    def add_middleware(self, web_server: FastAPI, api_server: FastAPI) -> None:
        """Add global web and api middleware to their respective servers"""

        # Add global web middleware
        if web_server:
            for name, middleware in uvicore.config.app.web.middleware.items():
                cls = module.load(middleware.module).object
                web_server.add_middleware(cls, **middleware.options)

        # Add global api middleware
        if api_server:
            for name, middleware in uvicore.config.app.api.middleware.items():
                cls = module.load(middleware.module).object
                api_server.add_middleware(cls, **middleware.options)
コード例 #4
0
    def _get_dispatcher(self,
                        event: Union[str, Callable],
                        payload: Dict = {},
                        is_async: bool = False) -> Tuple:
        """Get dispatcher method for this event"""
        # This function determines the proper dispatching method for this event.
        # If event is a string, we use self._dispatch
        # If event is a class we call that classes .dispatch method
        method = None
        params = [event, payload]
        if type(event) == str:
            if '-' in event or '{' in event:
                # String event (we know because classes can't have dashes or {.
                # This is how we name dynamic string based events like per model or table...
                method = self._dispatch_async if is_async else self.dispatch
            else:
                # See if string event has a matching class.  If so, import and dispatch it
                try:
                    event = module.load(event).object(**payload)
                    params = []
                    method = event.dispatch_async if is_async else event.dispatch
                except:
                    # No class found for this string.  This is OK because events can
                    # be strings without matching classes.  Dispatch it anyway
                    method = self._dispatch_async if is_async else self._dispatch
        else:
            # Event is an event class INSTANCE.  Call the actual classes dispatch method
            # in case the user overrode it, we still execute it
            params = []
            method = event.dispatch_async if is_async else event.dispatch

        # Return tuple of dispatcher method and params
        return (method, params)
コード例 #5
0
ファイル: base.py プロジェクト: coboyoshi/uvicore
    async def retrieve_user(self, username: str, password: str, provider: Dict,
                            request: HTTPConnection,
                            **kwargs) -> Optional[UserInfo]:
        """Retrieve user from User Provider backend"""

        # Import user provider defined in auth config
        user_provider: UserProvider = module.load(provider.module).object()

        # Get user from user provider and validate password.  User will be Anonymous
        # if user not found, disabled or validation failed
        user = await user_provider.retrieve_by_credentials(
            # Require parameters
            username=username,
            password=password,
            request=request,

            # Pass in options from auth config
            **provider.options,

            # Pass in options from the calling authenticator
            **kwargs,
        )

        # Do not throw error if no user or not validated here.  We let the middleware handle that
        return user
コード例 #6
0
ファイル: bootstrap.py プロジェクト: coboyoshi/uvicore
    def add_exception_handlers(self, web_server: FastAPI,
                               api_server: FastAPI) -> None:
        """Add global web and api exception handlers to their respective servers"""
        from starlette.exceptions import HTTPException

        # Add global web exception handlers
        if web_server and uvicore.config.app.web.exception.handler:
            cls = module.load(uvicore.config.app.web.exception.handler).object
            web_server.add_exception_handler(HTTPException, cls)
            # for name, handler in uvicore.config.app.web.exceptions.items():
            #     if str(name).lower() == 'main':
            #         cls = module.load(handler).object
            #         web_server.add_exception_handler(HTTPException, cls)

        # Add global api exception handlers
        if api_server and uvicore.config.app.api.exception.handler:
            cls = module.load(uvicore.config.app.api.exception.handler).object
            api_server.add_exception_handler(HTTPException, cls)
コード例 #7
0
ファイル: base.py プロジェクト: coboyoshi/uvicore
    async def sync_user(self, provider: Dict, request: HTTPConnection,
                        **kwargs):
        # Import user provider defined in auth config
        user_provider: UserProvider = module.load(provider.module).object()

        # Create user from user provider
        # Returned user is actual backend user, NOT Auth User object
        user = await user_provider.sync_user(request, **kwargs)
        return user
コード例 #8
0
 def _get_package_config(self, package: str, options: Dict) -> Dict:
     config_module = package + '.config.package.config'  # Default if not defined
     if 'config' in options: config_module = options['config']
     config = Dict()
     try:
         config = Dict(load(config_module).object)
     except:
         # Often we won't have any config for a package, if so return empty Dict
         pass
     return config
コード例 #9
0
ファイル: provider.py プロジェクト: uvicore/framework
    def configs(self, options: List[Dict]) -> None:
        for config in options:
            # Load module to get actual config value
            value = load(config['module']).object

            # Merge config value with complete config
            #uvicore.config.merge(config['key'], value)
            new = Dict()
            new.dotset(config['key'], value)
            uvicore.config.merge(new)
コード例 #10
0
    def __call__(self, event: OnAppBooted):
        """Bootstrap the Console after the Application is Booted"""

        #from uvicore.console.console import cli
        cli = uvicore.ioc.make('uvicore.console.console.cli')

        # Deep merge all command groups, this allows simple command extension!
        groups = Dict()
        for package in uvicore.app.packages.values():
            if not 'console' in package: continue

            # Only register commands if package registration is allowed
            # AND if running from the console...OR if the command group is
            # 'http'.  We always want the http group regardless of cli or
            # http entrypoints.
            register = package.registers.commands
            is_console = uvicore.app.is_console
            for key, group in package.console['groups'].items():
                if (register and is_console) or key == 'http':
                    groups.merge({key: group})

        # Register each group and each groups commands
        click_groups = {}
        for key, group in groups.items():
            # Split key to find parent/child groups
            parts = key.split(':')
            parent = ':'.join(parts[0:-1])
            name = parts[-1]

            # Create a new click group if not exists
            @cli_group(help=group['help'])
            def click_group():
                pass

            click_groups[key] = click_group

            # Get click group based on key (this is how we handle sub groups)
            #click_group = click_groups[key]

            # Add all commands into this click_group
            for command_name, command_module in group.commands.items():
                # Dynamically import the commands module
                module = load(command_module).object
                click_group.add_command(module, command_name)

            # Add group to console
            if len(parts) == 1:
                # Root level group
                cli.add_command(click_group, name)
            else:
                # Sub group
                click_groups[parent].add_command(click_group, name)
コード例 #11
0
    async def retrieve_user(self, username: str, password: str,
                            provider: Dict) -> Optional[User]:
        """Retrieve user from User Provider backend"""
        # Import our user provider defined in auth config
        user_provider: UserProvider = module.load(provider.module).object()

        # Get user from user provider and validate password
        # If returned user is None, validation has failed, user is disabled or user not found
        user = await user_provider.retrieve_by_credentials(
            username, password, **provider.options)

        # Do not throw error if no user or not validated here.  We let the middleware handle that
        return user
コード例 #12
0
    def connect(self, store: str = None) -> CacheInterface:
        """Connect to a cache backend store"""
        store_name = store or self.default
        store = self.stores.get(store_name)
        if not store:
            raise Exception('Cache store {} not found'.format(store_name))

        if store_name not in self.backends:
            # Instantiate, connect and save store in local backends cache
            driver = module.load(store.driver).object(self, store)
            self._backends[store_name] = driver

        return self.backends[store_name]
コード例 #13
0
def test_load_file():
    # Import actual module (file) but not a method inside it
    # Module(
    #     object=<module 'uvicore.foundation.config.package' from '/home/mreschke/Code/mreschke/python/uvicore/uvicore/uvicore/foundation/config/package.py'>,
    #     name='package',
    #     path='uvicore.foundation.config',
    #     fullpath='uvicore.foundation.config.package',
    #     package='uvicore.foundation.config',
    #     file='/home/mreschke/Code/mreschke/python/uvicore/uvicore/uvicore/foundation/config/package.py')
    x = module.load('uvicore.foundation.config.package')
    assert "<module 'uvicore.foundation.config.package' from " in str(x.object)
    assert x.name == 'package'
    assert x.path == 'uvicore.foundation.config'
    assert x.fullpath == 'uvicore.foundation.config.package'
    assert x.package == 'uvicore.foundation.config'
    assert 'uvicore/foundation/config/package.py' in x.file
コード例 #14
0
def test_load_namespace():
    # Import namespace package (no __init__.py)
    # Module(
    #     object=<module 'uvicore.foundation' (namespace)>,
    #     name='foundation',
    #     path='uvicore',
    #     fullpath='uvicore.foundation',
    #     package='uvicore.foundation',
    #     file='/home/mreschke/Code/mreschke/python/uvicore/uvicore/uvicore/foundation')
    x = module.load('uvicore.foundation')
    assert str(x.object) == "<module 'uvicore.foundation' (namespace)>"
    assert x.name == 'foundation'
    assert x.path == 'uvicore'
    assert x.fullpath == 'uvicore.foundation'
    assert x.package == 'uvicore.foundation'
    assert 'uvicore/foundation' in x.file
コード例 #15
0
def test_load_package():
    # Import non root level package (has __init__.py)
    # Module(
    #     object=<module 'uvicore.container' from '/home/mreschke/Code/mreschke/python/uvicore/uvicore/uvicore/container/__init__.py'>,
    #     name='container',
    #     path='uvicore',
    #     fullpath='uvicore.container',
    #     package='uvicore.container',
    #     file='/home/mreschke/Code/mreschke/python/uvicore/uvicore/uvicore/container/__init__.py')
    x = module.load('uvicore.configuration')
    assert "<module 'uvicore.configuration' from " in str(x.object)
    assert x.name == 'configuration'
    assert x.path == 'uvicore'
    assert x.fullpath == 'uvicore.configuration'
    assert x.package == 'uvicore.configuration'
    assert 'uvicore/configuration/__init__.py' in x.file
コード例 #16
0
def test_load_root():
    # Import root level package (has __init__.py)
    # Module(
    #     object=<module 'uvicore' from '/home/mreschke/Code/mreschke/python/uvicore/uvicore/uvicore/__init__.py'>,
    #     name='uvicore',
    #     path='uvicore',
    #     fullpath='uvicore',
    #     package='uvicore',
    #     file='/home/mreschke/Code/mreschke/python/uvicore/uvicore/uvicore/__init__.py')
    x = module.load('uvicore')
    assert "<module 'uvicore' from " in str(x.object)
    assert x.name == 'uvicore'
    assert x.path == 'uvicore'
    assert x.fullpath == 'uvicore'
    assert x.package == 'uvicore'
    assert 'uvicore/__init__.py' in x.file
コード例 #17
0
ファイル: bootstrap.py プロジェクト: coboyoshi/uvicore
    def import_package_web_routes(self, package: Package) -> Dict:
        """Import one package web routes and return routes Dict"""

        # If no routes_modules defined, nothing todo
        if not package.web.routes_module: return

        # Allow only if running as HTTP or from certain CLI commands like package list/show...
        if package.registers.web_routes and (
                uvicore.app.is_http  #or
                #command_is('http') or
                #command_is('package') or
                #command_is('ioc')
        ) == False:
            return

        routes_module = package.web.routes_module
        prefix = package.web.prefix
        name_prefix = package.web.name_prefix

        # Import main web routes module
        routes: Routes = module.load(routes_module).object(package)

        # Get name prefix from package name plus custom name prefix
        if name_prefix:
            if name_prefix[0] == '.': name_prefix = name_prefix[1:]
            name_prefix = package.short_name + '.' + name_prefix
        else:
            name_prefix = package.short_name

        # Import the web router and create a new instance
        from uvicore.http.routing.web_router import WebRouter  # isort:skip
        router = WebRouter(package, prefix, name_prefix)

        # Get returned router with all defined routes
        router = routes.register(router)

        # Merge routes level middleware into each route
        routes_middleware = routes._middleware()
        if routes_middleware:
            for route in router.routes.values():
                (route.middleware,
                 route.endpoint) = router._merge_route_middleware(
                     routes_middleware, route.middleware, route.endpoint)

        # Return routes
        return router.routes
コード例 #18
0
    def _get_handlers(self,
                      event: Union[str, Callable],
                      payload: Dict = {}) -> Tuple:
        """Get all listener/handlers and fix up payload"""
        # Get event by string name or class inspection
        #event_meta = self.event(event)

        if type(event) == str:
            # String based event, merge payload with default event
            event = Dict(payload).merge({
                'name':
                event,
                'description':
                'String based dynamic event.'
            })

        # Payload default is a SuperDict
        #payload = Dict(payload)

        # If event is a class, payload is the class instance
        #if type(event) != str: payload = event

        # Get listener methods (dynamic import if string)
        listeners = self.event_listeners(event.name)
        handlers = []
        for handler in listeners:
            if type(handler) == str:
                # handler is a string to a listener class with handle() method
                try:
                    #cls = module.load(listener).object(uvicore.app)
                    cls = module.load(handler).object()
                    handlers.append(cls)
                    #handlers.append(cls.handle)
                except ModuleNotFoundError:
                    # Bad handler, handler will never fire
                    continue
            else:
                # handler is a Class
                if inspect.isclass(handler): handler = handler()

                # Listener is a Callable (if was a class, NOW its callable)
                handlers.append(handler)

        # Return tuple of event and handlers
        #return (event_meta, payload, handlers)
        return (event, handlers)
コード例 #19
0
ファイル: authentication.py プロジェクト: uvicore/framework
    async def retrieve_anonymous_user(self, request: HTTPConnection):
        """Retrieve anonymous user from User Provider backend"""

        # Import user provider defined in auth config
        # Anonymous user provider is always the 'default_provider'
        user_provider: UserProvider = module.load(self.config.default_provider.module).object()

        # Get additional provider kwargs from options and anonymous_options config
        kwargs = self.config.default_provider.options.clone()
        kwargs.merge(self.config.default_provider.anonymous_options)  # Anonymous wins in merge

        # Alter provider method called based on existence of username, id, or uuid parameters
        provider_method = user_provider.retrieve_by_username
        if 'id' in kwargs: provider_method = user_provider.retrieve_by_id
        if 'uuid' in kwargs: provider_method = user_provider.retrieve_by_uuid

        # Call user provider method passing in defined kwargs
        return await provider_method(request=request, **kwargs)
コード例 #20
0
def test_load_object():
    # Import class from inside a file
    # uvicore.support.module.Module(
    #     object=uvicore.container.ioc._Ioc,  # class
    #     name='_Ioc',
    #     path='uvicore.container.ioc',
    #     fullpath='uvicore.container.ioc._Ioc',
    #     package='uvicore.container',
    #     file='/home/mreschke/Code/mreschke/python/uvicore/uvicore/uvicore/'
    #         'container/ioc.py'
    # )
    x = module.load('uvicore.container.ioc._Ioc')
    assert "<class 'uvicore.container.ioc._Ioc'>" in str(x.object)
    assert x.name == '_Ioc'
    assert x.path == 'uvicore.container.ioc'
    assert x.fullpath == 'uvicore.container.ioc._Ioc'
    assert x.package == 'uvicore.container'
    assert 'uvicore/container/ioc.py' in x.file
コード例 #21
0
    def _register_providers(self, app_config: Dict) -> None:
        """Register all providers by calling each ServiceProviders register() method"""

        for package_name, service in self.providers.items():
            # Example:
            # package_name = uvicore.configuration
            # service = {'provider': 'uvicore.configuration.services.Configuration'}

            # Start a new package definition
            #x = OrderedDict()
            #x.dotset(package_name, package.Definition({
            self._packages[package_name] = Package({
                'name':
                package_name,
                'short_name':
                package_name.split('.')[-1]
                if '.' in package_name else package_name,
                'vendor':
                package_name.split('.')[0],  # Works fine even if no .
                'main':
                True if package_name == self.main else False,
                'path':
                location(package_name),
            })
            #self._packages.merge(x)
            #self._packages[package_name] = package.Definition({
            #dd(self.packages)

            # Instantiate the provider and call the register() method
            provider = load(service['provider']).object(
                app=self,
                name=package_name,
                package=None,  # Not available in register()
                app_config=app_config,
                package_config=self._get_package_config(package_name, service),
            )
            provider.register()

        # Complete registration
        self._registered = True
        #uvicore.events.dispatch('uvicore.foundation.events.app.Registered')
        #uvicore.events.dispatch(uvicore.foundation.events.app.Registered())
        #uvicore.events.dispatch('uvicore.foundation.events.app.Registered', {'test': 'test1'})
        events.Registered().dispatch()
コード例 #22
0
    def _boot_providers(self, app_config: Dict) -> None:
        for package_name, service in self.providers.items():
            # Example:
            # package_name = uvicore.configuration
            # service = {'provider': 'uvicore.configuration.services.Configuration'}

            # Import the provider and call boot()
            provider = load(service['provider']).object(
                app=self,
                name=package_name,
                package=self.package(package_name),
                app_config=app_config,
                package_config=self._get_package_config(package_name, service),
            )
            provider.boot()

        # Complete booting
        self._booted = True
        #uvicore.events.dispatch('uvicore.foundation.events.app.Booted')
        #uvicore.events.dispatch(uvicore.foundation.events.app.Booted())
        #uvicore.events.dispatch('uvicore.foundation.events.app.Booted')
        events.Booted().dispatch()
コード例 #23
0
ファイル: ioc.py プロジェクト: uvicore/framework
    def make(self, name: str, default: Callable[[], T] = None, **kwargs) -> T:
        if default is not None and self.binding(name) is None:
            # Default was provided and no binding currently exists
            # Bind the default provided but look for bindings override in app_config
            #object = default
            #bindings = self._app_config.get('bindings') or {}
            #object = bindings.get(name) or default
            object = self.overrides.get(name) or default
            self.bind(name, object, **kwargs)

        binding = self.binding(name)
        if not binding:
            # No binding set yet.  If we simply try to import the file only, it may have a
            # decorator that will bind itself.  If no binding found even after import, treat as not found
            if '.' in name: module.load(name)

            # Check binding again
            binding = self.binding(name)
            if not binding:
                raise ModuleNotFoundError("Could not find IoC name '{}' in mapping.".format(name))

        # If object is not defined, dynamically import it on first make (deferred)
        if not binding.object:
            # If object is None, dynamically import object from path
            binding.object = module.load(binding.path).object

        # Determine type
        is_class = inspect.isclass(binding.object)
        is_singleton = is_class and binding.singleton
        kwargs = binding.kwargs or {}

        # Odd case
        if not is_class and binding.singleton and hasattr(binding.object, '__class__') and '.' in str(getattr(binding.object, '__class__')):
            # If you override a singlton with another singleton (in the case of overriding a table for example)
            # You get an odd case where the binding object is the singleton itself.  So here we detect if the object
            # should be a singleton, and is NOT a class (because its already a singleton instance) and the object
            # is an instance (meaning it has a __class__ attribute) then we need to swap the instance with the object
            # and set the objects name to the instances __class__
            # By checking if __class__ has a . in it we skip over if someone accidentally added a singleton to a function or method
            # In case you are wondering, the singleton of the original IS the same singleton as the override!
            binding.instance = binding.object
            binding.object = binding.instance.__class__
            is_singleton = True

        # Instantiate a singleton only once
        made = None
        if is_singleton:
            if not binding.instance:
                if binding.factory:
                    factory = module.load(binding.factory).object
                    binding.instance = factory().make(binding.object, **kwargs)
                else:
                    binding.instance = binding.object(**kwargs)
            made = binding.instance

        # Instantiate a non-singleton every time
        # Unless there is no factory and no kwargs, simply return the object class
        elif is_class:
            if binding.factory:
                if type(binding.factory) == str:
                    # String factory, dynamically import it
                    factory = module.load(binding.factory).object
                else:
                    # Direct class factory
                    factory = binding.factory
                made = factory().make(binding.object, **kwargs)
            elif binding.kwargs:
                made = binding.object(**kwargs)
            else:
                made = binding.object

        # Bind is not a class.  Must be a method or module, return it
        else:
            made = binding.object

        # Return made object
        return made
コード例 #24
0
def test_load_invalid():
    # Import invalid module
    with pytest.raises(ModuleNotFoundError):
        module.load('uvicorex')
コード例 #25
0
def test_load_invalid_attribute():
    # Import invalid attribute
    with pytest.raises(Exception):
        module.load('uvicore.nothing')
コード例 #26
0
def test_load_wildcard():
    # Import wildcard
    module.load('uvicore.foundation.config.*')
コード例 #27
0
    def controller(self,
                   module: Union[str, Callable],
                   *,
                   prefix: str = '',
                   name: str = '',
                   tags: Optional[List[str]] = None,
                   options: Dict = {}) -> List:
        """Include a Route Controller"""
        if prefix:
            if prefix[-1] == '/': prefix = prefix[0:-1]  # Remove trailing /
            if prefix[0] != '/': prefix = '/' + prefix  # Add beginning /

        # Get name
        if not name: name = prefix

        # Clean name
        if name:
            name = name.replace('/', '.')
            if name[-1] == '.': name = name[0:-1]  # Remove trailing .
            if name[0] == '.': name = name[1:]  # Remove beginning .

        # Import controller module from string
        cls = module
        if type(module) == str:
            if self.controllers:
                if '.' not in module:
                    # We are defining just 'home', so we add .Home class
                    module = self.controllers + '.' + module + '.' + string.studly(
                        module)
                elif module[0] == '.':
                    # We are appending the path to self.controllers
                    # Must have class too, ex: .folder.stuff.Stuff
                    module = self.controllers + module
                # elif module.count('.') == 1: # NO, we'll just add a . before, like .home.Home and it does the same thing
                #     # We are defining the file and the class (home.Home)
                #     # Only works with ONE dot.  If you want to append use .folder.stuff.Stuff
                #     module = self.controllers + '.' + module
                else:
                    # We are defining the FULL module path even though we have defined a self.controller path
                    # Must have class too, ex: acme.appstub.http.api.stuff.Stuff
                    pass

            # Dynamically import the calculated module
            cls = load(module).object
            if str(type(cls)) == "<class 'module'>":
                # Trying to load a module, but we want the class inside the module, auto add
                module = module + '.' + string.studly(module.split('.')[-1])
                cls = load(module).object

        # Instantiate controller file
        controller: Routes = cls(self.package, **options)

        # New self (Web or Api) router instance
        router = self.__class__(self.package, self.prefix + prefix,
                                self.name + '.' + name, self.controllers)

        # Register controllers routes and return new updated router
        router = controller.register(router)

        # Add contoller class level attributes as middleware to each route on this controller
        controller_middlewares = controller._middleware()
        if controller_middlewares:
            for route in router.routes.values():
                (route.middleware,
                 route.endpoint) = self._merge_route_middleware(
                     controller_middlewares, route.middleware, route.endpoint)

        # Merge controllers routes into this main (parent of recursion) router
        #dump(router.routes)
        self.routes.merge(router.routes)

        # Return just this controllers routes as a list
        routes = []
        for route in router.routes.keys():
            # Append .controller(tags=[xyz]) if exists
            if tags:
                if router.routes[route].tags is None:
                    router.routes[route].tags = []
                router.routes[route].tags.extend(tags)
            routes.append(router.routes[route])

        return routes
コード例 #28
0
ファイル: router.py プロジェクト: uvicore/framework
    def controller(self,
                   module: Union[str, Callable],
                   *,
                   prefix: str = '',
                   name: str = '',
                   tags: Optional[List[str]] = None,
                   options: Dict = {}) -> List:
        if prefix:
            if prefix[-1] == '/': prefix = prefix[0:-1]  # Remove trailing /
            if prefix[0] != '/': prefix = '/' + prefix  # Add beginning /

        # Get name
        if not name: name = prefix

        # Clean name
        if name:
            name = name.replace('/', '.')
            if name[-1] == '.': name = name[0:-1]  # Remove trailing .
            if name[0] == '.': name = name[1:]  # Remove beginning .

        # Import controller module from string
        if type(module) == str:
            if self.controllers:
                if '.' not in module:
                    # We are defining just 'home', so we add .Home class
                    module = self.controllers + '.' + module + '.' + string.studly(
                        module)
                elif module.count('.') == 1:
                    # We are defining the file and the class (home.Home)
                    module = self.controllers + '.' + module
                else:
                    # We are defining the FULL module path even though we have defined a self.controller path
                    pass
            module = load(module).object

        # Instantiate controller file
        controller: Routes = module(self.package, **options)

        # New self (Web or Api) router instance
        router = self.__class__(self.package, self.prefix + prefix,
                                self.name + '.' + name, self.controllers)

        # Register controllers routes and return new updated router
        router = controller.register(router)

        # Add contoller class level attributes as middleware to each route on this controller
        controller_middlewares = controller._middleware()
        if controller_middlewares:
            for route in router.routes.values():
                (route.middleware,
                 route.endpoint) = self._merge_route_middleware(
                     controller_middlewares, route.middleware, route.endpoint)

        # Merge controllers routes into this main (parent of recursion) router
        #dump(router.routes)
        self.routes.merge(router.routes)

        # Return just this controllers routes as a list
        routes = []
        for route in router.routes.keys():
            routes.append(router.routes[route])

        return routes
コード例 #29
0
    async def __call__(self, scopes: SecurityScopes, request: Request):
        #dump(self.guard)
        # Dict({
        #     'authenticators': Dict({
        #         'jwt': Dict({
        #             'module': 'uvicore.auth.middleware.Jwt',
        #             'verify_signature': True,
        #             'algorithms': ['RS256'],
        #             'secret':
        #                 '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnc84SDViVX8JNye2GVQZ\n'
        #                 'ixAwG2PWXoOhkj++wGASoAXs2LN0Ue48conxf/0bgEtq6kcbLPR23SieqBZA77vc\n'
        #                 'yulimMbzfwNczyP3FRo8wSCqRgJipTse87WItd8ga2MUCzSS8q19V4swUT4T23Su\n'
        #                 'DiG/Ry5f1sYbvxP2kJAJMUCzVbS7STxh33h65Bj+P6JdzrCJi+yrLqg928RHjLIF\n'
        #                 'gDy4MyFBLTI8w5u6IJi1TLm6h9lj3YqSa/qDkkIardnnZa7Xj0IJCEB9c+RD4Q7C\n'
        #                 '+jco6g2Vr9oLP8Mg3c5lZPNVzcXC67UMVk9lK+zrlfPDI/m2+9kyTc/58S9ZUTFJ\nQwIDAQAB\n-----END PUBLIC KEY-----'
        #         }),
        #         'basic': Dict({
        #             'module': 'uvicore.auth.middleware.Basic',
        #             'provider': 'users',
        #             'realm': 'App1'
        #         })
        #     }),
        #     'name': 'api'
        # })

        for authenticator in self.guard.authenticators.values():
            # Get authenticator options by deep merging defaults and proper providers
            options = authenticator.clone()
            if 'options' in options:
                # Deep merge default options
                option_key = options.options
                if option_key not in self.options:
                    # This is an application error, not an HTTPException
                    raise Exception(
                        'Default options key {} not found in app config'.
                        format(option_key))
                options.defaults(
                    self.options[option_key])  # Merge seems to do a clone too!

            # Merge provider into options
            if 'provider' in options:
                if options.provider not in self.providers:
                    # This is an application error, not an HTTPException
                    raise Exception(
                        'Provider {} not found in app config'.format(
                            options.provider))
                options.provider = self.providers[options.provider].clone()

            options.guard = self.guard.name

            #dump(options)
            # Dict({
            #     'default_options': 'jwt',
            #     'module': 'uvicore.auth.middleware.Jwt',
            #     'provider': Dict({
            #         'module': 'uvicore.auth.models.user.User',
            #         'method': 'userinfo',
            #         'model': 'uvicore.auth.models.user.User',
            #         'includes': ['roles', 'roles.permissions', 'groups', 'groups.roles', 'groups.roles.permissions']
            #     }),
            #     'sync': Dict({'auto_create_user': True}),
            #     'verify_signature': True,
            #     'audience': '222b06eb-85ce-472b-af30-ec09244e3bf0',
            #     'algorithms': ['RS256'],
            #     'secret':
            #         '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnc84SDViVX8JNye2GVQZ\n'
            #         'ixAwG2PWXoOhkj++wGASoAXs2LN0Ue48conxf/0bgEtq6kcbLPR23SieqBZA77vc\n'
            #         'yulimMbzfwNczyP3FRo8wSCqRgJipTse87WItd8ga2MUCzSS8q19V4swUT4T23Su\n'
            #         'DiG/Ry5f1sYbvxP2kJAJMUCzVbS7STxh33h65Bj+P6JdzrCJi+yrLqg928RHjLIF\n'
            #         'gDy4MyFBLTI8w5u6IJi1TLm6h9lj3YqSa/qDkkIardnnZa7Xj0IJCEB9c+RD4Q7C\n'
            #         '+jco6g2Vr9oLP8Mg3c5lZPNVzcXC67UMVk9lK+zrlfPDI/m2+9kyTc/58S9ZUTFJ\nQwIDAQAB\n-----END PUBLIC KEY-----'
            # })

            # Import the auth middleware module
            middleware = module.load(options.module).object(options)

            # Fire the middleware __call__ callable and get the returned value
            value = await middleware(scopes, request)

            # If value is returned, auth was successful with this authenticator.  Return value, stop the middleware stack.
            # If value is None means auth headers not found.  Continue to next middleware in auth stack
            if value is not None:
                return value

        # If we are here, no auth middleware returned a value, meaning NOT logged in
        # If no value is ever returned we are not logged in.
        # Maybe here is the place to add an anonymous user to the request? with user.authenticated = False ???????
        # NO, think about this.  If a route is NOT guarded, this code will never run therefore request.user will
        # never exist.  Would have to do global auth middleware to accomplish an always present anonymous user.
        # I could have a built-in hidden global middleware that adds request.user as an anonymous model?
        raise NotAuthenticated('MASTER STACKER')
コード例 #30
0
ファイル: fields.py プロジェクト: uvicore/framework
 def _load_entity(self):
     # Fill actual entity class
     if uvicore.ioc.binding(self.model):
         self.entity = uvicore.ioc.make(self.model)
     else:
         self.entity = module.load(self.model).object