Skip to content

Commit 6618be8

Browse files
committed
Making archiver timezone aware
archiver: getData allows spezifiying the timezone the data shall be returned in. The datetime t0 and t1 are translated to GMT before the are converted to isostrings. carchier: data retrieval from achiver is now in a separate function. Required as timezone can not be hashed if tzlocal is used. So get_data_from_archiver uses the lru_cache. Dataframes are translated to the requested timezone
1 parent 0624bfe commit 6618be8

File tree

2 files changed

+44
-22
lines changed

2 files changed

+44
-22
lines changed

bact_archiver/archiver.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,13 @@
99
from abc import ABCMeta, abstractmethod, abstractproperty
1010
import json
1111
import logging
12+
import pytz
1213
from urllib.request import urlopen, quote
1314

14-
1515
logger = logging.getLogger('bact-archiver')
1616

17+
_utc = pytz.timezone('UTC')
18+
1719

1820
#: The format as requested by the archiver
1921
archiver_request_fmt = "%Y-%m-%dT%H:%M:%S.000000Z"
@@ -57,8 +59,12 @@ def getData(self, var, * t0, t1, **kws):
5759
Defaults to pandas
5860
time_format (str, optional) : requested time format (raw, timestamp, datetime).
5961
Defaults to timestamp
60-
padding (str, optional) : restrict timestamp to requested time range
61-
(cuts first entry and adds dummy last entry)
62+
padding (str, optional) : restrict timestamp to requested time range
63+
(cuts first entry and adds dummy last entry)
64+
65+
timezone (:class:`datetime.tzinfo`, optional): for pandas dataframes, use given
66+
tzinfo to translate the dataframe to. If none is given,
67+
translate it to the local timezone
6268
6369
Returns:
6470
tuple of numpy arrays or pandas.DataFrame see :func:`get_data`
@@ -132,6 +138,9 @@ def bpl_url_fmt(self):
132138
return url
133139

134140
def getData(self, pvname, *, t0, t1, **kws):
141+
142+
t0 = t0.astimezone(_utc)
143+
t1 = t1.astimezone(_utc)
135144
t0_str = convert_datetime_to_timestamp(t0)
136145
t1_str = convert_datetime_to_timestamp(t1)
137146
fmt = 'Trying to get data for pv %s in interval %s..%s = %s..%s',

bact_archiver/carchiver.py

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,35 @@ def read_sequence(seq):
8282

8383

8484
@lru_cache(maxsize=64)
85+
def get_data_from_archiver(data):
86+
'''
87+
88+
Singled out to be cached ..
89+
'''
90+
res = []
91+
years = []
92+
# ignore last '\n' and split into chunks
93+
for seq in data[:-1].split(b'\n\n'):
94+
chunk = read_sequence(seq)
95+
# logger.debug('chunk header "{}"'.format(chunk.header))
96+
97+
if chunk.value is not None:
98+
# logger.debug(chunk.value)
99+
res.append(chunk.value)
100+
header = chunk.header
101+
years.extend(chunk.header.year *
102+
np.ones(len(chunk.value[0]), dtype=np.int))
103+
logger.debug(chunk.header)
104+
# print('found data:',len(chunk.value[0]))
105+
else:
106+
pass
107+
# logger.debug('no data')
108+
109+
return res, years, header
110+
111+
85112
def get_data(data, *, return_type='pandas', time_format='timestamp',
86-
padding=False, t_start=None, t_stop=None):
113+
padding=False, t_start=None, t_stop=None, timezone=None):
87114
#print("get_data.cache_info: {}".format(request_data.cache_info()))
88115
"""Parses HTTP/PB data buffer
89116
@@ -121,24 +148,8 @@ def get_data(data, *, return_type='pandas', time_format='timestamp',
121148
header, values, seconds, nanos = get_data(f.read(), return_type='raw')
122149
"""
123150

124-
res = []
125-
years = []
126-
# ignore last '\n' and split into chunks
127-
for seq in data[:-1].split(b'\n\n'):
128-
chunk = read_sequence(seq)
129-
# logger.debug('chunk header "{}"'.format(chunk.header))
130151

131-
if chunk.value is not None:
132-
# logger.debug(chunk.value)
133-
res.append(chunk.value)
134-
header = chunk.header
135-
years.extend(chunk.header.year *
136-
np.ones(len(chunk.value[0]), dtype=np.int))
137-
logger.debug(chunk.header)
138-
# print('found data:',len(chunk.value[0]))
139-
else:
140-
pass
141-
# logger.debug('no data')
152+
res, years, header = get_data_from_archiver(data)
142153

143154
# if single chunk with data, return here
144155
if len(res) == 0:
@@ -175,7 +186,9 @@ def get_data(data, *, return_type='pandas', time_format='timestamp',
175186
# Code of old versin
176187
# df = df.tz_localize('UTC').tz_convert(dateutil.tz.tzlocal())
177188
# python3.7 pandas 0.24.2
178-
df = df.tz_convert(dateutil.tz.tzlocal())
189+
if timezone is None:
190+
timezone = dateutil.tz.tzlocal()
191+
df = df.tz_convert(timezone)
179192

180193
if padding:
181194
if t_start is not None and t_stop is not None and len(df.columns) == 1:

0 commit comments

Comments
 (0)