adloop 0.5.0__tar.gz → 0.5.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {adloop-0.5.0 → adloop-0.5.2}/PKG-INFO +2 -1
- {adloop-0.5.0 → adloop-0.5.2}/README.md +1 -0
- {adloop-0.5.0 → adloop-0.5.2}/pyproject.toml +1 -1
- {adloop-0.5.0 → adloop-0.5.2}/src/adloop/__init__.py +1 -1
- {adloop-0.5.0 → adloop-0.5.2}/src/adloop/ads/write.py +21 -14
- {adloop-0.5.0 → adloop-0.5.2}/src/adloop/__main__.py +0 -0
- {adloop-0.5.0 → adloop-0.5.2}/src/adloop/ads/__init__.py +0 -0
- {adloop-0.5.0 → adloop-0.5.2}/src/adloop/ads/client.py +0 -0
- {adloop-0.5.0 → adloop-0.5.2}/src/adloop/ads/currency.py +0 -0
- {adloop-0.5.0 → adloop-0.5.2}/src/adloop/ads/forecast.py +0 -0
- {adloop-0.5.0 → adloop-0.5.2}/src/adloop/ads/gaql.py +0 -0
- {adloop-0.5.0 → adloop-0.5.2}/src/adloop/ads/pmax.py +0 -0
- {adloop-0.5.0 → adloop-0.5.2}/src/adloop/ads/read.py +0 -0
- {adloop-0.5.0 → adloop-0.5.2}/src/adloop/auth.py +0 -0
- {adloop-0.5.0 → adloop-0.5.2}/src/adloop/bundled_credentials.json +0 -0
- {adloop-0.5.0 → adloop-0.5.2}/src/adloop/cli.py +0 -0
- {adloop-0.5.0 → adloop-0.5.2}/src/adloop/config.py +0 -0
- {adloop-0.5.0 → adloop-0.5.2}/src/adloop/crossref.py +0 -0
- {adloop-0.5.0 → adloop-0.5.2}/src/adloop/ga4/__init__.py +0 -0
- {adloop-0.5.0 → adloop-0.5.2}/src/adloop/ga4/client.py +0 -0
- {adloop-0.5.0 → adloop-0.5.2}/src/adloop/ga4/reports.py +0 -0
- {adloop-0.5.0 → adloop-0.5.2}/src/adloop/ga4/tracking.py +0 -0
- {adloop-0.5.0 → adloop-0.5.2}/src/adloop/safety/__init__.py +0 -0
- {adloop-0.5.0 → adloop-0.5.2}/src/adloop/safety/audit.py +0 -0
- {adloop-0.5.0 → adloop-0.5.2}/src/adloop/safety/guards.py +0 -0
- {adloop-0.5.0 → adloop-0.5.2}/src/adloop/safety/preview.py +0 -0
- {adloop-0.5.0 → adloop-0.5.2}/src/adloop/server.py +0 -0
- {adloop-0.5.0 → adloop-0.5.2}/src/adloop/tracking.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: adloop
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.2
|
|
4
4
|
Summary: Stop switching between Google Ads, GA4, and your code editor to figure out why conversions dropped.
|
|
5
5
|
Keywords: mcp,google-ads,google-analytics,ga4,cursor,marketing
|
|
6
6
|
Author: Daniel Klose
|
|
@@ -392,6 +392,7 @@ What's been shipped and what's next:
|
|
|
392
392
|
- ~~PyPI package~~ ✓ — `pip install adloop`
|
|
393
393
|
- ~~Bundled OAuth credentials~~ ✓ — no Google Cloud project required, auto-discovery of GA4/Ads accounts
|
|
394
394
|
- ~~Headless server support~~ ✓ — manual URL copy-paste flow for servers without a browser
|
|
395
|
+
- ~~Behavioral eval suites~~ ✓ — 28 prompt-and-expectation tests covering read, write, tracking, and planning workflows
|
|
395
396
|
- **Community launch** — HN, Indie Hackers, r/cursor, Twitter
|
|
396
397
|
- **Video walkthrough**
|
|
397
398
|
|
|
@@ -368,6 +368,7 @@ What's been shipped and what's next:
|
|
|
368
368
|
- ~~PyPI package~~ ✓ — `pip install adloop`
|
|
369
369
|
- ~~Bundled OAuth credentials~~ ✓ — no Google Cloud project required, auto-discovery of GA4/Ads accounts
|
|
370
370
|
- ~~Headless server support~~ ✓ — manual URL copy-paste flow for servers without a browser
|
|
371
|
+
- ~~Behavioral eval suites~~ ✓ — 28 prompt-and-expectation tests covering read, write, tracking, and planning workflows
|
|
371
372
|
- **Community launch** — HN, Indie Hackers, r/cursor, Twitter
|
|
372
373
|
- **Video walkthrough**
|
|
373
374
|
|
|
@@ -2525,22 +2525,29 @@ def _apply_create_negative_keyword_list(
|
|
|
2525
2525
|
) -> dict:
|
|
2526
2526
|
"""Create a shared negative keyword list and attach it to a campaign.
|
|
2527
2527
|
|
|
2528
|
-
Executes three sequential API calls. If step
|
|
2529
|
-
includes partial_failure info with the SharedSet resource name
|
|
2530
|
-
caller can clean up or retry the remaining steps.
|
|
2528
|
+
Executes three sequential API calls. If any step fails, the result
|
|
2529
|
+
includes partial_failure info with the SharedSet resource name (if
|
|
2530
|
+
created) so the caller can clean up or retry the remaining steps.
|
|
2531
2531
|
"""
|
|
2532
|
-
shared_set_resource = None
|
|
2533
|
-
|
|
2534
2532
|
# 1. Create the SharedSet
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2533
|
+
try:
|
|
2534
|
+
shared_set_service = client.get_service("SharedSetService")
|
|
2535
|
+
ss_op = client.get_type("SharedSetOperation")
|
|
2536
|
+
shared_set = ss_op.create
|
|
2537
|
+
shared_set.name = changes["list_name"]
|
|
2538
|
+
shared_set.type_ = client.enums.SharedSetTypeEnum.NEGATIVE_KEYWORDS
|
|
2539
|
+
ss_response = shared_set_service.mutate_shared_sets(
|
|
2540
|
+
customer_id=cid, operations=[ss_op]
|
|
2541
|
+
)
|
|
2542
|
+
shared_set_resource = ss_response.results[0].resource_name
|
|
2543
|
+
except Exception as exc:
|
|
2544
|
+
return {
|
|
2545
|
+
"partial_failure": True,
|
|
2546
|
+
"shared_set_resource": None,
|
|
2547
|
+
"completed_steps": [],
|
|
2548
|
+
"failed_step": "create_shared_set",
|
|
2549
|
+
"error": _extract_error_message(exc),
|
|
2550
|
+
}
|
|
2544
2551
|
|
|
2545
2552
|
# 2. Add keywords to the list
|
|
2546
2553
|
try:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|