Skip to content

API documentation

This module provides the core functionality of the Juice Core Uplink API Client in a more convenient way than the generated code.

May functionalities are not yet implemented, but some are.

SHTRestInterface

SHTRestInterface

Main entry point for interacting with the Juice Core Uplink API

Source code in src/juice_core/SHTRestInterface.py
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
@define(auto_attribs=True, eq=False)
class SHTRestInterface:
    """
    Main entry point for interacting with the Juice Core Uplink API
    """

    client: Client | None = None
    timeout: float = 40.0

    def __attrs_post_init__(self):
        if not self.client:
            self.client = Client(DEFAULT_URL)
        # self.client.timeout = self.timeout

    @cache
    @pandas_convertable
    def pcw(self):
        return get_pcw.sync(client=self.client)

    @cache
    @pandas_convertable
    def pcw_by_mnemonic(self, mnemonic: str):
        return get_pcw_by_mnemonic.sync(client=self.client, mnemonic=mnemonic)

    @cache
    @pandas_convertable(time_fields=["created"])
    def plans(self):
        """Retrieve all the plans available on the endpoint"""
        return get_plan.sync(client=self.client)

    def plan_id_by_name(self, name):
        """Retrieve the plan id from the plan name"""
        for plan in self.plans(as_pandas=False):
            if plan.name.lower().strip() == name.lower().strip():
                log.debug(f"Plan {name} has id {plan.id}")
                return plan.id

        log.warning(f"No plan with name {name} found")
        return None

    @cache
    @pandas_convertable(time_fields=["start", "end"])
    def plan_segments(self, plan_id_or_name):
        """Retrieve the segments of a plan"""
        plan = self.plan(plan_id_or_name, as_pandas=False)
        return plan.segments

    @cache
    @pandas_convertable(time_fields=["start", "end"])
    def engineering_segments(self, trajectory=DEFAULT_TRAJECTORY) -> pd.DataFrame:
        """Retrieve the engineering segments for a mnemonic"""
        return get_trajectory_engineering_segments_by_mnemonic.sync(
            mnemonic=trajectory,
            client=self.client,
        )

    @cache
    @pandas_convertable
    def plan(self, plan_id_or_name):
        """Retrieve the plan from the plan id or name"""
        if isinstance(plan_id_or_name, str):
            plan_id_or_name = self.plan_id_by_name(plan_id_or_name)

        return get_plan_by_id.sync(plan_id_or_name, client=self.client)

    @cache
    @pandas_convertable
    def known_series(self, trajectory=DEFAULT_TRAJECTORY):
        """Retrieve all the series available on the endpoint"""
        return get_trajectory_series_by_mnemonic.sync(
            client=self.client,
            mnemonic=trajectory,
        )

    @cache
    @pandas_convertable(is_timeseries=True)
    def series(
        self,
        series_name,
        trajectory=DEFAULT_TRAJECTORY,
        start=DEFAULT_START,
        end=DEFAULT_END,
    ):
        """Retrieve a serie from the endpoint"""

        q = {
            "start": str(start),
            "end": str(end),
            "trajectory": trajectory,
            "series": series_name,
        }

        body = json.dumps(q)
        return get_series.sync(client=self.client, body=body)

    def series_multi_(
        self,
        series_names,
        trajectory=DEFAULT_TRAJECTORY,
        start=DEFAULT_START,
        end=DEFAULT_END,
    ):
        loop = asyncio.get_event_loop()
        coroutine = self.series_multi(
            series_names,
            trajectory=trajectory,
            start=start,
            end=end,
        )
        return loop.run_until_complete(coroutine)

    def series_multi(
        self,
        series_names,
        trajectory=DEFAULT_TRAJECTORY,
        start=DEFAULT_START,
        end=DEFAULT_END,
    ):
        """Retrieve multiple series from the endpoint"""
        out = []
        for series_name in series_names:
            q = {
                "start": str(start),
                "end": str(end),
                "trajectory": trajectory,
                "series": series_name,
            }

            body = json.dumps(q)
            got = get_series.asyncio(client=self.client, body=body)
            out.append(got)

        return asyncio.gather(*out)

    @cache
    @pandas_convertable
    def event_types(self, trajectory=DEFAULT_TRAJECTORY):
        """Retrieve all the events applicable for a trajectory"""
        return get_trajectory_event_by_mnemonic.sync(
            client=self.client,
            mnemonic=trajectory,
        )

    @cache
    def segment_definition(self, mnemonic):
        return get_segment_definition_by_mnemonic.sync(
            client=self.client,
            mnemonic=mnemonic,
        )

    @pandas_convertable
    def segment_definitions(self, mnemonics: list[str]):
        return [self.segment_definition(m) for m in mnemonics]

    @cache
    @pandas_convertable(time_fields=["start", "end"])
    def events(
        self,
        mnemonics: list[str] | str = [],
        trajectory: str = DEFAULT_TRAJECTORY,
        start=DEFAULT_START,
        end=DEFAULT_END,
    ):
        """Retrieve events of a given type from the endpoint"""
        if isinstance(mnemonics, str):
            mnemonics = [mnemonics]

        if len(mnemonics) == 0:
            types = self.event_types(trajectory=trajectory, as_pandas=False)
            mnemonics = [m.mnemonic for m in types]
            log.info(f"Retrieving all known events {mnemonics}")

        q = {
            "start": str(start),
            "end": str(end),
            "trajectory": trajectory,
            "mnemonics": mnemonics,
        }

        body = json.dumps(q)
        return get_events.sync(client=self.client, body=body)

