Skip to content

Commit 8b76a26

Browse files
✨ Update summary to group by app with separators
- Group summary by app first, then by country within each app - Show app name only on first row of each group - Add visual separator between apps using end_section - Sort apps alphabetically, countries by search term count - Update totals to show apps and countries count
1 parent 715df4b commit 8b76a26

File tree

1 file changed

+55
-32
lines changed

1 file changed

+55
-32
lines changed

asa_api_cli/impression_share.py

Lines changed: 55 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -413,10 +413,10 @@ def share_summary(
413413
typer.Option("--days", "-d", help="Number of days to analyze (max 30)"),
414414
] = 7,
415415
) -> None:
416-
"""Show impression share summary by country.
416+
"""Show impression share summary by app and country.
417417
418418
Provides a high-level overview of your impression share performance
419-
grouped by country/region.
419+
grouped by app, then by country/region.
420420
421421
Examples:
422422
asa impression-share summary --days 14
@@ -449,50 +449,73 @@ def share_summary(
449449

450450
data = _parse_report_data(report)
451451

452-
# Aggregate by country
453-
by_country: dict[str, list[SearchTermShareData]] = {}
452+
# Aggregate by app, then by country
453+
by_app: dict[str, dict[str, list[SearchTermShareData]]] = {}
454454
for item in data:
455-
if item.country not in by_country:
456-
by_country[item.country] = []
457-
by_country[item.country].append(item)
455+
app_name = item.app_name or "Unknown"
456+
if app_name not in by_app:
457+
by_app[app_name] = {}
458+
if item.country not in by_app[app_name]:
459+
by_app[app_name][item.country] = []
460+
by_app[app_name][item.country].append(item)
458461

459462
table = Table(title=f"Impression Share Summary ({days} days)")
463+
table.add_column("App", style="magenta", no_wrap=True)
460464
table.add_column("Country", style="cyan")
461465
table.add_column("Search Terms", justify="right")
462466
table.add_column("Avg Share", justify="right")
463467
table.add_column("<30%", justify="right", style="red")
464468
table.add_column("30-50%", justify="right", style="yellow")
465469
table.add_column(">50%", justify="right", style="green")
466470

467-
# Calculate stats per country
468-
summary_rows = []
469-
for country, items in by_country.items():
470-
unique_terms = len({i.search_term for i in items})
471-
avg_shares = [i.avg_share for i in items if i.avg_share > 0]
472-
avg_share = sum(avg_shares) / len(avg_shares) if avg_shares else 0
471+
# Sort apps alphabetically
472+
total_terms = 0
473+
total_countries = set()
473474

474-
low_count = sum(1 for i in items if i.high_share and i.high_share < 0.3)
475-
mid_count = sum(1 for i in items if i.high_share and 0.3 <= i.high_share < 0.5)
476-
high_count = sum(1 for i in items if i.high_share and i.high_share >= 0.5)
475+
for app_name in sorted(by_app.keys()):
476+
countries_data = by_app[app_name]
477477

478-
summary_rows.append(
479-
(country, unique_terms, avg_share, low_count, mid_count, high_count)
480-
)
478+
# Calculate stats per country for this app
479+
country_rows = []
480+
for country, items in countries_data.items():
481+
unique_terms = len({i.search_term for i in items})
482+
avg_shares = [i.avg_share for i in items if i.avg_share > 0]
483+
avg_share = sum(avg_shares) / len(avg_shares) if avg_shares else 0
481484

482-
# Sort by number of terms
483-
summary_rows.sort(key=lambda x: x[1], reverse=True)
485+
low_count = sum(1 for i in items if i.high_share and i.high_share < 0.3)
486+
mid_count = sum(
487+
1 for i in items if i.high_share and 0.3 <= i.high_share < 0.5
488+
)
489+
high_count = sum(1 for i in items if i.high_share and i.high_share >= 0.5)
484490

485-
for country, terms, avg, low, mid, high in summary_rows:
486-
table.add_row(
487-
country,
488-
str(terms),
489-
f"{avg * 100:.0f}%",
490-
str(low),
491-
str(mid),
492-
str(high),
493-
)
491+
country_rows.append(
492+
(country, unique_terms, avg_share, low_count, mid_count, high_count)
493+
)
494+
total_terms += unique_terms
495+
total_countries.add(country)
496+
497+
# Sort by number of terms within each app
498+
country_rows.sort(key=lambda x: x[1], reverse=True)
499+
500+
# Add rows with app name on first row only
501+
for i, (country, terms, avg, low, mid, high) in enumerate(country_rows):
502+
table.add_row(
503+
app_name[:25] if i == 0 else "",
504+
country,
505+
str(terms),
506+
f"{avg * 100:.0f}%",
507+
str(low),
508+
str(mid),
509+
str(high),
510+
)
511+
512+
# Add separator between apps (if not last app)
513+
if app_name != sorted(by_app.keys())[-1]:
514+
table.add_row("", "", "", "", "", "", "", end_section=True)
494515

495516
console.print(table)
496517

497-
total_terms = sum(r[1] for r in summary_rows)
498-
print_info(f"\nTotal: {total_terms} unique search terms across {len(by_country)} countries")
518+
print_info(
519+
f"\nTotal: {total_terms} search terms across {len(by_app)} apps "
520+
f"and {len(total_countries)} countries"
521+
)

0 commit comments

Comments
 (0)