gpp-client 25.5.0a0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. gpp_client-25.5.0a0/LICENSE +25 -0
  2. gpp_client-25.5.0a0/PKG-INFO +175 -0
  3. gpp_client-25.5.0a0/README.md +108 -0
  4. gpp_client-25.5.0a0/pyproject.toml +91 -0
  5. gpp_client-25.5.0a0/setup.cfg +4 -0
  6. gpp_client-25.5.0a0/src/custom_plugins/__init__.py +4 -0
  7. gpp_client-25.5.0a0/src/custom_plugins/alias_str_wrapper.py +31 -0
  8. gpp_client-25.5.0a0/src/custom_plugins/fix_custom_fields_literal.py +107 -0
  9. gpp_client-25.5.0a0/src/gpp_client/__init__.py +3 -0
  10. gpp_client-25.5.0a0/src/gpp_client/api/__init__.py +752 -0
  11. gpp_client-25.5.0a0/src/gpp_client/api/_client.py +109 -0
  12. gpp_client-25.5.0a0/src/gpp_client/api/async_base_client.py +372 -0
  13. gpp_client-25.5.0a0/src/gpp_client/api/base_model.py +29 -0
  14. gpp_client-25.5.0a0/src/gpp_client/api/base_operation.py +158 -0
  15. gpp_client-25.5.0a0/src/gpp_client/api/custom_fields.py +6456 -0
  16. gpp_client-25.5.0a0/src/gpp_client/api/custom_mutations.py +797 -0
  17. gpp_client-25.5.0a0/src/gpp_client/api/custom_queries.py +524 -0
  18. gpp_client-25.5.0a0/src/gpp_client/api/custom_typing_fields.py +1609 -0
  19. gpp_client-25.5.0a0/src/gpp_client/api/enums.py +1110 -0
  20. gpp_client-25.5.0a0/src/gpp_client/api/exceptions.py +85 -0
  21. gpp_client-25.5.0a0/src/gpp_client/api/input_types.py +2415 -0
  22. gpp_client-25.5.0a0/src/gpp_client/cli/__init__.py +0 -0
  23. gpp_client-25.5.0a0/src/gpp_client/cli/cli.py +24 -0
  24. gpp_client-25.5.0a0/src/gpp_client/cli/commands/__init__.py +0 -0
  25. gpp_client-25.5.0a0/src/gpp_client/cli/commands/call_for_proposals.py +176 -0
  26. gpp_client-25.5.0a0/src/gpp_client/cli/commands/config.py +64 -0
  27. gpp_client-25.5.0a0/src/gpp_client/cli/commands/observation.py +234 -0
  28. gpp_client-25.5.0a0/src/gpp_client/cli/commands/program.py +157 -0
  29. gpp_client-25.5.0a0/src/gpp_client/cli/commands/program_note.py +184 -0
  30. gpp_client-25.5.0a0/src/gpp_client/cli/commands/target.py +177 -0
  31. gpp_client-25.5.0a0/src/gpp_client/cli/utils.py +87 -0
  32. gpp_client-25.5.0a0/src/gpp_client/client/__init__.py +3 -0
  33. gpp_client-25.5.0a0/src/gpp_client/client/client.py +158 -0
  34. gpp_client-25.5.0a0/src/gpp_client/config/__init__.py +3 -0
  35. gpp_client-25.5.0a0/src/gpp_client/config/config.py +109 -0
  36. gpp_client-25.5.0a0/src/gpp_client/managers/__init__.py +13 -0
  37. gpp_client-25.5.0a0/src/gpp_client/managers/base_manager.py +22 -0
  38. gpp_client-25.5.0a0/src/gpp_client/managers/call_for_proposals.py +328 -0
  39. gpp_client-25.5.0a0/src/gpp_client/managers/observation.py +416 -0
  40. gpp_client-25.5.0a0/src/gpp_client/managers/program.py +325 -0
  41. gpp_client-25.5.0a0/src/gpp_client/managers/program_note.py +338 -0
  42. gpp_client-25.5.0a0/src/gpp_client/managers/target.py +335 -0
  43. gpp_client-25.5.0a0/src/gpp_client/managers/utils.py +97 -0
  44. gpp_client-25.5.0a0/src/gpp_client/patches/__init__.py +9 -0
  45. gpp_client-25.5.0a0/src/gpp_client/patches/patches.py +78 -0
  46. gpp_client-25.5.0a0/src/gpp_client.egg-info/PKG-INFO +175 -0
  47. gpp_client-25.5.0a0/src/gpp_client.egg-info/SOURCES.txt +49 -0
  48. gpp_client-25.5.0a0/src/gpp_client.egg-info/dependency_links.txt +1 -0
  49. gpp_client-25.5.0a0/src/gpp_client.egg-info/entry_points.txt +2 -0
  50. gpp_client-25.5.0a0/src/gpp_client.egg-info/requires.txt +20 -0
  51. gpp_client-25.5.0a0/src/gpp_client.egg-info/top_level.txt +2 -0
