Spaces:
Running
Running
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
|