From 0559505b3bab54da50ab1fdd6eb82df3c18ba307 Mon Sep 17 00:00:00 2001 From: Leo Singer <leo.singer@ligo.org> Date: Thu, 27 Feb 2020 17:53:26 -0500 Subject: [PATCH] Work around GPS time validation bug in GraceDB server Work around a bug in GraceDB where normalization of floating-point GPS times to fixed-precision decimal representation is applied to JSON-encoded requests but not form-encoded requests. This bug caused superevent API requests with GPS times specified with more than 6 decimal places to fail. See https://git.ligo.org/lscsoft/gracedb/issues/195. --- CHANGES.rst | 6 +++++- gracedb_sdk/api/events.py | 19 ++++++++++++------- gracedb_sdk/tests/test_api.py | 16 +++++++++++----- 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index b91d7af..e2d2d8d 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,7 +4,11 @@ Changelog 0.1.3 (unreleased) ------------------ -- No changes yet. +- Work around a bug in GraceDB where normalization of floating-point GPS + times to fixed-precision decimal representation is applied to JSON-encoded + requests but not form-encoded requests. This bug caused superevent API + requests with GPS times specified with more than 6 decimal places to fail. + See https://git.ligo.org/lscsoft/gracedb/issues/195. 0.1.2 (2020-02-20) ------------------ diff --git a/gracedb_sdk/api/events.py b/gracedb_sdk/api/events.py index 6f5e486..232669d 100644 --- a/gracedb_sdk/api/events.py +++ b/gracedb_sdk/api/events.py @@ -18,7 +18,7 @@ from os.path import join from .base import Deletable, Mapping, Mutable, Resource from .event import Event, Superevent -from .util import field_collection +from .util import field_collection, str_or_collection class BaseEvents(Deletable, Mapping, Mutable, Resource): @@ -69,20 +69,25 @@ class Superevents(BaseEvents): def create_or_update(self, superevent_id, *, events=None, labels=None, **kwargs): - data = (*field_collection('events', events), - *field_collection('labels', labels), - *kwargs.items()) + data = {key: value for key, value in kwargs.items() + if value is not None} + if events: + data['events'] = str_or_collection(events) + if labels: + data['labels'] = str_or_collection(labels) # Automatically guess category based on prefix of preferred event preferred_event = kwargs.get('preferred_event') if preferred_event is not None: category = SUPEREVENT_CATEGORIES[preferred_event[0]] - data += (('category', category),) + data['category'] = category + # FIXME: superevent creation requests must be JSON-encoded rather than + # form-encoded due to https://git.ligo.org/lscsoft/gracedb/issues/195 if superevent_id is None: - return super().create_or_update(superevent_id, data=data) + return super().create_or_update(superevent_id, json=data) else: # FIXME: GraceDB does not support 'put' here, only 'patch'! # This is inconsistent between events and superevents. url = join(self.url, superevent_id) + '/' - return self.session.patch(url, data=data) + return self.session.patch(url, json=data) diff --git a/gracedb_sdk/tests/test_api.py b/gracedb_sdk/tests/test_api.py index b572b60..299c4ea 100644 --- a/gracedb_sdk/tests/test_api.py +++ b/gracedb_sdk/tests/test_api.py @@ -51,7 +51,10 @@ def skip_if_not_authorized(client): group='Test', pipeline='gstlal') graceid = event['graceid'] superevent = client.superevents.create( - preferred_event=graceid, t_0=1e9, t_start=1e9, t_end=1e9) + preferred_event=graceid, + t_start=1000000000.12345678, + t_0=1000000001.12345678, + t_end=1000000002.12345678) superevent_id = superevent['superevent_id'] client.superevents[superevent_id].expose() except HTTPError as e: @@ -225,15 +228,18 @@ def test_events_voevents_get(client, events_create, events_voevents_create): def superevents_create(client, events_create): event_id = events_create['graceid'] return client.superevents.create( - preferred_event=event_id, t_0=1e9, t_start=1e9, t_end=1e9) + preferred_event=event_id, + t_start=1000000000.12345678, + t_0=1000000001.12345678, + t_end=1000000002.12345678) def test_superevents_create(client, events_create, superevents_create): event_id = events_create['graceid'] assert superevents_create['preferred_event'] == event_id - assert superevents_create['t_start'] == 1e9 - assert superevents_create['t_0'] == 1e9 - assert superevents_create['t_end'] == 1e9 + assert superevents_create['t_start'] == 1000000000.123457 + assert superevents_create['t_0'] == 1000000001.123457 + assert superevents_create['t_end'] == 1000000002.123457 def test_superevents_get(client, superevents_create): -- GitLab