Exemple #1
0
    def route_url(self, route_name, *elements, **kw):
        """ See: pyramid.URLMethodsMixin.route_url
        """

        mapper = self.registry.getUtility(IRoutesMapper)
        route = mapper.get_route(route_name)

        if route is None:
            raise KeyError('No such route named %s' % route_name)

        if route.pregenerator is not None:
            elements, kw = route.pregenerator(self, elements, kw)

        app_url, scheme, host, port, qs, anchor = parse_url_overrides(kw)

        if app_url is None:
            if scheme is not None or host is not None or port is not None:
                app_url = self._partial_application_url(scheme, host, port)
            else:
                app_url = self.request.host_url
                application_path_url = (self.config.settings.get('application_path_url') or '').strip('/')
                if application_path_url:
                    app_url = string_join('/', (app_url.strip('/'), application_path_url))

        path = route.generate(kw)  # raises KeyError if generate fails

        if elements:
            suffix = _join_elements(elements)
            if not path.endswith('/'):
                suffix = '/' + suffix
        else:
            suffix = ''

        return app_url + path + suffix + qs + anchor
Exemple #2
0
def construct_sequence_items(name, values):
    maybe_deep_name = name + '.'
    result_sequence = defaultdict(dict)
    for key, value in values.items():
        if not value:
            continue

        if key == name:
            key_first = ''
        elif key.startswith(maybe_deep_name):
            key_first = key.split(maybe_deep_name, 1)[1]
        else:
            continue

        value = maybe_list(value)
        if '.' in key_first:
            maybe_number, key_second = key_first.split('.', 1)
            maybe_number = maybe_integer(maybe_number)
            if maybe_number is not None:
                key = string_join('.', [name, key_second])
                result_sequence[maybe_number][key] = value[0]
                continue

        elif key_first:
            maybe_number = maybe_integer(key_first)
            if maybe_number is not None:
                result_sequence[maybe_number][name] = value[0]
                continue

        for i, key_value in enumerate(value):
            result_sequence[i][key] = key_value

    return [v for i, v in sorted(result_sequence.items())]
Exemple #3
0
    def __call__(self, environ, start_response):
        content_type = get_content_type(environ.get('CONTENT_TYPE'))
        if content_type == 'application/json' and 'wsgi.input' in environ:
            body = environ['wsgi.input'].read()
            if body:
                arguments = []
                body = to_string(body)
                try:
                    body_json = loads(body)
                    for key, values in dict(body_json).items():
                        key = to_string(key)
                        values = maybe_list(values)
                        for value in values:
                            if value is None:
                                arguments.append('%s=' % key)
                            else:
                                arguments.append('%s=%s' % (key, quote(dump_query_value(value))))
                    body = string_join('&', arguments)
                except (ValueError, UnicodeEncodeError):
                    headers = [('Content-type', 'application/json')]
                    error = HTTPInvalidJSONPayload()
                    start_response(error.status, headers)
                    return format_error_response_to_json(error)

            environ_add_POST(environ, body or '')

        return self.application(environ, start_response)
Exemple #4
0
    def __call__(self, environ, start_response):
        try:
            for chunk in self.application(environ, start_response):
                yield chunk
        except (BaseException, Exception) as error:
            # Save / log error
            request = make_request(self.config, environ)

            try:
                small_message = '%s: %s' % (error.__class__.__name__, to_string(error))
            except (BaseException, Exception):
                small_message = error

            print_message = True
            if request.api is not None:
                api_manager = self.settings.get('api_manager')
                if api_manager is not None:
                    logging_api_name = api_manager.__api_name__
                else:
                    logging_api_name = 'logging'

                try:
                    getattr(request.api, logging_api_name).log_critical(
                        'internal_server_error',
                        str(small_message))
                except (BaseException, Exception):
                    pass
                else:
                    print_message = False

            if print_message:
                print_(string_join('', format_exception(*sys.exc_info())))

            if isinstance(request.registry.config, APIConfigurator):
                headers = [('Content-type', 'application/json')]
                internal_server_error = HTTPInternalServerError()
                start_response(internal_server_error.status, headers)
                response = format_error_response_to_json(internal_server_error, request=request)
                yield response
            else:
                return_default = False
                error_view = self.config.settings.get('errors.interface.global_error_view')
                if error_view is None:
                    return_default = True
                else:
                    try:
                        response = error_view(error, request)
                    except Exception:
                        return_default = True
                    else:
                        start_response(response.status, response.headerlist)
                        yield response.body

                if return_default:
                    internal_server_error = HTTPInternalServerError()
                    for response in internal_server_error(environ, start_response):
                        yield response
