|
3 | 3 | import logging
|
4 | 4 | import signal as signal_module
|
5 | 5 | import sys
|
6 |
| -from argparse import ArgumentParser, Namespace, RawDescriptionHelpFormatter |
| 6 | +import textwrap |
| 7 | +from argparse import ArgumentParser, Namespace, RawTextHelpFormatter |
7 | 8 | from typing import Any, Dict, Optional
|
8 | 9 |
|
9 | 10 | from graphql import GraphQLError, print_schema
|
@@ -78,7 +79,7 @@ def get_parser(with_examples: bool = False) -> ArgumentParser:
|
78 | 79 | parser = ArgumentParser(
|
79 | 80 | description=description,
|
80 | 81 | epilog=examples if with_examples else None,
|
81 |
| - formatter_class=RawDescriptionHelpFormatter, |
| 82 | + formatter_class=RawTextHelpFormatter, |
82 | 83 | )
|
83 | 84 | parser.add_argument(
|
84 | 85 | "server", help="the server url starting with http://, https://, ws:// or wss://"
|
@@ -122,6 +123,27 @@ def get_parser(with_examples: bool = False) -> ArgumentParser:
|
122 | 123 | action="store_true",
|
123 | 124 | dest="print_schema",
|
124 | 125 | )
|
| 126 | + parser.add_argument( |
| 127 | + "--schema-download", |
| 128 | + nargs="*", |
| 129 | + help=textwrap.dedent( |
| 130 | + """select the introspection query arguments to download the schema. |
| 131 | + Only useful if --print-schema is used. |
| 132 | + By default, it will: |
| 133 | +
|
| 134 | + - request field descriptions |
| 135 | + - not request deprecated input fields |
| 136 | +
|
| 137 | + Possible options: |
| 138 | +
|
| 139 | + - descriptions:false for a compact schema without comments |
| 140 | + - input_value_deprecation:true to download deprecated input fields |
| 141 | + - specified_by_url:true |
| 142 | + - schema_description:true |
| 143 | + - directive_is_repeatable:true""" |
| 144 | + ), |
| 145 | + dest="schema_download", |
| 146 | + ) |
125 | 147 | parser.add_argument(
|
126 | 148 | "--execute-timeout",
|
127 | 149 | help="set the execute_timeout argument of the Client (default: 10)",
|
@@ -362,6 +384,42 @@ def get_transport(args: Namespace) -> Optional[AsyncTransport]:
|
362 | 384 | return None
|
363 | 385 |
|
364 | 386 |
|
| 387 | +def get_introspection_args(args: Namespace) -> Dict: |
| 388 | + """Get the introspection args depending on the schema_download argument""" |
| 389 | + |
| 390 | + # Parse the headers argument |
| 391 | + introspection_args = {} |
| 392 | + |
| 393 | + possible_args = [ |
| 394 | + "descriptions", |
| 395 | + "specified_by_url", |
| 396 | + "directive_is_repeatable", |
| 397 | + "schema_description", |
| 398 | + "input_value_deprecation", |
| 399 | + ] |
| 400 | + |
| 401 | + if args.schema_download is not None: |
| 402 | + for arg in args.schema_download: |
| 403 | + |
| 404 | + try: |
| 405 | + # Split only the first colon (throw a ValueError if no colon is present) |
| 406 | + arg_key, arg_value = arg.split(":", 1) |
| 407 | + |
| 408 | + if arg_key not in possible_args: |
| 409 | + raise ValueError(f"Invalid schema_download: {args.schema_download}") |
| 410 | + |
| 411 | + arg_value = arg_value.lower() |
| 412 | + if arg_value not in ["true", "false"]: |
| 413 | + raise ValueError(f"Invalid schema_download: {args.schema_download}") |
| 414 | + |
| 415 | + introspection_args[arg_key] = arg_value == "true" |
| 416 | + |
| 417 | + except ValueError: |
| 418 | + raise ValueError(f"Invalid schema_download: {args.schema_download}") |
| 419 | + |
| 420 | + return introspection_args |
| 421 | + |
| 422 | + |
365 | 423 | async def main(args: Namespace) -> int:
|
366 | 424 | """Main entrypoint of the gql-cli script
|
367 | 425 |
|
@@ -395,6 +453,7 @@ async def main(args: Namespace) -> int:
|
395 | 453 | async with Client(
|
396 | 454 | transport=transport,
|
397 | 455 | fetch_schema_from_transport=args.print_schema,
|
| 456 | + introspection_args=get_introspection_args(args), |
398 | 457 | execute_timeout=args.execute_timeout,
|
399 | 458 | ) as session:
|
400 | 459 |
|
|
0 commit comments