Skip to content

Commit d168946

Browse files
committed
Merge remote-tracking branch 'origin/use-entry-points' into publish-wheel
2 parents ee2858a + f541348 commit d168946

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+367
-160
lines changed

.github/workflows/lint.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414
python-version: 3.8
1515
- name: Install dependencies
1616
run: |
17-
python -m pip install --upgrade pip
17+
python -m pip install --upgrade pip wheel
1818
pip install tox
1919
- name: Run lint and static type checks
2020
run: tox

.github/workflows/tests.yml

+5-5
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ jobs:
3030
python-version: ${{ matrix.python-version }}
3131
- name: Install dependencies
3232
run: |
33-
python -m pip install --upgrade pip
33+
python -m pip install --upgrade pip wheel
3434
pip install tox tox-gh-actions
3535
- name: Test with tox
3636
run: tox
@@ -52,7 +52,7 @@ jobs:
5252
python-version: 3.8
5353
- name: Install dependencies with only ${{ matrix.dependency }} extra dependency
5454
run: |
55-
python -m pip install --upgrade pip
55+
python -m pip install --upgrade pip wheel
5656
pip install .[${{ matrix.dependency }},test_no_transport]
5757
- name: Test with --${{ matrix.dependency }}-only
5858
run: pytest tests --${{ matrix.dependency }}-only
@@ -68,9 +68,9 @@ jobs:
6868
python-version: 3.8
6969
- name: Install test dependencies
7070
run: |
71-
python -m pip install --upgrade pip
72-
pip install .[test]
71+
python -m pip install --upgrade pip wheel
72+
pip install -e.[test]
7373
- name: Test with coverage
74-
run: pytest --cov=gql --cov-report=xml tests
74+
run: pytest --cov=gql --cov-report=xml --cov-report=term-missing tests
7575
- name: Upload coverage to Codecov
7676
uses: codecov/codecov-action@v1

MANIFEST.in

-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ include Makefile
1111

1212
include tox.ini
1313

14-
include scripts/gql-cli
15-
1614
include gql/py.typed
1715

1816
recursive-include tests *.py *.graphql *.cnf *.yaml *.pem

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
.PHONY: clean tests docs
22

3-
SRC_PYTHON := gql tests scripts/gql-cli docs/code_examples
3+
SRC_PYTHON := gql tests docs/code_examples
44

55
dev-setup:
66
python pip install -e ".[test]"

docs/code_examples/aiohttp_async.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ async def main():
1111
# Using `async with` on the client will start a connection on the transport
1212
# and provide a `session` variable to execute queries on this connection
1313
async with Client(
14-
transport=transport, fetch_schema_from_transport=True,
14+
transport=transport,
15+
fetch_schema_from_transport=True,
1516
) as session:
1617

1718
# Execute single query

docs/code_examples/appsync/mutation_api_key.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ async def main():
3131
transport = AIOHTTPTransport(url=url, auth=auth)
3232

3333
async with Client(
34-
transport=transport, fetch_schema_from_transport=False,
34+
transport=transport,
35+
fetch_schema_from_transport=False,
3536
) as session:
3637

