Ariadne is a Python library for implementing GraphQL servers using schema-first approach.

Overview

Ariadne

Documentation Build Status Codecov


Ariadne

Ariadne is a Python library for implementing GraphQL servers.

  • Schema-first: Ariadne enables Python developers to use schema-first approach to the API implementation. This is the leading approach used by the GraphQL community and supported by dozens of frontend and backend developer tools, examples, and learning resources. Ariadne makes all of this immediately available to your and other members of your team.
  • Simple: Ariadne offers small, consistent and easy to memorize API that lets developers focus on business problems, not the boilerplate.
  • Open: Ariadne was designed to be modular and open for customization. If you are missing or unhappy with something, extend or easily swap with your own.

Documentation is available here.

Features

  • Simple, quick to learn and easy to memorize API.
  • Compatibility with GraphQL.js version 14.4.0.
  • Queries, mutations and input types.
  • Asynchronous resolvers and query execution.
  • Subscriptions.
  • Custom scalars, enums and schema directives.
  • Unions and interfaces.
  • File uploads.
  • Defining schema using SDL strings.
  • Loading schema from .graphql files.
  • WSGI middleware for implementing GraphQL in existing sites.
  • Apollo Tracing and OpenTracing extensions for API monitoring.
  • Opt-in automatic resolvers mapping between camelCase and snake_case, and a @convert_kwargs_to_snake_case function decorator for converting camelCase kwargs to snake_case.
  • Build-in simple synchronous dev server for quick GraphQL experimentation and GraphQL Playground.
  • Support for Apollo GraphQL extension for Visual Studio Code.
  • GraphQL syntax validation via gql() helper function. Also provides colorization if Apollo GraphQL extension is installed.
  • No global state or object registry, support for multiple GraphQL APIs in same codebase with explicit type reuse.
  • Support for Apollo Federation.

Installation

Ariadne can be installed with pip:

pip install ariadne

Quickstart

The following example creates an API defining Person type and single query field people returning a list of two persons. It also starts a local dev server with GraphQL Playground available on the http://127.0.0.1:8000 address.

Start by installing uvicorn, an ASGI server we will use to serve the API:

pip install uvicorn

Then create an example.py file for your example application:

from ariadne import ObjectType, QueryType, gql, make_executable_schema
from ariadne.asgi import GraphQL

# Define types using Schema Definition Language (https://graphql.org/learn/schema/)
# Wrapping string in gql function provides validation and better error traceback
type_defs = gql("""
    type Query {
        people: [Person!]!
    }

    type Person {
        firstName: String
        lastName: String
        age: Int
        fullName: String
    }
""")

# Map resolver functions to Query fields using QueryType
query = QueryType()

# Resolvers are simple python functions
@query.field("people")
def resolve_people(*_):
    return [
        {"firstName": "John", "lastName": "Doe", "age": 21},
        {"firstName": "Bob", "lastName": "Boberson", "age": 24},
    ]


# Map resolver functions to custom type fields using ObjectType
person = ObjectType("Person")

@person.field("fullName")
def resolve_person_fullname(person, *_):
    return "%s %s" % (person["firstName"], person["lastName"])

# Create executable GraphQL schema
schema = make_executable_schema(type_defs, query, person)

# Create an ASGI app using the schema, running in debug mode
app = GraphQL(schema, debug=True)

Finally run the server:

uvicorn example:app

For more guides and examples, please see the documentation.

Contributing

We are welcoming contributions to Ariadne! If you've found a bug or issue, feel free to use GitHub issues. If you have any questions or feedback, don't hesitate to catch us on Spectrum.

For guidance and instructions, please see CONTRIBUTING.md.

Website and the docs have their own GitHub repository: mirumee/ariadne-website

Also make sure you follow @AriadneGraphQL on Twitter for latest updates, news and random musings!

Crafted with ❤️ by Mirumee Software [email protected]

