Skip to content

Commit dbee332

Browse files
✨ Support all countries in impression-share correlate
Remove requirement for --country flag. Command now automatically iterates through all countries found in impression share data and builds keyword indices for each. - Country column added to output table - Results sorted by share, then country, then search term - Still supports --country flag to filter to single country
1 parent 23fa99c commit dbee332

File tree

1 file changed

+40
-26
lines changed

1 file changed

+40
-26
lines changed

asa_api_cli/impression_share.py

Lines changed: 40 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,7 @@ def correlate_impression_share(
637637
] = 7,
638638
country: Annotated[
639639
str | None,
640-
typer.Option("--country", "-c", help="Filter by country code (required for correlation)"),
640+
typer.Option("--country", "-c", help="Filter by country code (optional, defaults to all)"),
641641
] = None,
642642
min_share: Annotated[
643643
float | None,
@@ -673,16 +673,12 @@ def correlate_impression_share(
673673
campaign-level attribution for impression share data.
674674
675675
Examples:
676-
asa impression-share correlate --country US
677-
asa impression-share correlate --country AU --min-share 30
678-
asa impression-share correlate --country US --unmatched # New keyword opportunities
679-
asa impression-share correlate --country US --matched --min-share 40 # Bid increase candidates
676+
asa impression-share correlate # All countries
677+
asa impression-share correlate --country US # Single country
678+
asa impression-share correlate --min-share 30 # Low share only
679+
asa impression-share correlate --unmatched # New keyword opportunities
680+
asa impression-share correlate --matched --min-share 40 # Bid increase candidates
680681
"""
681-
if not country:
682-
print_error("Error", "Country is required for correlation. Use --country/-c")
683-
raise typer.Exit(1)
684-
685-
country = country.upper()
686682
client = get_client()
687683

688684
if days > 30:
@@ -692,6 +688,8 @@ def correlate_impression_share(
692688
end_date = date.today() - timedelta(days=1)
693689
start_date = end_date - timedelta(days=days - 1)
694690

691+
country_codes = [country.upper()] if country else None
692+
695693
try:
696694
with client:
697695
# Step 1: Get impression share data
@@ -700,39 +698,47 @@ def correlate_impression_share(
700698
start_date=start_date,
701699
end_date=end_date,
702700
granularity=GranularityType.DAILY,
703-
country_codes=[country],
701+
country_codes=country_codes,
704702
poll_interval=3.0,
705703
timeout=120.0,
706704
)
707705

708706
if not report.row:
709-
print_warning(f"No impression share data available for {country}")
707+
print_warning("No impression share data available")
710708
return
711709

712710
print_success(f"Retrieved {len(report.row)} impression share records")
713711

714-
# Step 2: Build keyword index for this country
715-
with spinner(f"Building keyword index for {country}..."):
716-
keyword_index = _build_keyword_index(client, country)
717-
718-
total_kw = sum(len(v) for v in keyword_index.values())
719-
print_info(f"Indexed {total_kw} keywords from {len(keyword_index)} unique terms")
720-
721-
# Step 3: Correlate data
712+
# Parse and aggregate data
722713
share_data = _parse_report_data(report)
723714
aggregated = _aggregate_by_search_term(share_data)
724715

716+
# Find all unique countries in the data
717+
countries_in_data = {item.country.upper() for item in aggregated.values() if item.country}
718+
print_info(f"Found data for {len(countries_in_data)} countries: {', '.join(sorted(countries_in_data))}")
719+
720+
# Step 2: Build keyword index for each country
721+
keyword_indices: dict[str, dict[str, list[KeywordInfo]]] = {}
722+
total_keywords = 0
723+
724+
for ctry in countries_in_data:
725+
with spinner(f"Building keyword index for {ctry}..."):
726+
keyword_indices[ctry] = _build_keyword_index(client, ctry)
727+
kw_count = sum(len(v) for v in keyword_indices[ctry].values())
728+
total_keywords += kw_count
729+
730+
print_info(f"Indexed {total_keywords} keywords across {len(countries_in_data)} countries")
731+
732+
# Step 3: Correlate data
725733
correlated: list[CorrelatedSearchTerm] = []
726734
for item in aggregated.values():
727-
if item.country.upper() != country:
728-
continue
729-
735+
ctry = item.country.upper()
736+
keyword_index = keyword_indices.get(ctry, {})
730737
search_term_lower = item.search_term.lower()
731738
matched_keywords = keyword_index.get(search_term_lower, [])
732739

733740
if matched_keywords:
734741
# Use first match (could be multiple campaigns with same keyword)
735-
# TODO: Could show all matches or pick based on criteria
736742
match = matched_keywords[0]
737743
correlated.append(
738744
CorrelatedSearchTerm(
@@ -782,7 +788,7 @@ def correlate_impression_share(
782788
return
783789

784790
# Sort by share (lowest first)
785-
correlated.sort(key=lambda x: x.avg_share)
791+
correlated.sort(key=lambda x: (x.avg_share, x.country, x.search_term))
786792

787793
# Stats
788794
matched_count = sum(1 for c in correlated if c.is_matched)
@@ -835,8 +841,15 @@ def correlate_impression_share(
835841
# Display table
836842
display_limit = len(correlated) if limit == 0 else limit
837843

838-
table = Table(title=f"Impression Share Correlation - {country}")
844+
title = "Impression Share Correlation"
845+
if country:
846+
title += f" - {country.upper()}"
847+
else:
848+
title += f" - All Countries ({len(countries_in_data)})"
849+
850+
table = Table(title=title)
839851
table.add_column("Search Term", style="cyan", max_width=30)
852+
table.add_column("Ctry", style="dim", width=4)
840853
table.add_column("Share", justify="right", width=8)
841854
table.add_column("Campaign", style="magenta", max_width=25)
842855
table.add_column("Keyword", style="dim", max_width=20)
@@ -857,6 +870,7 @@ def correlate_impression_share(
857870

858871
table.add_row(
859872
row.search_term[:30],
873+
row.country,
860874
f"[{share_style}]{row.share_range}[/{share_style}]",
861875
campaign_display,
862876
keyword_display,

0 commit comments

Comments
 (0)