diff --git a/fitbit/api.py b/fitbit/api.py index 1b458b1..8739373 100644 --- a/fitbit/api.py +++ b/fitbit/api.py @@ -513,7 +513,7 @@ def water_goal(self, target=None): return self._resource_goal('foods/log/water', data) def time_series(self, resource, user_id=None, base_date='today', - period=None, end_date=None): + period=None, end_date=None, timezone=None): """ The time series is a LOT of methods, (documented at urls below) so they don't get their own method. They all follow the same patterns, and @@ -545,16 +545,22 @@ def time_series(self, resource, user_id=None, base_date='today', base_date=self._get_date_string(base_date), end=end ) + + if timezone: + url = url + ('?timezone=%s' % timezone) + return self.make_request(url) - def intraday_time_series(self, resource, base_date='today', detail_level='1min', start_time=None, end_time=None): + def intraday_time_series(self, resource, base_date='today', detail_level='1min', + end_date=None, start_time=None, end_time=None, timezone=None): """ The intraday time series extends the functionality of the regular time series, but returning data at a more granular level for a single day, defaulting to 1 minute intervals. To access this feature, one must fill out the Private Support form here (see https://dev.fitbit.com/docs/help/). For details on the resources available and more information on how to get access, see: - https://dev.fitbit.com/docs/activity/#get-activity-intraday-time-series + + Use this method to retrieve intraday data for AZM, activity and heart rate. """ # Check that the time range is valid @@ -572,10 +578,16 @@ def intraday_time_series(self, resource, base_date='today', detail_level='1min', if not detail_level in ['1sec', '1min', '15min']: raise ValueError("Period must be either '1sec', '1min', or '15min'") - url = "{0}/{1}/user/-/{resource}/date/{base_date}/1d/{detail_level}".format( + if end_date: + end = self._get_date_string(end_date) + else: + end = '1d' + + url = "{0}/{1}/user/-/{resource}/date/{base_date}/{end}/{detail_level}".format( *self._get_common_args(), resource=resource, base_date=self._get_date_string(base_date), + end=end, detail_level=detail_level ) @@ -589,8 +601,38 @@ def intraday_time_series(self, resource, base_date='today', detail_level='1min', url = url + '.json' + if timezone: + url = url + ('?timezone=%s' % timezone) + + return self.make_request(url) + + + def intraday_time_series2(self, resource, base_date='today', end_date=None): + """ + The intraday time series extends the functionality of the regular time series, but returning data at a + more granular level for a single day, defaulting to 1 minute intervals. To access this feature, one must + fill out the Private Support form here (see https://dev.fitbit.com/docs/help/). + For details on the resources available and more information on how to get access, see: + https://dev.fitbit.com/docs/activity/#get-activity-intraday-time-series + + Use this method to retrieve intraday data for breathing rate, HRV and SpO2. + """ + + url = "{0}/{1}/user/-/{resource}/date/{base_date}/".format( + *self._get_common_args(), + resource=resource, + base_date=self._get_date_string(base_date) + ) + + if end_date: + end = self._get_date_string(end_date) + url = url + end + '/' + + url = url + 'all.json' + return self.make_request(url) + def activity_stats(self, user_id=None, qualifier=''): """ * https://dev.fitbit.com/docs/activity/#activity-types diff --git a/fitbit_tests/test_api.py b/fitbit_tests/test_api.py index f019d72..9f2839a 100644 --- a/fitbit_tests/test_api.py +++ b/fitbit_tests/test_api.py @@ -684,12 +684,13 @@ class PartnerAPITest(TestBase): https://dev.fitbit.com/docs/ """ - def _test_intraday_timeseries(self, resource, base_date, detail_level, - start_time, end_time, expected_url): + def _test_intraday_timeseries(self, resource, base_date, detail_level, end_date, + start_time, end_time, timezone, expected_url): """ Helper method for intraday timeseries tests """ with mock.patch.object(self.fb, 'make_request') as make_request: retval = self.fb.intraday_time_series( - resource, base_date, detail_level, start_time, end_time) + resource, base_date, detail_level, + end_date, start_time, end_time, timezone) args, kwargs = make_request.call_args self.assertEqual((expected_url,), args) @@ -756,35 +757,79 @@ def test_intraday_timeseries(self): # Default self._test_intraday_timeseries( resource, base_date=base_date, detail_level='1min', - start_time=None, end_time=None, + end_date=None, start_time=None, + end_time=None, timezone=None, expected_url=URLBASE + "/-/FOO/date/1918-05-11/1d/1min.json") # start_date can be a date object self._test_intraday_timeseries( resource, base_date=datetime.date(1918, 5, 11), - detail_level='1min', start_time=None, end_time=None, + detail_level='1min', end_date=None, start_time=None, + end_time=None, timezone=None, expected_url=URLBASE + "/-/FOO/date/1918-05-11/1d/1min.json") # start_time can be a datetime object self._test_intraday_timeseries( resource, base_date=base_date, detail_level='1min', - start_time=datetime.time(3, 56), end_time='15:07', + end_date=None, start_time=datetime.time(3, 56), + end_time='15:07', timezone=None, expected_url=URLBASE + "/-/FOO/date/1918-05-11/1d/1min/time/03:56/15:07.json") # end_time can be a datetime object self._test_intraday_timeseries( resource, base_date=base_date, detail_level='1min', - start_time='3:56', end_time=datetime.time(15, 7), + end_date=None, start_time='3:56', + end_time=datetime.time(15, 7), timezone=None, expected_url=URLBASE + "/-/FOO/date/1918-05-11/1d/1min/time/3:56/15:07.json") # start_time can be a midnight datetime object self._test_intraday_timeseries( resource, base_date=base_date, detail_level='1min', - start_time=datetime.time(0, 0), end_time=datetime.time(15, 7), + end_date=None, start_time=datetime.time(0, 0), + end_time=datetime.time(15, 7), timezone=None, expected_url=URLBASE + "/-/FOO/date/1918-05-11/1d/1min/time/00:00/15:07.json") # end_time can be a midnight datetime object self._test_intraday_timeseries( resource, base_date=base_date, detail_level='1min', - start_time=datetime.time(3, 56), end_time=datetime.time(0, 0), + end_date=None, start_time=datetime.time(3, 56), + end_time=datetime.time(0, 0), timezone=None, expected_url=URLBASE + "/-/FOO/date/1918-05-11/1d/1min/time/03:56/00:00.json") # start_time and end_time can be a midnight datetime object self._test_intraday_timeseries( resource, base_date=base_date, detail_level='1min', - start_time=datetime.time(0, 0), end_time=datetime.time(0, 0), + end_date=None, start_time=datetime.time(0, 0), + end_time=datetime.time(0, 0), timezone=None, expected_url=URLBASE + "/-/FOO/date/1918-05-11/1d/1min/time/00:00/00:00.json") + + + def _test_intraday_timeseries2(self, resource, base_date, end_date, expected_url): + """ Helper method for intraday timeseries tests """ + with mock.patch.object(self.fb, 'make_request') as make_request: + retval = self.fb.intraday_time_series2( + resource, base_date, end_date) + args, kwargs = make_request.call_args + self.assertEqual((expected_url,), args) + + def test_intraday_timeseries2(self): + """ + Intraday Time Series tests: + https://dev.fitbit.com/docs/activity/#get-activity-intraday-time-series + + Tests the following methods/URLs: + GET https://api.fitbit.com/1/user/-/FOO/date/1918-05-11/1d/1min.json + GET https://api.fitbit.com/1/user/-/FOO/date/1918-05-11/1d/1min.json + GET https://api.fitbit.com/1/user/-/FOO/date/1918-05-11/1d/1min/time/03:56/15:07.json + GET https://api.fitbit.com/1/user/-/FOO/date/1918-05-11/1d/1min/time/3:56/15:07.json + """ + resource = 'FOO' + base_date = '1918-05-11' + + # Default + self._test_intraday_timeseries2( + resource, base_date=base_date, end_date=None, + expected_url=URLBASE + "/-/FOO/date/1918-05-11/all.json") + # base_date can be a date object + self._test_intraday_timeseries2( + resource, base_date=datetime.date(1918, 5, 11), end_date=None, + expected_url=URLBASE + "/-/FOO/date/1918-05-11/all.json") + # end_date can be a date object + self._test_intraday_timeseries2( + resource, base_date=datetime.date(1918, 5, 11), + end_date=datetime.date(1918, 5, 12), + expected_url=URLBASE + "/-/FOO/date/1918-05-11/1918-05-12/all.json") \ No newline at end of file