engineering_segments(trajectory=DEFAULT_TRAJECTORY) -> pd.DataFrame cached

Retrieve the engineering segments for a mnemonic

Source code in src/juice_core/SHTRestInterface.py
210
211
212
213
214
215
216
217
@cache
@pandas_convertable(time_fields=["start", "end"])
def engineering_segments(self, trajectory=DEFAULT_TRAJECTORY) -> pd.DataFrame:
    """Retrieve the engineering segments for a mnemonic"""
    return get_trajectory_engineering_segments_by_mnemonic.sync(
        mnemonic=trajectory,
        client=self.client,
    )

event_types(trajectory=DEFAULT_TRAJECTORY) cached

Retrieve all the events applicable for a trajectory

Source code in src/juice_core/SHTRestInterface.py
297
298
299
300
301
302
303
304
@cache
@pandas_convertable
def event_types(self, trajectory=DEFAULT_TRAJECTORY):
    """Retrieve all the events applicable for a trajectory"""
    return get_trajectory_event_by_mnemonic.sync(
        client=self.client,
        mnemonic=trajectory,
    )

events(mnemonics: list[str] | str = [], trajectory: str = DEFAULT_TRAJECTORY, start=DEFAULT_START, end=DEFAULT_END) cached

Retrieve events of a given type from the endpoint

Source code in src/juice_core/SHTRestInterface.py
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
@cache
@pandas_convertable(time_fields=["start", "end"])
def events(
    self,
    mnemonics: list[str] | str = [],
    trajectory: str = DEFAULT_TRAJECTORY,
    start=DEFAULT_START,
    end=DEFAULT_END,
):
    """Retrieve events of a given type from the endpoint"""
    if isinstance(mnemonics, str):
        mnemonics = [mnemonics]

    if len(mnemonics) == 0:
        types = self.event_types(trajectory=trajectory, as_pandas=False)
        mnemonics = [m.mnemonic for m in types]
        log.info(f"Retrieving all known events {mnemonics}")

    q = {
        "start": str(start),
        "end": str(end),
        "trajectory": trajectory,
        "mnemonics": mnemonics,
    }

    body = json.dumps(q)
    return get_events.sync(client=self.client, body=body)

known_series(trajectory=DEFAULT_TRAJECTORY) cached

Retrieve all the series available on the endpoint

Source code in src/juice_core/SHTRestInterface.py
228
229
230
231
232
233
234
235
@cache
@pandas_convertable
def known_series(self, trajectory=DEFAULT_TRAJECTORY):
    """Retrieve all the series available on the endpoint"""
    return get_trajectory_series_by_mnemonic.sync(
        client=self.client,
        mnemonic=trajectory,
    )

plan(plan_id_or_name) cached

Retrieve the plan from the plan id or name

