Ejemplo n.º 1
0
async def __type_resolver(
    parent: Optional[Any],
    args: Dict[str, Any],
    ctx: Optional[Any],
    info: "ResolveInfo",
) -> "GraphQLType":
    """
    Callable to use to resolve the `__type` field.
    :param parent: default root value or field parent value
    :param args: computed arguments related to the resolved field
    :param ctx: context passed to the query execution
    :param info: information related to the execution and the resolved field
    :type parent: Optional[Any]
    :type args: Dict[str, Any]
    :type ctx: Optional[Any]
    :type info: ResolveInfo
    :return: the computed field value
    :rtype: GraphQLType
    """
    # pylint: disable=unused-argument
    if not info.schema.is_introspectable:
        raise TartifletteError("Introspection is disabled for this schema")

    info.is_introspection = True
    try:
        return info.schema.find_type(args["name"])
    except KeyError:
        pass
    return None
Ejemplo n.º 2
0
    def add_error(
        self,
        raw_exception: Union["TartifletteError", "MultipleException",
                             Exception],
        path: Optional[List[str]] = None,
        locations: Optional[List["Location"]] = None,
    ) -> None:
        """
        Adds the contents of an exception to the known execution errors.
        :param raw_exception: the raw exception to treat
        :param path: the path where the raw exception occurred
        :param locations: the locations linked to the raw exception
        :type raw_exception: Union[TartifletteError, MultipleException, Exception]
        :type path: Optional[List[str]]
        :param locations: Optional[List["Location"]]
        """
        exceptions = (raw_exception.exceptions if isinstance(
            raw_exception, MultipleException) else [raw_exception])

        for exception in exceptions:
            graphql_error = (
                exception
                if is_coercible_exception(exception) else TartifletteError(
                    str(exception), path, locations, original_error=exception))

            self.errors.append(graphql_error)
Ejemplo n.º 3
0
    async def create_source_event_stream(
        self,
        execution_ctx: ExecutionContext,
        request_ctx: Optional[Dict[str, Any]],
        parent_result: Optional[Any] = None,
    ):
        if not self.subscribe:
            raise TartifletteError(
                "Can't execute a subscription query on a field which doesn't "
                "provide a source event stream with < @Subscription >.")

        info = Info(
            query_field=self,
            schema_field=self.field_executor.schema_field,
            schema=self.schema,
            path=self.path,
            location=self.location,
            execution_ctx=execution_ctx,
        )

        return self.subscribe(
            parent_result,
            await coerce_arguments(
                self.field_executor.schema_field.arguments,
                self.arguments,
                request_ctx,
                info,
            ),
            request_ctx,
            info,
        )
Ejemplo n.º 4
0
    async def execute(
        self,
        query: Union[str, bytes],
        operation_name: Optional[str] = None,
        context: Optional[Any] = None,
        variables: Optional[Dict[str, Any]] = None,
        initial_value: Optional[Any] = None,
    ) -> Dict[str, Any]:
        """
        Parses and executes a GraphQL query/mutation request.
        :param query: the GraphQL request / query as UTF8-encoded string
        :param operation_name: the operation name to execute
        :param context: value that can contain everything you need and that
        will be accessible from the resolvers
        :param variables: the variables provided in the GraphQL request
        :param initial_value: an initial value corresponding to the root type
        being executed
        :type query: Union[str, bytes]
        :type operation_name: Optional[str]
        :type context: Optional[Any]
        :type variables: Optional[Dict[str, Any]]
        :type initial_value: Optional[Any]
        :return: computed response corresponding to the request
        :rtype: Dict[str, Any]
        """
        document, errors = self._cached_parse_and_validate_query(
            query, self._schema)

        # Goes through potential schema directives and finish in self._perform_query
        try:
            return await self._query_executor(
                self._schema,
                document,
                errors,
                operation_name,
                context,
                variables,
                initial_value,
                context_coercer=context,
            )
        # pylint: disable=broad-except
        except Exception as e:
            if not isinstance(e, TartifletteError):
                e = TartifletteError(
                    message=str(e),
                    path=[self._schema.query_operation_name],
                    original_error=e,
                )
            return await self._build_response(errors=[e])
Ejemplo n.º 5
0
def to_graphql_error(
        raw_exception: Exception,
        message: Optional[str] = None) -> Union["TartifletteError", Exception]:
    """
    Converts the raw exception into a TartifletteError if its not coercible or
    returns the raw exception if coercible.
    :param raw_exception: the raw exception to be treated
    :param message: message replacing the raw exception message when it's not
    coercible
    :type raw_exception: Exception
    :type message: Optional[str]
    :return: a coercible exception
    :rtype: Union["TartifletteError", Exception]
    """
    return (raw_exception if is_coercible_exception(raw_exception) else
            TartifletteError(message or str(raw_exception),
                             original_error=raw_exception))
