Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

KeyError: 'dehydrated state' #183

Open
natesanshreyas opened this issue Aug 19, 2024 · 3 comments
Open

KeyError: 'dehydrated state' #183

natesanshreyas opened this issue Aug 19, 2024 · 3 comments

Comments

@natesanshreyas
Copy link

Has anyone come across this before?

weight_data = client.get_measurements('Weight', single_date, single_date)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

File "/Users/shreyasnatesan/Desktop/NucampFolder/Python/1-Fundamentals/myenv/lib/python3.12/site-packages/myfitnesspal/client.py", line 615, in get_measurements
measurement_ids = self._get_measurement_ids(document)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/shreyasnatesan/Desktop/NucampFolder/Python/1-Fundamentals/myenv/lib/python3.12/site-packages/myfitnesspal/client.py", line 741, in _get_measurement_ids
for q in next_data_json["props"]["pageProps"]["dehydratedState"]["queries"]:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^
KeyError: 'dehydratedState'

Seems like an issue with client.py, any way to debug or fix this?

@hannahburkhardt
Copy link
Collaborator

I can't reproduce the issue. Can you provide a more detailed example? What are the weights that you are expecting to be returned?

@natesanshreyas
Copy link
Author

import os.path
import pandas as pd
from google.auth.transport.requests import Request
from google.oauth2.credentials import Credentials
from google_auth_oauthlib.flow import InstalledAppFlow
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError
import myfitnesspal
import browser_cookie3
import datetime

Initialize MyFitnessPal client with Chrome cookies

client = myfitnesspal.Client(browser_cookie3.chrome())

Define the start date as today and go back 8 days

end_date = datetime.date.today()
start_date = end_date - datetime.timedelta(days=7) # This will give you a 8-day range

data = []

Loop over the range of dates and collect totals for each day

for single_date in (start_date + datetime.timedelta(n) for n in range(8)):
try:
# Attempt to fetch the data
day = client.get_date(single_date.year, single_date.month, single_date.day)
weight_data = client.get_measurements('Weight', single_date, single_date)
weight = weight_data.get(single_date, None) # Leave blank if no data

    totals = day.totals

    # Append the data to the list
    data.append({
        'Date': single_date.strftime('%Y-%m-%d'),
        'Weight': weight if weight else 0,
        'Fat (g)': totals.get('fat', 0),
        'Carbohydrates (g)': totals.get('carbohydrates', 0),
        'Protein (g)': totals.get('protein', 0),
        'Calories': totals.get('calories', 0)
    })
except KeyError as e:
    print(f"KeyError occurred for date {single_date}: {e}. Skipping this date.")
except Exception as e:
    print(f"An unexpected error occurred for date {single_date}: {e}. Skipping this date.")

Convert the data list to a DataFrame

df = pd.DataFrame(data)

Google Sheets API integration

SCOPES = ["https://www.googleapis.com/auth/spreadsheets"]

The ID of the target spreadsheet.

SPREADSHEET_ID = ""

def get_start_position(service, spreadsheet_id, target_date):
# Retrieve the sheet data
sheet = service.spreadsheets()
result = sheet.values().get(spreadsheetId=spreadsheet_id, range="Current Overall Protocol 2024!A1:Z").execute()
values = result.get('values', [])

# Find the date in the sheet
for row_idx, row in enumerate(values):
    for col_idx, cell_value in enumerate(row):
        if cell_value == target_date:  # Adjust the date format to match your sheet
            start_column = chr(ord('A') + col_idx)
            base_row = row_idx + 1
            return start_column, base_row

# Default fallback if date is not found
return None, None

def main():
creds = None
if os.path.exists("token.json"):
creds = Credentials.from_authorized_user_file("token.json", SCOPES)

if not creds or not creds.valid:
    if creds and creds.expired and creds.refresh_token:
        creds.refresh(Request())
    else:
        flow = InstalledAppFlow.from_client_secrets_file(
            "credentials.json", SCOPES
        )
        creds = flow.run_local_server(port=0)
    with open("token.json", "w") as token:
        token.write(creds.to_json())

try:
    # Build the service after creds are defined
    service = build("sheets", "v4", credentials=creds)

    for idx, row in df.iterrows():
        date_str = row['Date']
        start_column, base_row = get_start_position(service, SPREADSHEET_ID, date_str)

        if start_column and base_row:
            end_column = chr(ord(start_column) + len(row) - 1)
            RANGE_NAME = f"Current Overall Protocol 2024!{start_column}{base_row}:{end_column}{base_row}"

            # Convert DataFrame row to list for Google Sheets API
            values = [[row['Date'], row['Weight'], row['Fat (g)'], row['Carbohydrates (g)'], row['Protein (g)'], row['Calories']]]

            # Prepare the body for the API request
            body = {
                "values": values
            }

            # Call the Sheets API to update the target range
            result = service.spreadsheets().values().update(
                spreadsheetId=SPREADSHEET_ID, range=RANGE_NAME,
                valueInputOption="RAW", body=body
            ).execute()

            print(f"Updated {result.get('updatedCells')} cells for date {date_str}.")

        else:
            print(f"Date {date_str} not found in the sheet. Skipping update.")

except HttpError as error:
    print(f"An error occurred: {error}")

if name == 'main':
main()

This is the script I'm using, I'm essentially trying to get the date, weight, fat, carbs, protein, and calories for the past seven days off of MFP. I'm not sure what the "dehydrated state" issue even is. If I get rid of the try except block I get this error:

Traceback (most recent call last):
File "/Users/shreyasnatesan/Desktop/NucampFolder/Python/1-Fundamentals/quickstart.py", line 25, in
weight_data = client.get_measurements('Weight', single_date, single_date)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/shreyasnatesan/Documents/python/venv/lib/python3.12/site-packages/myfitnesspal/client.py", line 615, in get_measurements
measurement_ids = self._get_measurement_ids(document)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/shreyasnatesan/Documents/python/venv/lib/python3.12/site-packages/myfitnesspal/client.py", line 741, in _get_measurement_ids
for q in next_data_json["props"]["pageProps"]["dehydratedState"]["queries"]:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^
KeyError: 'dehydratedState'

Seems like there's something in the client.py around "dehydratedState"? No idea what that means or how to fix that.

@Philomath88
Copy link

Philomath88 commented Oct 23, 2024

I second that. it only happened from yesterday onwards - it relates to getting a weight measurement.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants