def lookup_row(self, request, node, value): if isinstance(node.typ, Sequence): row = [] value_length = len(value) for i in range(self.sequence_count[node.name]): if i >= value_length: child_value = None else: child_value = value[i] for child in node.children[0].children: if child_value is None: row.extend(self.lookup_row(request, child, None)) elif isinstance(value, dict): row.extend(self.lookup_row(request, child, child_value.get(camelcase(node.name)))) else: row.extend(self.lookup_row(request, child, getattr(child_value, child.name, None))) return row elif isinstance(node.typ, Mapping): row = [] for child in node.children: if isinstance(value, dict): row.extend(self.lookup_row(request, child, value.get(camelcase(node.name)))) else: row.extend(self.lookup_row(request, child, getattr(value, child.name, None))) return row else: if value is not None and hasattr(node, 'value_decoder'): value = node.value_decoder(request, value) return [value]
def get_route_info(self, request, route_name): intr_route = request.registry.introspector.get("routes", route_name) if intr_route is not None: route = intr_route["object"] params = dict((k, "{{%s}}" % camelcase(k)) for k in lookup_for_route_params(route)) url = "%s%s" % (request.application_url, unquote(route.generate(params))) return intr_route, url, params.keys()
def get_route_info(self, request, route_name): intr_route = request.registry.introspector.get('routes', route_name) if intr_route is not None: route = intr_route['object'] params = {k: '{{%s}}' % camelcase(k) for k in lookup_for_route_params(route)} url = '%s%s' % (request.application_url, unquote(route.generate(params))) return intr_route, url, params.keys()
def format_error_to_json_values(error, kwargs=None, request=None): if request: translate = translate_factory(request) else: translate = lambda tstring, **kw: tstring if isinstance(error, HTTPError): status = error.code key = camelcase(error.title) title = error.title message = error.explanation elif isinstance(error, Invalid): status = 400 key = camelcase(error._keyname()) title = _('Form error') message = error.msg errors = defaultdict(list) for path in error.paths(): for exc in path: key = str(exc.node.name) if exc.positional and exc.pos: # Ignore 0 position key += '.' + str(exc.pos) if key and exc.msg: key = camelcase(key) for message in exc.messages(): errors[key].append(translate(message)) if not kwargs: kwargs = {} kwargs['errors'] = errors else: status = getattr(error, 'code', 400) key = camelcase(getattr(error, 'key', 'undefined')) title = getattr(error, 'title', None) message = getattr(error, 'msg', getattr(error, 'message', 'Undefined')) values = { 'status': status, 'property': key, 'title': title and translate(title) or None, 'message': translate(message)} if kwargs: values.update(kwargs) return values
def format_error_to_json_values(error, kwargs=None, request=None): if request: translate = translate_factory(request) else: translate = lambda tstring, **kw: tstring if isinstance(error, HTTPError): status = error.code key = camelcase(error.title) message = error.explanation elif isinstance(error, Invalid): status = 400 key = camelcase(error._keyname()) message = error.msg errors = MissingList() for path in error.paths(): for exc in path: key = str(exc.node.name) if exc.positional and exc.pos: # Ignore 0 position key += '.' + str(exc.pos) if key and exc.msg: key = camelcase(key) for message in exc.messages(): errors[key].append(translate(message)) if not kwargs: kwargs = {} kwargs['errors'] = errors else: status = getattr(error, 'code', 400) key = camelcase(getattr(error, 'key', 'undefined')) message = getattr(error, 'msg', getattr(error, 'message', u'Undefined')) values = { 'status': status, 'property': key, 'message': translate(message)} if kwargs: values.update(kwargs) return values
def encode_key(self, key): return camelcase(key)
def __call__(self, context, request): requests = [] folders = MissingList() folders_descriptions = {} config = request.registry.config for schema_view in request.registry.getAllUtilitiesRegisteredFor(ISchemaView): # Make route for url schema_route = request.registry.introspector.get('routes', schema_view.route_name) if schema_route is not None: # Schema permission headers = set() permissions = lookup_for_route_permissions(request.registry, schema_route) method_permissions = maybe_list(permissions.get('GET')) for method_permission in method_permissions: if method_permission not in (Everyone, NotAuthenticated): headers.add('Authorization: Token {{token}}') break request_id = self.new_unique_id() requests.append({ 'id': request_id, 'headers': '\n'.join(headers), 'url': request.route_url(schema_view.route_name), 'preRequestScript': '', 'pathVariables': {}, 'method': u'GET', 'data': [], 'dataMode': 'params', 'version': 2, 'tests': '', 'currentHelper': 'normal', 'helperAttributes': {}, 'time': self.collection_time, 'name': u'Schema: %s' % schema_view.title, 'description': schema_view.description or '', 'collectionId': self.collection_id, 'responses': [], 'owner': 0, 'synced': False}) folders[schema_view.title].append(request_id) folders_descriptions[schema_view.title] = schema_view.description for route_name, request_methods in schema_view.routes_names.items(): # Make route for url intr_route = request.registry.introspector.get('routes', route_name) if intr_route is None: continue route = intr_route['object'] permissions = lookup_for_route_permissions(request.registry, intr_route) params = dict((k, '{{%s}}' % camelcase(k)) for k in lookup_for_route_params(route)) url = '%s%s' % (request.application_url, unquote(route.generate(params))) schemas_by_methods = MissingList() for schema in config.lookup_input_schema(route_name, request_methods): for request_method in maybe_list(schema.request_method) or DEFAULT_METHODS: schemas_by_methods[request_method].append(schema) for schema in config.lookup_output_schema(route_name, request_methods): for request_method in maybe_list(schema.request_method) or DEFAULT_METHODS: schemas_by_methods[request_method].append(schema) for request_method, schemas in schemas_by_methods.items(): title = None description = None schema_data = [] tests = [] for schema in schemas: if schema.schema_type == 'request': if schema.schema: schema_data.extend( self.construct_data(request_method, schema.schema)) if schema.fields_schema: schema_data.extend( self.construct_data(request_method, schema.fields_schema)) if schema.schema and not title: title = schema.schema.title if schema.schema and not description: description = schema.schema.description variables = getattr(schema.schema, 'postman_environment_variables', None) if variables: for environment_key, response_key in variables.items(): environment_key = camelcase(environment_key) response_key = camelcase(response_key) tests.append( 'if (answer.%s){ postman.setEnvironmentVariable("%s", answer.%s); }' % (response_key, environment_key, response_key)) if tests: tests.insert(0, 'var answer = JSON.parse(responseBody);') # Input params method_url = url request_schema_data = [] request_method = request_method.upper() if request_method == 'GET': queries = [] for url_param in schema_data: if url_param['value']: queries.append( '%s=%s' % (quote(url_param['key']), quote(url_param['value']))) else: queries.append(quote(url_param['key'])) if queries: method_url = '%s?%s' % (method_url, '&'.join(queries)) else: request_schema_data = schema_data # Method permission headers = set() method_permissions = maybe_list(permissions.get(request_method)) for method_permission in method_permissions: if method_permission not in (Everyone, NotAuthenticated): headers.add('Authorization: Token {{token}}') break if not title: title = route_name.replace('_', ' ').title() request_id = self.new_unique_id() requests.append({ 'id': request_id, 'headers': '\n'.join(headers), 'url': method_url, 'preRequestScript': '', 'pathVariables': {}, 'method': request_method, 'data': request_schema_data, 'dataMode': 'params', 'version': 2, 'tests': '\n'.join(tests), 'currentHelper': 'normal', 'helperAttributes': {}, 'time': self.collection_time, 'name': title, 'description': description or '', 'collectionId': self.collection_id, 'responses': [], 'owner': 0, 'synced': False}) folders[schema_view.title].append(request_id) response_folders = [] for key, requests_ids in folders.items(): response_folders.append({ 'id': self.new_unique_id(), 'name': key, 'description': folders_descriptions.get(key) or '', 'order': requests_ids, 'collection_name': self.title, 'collection_id': self.collection_id, 'collection_owner': '', 'write': True}) return { 'id': self.collection_id, 'name': self.title, 'description': self.description or '', 'timestamp': self.collection_time, 'synced': False, 'owner': '', 'subscribed': False, 'remoteLink': '', 'public': False, 'write': True, 'order': [], 'folders': response_folders, 'requests': requests}
def encode_key(self, key): return camelcase(key) if self.auto_camelcase else key
def __call__(self, context, request): nodes = MissingDict() requested_methods = [key.lower() for key in request.GET.keys()] types = MissingList() models = MissingList() for route_name, request_methods in self.routes_names.items(): route_methods = [] for request_method in maybe_list(request_methods or DEFAULT_METHODS): if not requested_methods or request_method.lower( ) in requested_methods: route_methods.append(request_method) if not route_methods: continue intr_route = request.registry.introspector.get( 'routes', route_name) if intr_route is None: continue route = intr_route['object'] params = dict((k, '{{%s}}' % camelcase(k)) for k in lookup_for_route_params(route)) url = '%s%s' % (request.application_url, unquote(route.generate(params))) schemas = request.registry.config.lookup_input_schema( route_name, route_methods) schemas.extend( request.registry.config.lookup_output_schema( route_name, route_methods)) for schema in schemas: fields = [] if schema.schema: details = self.construct_structure(request, schema.schema, schema.schema_type, types, models) if isinstance(details, dict): fields.append(details) else: fields.extend(details) if schema.schema_type == 'request' and schema.fields_schema: details = self.construct_structure(request, schema.fields_schema, schema.schema_type, types, models) if isinstance(details, dict): fields.append(details) else: fields.extend(details) name = camelcase('%s_%s' % (schema.request_method, schema.route_name)) nodes[name][schema.schema_type] = fields nodes[name]['method'] = schema.request_method.upper() nodes[name]['url'] = url nodes['fieldTypes'] = lookup_for_common_fields(types, ignore_key='fieldType') nodes['models'] = lookup_for_common_fields(models, ignore_key='model') return nodes
def construct_data(self, request_method, schema, keep_parent_name=None): response = [] if isinstance(schema.typ, Sequence): child = schema.children[0] response.extend(self.construct_data( request_method, child, keep_parent_name=schema.name)) return response elif isinstance(schema.typ, Tuple): for child in schema.children: response.extend( self.construct_data( request_method, child, keep_parent_name=schema.name)) return response elif isinstance(schema.typ, Mapping): for child in schema.children: response.extend( self.construct_data( request_method, child)) return response else: if hasattr(schema.typ, 'typ'): return self.construct_data( request_method, schema.typ, keep_parent_name=keep_parent_name) default = schema.serialize() if default is null: default = '' if schema.missing not in (drop, required, null): default = schema.missing if hasattr(schema, 'postman_default'): default = schema.postman_default if default == '' and schema.missing is required and request_method.upper() == 'POST': if not schema.validator: if isinstance(schema.typ, String): default = '%s {{$randomInt}}' % schema.name.replace('_', ' ').title() elif isinstance(schema.typ, Boolean): default = 'true' elif isinstance(schema.typ, Date): default = TODAY_DATE() elif isinstance(schema.typ, DateTime): default = NOW_DATE() else: validators = schema.validator if not is_nonstr_iter(validators): validators = [validators] for validator in validators: if isinstance(validator, OneOf): default = validator.choices[0] break if default is None: default = '' response.append({ 'key': camelcase(keep_parent_name or schema.name), 'value': str(default), 'type': 'text', 'enabled': schema.required}) return response
def construct_structure(self, request, schema, schema_type, types, models, parent_name=None): if isinstance(schema.typ, Sequence): child = schema.children[0] if not schema.name: schema = child name = camelcase(schema.name) details = { 'model': name, 'type': 'sequence', 'title': schema.title, 'description': schema.description or None } models[name].append(details) # Find and add child child_details = self.construct_structure(request, child, schema_type, types, models, parent_name=schema.name) if isinstance(details, dict): if isinstance(child.typ, Mapping): details['type'] = 'model' details.update(child_details) else: details['fields'] = [child_details] else: details['fields'] = child_details return details elif isinstance(schema.typ, Tuple): raise NotImplementedError('Tuple type need to be implemented') elif isinstance(schema.typ, Mapping): fields = [] for child in schema.children: fields.append( self.construct_structure(request, child, schema_type, types, models, parent_name=schema.name)) name = schema.name or parent_name if not name: return fields name = camelcase(name) details = { 'type': 'model', 'title': schema.title, 'description': schema.description or None, 'fields': fields, 'model': name } models[name].append(details) return details else: name = camelcase(schema.name) details = { 'fieldType': name, 'title': schema.title, 'description': schema.description or None } types[name].append(details) if isinstance(schema.typ, FilterByType): for cls in schema.typ.__class__.__mro__[1:]: if cls is not FilterByType: details['type'] = str(cls.__name__).lower() break details['filter'] = True else: details['type'] = get_colander_type_name(schema.typ) request_validation = [] if schema.validator: if isinstance(schema.validator, All): validators = schema.validator.validators elif not is_nonstr_iter(schema.validator): validators = [schema.validator] for validator in validators: if isinstance(validator, OneOfWithDescription): details['options'] = [] for choice, description in validator.choices_with_descripton: details['options'].append({ 'value': choice, 'text': request.translate(description) }) elif isinstance(validator, OneOf): details['options'] = [] for choice in validator.choices: choice_description = force_unicode(choice).replace( u'_', u' ').title() details['options'].append({ 'value': choice, 'text': choice_description }) else: if isinstance(validator, Length): validation_option = {} if validator.min is not None: validation_option['min'] = validator.min if validator.max is not None: validation_option['max'] = validator.max else: validation_option = True request_validation.append( (validator, validation_option)) if hasattr(schema, 'use_when'): details['useWhen'] = dict( (camelcase(k), v) for k, v in schema.use_when.items()) if schema_type == 'request': validation = {} if schema.required: validation['required'] = True if request_validation: for validator, validation_option in request_validation: validation[get_colander_type_name( validator)] = validation_option if validation: details['validation'] = validation default = schema.missing else: if schema.missing is drop: details['maybeNotSent'] = True default = schema.default if (default is not drop and default is not required and default is not null): if isinstance(schema.typ, Number): default = schema.typ.num(default) elif isinstance(schema.typ, BaseBoolean): default = asbool(default) details['default'] = default return details
def get_colander_type_name(node): return camelcase(str(node.__class__.__name__).lower())
def _render(value, system): request = system.get('request') if request is not None: response = request.response ct = response.content_type if ct == response.default_content_type: response.content_type = 'text/csv' output = request.registry.config.lookup_output_schema( request.matched_route.name, request_method=request.method) if output: output = output[0] node = output.schema.children[0] value_lines = [] header = [] value_lines.append(header) for child in node.children: header.append(child.title) for item_value in value: row = [] value_lines.append(row) if isinstance(item_value, dict): for child in node.children: row.append( item_value.get(camelcase(child.name))) else: for child in node.children: row.append( getattr(item_value, child.name, None)) value = value_lines separator = u';' separator_replace = u',' line_break = u'\n' line_break_replace = u' ' lines = [] for value_items in value: row = [] for item in value_items: if item is None: item = u'' elif isinstance(item, bool): if item: item = u'true' else: item = u'false' elif isinstance(item, (int, basestring, long)): item = force_unicode(item) elif isinstance(item, (DATE, DATETIME)): item = item.isoformat() else: item = dumps(item) print item if u'"' in item: item = u'"%s"' % item.replace(u'"', u'\\"') item = item.replace(separator, separator_replace) item = item.replace(line_break, line_break_replace) row.append(item) lines.append(separator.join(row)) return line_break.join(lines)
def _render(value, system): request = system.get('request') output_schema = None if isinstance(value, dict): output_schema = value['schema'] value = value['value'] delimiter = ';' quote_char = '"' line_terminator = '\r\n' quoting = QUOTE_ALL encoder = None if request is not None: response = request.response ct = response.content_type if ct == response.default_content_type: response.content_type = 'text/csv' output = request.registry.config.lookup_output_schema( request.matched_route.name, request_method=request.method) if output: output_schema = output[0].schema if output_schema: value = self.lookup_rows(request, output_schema.children[0], value) output_filename = getattr(output_schema, 'filename', None) if output_filename: if callable(output_filename): output_filename = output_filename() response.content_disposition = 'attachment; filename="%s"' % output_filename _get_param = request.params.get get_param = lambda k: _get_param(k) or _get_param(camelcase(k)) csv_delimiter = get_param('csv_delimiter') if csv_delimiter: delimiter = to_string(csv_delimiter) if delimiter == '\\t': delimiter = '\t' else: delimiter = delimiter[0] csv_quote_char = get_param('csv_quote_char') if csv_quote_char: quote_char = to_string(csv_quote_char) csv_line_terminator = get_param('csv_line_terminator') if csv_line_terminator: if csv_line_terminator == '\\n\\r': line_terminator = '\n\r' elif csv_line_terminator == '\\n': line_terminator = '\n' elif csv_line_terminator == '\\r': line_terminator = '\r' csv_encoding = get_param('csv_encoding') if csv_encoding: try: encoder = codecs.lookup(csv_encoding) except LookupError: raise Error('csv_encoding', _('Invalid CSV encoding')) else: if encoder.name != 'utf-8': request.response.charset = encoder.name yes_text = request.translate(_('Yes')) no_text = request.translate(_('No')) csv_quoting = get_param('csv_quoting') if csv_quoting: csv_quoting = to_string(csv_quoting).lower() if csv_quoting == 'minimal': quoting = QUOTE_MINIMAL elif csv_quoting == 'non_numeric': quoting = QUOTE_NONNUMERIC elif csv_quoting == 'none': quoting = QUOTE_NONE else: yes_text = 'Yes' no_text = 'No' if not value: return '' f = StringIO() csvfile = csv_writer( f, delimiter=delimiter, quotechar=quote_char, lineterminator=line_terminator, quoting=quoting) for value_items in value: row = [] for item in value_items: if item is None: item = '' elif not isinstance(item, str): if isinstance(item, bool): item = item and yes_text or no_text elif isinstance(item, (float, int)): item = str(item) elif isinstance(item, (DATE, DATETIME)): item = item.isoformat() elif not isinstance(item, str): item = to_string(item) row.append(item) csvfile.writerow(row) f.seek(0) response = f.read() f.close() if encoder: response = encoder.decode(encoder.encode(response)[0])[0] else: response = to_string(response) return response
def get_schema_nodes(self, request): cache_key = 'schema build cache %s' % self.schema_route_name schema_expire_cache = request.settings.get('schema_expire_cache', MARKER) nodes = request.cache.get(cache_key, MARKER, expire=schema_expire_cache) if nodes is MARKER: nodes = defaultdict(dict) global_types = defaultdict(list) global_models = defaultdict(list) keep_types_keys = defaultdict(set) keep_models_keys = defaultdict(set) to_translate = defaultdict(list) for route_name in self.get_route_names(): info = self.get_route_info(request, route_name) if not info: continue intr_route, url, url_keys = info url_keys = [camelcase(k) for k in url_keys] schemas = request.registry.config.lookup_input_schema(route_name, self.request_methods) schemas.extend(request.registry.config.lookup_output_schema(route_name, self.request_methods)) for schema in schemas: fields = [] types = defaultdict(list) models = defaultdict(list) if schema.schema: details = self.construct_structure( request, schema.schema, schema.schema_type, types, models, to_translate) if isinstance(details, dict): fields.append(details) else: fields.extend(details) if schema.schema_type == 'request' and schema.fields_schema: details = self.construct_structure( request, schema.fields_schema, schema.schema_type, types, models, to_translate) if isinstance(details, dict): fields.append(details) else: fields.extend(details) if schema.route_name != self.csv_route_name: key = schema.request_method.lower() if key == 'get' and schema.route_name == self.list_route_name: key = 'list' else: key = 'csv' nodes[key][schema.schema_type] = fields nodes[key]['routeName'] = route_name nodes[key]['method'] = schema.request_method.upper() nodes[key]['url'] = url nodes[key]['urlKeys'] = url_keys nodes[key]['renderer'] = schema.renderer.lower() if types: keep_types_keys[key].update(types.keys()) for k, values in types.items(): global_types[k].extend(values) if models: keep_models_keys[key].update(models.keys()) for k, values in models.items(): global_models[k].extend(values) if global_types: if to_translate: to_translate['fieldTypes'] = defaultdict(set) nodes['fieldTypes'] = lookup_common_fields( global_types, to_translate, ignore_key='fieldType', is_field_type=True) nodes['keep_types_keys'] = keep_types_keys if global_models: if to_translate: to_translate['models'] = defaultdict(set) nodes['models'] = lookup_common_fields(global_models, to_translate, ignore_key='model') nodes['keep_models_keys'] = keep_models_keys if to_translate: nodes['to_translate'] = to_translate request.cache.put(cache_key, nodes, expire=schema_expire_cache) permissions_cache = {} types_keys = set() types = nodes.pop('fieldTypes', None) keep_types_keys = nodes.pop('keep_types_keys', None) models_keys = set() models = nodes.pop('models', None) keep_models_keys = nodes.pop('keep_models_keys', None) to_translate = nodes.pop('to_translate', None) fields_translation = {} models_translation = {} if to_translate: translator = request.translator fields_translation = to_translate.pop('fieldTypes', fields_translation) models_translation = to_translate.pop('models', fields_translation) for key, details in nodes.items(): route_name = details['routeName'] if route_name not in permissions_cache: info = self.get_route_info(request, route_name) permissions_cache[route_name] = lookup_for_route_permissions(request.registry, info[0]) method_permissions = maybe_list(permissions_cache[route_name].get(details['method'])) if not self.validate_permission(request, method_permissions): nodes.pop(key) continue if keep_types_keys: types_keys.update(keep_types_keys[key]) if keep_models_keys: models_keys.update(keep_models_keys[key]) if types_keys: nodes['fieldTypes'] = {} for k in types_keys: nodes['fieldTypes'][k] = details = types[k] field_fields = fields_translation.get(k) if field_fields: for field in field_fields: if field == 'options': for option in details[field]: if option['text']: option['text'] = translator(option['text']) else: details[field] = translator(details[field]) if models_keys: nodes['models'] = {} for k in models_keys: nodes['models'][k] = details = models[k] model_fields = models_translation.get(k) if model_fields: for field in model_fields: if field == 'options': for option in details[field]: if option['text']: option['text'] = translator(option['text']) else: details[field] = translator(details[field]) if to_translate: for key, values in to_translate.items(): for value in values: text_value = value.get(key) if text_value: value[key] = translator(text_value) print(text_value, value[key]) return nodes
def get_colander_type_name(node): if hasattr(node, 'schema_type_name'): return node.schema_type_name else: return camelcase(str(node.__class__.__name__).lower())
def construct_structure(self, request, schema, schema_type, types, models, to_translate, parent_name=None): if isinstance(schema.typ, Sequence): child = schema.children[0] if not schema.name: schema = child name = camelcase(schema.name) details = { 'model': name, 'type': 'sequence', 'title': schema.title, 'description': schema.description or ''} models[name].append(details) if isinstance(schema.title, TranslationString): to_translate['title'].append(details) if isinstance(schema.description, TranslationString): to_translate['description'].append(details) # Find and add child child_details = self.construct_structure( request, child, schema_type, types, models, to_translate, parent_name=schema.name) if isinstance(details, dict): if isinstance(child.typ, Mapping): details['type'] = 'model' details.update(child_details) else: details['fields'] = [child_details] else: details['fields'] = child_details return details elif isinstance(schema.typ, Tuple): raise NotImplementedError('Tuple type need to be implemented') elif isinstance(schema.typ, Mapping): fields = [] for child in schema.children: fields.append(self.construct_structure( request, child, schema_type, types, models, to_translate, parent_name=schema.name)) name = schema.name or parent_name if not name: return fields name = camelcase(name) details = { 'type': 'model', 'title': schema.title, 'description': schema.description or '', 'fields': fields, 'model': name} models[name].append(details) if isinstance(schema.title, TranslationString): to_translate['title'].append(details) if isinstance(schema.description, TranslationString): to_translate['description'].append(details) return details else: name = camelcase(schema.name) details = { 'fieldType': name, 'title': schema.title, 'description': schema.description or ''} if isinstance(schema.title, TranslationString): to_translate['title'].append(details) if isinstance(schema.description, TranslationString): to_translate['description'].append(details) if hasattr(schema, 'model_reference'): model = schema.model_reference['model'] model_key = schema.model_reference.get('key') or 'key' model_query = schema.model_reference.get('query') or 'name' model_application = schema.model_reference.get('application_name') or request.application_name details['modelReference'] = { 'applicationName': model_application, 'schemaName': schema.model_reference['schema'], 'key': camelcase(model[model_key].name), 'model': camelcase(model.name), 'queryField': camelcase(model[model_query].name)} types[name].append(details) if isinstance(schema.typ, FilterByType): for cls in schema.typ.__class__.__mro__[1:]: if cls is not FilterByType: details['type'] = str(cls.__name__).lower() break details['filter'] = True elif hasattr(schema, 'schema_type_name'): details['type'] = camelcase(schema.schema_type_name) else: details['type'] = get_colander_type_name(schema.typ) request_validation = [] if schema.validator: if isinstance(schema.validator, All): validators = schema.validator.validators elif not is_nonstr_iter(schema.validator): validators = [schema.validator] else: validators = schema.validator for validator in validators: if isinstance(validator, OneOfWithDescription): details['options'] = [] add_option = details['options'].append save_to_translate = False for choice, description in validator.choices_with_descripton: add_option({'value': choice, 'text': description}) save_to_translate = save_to_translate or isinstance(description, TranslationString) if save_to_translate: to_translate['options'].append(details) elif isinstance(validator, OneOf): details['options'] = [] add_option = details['options'].append for choice in validator.choices: add_option({ 'value': choice, 'text': choice.replace('_', ' ').title()}) else: if isinstance(validator, Length): validation_option = {} if validator.min is not None: validation_option['min'] = validator.min if validator.max is not None: validation_option['max'] = validator.max else: validation_option = True request_validation.append((validator, validation_option)) if hasattr(schema, 'use_when'): details['useWhen'] = {camelcase(k): v for k, v in schema.use_when.items()} if schema_type == 'request': validation = {} if schema.required: validation['required'] = True if request_validation: for validator, validation_option in request_validation: validation[get_colander_type_name(validator)] = validation_option if validation: details['validation'] = validation default = schema.missing else: if schema.missing is drop: details['maybeNotSent'] = True default = schema.default if (default is not drop and default is not required and default is not null): if isinstance(schema.typ, Number): default = schema.typ.num(default) elif isinstance(schema.typ, BaseBoolean): default = asbool(default) details['default'] = default return details
def construct_structure(self, request, schema, schema_type, types, models, to_translate, parent_name=None): if isinstance(schema.typ, Sequence): child = schema.children[0] if not schema.name: schema = child name = camelcase(schema.name) details = { "model": name, "type": "sequence", "title": schema.title, "description": schema.description or EMPTY_STRING, } models[name].append(details) if isinstance(schema.title, TranslationString): to_translate["title"].append(details) if isinstance(schema.description, TranslationString): to_translate["description"].append(details) # Find and add child child_details = self.construct_structure( request, child, schema_type, types, models, to_translate, parent_name=schema.name ) if isinstance(details, dict): if isinstance(child.typ, Mapping): details["type"] = "model" details.update(child_details) else: details["fields"] = [child_details] else: details["fields"] = child_details return details elif isinstance(schema.typ, Tuple): raise NotImplementedError("Tuple type need to be implemented") elif isinstance(schema.typ, Mapping): fields = [] for child in schema.children: fields.append( self.construct_structure( request, child, schema_type, types, models, to_translate, parent_name=schema.name ) ) name = schema.name or parent_name if not name: return fields name = camelcase(name) details = { "type": "model", "title": schema.title, "description": schema.description or EMPTY_STRING, "fields": fields, "model": name, } models[name].append(details) if isinstance(schema.title, TranslationString): to_translate["title"].append(details) if isinstance(schema.description, TranslationString): to_translate["description"].append(details) return details else: name = camelcase(schema.name) details = {"fieldType": name, "title": schema.title, "description": schema.description or EMPTY_STRING} if isinstance(schema.title, TranslationString): to_translate["title"].append(details) if isinstance(schema.description, TranslationString): to_translate["description"].append(details) if hasattr(schema, "model_reference"): model = schema.model_reference["model"] model_key = schema.model_reference.get("key") or "key" model_query = schema.model_reference.get("query") or "name" model_application = schema.model_reference.get("application_name") or request.application_name details["modelReference"] = { "applicationName": model_application, "schemaName": schema.model_reference["schema"], "key": camelcase(model[model_key].name), "model": camelcase(model.name), "queryField": camelcase(model[model_query].name), } types[name].append(details) if isinstance(schema.typ, FilterByType): for cls in schema.typ.__class__.__mro__[1:]: if cls is not FilterByType: details["type"] = str(cls.__name__).lower() break details["filter"] = True elif hasattr(schema, "schema_type_name"): details["type"] = camelcase(schema.schema_type_name) else: details["type"] = get_colander_type_name(schema.typ) request_validation = [] if schema.validator: if isinstance(schema.validator, All): validators = schema.validator.validators elif not is_nonstr_iter(schema.validator): validators = [schema.validator] else: validators = schema.validator for validator in validators: if isinstance(validator, OneOfWithDescription): details["options"] = [] add_option = details["options"].append save_to_translate = False for choice, description in validator.choices_with_descripton: add_option({"value": choice, "text": description}) save_to_translate = save_to_translate or isinstance(description, TranslationString) if save_to_translate: to_translate["options"].append(details) elif isinstance(validator, OneOf): details["options"] = [] add_option = details["options"].append for choice in validator.choices: add_option({"value": choice, "text": to_unicode(choice).replace(UNDERSCORE, SPACE).title()}) else: if isinstance(validator, Length): validation_option = {} if validator.min is not None: validation_option["min"] = validator.min if validator.max is not None: validation_option["max"] = validator.max else: validation_option = True request_validation.append((validator, validation_option)) if hasattr(schema, "use_when"): details["useWhen"] = dict((camelcase(k), v) for k, v in schema.use_when.items()) if schema_type == "request": validation = {} if schema.required: validation["required"] = True if request_validation: for validator, validation_option in request_validation: validation[get_colander_type_name(validator)] = validation_option if validation: details["validation"] = validation default = schema.missing else: if schema.missing is drop: details["maybeNotSent"] = True default = schema.default if default is not drop and default is not required and default is not null: if isinstance(schema.typ, Number): default = schema.typ.num(default) elif isinstance(schema.typ, BaseBoolean): default = asbool(default) details["default"] = default return details
def _render(value, system): request = system.get('request') if request is not None: response = request.response ct = response.content_type if ct == response.default_content_type: response.content_type = 'text/csv' output = request.registry.config.lookup_output_schema( request.matched_route.name, request_method=request.method) if output: output = output[0] node = output.schema.children[0] value_lines = [] header = [] value_lines.append(header) for child in node.children: header.append(child.title) for item_value in value: row = [] value_lines.append(row) if isinstance(item_value, dict): for child in node.children: row.append(item_value.get(camelcase(child.name))) else: for child in node.children: row.append(getattr(item_value, child.name, None)) value = value_lines separator = u';' separator_replace = u',' line_break = u'\n' line_break_replace = u' ' lines = [] for value_items in value: row = [] for item in value_items: if item is None: item = u'' elif isinstance(item, bool): if item: item = u'true' else: item = u'false' elif isinstance(item, (int, basestring, long)): item = force_unicode(item) elif isinstance(item, (DATE, DATETIME)): item = item.isoformat() else: item = dumps(item) print item if u'"' in item: item = u'"%s"' % item.replace(u'"', u'\\"') item = item.replace(separator, separator_replace) item = item.replace(line_break, line_break_replace) row.append(item) lines.append(separator.join(row)) return line_break.join(lines)