def resolve_function(self, func, output_name=None, seen_state=None, parent_parameter=None): if output_name is None: output_name = 'response' if seen_state is None: seen_state = set(self.initial) steps = [] kwargs = {} consts = {} parameters = inspect.signature(func).parameters.values() for parameter in parameters: # The 'response' keyword always indicates the previous return value. if parameter.name == 'response': kwargs['response'] = 'response' continue # Check if the parameter class exists in 'initial'. if parameter.annotation in self.reverse_initial: initial_kwarg = self.reverse_initial[parameter.annotation] kwargs[parameter.name] = initial_kwarg continue # The 'Parameter' annotation can be used to get the parameter # itself. Used for example in 'Header' components that need the # parameter name in order to lookup a particular value. if parameter.annotation is inspect.Parameter: consts[parameter.name] = parent_parameter continue # Otherwise, find a component to resolve the parameter. for component in self.components: if component.can_handle_parameter(parameter): identity = component.identity(parameter) kwargs[parameter.name] = identity if identity not in seen_state: seen_state.add(identity) steps += self.resolve_function( func=component.resolve, output_name=identity, seen_state=seen_state, parent_parameter=parameter) break else: msg = 'No component able to handle parameter "%s" on function "%s".' raise ConfigurationError(msg % (parameter.name, func.__name__)) is_async = asyncio.iscoroutinefunction(func) if is_async and not self.allow_async: msg = 'Function "%s" may not be async.' raise ConfigurationError(msg % (func.__name__, )) step = (func, is_async, kwargs, consts, output_name) steps.append(step) return steps
def encode(payload, secret=None, algorithm=None, **kwargs): if secret is None: msg = 'The secret keyword argument must be defined.' raise ConfigurationError(msg) from None algorithm = 'HS256' if algorithm is None else algorithm try: token = jwt.encode(payload, secret, algorithm=algorithm, **kwargs).decode(encoding='UTF-8') except Exception as exc: raise ConfigurationError(exc.__class__.__name__) from None return token
def get_current_app() -> App: app_path = get_app_path() if not os.path.exists(app_path): raise ConfigurationError("No app.py module exists.") spec = importlib.util.spec_from_file_location("app", app_path) module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) app = getattr(module, 'app', None) if app is None: raise ConfigurationError("The app.py module did not contain an 'app' variable.") return app
def __new__(cls, name, bases, attrs): properties = [] for key, value in list(attrs.items()): if key in ['keys', 'items', 'values', 'get', 'validator']: msg = ('Cannot use reserved name "%s" on Type "%s", as it ' 'clashes with the class interface.') raise ConfigurationError(msg % (key, name)) elif hasattr(value, 'validate'): attrs.pop(key) properties.append((key, value)) # If this class is subclassing another Type, add that Type's properties. # Note that we loop over the bases in reverse. This is necessary in order # to maintain the correct order of properties. for base in reversed(bases): if hasattr(base, 'validator'): properties = [(key, base.validator.properties[key]) for key in base.validator.properties if key not in attrs] + properties properties = sorted(properties, key=lambda item: item[1]._creation_counter) required = [ key for key, value in properties if not value.has_default() ] attrs['validator'] = validators.Object(def_name=name, properties=properties, required=required, additional_properties=None) attrs['_creation_counter'] = validators.Validator._creation_counter validators.Validator._creation_counter += 1 return super(TypeMetaclass, cls).__new__(cls, name, bases, attrs)
def __init__(self, settings: Settings, token=None, issuer=None, audience=None, leeway=None): jwt_settings = settings.get('JWT', {}) self.secret = jwt_settings.get('SECRET', None) if self.secret is None: msg = 'The SECRET setting under JWT settings must be defined.' raise ConfigurationError(msg) from None self.algorithms = jwt_settings.get('ALGORITHMS', ['HS256']) self.token = token self.issuer = issuer if issuer is not None else jwt_settings.get( 'ISSUER', None) self.audience = audience if audience is not None else jwt_settings.get( 'AUDIENCE', None) self.leeway = leeway if leeway is not None else jwt_settings.get( 'LEEWAY', None) try: kwargs = {} if self.issuer: kwargs.update({'issuer': self.issuer}) if self.audience: kwargs.update({'audience': self.audience}) if self.leeway: kwargs.update({'leeway': self.leeway}) self.payload = jwt.decode(self.token, self.secret, algorithms=self.algorithms, **kwargs) except Exception: self.payload = None raise AuthenticationFailed()
def build(cls, arg_name: ArgName, templates: Templates): paths = arg_name.split(cls.path_delimiter) path = os.path.join(cls.prefix, *paths) for suffix in cls.suffixes: try: return templates.get_template(path + suffix) except jinja2.TemplateNotFound: pass raise ConfigurationError('No template found for "%s".' % arg_name)
def get_settings(settings: Settings): user_settings = dict(DEFAULTS) user_settings.update(settings.get(SETTINGS_KEY, {})) for module in IMPORT_STRINGS: if module not in user_settings and module not in DEFAULTS: raise ConfigurationError(f'{module} settings is required.') if user_settings['ORM'] == 'sqlalcamy': user_settings[module] = import_from_string(user_settings[module]) return user_settings
def test(file_or_dir): if not file_or_dir: file_or_dir = [] if os.path.exists('tests'): file_or_dir.append('tests') if os.path.exists('tests.py'): file_or_dir.append('tests.py') if not file_or_dir: raise ConfigurationError( "No 'tests/' directory or 'tests.py' module.") exitcode = pytest.main(list(file_or_dir)) if exitcode: sys.exit(exitcode)
def get_current_app(): app_path = os.path.join(os.getcwd(), 'app.py') if not os.path.exists(app_path): raise NoCurrentApp("No app.py module exists.") spec = importlib.util.spec_from_file_location("app", app_path) module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) if not hasattr(module, 'app'): raise ConfigurationError( "The app.py module did not contain an 'app' variable.") app = module.app return app
def test() -> None: # pragma: nocover """ Run the test suite. """ file_or_dir = [] if os.path.exists('tests'): file_or_dir.append('tests') if os.path.exists('tests.py'): file_or_dir.append('tests.py') if not file_or_dir: raise ConfigurationError("No 'tests/' directory or 'tests.py' module.") exitcode = pytest.main(list(file_or_dir)) if exitcode: sys.exit(exitcode)
def test(file_or_dir): from apistar.main import get_current_app app = get_current_app() if not file_or_dir: file_or_dir = [] if os.path.exists('tests'): file_or_dir.append('tests') if os.path.exists('tests.py'): file_or_dir.append('tests.py') if not file_or_dir: raise ConfigurationError( "No 'tests/' directory or 'tests.py' module.") exitcode = pytest.main(list(file_or_dir)) if exitcode: sys.exit(exitcode)
def __new__(cls, name, bases, attrs): properties = [] for key, value in list(attrs.items()): if key in ['keys', 'items', 'values', 'get', 'validator']: msg = ('Cannot use reserved name "%s" on Type "%s", as it ' 'clashes with the class interface.') raise ConfigurationError(msg % (key, name)) elif isinstance(value, validators.Validator): attrs.pop(key) properties.append((key, value)) properties = sorted(properties, key=lambda item: item[1]._creation_counter) required = [ key for key, value in properties if not value.has_default() ] attrs['validator'] = validators.Object(def_name=name, properties=properties, required=required, additional_properties=None) return super(TypeMetaclass, cls).__new__(cls, name, bases, attrs)
def _raise_setup_error(self): msg = ('JWT_SECRET must be defined as an environment variable or passed as part of' ' settings on instantiation.' ' See https://github.com/audiolion/apistar-jwt#Setup') raise ConfigurationError(msg)
def resolve_function( self, func, output_name=None, seen_state=None, parent_parameter=None, set_return=False, ): if seen_state is None: seen_state = set(self.initial) steps = [] kwargs = {} consts = {} signature = inspect.signature(func) if output_name is None: if signature.return_annotation in self.reverse_initial: output_name = self.reverse_initial[signature.return_annotation] else: output_name = "return_value" for parameter in signature.parameters.values(): if parameter.annotation is ReturnValue: kwargs[parameter.name] = "return_value" continue # Check if the parameter class exists in 'initial'. if parameter.annotation in self.reverse_initial: initial_kwarg = self.reverse_initial[parameter.annotation] kwargs[parameter.name] = initial_kwarg continue # The 'Parameter' annotation can be used to get the parameter # itself. Used for example in 'Header' components that need the # parameter name in order to lookup a particular value. if parameter.annotation is inspect.Parameter: consts[parameter.name] = parent_parameter continue # Otherwise, find a component to resolve the parameter. for component in self.components: if component.can_handle_parameter(parameter): identity = component.identity(parameter) kwargs[parameter.name] = identity if identity not in seen_state: seen_state.add(identity) steps += self.resolve_function( func=component.resolve, output_name=identity, seen_state=seen_state, parent_parameter=parameter, ) break else: msg = f"No component able to handle parameter {parameter.name}: {parameter} on function {func.__name__}." raise ConfigurationError(msg) is_async = asyncio.iscoroutinefunction(func) if is_async and not self.allow_async: msg = 'Function "%s" may not be async.' raise ConfigurationError(msg % (func.__name__, )) step = (func, is_async, kwargs, consts, output_name, set_return) steps.append(step) return steps