Exemple #5
0
def parse_request_type(content_type):
    if content_type is None:
        return 'text/plain'

    content_type = to_string(content_type)
    if ';' in content_type:
        content_type = content_type.split(';', 1)[0]

    return string_join('/', (c.strip().lower() for c in content_type.split('/')))
Exemple #6
0
        def wrapper(context, request):
            context.output_schema = self.schema

            # Define allowed fields
            context.allowed_fields = self.allowed_fields

            # Look and validate requested fields
            include_fields = getattr(context, 'include_fields', None)
            if include_fields:
                context.output_fields = construct_allowed_fields(
                    self.allowed_fields,
                    include_fields)
            else:
                context.output_fields = deepcopy(self.allowed_fields)

            # Exclude fields
            exclude_fields = getattr(context, 'exclude_fields', None)
            if exclude_fields:
                for field in exclude_fields:
                    if '.' not in field:
                        context.output_fields.pop(field, None)
                    else:
                        field_blocks = field.split('.')
                        previous = context.output_fields
                        for field_block in field_blocks[:-1]:
                            previous = previous.get(field_block)
                            if not previous:
                                break
                        if previous:
                            previous.pop(field_blocks[-1])

            if not context.output_fields:
                keys = string_join('+', self.allowed_fields_to_set(self.allowed_fields))
                raise Error(keys, u('Please define some fields to export'))

            context.fields = deepcopy(context.output_fields)
            self.add_required_fields(context.fields, self.required_fields)

            result = wrapped(context, request)
            if getattr(self.schema, 'ignore_construct', False):
                return result
            else:
                return self.construct_structure(
                    self.schema,
                    result,
                    context.output_fields)
Exemple #7
0
    def log(self, code, message, level='INFO', extra=None):
        level = level.upper()
        header = ('-' * 30) + ' ' + level + ' ' + ('-' * 30)
        print_(header)

        arguments = [
            ('Application', self.request.application_name),
            ('Code', code),
            ('URL', self.request.url),
            ('Method', self.request.method),
            ('Date', NOW()),
            ('Language', self.request.locale_name),
            ('IP address', self.request.ip_address)]

        if extra:
            arguments.extend(extra.items())

        if self.request.authenticated:
            arguments.extend([
                ('Session type', self.request.authenticated.session_type),
                ('Session id', self.request.authenticated.session_id)])
        else:
            arguments.append(('Session', 'Without autentication'))

        bigger = max(len(k) for k, v in arguments)
        for key, value in arguments:
            print_(key, ' ' * (bigger - len(key)), ':', to_unicode(value))

        if level == 'CRITICAL':
            sys_exc_info = sys.exc_info()  # type, value, traceback
            if sys_exc_info[2] is not None:
                print_()
                print_(string_join('', format_exception(*sys_exc_info)))

        print_()
        try:
            message = to_unicode(message)
            for line in message.split(linesep):
                print_('  %s' % line)
        except UnicodeEncodeError:
            pass

        print_('-' * len(header))
Exemple #8
0
    def make_wsgi_app(self, install_middlewares=True):
        # Find for possible configuration extensions
        self.lookup_extensions()

        # Scan all package routes
        self.scan(self.package_name, categories=['pyramid'])

        # Scan package jobs
        scan_jobs = False
        jobs_manager = None
        for name, extension in self.registry.getUtilitiesFor(IBaseSessionManager):
            if issubclass(extension.session, BaseMailerSession) and 'queue_path' in extension.settings:
                scan_jobs = True
            elif issubclass(extension.session, BaseJobsSession):
                scan_jobs = True
                jobs_manager = extension
            elif isinstance(extension, BaseJobsManager):
                jobs_manager = extension
        if scan_jobs:
            if jobs_manager is None:
                raise ValueError('Please define module for jobs.')
            self.scan(self.package_name, categories=['ines.jobs'], jobs_manager=jobs_manager)
            self.scan('ines', categories=['ines.jobs'], jobs_manager=jobs_manager)

        app = super(Configurator, self).make_wsgi_app()

        if install_middlewares:
            # Look for middlewares in API Sessions
            for name, extension in self.registry.getUtilitiesFor(IBaseSessionManager):
                if hasattr(extension, '__middlewares__'):
                    for extension_middleware in extension.__middlewares__:
                        self.install_middleware(
                            extension_middleware.name,
                            extension_middleware,
                            settings={'api_manager': extension})

            # Define middleware settings
            middlewares_settings = defaultdict(dict)
            for key, value in self.settings.items():
                if key.startswith('middleware.'):
                    maybe_name = key.split('middleware.', 1)[1]
                    if '.' in maybe_name:
                        parts = maybe_name.split('.')
                        setting_key = parts[-1]
                        name = string_join('.', parts[:-1])
                        middlewares_settings[name][setting_key] = value
                    else:
                        # Install settings middlewares
                        middleware_class = get_object_on_path(value)
                        self.install_middleware(maybe_name, middleware_class)

            # Install middlewares with reversed order. Lower position first
            if self.middlewares:
                middlewares = []
                for name, middleware, settings in self.middlewares:
                    middlewares_settings[name].update(settings)

                    default_position = getattr(middleware, 'position', DEFAULT_MIDDLEWARE_POSITION.get(name))
                    position = settings.get('position', default_position) or 0
                    middlewares.append((position, name, middleware))
                middlewares.sort(reverse=True)

                for position, name, middleware in middlewares:
                    app = middleware(self, app, **middlewares_settings[name])
                    app.name = name

        return app
