Cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

get_sleep range problem

ANSWERED

Hi,

 

When I take sleep-related statistics via get_sleep(date=today), all works perfectly, I am able to get all the data for a particular day. 

jsonSleep = authd_client.get_sleep(date=today)

However, as per Fitbit API documentation, there is a chance to get sleep logs by date range, using get_sleep(start, end). As far as I understand, this method should work under 1.2 API

https://dev.fitbit.com/build/reference/web-api/sleep/

When I check the Fitbit library, it seems to be outdated, using API version 1 and it does not contain the method get sleep by range

https://github.com/orcasgit/python-fitbit

In order to fix it, I changed the API version from 1 to 1.2 within the library and defined the desired method as follows:

Standard get_sleep as of the particular date

    def get_sleep(self, date):
        """
        https://dev.fitbit.com/docs/sleep/#get-sleep-logs
        date should be a datetime.date object.
        """
        url = "{0}/{1}/user/-/sleep/date/{year}-{month}-{day}.json".format(
            *self._get_common_args(),
            year=date.year,
            month=date.month,
            day=date.day
        )
        return self.make_request(url)

 Added another method to get stats by date range:

def get_sleep_range(self, sDate, eDate):
"""
https://dev.fitbit.com/docs/sleep/#get-sleep-logs
date should be a datetime.date object.
"""
url = "{0}/{1}/user/-/sleep/date/{sYear}-{sMonth}-{sDay}/{eYear}-{eMonth}-{eDay}.json".format(
*self._get_common_args(),
sYear=sDate.year,
sMonth=sDate.month,
sDay=sDate.day,
eYear=eDate.year,
eMonth=eDate.month,
eDay=eDate.day
)
return self.make_request(url)

Later, I made another request:

start = datetime.date(year=2019, month=4, day=01)
end = datetime.date(year=2019, month=5, day=30)

jsonSleep = authd_client.get_sleep_range(startDate,endDate)

 However, eventually, request fails

Traceback (most recent call last):
  File "/Users/ievgeniishulitskyi/PycharmProjects/Project/.idea/Summary_v3.py", line 26, in <module>
    jsonSleep = authd_client.get_sleep_range(start,end)
  File "/Users/ievgeniishulitskyi/Desktop/Sleep/python-fitbit-master/fitbit/api.py", line 826, in get_sleep_range
    return self.make_request(url)
  File "/Users/ievgeniishulitskyi/Desktop/Sleep/python-fitbit-master/fitbit/api.py", line 256, in make_request
    response = self.client.make_request(*args, **kwargs)
  File "/Users/ievgeniishulitskyi/Desktop/Sleep/python-fitbit-master/fitbit/api.py", line 99, in make_request
    exceptions.detect_and_raise_error(response)
  File "/Users/ievgeniishulitskyi/Desktop/Sleep/python-fitbit-master/fitbit/exceptions.py", line 96, in detect_and_raise_error
    raise HTTPBadRequest(response)
fitbit.exceptions.HTTPBadRequest: Invalid date: 2019-4-1/2019-5-30

Any ideas what I am missing?

 

Thanks!

Best Answer
0 Votes
1 BEST ANSWER

Accepted Solutions

Hi,

 

Actually, I've fixed an issue with your suggestion. Feel a bit ashamed since it was returned as server response, so quite obvious but just did not expect it to be that easy, considering the fact that other method (get_sleep) works with default format, which can be 2019-4-5

 

Tricky thing that I can provide the following:

 

 

start = datetime.date(year=2019, month=05, day=02)

 

But in API there is a standard datetime method used:

 

month=date.month,
day=date.day

Which returns single-digit date format for both months and days, eg 2019-5-2

 

The resolution is to amend the API file:

 

 

    def get_sleep_range(self, sDate, eDate):
        """
        https://dev.fitbit.com/docs/sleep/#get-sleep-logs
        date should be a datetime.date object.
        """
        url = "{0}/{1}/user/-/sleep/date/{sYear}-{sMonth}-{sDay}/{eYear}-{eMonth}-{eDay}.json".format(
            *self._get_common_args(),
            sYear=sDate.year,
            sMonth=sDate.strftime("%m"),
            sDay=sDate.strftime("%d"),
            eYear=eDate.year,
            eMonth=eDate.strftime("%m"),
            eDay=eDate.strftime("%d")
        )
        return self.make_request(url)

 

View best answer in original post

Best Answer
0 Votes
4 REPLIES 4

Hi @shulitskyi,

 

I'll be happy to assist. Based on your post, it looks like the dates you've provided are invalid:

 

fitbit.exceptions.HTTPBadRequest: Invalid date: 2019-4-1/2019-5-30

Can you try formatting the API call in the following way and let me know if it was successful?

 

https://api.fitbit.com/1.2/user/-/sleep/date/2019-04-01/2019-05-30.json

 

I hope this helps!

 

Best Answer
0 Votes

Hi John,

 

That was my first guess but the thing is that I used the format needed for the API config file, otherwise neither time series nor daily extractions will not work as well

Best Answer
0 Votes

Hi @shulitskyi,

 

Thanks for providing that information. So that I can see what is going on, can you provide me with your application's client ID? 

 

Also, can you let me know which folder the API config file resides in within the github you provided me?

 

Lastly, provide me with the errors and/or responses you are seeing from the time series and daily extractions so that I may investigate further.

 

Looking forward to hearing from you!

Best Answer
0 Votes

Hi,

 

Actually, I've fixed an issue with your suggestion. Feel a bit ashamed since it was returned as server response, so quite obvious but just did not expect it to be that easy, considering the fact that other method (get_sleep) works with default format, which can be 2019-4-5

 

Tricky thing that I can provide the following:

 

 

start = datetime.date(year=2019, month=05, day=02)

 

But in API there is a standard datetime method used:

 

month=date.month,
day=date.day

Which returns single-digit date format for both months and days, eg 2019-5-2

 

The resolution is to amend the API file:

 

 

    def get_sleep_range(self, sDate, eDate):
        """
        https://dev.fitbit.com/docs/sleep/#get-sleep-logs
        date should be a datetime.date object.
        """
        url = "{0}/{1}/user/-/sleep/date/{sYear}-{sMonth}-{sDay}/{eYear}-{eMonth}-{eDay}.json".format(
            *self._get_common_args(),
            sYear=sDate.year,
            sMonth=sDate.strftime("%m"),
            sDay=sDate.strftime("%d"),
            eYear=eDate.year,
            eMonth=eDate.strftime("%m"),
            eDay=eDate.strftime("%d")
        )
        return self.make_request(url)

 

Best Answer
0 Votes