Skip to content

An extension for strawberry-graphql that allows using rich logging for debugging

License

Notifications You must be signed in to change notification settings

Zlira/rich-strawberry

Repository files navigation

Rich Strawberry

This is a work in progress!

rich-strawberry is a small add-on for the strawberry-graphql library that uses rich to print error information nicely.

Basic Example

You can use the RichLoggerExtension to get improved traceback in your application. However, you'll need to disable the default logger to avoid logging every exception twice.

Here's a basic example:

import logging

import strawberry

from rich_strawberry import RichLoggerExtension

logger = logging.getLogger("strawberry.execution")
logger.disabled = True


@strawberry.type
class Query:
    @strawberry.field
    def version(self) -> int:
        raise ValueError


schema = strawberry.Schema(query=Query, extensions=[RichLoggerExtension()])

This will give you the following output in the console for the query query { version }:

Basic Output

Configuration

Suppressing frames

By default, the logger uses a feature from rich to suppress the frames from graphql and strawberry-graphql libraries. You can configure the list of modules for which the frames will be suppressed. For example, if you want the full traceback:

import logging

import strawberry

from rich_strawberry import RichLoggerExtension, RichGraphQLLogger

logger = logging.getLogger("strawberry.execution")
logger.disabled = True


@strawberry.type
class Query:
    @strawberry.field
    def version(self) -> int:
        raise ValueError


debug_logger = RichGraphQLLogger(suppress_traceback_from=[])
schema = strawberry.Schema(
    query=Query, extensions=[RichLoggerExtension(logger=debug_logger)]
)

Here's the full console output:

Output Without Frame Suppression

Logging context

You can also configure some values from the context to be logged on error.

import logging

import strawberry

from rich_strawberry import RichLoggerExtension, RichGraphQLLogger

logger = logging.getLogger("strawberry.execution")
logger.disabled = True


@strawberry.type
class Query:
    @strawberry.field
    def version(self) -> int:
        raise ValueError


debug_logger = RichGraphQLLogger(log_context_keys=("request",))
schema = strawberry.Schema(
    query=Query, extensions=[RichLoggerExtension(logger=debug_logger)]
)

This will use rich.inspect to print that context value into the console:

Output With Request

❗ This feature is not very well tested with different integrations so it might not work as expected.

Using with subscription

At the moment of writing, subscriptions don't support extensions (check this merge request, maybe they already do!) So if you want to use the RichGraphQLLogger for your subscriptions, you'll need to define a custom Schema class and overwrite its process_errors method:

from typing import Optional

import strawberry
from strawberry.types import ExecutionContext
from graphql import GraphQLError

from rich_strawberry.logger import RichGraphQLLogger

class SchemaWithRichLogger(strawberry.Schema):
    def __init__(
        self,
        debug_logger: Optional[RichGraphQLLogger] = None,
        *args,
        **kwargs,
    ):
        super().__init__(*args, **kwargs)
        self.debug_logger = debug_logger or RichGraphQLLogger()

    def process_errors(
        self,
        errors: list[GraphQLError],
        execution_context: Optional[ExecutionContext] = None,
    ) -> None:
        self.debug_logger.print_errors(errors, execution_context)

You can see a full example with subscriptions here.

Context values aren't logged for subscriptions.

About

An extension for strawberry-graphql that allows using rich logging for debugging

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages