Spaces:
Sleeping
Sleeping
gauravlochab
commited on
Commit
·
cba6d8a
1
Parent(s):
31508e9
feat: add timezone adjustment function and enhance logging for timestamp handling
Browse files
app.py
CHANGED
|
@@ -28,6 +28,24 @@ global_df = None
|
|
| 28 |
# Configuration
|
| 29 |
API_BASE_URL = "https://afmdb.autonolas.tech"
|
| 30 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 31 |
def get_agent_type_by_name(type_name: str) -> Dict[str, Any]:
|
| 32 |
"""Get agent type by name"""
|
| 33 |
response = requests.get(f"{API_BASE_URL}/api/agent-types/name/{type_name}")
|
|
@@ -93,10 +111,12 @@ def extract_apr_value(attr: Dict[str, Any]) -> Dict[str, Any]:
|
|
| 93 |
try:
|
| 94 |
# The APR value is stored in the json_value field
|
| 95 |
if attr["json_value"] is None:
|
|
|
|
| 96 |
return {"apr": None, "timestamp": None, "agent_id": attr["agent_id"], "is_dummy": False}
|
| 97 |
|
| 98 |
# If json_value is a string, parse it
|
| 99 |
if isinstance(attr["json_value"], str):
|
|
|
|
| 100 |
json_data = json.loads(attr["json_value"])
|
| 101 |
else:
|
| 102 |
json_data = attr["json_value"]
|
|
@@ -104,10 +124,24 @@ def extract_apr_value(attr: Dict[str, Any]) -> Dict[str, Any]:
|
|
| 104 |
apr = json_data.get("apr")
|
| 105 |
timestamp = json_data.get("timestamp")
|
| 106 |
|
|
|
|
|
|
|
| 107 |
# Convert timestamp to datetime if it exists
|
| 108 |
timestamp_dt = None
|
| 109 |
if timestamp:
|
|
|
|
| 110 |
timestamp_dt = datetime.fromtimestamp(timestamp)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 111 |
|
| 112 |
return {"apr": apr, "timestamp": timestamp_dt, "agent_id": attr["agent_id"], "is_dummy": False}
|
| 113 |
except (json.JSONDecodeError, KeyError, TypeError) as e:
|
|
@@ -120,6 +154,11 @@ def fetch_apr_data_from_db():
|
|
| 120 |
"""
|
| 121 |
global global_df
|
| 122 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 123 |
try:
|
| 124 |
# Step 1: Find the Modius agent type
|
| 125 |
modius_type = get_agent_type_by_name("Modius")
|
|
@@ -158,6 +197,10 @@ def fetch_apr_data_from_db():
|
|
| 158 |
for attr in apr_attributes:
|
| 159 |
apr_data = extract_apr_value(attr)
|
| 160 |
if apr_data["apr"] is not None and apr_data["timestamp"] is not None:
|
|
|
|
|
|
|
|
|
|
|
|
|
| 161 |
# Get agent name
|
| 162 |
agent_name = get_agent_name(attr["agent_id"], modius_agents)
|
| 163 |
# Add agent name to the data
|
|
@@ -180,6 +223,12 @@ def fetch_apr_data_from_db():
|
|
| 180 |
return global_df
|
| 181 |
|
| 182 |
global_df = pd.DataFrame(apr_data_list)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 183 |
return global_df
|
| 184 |
|
| 185 |
except requests.exceptions.RequestException as e:
|
|
@@ -379,11 +428,32 @@ def create_combined_time_series_graph(df):
|
|
| 379 |
)
|
| 380 |
return fig
|
| 381 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 382 |
# Create Plotly figure
|
| 383 |
fig = go.Figure()
|
| 384 |
|
| 385 |
# Get unique agents
|
| 386 |
unique_agents = df['agent_id'].unique()
|
|
|
|
| 387 |
|
| 388 |
# Define a color scale for different agents
|
| 389 |
colors = px.colors.qualitative.Plotly[:len(unique_agents)]
|
|
@@ -428,7 +498,9 @@ def create_combined_time_series_graph(df):
|
|
| 428 |
|
| 429 |
# Sort the data by timestamp
|
| 430 |
agent_data = agent_data.sort_values('timestamp')
|
| 431 |
-
|
|
|
|
|
|
|
| 432 |
# Add the combined line for both APR and Performance
|
| 433 |
fig.add_trace(
|
| 434 |
go.Scatter(
|
|
@@ -444,7 +516,7 @@ def create_combined_time_series_graph(df):
|
|
| 444 |
|
| 445 |
# Add scatter points for APR values
|
| 446 |
apr_data = agent_data[agent_data['metric_type'] == 'APR']
|
| 447 |
-
|
| 448 |
if not apr_data.empty:
|
| 449 |
fig.add_trace(
|
| 450 |
go.Scatter(
|
|
@@ -461,7 +533,7 @@ def create_combined_time_series_graph(df):
|
|
| 461 |
|
| 462 |
# Add scatter points for Performance values
|
| 463 |
perf_data = agent_data[agent_data['metric_type'] == 'Performance']
|
| 464 |
-
|
| 465 |
if not perf_data.empty:
|
| 466 |
fig.add_trace(
|
| 467 |
go.Scatter(
|
|
@@ -478,7 +550,7 @@ def create_combined_time_series_graph(df):
|
|
| 478 |
|
| 479 |
# Update layout
|
| 480 |
fig.update_layout(
|
| 481 |
-
title="APR and Performance Values for All Agents",
|
| 482 |
xaxis_title="Time",
|
| 483 |
yaxis_title="Value",
|
| 484 |
template="plotly_white",
|
|
@@ -492,8 +564,17 @@ def create_combined_time_series_graph(df):
|
|
| 492 |
x=1,
|
| 493 |
groupclick="toggleitem"
|
| 494 |
),
|
| 495 |
-
margin=dict(r=20, l=20, t=
|
| 496 |
-
hovermode="closest"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 497 |
)
|
| 498 |
|
| 499 |
# Update axes
|
|
|
|
| 28 |
# Configuration
|
| 29 |
API_BASE_URL = "https://afmdb.autonolas.tech"
|
| 30 |
|
| 31 |
+
# Add a timezone adjustment function at the top of the file after imports
|
| 32 |
+
def adjust_timestamp(timestamp_dt, hours_offset=0):
|
| 33 |
+
"""
|
| 34 |
+
Adjust a timestamp by the specified number of hours.
|
| 35 |
+
Used to correct for timezone differences between environments.
|
| 36 |
+
|
| 37 |
+
Args:
|
| 38 |
+
timestamp_dt: datetime object to adjust
|
| 39 |
+
hours_offset: number of hours to add (can be negative)
|
| 40 |
+
|
| 41 |
+
Returns:
|
| 42 |
+
Adjusted datetime object
|
| 43 |
+
"""
|
| 44 |
+
if timestamp_dt is None:
|
| 45 |
+
return None
|
| 46 |
+
|
| 47 |
+
return timestamp_dt + timedelta(hours=hours_offset)
|
| 48 |
+
|
| 49 |
def get_agent_type_by_name(type_name: str) -> Dict[str, Any]:
|
| 50 |
"""Get agent type by name"""
|
| 51 |
response = requests.get(f"{API_BASE_URL}/api/agent-types/name/{type_name}")
|
|
|
|
| 111 |
try:
|
| 112 |
# The APR value is stored in the json_value field
|
| 113 |
if attr["json_value"] is None:
|
| 114 |
+
logger.warning(f"Null JSON value for agent_id: {attr.get('agent_id')}")
|
| 115 |
return {"apr": None, "timestamp": None, "agent_id": attr["agent_id"], "is_dummy": False}
|
| 116 |
|
| 117 |
# If json_value is a string, parse it
|
| 118 |
if isinstance(attr["json_value"], str):
|
| 119 |
+
logger.info(f"Parsing JSON string for agent_id: {attr.get('agent_id')}")
|
| 120 |
json_data = json.loads(attr["json_value"])
|
| 121 |
else:
|
| 122 |
json_data = attr["json_value"]
|
|
|
|
| 124 |
apr = json_data.get("apr")
|
| 125 |
timestamp = json_data.get("timestamp")
|
| 126 |
|
| 127 |
+
logger.info(f"Raw timestamp from API: {timestamp}, type: {type(timestamp)}")
|
| 128 |
+
|
| 129 |
# Convert timestamp to datetime if it exists
|
| 130 |
timestamp_dt = None
|
| 131 |
if timestamp:
|
| 132 |
+
# Just use the standard conversion without timezone specification
|
| 133 |
timestamp_dt = datetime.fromtimestamp(timestamp)
|
| 134 |
+
logger.info(f"Converted timestamp: {timestamp_dt}")
|
| 135 |
+
|
| 136 |
+
# Log timezone information
|
| 137 |
+
try:
|
| 138 |
+
local_now = datetime.now()
|
| 139 |
+
logger.info(f"Current local time: {local_now}")
|
| 140 |
+
logger.info(f"Difference between API time and local time (hours): {(timestamp_dt - local_now).total_seconds() / 3600:.2f}")
|
| 141 |
+
except Exception as e:
|
| 142 |
+
logger.error(f"Error calculating time difference: {e}")
|
| 143 |
+
else:
|
| 144 |
+
logger.warning(f"No timestamp in data for agent_id: {attr.get('agent_id')}")
|
| 145 |
|
| 146 |
return {"apr": apr, "timestamp": timestamp_dt, "agent_id": attr["agent_id"], "is_dummy": False}
|
| 147 |
except (json.JSONDecodeError, KeyError, TypeError) as e:
|
|
|
|
| 154 |
"""
|
| 155 |
global global_df
|
| 156 |
|
| 157 |
+
# Set the timezone offset between local and HF environments
|
| 158 |
+
# Based on the logs, we're seeing ~6 hour difference
|
| 159 |
+
# If HF is showing earlier times than local, use a negative value
|
| 160 |
+
TIMEZONE_OFFSET_HOURS = -3 # Adjust based on observed differences
|
| 161 |
+
|
| 162 |
try:
|
| 163 |
# Step 1: Find the Modius agent type
|
| 164 |
modius_type = get_agent_type_by_name("Modius")
|
|
|
|
| 197 |
for attr in apr_attributes:
|
| 198 |
apr_data = extract_apr_value(attr)
|
| 199 |
if apr_data["apr"] is not None and apr_data["timestamp"] is not None:
|
| 200 |
+
# Apply timezone adjustment
|
| 201 |
+
apr_data["timestamp"] = adjust_timestamp(apr_data["timestamp"], TIMEZONE_OFFSET_HOURS)
|
| 202 |
+
logger.info(f"Adjusted timestamp: {apr_data['timestamp']}")
|
| 203 |
+
|
| 204 |
# Get agent name
|
| 205 |
agent_name = get_agent_name(attr["agent_id"], modius_agents)
|
| 206 |
# Add agent name to the data
|
|
|
|
| 223 |
return global_df
|
| 224 |
|
| 225 |
global_df = pd.DataFrame(apr_data_list)
|
| 226 |
+
|
| 227 |
+
# Log timestamp ranges for debugging
|
| 228 |
+
if not global_df.empty:
|
| 229 |
+
logger.info(f"DataFrame timestamp min: {global_df['timestamp'].min()}")
|
| 230 |
+
logger.info(f"DataFrame timestamp max: {global_df['timestamp'].max()}")
|
| 231 |
+
|
| 232 |
return global_df
|
| 233 |
|
| 234 |
except requests.exceptions.RequestException as e:
|
|
|
|
| 428 |
)
|
| 429 |
return fig
|
| 430 |
|
| 431 |
+
# Debug: Print detailed info about the dataframe
|
| 432 |
+
logger.info(f"Combined graph data - shape: {df.shape}")
|
| 433 |
+
logger.info(f"Timestamp min: {df['timestamp'].min()}, timezone info: {getattr(df['timestamp'].min(), 'tzinfo', None)}")
|
| 434 |
+
logger.info(f"Timestamp max: {df['timestamp'].max()}, timezone info: {getattr(df['timestamp'].max(), 'tzinfo', None)}")
|
| 435 |
+
logger.info("Platform/Environment info:")
|
| 436 |
+
logger.info(f"Host: {os.uname().nodename if hasattr(os, 'uname') else 'Unknown'}")
|
| 437 |
+
logger.info(f"System: {os.name}")
|
| 438 |
+
|
| 439 |
+
# Create a timestamp reference to identify the environment
|
| 440 |
+
current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
| 441 |
+
logger.info(f"Environment check - current time: {current_time}")
|
| 442 |
+
|
| 443 |
+
# Add a title annotation with environment information to help identify which environment is which
|
| 444 |
+
environment_tag = "LOCAL" if os.environ.get("GRADIO_SERVER_PORT") is None else "HUGGINGFACE"
|
| 445 |
+
logger.info(f"Environment tag: {environment_tag}")
|
| 446 |
+
|
| 447 |
+
# Debug: Print every data point with full details to verify consistency
|
| 448 |
+
for idx, row in df.iterrows():
|
| 449 |
+
logger.info(f"Data point {idx}: agent={row['agent_name']}, time={row['timestamp']}, apr={row['apr']}, type={row['metric_type']}")
|
| 450 |
+
|
| 451 |
# Create Plotly figure
|
| 452 |
fig = go.Figure()
|
| 453 |
|
| 454 |
# Get unique agents
|
| 455 |
unique_agents = df['agent_id'].unique()
|
| 456 |
+
logger.info(f"Unique agents: {[df[df['agent_id'] == agent_id]['agent_name'].iloc[0] for agent_id in unique_agents]}")
|
| 457 |
|
| 458 |
# Define a color scale for different agents
|
| 459 |
colors = px.colors.qualitative.Plotly[:len(unique_agents)]
|
|
|
|
| 498 |
|
| 499 |
# Sort the data by timestamp
|
| 500 |
agent_data = agent_data.sort_values('timestamp')
|
| 501 |
+
logger.info(f"Agent {agent_name} data points: {len(agent_data)}")
|
| 502 |
+
logger.info(f"Agent {agent_name} timestamps: {agent_data['timestamp'].tolist()}")
|
| 503 |
+
|
| 504 |
# Add the combined line for both APR and Performance
|
| 505 |
fig.add_trace(
|
| 506 |
go.Scatter(
|
|
|
|
| 516 |
|
| 517 |
# Add scatter points for APR values
|
| 518 |
apr_data = agent_data[agent_data['metric_type'] == 'APR']
|
| 519 |
+
logger.info(f"Agent {agent_name} APR points: {len(apr_data)}")
|
| 520 |
if not apr_data.empty:
|
| 521 |
fig.add_trace(
|
| 522 |
go.Scatter(
|
|
|
|
| 533 |
|
| 534 |
# Add scatter points for Performance values
|
| 535 |
perf_data = agent_data[agent_data['metric_type'] == 'Performance']
|
| 536 |
+
logger.info(f"Agent {agent_name} Performance points: {len(perf_data)}")
|
| 537 |
if not perf_data.empty:
|
| 538 |
fig.add_trace(
|
| 539 |
go.Scatter(
|
|
|
|
| 550 |
|
| 551 |
# Update layout
|
| 552 |
fig.update_layout(
|
| 553 |
+
title=f"APR and Performance Values for All Agents - {environment_tag} - {current_time}",
|
| 554 |
xaxis_title="Time",
|
| 555 |
yaxis_title="Value",
|
| 556 |
template="plotly_white",
|
|
|
|
| 564 |
x=1,
|
| 565 |
groupclick="toggleitem"
|
| 566 |
),
|
| 567 |
+
margin=dict(r=20, l=20, t=50, b=20), # Increased top margin for title
|
| 568 |
+
hovermode="closest",
|
| 569 |
+
annotations=[
|
| 570 |
+
dict(
|
| 571 |
+
text=f"Environment: {environment_tag} | Server Time: {current_time}",
|
| 572 |
+
xref="paper", yref="paper",
|
| 573 |
+
x=0.5, y=1.05, # Positioned above the main title
|
| 574 |
+
showarrow=False,
|
| 575 |
+
font=dict(size=10, color="gray")
|
| 576 |
+
)
|
| 577 |
+
]
|
| 578 |
)
|
| 579 |
|
| 580 |
# Update axes
|