-
Notifications
You must be signed in to change notification settings - Fork 0
Fix formatting errors #580
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,7 +20,7 @@ | |
| async def get_categories( | ||
| request: Request, | ||
| current_user: str = Depends(get_current_active_user), | ||
| db: DataSource = Depends(get_data_source) | ||
| db: DataSource = Depends(get_data_source), | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Resolve shadowed
Suggested fix-from src.core.data.factory import get_data_source
from src.core.data.data_source import DataSource
from src.core.factory import get_data_sourceAlso applies to: 43-43 🤖 Prompt for AI Agents |
||
| ): | ||
| """ | ||
| Retrieves all categories from the database. | ||
|
|
@@ -40,7 +40,7 @@ async def create_category( | |
| request: Request, | ||
| category: CategoryCreate, | ||
| current_user: str = Depends(get_current_active_user), | ||
| db: DataSource = Depends(get_data_source) | ||
| db: DataSource = Depends(get_data_source), | ||
| ): | ||
| """ | ||
| Creates a new category in the database. | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -12,12 +12,15 @@ | |||||||||||||||||||
| router = APIRouter() | ||||||||||||||||||||
|
|
||||||||||||||||||||
| # Use absolute path for performance log file | ||||||||||||||||||||
| LOG_FILE = Path(__file__).resolve().parent.parent.parent / "performance_metrics_log.jsonl" | ||||||||||||||||||||
| LOG_FILE = ( | ||||||||||||||||||||
| Path(__file__).resolve().parent.parent.parent / "performance_metrics_log.jsonl" | ||||||||||||||||||||
| ) | ||||||||||||||||||||
|
|
||||||||||||||||||||
|
|
||||||||||||||||||||
| @router.get("/stats", response_model=ConsolidatedDashboardStats) | ||||||||||||||||||||
| async def get_dashboard_stats( | ||||||||||||||||||||
| repository: EmailRepository = Depends(get_email_repository), | ||||||||||||||||||||
| current_user: str = Depends(get_current_active_user) | ||||||||||||||||||||
| current_user: str = Depends(get_current_active_user), | ||||||||||||||||||||
|
Check failure on line 23 in modules/dashboard/routes.py
|
||||||||||||||||||||
| ): | ||||||||||||||||||||
| """ | ||||||||||||||||||||
| Retrieve consolidated dashboard statistics using efficient server-side aggregations. | ||||||||||||||||||||
|
|
@@ -34,11 +37,11 @@ | |||||||||||||||||||
| categorized_emails = await repository.get_category_breakdown(limit=10) | ||||||||||||||||||||
|
|
||||||||||||||||||||
| # Extract values from aggregates | ||||||||||||||||||||
| total_emails = aggregates.get('total_emails', 0) | ||||||||||||||||||||
| unread_emails = aggregates.get('unread_count', 0) | ||||||||||||||||||||
| auto_labeled = aggregates.get('auto_labeled', 0) | ||||||||||||||||||||
| categories_count = aggregates.get('categories_count', 0) | ||||||||||||||||||||
| weekly_growth_data = aggregates.get('weekly_growth') | ||||||||||||||||||||
| total_emails = aggregates.get("total_emails", 0) | ||||||||||||||||||||
| unread_emails = aggregates.get("unread_count", 0) | ||||||||||||||||||||
| auto_labeled = aggregates.get("auto_labeled", 0) | ||||||||||||||||||||
| categories_count = aggregates.get("categories_count", 0) | ||||||||||||||||||||
| weekly_growth_data = aggregates.get("weekly_growth") | ||||||||||||||||||||
|
|
||||||||||||||||||||
| # Calculate time_saved (2 minutes per auto-labeled email, matching legacy implementation) | ||||||||||||||||||||
| time_saved_minutes = auto_labeled * 2 | ||||||||||||||||||||
|
|
@@ -50,12 +53,12 @@ | |||||||||||||||||||
| weekly_growth = None | ||||||||||||||||||||
| if weekly_growth_data: | ||||||||||||||||||||
| weekly_growth = WeeklyGrowth( | ||||||||||||||||||||
| emails=weekly_growth_data.get('emails', 0), | ||||||||||||||||||||
| percentage=weekly_growth_data.get('percentage', 0.0) | ||||||||||||||||||||
| emails=weekly_growth_data.get("emails", 0), | ||||||||||||||||||||
| percentage=weekly_growth_data.get("percentage", 0.0), | ||||||||||||||||||||
| ) | ||||||||||||||||||||
|
|
||||||||||||||||||||
| # Performance metrics (keep existing logic for now) | ||||||||||||||||||||
| performance_metrics = defaultdict(lambda: {'total_duration': 0, 'count': 0}) | ||||||||||||||||||||
| performance_metrics = defaultdict(lambda: {"total_duration": 0, "count": 0}) | ||||||||||||||||||||
| try: | ||||||||||||||||||||
| with open(LOG_FILE, "r", encoding="utf-8") as f: | ||||||||||||||||||||
| for line in f: | ||||||||||||||||||||
|
|
@@ -64,17 +67,17 @@ | |||||||||||||||||||
| op = log_entry.get("operation") | ||||||||||||||||||||
| duration = log_entry.get("duration_seconds") | ||||||||||||||||||||
| if op and duration is not None: | ||||||||||||||||||||
| performance_metrics[op]['total_duration'] += duration | ||||||||||||||||||||
| performance_metrics[op]['count'] += 1 | ||||||||||||||||||||
| performance_metrics[op]["total_duration"] += duration | ||||||||||||||||||||
| performance_metrics[op]["count"] += 1 | ||||||||||||||||||||
| except json.JSONDecodeError: | ||||||||||||||||||||
| continue | ||||||||||||||||||||
| except FileNotFoundError: | ||||||||||||||||||||
| logger.warning(f"Performance log file not found: {LOG_FILE}") | ||||||||||||||||||||
|
|
||||||||||||||||||||
| avg_performance_metrics = { | ||||||||||||||||||||
| op: data['total_duration'] / data['count'] | ||||||||||||||||||||
| op: data["total_duration"] / data["count"] | ||||||||||||||||||||
| for op, data in performance_metrics.items() | ||||||||||||||||||||
| if data['count'] > 0 # Avoid division by zero | ||||||||||||||||||||
| if data["count"] > 0 # Avoid division by zero | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| return ConsolidatedDashboardStats( | ||||||||||||||||||||
|
|
@@ -88,5 +91,8 @@ | |||||||||||||||||||
| performance_metrics=avg_performance_metrics, | ||||||||||||||||||||
| ) | ||||||||||||||||||||
| except Exception as e: | ||||||||||||||||||||
| logger.error(f"Error fetching dashboard stats for user {current_user}: {e}", exc_info=True) | ||||||||||||||||||||
| logger.error( | ||||||||||||||||||||
| f"Error fetching dashboard stats for user {current_user}: {e}", | ||||||||||||||||||||
| exc_info=True, | ||||||||||||||||||||
| ) | ||||||||||||||||||||
|
Comment on lines
+94
to
+97
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid logging raw user identifiers in server error logs. Line 95 logs Suggested fix- logger.error(
- f"Error fetching dashboard stats for user {current_user}: {e}",
- exc_info=True,
- )
+ logger.error(
+ "Error fetching dashboard stats",
+ extra={"route": "dashboard_stats"},
+ exc_info=True,
+ )📝 Committable suggestion
Suggested change
🧰 Tools🪛 GitHub Check: SonarCloud Code Analysis[warning] 94-97: Change this code to not log user-controlled data. 🤖 Prompt for AI Agents |
||||||||||||||||||||
| raise HTTPException(status_code=500, detail="Error fetching dashboard stats.") | ||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: MasumRab/EmailIntelligence
Length of output: 3099
Fix the import errors in
test_launcher.pyinstead of silently excluding it from coverage.The project's own documentation (
test-path-issues-plan.md) documents thattest_launcher.pyhas a known import failure: it attempts to importPYTHON_MAX_VERSIONfromlaunch.py, but this constant doesn't exist. This PR excludes the test from coverage without fixing the underlying issue or documenting the exclusion.Rather than masking the broken test, resolve the import error so the test can run and contribute to coverage. If continued exclusion is necessary, document the reason explicitly in the CI workflow or a code comment.
🤖 Prompt for AI Agents