Ejemplo n.º 6
0
def _add_errors_to_execution_context(
    execution_context: ExecutionContext,
    raw_exception: Union[Exception, MultipleException],
    path: Union[str, List[str]],
    location: "Location",
) -> None:
    exceptions = (raw_exception.exceptions if isinstance(
        raw_exception, MultipleException) else [raw_exception])

    for exception in exceptions:
        gql_error = (exception if is_coercible_exception(exception) else
                     TartifletteError(str(exception),
                                      path, [location],
                                      original_error=exception))

        gql_error.coerce_value = partial(gql_error.coerce_value,
                                         path=path,
                                         locations=[location])

        execution_context.add_error(gql_error)
Ejemplo n.º 7
0
def graphql_error_from_nodes(
    message: str,
    nodes: Union["Node", List["Node"]],
    path: Optional[Union[List[str], "Path"]] = None,
    original_error: Optional[Exception] = None,
    extensions: Optional[Dict[str, Any]] = None,
) -> "TartifletteError":
    """
    Returns a TartifletteError linked to a list of AST nodes which make it
    possible to fill in the location of the error.
    :param message: error message
    :param nodes: AST nodes to link to the error
    :param path: the path where the original exception occurred
    :param original_error: the original raised exception
    :param extensions: Extensions dict to add to the error.
    :type message: str
    :type nodes: Union[Node, List[Node]]
    :type path: Optional[List[str]]
    :type original_error: Optional[Exception]
    :type extensions: Optional[Dict[str, Any]]
    :return: a TartifletteError with locations
    :rtype: TartifletteError
    """
    if not isinstance(nodes, list):
        nodes = [nodes]

    if isinstance(path, Path):
        path = path.as_list()

    return TartifletteError(
        message,
        locations=[node.location for node in nodes],
        path=path,
        original_error=original_error,
        extensions=extensions,
    )
Ejemplo n.º 8
0
async def build_execution_context(
    schema: "GraphQLSchema",
    document: "DocumentNode",
    root_value: Optional[Any],
    context: Optional[Any],
    raw_variable_values: Optional[Dict[str, Any]],
    operation_name: str,
) -> Tuple[Optional["ExecutionContext"], Optional[List["TartifletteError"]]]:
    """
    Factory function to build and return an ExecutionContext instance.
    :param schema: the GraphQLSchema instance linked to the engine
    :param document: the DocumentNode instance linked to the GraphQL request
    :param root_value: an initial value corresponding to the root type being
    executed
    :param context: value that can contain everything you need and that will be
    accessible from the resolvers
    :param raw_variable_values: the variables provided in the GraphQL request
    :param operation_name: the operation name to execute
    :type schema: GraphQLSchema
    :type document: DocumentNode
    :type root_value: Optional[Any]
    :type context: Optional[Any]
    :type raw_variable_values: Optional[Dict[str, Any]]
    :type operation_name: str
    :return: an ExecutionContext instance
    :rtype: Tuple[Optional[ExecutionContext], Optional[List[TartifletteError]]]
    """
    # pylint: disable=too-many-arguments,too-many-locals,too-complex
    errors: List["TartifletteError"] = []
    operation: Optional["OperationDefinitionNode"] = None
    fragments: Dict[str, "FragmentDefinitionNode"] = {}
    operations: Dict[Optional[str], "OperationDefinitionNode"] = {}

    for definition in document.definitions:
        if isinstance(definition, OperationDefinitionNode):
            operations[definition.name.value if definition.
                       name else None] = definition
        else:
            fragments[definition.name.value] = definition

    if operation_name:
        operation = operations.get(operation_name)
    elif len(operations) == 1:
        _, operation = operations.popitem()

    if not operation:
        errors.append(
            TartifletteError(
                f"Unknown operation named < {operation_name} >."
                if operation_name else
                "Must provide operation name if query contains multiple operations."
            ))

    variable_values: Dict[str, Any] = {}
    if operation:
        executable_variable_definitions = collect_executable_variable_definitions(
            schema, operation)

        variable_values, variable_errors = await coerce_variables(
            executable_variable_definitions, raw_variable_values or {},
            context)

        if variable_errors:
            errors.extend(variable_errors)

    if errors:
        return None, errors

    return (
        ExecutionContext(
            schema=schema,
            fragments=fragments,
            operation=operation,
            context=context,
            root_value=root_value,
            variable_values=variable_values,
        ),
        None,
    )
Ejemplo n.º 9
0
 async def my_execute(_, exec_ctx, *__, **___):
     exec_ctx.add_error(TartifletteError("My error"))
Ejemplo n.º 10
0
def to_graphql_error(exception, message=None):
    if is_coercible_exception(exception):
        return exception
    return TartifletteError(message or str(exception),
                            original_error=exception)