tartiflette-aiohttp is a wrapper of aiohttp which includes the Tartiflette GraphQL Engine, do not hesitate to take a look of the Tartiflette project.

Overview

Tartiflette aiohttp

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

Usage

# main.py
from aiohttp import web
from tartiflette import Resolver
from tartiflette_aiohttp import register_graphql_handlers

@Resolver("Query.hello")
async def resolver_hello(parent, args, ctx, info):
    return "hello " + args["name"]

sdl = """
    type Query {
        hello(name: String): String
    }
"""

web.run_app(
    register_graphql_handlers(
        web.Application(),
        engine_sdl=sdl
    )
)

Save the file and start the server.

$ python main.py
======== Running on http://0.0.0.0:8080 ========
(Press CTRL+C to quit)

Note: The server will be listening on the /graphql path by default.

Send a request to your server

curl -v -d '{"query": "query { hello(name: "Chuck") }"}' -H "Content-Type: application/json" http://localhost:8080/graphql

Installation

tartiflette-aiohttp is available on pypi.org.

WARNING: Do not forget to install the tartiflette dependencies beforehand as explained in the tutorial.

pip install tartiflette-aiohttp

How to use

Use with built-in Tartiflette Engine

The basic and common way to use Tartiflette with aiohttp, is to create an aiohttp web.Application and use the register_graphql_handlers helper to bind Tartiflette and aiohttp together. engine_* parameters will be forwarded to the built-in tartiflette engine instance.

from aiohttp import web
from tartiflette_aiohttp import register_graphql_handlers

sdl = """
    type Query {
        hello(name: String): String
    }
"""

ctx = {
    'user_service': user_service
}

web.run_app(
    register_graphql_handlers(
        app=web.Application(),
        engine_sdl=sdl,
        engine_schema_name="default",
        executor_context=ctx,
        executor_http_endpoint='/graphql',
        executor_http_methods=['POST', 'GET']
    )
)

Parameters:

  • engine_sdl: Contains the Schema Definition Language
    • Can be a string which contains the SDL
    • Can be an array of strings, which contain the SDLs
    • Can be a path to an SDL
    • Can be an array of paths which contain the SDLs
  • engine_schema_name: Name of the schema used by the built-in engine. Useful for advanced use-cases, see Schema Registry API.
  • executor_context: Context which will be passed to each resolver (as a dict). Very useful for passing handlers to services, functions or data that you want to use in your resolvers. The context reference is unique per request, a shallow copy is created based on the context passed.
    • req: Request object from aiohttp
    • app: Application object from aiohttp
  • executor_http_endpoint: Endpoint where the GraphQL Engine will be attached, by default on /graphql
  • executor_http_methods: HTTP Methods where the GraphQL Engine will be attached, by default on POST and GET.

Use with custom Tartiflette engine

In the case you already have a Tartiflette Engine instance, or, you do not want to use the built-in instance. You can pass an existing instance to the register_graphql_handlers helper.

# main.py
from aiohttp import web
from tartiflette import Resolver, Engine
from tartiflette_aiohttp import register_graphql_handlers

@Resolver("Query.hello")
async def resolver_hello(parent, args, ctx, info):
    return "hello " + args["name"]

sdl = """
    type Query {
        hello(name: String): String
    }
"""

engine = Engine(sdl)

ctx = {
    'user_service': user_service
}

web.run_app(
    register_graphql_handlers(
        app=web.Application(),
        engine=engine,
        executor_context=ctx,
        executor_http_endpoint='/graphql',
        executor_http_methods=['POST', 'GET']
    )
)

Parameters:

  • engine: an instance of the Tartiflette Engine
  • executor_context: Context which will be passed to each resolver (as a dict). Very useful for passing handlers to services, functions or data that you want to use in your resolvers.
    • req: Request object from aiohttp
    • app: Application object from aiohttp
  • executor_http_endpoint: Endpoint where the GraphQL Engine will be attached, by default on /graphql
  • executor_http_methods: HTTP Methods where the GraphQL Engine will be attached, by default on POST and GET

Tartiflette with subscriptions

Tartiflette embeds an easy way to deal with subscriptions. The only thing to do is to fill in the subscription_ws_endpoint parameter and everything will work out of the box with aiohttp WebSockets. You can see a full example here.

Enable GraphiQL handler

Tartiflette allows you to set up an instance of GraphiQL easily to quickly test your queries. The easiest way to do that is to set the graphiql_enabled parameter to True. Then, you can customize your GraphiQL instance by filling the graphiql_options parameter as bellow:

from aiohttp import web

from tartiflette_aiohttp import register_graphql_handlers


_SDL = """
    type Query {
        hello(name: String): String
    }
"""

web.run_app(
    register_graphql_handlers(
        app=web.Application(),
        engine_sdl=_SDL,
        graphiql_enabled=True,
        graphiql_options={  # This is optional
            "endpoint": "/explorer",  # Default: `/graphiql`,
            "default_query": """
                query Hello($name: String) {
                  hello(name: $name)
                }
            """,
            "default_variables": {
                "name": "Bob",
            },
            "default_headers": {
                "Authorization": "Bearer <default_token>",
            },
        },
    )
)

Parameters:

  • engine_sdl: Contains the Schema Definition Language
    • Can be a string which contains the SDL
    • Can be an array of strings, which contain the SDLs
    • Can be a path to an SDL
    • Can be an array of paths which contain the SDLs
  • graphiql_enabled (Optional[bool] = False): Determines whether or not we should include a GraphiQL interface
  • graphiql_options (Optional[dict] = None): Customization options for the GraphiQL instance:
    • endpoint (Optional[str] = "/graphiql"): allows to customize the GraphiQL interface endpoint path
    • default_query (Optional[str] = None): allows you to pre-fill the GraphiQL interface with a default query
    • default_variables (Optional[dict] = None): allows you to pre-fill the GraphiQL interface with default variables
    • default_headers (Optional[dict] = None): allows you to add default headers to each request sent through the GraphiQL instance

Advance Use Case

Response header manipulation from resolver

It is possible to set header to the response directly from the resolver using set_response_headers method like:

from tartiflette_aiohttp import set_response_headers

@Resolver("Query.X")
async def resolver_x(parent_result, args, ctx, info):
    # do things
    set_response_headers({"Header": "Value", "AnotherHeader": "AnotherValue"})
    return result

Note that this feature uses ContextVar and will only works for python 3.7.1 and later.

OR it is also possible to do, if you do not have ContextVar, or don't want to use them:

from aiohttp import web

def a_callable(req, data, ctx):
    return web.json_response(data, headers=ctx["_any_custom_key"])

web.run_app(
    register_graphql_handlers(
        app=web.Application(),
        engine_sdl=_SDL,
        response_formatter=a_callable
    )
)