3738
query = gql(

docs/code_examples/appsync/mutation_iam.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ async def main():
3030
transport = AIOHTTPTransport(url=url, auth=auth)
3131

3232
async with Client(
33-
transport=transport, fetch_schema_from_transport=False,
33+
transport=transport,
34+
fetch_schema_from_transport=False,
3435
) as session:
3536

3637
query = gql(

docs/code_examples/requests_sync.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
from gql.transport.requests import RequestsHTTPTransport
33

44
transport = RequestsHTTPTransport(
5-
url="https://countries.trevorblades.com/", verify=True, retries=3,
5+
url="https://countries.trevorblades.com/",
6+
verify=True,
7+
retries=3,
68
)
79

810
client = Client(transport=transport, fetch_schema_from_transport=True)

docs/code_examples/requests_sync_dsl.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
from gql.transport.requests import RequestsHTTPTransport
44

55
transport = RequestsHTTPTransport(
6-
url="https://countries.trevorblades.com/", verify=True, retries=3,
6+
url="https://countries.trevorblades.com/",
7+
verify=True,
8+
retries=3,
79
)
810

911
client = Client(transport=transport, fetch_schema_from_transport=True)

docs/code_examples/websockets_async.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ async def main():
1414
# Using `async with` on the client will start a connection on the transport
1515
# and provide a `session` variable to execute queries on this connection
1616
async with Client(
17-
transport=transport, fetch_schema_from_transport=True,
17+
transport=transport,
18+
fetch_schema_from_transport=True,
1819
) as session:
1920

2021
# Execute single query

gql/cli.py

+51-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
import asyncio
12
import json
23
import logging
4+
import signal as signal_module
35
import sys
46
from argparse import ArgumentParser, Namespace, RawDescriptionHelpFormatter
57
from typing import Any, Dict, Optional
@@ -132,11 +134,15 @@ def get_parser(with_examples: bool = False) -> ArgumentParser:
132134
appsync_auth_group = appsync_group.add_mutually_exclusive_group()
133135

134136
appsync_auth_group.add_argument(
135-
"--api-key", help="Provide an API key for authentication", dest="api_key",
137+
"--api-key",
138+
help="Provide an API key for authentication",
139+
dest="api_key",
136140
)
137141

138142
appsync_auth_group.add_argument(
139-
"--jwt", help="Provide an JSON Web token for authentication", dest="jwt",
143+
"--jwt",
144+
help="Provide an JSON Web token for authentication",
145+
dest="jwt",
140146
)
141147

142148
return parser
@@ -403,3 +409,46 @@ async def main(args: Namespace) -> int:
403409
exit_code = 1
404410

405411
return exit_code
412+
413+
414+
def gql_cli() -> None:
415+
"""Synchronously invoke ``main`` with the parsed command line arguments.
416+
417+
Formerly ``scripts/gql-cli``, now registered as an ``entry_point``
418+
"""
419+
# Get arguments from command line
420+
parser = get_parser(with_examples=True)
421+
args = parser.parse_args()
422+
423+
try:
424+
# Create a new asyncio event loop
425+
loop = asyncio.new_event_loop()
426+
asyncio.set_event_loop(loop)
427+
428+
# Create a gql-cli task with the supplied arguments
429+
main_task = asyncio.ensure_future(main(args), loop=loop)
430+
431+
# Add signal handlers to close gql-cli cleanly on Control-C
432+
for signal_name in ["SIGINT", "SIGTERM", "CTRL_C_EVENT", "CTRL_BREAK_EVENT"]:
433+
signal = getattr(signal_module, signal_name, None)
434+
435+
if signal is None:
436+
continue
437+
438+
try:
439+
loop.add_signal_handler(signal, main_task.cancel)
440+
except NotImplementedError: # pragma: no cover
441+
# not all signals supported on all platforms
442+
pass
443+
444+
# Run the asyncio loop to execute the task
445+
exit_code = 0
446+
try:
447+
exit_code = loop.run_until_complete(main_task)
448+
finally:
449+
loop.close()
450+
451+
# Return with the correct exit code
452+
sys.exit(exit_code)
453+
except KeyboardInterrupt: # pragma: no cover
454+
pass

gql/dsl.py

+17-6
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,9 @@ class DSLSelector(ABC):
311311
selection_set: SelectionSetNode
312312

313313
def __init__(
314-
self, *fields: "DSLSelectable", **fields_with_alias: "DSLSelectableWithAlias",
314+
self,
315+
*fields: "DSLSelectable",
316+
**fields_with_alias: "DSLSelectableWithAlias",
315317
):
316318
""":meta private:"""
317319
self.selection_set = SelectionSetNode(selections=())
@@ -326,7 +328,9 @@ def is_valid_field(self, field: "DSLSelectable") -> bool:
326328
) # pragma: no cover
327329

328330
def select(
329-
self, *fields: "DSLSelectable", **fields_with_alias: "DSLSelectableWithAlias",
331+
self,
332+
*fields: "DSLSelectable",
333+
**fields_with_alias: "DSLSelectableWithAlias",
330334
):
331335
r"""Select the fields which should be added.
332336
@@ -387,7 +391,9 @@ def executable_ast(self):
387391
) # pragma: no cover
388392

389393
def __init__(
390-
self, *fields: "DSLSelectable", **fields_with_alias: "DSLSelectableWithAlias",
394+
self,
395+
*fields: "DSLSelectable",
396+
**fields_with_alias: "DSLSelectableWithAlias",
391397
):
392398
r"""Given arguments of type :class:`DSLSelectable` containing GraphQL requests,
393399
generate an operation which can be converted to a Document
@@ -552,7 +558,9 @@ def get_ast_definitions(self) -> Tuple[VariableDefinitionNode, ...]:
552558
"""
553559
return tuple(
554560
VariableDefinitionNode(
555-
type=var.type, variable=var.ast_variable, default_value=None,
561+
type=var.type,
562+
variable=var.ast_variable,
563+
default_value=None,
556564
)
557565
for var in self.variables.values()
558566
if var.type is not None # only variables used
@@ -889,7 +897,9 @@ class DSLInlineFragment(DSLSelectable, DSLFragmentSelector):
889897
ast_field: InlineFragmentNode
890898

891899
def __init__(
892-
self, *fields: "DSLSelectable", **fields_with_alias: "DSLSelectableWithAlias",
900+
self,
901+
*fields: "DSLSelectable",
902+
**fields_with_alias: "DSLSelectableWithAlias",
893903
):
894904
r"""Initialize the DSLInlineFragment.
895905
@@ -944,7 +954,8 @@ class DSLFragment(DSLSelectable, DSLFragmentSelector, DSLExecutable):
944954
name: str
945955

946956
def __init__(
947-
self, name: str,
957+
self,
958+
name: str,
948959
):
949960
r"""Initialize the DSLFragment.
950961

gql/transport/aiohttp.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,8 @@ async def execute(
222222
# If we upload files, we will extract the files present in the
223223
# variable_values dict and replace them by null values
224224
nulled_variable_values, files = extract_files(
225-
variables=variable_values, file_classes=self.file_classes,
225+
variables=variable_values,
226+
file_classes=self.file_classes,
226227
)
227228

228229
# Save the nulled variable values in the payload
@@ -275,7 +276,8 @@ async def execute(
275276
# Add headers for AppSync if requested
276277
if isinstance(self.auth, AppSyncAuthentication):
277278
post_args["headers"] = self.auth.get_headers(
278-
json.dumps(payload), {"content-type": "application/json"},
279+
json.dumps(payload),
280+
{"content-type": "application/json"},
279281
)
280282

281283
if self.session is None:

gql/transport/appsync_websockets.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,12 @@ async def _send_query(
172172
"authorization": self.auth.get_headers(serialized_data)
173173
}
174174

175-
await self._send(json.dumps(message, separators=(",", ":"),))
175+
await self._send(
176+
json.dumps(
177+
message,
178+
separators=(",", ":"),
179+
)
180+
)
176181

177182
return query_id
178183

gql/transport/async_transport.py

+4-6
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,14 @@
77
class AsyncTransport:
88
@abc.abstractmethod
99
async def connect(self):
10-
"""Coroutine used to create a connection to the specified address
11-
"""
10+
"""Coroutine used to create a connection to the specified address"""
1211
raise NotImplementedError(
1312
"Any AsyncTransport subclass must implement connect method"
1413
) # pragma: no cover
1514

1615
@abc.abstractmethod
1716
async def close(self):
18-
"""Coroutine used to Close an established connection
19-
"""
17+
"""Coroutine used to Close an established connection"""
2018
raise NotImplementedError(
2119
"Any AsyncTransport subclass must implement close method"
2220
) # pragma: no cover
@@ -28,8 +26,8 @@ async def execute(
2826
variable_values: Optional[Dict[str, Any]] = None,
2927
operation_name: Optional[str] = None,
3028
) -> ExecutionResult:
31-
"""Execute the provided document AST for either a remote or local GraphQL Schema.
32-
"""
29+
"""Execute the provided document AST for either a remote or local GraphQL
30+
Schema."""
3331
raise NotImplementedError(
3432
"Any AsyncTransport subclass must implement execute method"
3533
) # pragma: no cover

gql/transport/local_schema.py

+13-9
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ class LocalSchemaTransport(AsyncTransport):
1010
"""A transport for executing GraphQL queries against a local schema."""
1111

1212
def __init__(
13-
self, schema: GraphQLSchema,
13+
self,
14+
schema: GraphQLSchema,
1415
):
1516
"""Initialize the transport with the given local schema.
1617
@@ -19,20 +20,20 @@ def __init__(
1920
self.schema = schema
2021

2122
async def connect(self):
22-
"""No connection needed on local transport
23-
"""
23+
"""No connection needed on local transport"""
2424
pass
2525

2626
async def close(self):
27-
"""No close needed on local transport
28-
"""
27+
"""No close needed on local transport"""
2928
pass
3029

3130
async def execute(
32-
self, document: DocumentNode, *args, **kwargs,
31+
self,
32+
document: DocumentNode,
33+
*args,
34+
**kwargs,
3335
) -> ExecutionResult:
34-
"""Execute the provided document AST for on a local GraphQL Schema.
35-
"""
36+
"""Execute the provided document AST for on a local GraphQL Schema."""
3637

3738
result_or_awaitable = execute(self.schema, document, *args, **kwargs)
3839

@@ -48,7 +49,10 @@ async def execute(
4849
return execution_result
4950

5051
async def subscribe(
51-
self, document: DocumentNode, *args, **kwargs,
52+
self,
53+
document: DocumentNode,
54+
*args,
55+
**kwargs,
5256
) -> AsyncGenerator[ExecutionResult, None]:
5357
"""Send a subscription and receive the results using an async generator
5458

gql/transport/requests.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,8 @@ def execute( # type: ignore
155155
# If we upload files, we will extract the files present in the
156156
# variable_values dict and replace them by null values
157157
nulled_variable_values, files = extract_files(
158-
variables=variable_values, file_classes=self.file_classes,
158+
variables=variable_values,
159+
file_classes=self.file_classes,
159160
)
160161

161162
# Save the nulled variable values in the payload

gql/transport/transport.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@ def execute(self, document: DocumentNode, *args, **kwargs) -> ExecutionResult:
1818
) # pragma: no cover
1919

2020
def connect(self):
21-
"""Establish a session with the transport.
22-
"""
21+
"""Establish a session with the transport."""
2322
pass # pragma: no cover
2423

2524
def close(self):

0 commit comments

Comments
 (0)