gpp-client 26.4.1.dev1__tar.gz → 26.5.0.dev1__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.
- gpp_client-26.5.0.dev1/.gitignore +178 -0
- {gpp_client-26.4.1.dev1/src/gpp_client.egg-info → gpp_client-26.5.0.dev1}/PKG-INFO +10 -13
- gpp_client-26.5.0.dev1/graphql/README.md +39 -0
- {gpp_client-26.4.1.dev1 → gpp_client-26.5.0.dev1}/pyproject.toml +29 -19
- gpp_client-26.5.0.dev1/src/gpp_client/__init__.py +47 -0
- {gpp_client-26.4.1.dev1 → gpp_client-26.5.0.dev1}/src/gpp_client/cli/cli.py +45 -37
- gpp_client-26.5.0.dev1/src/gpp_client/cli/commands/__init__.py +23 -0
- gpp_client-26.5.0.dev1/src/gpp_client/cli/commands/attachment.py +97 -0
- gpp_client-26.5.0.dev1/src/gpp_client/cli/commands/goats.py +56 -0
- gpp_client-26.5.0.dev1/src/gpp_client/cli/commands/observation.py +97 -0
- gpp_client-26.5.0.dev1/src/gpp_client/cli/commands/program.py +117 -0
- gpp_client-26.5.0.dev1/src/gpp_client/cli/commands/scheduler.py +52 -0
- gpp_client-26.5.0.dev1/src/gpp_client/cli/commands/site_status.py +37 -0
- gpp_client-26.5.0.dev1/src/gpp_client/cli/commands/target.py +94 -0
- gpp_client-26.5.0.dev1/src/gpp_client/cli/commands/workflow_state.py +61 -0
- {gpp_client-26.4.1.dev1 → gpp_client-26.5.0.dev1}/src/gpp_client/cli/output.py +148 -1
- gpp_client-26.5.0.dev1/src/gpp_client/cli/utils.py +164 -0
- gpp_client-26.5.0.dev1/src/gpp_client/client.py +281 -0
- gpp_client-26.5.0.dev1/src/gpp_client/constants.py +21 -0
- gpp_client-26.5.0.dev1/src/gpp_client/domains/__init__.py +30 -0
- gpp_client-26.5.0.dev1/src/gpp_client/domains/atom.py +46 -0
- {gpp_client-26.4.1.dev1/src/gpp_client/managers → gpp_client-26.5.0.dev1/src/gpp_client/domains}/attachment.py +174 -161
- gpp_client-26.5.0.dev1/src/gpp_client/domains/base.py +162 -0
- gpp_client-26.5.0.dev1/src/gpp_client/domains/goats.py +46 -0
- gpp_client-26.5.0.dev1/src/gpp_client/domains/observation.py +356 -0
- gpp_client-26.5.0.dev1/src/gpp_client/domains/program.py +292 -0
- gpp_client-26.4.1.dev1/src/gpp_client/directors/scheduler/coordinators/program.py → gpp_client-26.5.0.dev1/src/gpp_client/domains/scheduler.py +72 -32
- {gpp_client-26.4.1.dev1/src/gpp_client/managers → gpp_client-26.5.0.dev1/src/gpp_client/domains}/site_status.py +15 -16
- gpp_client-26.5.0.dev1/src/gpp_client/domains/target.py +333 -0
- gpp_client-26.5.0.dev1/src/gpp_client/domains/workflow_state.py +290 -0
- gpp_client-26.5.0.dev1/src/gpp_client/environment.py +49 -0
- {gpp_client-26.4.1.dev1/src/gpp_client/api → gpp_client-26.5.0.dev1/src/gpp_client/generated}/__init__.py +601 -2
- gpp_client-26.5.0.dev1/src/gpp_client/generated/client.py +7335 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/clone_observation.py +24 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/clone_target.py +20 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/create_call_for_proposals.py +26 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/create_observation.py +22 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/create_program.py +20 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/create_target_by_program_id.py +20 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/create_target_by_program_reference.py +24 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/create_target_by_proposal_reference.py +24 -0
- {gpp_client-26.4.1.dev1/src/gpp_client/api → gpp_client-26.5.0.dev1/src/gpp_client/generated}/custom_fields.py +777 -10
- {gpp_client-26.4.1.dev1/src/gpp_client/api → gpp_client-26.5.0.dev1/src/gpp_client/generated}/custom_typing_fields.py +120 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/delete_call_for_proposals_by_id.py +27 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/delete_observation_by_id.py +23 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/delete_observation_by_reference.py +23 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/delete_program_by_id.py +69 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/delete_target_by_id.py +32 -0
- {gpp_client-26.4.1.dev1/src/gpp_client/api → gpp_client-26.5.0.dev1/src/gpp_client/generated}/enums.py +94 -5
- gpp_client-26.5.0.dev1/src/gpp_client/generated/fragments.py +681 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/get_call_for_proposals.py +19 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/get_calls_for_proposals.py +23 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/get_observation.py +15 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/get_observation_attachments_by_id.py +20 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/get_observation_attachments_by_reference.py +20 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/get_observation_workflow_state_by_id.py +25 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/get_observation_workflow_state_by_reference.py +25 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/get_observations.py +21 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/get_program_attachments_by_id.py +20 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/get_program_attachments_by_proposal_reference.py +20 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/get_program_attachments_by_reference.py +20 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/get_program_by_id.py +15 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/get_program_by_proposal_reference.py +15 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/get_program_by_reference.py +15 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/get_programs.py +21 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/get_target_by_id.py +15 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/get_targets.py +21 -0
- {gpp_client-26.4.1.dev1/src/gpp_client/api → gpp_client-26.5.0.dev1/src/gpp_client/generated}/input_types.py +122 -10
- gpp_client-26.5.0.dev1/src/gpp_client/generated/package_environment.py +5 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/ping.py +19 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/restore_call_for_proposals_by_id.py +27 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/restore_observation_by_id.py +23 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/restore_observation_by_reference.py +23 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/restore_program_by_id.py +69 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/restore_target_by_id.py +32 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/set_observation_workflow_state.py +21 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/update_call_for_proposals_by_id.py +27 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/update_calls_for_proposals.py +27 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/update_observation_by_id.py +23 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/update_observation_by_reference.py +23 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/update_observations.py +23 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/update_program_by_id.py +21 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/update_programs.py +21 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/update_target_by_id.py +21 -0
- gpp_client-26.5.0.dev1/src/gpp_client/generated/update_targets.py +21 -0
- gpp_client-26.5.0.dev1/src/gpp_client/rest/__init__.py +7 -0
- gpp_client-26.4.1.dev1/src/gpp_client/rest.py → gpp_client-26.5.0.dev1/src/gpp_client/rest/client.py +30 -38
- gpp_client-26.5.0.dev1/src/gpp_client/rest/utils.py +98 -0
- gpp_client-26.5.0.dev1/src/gpp_client/settings.py +225 -0
- gpp_client-26.5.0.dev1/src/gpp_client/urls.py +57 -0
- gpp_client-26.4.1.dev1/PKG-INFO +0 -100
- gpp_client-26.4.1.dev1/setup.cfg +0 -4
- gpp_client-26.4.1.dev1/src/custom_plugins/__init__.py +0 -3
- gpp_client-26.4.1.dev1/src/custom_plugins/alias_str_wrapper.py +0 -31
- gpp_client-26.4.1.dev1/src/gpp_client/__init__.py +0 -10
- gpp_client-26.4.1.dev1/src/gpp_client/api/_client.py +0 -1636
- gpp_client-26.4.1.dev1/src/gpp_client/cli/__init__.py +0 -3
- gpp_client-26.4.1.dev1/src/gpp_client/cli/commands/attachment.py +0 -230
- gpp_client-26.4.1.dev1/src/gpp_client/cli/commands/call_for_proposals.py +0 -176
- gpp_client-26.4.1.dev1/src/gpp_client/cli/commands/config.py +0 -227
- gpp_client-26.4.1.dev1/src/gpp_client/cli/commands/configuration_request.py +0 -78
- gpp_client-26.4.1.dev1/src/gpp_client/cli/commands/goats.py +0 -53
- gpp_client-26.4.1.dev1/src/gpp_client/cli/commands/group.py +0 -165
- gpp_client-26.4.1.dev1/src/gpp_client/cli/commands/observation.py +0 -264
- gpp_client-26.4.1.dev1/src/gpp_client/cli/commands/program.py +0 -157
- gpp_client-26.4.1.dev1/src/gpp_client/cli/commands/program_note.py +0 -184
- gpp_client-26.4.1.dev1/src/gpp_client/cli/commands/scheduler.py +0 -28
- gpp_client-26.4.1.dev1/src/gpp_client/cli/commands/site_status.py +0 -28
- gpp_client-26.4.1.dev1/src/gpp_client/cli/commands/target.py +0 -199
- gpp_client-26.4.1.dev1/src/gpp_client/cli/commands/workflow_state.py +0 -54
- gpp_client-26.4.1.dev1/src/gpp_client/cli/utils.py +0 -96
- gpp_client-26.4.1.dev1/src/gpp_client/client.py +0 -265
- gpp_client-26.4.1.dev1/src/gpp_client/config/__init__.py +0 -5
- gpp_client-26.4.1.dev1/src/gpp_client/config/config.py +0 -369
- gpp_client-26.4.1.dev1/src/gpp_client/config/defaults.py +0 -60
- gpp_client-26.4.1.dev1/src/gpp_client/config/environment.py +0 -34
- gpp_client-26.4.1.dev1/src/gpp_client/config/models.py +0 -62
- gpp_client-26.4.1.dev1/src/gpp_client/coordinator/__init__.py +0 -3
- gpp_client-26.4.1.dev1/src/gpp_client/coordinator/base.py +0 -17
- gpp_client-26.4.1.dev1/src/gpp_client/credentials/__init__.py +0 -4
- gpp_client-26.4.1.dev1/src/gpp_client/credentials/credential_resolver.py +0 -174
- gpp_client-26.4.1.dev1/src/gpp_client/credentials/env_var_reader.py +0 -63
- gpp_client-26.4.1.dev1/src/gpp_client/director.py +0 -44
- gpp_client-26.4.1.dev1/src/gpp_client/directors/__init__.py +0 -4
- gpp_client-26.4.1.dev1/src/gpp_client/directors/base.py +0 -17
- gpp_client-26.4.1.dev1/src/gpp_client/directors/goats/__init__.py +0 -3
- gpp_client-26.4.1.dev1/src/gpp_client/directors/goats/coordinators/__init__.py +0 -4
- gpp_client-26.4.1.dev1/src/gpp_client/directors/goats/coordinators/observation.py +0 -43
- gpp_client-26.4.1.dev1/src/gpp_client/directors/goats/coordinators/program.py +0 -23
- gpp_client-26.4.1.dev1/src/gpp_client/directors/goats/goats.py +0 -35
- gpp_client-26.4.1.dev1/src/gpp_client/directors/scheduler/__init__.py +0 -3
- gpp_client-26.4.1.dev1/src/gpp_client/directors/scheduler/coordinators/__init__.py +0 -4
- gpp_client-26.4.1.dev1/src/gpp_client/directors/scheduler/coordinators/observation.py +0 -16
- gpp_client-26.4.1.dev1/src/gpp_client/directors/scheduler/coordinators/target.py +0 -14
- gpp_client-26.4.1.dev1/src/gpp_client/directors/scheduler/scheduler.py +0 -31
- gpp_client-26.4.1.dev1/src/gpp_client/managers/__init__.py +0 -23
- gpp_client-26.4.1.dev1/src/gpp_client/managers/atom.py +0 -83
- gpp_client-26.4.1.dev1/src/gpp_client/managers/base.py +0 -447
- gpp_client-26.4.1.dev1/src/gpp_client/managers/call_for_proposals.py +0 -375
- gpp_client-26.4.1.dev1/src/gpp_client/managers/configuration_request.py +0 -199
- gpp_client-26.4.1.dev1/src/gpp_client/managers/group.py +0 -383
- gpp_client-26.4.1.dev1/src/gpp_client/managers/observation.py +0 -764
- gpp_client-26.4.1.dev1/src/gpp_client/managers/program.py +0 -417
- gpp_client-26.4.1.dev1/src/gpp_client/managers/program_note.py +0 -398
- gpp_client-26.4.1.dev1/src/gpp_client/managers/target.py +0 -486
- gpp_client-26.4.1.dev1/src/gpp_client/managers/workflow_state.py +0 -342
- gpp_client-26.4.1.dev1/src/gpp_client/subscribers/__init__.py +0 -5
- gpp_client-26.4.1.dev1/src/gpp_client/subscribers/observation.py +0 -45
- gpp_client-26.4.1.dev1/src/gpp_client/subscribers/program.py +0 -28
- gpp_client-26.4.1.dev1/src/gpp_client/subscribers/target.py +0 -29
- gpp_client-26.4.1.dev1/src/gpp_client.egg-info/SOURCES.txt +0 -96
- gpp_client-26.4.1.dev1/src/gpp_client.egg-info/dependency_links.txt +0 -1
- gpp_client-26.4.1.dev1/src/gpp_client.egg-info/entry_points.txt +0 -2
- gpp_client-26.4.1.dev1/src/gpp_client.egg-info/requires.txt +0 -8
- gpp_client-26.4.1.dev1/src/gpp_client.egg-info/top_level.txt +0 -3
- {gpp_client-26.4.1.dev1 → gpp_client-26.5.0.dev1}/LICENSE +0 -0
- {gpp_client-26.4.1.dev1 → gpp_client-26.5.0.dev1}/README.md +0 -0
- {gpp_client-26.4.1.dev1/src/gpp_client/cli/commands → gpp_client-26.5.0.dev1/src/gpp_client/cli}/__init__.py +0 -0
- {gpp_client-26.4.1.dev1 → gpp_client-26.5.0.dev1}/src/gpp_client/cli/console.py +0 -0
- {gpp_client-26.4.1.dev1 → gpp_client-26.5.0.dev1}/src/gpp_client/exceptions.py +0 -0
- {gpp_client-26.4.1.dev1/src/gpp_client/api → gpp_client-26.5.0.dev1/src/gpp_client/generated}/async_base_client.py +0 -0
- {gpp_client-26.4.1.dev1/src/gpp_client/api → gpp_client-26.5.0.dev1/src/gpp_client/generated}/base_model.py +0 -0
- {gpp_client-26.4.1.dev1/src/gpp_client/api → gpp_client-26.5.0.dev1/src/gpp_client/generated}/base_operation.py +0 -0
- {gpp_client-26.4.1.dev1/src/gpp_client/api → gpp_client-26.5.0.dev1/src/gpp_client/generated}/custom_mutations.py +0 -0
- {gpp_client-26.4.1.dev1/src/gpp_client/api → gpp_client-26.5.0.dev1/src/gpp_client/generated}/custom_queries.py +0 -0
- {gpp_client-26.4.1.dev1/src/gpp_client/api → gpp_client-26.5.0.dev1/src/gpp_client/generated}/exceptions.py +0 -0
- {gpp_client-26.4.1.dev1/src/gpp_client/api → gpp_client-26.5.0.dev1/src/gpp_client/generated}/get_goats_observations.py +0 -0
- {gpp_client-26.4.1.dev1/src/gpp_client/api → gpp_client-26.5.0.dev1/src/gpp_client/generated}/get_goats_programs.py +0 -0
- {gpp_client-26.4.1.dev1/src/gpp_client/api → gpp_client-26.5.0.dev1/src/gpp_client/generated}/get_scheduler_all_programs_id.py +0 -0
- {gpp_client-26.4.1.dev1/src/gpp_client/api → gpp_client-26.5.0.dev1/src/gpp_client/generated}/get_scheduler_programs.py +0 -0
- {gpp_client-26.4.1.dev1/src/gpp_client/api → gpp_client-26.5.0.dev1/src/gpp_client/generated}/obs_calculation_update.py +0 -0
- {gpp_client-26.4.1.dev1/src/gpp_client/api → gpp_client-26.5.0.dev1/src/gpp_client/generated}/observation_edit.py +0 -0
- {gpp_client-26.4.1.dev1/src/gpp_client/api → gpp_client-26.5.0.dev1/src/gpp_client/generated}/program_edit.py +0 -0
- {gpp_client-26.4.1.dev1/src/gpp_client/api → gpp_client-26.5.0.dev1/src/gpp_client/generated}/target_edit.py +0 -0
- {gpp_client-26.4.1.dev1 → gpp_client-26.5.0.dev1}/src/gpp_client/logging_utils.py +0 -0
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
share/python-wheels/
|
|
24
|
+
*.egg-info/
|
|
25
|
+
.installed.cfg
|
|
26
|
+
*.egg
|
|
27
|
+
MANIFEST
|
|
28
|
+
|
|
29
|
+
# PyInstaller
|
|
30
|
+
# Usually these files are written by a python script from a template
|
|
31
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
32
|
+
*.manifest
|
|
33
|
+
*.spec
|
|
34
|
+
|
|
35
|
+
# Installer logs
|
|
36
|
+
pip-log.txt
|
|
37
|
+
pip-delete-this-directory.txt
|
|
38
|
+
|
|
39
|
+
# Unit test / coverage reports
|
|
40
|
+
htmlcov/
|
|
41
|
+
.tox/
|
|
42
|
+
.nox/
|
|
43
|
+
.coverage
|
|
44
|
+
.coverage.*
|
|
45
|
+
.cache
|
|
46
|
+
nosetests.xml
|
|
47
|
+
coverage.xml
|
|
48
|
+
*.cover
|
|
49
|
+
*.py,cover
|
|
50
|
+
.hypothesis/
|
|
51
|
+
.pytest_cache/
|
|
52
|
+
cover/
|
|
53
|
+
|
|
54
|
+
# Translations
|
|
55
|
+
*.mo
|
|
56
|
+
*.pot
|
|
57
|
+
|
|
58
|
+
# Django stuff:
|
|
59
|
+
*.log
|
|
60
|
+
local_settings.py
|
|
61
|
+
db.sqlite3
|
|
62
|
+
db.sqlite3-journal
|
|
63
|
+
|
|
64
|
+
# Flask stuff:
|
|
65
|
+
instance/
|
|
66
|
+
.webassets-cache
|
|
67
|
+
|
|
68
|
+
# Scrapy stuff:
|
|
69
|
+
.scrapy
|
|
70
|
+
|
|
71
|
+
# Sphinx documentation
|
|
72
|
+
docs/_build/
|
|
73
|
+
|
|
74
|
+
# PyBuilder
|
|
75
|
+
.pybuilder/
|
|
76
|
+
|
|
77
|
+
# Jupyter Notebook
|
|
78
|
+
.ipynb_checkpoints
|
|
79
|
+
|
|
80
|
+
# IPython
|
|
81
|
+
profile_default/
|
|
82
|
+
ipython_config.py
|
|
83
|
+
|
|
84
|
+
# pyenv
|
|
85
|
+
# For a library or package, you might want to ignore these files since the code is
|
|
86
|
+
# intended to run in multiple environments; otherwise, check them in:
|
|
87
|
+
# .python-version
|
|
88
|
+
|
|
89
|
+
# pipenv
|
|
90
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
91
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
92
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
93
|
+
# install all needed dependencies.
|
|
94
|
+
#Pipfile.lock
|
|
95
|
+
|
|
96
|
+
# UV
|
|
97
|
+
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
|
|
98
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
99
|
+
# commonly ignored for libraries.
|
|
100
|
+
#uv.lock
|
|
101
|
+
|
|
102
|
+
# poetry
|
|
103
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
|
104
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
|
105
|
+
# commonly ignored for libraries.
|
|
106
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
|
107
|
+
#poetry.lock
|
|
108
|
+
|
|
109
|
+
# pdm
|
|
110
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
|
111
|
+
#pdm.lock
|
|
112
|
+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
|
113
|
+
# in version control.
|
|
114
|
+
# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
|
|
115
|
+
.pdm.toml
|
|
116
|
+
.pdm-python
|
|
117
|
+
.pdm-build/
|
|
118
|
+
|
|
119
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
|
120
|
+
__pypackages__/
|
|
121
|
+
|
|
122
|
+
# Celery stuff
|
|
123
|
+
celerybeat-schedule
|
|
124
|
+
celerybeat.pid
|
|
125
|
+
|
|
126
|
+
# SageMath parsed files
|
|
127
|
+
*.sage.py
|
|
128
|
+
|
|
129
|
+
# Environments
|
|
130
|
+
.env
|
|
131
|
+
.venv
|
|
132
|
+
env/
|
|
133
|
+
venv/
|
|
134
|
+
ENV/
|
|
135
|
+
env.bak/
|
|
136
|
+
venv.bak/
|
|
137
|
+
|
|
138
|
+
# Spyder project settings
|
|
139
|
+
.spyderproject
|
|
140
|
+
.spyproject
|
|
141
|
+
|
|
142
|
+
# Rope project settings
|
|
143
|
+
.ropeproject
|
|
144
|
+
|
|
145
|
+
# mkdocs documentation
|
|
146
|
+
/site
|
|
147
|
+
|
|
148
|
+
# mypy
|
|
149
|
+
.mypy_cache/
|
|
150
|
+
.dmypy.json
|
|
151
|
+
dmypy.json
|
|
152
|
+
|
|
153
|
+
# Pyre type checker
|
|
154
|
+
.pyre/
|
|
155
|
+
|
|
156
|
+
# pytype static type analyzer
|
|
157
|
+
.pytype/
|
|
158
|
+
|
|
159
|
+
# Cython debug symbols
|
|
160
|
+
cython_debug/
|
|
161
|
+
|
|
162
|
+
# PyCharm
|
|
163
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
|
164
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
|
165
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
|
166
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
|
167
|
+
#.idea/
|
|
168
|
+
|
|
169
|
+
# Ruff stuff:
|
|
170
|
+
.ruff_cache/
|
|
171
|
+
|
|
172
|
+
# PyPI configuration file
|
|
173
|
+
.pypirc
|
|
174
|
+
|
|
175
|
+
# macOS files
|
|
176
|
+
*.DS_Store
|
|
177
|
+
|
|
178
|
+
.vscode
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gpp-client
|
|
3
|
-
Version: 26.
|
|
3
|
+
Version: 26.5.0.dev1
|
|
4
4
|
Summary: Gemini Program Platform client.
|
|
5
|
+
Project-URL: Homepage, https://github.com/gemini-hlsw/gpp-client
|
|
6
|
+
Project-URL: Source, https://github.com/gemini-hlsw/gpp-client
|
|
7
|
+
Project-URL: Issues, https://github.com/gemini-hlsw/gpp-client/issues
|
|
8
|
+
Project-URL: Documentation, https://gpp-client.readthedocs.io/en/latest/
|
|
5
9
|
Author: NOIRLab
|
|
6
10
|
License: Copyright (c) 2025 Association of Universities for Research in Astronomy, Inc. (AURA)
|
|
7
11
|
All rights reserved.
|
|
@@ -28,34 +32,27 @@ License: Copyright (c) 2025 Association of Universities for Research in Astronom
|
|
|
28
32
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
29
33
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
|
30
34
|
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
Project-URL: Source, https://github.com/gemini-hlsw/gpp-client
|
|
34
|
-
Project-URL: Issues, https://github.com/gemini-hlsw/gpp-client/issues
|
|
35
|
-
Project-URL: Documentation, https://gpp-client.readthedocs.io/en/latest/
|
|
36
|
-
Keywords: gemini,gpp,client,program,platform
|
|
35
|
+
License-File: LICENSE
|
|
36
|
+
Keywords: client,gemini,gpp,platform,program
|
|
37
37
|
Classifier: Development Status :: 3 - Alpha
|
|
38
38
|
Classifier: Intended Audience :: Science/Research
|
|
39
39
|
Classifier: Operating System :: OS Independent
|
|
40
40
|
Classifier: Programming Language :: Python :: 3
|
|
41
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
42
41
|
Classifier: Programming Language :: Python :: 3.11
|
|
43
42
|
Classifier: Programming Language :: Python :: 3.12
|
|
44
43
|
Classifier: Programming Language :: Python :: 3.13
|
|
45
44
|
Classifier: Programming Language :: Python :: 3.14
|
|
46
45
|
Classifier: Topic :: Scientific/Engineering :: Astronomy
|
|
47
|
-
Requires-Python: >=3.
|
|
48
|
-
Description-Content-Type: text/markdown
|
|
49
|
-
License-File: LICENSE
|
|
46
|
+
Requires-Python: >=3.11.0
|
|
50
47
|
Requires-Dist: aiohttp>=3.13.3
|
|
51
48
|
Requires-Dist: beautifulsoup4>=4.11.0
|
|
52
49
|
Requires-Dist: graphql-core>=3.2.0
|
|
53
50
|
Requires-Dist: httpx>=0.23
|
|
51
|
+
Requires-Dist: pydantic-settings>=2.13.1
|
|
54
52
|
Requires-Dist: pydantic>=2.12.0
|
|
55
|
-
Requires-Dist: toml>=0.10
|
|
56
53
|
Requires-Dist: typer>=0.21.1
|
|
57
54
|
Requires-Dist: websockets>=14.2
|
|
58
|
-
|
|
55
|
+
Description-Content-Type: text/markdown
|
|
59
56
|
|
|
60
57
|
# GPP Client
|
|
61
58
|
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
## GraphQL Operations Structure
|
|
2
|
+
|
|
3
|
+
GraphQL operations are now organized to support both shared and environment-specific behavior.
|
|
4
|
+
|
|
5
|
+
### Directory Layout
|
|
6
|
+
|
|
7
|
+
- `graphql/operations/shared/`
|
|
8
|
+
- Contains all operations and fragments used in both development and production.
|
|
9
|
+
- `graphql/operations/development_only.graphql`
|
|
10
|
+
- Contains operations and fragments that exist only in the development schema.
|
|
11
|
+
|
|
12
|
+
### How It Works
|
|
13
|
+
|
|
14
|
+
- **Production**
|
|
15
|
+
- Uses only the contents of `shared/`.
|
|
16
|
+
|
|
17
|
+
- **Development**
|
|
18
|
+
- Uses `shared/` + `development_only.graphql`.
|
|
19
|
+
|
|
20
|
+
- During code generation, these are assembled into a temporary build directory and passed to `ariadne-codegen`.
|
|
21
|
+
|
|
22
|
+
### Rules
|
|
23
|
+
|
|
24
|
+
- `development_only.graphql` must be **additive only**.
|
|
25
|
+
- No operation or fragment names may collide with anything in `shared/`.
|
|
26
|
+
- Violations will fail code generation.
|
|
27
|
+
|
|
28
|
+
- If `development_only.graphql` is empty or missing, it is ignored.
|
|
29
|
+
|
|
30
|
+
### Guidelines
|
|
31
|
+
|
|
32
|
+
- Put anything stable and supported in both environments into `shared/`.
|
|
33
|
+
- Put experimental, dev-only, or not-yet-released schema usage into `development_only.graphql`.
|
|
34
|
+
- Once a dev-only operation is promoted to production, move it into `shared/` and remove it from `development_only.graphql`.
|
|
35
|
+
|
|
36
|
+
### Notes
|
|
37
|
+
|
|
38
|
+
- The `build/` directory is temporary and is recreated on each codegen run.
|
|
39
|
+
- Generated client code reflects the environment used during codegen.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[build-system]
|
|
2
|
-
requires = ["
|
|
3
|
-
build-backend = "
|
|
2
|
+
requires = ["hatchling", "uv-dynamic-versioning"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "gpp-client"
|
|
@@ -8,13 +8,12 @@ description = "Gemini Program Platform client."
|
|
|
8
8
|
readme = "README.md"
|
|
9
9
|
authors = [{ name = "NOIRLab" }]
|
|
10
10
|
license = { file = "LICENSE" }
|
|
11
|
-
requires-python = ">=3.
|
|
11
|
+
requires-python = ">=3.11.0"
|
|
12
12
|
classifiers = [
|
|
13
13
|
"Development Status :: 3 - Alpha",
|
|
14
14
|
"Intended Audience :: Science/Research",
|
|
15
15
|
"Operating System :: OS Independent",
|
|
16
16
|
"Programming Language :: Python :: 3",
|
|
17
|
-
"Programming Language :: Python :: 3.10",
|
|
18
17
|
"Programming Language :: Python :: 3.11",
|
|
19
18
|
"Programming Language :: Python :: 3.12",
|
|
20
19
|
"Programming Language :: Python :: 3.13",
|
|
@@ -27,15 +26,32 @@ dependencies = [
|
|
|
27
26
|
"graphql-core>=3.2.0",
|
|
28
27
|
"httpx>=0.23",
|
|
29
28
|
"pydantic>=2.12.0",
|
|
30
|
-
"
|
|
29
|
+
"pydantic-settings>=2.13.1",
|
|
31
30
|
"typer>=0.21.1",
|
|
32
31
|
"websockets>=14.2",
|
|
33
32
|
]
|
|
34
|
-
|
|
33
|
+
dynamic = ["version"]
|
|
35
34
|
keywords = ["gemini", "gpp", "client", "program", "platform"]
|
|
36
35
|
|
|
37
|
-
[tool.
|
|
38
|
-
|
|
36
|
+
[tool.hatch.version]
|
|
37
|
+
source = "uv-dynamic-versioning"
|
|
38
|
+
|
|
39
|
+
[tool.uv-dynamic-versioning]
|
|
40
|
+
style = "pep440"
|
|
41
|
+
pattern = '^v(?P<base>\d{2}\.\d{1,2}\.\d+)(?:\.(?P<stage>dev)(?P<revision>\d+))?$'
|
|
42
|
+
strict = true
|
|
43
|
+
metadata = false
|
|
44
|
+
|
|
45
|
+
[tool.hatch.build.targets.wheel]
|
|
46
|
+
packages = ["src/gpp_client"]
|
|
47
|
+
|
|
48
|
+
[tool.hatch.build.targets.sdist]
|
|
49
|
+
include = [
|
|
50
|
+
"src/gpp_client",
|
|
51
|
+
"README.md",
|
|
52
|
+
"LICENSE",
|
|
53
|
+
"pyproject.toml",
|
|
54
|
+
]
|
|
39
55
|
|
|
40
56
|
[project.scripts]
|
|
41
57
|
gpp = "gpp_client.cli.cli:main"
|
|
@@ -50,23 +66,13 @@ docstring-code-line-length = "dynamic"
|
|
|
50
66
|
|
|
51
67
|
[tool.ruff]
|
|
52
68
|
# Ignore generated code.
|
|
53
|
-
extend-exclude = ["
|
|
69
|
+
extend-exclude = ["generated"]
|
|
54
70
|
|
|
55
71
|
[tool.pytest.ini_options]
|
|
56
72
|
testpaths = ["tests"]
|
|
57
73
|
addopts = "-r A -v -n auto"
|
|
58
74
|
asyncio_default_fixture_loop_scope = "session"
|
|
59
75
|
|
|
60
|
-
[tool.ariadne-codegen]
|
|
61
|
-
client_name = "_GPPClient"
|
|
62
|
-
client_file_name = "_client"
|
|
63
|
-
enable_custom_operations = true
|
|
64
|
-
target_package_name = "api"
|
|
65
|
-
target_package_path = "src/gpp_client"
|
|
66
|
-
convert_to_snake_case = true
|
|
67
|
-
plugins = ["custom_plugins.AliasStrWrapperPlugin"]
|
|
68
|
-
queries_path = "src/queries"
|
|
69
|
-
|
|
70
76
|
[tool.numpydoc_validation]
|
|
71
77
|
checks = [
|
|
72
78
|
"all", # All except the rules listed below.
|
|
@@ -104,6 +110,10 @@ docs = [
|
|
|
104
110
|
"sphinx-copybutton>=0.5.2",
|
|
105
111
|
"sphinxcontrib-typer>=0.7.2",
|
|
106
112
|
]
|
|
113
|
+
notebook = [
|
|
114
|
+
"ipykernel>=7.2.0",
|
|
115
|
+
"jupyter>=1.1.1",
|
|
116
|
+
]
|
|
107
117
|
schema = [
|
|
108
118
|
"aiohttp>=3.13.3",
|
|
109
119
|
"gql>=3.5.0,<4.0.0",
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Top-level package for gpp_client.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import importlib.metadata
|
|
6
|
+
from typing import TYPE_CHECKING, Any
|
|
7
|
+
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from .client import GPPClient
|
|
10
|
+
|
|
11
|
+
__all__ = ["GPPClient", "__version__"]
|
|
12
|
+
|
|
13
|
+
_FALLBACK_VERSION = "0.0.0"
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
try:
|
|
17
|
+
__version__ = importlib.metadata.version(__name__)
|
|
18
|
+
except importlib.metadata.PackageNotFoundError:
|
|
19
|
+
# Have fallback version for development environments.
|
|
20
|
+
__version__ = _FALLBACK_VERSION
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def __getattr__(name: str) -> Any:
|
|
24
|
+
"""
|
|
25
|
+
Lazily import top-level package attributes.
|
|
26
|
+
|
|
27
|
+
Parameters
|
|
28
|
+
----------
|
|
29
|
+
name : str
|
|
30
|
+
The attribute name being accessed.
|
|
31
|
+
|
|
32
|
+
Returns
|
|
33
|
+
-------
|
|
34
|
+
Any
|
|
35
|
+
The resolved attribute.
|
|
36
|
+
|
|
37
|
+
Raises
|
|
38
|
+
------
|
|
39
|
+
AttributeError
|
|
40
|
+
If the attribute is not supported.
|
|
41
|
+
"""
|
|
42
|
+
if name == "GPPClient":
|
|
43
|
+
from .client import GPPClient
|
|
44
|
+
|
|
45
|
+
return GPPClient
|
|
46
|
+
|
|
47
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
@@ -4,35 +4,33 @@ CLI entry point for GPP Client.
|
|
|
4
4
|
|
|
5
5
|
__all__ = ["app"]
|
|
6
6
|
|
|
7
|
-
from importlib.metadata import version as get_version
|
|
8
|
-
from typing import Annotated
|
|
9
7
|
from dataclasses import dataclass
|
|
8
|
+
from typing import Annotated
|
|
9
|
+
|
|
10
10
|
import typer
|
|
11
11
|
|
|
12
|
+
from gpp_client import GPPClient, __version__
|
|
12
13
|
from gpp_client.cli import output
|
|
13
14
|
from gpp_client.cli.commands import (
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
program_note,
|
|
23
|
-
scheduler,
|
|
24
|
-
site_status,
|
|
25
|
-
target,
|
|
26
|
-
workflow_state,
|
|
15
|
+
attachment_app,
|
|
16
|
+
goats_app,
|
|
17
|
+
observation_app,
|
|
18
|
+
program_app,
|
|
19
|
+
scheduler_app,
|
|
20
|
+
site_status_app,
|
|
21
|
+
target_app,
|
|
22
|
+
workflow_state_app,
|
|
27
23
|
)
|
|
28
24
|
from gpp_client.cli.utils import async_command
|
|
29
|
-
from gpp_client.
|
|
30
|
-
|
|
31
|
-
__version__ = get_version("gpp-client").strip()
|
|
25
|
+
from gpp_client.settings import get_config_path as _get_config_path
|
|
32
26
|
|
|
33
27
|
|
|
34
28
|
@dataclass(slots=True)
|
|
35
29
|
class CLIState:
|
|
30
|
+
"""
|
|
31
|
+
Shared CLI state.
|
|
32
|
+
"""
|
|
33
|
+
|
|
36
34
|
debug: bool = False
|
|
37
35
|
|
|
38
36
|
|
|
@@ -41,9 +39,17 @@ app = typer.Typer(
|
|
|
41
39
|
)
|
|
42
40
|
|
|
43
41
|
|
|
44
|
-
def version_callback(value: bool):
|
|
42
|
+
def version_callback(value: bool) -> None:
|
|
43
|
+
"""
|
|
44
|
+
Callback to print version and exit.
|
|
45
|
+
|
|
46
|
+
Parameters
|
|
47
|
+
----------
|
|
48
|
+
value : bool
|
|
49
|
+
Whether to print the version and exit.
|
|
50
|
+
"""
|
|
45
51
|
if value:
|
|
46
|
-
|
|
52
|
+
output.info(f"{__version__}")
|
|
47
53
|
raise typer.Exit()
|
|
48
54
|
|
|
49
55
|
|
|
@@ -69,22 +75,6 @@ def main_callback(
|
|
|
69
75
|
):
|
|
70
76
|
"""Main entry point callback for GPP Client CLI."""
|
|
71
77
|
ctx.obj = CLIState(debug=debug)
|
|
72
|
-
pass
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
app.add_typer(config.app)
|
|
76
|
-
app.add_typer(program_note.app)
|
|
77
|
-
app.add_typer(target.app)
|
|
78
|
-
app.add_typer(program.app)
|
|
79
|
-
app.add_typer(call_for_proposals.app)
|
|
80
|
-
app.add_typer(observation.app)
|
|
81
|
-
app.add_typer(site_status.app)
|
|
82
|
-
app.add_typer(group.app)
|
|
83
|
-
app.add_typer(configuration_request.app)
|
|
84
|
-
app.add_typer(workflow_state.app)
|
|
85
|
-
app.add_typer(scheduler.app)
|
|
86
|
-
app.add_typer(goats.app)
|
|
87
|
-
app.add_typer(attachment.app)
|
|
88
78
|
|
|
89
79
|
|
|
90
80
|
@app.command("ping")
|
|
@@ -92,7 +82,7 @@ app.add_typer(attachment.app)
|
|
|
92
82
|
async def ping() -> None:
|
|
93
83
|
"""Ping GPP. Requires valid credentials."""
|
|
94
84
|
client = GPPClient()
|
|
95
|
-
success, error = await client.
|
|
85
|
+
success, error = await client.ping()
|
|
96
86
|
if not success:
|
|
97
87
|
output.fail(f"Failed to reach GPP: {error}")
|
|
98
88
|
raise typer.Exit(code=1)
|
|
@@ -100,6 +90,24 @@ async def ping() -> None:
|
|
|
100
90
|
output.success("GPP is reachable. Credentials are valid.")
|
|
101
91
|
|
|
102
92
|
|
|
93
|
+
@app.command("get-config-path")
|
|
94
|
+
def get_config_path() -> None:
|
|
95
|
+
"""Get the path to the GPP Client configuration file."""
|
|
96
|
+
|
|
97
|
+
config_path = _get_config_path()
|
|
98
|
+
output.info(f"{config_path.resolve()}")
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
app.add_typer(observation_app)
|
|
102
|
+
app.add_typer(program_app)
|
|
103
|
+
app.add_typer(attachment_app)
|
|
104
|
+
app.add_typer(target_app)
|
|
105
|
+
app.add_typer(workflow_state_app)
|
|
106
|
+
app.add_typer(site_status_app)
|
|
107
|
+
app.add_typer(goats_app)
|
|
108
|
+
app.add_typer(scheduler_app)
|
|
109
|
+
|
|
110
|
+
|
|
103
111
|
def main() -> None:
|
|
104
112
|
"""Main entry point for GPP Client CLI."""
|
|
105
113
|
app()
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Commands for the GPP CLI.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from .attachment import attachment_app
|
|
6
|
+
from .goats import goats_app
|
|
7
|
+
from .observation import observation_app
|
|
8
|
+
from .program import program_app
|
|
9
|
+
from .scheduler import scheduler_app
|
|
10
|
+
from .site_status import site_status_app
|
|
11
|
+
from .target import target_app
|
|
12
|
+
from .workflow_state import workflow_state_app
|
|
13
|
+
|
|
14
|
+
__all__ = [
|
|
15
|
+
"observation_app",
|
|
16
|
+
"program_app",
|
|
17
|
+
"attachment_app",
|
|
18
|
+
"target_app",
|
|
19
|
+
"workflow_state_app",
|
|
20
|
+
"site_status_app",
|
|
21
|
+
"goats_app",
|
|
22
|
+
"scheduler_app",
|
|
23
|
+
]
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Attachment CLI commands.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
__all__ = ["attachment_app"]
|
|
6
|
+
|
|
7
|
+
from typing import Annotated
|
|
8
|
+
|
|
9
|
+
import typer
|
|
10
|
+
|
|
11
|
+
from gpp_client.cli import output
|
|
12
|
+
from gpp_client.cli.utils import async_command, require_exactly_one
|
|
13
|
+
from gpp_client.client import GPPClient
|
|
14
|
+
|
|
15
|
+
attachment_app = typer.Typer(
|
|
16
|
+
name="attachment",
|
|
17
|
+
help="Attachment operations.",
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@attachment_app.command("list")
|
|
22
|
+
@async_command
|
|
23
|
+
async def list_attachments(
|
|
24
|
+
observation_id: Annotated[
|
|
25
|
+
str | None,
|
|
26
|
+
typer.Option(
|
|
27
|
+
"--observation-id",
|
|
28
|
+
help="List attachments by observation ID.",
|
|
29
|
+
),
|
|
30
|
+
] = None,
|
|
31
|
+
observation_reference: Annotated[
|
|
32
|
+
str | None,
|
|
33
|
+
typer.Option(
|
|
34
|
+
"--observation-reference",
|
|
35
|
+
help="List attachments by observation reference.",
|
|
36
|
+
),
|
|
37
|
+
] = None,
|
|
38
|
+
program_id: Annotated[
|
|
39
|
+
str | None,
|
|
40
|
+
typer.Option(
|
|
41
|
+
"--program-id",
|
|
42
|
+
help="List attachments by program ID.",
|
|
43
|
+
),
|
|
44
|
+
] = None,
|
|
45
|
+
program_reference: Annotated[
|
|
46
|
+
str | None,
|
|
47
|
+
typer.Option(
|
|
48
|
+
"--program-reference",
|
|
49
|
+
help="List attachments by program reference.",
|
|
50
|
+
),
|
|
51
|
+
] = None,
|
|
52
|
+
proposal_reference: Annotated[
|
|
53
|
+
str | None,
|
|
54
|
+
typer.Option(
|
|
55
|
+
"--proposal-reference",
|
|
56
|
+
help="List attachments by proposal reference.",
|
|
57
|
+
),
|
|
58
|
+
] = None,
|
|
59
|
+
) -> None:
|
|
60
|
+
"""
|
|
61
|
+
List attachments using exactly one selector.
|
|
62
|
+
"""
|
|
63
|
+
selector_name, selector_value = require_exactly_one(
|
|
64
|
+
observation_id=observation_id,
|
|
65
|
+
observation_reference=observation_reference,
|
|
66
|
+
program_id=program_id,
|
|
67
|
+
program_reference=program_reference,
|
|
68
|
+
proposal_reference=proposal_reference,
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
with output.status("Fetching attachments..."):
|
|
72
|
+
async with GPPClient() as client:
|
|
73
|
+
match selector_name:
|
|
74
|
+
case "observation_id":
|
|
75
|
+
result = await client.attachment.get_all_by_observation_id(
|
|
76
|
+
observation_id=selector_value
|
|
77
|
+
)
|
|
78
|
+
case "observation_reference":
|
|
79
|
+
result = await client.attachment.get_all_by_observation_reference(
|
|
80
|
+
observation_reference=selector_value
|
|
81
|
+
)
|
|
82
|
+
case "program_id":
|
|
83
|
+
result = await client.attachment.get_all_by_program_id(
|
|
84
|
+
program_id=selector_value
|
|
85
|
+
)
|
|
86
|
+
case "program_reference":
|
|
87
|
+
result = await client.attachment.get_all_by_program_reference(
|
|
88
|
+
program_reference=selector_value
|
|
89
|
+
)
|
|
90
|
+
case "proposal_reference":
|
|
91
|
+
result = await client.attachment.get_all_by_proposal_reference(
|
|
92
|
+
proposal_reference=selector_value
|
|
93
|
+
)
|
|
94
|
+
case _:
|
|
95
|
+
raise typer.BadParameter(f"Unsupported selector: {selector_name}")
|
|
96
|
+
|
|
97
|
+
output.json_pydantic(result)
|