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

Fix Callback Error Updating store-trips.data - TypeError: 'float' object is not subscriptable fixed #121

Merged
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions docker-compose-dev.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# docker-compose.yml
version: "3"
services:
dashboard:
Expand All @@ -14,7 +13,7 @@ services:
DASH_DEBUG_MODE: "True"
DASH_SILENCE_ROUTES_LOGGING: "False"
DASH_SERVER_PORT: 8050
DB_HOST: db
DB_HOST: mongodb://db:27017/openpath_prod_ca_ebike
TeachMeTW marked this conversation as resolved.
Show resolved Hide resolved
WEB_SERVER_HOST: 0.0.0.0
SERVER_BRANCH: master
CONFIG_PATH: "https://raw.githubusercontent.com/e-mission/nrel-openpath-deploy-configs/main/configs/"
Expand All @@ -30,7 +29,7 @@ services:
- ./app_sidebar_collapsible.py:/usr/src/app/app_sidebar_collapsible.py
deploy:
restart_policy:
condition: on-failure
condition: on-failure
TeachMeTW marked this conversation as resolved.
Show resolved Hide resolved
db:
image: mongo:4.4.0
deploy:
Expand Down
67 changes: 62 additions & 5 deletions docker/load_mongodump.sh
TeachMeTW marked this conversation as resolved.
Show resolved Hide resolved
TeachMeTW marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -1,10 +1,67 @@
#!/bin/bash

# Directory of the script
SCRIPT_DIR="$(dirname "$0")"

# Path to the configuration file (one level up)
CONFIG_FILE="$SCRIPT_DIR/../docker-compose-dev.yml"

# Check if the correct number of arguments is provided
if [ "$#" -ne 1 ]; then
echo "Usage: $0 <mongodump-file>"
echo " <mongodump-file> : The path to the MongoDB dump file to be restored."
exit 1
fi

MONGODUMP_FILE=$1

echo "Copying file to docker container"
docker cp $MONGODUMP_FILE op-admin-dashboard-db-1:/tmp
# Print debug information
echo "Script Directory: $SCRIPT_DIR"
echo "Configuration File Path: $CONFIG_FILE"
echo "MongoDump File Path: $MONGODUMP_FILE"

# Check if the provided file exists
if [ ! -f "$MONGODUMP_FILE" ]; then
echo "Error: File '$MONGODUMP_FILE' does not exist."
exit 1
fi

# Check if the configuration file exists
if [ ! -f "$CONFIG_FILE" ]; then
echo "Error: Configuration file '$CONFIG_FILE' does not exist."
exit 1
fi

# Print details about the configuration file
echo "Configuration file details:"
ls -l "$CONFIG_FILE"


# Extract DB_HOST from the YAML file
DB_HOST=$(grep -i "DB_HOST:" "$CONFIG_FILE" | sed 's/^[^:]*: *//')
if [ -z "$DB_HOST" ]; then
echo "Error: DB_HOST not found in configuration file."
exit 1
fi

# Extract the database name from DB_HOST
DB_NAME=$(echo "$DB_HOST" | sed -e 's/^mongodb:\/\/[^:]*:[0-9]*\///')

# Check if the database name was extracted correctly
if [ -z "$DB_NAME" ]; then
echo "Error: Failed to extract database name from DB_HOST."
exit 1
fi

echo "Copying file to Docker container"
docker cp "$MONGODUMP_FILE" op-admin-dashboard-db-1:/tmp

FILE_NAME=$(basename "$MONGODUMP_FILE")

FILE_NAME=`basename $MONGODUMP_FILE`
echo "Clearing existing database"
docker exec op-admin-dashboard-db-1 bash -c 'mongo --eval "db.getMongo().getDBNames().forEach(function(d) { if (d !== \"admin\" && d !== \"local\") db.getSiblingDB(d).dropDatabase(); })"'

echo "Restoring the dump from $FILE_NAME"
docker exec -e MONGODUMP_FILE=$FILE_NAME op-admin-dashboard-db-1 bash -c 'cd /tmp && tar xvf $MONGODUMP_FILE && mongorestore'
echo "Restoring the dump from $FILE_NAME to database $DB_NAME"
docker exec -e MONGODUMP_FILE=$FILE_NAME op-admin-dashboard-db-1 bash -c "cd /tmp && tar xvf $FILE_NAME && mongorestore -d $DB_NAME dump/openpath_prod_ca_ebike"

echo "Database restore complete."
21 changes: 20 additions & 1 deletion utils/db_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,26 @@ def query_confirmed_trips(start_date: str, end_date: str, tz: str):
# Add primary modes from the sensed, inferred and ble summaries. Note that we do this
# **before** filtering the `all_trip_columns` because the
# *_section_summary columns are not currently valid
get_max_mode_from_summary = lambda md: max(md["distance"], key=md["distance"].get) if len(md["distance"]) > 0 else "INVALID"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the same functionality that I had to update in #141. Your checks are much more thorough than mine, so I'll go ahead and update to match this, but I set the result to UNKNOWN instead of INVALID, and I'm wondering if we should do the same thing in both places? I chose UNKNOWN since that is what trips where we were unable to sense a mode for most of the distance are displayed as, what purpose does INVALID serve here? Or maybe, what is the difference between an INVALID sensed mode and an UNKNOWN sensed mode?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Abby-Wheelis I am not entirely sure what INVALID would represent here as opposed to unknown. I believe @shankari was the one who originally wrote this line of code that I refactored. I can change it to UNKNOWN to match #141

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@TeachMeTW can you look at the commit where I wrote that code and see if I added in an explanation of why my choice? I have some vague recollection of the decision making, but the comments I wrote at the time are likely to be more clear.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shankari @Abby-Wheelis based on existing comments, this is how I interpreted it.

INVALID: used to signify that the data or result is not just unknown but invalid. It implies that something went wrong or the data provided does not meet the expected format or criteria. It's a more explicit signal that the data is unusable.

UNKNOWN: indicates that the mode is not known, but does not necessarily imply that there was an error or problem with the data. It often means that the information is not available or could not be determined but is expected to be a valid state to encounter.

Should we keep both Invalid and unknown or just use one?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can keep both, thank you for the explanation! Hopefully once we figure out #1088 and resolve the underlying data issues there will be less INVALID sense modes

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shankari if possible please resolve the issue if no further reviews/changes are needed


# Check if 'md' is not a dictionary or does not contain the key 'distance'
# or if 'md["distance"]' is not a dictionary.
# If any of these conditions are true, return "INVALID".
get_max_mode_from_summary = lambda md: (
"INVALID"
if not isinstance(md, dict)
or "distance" not in md
or not isinstance(md["distance"], dict)
# If 'md' is a dictionary and 'distance' is a valid key pointing to a dictionary:
else (
# Get the maximum value from 'md["distance"]' using the values of 'md["distance"].get' as the key for 'max'.
# This operation only happens if the length of 'md["distance"]' is greater than 0.
# Otherwise, return "INVALID".
max(md["distance"], key=md["distance"].get)
if len(md["distance"]) > 0
else "INVALID"
)
)

df["data.primary_sensed_mode"] = df.cleaned_section_summary.apply(get_max_mode_from_summary)
df["data.primary_predicted_mode"] = df.inferred_section_summary.apply(get_max_mode_from_summary)
if 'ble_sensed_summary' in df.columns:
Expand Down