Source code in src/juice_core/SHTRestInterface.py
219
220
221
222
223
224
225
226
@cache
@pandas_convertable
def plan(self, plan_id_or_name):
    """Retrieve the plan from the plan id or name"""
    if isinstance(plan_id_or_name, str):
        plan_id_or_name = self.plan_id_by_name(plan_id_or_name)

    return get_plan_by_id.sync(plan_id_or_name, client=self.client)

plan_id_by_name(name)

Retrieve the plan id from the plan name

Source code in src/juice_core/SHTRestInterface.py
193
194
195
196
197
198
199
200
201
def plan_id_by_name(self, name):
    """Retrieve the plan id from the plan name"""
    for plan in self.plans(as_pandas=False):
        if plan.name.lower().strip() == name.lower().strip():
            log.debug(f"Plan {name} has id {plan.id}")
            return plan.id

    log.warning(f"No plan with name {name} found")
    return None

plan_segments(plan_id_or_name) cached

Retrieve the segments of a plan

Source code in src/juice_core/SHTRestInterface.py
203
204
205
206
207
208
@cache
@pandas_convertable(time_fields=["start", "end"])
def plan_segments(self, plan_id_or_name):
    """Retrieve the segments of a plan"""
    plan = self.plan(plan_id_or_name, as_pandas=False)
    return plan.segments

plans() cached

Retrieve all the plans available on the endpoint

Source code in src/juice_core/SHTRestInterface.py
187
188
189
190
191
@cache
@pandas_convertable(time_fields=["created"])
def plans(self):
    """Retrieve all the plans available on the endpoint"""
    return get_plan.sync(client=self.client)

series(series_name, trajectory=DEFAULT_TRAJECTORY, start=DEFAULT_START, end=DEFAULT_END) cached

Retrieve a serie from the endpoint

Source code in src/juice_core/SHTRestInterface.py
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
@cache
@pandas_convertable(is_timeseries=True)
def series(
    self,
    series_name,
    trajectory=DEFAULT_TRAJECTORY,
    start=DEFAULT_START,
    end=DEFAULT_END,
):
    """Retrieve a serie from the endpoint"""

    q = {
        "start": str(start),
        "end": str(end),
        "trajectory": trajectory,
        "series": series_name,
    }

    body = json.dumps(q)
    return get_series.sync(client=self.client, body=body)

series_multi(series_names, trajectory=DEFAULT_TRAJECTORY, start=DEFAULT_START, end=DEFAULT_END)

Retrieve multiple series from the endpoint

Source code in src/juice_core/SHTRestInterface.py
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
def series_multi(
    self,
    series_names,
    trajectory=DEFAULT_TRAJECTORY,
    start=DEFAULT_START,
    end=DEFAULT_END,
):
    """Retrieve multiple series from the endpoint"""
    out = []
    for series_name in series_names:
        q = {
            "start": str(start),
            "end": str(end),
            "trajectory": trajectory,
            "series": series_name,
        }

        body = json.dumps(q)
        got = get_series.asyncio(client=self.client, body=body)
        out.append(got)

    return asyncio.gather(*out)

expand_column(tab: pd.DataFrame, column_name='description') -> pd.DataFrame

Some tables have a description column that contains additional information.

This function expands the description column into multiple columns.

Parameters

tab (pd.DataFrame): table to expand, must have a description column

Returns

pd.DataFrame: a new dataframe with the description column expanded

Source code in src/juice_core/SHTRestInterface.py
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
def expand_column(tab: pd.DataFrame, column_name="description") -> pd.DataFrame:
    """Some tables have a description column that contains additional information.

    This function expands the description column into multiple columns.

    Parameters
    ----------
    tab (pd.DataFrame):
        table to expand, must have a description column

    Returns
    -------
    pd.DataFrame:
        a new dataframe with the description column expanded

    """
    additional_columns = []
    for d in tab[column_name]:
        values = {}
        for item in d.split(";"):
            key, value = item.split("=")
            values[key.strip()] = value.strip()

        additional_columns.append(values)

    tab_ = tab.drop(columns=[column_name], inplace=False)
    newd = pd.DataFrame(additional_columns)

    return tab_.join(newd)