<jupyter_start><jupyter_text>Fitbit access on JupyterhubFitbit API authenticates your application by opening a browser window that connects to Fitbit: https://dev.fitbit.com/build/reference/web-api/basics/. However, because Jupyterhub is running on a remote server, opening a browser window (on the remote server) is not an option for us. We can use a somewhat manual method to get around this limitation.Below is the code for downloading your Fitbit data using course Jupyterhub. Refer to [this page](https://dev.fitbit.com/build/reference/web-api/basics/) for details. You need the following:* Registered application: https://dev.fitbit.com/apps* Client ID and Client Secret* Callback URL (on dev.fitbit.com) has to match redirect_uri (for OAuth2Server below)* OAuth 2.0 Application Type must be "Personal" (otherwise intraday data is not available)![](images/EditApplication-manage.png)![](images/EditApplication-personal.png)<jupyter_code>import fitbit  # clone https://github.com/orcasgit/python-fitbit

class OAuth2Server:
    def __init__(self, client_id, client_secret,
                 redirect_uri='http://127.0.0.1:8080/'):
        
        from fitbit import Fitbit
        
        """ Initialize the FitbitOauth2Client """
        self.success_html = """
            <h1>You are now authorized to access the Fitbit API!</h1>
            <br/><h3>You can close this window</h3>"""
        self.failure_html = """
            <h1>ERROR: %s</h1><br/><h3>You can close this window</h3>%s"""

        self.fitbit = Fitbit(
            client_id,
            client_secret,
            redirect_uri=redirect_uri,
            timeout=10,
        )

CLIENT_ID = 'YOUR_CLIENT_ID'
CLIENT_SECRET = 'YOUR_CLIENT_SECRET'
# Instantiate OAuth server
server = OAuth2Server(CLIENT_ID, CLIENT_SECRET)

# Request to be authorized via OAuth
url,_ = server.fitbit.client.authorize_token_url()
print("1. Open this URL and you will be forwarded to another.\n" + 
      url + "\n\n2. Copy the destination URL and paste below")
def getAccessToken(server, url=None):

    from urllib.parse import urlparse, parse_qs
    
    parsed = urlparse(url)
    code = parse_qs(parsed.query)['code'][0]
    out = server.fitbit.client.fetch_access_token(code)
    
    return(out)

destinationURL = 'http://127.0.0.1:8080/?code=9d5e143b4d8c0fe8925f718fb4ca4d7f45048633&state=xAdN79wmz1WBUzuZ0MDSLRONY15lLG#_=_'
credentials = getAccessToken(server, destinationURL)
# Instantiate connection
auth2_client = fitbit.Fitbit(
    CLIENT_ID,
    CLIENT_SECRET,
    oauth2=True,
    access_token=credentials['access_token'],
    refresh_token=credentials['refresh_token'],
)
def pull_date_activity(connection, date_string, endpoint='activities/steps'):
    """
    Pull activity from an endpoint for a given day
    
    Inputs:
        connection: Connection to your Fitbit app
        endpoint: API endpoint you want to pull data from
        date_string: Date string of the form "yyyy-mm-dd"
    Returns:
        Pandas DataFrame of values for requested activity for the requested date
    """
    import pandas as pd
    
    result_set = connection.intraday_time_series(
        endpoint,
        base_date=date_string
    )
    
    act_type = endpoint.split('/')[1]
    get_key = f'activities-{act_type}-intraday'
    df = pd.DataFrame.from_dict(result_set[get_key]['dataset'])
    df['timestamp'] = date_string + ' ' + df['time']
    df['timestamp'] = pd.to_datetime(df.timestamp)
    df.drop(['time'], axis=1, inplace=True)
    df.set_index('timestamp', inplace=True)
    df.rename(columns={'value': act_type}, inplace=True)
    
    return df
    
test_date = pull_date_activity(
    auth2_client,
    '2018-05-25'
)

test_date.rolling(window=15, win_type='triang').mean().plot(figsize=(20, 6), title="2018-05-25")<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10884353741496598, 'fraction_numerical': 0.025379382522239664, 'mean_word_length': 3.6004813477737665, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 15, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '197490', 'license': 'Apache-2.0', 'n_tokens_mistral': 1282, 'n_tokens_neox': 1220, 'n_words': 303, 'path': 'FitBitAPI.ipynb', 'repo_name': 'zhangyandrew/Spring-2018', 'size': '3822'}