Skip to content

Commit

Permalink
Add support for before in get_latest and enable getting ts name by …
Browse files Browse the repository at this point in the history
…label in DTS (#168)

* Add support for 'before' in get_latest and enable getting ts name by label in dts

* Bump version to 0.11.22

* Remove duplicate code and raise InputError on non-existing labels
  • Loading branch information
Erlend Vollset committed Dec 5, 2018
1 parent 45a2d02 commit a80bc07
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 14 deletions.
2 changes: 1 addition & 1 deletion cognite/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@
#

__all__ = ["v04", "v05", "v06", "preprocessing", "config", "data_transfer_service"]
__version__ = "0.11.21"
__version__ = "0.11.22"
38 changes: 29 additions & 9 deletions cognite/data_transfer_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from typing import Dict, List, Union

import pandas as pd

from cognite import config
from cognite._utils import InputError, get_aggregate_func_return_name, to_camel_case, to_snake_case
from cognite.v05 import files
Expand Down Expand Up @@ -240,6 +239,28 @@ def __init__(
self.cookies = cookies
self.num_of_processes = num_of_processes

def get_time_series_name(self, ts_label: str, dataframe_label: str = "default"):
if self.ts_data_specs is None:
raise InputError("Data spec does not contain any TimeSeriesDataSpecs")

tsds = None
for ts_data_spec in self.ts_data_specs:
if ts_data_spec.label == dataframe_label:
tsds = ts_data_spec

if tsds:
# Temporary workaround that you cannot use get_datapoints_frame with ts id.
ts_res = time_series_v06.get_multiple_time_series_by_id(
ids=list(set([ts.id for ts in tsds.time_series])), api_key=self.api_key, project=self.project
)
id_to_name = {ts["id"]: ts["name"] for ts in ts_res.to_json()}

for ts in tsds.time_series:
if ts.label == ts_label:
return id_to_name[ts.id]
raise InputError("Invalid time series label")
raise InputError("Invalid dataframe label")

def get_dataframes(self, drop_agg_suffix: bool = True):
"""Return a dictionary of dataframes indexed by label - one per data spec.
Expand Down Expand Up @@ -301,22 +322,21 @@ def get_dataframe(self, label: str = "default", drop_agg_suffix: bool = True):
df = self.__apply_missing_data_strategies(df, ts_list, tsds.missing_data_strategy)
df = self.__convert_ts_names_to_labels(df, tsds, drop_agg_suffix)
return df
return None
raise InputError("Invalid label")

def get_file(self, name):
"""Return files by name as specified in the DataSpec
Args:
name (str): Name of file
"""
if not self.files_data_spec:
if not self.files_data_spec or not isinstance(self.files_data_spec, FilesDataSpec):
raise InputError("Data spec does not contain a FilesDataSpec")
if isinstance(self.files_data_spec, FilesDataSpec):
id = self.files_data_spec.file_ids.get(name)
if id:
file_bytes = files.download_file(id, get_contents=True, api_key=self.api_key, project=self.project)
return BytesIO(file_bytes)
raise InputError("Invalid name")
id = self.files_data_spec.file_ids.get(name)
if id:
file_bytes = files.download_file(id, get_contents=True, api_key=self.api_key, project=self.project)
return BytesIO(file_bytes)
raise InputError("Invalid name")

def __convert_ts_names_to_labels(self, df: pd.DataFrame, tsds: TimeSeriesDataSpec, drop_agg_suffix: bool):
name_to_label = {}
Expand Down
5 changes: 3 additions & 2 deletions cognite/v05/timeseries.py
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ def post_datapoints(name, datapoints: List[Datapoint], **kwargs):
return res.json()


def get_latest(name, **kwargs):
def get_latest(name, before=None, **kwargs):
"""Returns a LatestDatapointObject containing the latest datapoint for the given timeseries.
Args:
Expand All @@ -391,7 +391,8 @@ def get_latest(name, **kwargs):
api_key, project = config.get_config_variables(kwargs.get("api_key"), kwargs.get("project"))
url = config.get_base_url() + "/api/0.5/projects/{}/timeseries/latest/{}".format(project, quote(name, safe=""))
headers = {"api-key": api_key, "accept": "application/json"}
res = _utils.get_request(url, headers=headers, cookies=config.get_cookies())
params = {"before": before}
res = _utils.get_request(url, params=params, headers=headers, cookies=config.get_cookies())
return LatestDatapointResponse(res.json())


Expand Down
7 changes: 6 additions & 1 deletion tests/test_data_transfer_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
from io import BytesIO

import pandas as pd

import pytest

from cognite.data_transfer_service import (
DataSpec,
DataSpecValidationError,
Expand Down Expand Up @@ -227,3 +227,8 @@ def test_get_dataframes_column_mapping_no_drop_agg_suffix(self, data_spec):
"ts3|count",
"ts4|stepinterpolation",
]

def test_get_timeseries_name(self, data_spec):
dts = DataTransferService(data_spec, num_of_processes=3)
for ts_label in ["ts1", "ts2", "ts3", "ts4"]:
assert dts.get_time_series_name(ts_label) == "constant"
6 changes: 5 additions & 1 deletion tests/v05/test_timeseries.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

import numpy as np
import pandas as pd

import pytest

from cognite.v05 import dto, timeseries

TS_NAME = None
Expand Down Expand Up @@ -153,10 +153,14 @@ def test_get_latest(self):
from cognite.v05.dto import LatestDatapointResponse

response = timeseries.get_latest("constant")
assert list(response.to_json().keys()) == ["timestamp", "value"]
assert isinstance(response, LatestDatapointResponse)
assert isinstance(response.to_ndarray(), np.ndarray)
assert isinstance(response.to_pandas(), pd.DataFrame)
assert isinstance(response.to_json(), dict)
timestamp = response.to_json()["timestamp"]
response = timeseries.get_latest("constant", before=timestamp)
assert response.to_json()["timestamp"] < timestamp


class TestDatapointsFrame:
Expand Down

0 comments on commit a80bc07

Please sign in to comment.