@Resolver("Type.field_name")
async def fiel_name_resolver(pr, args, ctx, info):
    ctx["_any_custom_key"] = {"X-Header": "What a wonderfull value"}
    return something
Comments
  • Subscriptions do not work in the getting started example

    Subscriptions do not work in the getting started example

    tartiflette-aiohttp = "^0.8.4"

    Python version is 3.7.4

    I've copied the code from the getting started example on the website line for line, but the subscriptions aren't working. The default subscription resolver on line 145 of the factory.py file is being invoked rather than the one defined in the application.

    Please can you check?

    opened by jamessmith-decisionlab 16
  • How to do per-request cleanup/teardown of context data?

    How to do per-request cleanup/teardown of context data?

    I am using SQLAlchemy to interact with a database in my GraphQL server. The creation of an SQLAlchemy connection/session is happening in my context_factory function, which ensures I get a new session on each web request.

    But I need to properly close and cleanup this connection at the end of each request.

    Is there a hook provided for doing per-request cleanup of data stored in the context?

    opened by dkbarn 15
  • doc/issue-76

    doc/issue-76

    Pull request for connection _unsubscribe implementation based on tasks rather than trying to directly close the async generator directly, to fix changes made in python 3.8.

    Information to do it this way gotten from: https://bugs.python.org/issue38559

    This is way outside of my wheelhouse so if someone with asyncio experience can take a look and make sure this is the correct way to proceed that'd be good.

    Thanks

    opened by daveoconnor 10
  • Error with subscriptions on refreshing graphiql page

    Error with subscriptions on refreshing graphiql page

    Using a fairly by-the-documentation installation I'm getting an error when I refresh the GraphiQL UI when a subscription is running.

    Error:

    Error handling request Traceback (most recent call last): File "/home/USER/PROJECT/PROJECT/venv/lib/python3.8/site-packages/aiohttp/web_protocol.py", line 418, in start resp = await task File "/home/USER/PROJECT/PROJECT/venv/lib/python3.8/site-packages/aiohttp/web_app.py", line 458, in _handle resp = await handler(request) File "/home/USER/PROJECT/PROJECT/venv/lib/python3.8/site-packages/aiohttp/web_urldispatcher.py", line 158, in handler_wrapper return await result File "/home/USER/PROJECT/PROJECT/venv/lib/python3.8/site-packages/tartiflette_aiohttp/_subscription_ws_handler.py", line 263, in call await shield(self._handle_request()) File "/home/USER/PROJECT/PROJECT/venv/lib/python3.8/site-packages/tartiflette_aiohttp/_subscription_ws_handler.py", line 257, in _handle_request await self._on_close(connection_context, tasks) File "/home/USER/PROJECT/PROJECT/venv/lib/python3.8/site-packages/tartiflette_aiohttp/_subscription_ws_handler.py", line 233, in _on_close await self._unsubscribe(connection_context, operation_id) File "/home/USER/PROJECT/PROJECT/venv/lib/python3.8/site-packages/tartiflette_aiohttp/_subscription_ws_handler.py", line 141, in _unsubscribe await operation.aclose() RuntimeError: aclose(): asynchronous generator is already running

    PROJECT/subscription_resolvers.py

    import asyncio
    from tartiflette import Subscription
    
    @Subscription("Subscription.foos")
    async def subscription_foos(parent, args, ctx, info):
        data = [
            {
                "id": 1,
                "name": "one"
            },
            {
                "id": 2,
                "name": "two"
            }
        ]
        while True:
            yield {
                'foos': data
            }
            await asyncio.sleep(1)
    

    PROJECT/sdl/Subscription.graphql

    type Foo {
        id: Int
        name: String
    }
    type Subscription {
        foos: [Foo]
    }
    

    Data is as expected.

    Let me know if there's any more info I can provide to help with this.

    bug 
    opened by daveoconnor 7
  • Multiple non anonymous operations raise an error

    Multiple non anonymous operations raise an error

    • tartiflette: 0.6.7
    • tartiflette-aiohttp: 0.4.2
    • Python version: 3.7.2
    • Executed in docker: No

    If a Document contains only one operation, that operation may be unnamed or represented in the shorthand form, which omits both the query keyword and operation name. Otherwise, if a GraphQL Document contains multiple operations, each operation must be named. When submitting a Document with multiple operations to a GraphQL service, the name of the desired operation to be executed must also be provided.

    https://graphql.github.io/graphql-spec/June2018/

    Request:

    query allUsers {
      users {
        name
      }
    }
    
    query singleUser {
      user(id: 1) {
        name
      }
    }
    
    

    Response:

    {
      "data": null,
      "errors": [
        {
          "message": "Must provide operation name if query contains multiple operations.",
          "path": null,
          "locations": []
        }
      ]
    }
    
    bug 
    opened by thecylax 7
  • [bug report] Can't run a subscription in local.

    [bug report] Can't run a subscription in local.

    Bug Report

    Presentation

    I try to create a subscription in my api, i can't make it work. I try to run a subscription with the tutorial example to be sure it's come from my configuration, but I can't make it work too.

    Execution environment

    • tartiflette: 1.2.1
    • tartiflette-aiohttp: 1.3.0
    • Python: 3.7.5
    • Executed in docker: No

    GraphQL Schema & Query:

    I follow the getting started up to step 10. Running a subscription.

    So my schema for the subscription is

    enum CookingStatus {
      COOKING
      COOKED
    }
    
    type CookingTimer {
      remainingTime: Int!
      status: CookingStatus!
    }
    
    type Subscription {
      launchAndWaitCookingTimer(id: Int!): CookingTimer
    }
    

    I try with multiple python clients and graphiql.

    from gql import gql, Client, WebsocketsTransport
    
    transport = WebsocketsTransport(url='wss://localhost:8080/graphql')
    
    client = Client(
        transport=transport,
        fetch_schema_from_transport=True,
    )
    
    query = gql('''
        subscription {
      launchAndWaitCookingTimer(id: 1) {
        remainingTime
        status
      }
    }
    ''')
    
    for result in client.subscribe(query):
        print (result)
    
    from graphql_client import GraphQLClient
    
    query = """
       subscription {
      launchAndWaitCookingTimer(id: 1) {
        remainingTime
        status
      }
    }
    """
    
    def callback(_id, data):
        print("got new data..")
        print(f"msg id: {_id}. data: {data}")
    
    with GraphQLClient('wss://localhost:8080') as client:
        sub_id = client.subscribe(query, callback=callback)
        client.stop_subscribe(sub_id)
    
    from python_graphql_client import GraphqlClient
    
    # Instantiate the client with a websocket endpoint.
    client = GraphqlClient(endpoint="wss://localhost:8080/ws")
    
    # Create the query string and variables required for the request.
    query = """
       subscription {
      launchAndWaitCookingTimer(id: 1) {
        remainingTime
        status
      }
    }
    """
    
    # Asynchronous request
    import asyncio
    
    data = asyncio.run(client.subscribe(query=query, handle=print))
    

    Stack trace

    With each client or graphiql for each subscription the tartiflette server gave me the same error:

    ======== Running on http://0.0.0.0:8080 ========
    (Press CTRL+C to quit)
    Error handling request
    Traceback (most recent call last):
      File "/home/alex/.pyenv/versions/product-api/lib/python3.7/site-packages/aiohttp/web_protocol.py", line 418, in start
        resp = await task
      File "/home/alex/.pyenv/versions/product-api/lib/python3.7/site-packages/aiohttp/web_app.py", line 458, in _handle
        resp = await handler(request)
      File "/home/alex/.pyenv/versions/product-api/lib/python3.7/site-packages/aiohttp/web_urldispatcher.py", line 158, in handler_wrapper
        return await result
      File "/home/alex/.pyenv/versions/product-api/lib/python3.7/site-packages/tartiflette_aiohttp/_subscription_ws_handler.py", line 265, in __call__
        self._context = await self._context_factory(request)
    TypeError: object _AsyncGeneratorContextManager can't be used in 'await' expression
    Error handling request
    Traceback (most recent call last):
      File "/home/alex/.pyenv/versions/product-api/lib/python3.7/site-packages/aiohttp/web_protocol.py", line 418, in start
        resp = await task
      File "/home/alex/.pyenv/versions/product-api/lib/python3.7/site-packages/aiohttp/web_app.py", line 458, in _handle
        resp = await handler(request)
      File "/home/alex/.pyenv/versions/product-api/lib/python3.7/site-packages/aiohttp/web_urldispatcher.py", line 158, in handler_wrapper
        return await result
      File "/home/alex/.pyenv/versions/product-api/lib/python3.7/site-packages/tartiflette_aiohttp/_subscription_ws_handler.py", line 265, in __call__
        self._context = await self._context_factory(request)
    TypeError: object _AsyncGeneratorContextManager can't be used in 'await' expression
    

    The Previous error does not make the client quit or stop, and my query and mutations works fine with clients or graphiql.

    On clientside I have the following stack trace

    $ python test_subscription.py
    ### waiting for 1 minute with nothing then the followin error append 
    Traceback (most recent call last):
      File "recipes_manager/test_query.py", line 19, in <module>
        for result in client.subscribe(query):
      File "/home/alex/.pyenv/versions/tartiflette/lib/python3.7/site-packages/gql/client.py", line 176, in subscribe
        loop.run_until_complete(generator_task)
      File "/home/alex/.pyenv/versions/3.7.5/lib/python3.7/asyncio/base_events.py", line 579, in run_until_complete
        return future.result()
      File "/home/alex/.pyenv/versions/tartiflette/lib/python3.7/site-packages/gql/client.py", line 164, in subscribe
        result = loop.run_until_complete(generator_task)
      File "/home/alex/.pyenv/versions/3.7.5/lib/python3.7/asyncio/base_events.py", line 579, in run_until_complete
        return future.result()
      File "/home/alex/.pyenv/versions/tartiflette/lib/python3.7/site-packages/gql/client.py", line 132, in subscribe_async
        async with self as session:
      File "/home/alex/.pyenv/versions/tartiflette/lib/python3.7/site-packages/gql/client.py", line 189, in __aenter__
        await self.transport.connect()
      File "/home/alex/.pyenv/versions/tartiflette/lib/python3.7/site-packages/gql/transport/websockets.py", line 514, in connect
        websockets.connect(self.url, **connect_args,), self.connect_timeout,
      File "/home/alex/.pyenv/versions/3.7.5/lib/python3.7/asyncio/tasks.py", line 449, in wait_for
        raise futures.TimeoutError()
    concurrent.futures._base.TimeoutError
    

    And the result on graphiql: image

    Conclusion

    Do you have any idea why I can't run some subscription ? Thank's by advance.

    opened by Boblebol 6
  • buildSubscriptionURL() doesn't choose wss when graphiql served by https

    buildSubscriptionURL() doesn't choose wss when graphiql served by https

    Hi, we are now deploying our tartiflette-based backend for internal use, but wish to continue to support graphiql for a while longer.

    We're running our app in docker swarm with traefik front-end with tls support (client to traefik), and non-tls from traefik to the backend app.

    when I load https://my-app.mydomain.com/graphiql .. the page loads but returns this error

    client.js:1571 Mixed Content: The page at 'https://my-app.mydomain.com/graphiql' was loaded over HTTPS, but attempted to connect to the insecure WebSocket endpoint 'ws://caentry-dev.svc.sfi.ca/ws'. This request has been blocked; this endpoint must be available over WSS.	
    

    I think the issue is that buildSubscriptionURL() doesn't check to see if the html was loaded over https, so only chooses the 'ws' scheme instead of the 'wss' scheme.

    I think checking window.location.protocol to see if it's https: would solve this?

    enhancement 
    opened by bkcsfi 6
  • Subscriptions are missing keepalives

    Subscriptions are missing keepalives

    Been meaning to post this for a while after discussing it in the chat. I'd been having issues with the websocket connection closing and reopening - thanks to apollo reconnect - every ~50 seconds and not being able to determine why. After doing some research it seems that norm is that the server sends a keepalive.

    https://github.com/apollographql/subscriptions-transport-ws/blob/master/PROTOCOL.md

    This isn't majorly important at the moment and shouldn't be a big change so I'll try to look into it at some point in the future if no one else does, but it might be a while before I can get to it. Unit tests for subscriptions would be a big help in making that something that's safer to work on without fear of breaking things.

    For anyone who comes across this issue in the meantime I've been able to implement a workaround on the apollo client side using a websocket link:

    const subscriptionClient = new SubscriptionClient(this.wsdomain, {
    	reconnect: true,
    	lazy: true,
            options: {
    		reconnect: true,
    		lazy: true,
    //		... other options ...
    	}
    });
    
    setInterval(() => {
    	if (subscriptionClient.status === 1) {
    		subscriptionClient.client.send('{"type":"ka"}');
    	 }
    }, 40000);
    const wsLink = new WebSocketLink(subscriptionClient);
    

    Thanks!

    opened by daveoconnor 4
  • Allow custom context_factory to be an asynccontextmanager (tartiflette#94)

    Allow custom context_factory to be an asynccontextmanager (tartiflette#94)

    This adds support for context_factory to be defined as an asynccontextmanager, which allows for both setup and teardown of any data in the context.

    ~~To maintain backwards compatibility, context_factory is also still allowed to be defined as a coroutinefunction.~~ Backwards compatibility removed as it was not deemed necessary. The context_factory can now only be an asynccontextmanager, and default_context_factory has been updated accordingly.

    Closes #94

    opened by dkbarn 3
  • Context passed to subscriptions is None

    Context passed to subscriptions is None

    When using subscriptions, both the resolver and the subscription handler receive None as the context, regardless of what is passed in to register_graphql_handlers.

    I was expecting that context to be the same context (though a unique instance as for all requests) that is received by query and mutation resolvers. I wondered how the examples worked but then noticed that it just uses a global instead of passing the redis connection through the context.

    I noticed that for subscriptions the context is being pulled from the websocket message payload, which seems odd to me but maybe I don't fully understand: https://github.com/tartiflette/tartiflette-aiohttp/blob/e2c48e0ef6b02804e3a4ca31d58e12fbcff3407e/tartiflette_aiohttp/_subscription_ws_handler.py#L29

    Here's an small example app that demos the behavior I'm seeing:

    import asyncio
    import sys
    
    from aiohttp import web
    
    from tartiflette import Resolver, Subscription
    from tartiflette_aiohttp import register_graphql_handlers
    
    
    SDL = """
    type Query {
        countdownLength: Int!
    }
    
    type Subscription {
        countdown: Int!
    }
    """
    
    
    @Resolver("Query.countdownLength")
    async def resolver_length(_parent, _args, ctx, _info):
        return ctx["length"]
    
    
    @Subscription("Subscription.countdown")
    async def on_countdown(parent, _args, ctx, _info):
        print(f"subscription: ctx={ctx}")
        countdown = 5  # would expect to use ctx["length"] here
        while countdown > 0:
            yield countdown
            countdown -= 1
            await asyncio.sleep(1)
        yield 0
    
    
    @Resolver("Subscription.countdown")
    async def resolver_countdown(payload, _args, ctx, _info):
        print(f"resolver: payload={payload} ctx={ctx}")
        return payload
    
    
    def main():
        app = web.Application()
        register_graphql_handlers(
            app,
            engine_sdl=SDL,
            executor_context={"length": 5},
            subscription_ws_endpoint="/ws",
            graphiql_enabled=True,
        )
        web.run_app(app, port=8089)
        return 0
    
    
    if __name__ == "__main__":
        sys.exit(main())
    

    Which produces output:

    ======== Running on http://0.0.0.0:8089 ========
    (Press CTRL+C to quit)
    subscription: ctx=None
    resolver: payload=5 ctx=None
    resolver: payload=4 ctx=None
    resolver: payload=3 ctx=None
    resolver: payload=2 ctx=None
    resolver: payload=1 ctx=None
    resolver: payload=0 ctx=None
    
    bug 
    opened by jonypawks 3
  • Subscription handler not working when passing engine as coroutine to `register_graphql_handlers`

    Subscription handler not working when passing engine as coroutine to `register_graphql_handlers`

    • tartiflette: 0.11.1
    • tartiflette-aiohttp: 0.8.0

    When I try to pass the engine to register_graphql_handlers like this:

    def run():
        app = web.Application()
    
        engine: Engine = create_engine(
           ...
        )
    
        web.run_app(
            register_graphql_handlers(
                app=app,
                engine=engine,
                subscription_ws_endpoint="/ws",
            )
        )
    

    I get the following error when trying to execute a subscription:

    Traceback (most recent call last):
      File "/lib/python3.7/site-packages/tartiflette_aiohttp/_subscription_ws_handler.py", line 212, in _on_message
        return await self._process_message(connection_context, parsed_message)
      File "/lib/python3.7/site-packages/tartiflette_aiohttp/_subscription_ws_handler.py", line 189, in _process_message
        return await self._on_start(connection_context, operation_id, payload)
      File "/lib/python3.7/site-packages/tartiflette_aiohttp/_subscription_ws_handler.py", line 154, in _on_start
        iterator = self._engine.subscribe(**params)
    AttributeError: 'coroutine' object has no attribute 'subscribe'
    

    This makes sense because the engine coroutine won't be consumed in the register_graphql_handlers but on app startup while a few lines later the engine coroutine will be passed to the AIOHTTPSubscriptionHandler which expects an Engine and not a Awaitable[Engine].

    opened by arjandepooter 3
  • Bump isort from 5.10.1 to 5.11.4

    Bump isort from 5.10.1 to 5.11.4

    Bumps isort from 5.10.1 to 5.11.4.

    Release notes

    Sourced from isort's releases.

    5.11.4

    Changes

    :package: Dependencies

    5.11.3

    Changes

    :beetle: Fixes

    :construction_worker: Continuous Integration

    v5.11.3

    Changes

    :beetle: Fixes

    :construction_worker: Continuous Integration

    5.11.2

    Changes

    5.11.1

    Changes December 12 2022

    ... (truncated)

    Changelog

    Sourced from isort's changelog.

    5.11.4 December 21 2022

    5.11.3 December 16 2022

    5.11.2 December 12 2022

    5.11.1 December 12 2022

    5.11.0 December 12 2022

    Commits
    • 98390f5 Merge pull request #2059 from PyCQA/version/5.11.4
    • df69a05 Bump version 5.11.4
    • f9add58 Merge pull request #2058 from PyCQA/deps/poetry-1.3.1
    • 36caa91 Bump Poetry 1.3.1
    • 3c2e2d0 Merge pull request #1978 from mgorny/toml-test
    • 45d6abd Remove obsolete toml import from the test suite
    • 3020e0b Merge pull request #2057 from mgorny/poetry-install
    • a6fdbfd Stop installing documentation files to top-level site-packages
    • ff306f8 Fix tag template to match old standard
    • 227c4ae Merge pull request #2052 from hugovk/main
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
  • Bump black from 20.8b1 to 23.1a1

    Bump black from 20.8b1 to 23.1a1

    Bumps black from 20.8b1 to 23.1a1.

    Release notes

    Sourced from black's releases.

    23.1a1

    This release provides a preview of Black's 2023 stable style. Black's default formatting style includes the following changes:

    • Enforce empty lines before classes and functions with sticky leading comments (#3302) (22.12.0)
    • Reformat empty and whitespace-only files as either an empty file (if no newline is present) or as a single newline character (if a newline is present) (#3348) (22.12.0)
    • Implicitly concatenated strings used as function args are now wrapped inside parentheses (#3307) (22.12.0)
    • Correctly handle trailing commas that are inside a line's leading non-nested parens (#3370) (22.12.0)
    • --skip-string-normalization / -S now prevents docstring prefixes from being normalized as expected (#3168) (since 22.8.0)
    • When using --skip-magic-trailing-comma or -C, trailing commas are stripped from subscript expressions with more than 1 element (#3209) (22.8.0)
    • Implicitly concatenated strings inside a list, set, or tuple are now wrapped inside parentheses (#3162) (22.8.0)
    • Fix a string merging/split issue when a comment is present in the middle of implicitly concatenated strings on its own line (#3227) (22.8.0)
    • Docstring quotes are no longer moved if it would violate the line length limit (#3044, #3430) (22.6.0)
    • Parentheses around return annotations are now managed (#2990) (22.6.0)
    • Remove unnecessary parentheses around awaited objects (#2991) (22.6.0)
    • Remove unnecessary parentheses in with statements (#2926) (22.6.0)
    • Remove trailing newlines after code block open (#3035) (22.6.0)
    • Code cell separators #%% are now standardised to # %% (#2919) (22.3.0)
    • Remove unnecessary parentheses from except statements (#2939) (22.3.0)
    • Remove unnecessary parentheses from tuple unpacking in for loops (#2945) (22.3.0)
    • Avoid magic-trailing-comma in single-element subscripts (#2942) (22.3.0)

    Please try it out and give feedback here: psf/black#3407

    A stable 23.1.0 release will follow in January 2023.

    22.12.0

    Preview style

    • Enforce empty lines before classes and functions with sticky leading comments (#3302)
    • Reformat empty and whitespace-only files as either an empty file (if no newline is present) or as a single newline character (if a newline is present) (#3348)
    • Implicitly concatenated strings used as function args are now wrapped inside parentheses (#3307)
    • Correctly handle trailing commas that are inside a line's leading non-nested parens (#3370)

    Configuration

    ... (truncated)

    Changelog

    Sourced from black's changelog.

    Change Log

    Unreleased

    Highlights

    Stable style

    • Fix a crash when a colon line is marked between # fmt: off and # fmt: on (#3439)

    Preview style

    • Fix a crash in preview style with assert + parenthesized string (#3415)
    • Fix crashes in preview style with walrus operators used in function return annotations and except clauses (#3423)
    • Do not put the closing quotes in a docstring on a separate line, even if the line is too long (#3430)
    • Long values in dict literals are now wrapped in parentheses; correspondingly unnecessary parentheses around short values in dict literals are now removed; long string lambda values are now wrapped in parentheses (#3440)

    Configuration

    Packaging

    • Upgrade mypyc from 0.971 to 0.991 so mypycified Black can be built on armv7 (#3380)
    • Drop specific support for the tomli requirement on 3.11 alpha releases, working around a bug that would cause the requirement not to be installed on any non-final Python releases (#3448)

    Parser

    Performance

    Output

    ... (truncated)

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
  • Bump pylint from 2.11.1 to 2.15.9

    Bump pylint from 2.11.1 to 2.15.9

    Bumps pylint from 2.11.1 to 2.15.9.

    Commits
    • 1ded4d0 Bump pylint to 2.15.9, update changelog (#7952)
    • 785c629 [testutil] More information in output for functional test fail (#7948)
    • 3c3ab98 [pypy3.8] Disable multiple-statements false positive on affected functional t...
    • dca3940 Fix inconsistent argument exit code when argparse exit with its own error cod...
    • 494e514 Fix ModuleNotFoundError when using pylint_django (#7940) (#7941)
    • 83668de fix: bump dill to >= 0.3.6, prevents tests hanging with python3.11 (#7918)
    • eadc308 [github actions] Fix enchant's install in the spelling job
    • 391323e Avoid hanging forever after a parallel job was killed (#7834) (#7930)
    • 4655b92 Prevent used-before-assignment in pattern matching with a guard (#7922) (#7...
    • 1f84ed9 Bump pylint to 2.15.8, update changelog (#7899)
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
  • Bump pytest-asyncio from 0.16.0 to 0.20.3

    Bump pytest-asyncio from 0.16.0 to 0.20.3

    Bumps pytest-asyncio from 0.16.0 to 0.20.3.

    Release notes

    Sourced from pytest-asyncio's releases.

    pytest-asyncio 0.20.3


    title: 'pytest-asyncio'

    image

    image

    image

    Supported Python versions

    image

    pytest-asyncio is a pytest plugin. It facilitates testing of code that uses the asyncio library.

    Specifically, pytest-asyncio provides support for coroutines as test functions. This allows users to await code inside their tests. For example, the following code is executed as a test item by pytest:

    @pytest.mark.asyncio
    async def test_some_asyncio_code():
        res = await library.do_something()
        assert b"expected result" == res
    

    Note that test classes subclassing the standard unittest library are not supported. Users are advised to use unittest.IsolatedAsyncioTestCase or an async framework such as asynctest.

    pytest-asyncio is available under the Apache License 2.0.

    Installation

    To install pytest-asyncio, simply:

    $ pip install pytest-asyncio
    

    ... (truncated)

    Changelog

    Sourced from pytest-asyncio's changelog.

    0.20.3 (22-12-08)

    • Prevent DeprecationWarning to bubble up on CPython 3.10.9 and 3.11.1. [#460](https://github.com/pytest-dev/pytest-asyncio/issues/460) <https://github.com/pytest-dev/pytest-asyncio/issues/460>_

    0.20.2 (22-11-11)

    • Fixes an issue with async fixtures that are defined as methods on a test class not being rebound to the actual test instance. [#197](https://github.com/pytest-dev/pytest-asyncio/issues/197) <https://github.com/pytest-dev/pytest-asyncio/issues/197>_
    • Replaced usage of deprecated @pytest.mark.tryfirst with @pytest.hookimpl(tryfirst=True) [#438](https://github.com/pytest-dev/pytest-asyncio/issues/438) <https://github.com/pytest-dev/pytest-asyncio/pull/438>_

    0.20.1 (22-10-21)

    • Fixes an issue that warned about using an old version of pytest, even though the most recent version was installed. [#430](https://github.com/pytest-dev/pytest-asyncio/issues/430) <https://github.com/pytest-dev/pytest-asyncio/issues/430>_

    0.20.0 (22-10-21)

    • BREAKING: Removed legacy mode. If you're upgrading from v0.19 and you haven't configured asyncio_mode = legacy, you can upgrade without taking any additional action. If you're upgrading from an earlier version or you have explicitly enabled legacy mode, you need to switch to auto or strict mode before upgrading to this version.
    • Deprecate use of pytest v6.
    • Fixed an issue which prevented fixture setup from being cached. [#404](https://github.com/pytest-dev/pytest-asyncio/issues/404) <https://github.com/pytest-dev/pytest-asyncio/pull/404>_

    0.19.0 (22-07-13)

    • BREAKING: The default asyncio_mode is now strict. [#293](https://github.com/pytest-dev/pytest-asyncio/issues/293) <https://github.com/pytest-dev/pytest-asyncio/issues/293>_
    • Removes setup.py since all relevant configuration is present setup.cfg. Users requiring an editable installation of pytest-asyncio need to use pip v21.1 or newer. [#283](https://github.com/pytest-dev/pytest-asyncio/issues/283) <https://github.com/pytest-dev/pytest-asyncio/issues/283>_
    • Declare support for Python 3.11.

    0.18.3 (22-03-25)

    • Adds pytest-trio <https://pypi.org/project/pytest-trio/>_ to the test dependencies
    • Fixes a bug that caused pytest-asyncio to try to set up async pytest_trio fixtures in strict mode. [#298](https://github.com/pytest-dev/pytest-asyncio/issues/298) <https://github.com/pytest-dev/pytest-asyncio/issues/298>_

    0.18.2 (22-03-03)

    • Fix asyncio auto mode not marking static methods. [#295](https://github.com/pytest-dev/pytest-asyncio/issues/295) <https://github.com/pytest-dev/pytest-asyncio/issues/295>_
    • Fix a compatibility issue with Hypothesis 6.39.0. [#302](https://github.com/pytest-dev/pytest-asyncio/issues/302) <https://github.com/pytest-dev/pytest-asyncio/issues/302>_

    0.18.1 (22-02-10)

    • Fixes a regression that prevented async fixtures from working in synchronous tests. [#286](https://github.com/pytest-dev/pytest-asyncio/issues/286) <https://github.com/pytest-dev/pytest-asyncio/issues/286>_

    0.18.0 (22-02-07)

    • Raise a warning if @​pytest.mark.asyncio is applied to non-async function. [#275](https://github.com/pytest-dev/pytest-asyncio/issues/275) <https://github.com/pytest-dev/pytest-asyncio/issues/275>_
    • Support parametrized event_loop fixture. [#278](https://github.com/pytest-dev/pytest-asyncio/issues/278) <https://github.com/pytest-dev/pytest-asyncio/issues/278>_

    0.17.2 (22-01-17)

    • Require typing-extensions on Python`_

    ... (truncated)

    Commits
    • 007e8ec [fix] Prevent DeprecationWarning about existing event loops to bubble up into...
    • 44ca3da Build(deps): Bump zipp from 3.10.0 to 3.11.0 in /dependencies/default (#455)
    • c3c601c Build(deps): Bump pypa/gh-action-pypi-publish from 1.5.1 to 1.5.2 (#456)
    • a962e2b Build(deps): Bump importlib-metadata in /dependencies/default (#454)
    • 56a393a Simplify README, move most content to a separate user documentation. (#448)
    • 3c78732 Build(deps): Bump hypothesis in /dependencies/default (#453)
    • d6a9a72 Build(deps): Bump exceptiongroup in /dependencies/default (#451)
    • 42da7a0 Build(deps): Bump hypothesis in /dependencies/default (#450)
    • 0b281b1 Build(deps): Bump mypy from 0.990 to 0.991 in /dependencies/default (#446)
    • d39589c Update pre-commit hooks (#449)
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
  • Add CodeQL workflow for GitHub code scanning

    Add CodeQL workflow for GitHub code scanning

    Hi tartiflette/tartiflette-aiohttp!

    This is a one-off automatically generated pull request from LGTM.com :robot:. You might have heard that we’ve integrated LGTM’s underlying CodeQL analysis engine natively into GitHub. The result is GitHub code scanning!

    With LGTM fully integrated into code scanning, we are focused on improving CodeQL within the native GitHub code scanning experience. In order to take advantage of current and future improvements to our analysis capabilities, we suggest you enable code scanning on your repository. Please take a look at our blog post for more information.

    This pull request enables code scanning by adding an auto-generated codeql.yml workflow file for GitHub Actions to your repository — take a look! We tested it before opening this pull request, so all should be working :heavy_check_mark:. In fact, you might already have seen some alerts appear on this pull request!

    Where needed and if possible, we’ve adjusted the configuration to the needs of your particular repository. But of course, you should feel free to tweak it further! Check this page for detailed documentation.

    Questions? Check out the FAQ below!

    FAQ

    Click here to expand the FAQ section

    How often will the code scanning analysis run?

    By default, code scanning will trigger a scan with the CodeQL engine on the following events:

    • On every pull request — to flag up potential security problems for you to investigate before merging a PR.
    • On every push to your default branch and other protected branches — this keeps the analysis results on your repository’s Security tab up to date.
    • Once a week at a fixed time — to make sure you benefit from the latest updated security analysis even when no code was committed or PRs were opened.

    What will this cost?

    Nothing! The CodeQL engine will run inside GitHub Actions, making use of your unlimited free compute minutes for public repositories.

    What types of problems does CodeQL find?

    The CodeQL engine that powers GitHub code scanning is the exact same engine that powers LGTM.com. The exact set of rules has been tweaked slightly, but you should see almost exactly the same types of alerts as you were used to on LGTM.com: we’ve enabled the security-and-quality query suite for you.

    How do I upgrade my CodeQL engine?

    No need! New versions of the CodeQL analysis are constantly deployed on GitHub.com; your repository will automatically benefit from the most recently released version.

    The analysis doesn’t seem to be working

    If you get an error in GitHub Actions that indicates that CodeQL wasn’t able to analyze your code, please follow the instructions here to debug the analysis.

    How do I disable LGTM.com?

    If you have LGTM’s automatic pull request analysis enabled, then you can follow these steps to disable the LGTM pull request analysis. You don’t actually need to remove your repository from LGTM.com; it will automatically be removed in the next few months as part of the deprecation of LGTM.com (more info here).

    Which source code hosting platforms does code scanning support?

    GitHub code scanning is deeply integrated within GitHub itself. If you’d like to scan source code that is hosted elsewhere, we suggest that you create a mirror of that code on GitHub.

    How do I know this PR is legitimate?

    This PR is filed by the official LGTM.com GitHub App, in line with the deprecation timeline that was announced on the official GitHub Blog. The proposed GitHub Action workflow uses the official open source GitHub CodeQL Action. If you have any other questions or concerns, please join the discussion here in the official GitHub community!

    I have another question / how do I get in touch?

    Please join the discussion here to ask further questions and send us suggestions!

    opened by lgtm-com[bot] 0
  • Bump pytest from 6.2.5 to 7.2.0

    Bump pytest from 6.2.5 to 7.2.0

    Bumps pytest from 6.2.5 to 7.2.0.

    Release notes

    Sourced from pytest's releases.

    7.2.0

    pytest 7.2.0 (2022-10-23)

    Deprecations

    • #10012: Update pytest.PytestUnhandledCoroutineWarning{.interpreted-text role="class"} to a deprecation; it will raise an error in pytest 8.

    • #10396: pytest no longer depends on the py library. pytest provides a vendored copy of py.error and py.path modules but will use the py library if it is installed. If you need other py.* modules, continue to install the deprecated py library separately, otherwise it can usually be removed as a dependency.

    • #4562: Deprecate configuring hook specs/impls using attributes/marks.

      Instead use :pypytest.hookimpl{.interpreted-text role="func"} and :pypytest.hookspec{.interpreted-text role="func"}. For more details, see the docs <legacy-path-hooks-deprecated>{.interpreted-text role="ref"}.

    • #9886: The functionality for running tests written for nose has been officially deprecated.

      This includes:

      • Plain setup and teardown functions and methods: this might catch users by surprise, as setup() and teardown() are not pytest idioms, but part of the nose support.
      • Setup/teardown using the @​with_setup decorator.

      For more details, consult the deprecation docs <nose-deprecation>{.interpreted-text role="ref"}.

    Features

    • #9897: Added shell-style wildcard support to testpaths.

    Improvements

    • #10218: @pytest.mark.parametrize() (and similar functions) now accepts any Sequence[str] for the argument names, instead of just list[str] and tuple[str, ...].

      (Note that str, which is itself a Sequence[str], is still treated as a comma-delimited name list, as before).

    • #10381: The --no-showlocals flag has been added. This can be passed directly to tests to override --showlocals declared through addopts.

    • #3426: Assertion failures with strings in NFC and NFD forms that normalize to the same string now have a dedicated error message detailing the issue, and their utf-8 representation is expresed instead.

    • #7337: A warning is now emitted if a test function returns something other than [None]{.title-ref}. This prevents a common mistake among beginners that expect that returning a [bool]{.title-ref} (for example [return foo(a, b) == result]{.title-ref}) would cause a test to pass or fail, instead of using [assert]{.title-ref}.

    • #8508: Introduce multiline display for warning matching via :pypytest.warns{.interpreted-text role="func"} and enhance match comparison for :py_pytest._code.ExceptionInfo.match{.interpreted-text role="func"} as returned by :pypytest.raises{.interpreted-text role="func"}.

    • #8646: Improve :pypytest.raises{.interpreted-text role="func"}. Previously passing an empty tuple would give a confusing error. We now raise immediately with a more helpful message.

    • #9741: On Python 3.11, use the standard library's tomllib{.interpreted-text role="mod"} to parse TOML.

      tomli{.interpreted-text role="mod"}` is no longer a dependency on Python 3.11.

    • #9742: Display assertion message without escaped newline characters with -vv.

    • #9823: Improved error message that is shown when no collector is found for a given file.

    ... (truncated)

    Commits
    • 3af3f56 Prepare release version 7.2.0
    • bc2c3b6 Merge pull request #10408 from NateMeyvis/patch-2
    • d84ed48 Merge pull request #10409 from pytest-dev/asottile-patch-1
    • ffe49ac Merge pull request #10396 from pytest-dev/pylib-hax
    • d352098 allow jobs to pass if codecov.io fails
    • c5c562b Fix typos in CONTRIBUTING.rst
    • d543a45 add deprecation changelog for py library vendoring
    • f341a5c Merge pull request #10407 from NateMeyvis/patch-1
    • 1027dc8 [pre-commit.ci] auto fixes from pre-commit.com hooks
    • 6b905ee Add note on tags to CONTRIBUTING.rst
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
Releases(1.4.1)
  • 1.4.1(Nov 15, 2021)

  • 1.4.0(Dec 15, 2020)

    [1.4.0] - 2020-12-14

    Added

    • ISSUE-123 - Add an optional subscription_keep_alive_interval parameter to the register_graphql_handlers function. When provided, a keep alive message will be send to the client each subscription_keep_alive_interval seconds.
    Source code(tar.gz)
    Source code(zip)
  • 1.3.1(Sep 24, 2020)

    [1.3.1] - 2020-09-24

    Changed

    • Test platform:
      • pytest to 6.0.2
      • pytest-cov to 2.10.1
      • pylint to 2.6.0
      • isort to 5.5.3
      • black to 20.8b1
      • xenon to 0.7.1

    Fixed

    • ISSUE-112 - Fix async context generator with subscription.
    Source code(tar.gz)
    Source code(zip)
  • 1.3.0(Aug 1, 2020)

    [1.3.0] - 2020-07-31

    Added

    • Added a way to hook the response formatting stage of the request execution. Simply register a callable looking like:
    def a_method(req: aiohttp.web.Request, data: Dict[str, Any], ctx: Dict[str, Any]) -> aiohttp.web.Response:
         pass
    

    This is done via the register_graphql_handler(..., response_formatter= a_method).

    Changed

    • ISSUE-94 - Changed the context_factory from a simple async method to an asynccontextmanager decorated one - Thanks @jugdizh

    • Test platform:

      • pytest from 5.3.4 -> 6.0.1
      • pytest-asyncio from 0.10.0 -> 0.14.0
      • pytest-cov from 2.8.1 -> 2.10.0
      • pylint from 2.4.4 -> 2.5.3

    Fixed

    Source code(tar.gz)
    Source code(zip)
  • 1.2.0(Jan 29, 2020)

    [1.2.0] - 2020-01-29

    Added

    • Possibility to set header to the response directly from the resolver using set_response_headers method.
    from tartiflette_aiohttp import set_response_headers
    
    @Resolver("Query.X")
    async def resolver_x(parent_result, args, ctx, info):
        # do things
        set_response_headers({"Header": "Value", "AnotherHeader": "AnotherValue"})
        return result
    

    Note that this feature uses ContextVar and will only works for python 3.7.1 and later.

    Changed

    • pytest updated to 5.3.4
    • pylint updated to 2.4.4
    Source code(tar.gz)
    Source code(zip)
  • 1.1.1(Oct 15, 2019)

    [1.1.1] - 2019-10-15

    Changed

    • Github actions worflow. There is now only one.
    • xenon updated to 0.7.0
    • pytest updated to 5.2.1
    • pytest-cov updated to 2.8.1
    Source code(tar.gz)
    Source code(zip)
  • 1.1.0(Oct 3, 2019)

    [1.1.0] -- 2019-10-02

    Added

    • ISSUE-55 - Add a new optional context_factory parameter to the register_graphql_handlers function. This parameter can take a coroutine function which will be called on each request with the following signature:
      async def context_factory(
          context: Dict[str, Any], req: "aiohttp.web.Request"
      ) -> Dict[str, Any]:
          """
          Generates a new context.
          :param context: the value filled in through the `executor_context`
          parameter
          :param req: the incoming aiohttp request instance
          :type context: Dict[str, Any]
          :type req: aiohttp.web.Request
          :return: the context for the incoming request
          :rtype: Dict[str, Any]
          """
      

    The aim of this function will be to returns the context which will be forwarded to the Tartiflette engine on the execute or subscribe method.

    Source code(tar.gz)
    Source code(zip)
  • 1.0.0(Sep 12, 2019)

    [1.0.0] -- 2019-09-12

    Changed

    • Bump subscriptions-transport-ws from 0.7.0 to 0.8.3
    • Bump graphiql from 0.12.0 to 0.14.2
    • Update aiohttp requirement from >=3.5.4,<3.6.0 to >=3.5.4,<3.7.0
    • Bump pytest from 5.1.1 to 5.1.2
    • Update tartiflette requirement from >=0.12.0,<0.13.0 to >=0.12.0,<2.0.0 - ISSUE-49 thrown by @aljinovic

    Fixed

    • Fix RuntimeError when subscription connection is reset - ISSUE-50 thrown by @jonypawks
    • Determines the appropriate ws protocol to use depending on current used protocol - ISSUE-20 thrown by @bkcsfi
    Source code(tar.gz)
    Source code(zip)
  • 0.8.5(Sep 5, 2019)

  • 0.8.2(Jul 4, 2019)

  • 0.8.1(Jun 19, 2019)

    [0.8.1] - 2019-06-19

    Fixed

    • Fixed the issue #25 thrown by @arjandepooter

    It was impossible to execute subscription with this piece of code.

    def run():
        app = web.Application()
    
        engine: Engine = create_engine(
           ...
        )
    
        web.run_app(
            register_graphql_handlers(
                app=app,
                engine=engine,
                subscription_ws_endpoint="/ws",
            )
        )
    
    Source code(tar.gz)
    Source code(zip)
  • 0.8.0(Jun 18, 2019)

    [0.8.0] - 2019-06-17

    Changed

    • Bump tartiflette version to <0.12.0,>=0.11.0.
    • Update to the new create_engine API, breaking the way the engine parameter works.

    Before it was possible to do:

    
    from tartiflette import Engine
    
    engine = Engine(sdl)
    
    ctx = {
        'user_service': user_service
    }
    
    web.run_app(
        register_graphql_handlers(
            app=web.Application(),
            engine=engine,
            executor_context=ctx,
            executor_http_endpoint='/graphql',
            executor_http_methods=['POST', 'GET']
        )
    )
    

    Typically you were able to provide your own already initialized Engine Instance. Now the engine is issued by the coroutine returning method create_engine.

    You have 3 choice in order to provide your own Engine :

    Provide a non-awaited create_engine

    
    from tartiflette import create_engine
    
    engine = create_engine(sdl)
    
    ctx = {
        'user_service': user_service
    }
    
    web.run_app(
        register_graphql_handlers(
            app=web.Application(),
            engine=engine,
            executor_context=ctx,
            executor_http_endpoint='/graphql',
            executor_http_methods=['POST', 'GET']
        )
    )
    

    register_graphql_handlers will await that coroutine. (It can be any coroutine that respect the create_engine prototype)

    Provide your own instance of child class of Engine

    
    from tartiflette import Engine
    
    class myEngine(Engine):
        def __init__(self, my, parameters):
            super().__init__()
            self._my = my
            self._parameters = parameters
    
        async def cook(
            self,
            sdl: Union[str, List[str]],
            error_coercer: Callable[[Exception], dict] = None,
            custom_default_resolver: Optional[Callable] = None,
            modules: Optional[Union[str, List[str]]] = None,
            schema_name: str = "default",
        ):
            await super().cook(
                sdl,
                error_coercer,
                custom_default_resolver,
                modules,
                schema_name
            )
            print(self._my, self._parameters)
    
    ctx = {
        'user_service': user_service
    }
    
    web.run_app(
        register_graphql_handlers(
            app=web.Application(),
            engine=myEngine(my, parameters),
            executor_context=ctx,
            executor_http_endpoint='/graphql',
            executor_http_methods=['POST', 'GET']
        )
    )
    

    Provide you instance of an Engine class composed with an Engine

    
    from tartiflette import Engine
    
    class myEngine:
        def __init__(self, my, parameters):
            self._engine = Engine()
            self._my = my
            self._parameters = parameters
    
        async def cook(
            self,
            sdl: Union[str, List[str]],
            error_coercer: Callable[[Exception], dict] = None,
            custom_default_resolver: Optional[Callable] = None,
            modules: Optional[Union[str, List[str]]] = None,
            schema_name: str = "default",
        ):
            print(self._my)
            await self._engine.cook(
                sdl,
                error_coercer,
                custom_default_resolver,
                modules,
                schema_name
            )
            print(self._parameters)
    
        async def execute(
            self,
            query: str,
            operation_name: Optional[str] = None,
            context: Optional[Dict[str, Any]] = None,
            variables: Optional[Dict[str, Any]] = None,
            initial_value: Optional[Any] = None,
        ):
            return await self._engine.execute(
                query,
                operation_name,
                context,
                variables,
                initial_value
            )
    
    ctx = {
        'user_service': user_service
    }
    
    web.run_app(
        register_graphql_handlers(
            app=web.Application(),
            engine=myEngine(my, parameters),
            executor_context=ctx,
            executor_http_endpoint='/graphql',
            executor_http_methods=['POST', 'GET']
        )
    )
    
    Source code(tar.gz)
    Source code(zip)
  • 0.7.0(Jun 3, 2019)

Owner
tartiflette
GraphQL Python Engine built for python 3.6+, by dailymotion
tartiflette
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
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
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
This is a graphql api build using ariadne python that serves a graphql-endpoint at port 3002 to perform language translation and identification using deep learning in python pytorch.

Language Translation and Identification this machine/deep learning api that will be served as a graphql-api using ariadne, to perform the following ta

crispengari 2 Dec 30, 2021
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
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
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
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
graphw00f is Server Engine Fingerprinting utility for software security professionals looking to learn more about what technology is behind a given GraphQL endpoint.

graphw00f - GraphQL Server Fingerprinting graphw00f (inspired by wafw00f) is the GraphQL fingerprinting tool for GQL endpoints. Table of Contents How

Dolev Farhi 282 Jan 4, 2023
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
Integrate GraphQL into your Django project.

Graphene-Django A Django integration for Graphene. ?? Join the community on Slack Documentation Visit the documentation to get started! Quickstart For

GraphQL Python 4k Dec 31, 2022
Django Project with Rest and Graphql API's

Django-Rest-and-Graphql # 1. Django Project Setup With virtual environment: mkdir {project_name}. To install virtual Environment sudo apt-get install

Shubham Agrawal 5 Nov 22, 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
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
Ariadne is a Python library for implementing GraphQL servers using schema-first approach.

Ariadne Ariadne is a Python library for implementing GraphQL servers. Schema-first: Ariadne enables Python developers to use schema-first approach to

Mirumee Labs 1.9k Jan 1, 2023
Adds GraphQL support to your Flask application.

Flask-GraphQL Adds GraphQL support to your Flask application. Usage Just use the GraphQLView view from flask_graphql from flask import Flask from flas

GraphQL Python 1.3k Dec 31, 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