Exemple #9
0
    def __call__(self, context, request):
        requests = []
        folders = defaultdict(list)
        folders_descriptions = {}
        config = request.registry.config
        authentication = request.registry.queryUtility(IAuthenticationPolicy)

        for schema_view in request.registry.getAllUtilitiesRegisteredFor(ISchemaView):
            # Make route for url
            intr_route = request.registry.introspector.get('routes', schema_view.schema_route_name)
            if intr_route is not None:
                headers = set()

                # Schema permission
                if authentication:
                    permissions = lookup_for_route_permissions(request.registry, intr_route)
                    method_permissions = maybe_list(permissions.get('GET'))
                    headers.update(self.get_authentication_headers(authentication, method_permissions))

                request_id = self.new_unique_id()
                requests.append({
                    'id': request_id,
                    'headers': string_join('\n', headers),
                    'url': request.route_url(schema_view.schema_route_name),
                    'preRequestScript': '',
                    'pathVariables': {},
                    'method': GET_STRING,
                    'data': [],
                    'dataMode': 'params',
                    'version': 2,
                    'tests': '',
                    'currentHelper': 'normal',
                    'helperAttributes': {},
                    'time': self.collection_time,
                    'name': SCHEMA_TITLE % schema_view.title,
                    'description': schema_view.description or '',
                    'collectionId': self.collection_id,
                    'responses': [],
                    'owner': 0,
                    'synced': False})
                folders[schema_view.postman_folder_name or schema_view.title].append(request_id)
                folders_descriptions[schema_view.title] = schema_view.description

            # Make route for url
            for route_name in schema_view.get_route_names():
                intr_route = request.registry.introspector.get('routes', route_name)
                if intr_route is None:
                    continue
                route = intr_route['object']

                if authentication:
                    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 = defaultdict(list)
                for schema in config.lookup_input_schema(route_name, schema_view.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, schema_view.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)))

                        first_key_for = getattr(schema.schema, 'postman_environment_set_first_key', None)
                        if first_key_for:
                            tests.append((
                                'if(answer){for(var k in answer){postman.setEnvironmentVariable("%s", k);break;}}'
                                % camelcase(first_key_for)))

                    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, string_join('&', queries))
                    else:
                        request_schema_data = schema_data

                    headers = set()

                    # Method permission
                    if authentication:
                        method_permissions = maybe_list(permissions.get(request_method))
                        headers.update(self.get_authentication_headers(authentication, method_permissions))

                    request_id = self.new_unique_id()
                    requests.append({
                        'id': request_id,
                        'headers': string_join('\n', headers),
                        'url': method_url,
                        'preRequestScript': '',
                        'pathVariables': {},
                        'method': request_method,
                        'data': request_schema_data,
                        'dataMode': 'params',
                        'version': 2,
                        'tests': string_join('\n', tests),
                        'currentHelper': 'normal',
                        'helperAttributes': {},
                        'time': self.collection_time,
                        'name': title or route_name.replace('_', ' ').title(),
                        'description': description or '',
                        'collectionId': self.collection_id,
                        'responses': [],
                        'owner': 0,
                        'synced': False})
                    folders[schema_view.postman_folder_name or 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}