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 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