async def request( self, request: GraphQLRequest, method: str = None, headers: Optional[Dict[str, str]] = None, ) -> GraphQLTransaction: headers = {**self._headers, **request.headers, **(headers or dict())} await self._validate(request=request, headers=headers) method = method or self._method if method == QueryMethod.post: kwargs = dict(data=json.dumps(request.asdict())) elif method == QueryMethod.get: params = request.asdict() for item in params: if isinstance(params[item], bool): params[item] = int(params[item]) if isinstance(params[item], dict): params[item] = str(params[item]) kwargs = dict(params=params) else: raise GraphQLClientException(f"Invalid method ({method}) specified") async with aiohttp.ClientSession( headers={**self._headers, **request.headers, **headers} ) as session: async with session.request(method, self.endpoint, **kwargs) as resp: body = await resp.json() transaction = GraphQLTransaction.create(request=request, json=body) if 200 <= resp.status < 300: return transaction raise GraphQLTransactionException(transaction)
async def _validate( self, request: GraphQLRequest, headers: Optional[Dict[str, str]] = None ): if request.validate: errors = await self.validate(request.query, request.schema, headers=headers) if request.schema is None: request.schema = await self.get_schema(headers=headers) if errors: raise GraphQLClientValidationException(*errors)
async def test_subscription(client, headers, subscription_query, mutation_city, city_name): request = GraphQLRequest(query=subscription_query, headers=headers) callbacks = CallbackRegistry() m = [] def callback(data): assert "city" in data.get("data") m.append(data) if len(m) > 1: city = data.get("data").get("city")[0] assert city.get("name") == city_name s1.cancel() callbacks.register( GraphQLSubscriptionEventType.DATA, lambda event: callback(event.message.payload.json), ) subscription: GraphQLSubscription = await client.subscribe(request, callbacks, headers=headers) s1 = subscription.task asyncio.ensure_future(s1) await asyncio.sleep(0.1) request = GraphQLRequest(query=mutation_city, headers=headers) _ = await client.query(request) try: await asyncio.wait([s1], timeout=1) assert len(m) == 2 except TimeoutError: pytest.fail( "Subscriptions timed out before receiving expected messages")
async def mutation_city(client, headers, city_name): yield f""" mutation {{ insert_city(objects: {{id: 4081, name: "{city_name}", population: 10, country_code: "GRC", district: "Greece"}}) {{ affected_rows }} }} """ delete_mutation = f""" mutation {{ delete_city(where: {{name: {{_eq: "{city_name}"}}}}) {{ affected_rows }} }} """ request = GraphQLRequest(query=delete_mutation) _ = await client.query(request=request, headers=headers)
async def introspect( self, headers: Optional[Dict[str, str]] = None ) -> graphql.GraphQLSchema: """ Introspect the GraphQL endpoint specified for this client and return a `graphql.GraphQLSchema` object specifying the schema associated with this endpoint. :return: GraphQL schema for the configured endpoint """ request = GraphQLRequest( query=graphql.get_introspection_query(descriptions=False), validate=False, headers=headers, ) introspection = await self.query(request) try: return graphql.build_client_schema(introspection=introspection.data) except TypeError: raise GraphQLIntrospectionException( f"Failed to build schema from introspection data: {introspection.errors}" )
async def test_mutation(client, headers, mutation_city, mutation_output): request = GraphQLRequest(query=mutation_city, headers=headers) transaction = await client.query(request) assert transaction.response.data == mutation_output
async def test_invalid_method(client, headers, query_city): request = GraphQLRequest(query=query_city, headers=headers) with pytest.raises(GraphQLClientException): _ = await client.request(method="PUT", request=request)
async def test_invalid_query(client, headers, invalid_query): request = GraphQLRequest(query=invalid_query, headers=headers) with pytest.raises(GraphQLSyntaxError): _ = await client.query(request)
async def test_simple_anonymous_query(client, headers, query_city, query_output): request = GraphQLRequest(query=query_city, headers=headers) transaction = await client.query(request) assert transaction.response.data == query_output