Understood! My apologies for the previous format. You want surgical, line-by-line instructions. I will provide precise "replace this line" or "add this after/before this line" instructions.
Actionable, Line-by-Line Changes for finops_framework
1. Changes in finops_framework/api.py
File Path: your_project/finops_framework/api.py
Change 1: Update typing
imports.
-
Find this line (or similar):
from typing import List, Dict, Any
-
Replace with:
from typing import List, Dict, Any, Optional # Added Optional
Change 2: Modify display_charts_section
method signature.
-
Find this line (it's the start of the method definition):
def display_charts_section(self, section_title: str, chart_configs: List[Dict[str, Any]], sql_queries: Dict[str, str], current_start_date: date, current_end_date: date):
-
Replace the entire above block with:
def display_charts_section(self, section_title: str, chart_configs: List[Dict[str, Any]], sql_queries: Dict[str, str], current_start_date: date, current_end_date: date, extra_query_params: Optional[Dict[str, Any]] = None): # Added this line
Change 3: Update parameter passing within display_charts_section
.
-
Find this line (it will be inside the
for chart_config in chart_configs:
loop):
data = self._data_fetcher.execute_query(query_string)
-
Insert the following 3 lines immediately before the line you just found:
if extra_query_params: params.update(extra_query_params)
-
Then, modify the line you found (the
data = ...
line) to:
data = self._data_fetcher.execute_query(query_string, params) # Modified to pass params
2. Changes in finops_framework/core/data_fetcher.py
File Path: your_project/finops_framework/core/data_fetcher.py
Change 1: Update typing
and datetime
imports.
-
Find this line (or similar):
from typing import Dict, Any
-
Replace with:
from typing import Dict, Any, Tuple # Added Tuple
-
Find this line (or similar, if it exists):
# (no specific datetime import, or just 'from datetime import date')
-
Ensure this line is present (add if not):
from datetime import date, timedelta # Ensure timedelta is imported
Change 2: Modify execute_query
method signature and logic.
-
Find this line (it's the start of the method definition):
def execute_query(self, query_string: str) -> pd.DataFrame:
-
Replace the entire above block with:
def execute_query(self, query_string: str, params: Dict[str, Any] = None) -> pd.DataFrame: # Modified signature
-
Find these lines within the
execute_query
method (they represent the original query execution):
# For simplicity, directly execute. In a real app, you might parameterize. try: result = self._session.sql(query_string).collect() return pd.DataFrame(result) except Exception as e: raise DataFetchError(f"Snowflake query failed: {e}")
-
Replace the entire above block with:
if params is None: # Added these two lines params = {} # try: # Existing try block # Use self._session.sql().collect() for parameterized queries # Snowpark handles parameters securely with named binds result_df = self._session.sql(query_string).collect(_bind_parameters=params) # Modified this line return pd.DataFrame(result_df) except Exception as e: # Existing exception handling raise DataFetchError(f"Snowflake query failed: {e}")
Change 3: Add calculate_prev_period_dates
method.
- Find the very end of the
DataFetcher
class (afterexecute_query
). -
Add this entire method block at the end of the
DataFetcher
class:
def calculate_prev_period_dates(self, start_date: date, end_date: date) -> Tuple[date, date]: """ Calculates the start and end dates for the previous period of the same duration. """ duration = end_date - start_date prev_end_date = start_date - timedelta(days=1) prev_start_date = prev_end_date - duration return prev_start_date, prev_end_date
3. Changes in finops_framework/ui/visual_renderers.py
File Path: your_project/finops_framework/ui/visual_renderers.py
Change 1: Enhance _render_altair_chart
for theme colors (Optional but recommended for consistency).
-
Find this line (inside
_render_altair_chart
):
st.altair_chart(chart_builder(data, height), use_container_width=True)
-
Replace the entire above line with:
# Apply theme colors chart_obj = chart_builder(data, height) # Modified to create chart_obj chart_colors = st.session_state.get("app_theme", {}).get("chart_colors", []) if chart_colors: chart_obj = chart_obj.encode( color=alt.Color( alt.Color.field('color_col_placeholder', type="nominal"), # Placeholder for actual color column scale=alt.Scale(range=chart_colors) ) ).resolve_scale(color='independent') # Allow color scale to be independent st.altair_chart(chart_obj, use_container_width=True) # Uses chart_obj
Change 2: Modify render_line_chart
for color_col
.
-
Find this line (it's the start of the
render_line_chart
method definition):
def render_line_chart(self, data: pd.DataFrame, config: Dict[str, Any]):
-
Insert the following 3 lines immediately after the line you just found:
color_encoding = None if "color_col" in config and config["color_col"] in data.columns: color_encoding = alt.Color(config["color_col"], title=config["color_col"])
-
Find this line (inside the
encode
section):
tooltip=[config["x_col"], config["y_col"]]
-
Replace that line with:
color=color_encoding, # Added this line tooltip=[config["x_col"], config["y_col"]] + ([config["color_col"]] if color_encoding else []) # Modified tooltip
Change 3: Modify render_bar_chart
for color_col
and sort
.
-
Find this line (it's the start of the
render_bar_chart
method definition):
def render_bar_chart(self, data: pd.DataFrame, config: Dict[str, Any]):
-
Insert the following 3 lines immediately after the line you just found:
color_encoding = None if "color_col" in config and config["color_col"] in data.columns: color_encoding = alt.Color(config["color_col"], title=config["color_col"])
-
Find this line (inside the
encode
section, defining the x-axis):
x=alt.X(config["x_col"], title=config.get("x_axis_title", config["x_col"])),
-
Replace that line with:
x=alt.X( # Modified x-axis encoding config["x_col"], title=config.get("x_axis_title", config["x_col"]), sort="-y" if config.get("sort_desc") else None # Added sort option ),
-
Find this line (inside the
encode
section):
tooltip=[config["x_col"], config["y_col"]]
-
Replace that line with:
color=color_encoding, # Added this line tooltip=[config["x_col"], config["y_col"]] + ([config["color_col"]] if color_encoding else []) # Modified tooltip
Change 4: Modify render_area_chart
for color_col
.
-
Find this line (it's the start of the
render_area_chart
method definition):
def render_area_chart(self, data: pd.DataFrame, config: Dict[str, Any]):
-
Insert the following 3 lines immediately after the line you just found:
color_encoding = None if "color_col" in config and config["color_col"] in data.columns: color_encoding = alt.Color(config["color_col"], title=config["color_col"])
-
Find this line (inside the
encode
section):
tooltip=[config["x_col"], config["y_col"]]
-
Replace that line with:
color=color_encoding, # Added this line tooltip=[config["x_col"], config["y_col"]] + ([config["color_col"]] if color_encoding else []) # Modified tooltip
These precise instructions should allow you to update your framework files with the necessary enhancements. Once these changes are applied, app.py
and user30.py
should run as intended!
Top comments (0)