gpp-client 26.7.3__tar.gz → 26.7.3.dev2__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.7.3 → gpp_client-26.7.3.dev2}/PKG-INFO +1 -1
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/domains/scheduler.py +31 -1
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/package_environment.py +1 -1
- gpp_client-26.7.3.dev2/src/gpp_client/rest/__init__.py +8 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/rest/client.py +57 -1
- gpp_client-26.7.3.dev2/src/gpp_client/rest/models.py +89 -0
- gpp_client-26.7.3/src/gpp_client/rest/__init__.py +0 -7
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/.gitignore +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/LICENSE +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/README.md +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/graphql/README.md +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/pyproject.toml +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/__init__.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/cli/__init__.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/cli/cli.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/cli/commands/__init__.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/cli/commands/attachment.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/cli/commands/goats.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/cli/commands/observation.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/cli/commands/program.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/cli/commands/scheduler.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/cli/commands/site_status.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/cli/commands/target.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/cli/commands/workflow_state.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/cli/console.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/cli/output.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/cli/utils.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/client.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/constants.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/domains/__init__.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/domains/atom.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/domains/attachment.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/domains/base.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/domains/goats.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/domains/observation.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/domains/program.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/domains/site_status.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/domains/target.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/domains/workflow_state.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/environment.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/exceptions.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/__init__.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/async_base_client.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/base_model.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/base_operation.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/client.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/clone_observation.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/clone_target.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/create_call_for_proposals.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/create_observation.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/create_program.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/create_target_by_program_id.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/create_target_by_program_reference.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/create_target_by_proposal_reference.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/custom_fields.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/custom_mutations.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/custom_queries.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/custom_typing_fields.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/delete_call_for_proposals_by_id.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/delete_observation_by_id.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/delete_observation_by_reference.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/delete_program_by_id.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/delete_target_by_id.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/enums.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/exceptions.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/fragments.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/get_call_for_proposals.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/get_calls_for_proposals.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/get_goats_observations.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/get_goats_programs.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/get_observation.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/get_observation_attachments_by_id.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/get_observation_attachments_by_reference.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/get_observation_workflow_state_by_id.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/get_observation_workflow_state_by_reference.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/get_observations.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/get_program_attachments_by_id.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/get_program_attachments_by_proposal_reference.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/get_program_attachments_by_reference.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/get_program_by_id.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/get_program_by_proposal_reference.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/get_program_by_reference.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/get_programs.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/get_scheduler_all_programs_id.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/get_scheduler_programs.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/get_target_by_id.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/get_targets.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/input_types.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/obs_calculation_update.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/observation_edit.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/ping.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/program_edit.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/restore_call_for_proposals_by_id.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/restore_observation_by_id.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/restore_observation_by_reference.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/restore_program_by_id.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/restore_target_by_id.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/scheduler_observations_updates.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/set_observation_workflow_state.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/target_edit.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/update_call_for_proposals_by_id.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/update_calls_for_proposals.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/update_observation_by_id.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/update_observation_by_reference.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/update_observations.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/update_program_by_id.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/update_programs.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/update_target_by_id.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/update_targets.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/logging_utils.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/rest/utils.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/settings.py +0 -0
- {gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/urls.py +0 -0
|
@@ -8,6 +8,7 @@ from datetime import datetime
|
|
|
8
8
|
from typing import Any, AsyncIterator
|
|
9
9
|
|
|
10
10
|
from gpp_client.domains.base import BaseDomain
|
|
11
|
+
from gpp_client.rest.models import VisibilityChanges, parse_visibility_changes
|
|
11
12
|
from gpp_client.generated import SchedulerObservationsUpdates
|
|
12
13
|
from gpp_client.generated.get_scheduler_all_programs_id import (
|
|
13
14
|
GetSchedulerAllProgramsId,
|
|
@@ -252,7 +253,7 @@ class SchedulerDomain(BaseDomain):
|
|
|
252
253
|
if observations:
|
|
253
254
|
async with self._rest as client:
|
|
254
255
|
atom_digest_response = (
|
|
255
|
-
await client.
|
|
256
|
+
await client.get_atom_digests(observations)
|
|
256
257
|
).split("\n")
|
|
257
258
|
obs_atoms_mapping = self._parse_atom_digest(atom_digest_response)
|
|
258
259
|
else:
|
|
@@ -288,6 +289,35 @@ class SchedulerDomain(BaseDomain):
|
|
|
288
289
|
response = await self.get_program_ids(today=today)
|
|
289
290
|
return [(p.reference.label, p.id) for p in response.programs.matches]
|
|
290
291
|
|
|
292
|
+
async def get_visibility_changes(self, since: datetime) -> VisibilityChanges:
|
|
293
|
+
"""
|
|
294
|
+
Get observations and targets with visibility changes since a time.
|
|
295
|
+
|
|
296
|
+
Queries the ODB ``/scheduler/visibility-changes`` REST endpoint, which
|
|
297
|
+
reports entities whose visibility-relevant inputs changed at or after
|
|
298
|
+
``since``.
|
|
299
|
+
|
|
300
|
+
Parameters
|
|
301
|
+
----------
|
|
302
|
+
since : datetime
|
|
303
|
+
Return entities changed at or after this time. Naive datetimes are
|
|
304
|
+
assumed to be UTC.
|
|
305
|
+
|
|
306
|
+
Returns
|
|
307
|
+
-------
|
|
308
|
+
VisibilityChanges
|
|
309
|
+
Changed observation and target GIDs plus the latest change
|
|
310
|
+
timestamp reported by the endpoint.
|
|
311
|
+
|
|
312
|
+
Raises
|
|
313
|
+
------
|
|
314
|
+
aiohttp.ClientError
|
|
315
|
+
For HTTP errors, connection failures, or timeouts.
|
|
316
|
+
"""
|
|
317
|
+
async with self._rest as client:
|
|
318
|
+
body = await client.get_visibility_changes(since)
|
|
319
|
+
return parse_visibility_changes(body)
|
|
320
|
+
|
|
291
321
|
async def subscribe_to_calculation_updates(
|
|
292
322
|
self,
|
|
293
323
|
) -> AsyncIterator[SchedulerObservationsUpdates]:
|
|
@@ -8,6 +8,7 @@ import asyncio
|
|
|
8
8
|
import gzip
|
|
9
9
|
import logging
|
|
10
10
|
import ssl
|
|
11
|
+
from datetime import datetime, timezone
|
|
11
12
|
|
|
12
13
|
import aiohttp
|
|
13
14
|
import certifi
|
|
@@ -102,11 +103,32 @@ class RESTClient:
|
|
|
102
103
|
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
|
103
104
|
await self.close()
|
|
104
105
|
|
|
105
|
-
async def
|
|
106
|
+
async def get_atom_digests(
|
|
106
107
|
self, observation_ids: list[str], accept_gzip: bool = True
|
|
107
108
|
) -> str:
|
|
108
109
|
"""
|
|
109
110
|
Request atom digests for the given observation IDs.
|
|
111
|
+
|
|
112
|
+
Parameters
|
|
113
|
+
----------
|
|
114
|
+
observation_ids : list[str]
|
|
115
|
+
(internal) IDs of the observation to request.
|
|
116
|
+
|
|
117
|
+
accept_gzip : bool
|
|
118
|
+
Endpoint allows to return a gzip-compressed representation of the
|
|
119
|
+
complete atoms digest in the case of being too big.
|
|
120
|
+
|
|
121
|
+
Returns
|
|
122
|
+
-------
|
|
123
|
+
str
|
|
124
|
+
TSV data as string, one row per line.
|
|
125
|
+
|
|
126
|
+
Raises
|
|
127
|
+
------
|
|
128
|
+
aiohttp.ClientResponseError
|
|
129
|
+
For HTTP error responses.
|
|
130
|
+
aiohttp.ClientError
|
|
131
|
+
For connection or timeout failures.
|
|
110
132
|
"""
|
|
111
133
|
headers = {}
|
|
112
134
|
if accept_gzip:
|
|
@@ -145,3 +167,37 @@ class RESTClient:
|
|
|
145
167
|
return await response.text()
|
|
146
168
|
else:
|
|
147
169
|
return await response.text()
|
|
170
|
+
|
|
171
|
+
async def get_visibility_changes(self, since: datetime) -> str:
|
|
172
|
+
"""
|
|
173
|
+
Request observations and targets with visibility changes since a time.
|
|
174
|
+
|
|
175
|
+
Parameters
|
|
176
|
+
----------
|
|
177
|
+
since : datetime
|
|
178
|
+
Return entities whose visibility-relevant inputs changed at or
|
|
179
|
+
after this time. Naive datetimes are assumed to be UTC.
|
|
180
|
+
|
|
181
|
+
Returns
|
|
182
|
+
-------
|
|
183
|
+
str
|
|
184
|
+
TSV data as string, one ``<gid>\\t<iso8601-timestamp>`` per line.
|
|
185
|
+
|
|
186
|
+
Raises
|
|
187
|
+
------
|
|
188
|
+
aiohttp.ClientResponseError
|
|
189
|
+
For HTTP error responses.
|
|
190
|
+
aiohttp.ClientError
|
|
191
|
+
For connection or timeout failures.
|
|
192
|
+
"""
|
|
193
|
+
if since.tzinfo is None:
|
|
194
|
+
since = since.replace(tzinfo=timezone.utc)
|
|
195
|
+
|
|
196
|
+
session = await self.get_session()
|
|
197
|
+
|
|
198
|
+
async with session.get(
|
|
199
|
+
"/scheduler/visibility-changes",
|
|
200
|
+
params={"since": since.astimezone(timezone.utc).isoformat()},
|
|
201
|
+
) as response:
|
|
202
|
+
response.raise_for_status()
|
|
203
|
+
return await response.text()
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Models and parsers for REST API responses.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
__all__ = ["VisibilityChanges", "parse_visibility_changes"]
|
|
6
|
+
|
|
7
|
+
import logging
|
|
8
|
+
from dataclasses import dataclass, field
|
|
9
|
+
from datetime import datetime
|
|
10
|
+
|
|
11
|
+
logger = logging.getLogger(__name__)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass(frozen=True)
|
|
15
|
+
class VisibilityChanges:
|
|
16
|
+
"""
|
|
17
|
+
Observations and targets whose visibility-relevant inputs changed.
|
|
18
|
+
|
|
19
|
+
Attributes
|
|
20
|
+
----------
|
|
21
|
+
observation_ids : frozenset[str]
|
|
22
|
+
Observation GIDs (``o-`` prefix) with visibility changes.
|
|
23
|
+
target_ids : frozenset[str]
|
|
24
|
+
Target GIDs (``t-`` prefix) with visibility changes.
|
|
25
|
+
max_timestamp : datetime | None
|
|
26
|
+
Latest change timestamp reported by the endpoint, or None when no
|
|
27
|
+
parseable timestamps were returned.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
observation_ids: frozenset[str] = field(default_factory=frozenset)
|
|
31
|
+
target_ids: frozenset[str] = field(default_factory=frozenset)
|
|
32
|
+
max_timestamp: datetime | None = None
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def parse_visibility_changes(body: str) -> VisibilityChanges:
|
|
36
|
+
"""
|
|
37
|
+
Parse the TSV body of ``/scheduler/visibility-changes``.
|
|
38
|
+
|
|
39
|
+
Each line is ``<gid>\\t<iso8601-timestamp>`` where the GID prefix
|
|
40
|
+
disambiguate the entity: ``o-`` for observations, ``t-`` for targets.
|
|
41
|
+
Malformed lines and unknown prefixes are skipped with a warning; a bad
|
|
42
|
+
timestamp keeps the GID but does not contribute to ``max_timestamp``.
|
|
43
|
+
|
|
44
|
+
Parameters
|
|
45
|
+
----------
|
|
46
|
+
body : str
|
|
47
|
+
Raw TSV response body.
|
|
48
|
+
|
|
49
|
+
Returns
|
|
50
|
+
-------
|
|
51
|
+
VisibilityChanges
|
|
52
|
+
Parsed observation/target GIDs and the latest change timestamp.
|
|
53
|
+
"""
|
|
54
|
+
observation_ids: set[str] = set()
|
|
55
|
+
target_ids: set[str] = set()
|
|
56
|
+
max_timestamp: datetime | None = None
|
|
57
|
+
|
|
58
|
+
for line in body.splitlines():
|
|
59
|
+
line = line.strip()
|
|
60
|
+
if not line:
|
|
61
|
+
continue
|
|
62
|
+
gid, _, raw_timestamp = line.partition("\t")
|
|
63
|
+
gid = gid.strip()
|
|
64
|
+
|
|
65
|
+
if gid.startswith("o-"):
|
|
66
|
+
observation_ids.add(gid)
|
|
67
|
+
elif gid.startswith("t-"):
|
|
68
|
+
target_ids.add(gid)
|
|
69
|
+
else:
|
|
70
|
+
logger.warning(
|
|
71
|
+
"Skipping visibility-changes line with unknown GID: %r", line
|
|
72
|
+
)
|
|
73
|
+
continue
|
|
74
|
+
|
|
75
|
+
try:
|
|
76
|
+
timestamp = datetime.fromisoformat(
|
|
77
|
+
raw_timestamp.strip().replace("Z", "+00:00")
|
|
78
|
+
)
|
|
79
|
+
except ValueError:
|
|
80
|
+
logger.warning("Unparseable timestamp in visibility-changes line: %r", line)
|
|
81
|
+
continue
|
|
82
|
+
if max_timestamp is None or timestamp > max_timestamp:
|
|
83
|
+
max_timestamp = timestamp
|
|
84
|
+
|
|
85
|
+
return VisibilityChanges(
|
|
86
|
+
observation_ids=frozenset(observation_ids),
|
|
87
|
+
target_ids=frozenset(target_ids),
|
|
88
|
+
max_timestamp=max_timestamp,
|
|
89
|
+
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/create_call_for_proposals.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/create_target_by_program_id.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/custom_typing_fields.py
RENAMED
|
File without changes
|
|
File without changes
|
{gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/delete_observation_by_id.py
RENAMED
|
File without changes
|
|
File without changes
|
{gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/delete_program_by_id.py
RENAMED
|
File without changes
|
{gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/delete_target_by_id.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/get_call_for_proposals.py
RENAMED
|
File without changes
|
{gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/get_calls_for_proposals.py
RENAMED
|
File without changes
|
{gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/get_goats_observations.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/get_program_by_reference.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/get_scheduler_programs.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/obs_calculation_update.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/restore_observation_by_id.py
RENAMED
|
File without changes
|
|
File without changes
|
{gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/restore_program_by_id.py
RENAMED
|
File without changes
|
{gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/restore_target_by_id.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/update_calls_for_proposals.py
RENAMED
|
File without changes
|
{gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/update_observation_by_id.py
RENAMED
|
File without changes
|
|
File without changes
|
{gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/update_observations.py
RENAMED
|
File without changes
|
{gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/update_program_by_id.py
RENAMED
|
File without changes
|
|
File without changes
|
{gpp_client-26.7.3 → gpp_client-26.7.3.dev2}/src/gpp_client/generated/update_target_by_id.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|