Comments
  • Support OPTIONS requests

    Support OPTIONS requests

    Hi, I keep getting a 405 when using the example code, and I'm wondering if it's a CORS issue, since my frontend and backend are running on different ports. If so, how do I enable CORS with Ariadne?

    bug decision needed 
    opened by chriswingler 18
  • Feature/on subscription complete callback

    Feature/on subscription complete callback

    Hello guys, how is it going?

    I came across using ariadne (which is very well written, by the way) for a project in my company. The project consists of a microservice that is going to provide queries and mostly subscriptions for our front-end layer. Within the architecture of the project, I need to control when the client initiates a subscription and when the subscription has ended to turn on and off, respectively, some of the retrieving information mechanisms (task etc). Within that use case, I can control when the client initiates the operation in the subscription's resolver context, but there was no way of knowing when the client has ended the subscription. Considering that, I added an optional asynchronous callback to the initialization of the server called on_subscription_complete.

    I've been a heavy user of the apollo-server which is a node equivalent of ariadne. By no means I want to compare, or blame whos "better", but just in the intention of presenting my idea, apollo-server has a similar feature (in it's version 3) called onOperationComplete that lets the developer know that the operation was ended by the client.

    That being said, I made some simple modifications to make this feature possible in ariadne:

    1. Created a class called subscription, within the contrib/subscritptions folder, to represent subscriptions within the asgi implementation context. I did it like this to have the opeartion_name in the subscriptions so I'm able to control which subscription was closed.
    from typing import AsyncGenerator
    
    class Subscription:
        def __init__(self, operation_name: str, async_generator: AsyncGenerator):
            self.operation_name = operation_name
            self.async_generator = async_generator
    
    1. Added the on_subscription_complete callback to the initialization of the server:
    OnConnect = Callable[[WebSocket, Any], None]
    OnDisconnect = Callable[[WebSocket], None]
    OnSubscriptionComplete = Callable[[Subscription], Awaitable]
    
    class GraphQL:
        def __init__(
            self,
            schema: GraphQLSchema,
            *,
            context_value: Optional[ContextValue] = None,
            root_value: Optional[RootValue] = None,
            on_connect: Optional[OnConnect] = None,
            on_disconnect: Optional[OnDisconnect] = None,
            on_subscription_complete: Optional[OnSubscriptionComplete] = None,
            validation_rules: Optional[ValidationRules] = None,
            debug: bool = False,
            introspection: bool = True,
            logger: Optional[str] = None,
            error_formatter: ErrorFormatter = format_error,
            extensions: Optional[Extensions] = None,
            middleware: Optional[Middlewares] = None,
            keepalive: float = None,
        ):
            self.context_value = context_value
            self.root_value = root_value
            self.on_connect = on_connect
            self.on_disconnect = on_disconnect
            self.on_subscription_complete = on_subscription_complete
            self.validation_rules = validation_rules
            self.debug = debug
            self.introspection = introspection
            self.logger = logger
            self.error_formatter = error_formatter
            self.extensions = extensions
            self.middleware = middleware
            self.keepalive = keepalive
            self.schema = schema
    
    1. Modified the implementation of start_websocket_subscription to support the subscription class
      if not success:
                results = cast(List[dict], results)
                await websocket.send_json(
                    {"type": GQL_ERROR, "id": operation_id, "payload": results[0]}
                )
      else:
               results = cast(AsyncGenerator, results)
               subscription = Subscription(data.get("operationName"), results)
               subscriptions[operation_id] = subscription
               asyncio.ensure_future(
                   self.observe_async_results(results, operation_id, websocket)
               )
    
    1. Changed the implementation of websocket_server to creating the subscriptions Dict supporting the subscription class
     subscriptions: Dict[str, Subscription] = {}
            await websocket.accept("graphql-ws")
            try:
                while WebSocketState.DISCONNECTED not in (
                    websocket.client_state,
                    websocket.application_state,
                ):
                    message = await websocket.receive_json()
                    await self.handle_websocket_message(message, websocket, subscriptions)
    
    1. Modified the implementation of handle_websocket_message to support the new subscriptions Dict
        async def handle_websocket_message(
            self,
            message: dict,
            websocket: WebSocket,
            subscriptions: Dict[str, Subscription],
        ):
            operation_id = cast(str, message.get("id"))
            message_type = cast(str, message.get("type"))
    
    1. Created close_subscription that receives a subscription and calls the on_subscription_complete callback and calls the subscription.async_generator.aclose() that was called in the previous implementation
     async def close_subscription(self, subscription: Subscription):
            if self.on_subscription_complete:
                await self.on_subscription_complete(subscription)
            await subscription.async_generator.aclose()
    
    1. Used the close_subscription in the websocket_server and handle_websocket_message to close the subscriptions accordantly
        async def websocket_server(self, websocket: WebSocket) -> None:
            subscriptions: Dict[str, Subscription] = {}
            await websocket.accept("graphql-ws")
            try:
                while WebSocketState.DISCONNECTED not in (
                    websocket.client_state,
                    websocket.application_state,
                ):
                    message = await websocket.receive_json()
                    await self.handle_websocket_message(message, websocket, subscriptions)
            except WebSocketDisconnect:
                pass
            finally:
                for subscription in subscriptions.values():
                    await self.close_subscription(subscription=subscription)
    
         async def handle_websocket_message(
            self,
            message: dict,
            websocket: WebSocket,
            subscriptions: Dict[str, Subscription],
        ):
            operation_id = cast(str, message.get("id"))
            message_type = cast(str, message.get("type"))
    
            if message_type == GQL_CONNECTION_INIT:
                await self.handle_websocket_connection_init_message(
                    message,
                    websocket,
                )
            elif message_type == GQL_CONNECTION_TERMINATE:
                await self.handle_websocket_connection_terminate_message(
                    websocket,
                )
            elif message_type == GQL_START:
                await self.start_websocket_subscription(
                    message.get("payload"), operation_id, websocket, subscriptions
                )
            elif message_type == GQL_STOP:
                if operation_id in subscriptions:
                    await self.close_subscription(subscription=subscriptions[operation_id])
                    del subscriptions[operation_id]
    

    And finally, here's me using it

    async def on_disconnect(websocket):
        print("client disconnect")
    
    
    async def on_subscription_complete(subscription):
        print(subscription)
    
    
    def build_server() -> CORSMiddleware:
        schema = build_schema()
        graphql_server = CORSMiddleware(
            GraphQL(
                schema,
                on_connect=on_connect,
                on_disconnect=on_disconnect,
                on_subscription_complete=on_subscription_complete,
                context_value=context_value,
                debug=True,
            ),
            allow_origins=["*"],
            allow_methods=("GET", "POST", "OPTIONS"),
        )
    
        return graphql_server
    

    Well, I hope this is a feature that helps improve ariadne as a whole and I hope I'm able to contribute in some way. If you guys have questions, please let me know. If you guys think this implementation could be done any better, please, also let me know.

    Thanks in advance.

    enhancement 
    opened by soares-fernando 16
  • GraphQL Playground retired, switch to GraphiQL?

    GraphQL Playground retired, switch to GraphiQL?

    GraphQL Playground has been retired, and will no longer receive updates: https://github.com/graphql/graphql-playground/issues/1143

    Down the line, I think it would make sense for Ariadne to switch to GraphiQL because of this.

    roadmap decision needed 
    opened by bartenra 16
  • Added option to trace default resolvers as well

    Added option to trace default resolvers as well

    Adding the option to trace default resolvers if someone want. This is actually very useful in tracing base field types for which resolvers are not explicitly set because those can be use in apollo studio to see which fields are being accessed and how much thereby helping api lifecycle management

    enhancement 
    opened by nilansaha 15
  • Extending a Schema

    Extending a Schema

    Hi, it is very useful library, thanks. Do you plan to implement support extending a schema, documentation? In my case are default scheme and extensions. I need to extend scheme by some extensions according some rule.

    roadmap decision needed 
    opened by VDigitall 15
  • Implement graphql-ws protocol support

    Implement graphql-ws protocol support

    Currently Ariadne implements subscription-transport-ws protocol which Apollo has deprecated and replaced with graphql-ws.

    We should either update ariadne.asgi.GraphQL to graphql-ws or refactor it to make WebSocket support handled via strategy pattern, eg:

    app = GraphQL(schema, websocket=GraphQLWS(options))
    
    enhancement 
    opened by rafalp 14
  • `make_executable_schema`'s  omits default enum values in args and inputs

    `make_executable_schema`'s omits default enum values in args and inputs

    GraphQL enums are represented in Python via the GraphQLEnumType. If those types are created from the SDL, they define no Python representation for GraphQL enum items. Developers can use Ariadne-provided EnumType to specify how enum items should be represented in Python themselves, but we also include "fallback" step that fills enum values with their str representations.

    However neither of those approaches takes care of enum items defined as default values for field arguments. Eg:

    type Query {
        users(role: UserRole = ADMIN): [User]
    }
    
    input FooBarInput {
        foo: FooEnum! = FOO
    }
    

    We will need to add additional step to make_executable_schema that gathers all enums from schema together with their Python representations, and then introspects schema's fields values for places where field or input has default value type of enum. If this is the case, we should set correct default_value on GraphQLArgument in the schema.

    bug roadmap 
    opened by rafalp 14
  • Custom Server example with Flask

    Custom Server example with Flask

    Hey there! I ported the custom server example from django to flask.

    It's quite short and it would be nice to add it to the docs.

    from ariadne import gql, ResolverMap, make_executable_schema
    from ariadne.constants import PLAYGROUND_HTML
    from graphql import format_error, graphql_sync
    from flask import request, jsonify
    from flask.views import MethodView
    
    type_defs = gql("""
        type Query {
            hello: String!
        }
    """)
    
    
    query = ResolverMap("Query")
    
    
    @query.field("hello")
    def resolve_hello(_, info):
        request = info.context
        print(request.headers)
        user_agent = request.headers.get("User-Agent", "Guest")
        return "Hello, %s!" % user_agent
    
    
    schema = make_executable_schema(type_defs, query)
    
    
    class GraphQlView(MethodView):
    
        def get(self):
            return PLAYGROUND_HTML, 200
    
        def post(self):
            data = request.get_json()
            if data is None or not isinstance(data, dict):
                return 'Bad Request', 400
    
            variables = data.get('variables')
            if variables and not isinstance(variables, dict):
                return 'Bad Request', 400
    
            # Note: Passing the request to the context is option. In Flask, the current
            #   request is allways accessible as flask.request.
            result = graphql_sync(
                schema,
                data.get('query'),
                context_value=request,
                variable_values=variables,
                operation_name=data.get('operationName')
            )
    
            response = {"data": result.data}
            if result.errors:
                response["errors"] = [format_error(e) for e in result.errors]
    
            return jsonify(response)
    
    opened by jrast 14
  • Support isinstance() checks in the base types

    Support isinstance() checks in the base types

    To avoid the error on e.g. isinstance(QueryType(), SchemaBindable)

    TypeError: Instance and class checks can only be used with @runtime_checkable protocols
    
    opened by vmarkovtsev 13
  • Really slow for huge list of objects

    Really slow for huge list of objects

    type FooBar {
      # some more flat fields
    }
    
    type Bar {
      n: Int!
      sub: FooBar!
    }
    
    type Foo {
      foo: [Bar!]!
    }
    

    We have a structure like this. The foo property on Foo can contain thousands of items. Sadly we need all of them at once, so we can't paginate over it. There's only one resolver to resolve foo itself which is quite fast (getting the nested object from a Mongo DB). Our current workaround is to implement a custom JSON scalar which just returns the data, by-passing all child resolvers. But this way we're loosing everything that GraphQL gives us. Is there anything that can be used to speed this up without using a JSON scalar or is this the best solution already? I know that GraphQL comes with some overhead but this can go up to 20 seconds vs 1 second with JSON scalar.

    We're using Ariadne in sync-mode.

    enhancement roadmap 
    opened by levrik 13
  • Initial groundwork for editable / disabling graphql playground

    Initial groundwork for editable / disabling graphql playground

    Please see initial work for making the playground editable / ability to disable

    1. I didn't think about supporting python3.6 (could add variable dataclass backport for 3.6)
    2. I don't really know how to use pytest / snapshots and would love some pointers, but I'll try and get tests in
    3. Is there a formatting / linting guide?

    I initially wanted to try and implement the handling of different content-type headers, but I'll move that into a seperate PR.

    opened by beneshed 13
  • multipart.File has no MIME type information

    multipart.File has no MIME type information

    Unfortunately, multipart's File class seems to have a serious regression compared to cgi's FieldStorage class: Where FieldStorage.type contained the declared MIME type of the uploaded file (or None if not given), File does not seem to have this information. This makes is basically impossible to download uploaded files while keeping the file type intact.

    help wanted 
    opened by srittau 4
  • Using middlewares with ASGI GraphQL as documented doesn't work

    Using middlewares with ASGI GraphQL as documented doesn't work

    Adding Middlewares to ASGI GraphQL as documented in https://ariadnegraphql.org/docs/middleware#custom-middleware-example doesn't work.

    This is the example from docs at the time of writing this issue:

    from ariadne.asgi import GraphQL
    from ariadne.asgi.handlers import GraphQLHTTPHandler
    from graphql import MiddlewareManager
    
    
    app = GrapqhQL(
        schema,
        http_handler=GraphQLHTTPHandler(
            middleware=MiddlewareManager(lowercase_middleware),
        ),
    )
    

    Firts, mypy will throw following error:

    error: Argument "middleware" to "GraphQLHTTPHandler" has incompatible type "MiddlewareManager"; expected
    "Union[Callable[[Any, Union[Any, Callable[[Any], Any], None]], Optional[List[Union[Tuple[Any, ...], List[Any], MiddlewareManager, None]]]], Optional[List[Union[Tuple[Any, ...], List[Any], MiddlewareManager, None]]], None]"
    

    Second, running this code will throw following error:

    self = <ariadne.asgi.handlers.http.GraphQLHTTPHandler object at 0x127605390>, request = <starlette.requests.Request object at 0x1279b5600>
    context = {'request': <starlette.requests.Request object at 0x1279b5600>}
    
        async def get_middleware_for_request(
            self, request: Any, context: Optional[ContextValue]
        ) -> Optional[MiddlewareManager]:
            middleware = self.middleware
            if callable(middleware):
                middleware = middleware(request, context)
                if isawaitable(middleware):
                    middleware = await middleware  # type: ignore
            if middleware:
                middleware = cast(list, middleware)
    >           return MiddlewareManager(*middleware)
    E           TypeError: graphql.execution.middleware.MiddlewareManager() argument after * must be an iterable, not MiddlewareManager
    

    By looking at the expected type I've tried:

    from ariadne.asgi import GraphQL
    from ariadne.asgi.handlers import GraphQLHTTPHandler
    from graphql import MiddlewareManager
    
    
    app = GrapqhQL(
        schema,
        http_handler=GraphQLHTTPHandler(
            middleware=[
                MiddlewareManager(lowercase_middleware),
            ],
        ),
    )
    

    It does satisfy mypy, but when the code is run the middlewares aren't ever getting called.

    By looking at the test suite:

    https://github.com/mirumee/ariadne/blob/9a6cd62c9172b5e43cc62cccdec9f28294d7238d/tests/asgi/test_configuration.py#L589..L621

    For example in this part:

    def test_middlewares_are_passed_to_query_executor(schema):
        http_handler = GraphQLHTTPHandler(middleware=[middleware])
        app = GraphQL(schema, http_handler=http_handler)
        client = TestClient(app)
        response = client.post("/", json={"query": '{ hello(name: "BOB") }'})
        assert response.json() == {"data": {"hello": "**Hello, BOB!**"}}
    

    I've noted, that you use a different syntax. This one is working, but it contradicts the doc and doesn't work with static type checking.

    From mypy you will get following error:

    error: List item 0 has incompatible type "Callable[[Callable[..., Any], Any, GraphQLResolveInfo, KwArg(Any)], Any]"; expected
    "Union[Tuple[Any, ...], List[Any], MiddlewareManager, None]"  [list-item]
    

    Workaround that I've found is to do:

    from ariadne.asgi import GraphQL
    from ariadne.asgi.handlers import GraphQLHTTPHandler
    
    
    app = GrapqhQL(
        schema,
        http_handler=GraphQLHTTPHandler(
            middleware=[
                lowercase_middleware,  # type: ignore[list-item]
            ],
        ),
    )
    

    I'd suggest adding type annotations to the test suite and run mypy on it.

    docs 
    opened by blazewicz 1
  • Using enums as argument default values is broken on InterfaceType

    Using enums as argument default values is broken on InterfaceType

    Similar to #547 but this bug is specific to type "interface". It seems that if you try to define a schema in which an interface type contains an enum argument with a default value, an error will be thrown when trying to execute an introspection query. This is with:

    ariadne 0.16.1 graphql-core 3.2.3

    Example:

    import enum
    import ariadne
    
    type_defs = """
        type Query {
            users: [User!]!
        }
    
        enum Role {
            ADMIN
            USER
        }
    
        interface User {
            name(role: Role! = USER): String!
        }
    """
    
    QueryGraphQLType = ariadne.QueryType()
    
    class Role(enum.Enum):
        ADMIN = "ADMIN"
        USER = "USER"
    
    RoleGraphQLType = ariadne.EnumType("Role", Role)
    
    UserGraphQLType = ariadne.InterfaceType("User")
    
    schema = ariadne.make_executable_schema(
        type_defs,
        QueryGraphQLType,
        RoleGraphQLType,
        UserGraphQLType,
    )
    
    query = "{__schema{types{name,fields{name,args{name,defaultValue}}}}}"
    
    result = ariadne.graphql_sync(schema, {"query": query}, debug=True)
    import pprint
    pprint.pprint(result)
    

    Error:

    Enum 'Role' cannot represent value: 'USER'
    
    GraphQL request:1:44
    1 | {__schema{types{name,fields{name,args{name,defaultValue}}}}}
      |                                            ^
    Traceback (most recent call last):
      File "/venv/lib/python3.8/site-packages/graphql/execution/execute.py", line 521, in execute_field
        result = resolve_fn(source, info, **args)
      File "/venv/lib/python3.8/site-packages/graphql/type/introspection.py", line 485, in default_value
        value_ast = ast_from_value(item[1].default_value, item[1].type)
      File "/venv/lib/python3.8/site-packages/graphql/utilities/ast_from_value.py", line 63, in ast_from_value
        ast_value = ast_from_value(value, type_.of_type)
      File "/venv/lib/python3.8/site-packages/graphql/utilities/ast_from_value.py", line 108, in ast_from_value
        serialized = type_.serialize(value)  # type: ignore
      File "/venv/lib/python3.8/site-packages/graphql/type/definition.py", line 1233, in serialize
        raise GraphQLError(
    graphql.error.graphql_error.GraphQLError: Enum 'Role' cannot represent value: 'USER'
    
    bug 
    opened by dkbarn 7
  • OpenAPI schema for ariadne routes is not generated by starlette

    OpenAPI schema for ariadne routes is not generated by starlette

    We're trying to generate an OpenAPI schema using starlette.schemas.SchemaGenerator, however it does not include any definitions for ariadne.

    As per starlette's docs:

    Schema generation works by inspecting the routes on the application through app.routes, and using the docstrings or other attributes on the endpoints in order to determine a complete API schema.

    Is it possible to add a docstring into ariadne's graphql endpoint, or allow it to be configured manually so that it can be picked up by ariadne's schema generator?

    EDIT: One possible workaround is to wrap ariadne's route with another route, but it would be great if this was available out of the box. EDIT 2: Seems like SchemaGenerator.get_endpoints doesn't find ariadne's endpoints. We're using it as follows:

    class GraphQLAdapter(Starlette):
        SCHEMA_PATH = ...
    
        def __init__(self):
            ...
            schema = make_executable_schema(...)
            graphql = GraphQL(schema)
    
            super().__init__(
                routes=[
                    Mount('', graphql),
                ],
            )
    
    opened by and3rson 5
Releases(0.17.1.b1)
  • 0.17.1.b1(Dec 16, 2022)

    CHANGELOG

    • Fixed an error when schema that defines an interface type with fields having enum arguments with default values (eg. field(arg: Enum = ENUM_MEMBER)) is introspected.
    Source code(tar.gz)
    Source code(zip)
  • 0.17.0(Dec 14, 2022)

    CHANGELOG

    • Bumped starlette dependency in setup.py to <1.0.
    • Added Python 3.11 to test matrix.
    • Removed usage of deprecated cgi module.
    • Renamed asgi-file-uploads optional dependency to file-uploads.
    Source code(tar.gz)
    Source code(zip)
  • 0.17.0.beta1(Dec 13, 2022)

  • 0.17.0.b2(Dec 13, 2022)

  • 0.17.0.dev1(Nov 4, 2022)

    CHANGELOG

    • GraphiQL2 is now default API explorer.
    • Added explorer option to ASGI and WSGI GraphQL applications that enables API explorer customization.
    • Added ExplorerHttp405 API explorer that returns 405 Method Not Allowed for GET HTTP requests.
    • Added implementations for GraphiQL2, GraphQL-Playground and Apollo Sandbox explorers.
    • Changed logger option to also support Logger and LoggerAdapter instance in addition to str with logger name.
    • Added support for @tag directive used by Apollo Federation.
    • Updated starlette dependency in setup.py to <1.0.
    • Moved project configuration from setup.py to pyproject.toml.
    Source code(tar.gz)
    Source code(zip)
  • 0.16.1(Sep 26, 2022)

  • 0.16.1.b1(Sep 16, 2022)

  • 0.16.0(Sep 8, 2022)

    CHANGELOG

    • Refactored ariadne.asgi.GraphQL to use strategy pattern for handling HTTP and WebSockets.
    • Updated load_schema_from_path to also support .gql and .graphqls files.
    • Added support for starlette 0.20.
    Source code(tar.gz)
    Source code(zip)
  • 0.16.0b2(Sep 7, 2022)

  • 0.16.0b1(Aug 4, 2022)

    CHANGELOG

    • Refactored ariadne.asgi.GraphQL to use strategy pattern for handling HTTP and WebSockets.
    • Updated load_schema_from_path to also use .gql and .graphqls files.
    • Added support for starlette 0.20.
    Source code(tar.gz)
    Source code(zip)
  • 0.15.1(Apr 22, 2022)

  • 0.15.0(Apr 13, 2022)

    Changelog

    • Updated graphql-core requirement to 3.2.0.
    • Bumped starlette supported versions to 0.18 and 0.19.
    • Drop Python 3.6 support.
    • Added basic support for OPTIONS HTTP request.
    • Refactor ariadne.asgi.GraphQL to make it easier to customize JSON response.
    • Added trace_default_resolver to ApolloTracingExtension that enables tracing for default resolvers.
    • Fixed make_federated_schema error when custom directive in schema has description.
    • Moved set_default_enum_values_on_schema, validate_schema_enum_values and type_implements_interface to public API.
    • Changed graphql_sync to use execute_sync instead of execute.
    • Added on_operation hook to ariadne.asgi.GraphQL that's called when individual subscription operation is started.
    • Added on_complete hook to ariadne.asgi.GraphQL that's called when individual subscription operation is completed.
    • Updated on_disconnect hook so its called in Webhook handler's finally clause, making it called in more situations.
    • Marked Extension, ExtensionSync and SchemaBindable protocols as @runtime_checkable.
    • Renamed parent to obj in ApolloTracing and OpenTracing extensions so arg name won't cause conflict when custom resolver has parent arg.
    Source code(tar.gz)
    Source code(zip)
  • 0.15.0.dev5(Apr 12, 2022)

    Changelog

    • Added on_complete hook to ariadne.asgi.GraphQL that's called when individual subscription operation is completed.
    • Updated on_disconnect hook so its called in Webhook handler's finally clause, making it called in more situations.
    • Marked Extension, ExtensionSync and SchemaBindable protocols as @runtime_checkable
    Source code(tar.gz)
    Source code(zip)
  • 0.15.0.dev4(Apr 4, 2022)

    CHANGELOG

    • Updated graphql-core requirement to 3.2.0.
    • Bumped starlette support to 0.18.
    • Drop Python 3.6 support.
    • Added basic support for OPTIONS HTTP request.
    • Refactor ariadne.asgi.GraphQL to make it easier to customize JSON response.
    • Added trace_default_resolver to ApolloTracingExtension that enables tracing for default resolvers.
    • Fixed make_federated_schema error when custom directive in schema has description.
    • Moved set_default_enum_values_on_schema, validate_schema_enum_values and type_implements_interface to public API.
    Source code(tar.gz)
    Source code(zip)
  • 0.14.1(Jan 28, 2022)

  • 0.14.0(Nov 24, 2021)

    • Added on_connect and on_disconnect options to ariadne.asgi.GraphQL, enabling developers to run additional initialization and cleanup for websocket connections.
    • Updated Starlette dependency to 0.17.1.
    • Added support for multiple keys for GraphQL federations.
    • Made Query type optional in federated schemas.
    • Updated default resolvers to test for Mapping instead of dict.
    • Removed ariadne.contrib.django. (Use ariadne_django instead).
    • Updated query cost validator to handle optional variables.
    Source code(tar.gz)
    Source code(zip)
  • 0.13.0(Mar 17, 2021)

    • Updated graphQL-core requirement to 3.1.3.
    • Added support for Python 3.9.
    • Added support for using nested variables as cost multipliers in the query price validator.
    • None is now correctly returned instead of {"__typename": typename} within federation.
    • Fixed some surprising behaviors in convert_kwargs_to_snake_case and snake_case_fallback_resolvers.
    Source code(tar.gz)
    Source code(zip)
  • 0.12.0(Aug 4, 2020)

    • Added validation_rules option to query executors as well as ASGI and WSGI apps and Django view that allow developers to include custom query validation logic in their APIs.
    • Added introspection option to ASGI and WSGI apps, allowing developers to disable GraphQL introspection on their server.
    • Added validation.cost_validator query validator that allows developers to limit maximum allowed query cost/complexity.
    • Removed default literal parser from ScalarType because GraphQL already provides one.
    • Added extensions and introspection configuration options to Django view.
    • Updated requirements list to require graphql-core 3.
    Source code(tar.gz)
    Source code(zip)
  • 0.11.0(Apr 1, 2020)

    0.11.0 (2020-04-01)

    • Fixed convert_kwargs_to_snake_case utility so it also converts the case in lists items.
    • Removed support for sending queries and mutations via WebSocket.
    • Freezed graphql-core dependency at version 3.0.3.
    • Unified default info.context value for WSGI to be dict with single request key.
    Source code(tar.gz)
    Source code(zip)
  • 0.10.0(Feb 11, 2020)

    0.10.0 (2020-02-11)

    • Added support for Apollo Federation.
    • Added the ability to send queries to the same channel as the subscription via WebSocket.
    Source code(tar.gz)
    Source code(zip)
  • 0.9.0(Dec 11, 2019)

  • 0.8.0(Nov 25, 2019)

    0.8.0 (2019-11-25)

    • Added recursive loading of GraphQL schema files from provided path.
    • Added support for passing multiple bindables as *args to make_executable_schema.
    • Updated Starlette dependency to 0.13.
    • Made python-multipart optional dependency for asgi-file-uploads.
    • Added Python 3.8 to officially supported versions.
    Source code(tar.gz)
    Source code(zip)
  • 0.7.0(Oct 4, 2019)

    0.7.0 (2019-10-03)

    • Added support for custom schema directives.
    • Added support for synchronous extensions and synchronous versions of ApolloTracing and OpenTracing extensions.
    • Added context argument to has_errors and format hooks.
    Source code(tar.gz)
    Source code(zip)
  • 0.6.0(Aug 12, 2019)

    0.6.0

    • Updated graphql-core-next to 1.1.1 which has feature parity with GraphQL.js 14.4.0.
    • Added basic extensions system to the ariadne.graphql.graphql. Currently only available in the ariadne.asgi.GraphQL app.
    • Added convert_kwargs_to_snake_case utility decorator that recursively converts the case of arguments passed to resolver from camelCase to snake_case.
    • Removed default_resolver and replaced its uses in library with graphql.default_field_resolver.
    • Resolver returned by resolve_to util follows graphql.default_field_resolver behaviour and supports resolving to callables.
    • Added is_default_resolver utility for checking if resolver function is graphql.default_field_resolver, resolver created with resolve_to or alias.
    • Added ariadne.contrib.tracing package with ApolloTracingExtension and OpenTracingExtension GraphQL extensions for adding Apollo tracing and OpenTracing monitoring to the API (ASGI only).
    • Updated ASGI app disconnection handler to also check client connection state.
    • Fixed ASGI app context_value option support for async callables.
    • Updated middleware option implementation in ASGI and WSGI apps to accept list of middleware functions or callable returning those.
    • Moved error formatting utils (get_formatted_error_context, get_formatted_error_traceback, unwrap_graphql_error) to public API.
    Source code(tar.gz)
    Source code(zip)
  • 0.5.0(Jun 7, 2019)

  • 0.4.0(May 23, 2019)

    0.4.0 (2019-05-23)

    • Updated graphql-core-next to 1.0.4 which has feature parity with GraphQL.js 14.3.1 and better type annotations.
    • ariadne.asgi.GraphQL is now an ASGI3 application. ASGI3 is now handled by all ASGI servers.
    • ObjectType.field and SubscriptionType.source decorators now raise ValueError when used without name argument (eg. @foo.field).
    • ScalarType will now use default literal parser that unpacks ast.value and calls value parser if scalar has value parser set.
    • Updated ariadne.asgi.GraphQL and ariadne.wsgi.GraphQL to support callables for context_value and root_value options.
    • Added logger option to ariadne.asgi.GraphQL, ariadne.wsgi.GraphQL and ariadne.graphql.* utils.
    • Added default logger that logs to ariadne.
    • Added support for extend type in schema definitions.
    • Removed unused format_errors utility function and renamed ariadne.format_errors module to ariadne.format_error.
    • Removed explicit typing dependency.
    • Added ariadne.contrib.django package that provides Django class-based view together with Date and Datetime scalars.
    • Fixed default ENUM values not being set.
    • Updated project setup so mypy ran in projects with Ariadne dependency run type checks against it's annotations.
    • Updated Starlette to 0.12.0.
    Source code(tar.gz)
    Source code(zip)
  • 0.3.0(Apr 8, 2019)

    Ariadne 0.3.0 release is focused on further improving the support for GraphQL specification and developer experience. It adds support for subscriptions, enums, interfaces and union GraphQL types, and unifies the API across those types. It also greatly improves developer experience by the inclusion of debug mode, error reporting, and includes graphql, graphql_sync and subscribe wrappers that ease integrations with existing sites greatly. Lastly, it also provides ASGI application that works with asynchronous servers and frameworks like Uvicorn and Starlette

    CHANGELOG

    • Added EnumType type for mapping enum variables to internal representation used in application.
    • Added support for subscriptions.
    • Updated Playground to 1.8.7.
    • Split GraphQLMiddleware into two classes and moved it to ariadne.wsgi.
    • Added an ASGI interface based on Starlette under ariadne.asgi.
    • Replaced the simple server utility with Uvicorn.
    • Made users responsible for calling make_executable_schema.
    • Added UnionType and InterfaceType types.
    • Updated library API to be more consistent between types, and work better with code analysis tools like PyLint. Added QueryType and MutationType convenience utils. Suffixed all types names with Type so they are less likely to clash with other libraries built-ins.
    • Improved error reporting to also include Python exception type, traceback and context in the error JSON. Added debug and error_formatter options to enable developer customization.
    • Introduced Ariadne wrappers for graphql, graphql_sync, and subscribe to ease integration into custom servers.
    Source code(tar.gz)
    Source code(zip)
  • 0.2.0(Jan 7, 2019)

    Ariadne 0.2.0 replaces GraphQL-Core with GraphQL-core-next that offers much better compliance with GraphQL specification, supports async query execution and resolvers, and improves library's API and developer experience.

    Changelog

    • Removed support for Python 3.5 and added support for 3.7.
    • Moved to GraphQL-core-next that supports async resolvers, query execution and implements a more recent version of GraphQL spec. If you are updating an existing project, you will need to uninstall graphql-core before installing graphql-core-next, as both libraries use graphql namespace.
    • Added gql() utility that provides GraphQL string validation on declaration time, and enables use of Apollo-GraphQL plugin in Python code.
    • Added load_schema_from_path() utility function that loads GraphQL types from a file or directory containing .graphql files, also performing syntax validation.
    • Added start_simple_server() shortcut function for quick dev server creation, abstracting away the GraphQLMiddleware.make_server() from first time users.
    • Boolean built-in scalar now checks the type of each serialized value. Returning values of type other than bool, int or float from a field resolver will result in a Boolean cannot represent a non boolean value error.
    • Redefining type in type_defs will now result in TypeError being raised. This is a breaking change from previous behavior where the old type was simply replaced with a new one.
    • Returning None from scalar parse_literal and parse_value function no longer results in GraphQL API producing default error message. Instead, None will be passed further down to resolver or produce a "value is required" error if its marked as such with ! For old behavior raise either ValueError or TypeError. See documentation for more details.
    • resolvers argument defined by GraphQLMiddleware.__init__(), GraphQLMiddleware.make_server() and start_simple_server() is now optional, allowing for quick experiments with schema definitions.
    • dict has been removed as primitive for mapping python function to fields. Instead, make_executable_schema() expects object or list of objects with a bind_to_schema method, that is called with a GraphQLSchema instance and are expected to add resolvers to schema.
    • Default resolvers are no longer set implicitly by make_executable_schema(). Instead you are expected to include either ariadne.fallback_resolvers or ariadne.snake_case_fallback_resolvers in the list of resolvers for your schema.
    • Added snake_case_fallback_resolvers that populates schema with default resolvers that map CamelCase and PascalCase field names from schema to snake_case names in Python.
    • Added ResolverMap object that enables assignment of resolver functions to schema types.
    • Added Scalar object that enables assignment of serialize, parse_value and parse_literal functions to custom scalars.
    • Both ResolverMap and Scalar are validating if schema defines specified types and/or fields at the moment of creation of executable schema, providing better feedback to the developer.
    Source code(tar.gz)
    Source code(zip)
  • 0.1.0(Oct 31, 2018)

    Ariadne 0.1.0 is first release of Ariadne that out of the box implements following features:

    • WSGI Middleware for adding GraphQL API to existing sites
    • Built-in dev server that enables developers to start experimenting quickly
    • GraphQL Playground as API explorer
    • Resolvers, mutations, custom scalars, inputs and enums
    • Modularization support
    • Documentation
    Source code(tar.gz)
    Source code(zip)
Owner
Mirumee Labs
High performance Python, React & React Native applications
Mirumee Labs
MGE-GraphQL is a Python library for building GraphQL mutations fast and easily

MGE-GraphQL Introduction MGE-GraphQL is a Python library for building GraphQL mutations fast and easily. Data Validations: A similar data validation w

MGE Software 4 Apr 23, 2022
A Python 3.6+ port of the GraphQL.js reference implementation of GraphQL.

GraphQL-core 3 GraphQL-core 3 is a Python 3.6+ port of GraphQL.js, the JavaScript reference implementation for GraphQL, a query language for APIs crea

GraphQL Python 458 Dec 13, 2022
GraphQL security auditing script with a focus on performing batch GraphQL queries and mutations

BatchQL BatchQL is a GraphQL security auditing script with a focus on performing batch GraphQL queries and mutations. This script is not complex, and

Assetnote 267 Dec 24, 2022
A Django GraphQL Starter that uses graphene and graphene_django to interface GraphQL.

Django GraphQL Starter GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data... According to the doc

0101 Solutions 1 Jan 10, 2022
A new GraphQL library for Python 🍓

Strawberry GraphQL Python GraphQL library based on dataclasses Installation ( Quick Start ) The quick start method provides a server and CLI to get go

Strawberry GraphQL 2.8k Jan 1, 2023
Graphql-codegen library - a pure python implementation

turms DEVELOPMENT Inspiration Turms is a pure python implementation of the awesome graphql-codegen library, following a simliar extensible design. It

Johannes Roos 22 Dec 23, 2022
A library to help construct a graphql-py server supporting react-relay

Relay Library for GraphQL Python GraphQL-relay-py is the Relay library for GraphQL-core. It allows the easy creation of Relay-compliant servers using

GraphQL Python 143 Nov 15, 2022
Generate a FullStack Playground using GraphQL and FastAPI 🚀

FastQL - FastAPI GraphQL Playground Generate a FullStack playground using FastAPI and GraphQL and Ariadne ?? . This Repository is based on this Articl

OBytes 109 Dec 23, 2022
This is a minimal project using graphene with django and user authentication to expose a graphql endpoint.

Welcome This is a minimal project using graphene with django and user authentication to expose a graphql endpoint. Definitely checkout how I have mana

yosef salmalian 1 Nov 18, 2021
Blazing fast GraphQL endpoints finder using subdomain enumeration, scripts analysis and bruteforce.

Graphinder Graphinder is a tool that extracts all GraphQL endpoints from a given domain. Run with docker docker run -it -v $(pwd):/usr/bin/graphinder

Escape 76 Dec 28, 2022
GraphQL framework for Python

Graphene ?? Join the community on Slack We are looking for contributors! Please check the ROADMAP to see how you can help ❤️ The below readme is the d

GraphQL Python 7.5k Jan 1, 2023
GraphQL framework for Python

Graphene ?? Join the community on Slack We are looking for contributors! Please check the ROADMAP to see how you can help ❤️ The below readme is the d

GraphQL Python 7.5k Jan 1, 2023
GraphQL Engine built with Python 3.6+ / asyncio

Tartiflette is a GraphQL Server implementation built with Python 3.6+. Summary Motivation Status Usage Installation Installation dependencies Tartifle

tartiflette 839 Dec 31, 2022
A python graphql api, which serves ECB currency rates from last 90 days.

Exchange Rate Api using GraphQL Get Code git pull https://github.com/alaturqua/exchangerate-graphql.git Create .env file with following content and s

Isa 1 Nov 4, 2021
This is a simple Python that will parse instanceStats GraphQL Query into a CSV

GraphQL Python Labs - by Gabs the CSE Table of Contents About The Project Getting Started Prerequisites Installation and Usage Roadmap Contributing Li

Gabriel (Gabs) Cerioni 1 Oct 27, 2021
Pygitstats - a package that allows you to use the GitHub GraphQL API with ease in your Python programs

Pygitstats - a package that allows you to use the GitHub GraphQL API with ease in your Python programs

Dillon Barnes 4 Mar 29, 2022
tartiflette-aiohttp is a wrapper of aiohttp which includes the Tartiflette GraphQL Engine, do not hesitate to take a look of the Tartiflette project.

tartiflette-aiohttp is a wrapper of aiohttp which includes the Tartiflette GraphQL Engine. You can take a look at the Tartiflette API documentation. U

tartiflette 60 Nov 8, 2022
ASGI support for the Tartiflette GraphQL engine

tartiflette-asgi is a wrapper that provides ASGI support for the Tartiflette Python GraphQL engine. It is ideal for serving a GraphQL API over HTTP, o

tartiflette 99 Dec 27, 2022
GraphQL is a query language and execution engine tied to any backend service.

GraphQL The GraphQL specification is edited in the markdown files found in /spec the latest release of which is published at https://graphql.github.io

GraphQL 14k Jan 1, 2023