def setup_error(cls, error): ''' Sample configuration:: error: 404: path: template.json # Use a template autoescape: false # with no autoescape whitespace: single # as a single line headers: Content-Type: application/json 500: function: module.fn args: [=status_code, =kwargs, =handler] ''' if not error: return if not isinstance(error, dict): return app_log.error('url:%s.error is not a dict', cls.name) # Compile all errors handlers cls.error = {} for error_code, error_config in error.items(): try: error_code = int(error_code) if error_code < 100 or error_code > 1000: raise ValueError() except ValueError: app_log.error('url.%s.error code %s is not a number (100 - 1000)', cls.name, error_code) continue if not isinstance(error_config, dict): return app_log.error('url:%s.error.%d is not a dict', cls.name, error_code) # Make a copy of the original. When we add headers, etc, it shouldn't affect original error_config = AttrDict(error_config) error_path, error_function = error_config.get('path'), error_config.get('function') if error_function: if error_path: error_config.pop('path') app_log.warning('url.%s.error.%d has function: AND path:. Ignoring path:', cls.name, error_code) cls.error[error_code] = {'function': build_transform( error_config, vars=AttrDict((('status_code', None), ('kwargs', None), ('handler', None))), filename='url:%s.error.%d' % (cls.name, error_code) )} elif error_path: encoding = error_config.get('encoding', 'utf-8') cls.error[error_code] = {'function': cls._error_fn(error_code, error_config)} mime_type, encoding = mimetypes.guess_type(error_path, strict=False) if mime_type: error_config.setdefault('headers', {}).setdefault('Content-Type', mime_type) else: app_log.error('url.%s.error.%d must have a path or function key', cls.name, error_code) # Add the error configuration for reference if error_code in cls.error: cls.error[error_code]['conf'] = error_config cls._write_error, cls.write_error = cls.write_error, cls._write_custom_error
def get_app_config(appname, args): ''' Get the stored configuration for appname, and override it with args. ``.target`` defaults to $GRAMEXDATA/apps/<appname>. ''' apps_config['cmd'] = {appname: args} app_config = AttrDict((+apps_config).get(appname, {})) app_config.setdefault('target', str(app_dir / app_config.get('target', appname))) app_config.target = os.path.abspath(app_config.target) return app_config
def save_user_config(appname, value): user_config = AttrDict() if user_conf_file.exists(): with user_conf_file.open(encoding='utf-8') as handle: user_config = yaml.safe_load(handle) if value is None: if appname in user_config: del user_config[appname] else: app_config = user_config.setdefault(appname, AttrDict()) app_config.update({key: value[key] for key in app_keys if key in value}) with user_conf_file.open(mode='w', encoding='utf-8') as handle: yaml.safe_dump(user_config, handle, indent=4, default_flow_style=False)