Skip to content

Commit 86fb756

Browse files
committed
chore: Linting
1 parent d785907 commit 86fb756

2 files changed

Lines changed: 42 additions & 82 deletions

File tree

analytics_mcp/tools/reporting/core.py

Lines changed: 36 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ async def run_report(
270270

271271
return proto_to_dict(response)
272272

273+
273274
async def run_funnel_report(
274275
property_id: int | str,
275276
funnel_steps: List[Dict[str, Any]],
@@ -290,7 +291,7 @@ async def run_funnel_report(
290291
- 'name': (str) Display name for the step
291292
- 'filter_expression': (Dict) Complete filter expression for the step
292293
OR for simple event-based steps:
293-
- 'name': (str) Display name for the step
294+
- 'name': (str) Display name for the step
294295
- 'event': (str) Event name to filter on
295296
Example:
296297
[
@@ -322,17 +323,17 @@ async def run_funnel_report(
322323
Example: {"next_action_dimension": "eventName", "limit": 5}
323324
segments: Optional list of segments to apply to the funnel.
324325
return_property_quota: Whether to return current property quota information.
325-
326+
326327
Returns:
327328
Dict containing the funnel report response with funnel results including:
328329
- funnel_table: Table showing progression through funnel steps
329330
- funnel_visualization: Data for visualizing the funnel
330331
- property_quota: (if requested) Current quota usage information
331-
332+
332333
Raises:
333334
ValueError: If funnel_steps is empty or contains invalid configurations
334335
Exception: If the API request fails
335-
336+
336337
Example:
337338
# Simple event-based funnel
338339
result = await run_funnel_report(
@@ -343,7 +344,7 @@ async def run_funnel_report(
343344
{"name": "Purchase", "event": "purchase"}
344345
]
345346
)
346-
347+
347348
# Advanced funnel with page path filtering
348349
result = await run_funnel_report(
349350
property_id="123456789",
@@ -375,109 +376,65 @@ async def run_funnel_report(
375376
date_ranges=[{"start_date": "7daysAgo", "end_date": "today"}]
376377
)
377378
"""
378-
# Validate inputs
379-
if not funnel_steps:
380-
raise ValueError("funnel_steps cannot be empty")
381-
382-
if len(funnel_steps) < 2:
383-
raise ValueError("funnel_steps must contain at least 2 steps")
384-
385-
# Set default date range if not provided
386-
if not date_ranges:
387-
date_ranges = [{"start_date": "30daysAgo", "end_date": "today"}]
388-
389-
# Validate and create funnel steps
379+
390380
steps = []
391381
for i, step in enumerate(funnel_steps):
392382
if not isinstance(step, dict):
393383
raise ValueError(f"Step {i+1} must be a dictionary")
394-
395-
step_name = step.get('name', f'Step {i+1}')
396-
397-
# Build filter expression
398-
if 'filter_expression' in step:
399-
# Use provided filter expression
400-
filter_expr = data_v1alpha.FunnelFilterExpression(step['filter_expression'])
401-
elif 'event' in step:
402-
# Simple event-based filter
384+
385+
step_name = step.get("name", f"Step {i+1}")
386+
387+
if "filter_expression" in step:
388+
filter_expr = data_v1alpha.FunnelFilterExpression(
389+
step["filter_expression"]
390+
)
391+
elif "event" in step:
403392
filter_expr = data_v1alpha.FunnelFilterExpression(
404393
funnel_event_filter=data_v1alpha.FunnelEventFilter(
405-
event_name=step['event']
394+
event_name=step["event"]
406395
)
407396
)
408397
else:
409398
raise ValueError(
410399
f"Step {i+1} must contain either 'filter_expression' or 'event' key"
411400
)
412-
401+
413402
funnel_step = data_v1alpha.FunnelStep(
414-
name=step_name,
415-
filter_expression=filter_expr
403+
name=step_name, filter_expression=filter_expr
416404
)
417405
steps.append(funnel_step)
418-
419-
# Create the funnel configuration
420-
funnel_config = data_v1alpha.Funnel(steps=steps)
421-
422-
# Create date ranges
423-
date_range_objects = []
424-
for dr in date_ranges:
425-
if not isinstance(dr, dict) or 'start_date' not in dr or 'end_date' not in dr:
426-
raise ValueError(
427-
"Each date range must be a dictionary with 'start_date' and 'end_date' keys"
428-
)
429-
date_range_objects.append(
430-
data_v1alpha.DateRange(start_date=dr['start_date'], end_date=dr['end_date'])
431-
)
432406

433-
# Create the request
434407
request = data_v1alpha.RunFunnelReportRequest(
435408
property=construct_property_rn(property_id),
436-
funnel=funnel_config,
437-
date_ranges=date_range_objects,
438-
return_property_quota=return_property_quota
409+
funnel=data_v1alpha.Funnel(steps=steps),
410+
date_ranges=[data_v1alpha.DateRange(dr) for dr in date_ranges],
411+
return_property_quota=return_property_quota,
439412
)
440-
441-
# Add breakdown if specified (this goes on the request, not the funnel)
442-
if funnel_breakdown and 'breakdown_dimension' in funnel_breakdown:
413+
414+
if funnel_breakdown and "breakdown_dimension" in funnel_breakdown:
443415
request.funnel_breakdown = data_v1alpha.FunnelBreakdown(
444416
breakdown_dimension=data_v1alpha.Dimension(
445-
name=funnel_breakdown['breakdown_dimension']
417+
name=funnel_breakdown["breakdown_dimension"]
446418
)
447419
)
448-
449-
# Add next action if specified (this also goes on the request, not the funnel)
450-
if funnel_next_action and 'next_action_dimension' in funnel_next_action:
420+
421+
if funnel_next_action and "next_action_dimension" in funnel_next_action:
451422
next_action_config = data_v1alpha.FunnelNextAction(
452423
next_action_dimension=data_v1alpha.Dimension(
453-
name=funnel_next_action['next_action_dimension']
424+
name=funnel_next_action["next_action_dimension"]
454425
)
455426
)
456-
if 'limit' in funnel_next_action:
457-
next_action_config.limit = funnel_next_action['limit']
427+
if "limit" in funnel_next_action:
428+
next_action_config.limit = funnel_next_action["limit"]
458429
request.funnel_next_action = next_action_config
459-
460-
# Add segments if provided
430+
461431
if segments:
462-
request.segments = [data_v1alpha.Segment(segment) for segment in segments]
463-
464-
# Execute the request with enhanced error handling
465-
try:
466-
client = create_data_api_alpha_client()
467-
response = await client.run_funnel_report(request=request)
468-
return proto_to_dict(response)
469-
except Exception as e:
470-
error_msg = str(e)
471-
if "INVALID_ARGUMENT" in error_msg:
472-
raise ValueError(f"Invalid funnel configuration: {error_msg}")
473-
elif "PERMISSION_DENIED" in error_msg:
474-
raise PermissionError(f"Permission denied accessing property: {error_msg}")
475-
elif "NOT_FOUND" in error_msg:
476-
raise ValueError(f"Property not found: {error_msg}")
477-
elif "QUOTA_EXCEEDED" in error_msg:
478-
raise RuntimeError(f"API quota exceeded: {error_msg}")
479-
else:
480-
raise Exception(f"Failed to run funnel report: {error_msg}")
432+
request.segments = [
433+
data_v1alpha.Segment(segment) for segment in segments
434+
]
435+
436+
response = await create_data_api_alpha_client().run_funnel_report(request)
437+
return proto_to_dict(response)
481438

482439

483440
# The `run_report` tool requires a more complex description that's generated at

analytics_mcp/tools/utils.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ def _get_package_version_with_fallback():
4646
"https://www.googleapis.com/auth/analytics.readonly"
4747
)
4848

49+
4950
def _create_credentials() -> google.auth.credentials.Credentials:
5051
"""Returns Application Default Credentials with read-only scope."""
5152
(credentials, _) = google.auth.default(scopes=[_READ_ONLY_ANALYTICS_SCOPE])
@@ -72,14 +73,16 @@ def create_data_api_client() -> data_v1beta.BetaAnalyticsDataAsyncClient:
7273
)
7374

7475

75-
def create_data_api_alpha_client() -> data_v1alpha.AlphaAnalyticsDataAsyncClient:
76+
def create_data_api_alpha_client() -> (
77+
data_v1alpha.AlphaAnalyticsDataAsyncClient
78+
):
7679
"""Returns a properly configured Google Analytics Data API (Alpha) async client.
7780
7881
Uses Application Default Credentials with read-only scope.
79-
"""
82+
"""
8083
return data_v1alpha.AlphaAnalyticsDataAsyncClient(
8184
client_info=_CLIENT_INFO, credentials=_create_credentials()
82-
)
85+
)
8386

8487

8588
def construct_property_rn(property_value: int | str) -> str:

0 commit comments

Comments
 (0)