@@ -0,0 +1,25 @@
1
+ Copyright (c) 2025 Association of Universities for Research in Astronomy, Inc. (AURA)
2
+ All rights reserved.
3
+
4
+ Unless otherwise stated, the copyright of this software is owned by AURA.
5
+ Redistribution and use in source and binary forms, with or without modification,
6
+ are permitted provided that the following conditions are met:
7
+
8
+ 1) Redistributions of source code must retain the above copyright notice,
9
+ this list of conditions and the following disclaimer.
10
+ 2) Redistributions in binary form must reproduce the above copyright notice,
11
+ this list of conditions and the following disclaimer in the documentation
12
+ and/or other materials provided with the distribution.
13
+ 3) The names of AURA and its representatives may not be used to endorse or
14
+ promote products derived from this software without specific prior written
15
+ permission.
16
+
17
+ THIS SOFTWARE IS PROVIDED BY AURA "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
18
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
19
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL AURA BE
20
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
22
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
25
+ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,175 @@
1
+ Metadata-Version: 2.4
2
+ Name: gpp-client
3
+ Version: 25.5.0a0
4
+ Summary: Gemini Program Platform client.
5
+ Author: NOIRLab
6
+ License: Copyright (c) 2025 Association of Universities for Research in Astronomy, Inc. (AURA)
7
+ All rights reserved.
8
+
9
+ Unless otherwise stated, the copyright of this software is owned by AURA.
10
+ Redistribution and use in source and binary forms, with or without modification,
11
+ are permitted provided that the following conditions are met:
12
+
13
+ 1) Redistributions of source code must retain the above copyright notice,
14
+ this list of conditions and the following disclaimer.
15
+ 2) Redistributions in binary form must reproduce the above copyright notice,
16
+ this list of conditions and the following disclaimer in the documentation
17
+ and/or other materials provided with the distribution.
18
+ 3) The names of AURA and its representatives may not be used to endorse or
19
+ promote products derived from this software without specific prior written
20
+ permission.
21
+
22
+ THIS SOFTWARE IS PROVIDED BY AURA "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
23
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
24
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL AURA BE
25
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
27
+ GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30
+ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+ Project-URL: Homepage, https://github.com/gemini-hlsw/gpp-client
32
+ Project-URL: Source, https://github.com/gemini-hlsw/gpp-client
33
+ Project-URL: Issues, https://github.com/gemini-hlsw/gpp-client/issues
34
+ Project-URL: Documentation, https://gpp-client.readthedocs.io/en/latest/
35
+ Keywords: gemini,gpp,client,program,platform
36
+ Classifier: Development Status :: 3 - Alpha
37
+ Classifier: Intended Audience :: Science/Research
38
+ Classifier: Operating System :: OS Independent
39
+ Classifier: Programming Language :: Python :: 3
40
+ Classifier: Programming Language :: Python :: 3.10
41
+ Classifier: Programming Language :: Python :: 3.11
42
+ Classifier: Programming Language :: Python :: 3.12
43
+ Classifier: Programming Language :: Python :: 3.13
44
+ Classifier: Topic :: Scientific/Engineering :: Astronomy
45
+ Requires-Python: >=3.10.0
46
+ Description-Content-Type: text/markdown
47
+ License-File: LICENSE
48
+ Requires-Dist: toml>=0.10.2
49
+ Requires-Dist: typer>=0.15.3
50
+ Requires-Dist: ariadne-codegen[subscriptions]>=0.14.0
51
+ Requires-Dist: click<8.2.0,>=8.0.0
52
+ Provides-Extra: test
53
+ Requires-Dist: pytest; extra == "test"
54
+ Requires-Dist: pytest-xdist; extra == "test"
55
+ Requires-Dist: pytest-cov; extra == "test"
56
+ Requires-Dist: pytest-asyncio; extra == "test"
57
+ Requires-Dist: pytest-remotedata; extra == "test"
58
+ Requires-Dist: pytest-mock; extra == "test"
59
+ Requires-Dist: ruff; extra == "test"
60
+ Provides-Extra: docs
61
+ Requires-Dist: sphinx; extra == "docs"
62
+ Requires-Dist: sphinx-rtd-theme; extra == "docs"
63
+ Requires-Dist: sphinx-autobuild; extra == "docs"
64
+ Requires-Dist: furo; extra == "docs"
65
+ Requires-Dist: sphinxcontrib-typer; extra == "docs"
66
+ Dynamic: license-file
67
+
68
+ # GPP Client
69
+
70
+ [![Run Tests](https://github.com/gemini-hlsw/gpp-client/actions/workflows/run_tests.yaml/badge.svg?branch=main)](https://github.com/gemini-hlsw/gpp-client/actions/workflows/run_tests.yaml)
71
+ ![Docs Status](https://readthedocs.org/projects/gpp-client/badge/?version=latest)
72
+
73
+ ---
74
+
75
+ _Pain-free python/CLI communication with the Gemini Program Platform (GPP)._
76
+
77
+ **Documentation**: <a href="https://gpp-client.readthedocs.io/en/latest/" target="_blank">https://gpp-client.readthedocs.io/en/latest/</a>
78
+
79
+ **Source Code**: <a href="https://github.com/gemini-hlsw/gpp-client" target="_blank">https://github.com/gemini-hlsw/gpp-client</a>
80
+
81
+ ---
82
+
83
+ Python client and CLI for the GPP. Key features:
84
+
85
+ - **Type‑safe GraphQL**
86
+ - Pydantic models from the GPP GraphQL schema, so every query, mutation, and input type is validated.
87
+ - **Resource Managers**
88
+ - High‑level `Manager` classes (e.g. `GPPClient.program`, `GPPClient.observation`) with convenient `get_by_id`, `get_all`, `create`, `update_by_id`, `delete_by_id`, `restore_by_id` and more methods, no need to write raw GraphQL.
89
+ - **Flexible payloads**
90
+ - Create or update via in‑memory Pydantic inputs **or** `from_json` files.
91
+ - **`gpp` CLI**
92
+ - Full CRUD surface on the command line: `gpp <resource> list|get|create|update|delete`, with rich table output and JSON export options.
93
+
94
+ ### Requirements
95
+
96
+ - `python>=3.10`
97
+ - `toml`
98
+ - `typer`
99
+ - `ariadne-codegen`
100
+
101
+ ## Development Status
102
+
103
+ 🚧 Alpha: the library is under heavy development. The public API and CLI flags may change between releases.
104
+
105
+ ## Installation
106
+
107
+ ```bash
108
+ pip install gpp-client
109
+ ```
110
+
111
+ ## Quickstart
112
+
113
+ ```python
114
+ from gpp_client import GPPClient
115
+
116
+ # Initialize with your GraphQL endpoint and credentials.
117
+ client = GPPClient(url="YOUR_URL", token="YOUR_TOKEN")
118
+
119
+ # List the first 5 program notes.
120
+ notes = await client.program_note.get_all(limit=5)
121
+ for note in notes["matches"]:
122
+ print(f"{note['id']}: {note['title']}")
123
+
124
+ # Create a new note from a JSON file.
125
+ new_note = await client.program_note.create(
126
+ from_json="path/to/program_note_payload.json",
127
+ program_id="p-123"
128
+ )
129
+ print("Created:", new_note)
130
+
131
+ # Or create a note from the pydantic model.
132
+ from gpp_client.api.enums import Existence
133
+ from gpp_client.api.input_types import ProgramNotePropertiesInput
134
+
135
+ properties = ProgramNotePropertiesInput(
136
+ title="Example",
137
+ text="This is an example.",
138
+ is_private=False,
139
+ existence=Existence.PRESENT
140
+ )
141
+ another_note = await client.program_note.create(properties=properties, program_id="p-123")
142
+
143
+ print("Created another:", another_note)
144
+ ```
145
+
146
+ ## As a CLI
147
+
148
+ ```bash
149
+ # Get help.
150
+ gpp --help
151
+
152
+ # Get observation help.
153
+ gpp obs --help
154
+
155
+ # List observations.
156
+ gpp obs list --limit 3
157
+
158
+ # Get details for one.
159
+ gpp obs get o-123
160
+
161
+ # Create via JSON.
162
+ gpp obs create --from-json new_obs.json --program-id p-123
163
+
164
+ # Update by ID via JSON.
165
+ gpp obs update --observation-id o-123 --from-json updated_obs.json
166
+ ```
167
+
168
+ ## Reporting Bugs and Feature Requests
169
+
170
+ **Jira**: https://noirlab.atlassian.net/jira/software/projects/GPC/boards/162
171
+
172
+ **NOIRLab Slack channel**: `#gpp-client`
173
+
174
+ While in heavy development, please file requests or report bugs via our Jira board or Slack channel.
175
+
@@ -0,0 +1,108 @@
1
+ # GPP Client
2
+
3
+ [![Run Tests](https://github.com/gemini-hlsw/gpp-client/actions/workflows/run_tests.yaml/badge.svg?branch=main)](https://github.com/gemini-hlsw/gpp-client/actions/workflows/run_tests.yaml)
4
+ ![Docs Status](https://readthedocs.org/projects/gpp-client/badge/?version=latest)
5
+
6
+ ---
7
+
8
+ _Pain-free python/CLI communication with the Gemini Program Platform (GPP)._
9
+
10
+ **Documentation**: <a href="https://gpp-client.readthedocs.io/en/latest/" target="_blank">https://gpp-client.readthedocs.io/en/latest/</a>
11
+
12
+ **Source Code**: <a href="https://github.com/gemini-hlsw/gpp-client" target="_blank">https://github.com/gemini-hlsw/gpp-client</a>
13
+
14
+ ---
15
+
16
+ Python client and CLI for the GPP. Key features:
17
+
18
+ - **Type‑safe GraphQL**
19
+ - Pydantic models from the GPP GraphQL schema, so every query, mutation, and input type is validated.
20
+ - **Resource Managers**
21
+ - High‑level `Manager` classes (e.g. `GPPClient.program`, `GPPClient.observation`) with convenient `get_by_id`, `get_all`, `create`, `update_by_id`, `delete_by_id`, `restore_by_id` and more methods, no need to write raw GraphQL.
22
+ - **Flexible payloads**
23
+ - Create or update via in‑memory Pydantic inputs **or** `from_json` files.
24
+ - **`gpp` CLI**
25
+ - Full CRUD surface on the command line: `gpp <resource> list|get|create|update|delete`, with rich table output and JSON export options.
26
+
27
+ ### Requirements
28
+
29
+ - `python>=3.10`
30
+ - `toml`
31
+ - `typer`
32
+ - `ariadne-codegen`
33
+
34
+ ## Development Status
35
+
36
+ 🚧 Alpha: the library is under heavy development. The public API and CLI flags may change between releases.
37
+
38
+ ## Installation
39
+
40
+ ```bash
41
+ pip install gpp-client
42
+ ```
43
+
44
+ ## Quickstart
45
+
46
+ ```python
47
+ from gpp_client import GPPClient
48
+
49
+ # Initialize with your GraphQL endpoint and credentials.
50
+ client = GPPClient(url="YOUR_URL", token="YOUR_TOKEN")
51
+
52
+ # List the first 5 program notes.
53
+ notes = await client.program_note.get_all(limit=5)
54
+ for note in notes["matches"]:
55
+ print(f"{note['id']}: {note['title']}")
56
+
57
+ # Create a new note from a JSON file.
58
+ new_note = await client.program_note.create(
59
+ from_json="path/to/program_note_payload.json",
60
+ program_id="p-123"
61
+ )
62
+ print("Created:", new_note)
63
+
64
+ # Or create a note from the pydantic model.
65
+ from gpp_client.api.enums import Existence
66
+ from gpp_client.api.input_types import ProgramNotePropertiesInput
67
+
68
+ properties = ProgramNotePropertiesInput(
69
+ title="Example",
70
+ text="This is an example.",
71
+ is_private=False,
72
+ existence=Existence.PRESENT
73
+ )
74
+ another_note = await client.program_note.create(properties=properties, program_id="p-123")
75
+
76
+ print("Created another:", another_note)
77
+ ```
78
+
79
+ ## As a CLI
80
+
81
+ ```bash
82
+ # Get help.
83
+ gpp --help
84
+
85
+ # Get observation help.
86
+ gpp obs --help
87
+
88
+ # List observations.
89
+ gpp obs list --limit 3
90
+
91
+ # Get details for one.
92
+ gpp obs get o-123
93
+
94
+ # Create via JSON.
95
+ gpp obs create --from-json new_obs.json --program-id p-123
96
+
97
+ # Update by ID via JSON.
98
+ gpp obs update --observation-id o-123 --from-json updated_obs.json
99
+ ```
100
+
101
+ ## Reporting Bugs and Feature Requests
102
+
103
+ **Jira**: https://noirlab.atlassian.net/jira/software/projects/GPC/boards/162
104
+
105
+ **NOIRLab Slack channel**: `#gpp-client`
106
+
107
+ While in heavy development, please file requests or report bugs via our Jira board or Slack channel.
108
+
@@ -0,0 +1,91 @@
1
+ [build-system]
2
+ requires = ["setuptools"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "gpp-client"
7
+ description = "Gemini Program Platform client."
8
+ readme = "README.md"
9
+ authors = [{ name = "NOIRLab" }]
10
+ license = { file = "LICENSE" }
11
+ requires-python = ">=3.10.0"
12
+ classifiers = [
13
+ "Development Status :: 3 - Alpha",
14
+ "Intended Audience :: Science/Research",
15
+ "Operating System :: OS Independent",
16
+ "Programming Language :: Python :: 3",
17
+ "Programming Language :: Python :: 3.10",
18
+ "Programming Language :: Python :: 3.11",
19
+ "Programming Language :: Python :: 3.12",
20
+ "Programming Language :: Python :: 3.13",
21
+ "Topic :: Scientific/Engineering :: Astronomy",
22
+ ]
23
+ dependencies = [
24
+ "toml>=0.10.2",
25
+ "typer>=0.15.3",
26
+ "ariadne-codegen[subscriptions]>=0.14.0",
27
+ "click>=8.0.0,<8.2.0",
28
+ ]
29
+ version = "25.05.0a0"
30
+ keywords = ["gemini", "gpp", "client", "program", "platform"]
31
+
32
+ [tool.setuptools.packages.find]
33
+ where = ["src"]
34
+
35
+ [project.optional-dependencies]
36
+ test = [
37
+ "pytest",
38
+ "pytest-xdist",
39
+ "pytest-cov",
40
+ "pytest-asyncio",
41
+ "pytest-remotedata",
42
+ "pytest-mock",
43
+ "ruff",
44
+ ]
45
+ docs = [
46
+ "sphinx",
47
+ "sphinx-rtd-theme",
48
+ "sphinx-autobuild",
49
+ "furo",
50
+ "sphinxcontrib-typer",
51
+ ]
52
+
53
+ [project.scripts]
54
+ gpp = "gpp_client.cli.cli:main"
55
+
56
+ [tool.ruff.format]
57
+ quote-style = "double"
58
+ indent-style = "space"
59
+ skip-magic-trailing-comma = false
60
+ line-ending = "auto"
61
+ docstring-code-format = true
62
+ docstring-code-line-length = "dynamic"
63
+
64
+ [tool.ruff]
65
+ # Ignore generated code.
66
+ extend-exclude = ["api"]
67
+
68
+ [tool.pytest.ini_options]
69
+ testpaths = ["tests"]
70
+ # addopts = "-r A -v -n auto --cov=src --cov-report=term --cov=tests --cov-branch"
71
+ addopts = ["--import-mode=importlib", "-rs"]
72
+ asyncio_default_fixture_loop_scope = "session"
73
+
74
+ [tool.ariadne-codegen]
75
+ schema_path = "schema.graphql"
76
+ client_name = "_GPPClient"
77
+ client_file_name = "_client"
78
+ enable_custom_operations = true
79
+ target_package_name = "api"
80
+ target_package_path = "src/gpp_client"
81
+ convert_to_snake_case = true
82
+ plugins = [
83
+ "custom_plugins.AliasStrWrapperPlugin",
84
+ "custom_plugins.FixCustomFieldsLiteralPlugin",
85
+ ]
86
+
87
+ [project.urls]
88
+ Homepage = "https://github.com/gemini-hlsw/gpp-client"
89
+ Source = "https://github.com/gemini-hlsw/gpp-client"
90
+ Issues = "https://github.com/gemini-hlsw/gpp-client/issues"
91
+ Documentation = "https://gpp-client.readthedocs.io/en/latest/"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,4 @@
1
+ from .alias_str_wrapper import AliasStrWrapperPlugin
2
+ from .fix_custom_fields_literal import FixCustomFieldsLiteralPlugin
3
+
4
+ __all__ = ["AliasStrWrapperPlugin", "FixCustomFieldsLiteralPlugin"]
@@ -0,0 +1,31 @@
1
+ __all__ = ["AliasStrWrapperPlugin"]
2
+
3
+ import ast
4
+
5
+ from ariadne_codegen.plugins.base import Plugin
6
+ from graphql import (
7
+ GraphQLInputField,
8
+ )
9
+
10
+
11
+ class AliasStrWrapperPlugin(Plugin):
12
+ def generate_input_field(
13
+ self,
14
+ field_implementation: ast.AnnAssign,
15
+ input_field: GraphQLInputField,
16
+ field_name: str,
17
+ ) -> ast.AnnAssign:
18
+ """Wraps alias value in str() for VSCode/Pyright compatibility.
19
+ Changes: alias="fooBar" to alias=str("fooBar")
20
+ """
21
+ # Check if the field has a keyword with alias=
22
+ if isinstance(field_implementation.value, ast.Call):
23
+ for keyword in field_implementation.value.keywords:
24
+ if keyword.arg == "alias" and isinstance(keyword.value, ast.Constant):
25
+ # Wrap alias value in str()
26
+ keyword.value = ast.Call(
27
+ func=ast.Name(id="str", ctx=ast.Load()),
28
+ args=[keyword.value],
29
+ keywords=[],
30
+ )
31
+ return field_implementation
@@ -0,0 +1,107 @@
1
+ __all__ = ["FixCustomFieldsLiteralPlugin"]
2
+
3
+ import ast
4
+ from typing import Any, Dict, List, Optional, cast
5
+
6
+ from ariadne_codegen.client_generators import custom_fields as _cf
7
+ from ariadne_codegen.plugins.base import Plugin
8
+
9
+
10
+ class FixCustomFieldsLiteralPlugin(Plugin):
11
+ """Patch CustomFieldsGenerator so GraphQL literals keep camelCase.
12
+
13
+ References
14
+ ----------
15
+ .. [1] *ariadne-codegen* source file:
16
+ https://github.com/mirumee/ariadne-codegen/blob/main/ariadne_codegen/client_generators/custom_fields.py
17
+ .. [2] Pull request that introduces the fix:
18
+ https://github.com/mirumee/ariadne-codegen/pull/326
19
+ """
20
+
21
+ def __init__(self, *args, **kwargs) -> None:
22
+ super().__init__(*args, **kwargs)
23
+
24
+ self._patch__generate_class_field()
25
+ self._patch_generate_product_type_method()
26
+
27
+ @staticmethod
28
+ def _patch__generate_class_field() -> None:
29
+ original = _cf.CustomFieldsGenerator._generate_class_field
30
+
31
+ def patched(
32
+ self,
33
+ name: str,
34
+ field_name: str,
35
+ org_name: str,
36
+ field: ast.ClassDef,
37
+ method_required: bool,
38
+ lineno: int,
39
+ ):
40
+ """Handles the generation of field types."""
41
+ if getattr(field, "args") or method_required:
42
+ return self.generate_product_type_method(
43
+ name, org_name, field_name, getattr(field, "args")
44
+ )
45
+ # Fallback to original behaviour (scalar fields, no args).
46
+ return original(
47
+ self,
48
+ name,
49
+ field_name,
50
+ org_name,
51
+ field,
52
+ method_required,
53
+ lineno,
54
+ )
55
+
56
+ _cf.CustomFieldsGenerator._generate_class_field = patched # type: ignore[attr-defined]
57
+
58
+ @staticmethod
59
+ def _patch_generate_product_type_method() -> None:
60
+ def patched(
61
+ self: _cf.CustomFieldsGenerator,
62
+ name: str,
63
+ org_name: str,
64
+ class_name: str,
65
+ arguments: Optional[Dict[str, Any]] = None,
66
+ ):
67
+ """Generates a method for a product type."""
68
+ arguments = arguments or {}
69
+ field_class_name = _cf.generate_name(class_name)
70
+ (
71
+ method_arguments,
72
+ return_arguments_keys,
73
+ return_arguments_values,
74
+ ) = self.argument_generator.generate_arguments(arguments)
75
+ self._imports.extend(self.argument_generator.imports)
76
+ arguments_body: List[ast.stmt] = []
77
+ arguments_keyword: List[ast.keyword] = []
78
+
79
+ if arguments:
80
+ (
81
+ arguments_body,
82
+ arguments_keyword,
83
+ ) = self.argument_generator.generate_clear_arguments_section(
84
+ return_arguments_keys, return_arguments_values
85
+ )
86
+
87
+ return _cf.generate_method_definition(
88
+ name,
89
+ arguments=method_arguments,
90
+ body=cast(
91
+ List[ast.stmt],
92
+ [
93
+ *arguments_body,
94
+ _cf.generate_return(
95
+ value=_cf.generate_call(
96
+ func=field_class_name,
97
+ args=[_cf.generate_constant(org_name)],
98
+ keywords=arguments_keyword,
99
+ )
100
+ ),
101
+ ],
102
+ ),
103
+ return_type=_cf.generate_name(f'"{class_name}"'),
104
+ decorator_list=[_cf.generate_name("classmethod")],
105
+ )
106
+
107
+ _cf.CustomFieldsGenerator.generate_product_type_method = patched # type: ignore[attr-defined]
@@ -0,0 +1,3 @@
1
+ from .client import GPPClient
2
+
3
+ __all__ = ["GPPClient"]