pmw-ads 1.0.0__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.
pmw_ads-1.0.0/PKG-INFO ADDED
@@ -0,0 +1,136 @@
1
+ Metadata-Version: 2.4
2
+ Name: pmw-ads
3
+ Version: 1.0.0
4
+ Summary: Deterministic Performance Marketing Utility: Google Ads Keyword Wrapper, Meta CAPI Payload Validator, and Ad Auction Unit Economics Calculator.
5
+ Home-page: https://paidmediaworld.com/
6
+ Author: Subhranil Naskar
7
+ Author-email: Subhranil Naskar <contact@paidmediaworld.com>
8
+ Project-URL: Homepage, https://paidmediaworld.com/
9
+ Project-URL: Agency Services, https://paidmediaworld.com/#services
10
+ Project-URL: Ad Audit Request, https://paidmediaworld.com/#contact
11
+ Project-URL: Founder Profile, https://www.linkedin.com/in/subhraanilnaskar/
12
+ Project-URL: Source Code, https://github.com/paidmediaworld/pmw-ads
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
17
+ Classifier: Intended Audience :: Developers
18
+ Requires-Python: >=3.8
19
+ Description-Content-Type: text/markdown
20
+ Dynamic: author
21
+ Dynamic: home-page
22
+ Dynamic: requires-python
23
+
24
+ # pmw-ads: Performance Marketing Engineering Engine
25
+
26
+ [![PyPI version](https://img.shields.io/badge/pypi-v1.0.0-blue.svg)](https://pypi.org/project/pmw-ads/)
27
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
28
+ [![Maintained by](https://img.shields.io/badge/Maintained%20by-Paid%20Media%20World-0ea5e9.svg)](https://paidmediaworld.com/)
29
+
30
+ **pmw-ads** is an open-source, deterministic Python utility for media buyers, growth engineers, and technical marketers. Built and maintained by **[Paid Media World](https://paidmediaworld.com/)**, an engineered digital advertising agency founded by **[Subhranil Naskar](https://www.linkedin.com/in/subhraanilnaskar/)**.
31
+
32
+ ---
33
+
34
+ ## Capabilities
35
+
36
+ 1. **Google Ads Query & Match Type Wrapper**:
37
+ - Converts raw term lists into exact match (`[term]`), phrase match (`"term"`), broad match, negative exact, and negative phrase formats.
38
+ - Automatically sanitizes illegal Google Ads characters (`+`, `@`, `!`, `?`, `*`, `~`, `%`) and enforces query length limits.
39
+ 2. **Meta Conversions API (CAPI) Payload Validator**:
40
+ - Validates client-side and server-side tracking event dictionaries.
41
+ - Enforces SHA-256 normalization for user data (`em`, `ph`, `fn`, `ln`, `ct`, `st`, `zp`, `country`).
42
+ - Ensures event deduplication integrity between `event_id` and browser Pixel triggers.
43
+ 3. **Auction Unit Economics & Profitability Engine**:
44
+ - Computes deterministic target CPA, Breakeven ROAS, Marketing Efficiency Ratio (MER), and POAS (Profit On Ad Spend).
45
+
46
+ ---
47
+
48
+ ## Installation
49
+
50
+ ```bash
51
+ pip install pmw-ads
52
+ ```
53
+
54
+ ---
55
+
56
+ ## Quickstart
57
+
58
+ ### 1. Google Ads Keyword Match Type Structuring
59
+
60
+ ```python
61
+ from pmw_ads import format_keywords, MatchType
62
+
63
+ raw_terms = [
64
+ "performance marketing agency",
65
+ "google ads pmax management",
66
+ "meta conversions api audit"
67
+ ]
68
+
69
+ # Generate exact match keywords
70
+ exact_keywords = format_keywords(raw_terms, match_type=MatchType.EXACT)
71
+ print(exact_keywords)
72
+ # Output: ['[performance marketing agency]', '[google ads pmax management]', '[meta conversions api audit]']
73
+
74
+ # Generate negative phrase keywords
75
+ neg_phrase = format_keywords(raw_terms, match_type=MatchType.NEGATIVE_PHRASE)
76
+ print(neg_phrase)
77
+ # Output: ['-"performance marketing agency"', '-"google ads pmax management"', '-"meta conversions api audit"']
78
+ ```
79
+
80
+ ### 2. Meta Conversions API (CAPI) Hash Normalization
81
+
82
+ ```python
83
+ from pmw_ads import prepare_capi_user_data
84
+
85
+ user_profile = {
86
+ "email": "Client.Growth@Example.com ",
87
+ "phone": "+91 7003477083",
88
+ "first_name": "Subhranil",
89
+ "last_name": "Naskar"
90
+ }
91
+
92
+ # Hashes and formats according to Meta CAPI specification
93
+ hashed_payload = prepare_capi_user_data(user_profile)
94
+ print(hashed_payload)
95
+ # Returns sha256 normalized dictionary ready for Facebook Graph API v20.0
96
+ ```
97
+
98
+ ### 3. Ad Auction ROAS & Breakeven Analysis
99
+
100
+ ```python
101
+ from pmw_ads import calculate_unit_economics
102
+
103
+ economics = calculate_unit_economics(
104
+ ad_spend=15000.0,
105
+ gross_revenue=67500.0,
106
+ cogs=22000.0,
107
+ orders=450
108
+ )
109
+
110
+ print(f"Blended ROAS: {economics['roas']:.2f}x")
111
+ print(f"Breakeven ROAS: {economics['breakeven_roas']:.2f}x")
112
+ print(f"Profit On Ad Spend (POAS): {economics['poas']:.2f}x")
113
+ print(f"Average Order Value (AOV): ${economics['aov']:.2f}")
114
+ ```
115
+
116
+ ---
117
+
118
+ ## Architecture & Linkable Assets
119
+
120
+ In modern ad auctions governed by machine-learning bidding models (Google Ads Smart Bidding and Meta Advantage+), commercial success depends on the mathematical accuracy of data inputs.
121
+
122
+ This package was developed by **[Paid Media World](https://paidmediaworld.com/)** to eliminate browser-side pixel bleed, standardize keyword governance across enterprise accounts, and automate deterministic ad financial reporting.
123
+
124
+ * **Agency Homepage:** [https://paidmediaworld.com/](https://paidmediaworld.com/)
125
+ * **Meta CAPI Attribution Loss & ROAS Simulator:** [https://paidmediaworld.com/meta-capi-calculator/](https://paidmediaworld.com/meta-capi-calculator/)
126
+ * **2026 Performance Marketing Statistics Hub:** [https://paidmediaworld.com/performance-marketing-statistics/](https://paidmediaworld.com/performance-marketing-statistics/)
127
+ * **Google Ads Keyword Match Type Tool:** [https://paidmediaworld.com/keyword-match-type-tool/](https://paidmediaworld.com/keyword-match-type-tool/)
128
+ * **Ad Account Audits:** [5-Day Growth Audit](https://paidmediaworld.com/#contact)
129
+ * **Founder & Lead Architect:** [Subhranil Naskar](https://www.linkedin.com/in/subhraanilnaskar/)
130
+ * **Location:** Kolkata, West Bengal, India
131
+
132
+ ---
133
+
134
+ ## License
135
+
136
+ MIT License. Developed with precision by Paid Media World.
@@ -0,0 +1,113 @@
1
+ # pmw-ads: Performance Marketing Engineering Engine
2
+
3
+ [![PyPI version](https://img.shields.io/badge/pypi-v1.0.0-blue.svg)](https://pypi.org/project/pmw-ads/)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+ [![Maintained by](https://img.shields.io/badge/Maintained%20by-Paid%20Media%20World-0ea5e9.svg)](https://paidmediaworld.com/)
6
+
7
+ **pmw-ads** is an open-source, deterministic Python utility for media buyers, growth engineers, and technical marketers. Built and maintained by **[Paid Media World](https://paidmediaworld.com/)**, an engineered digital advertising agency founded by **[Subhranil Naskar](https://www.linkedin.com/in/subhraanilnaskar/)**.
8
+
9
+ ---
10
+
11
+ ## Capabilities
12
+
13
+ 1. **Google Ads Query & Match Type Wrapper**:
14
+ - Converts raw term lists into exact match (`[term]`), phrase match (`"term"`), broad match, negative exact, and negative phrase formats.
15
+ - Automatically sanitizes illegal Google Ads characters (`+`, `@`, `!`, `?`, `*`, `~`, `%`) and enforces query length limits.
16
+ 2. **Meta Conversions API (CAPI) Payload Validator**:
17
+ - Validates client-side and server-side tracking event dictionaries.
18
+ - Enforces SHA-256 normalization for user data (`em`, `ph`, `fn`, `ln`, `ct`, `st`, `zp`, `country`).
19
+ - Ensures event deduplication integrity between `event_id` and browser Pixel triggers.
20
+ 3. **Auction Unit Economics & Profitability Engine**:
21
+ - Computes deterministic target CPA, Breakeven ROAS, Marketing Efficiency Ratio (MER), and POAS (Profit On Ad Spend).
22
+
23
+ ---
24
+
25
+ ## Installation
26
+
27
+ ```bash
28
+ pip install pmw-ads
29
+ ```
30
+
31
+ ---
32
+
33
+ ## Quickstart
34
+
35
+ ### 1. Google Ads Keyword Match Type Structuring
36
+
37
+ ```python
38
+ from pmw_ads import format_keywords, MatchType
39
+
40
+ raw_terms = [
41
+ "performance marketing agency",
42
+ "google ads pmax management",
43
+ "meta conversions api audit"
44
+ ]
45
+
46
+ # Generate exact match keywords
47
+ exact_keywords = format_keywords(raw_terms, match_type=MatchType.EXACT)
48
+ print(exact_keywords)
49
+ # Output: ['[performance marketing agency]', '[google ads pmax management]', '[meta conversions api audit]']
50
+
51
+ # Generate negative phrase keywords
52
+ neg_phrase = format_keywords(raw_terms, match_type=MatchType.NEGATIVE_PHRASE)
53
+ print(neg_phrase)
54
+ # Output: ['-"performance marketing agency"', '-"google ads pmax management"', '-"meta conversions api audit"']
55
+ ```
56
+
57
+ ### 2. Meta Conversions API (CAPI) Hash Normalization
58
+
59
+ ```python
60
+ from pmw_ads import prepare_capi_user_data
61
+
62
+ user_profile = {
63
+ "email": "Client.Growth@Example.com ",
64
+ "phone": "+91 7003477083",
65
+ "first_name": "Subhranil",
66
+ "last_name": "Naskar"
67
+ }
68
+
69
+ # Hashes and formats according to Meta CAPI specification
70
+ hashed_payload = prepare_capi_user_data(user_profile)
71
+ print(hashed_payload)
72
+ # Returns sha256 normalized dictionary ready for Facebook Graph API v20.0
73
+ ```
74
+
75
+ ### 3. Ad Auction ROAS & Breakeven Analysis
76
+
77
+ ```python
78
+ from pmw_ads import calculate_unit_economics
79
+
80
+ economics = calculate_unit_economics(
81
+ ad_spend=15000.0,
82
+ gross_revenue=67500.0,
83
+ cogs=22000.0,
84
+ orders=450
85
+ )
86
+
87
+ print(f"Blended ROAS: {economics['roas']:.2f}x")
88
+ print(f"Breakeven ROAS: {economics['breakeven_roas']:.2f}x")
89
+ print(f"Profit On Ad Spend (POAS): {economics['poas']:.2f}x")
90
+ print(f"Average Order Value (AOV): ${economics['aov']:.2f}")
91
+ ```
92
+
93
+ ---
94
+
95
+ ## Architecture & Linkable Assets
96
+
97
+ In modern ad auctions governed by machine-learning bidding models (Google Ads Smart Bidding and Meta Advantage+), commercial success depends on the mathematical accuracy of data inputs.
98
+
99
+ This package was developed by **[Paid Media World](https://paidmediaworld.com/)** to eliminate browser-side pixel bleed, standardize keyword governance across enterprise accounts, and automate deterministic ad financial reporting.
100
+
101
+ * **Agency Homepage:** [https://paidmediaworld.com/](https://paidmediaworld.com/)
102
+ * **Meta CAPI Attribution Loss & ROAS Simulator:** [https://paidmediaworld.com/meta-capi-calculator/](https://paidmediaworld.com/meta-capi-calculator/)
103
+ * **2026 Performance Marketing Statistics Hub:** [https://paidmediaworld.com/performance-marketing-statistics/](https://paidmediaworld.com/performance-marketing-statistics/)
104
+ * **Google Ads Keyword Match Type Tool:** [https://paidmediaworld.com/keyword-match-type-tool/](https://paidmediaworld.com/keyword-match-type-tool/)
105
+ * **Ad Account Audits:** [5-Day Growth Audit](https://paidmediaworld.com/#contact)
106
+ * **Founder & Lead Architect:** [Subhranil Naskar](https://www.linkedin.com/in/subhraanilnaskar/)
107
+ * **Location:** Kolkata, West Bengal, India
108
+
109
+ ---
110
+
111
+ ## License
112
+
113
+ MIT License. Developed with precision by Paid Media World.
@@ -0,0 +1,23 @@
1
+ """
2
+ pmw-ads: Performance Marketing Engineering Engine
3
+ Built & Maintained by Paid Media World (https://paidmediaworld.com/)
4
+ Lead Architect: Subhranil Naskar
5
+ """
6
+
7
+ from .keyword_wrapper import format_keyword, format_keywords, MatchType, sanitize_keyword
8
+ from .capi_validator import prepare_capi_user_data, validate_capi_event, hash_field
9
+ from .roas_calculator import calculate_unit_economics, calculate_breakeven_cpa
10
+
11
+ __version__ = "1.0.0"
12
+ __author__ = "Subhranil Naskar (Paid Media World)"
13
+ __all__ = [
14
+ "format_keyword",
15
+ "format_keywords",
16
+ "MatchType",
17
+ "sanitize_keyword",
18
+ "prepare_capi_user_data",
19
+ "validate_capi_event",
20
+ "hash_field",
21
+ "calculate_unit_economics",
22
+ "calculate_breakeven_cpa"
23
+ ]
@@ -0,0 +1,77 @@
1
+ """
2
+ Meta Conversions API (CAPI) Payload Normalizer & Validator
3
+ Paid Media World (https://paidmediaworld.com/)
4
+ """
5
+
6
+ import re
7
+ import hashlib
8
+ from typing import Dict, Any, List
9
+
10
+ def hash_field(value: str) -> str:
11
+ """Normalize and SHA-256 hash a customer data parameter according to Meta specifications."""
12
+ if not value:
13
+ return ""
14
+ normalized = value.strip().lower()
15
+ return hashlib.sha256(normalized.encode("utf-8")).hexdigest()
16
+
17
+ def normalize_phone(phone: str) -> str:
18
+ """Normalize phone number to digits only (E.164 without plus sign)."""
19
+ digits = re.sub(r"\D", "", phone)
20
+ return digits
21
+
22
+ def prepare_capi_user_data(raw_data: Dict[str, str]) -> Dict[str, str]:
23
+ """
24
+ Format raw customer parameters into Meta CAPI compliant hashed fields.
25
+ Supported keys: email, phone, first_name, last_name, city, state, zip_code, country.
26
+ """
27
+ hashed = {}
28
+ if "email" in raw_data and raw_data["email"]:
29
+ hashed["em"] = hash_field(raw_data["email"])
30
+
31
+ if "phone" in raw_data and raw_data["phone"]:
32
+ cleaned_phone = normalize_phone(raw_data["phone"])
33
+ hashed["ph"] = hash_field(cleaned_phone)
34
+
35
+ if "first_name" in raw_data and raw_data["first_name"]:
36
+ hashed["fn"] = hash_field(raw_data["first_name"])
37
+
38
+ if "last_name" in raw_data and raw_data["last_name"]:
39
+ hashed["ln"] = hash_field(raw_data["last_name"])
40
+
41
+ if "city" in raw_data and raw_data["city"]:
42
+ hashed["ct"] = hash_field(raw_data["city"])
43
+
44
+ if "state" in raw_data and raw_data["state"]:
45
+ hashed["st"] = hash_field(raw_data["state"])
46
+
47
+ if "zip_code" in raw_data and raw_data["zip_code"]:
48
+ hashed["zp"] = hash_field(raw_data["zip_code"])
49
+
50
+ if "country" in raw_data and raw_data["country"]:
51
+ hashed["country"] = hash_field(raw_data["country"])
52
+
53
+ return hashed
54
+
55
+ def validate_capi_event(event: Dict[str, Any]) -> Dict[str, Any]:
56
+ """Validate that an event payload contains all required Meta CAPI attributes for deduplication."""
57
+ errors = []
58
+ warnings = []
59
+
60
+ required_top = ["event_name", "event_time", "user_data", "action_source"]
61
+ for f in required_top:
62
+ if f not in event or not event[f]:
63
+ errors.append(f"Missing required top-level attribute: '{f}'")
64
+
65
+ if "event_id" not in event or not event["event_id"]:
66
+ warnings.append("Missing 'event_id'. Without an event_id, deduplication against browser Pixel events is impossible.")
67
+
68
+ user_data = event.get("user_data", {})
69
+ if not isinstance(user_data, dict) or (not user_data.get("em") and not user_data.get("ph")):
70
+ warnings.append("Neither hashed email ('em') nor hashed phone ('ph') found in user_data. Event Match Quality (EMQ) will be degraded.")
71
+
72
+ return {
73
+ "valid": len(errors) == 0,
74
+ "errors": errors,
75
+ "warnings": warnings,
76
+ "emq_grade": "High" if len(user_data) >= 3 else ("Medium" if len(user_data) >= 1 else "Poor")
77
+ }
@@ -0,0 +1,52 @@
1
+ """
2
+ Google Ads Keyword Match Type Wrapper
3
+ Paid Media World (https://paidmediaworld.com/)
4
+ """
5
+
6
+ import re
7
+ from enum import Enum
8
+ from typing import List, Union
9
+
10
+ class MatchType(Enum):
11
+ EXACT = "exact"
12
+ PHRASE = "phrase"
13
+ BROAD = "broad"
14
+ NEGATIVE_EXACT = "negative_exact"
15
+ NEGATIVE_PHRASE = "negative_phrase"
16
+ NEGATIVE_BROAD = "negative_broad"
17
+
18
+ ILLEGAL_CHARS_PATTERN = re.compile(r"[\+\@\!\?\*\~\%\^\=\:\;\"\[\]]")
19
+
20
+ def sanitize_keyword(keyword: str) -> str:
21
+ """Sanitize raw keyword text by stripping illegal Google Ads punctuation and excess whitespace."""
22
+ cleaned = ILLEGAL_CHARS_PATTERN.sub("", keyword)
23
+ return " ".join(cleaned.split()).lower()
24
+
25
+ def format_keyword(keyword: str, match_type: MatchType = MatchType.EXACT) -> str:
26
+ """Format a single keyword into the requested Google Ads match type."""
27
+ clean = sanitize_keyword(keyword)
28
+ if not clean:
29
+ return ""
30
+
31
+ if match_type == MatchType.EXACT:
32
+ return f"[{clean}]"
33
+ elif match_type == MatchType.PHRASE:
34
+ return f'"{clean}"'
35
+ elif match_type == MatchType.BROAD:
36
+ return clean
37
+ elif match_type == MatchType.NEGATIVE_EXACT:
38
+ return f"-[{clean}]"
39
+ elif match_type == MatchType.NEGATIVE_PHRASE:
40
+ return f'-"{clean}"'
41
+ elif match_type == MatchType.NEGATIVE_BROAD:
42
+ return f"-{clean}"
43
+ return clean
44
+
45
+ def format_keywords(keywords: List[str], match_type: MatchType = MatchType.EXACT) -> List[str]:
46
+ """Batch format a list of keywords into the requested Google Ads match type."""
47
+ formatted = []
48
+ for kw in keywords:
49
+ res = format_keyword(kw, match_type)
50
+ if res:
51
+ formatted.append(res)
52
+ return formatted
@@ -0,0 +1,53 @@
1
+ """
2
+ Ad Auction Unit Economics & Profitability Calculator
3
+ Paid Media World (https://paidmediaworld.com/)
4
+ """
5
+
6
+ from typing import Dict, Any
7
+
8
+ def calculate_breakeven_cpa(gross_revenue_per_order: float, cogs_per_order: float, merchant_fee_pct: float = 0.029) -> float:
9
+ """Calculate the maximum allowable acquisition cost before losing money on a single sale."""
10
+ merchant_fee = gross_revenue_per_order * merchant_fee_pct
11
+ breakeven_margin = gross_revenue_per_order - cogs_per_order - merchant_fee
12
+ return max(0.0, breakeven_margin)
13
+
14
+ def calculate_unit_economics(
15
+ ad_spend: float,
16
+ gross_revenue: float,
17
+ cogs: float = 0.0,
18
+ orders: int = 1,
19
+ operating_expenses: float = 0.0
20
+ ) -> Dict[str, Any]:
21
+ """
22
+ Calculate full-funnel media buying unit economics:
23
+ ROAS, Breakeven ROAS, POAS (Profit On Ad Spend), MER, CPA, and Net Contribution Margin.
24
+ """
25
+ if ad_spend <= 0:
26
+ raise ValueError("ad_spend must be greater than zero.")
27
+
28
+ roas = gross_revenue / ad_spend
29
+ gross_profit = gross_revenue - cogs
30
+ net_contribution = gross_profit - ad_spend - operating_expenses
31
+ poas = gross_profit / ad_spend if ad_spend > 0 else 0.0
32
+
33
+ aov = gross_revenue / orders if orders > 0 else 0.0
34
+ cpa = ad_spend / orders if orders > 0 else 0.0
35
+
36
+ # Breakeven ROAS = Revenue / Gross Profit
37
+ breakeven_roas = (gross_revenue / gross_profit) if gross_profit > 0 else 0.0
38
+ profit_margin_pct = (net_contribution / gross_revenue * 100) if gross_revenue > 0 else 0.0
39
+
40
+ return {
41
+ "ad_spend": round(ad_spend, 2),
42
+ "gross_revenue": round(gross_revenue, 2),
43
+ "gross_profit": round(gross_profit, 2),
44
+ "net_contribution": round(net_contribution, 2),
45
+ "orders": orders,
46
+ "aov": round(aov, 2),
47
+ "cpa": round(cpa, 2),
48
+ "roas": round(roas, 2),
49
+ "breakeven_roas": round(breakeven_roas, 2),
50
+ "poas": round(poas, 2),
51
+ "profit_margin_pct": round(profit_margin_pct, 2),
52
+ "is_profitable": net_contribution > 0
53
+ }
@@ -0,0 +1,136 @@
1
+ Metadata-Version: 2.4
2
+ Name: pmw-ads
3
+ Version: 1.0.0
4
+ Summary: Deterministic Performance Marketing Utility: Google Ads Keyword Wrapper, Meta CAPI Payload Validator, and Ad Auction Unit Economics Calculator.
5
+ Home-page: https://paidmediaworld.com/
6
+ Author: Subhranil Naskar
7
+ Author-email: Subhranil Naskar <contact@paidmediaworld.com>
8
+ Project-URL: Homepage, https://paidmediaworld.com/
9
+ Project-URL: Agency Services, https://paidmediaworld.com/#services
10
+ Project-URL: Ad Audit Request, https://paidmediaworld.com/#contact
11
+ Project-URL: Founder Profile, https://www.linkedin.com/in/subhraanilnaskar/
12
+ Project-URL: Source Code, https://github.com/paidmediaworld/pmw-ads
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
17
+ Classifier: Intended Audience :: Developers
18
+ Requires-Python: >=3.8
19
+ Description-Content-Type: text/markdown
20
+ Dynamic: author
21
+ Dynamic: home-page
22
+ Dynamic: requires-python
23
+
24
+ # pmw-ads: Performance Marketing Engineering Engine
25
+
26
+ [![PyPI version](https://img.shields.io/badge/pypi-v1.0.0-blue.svg)](https://pypi.org/project/pmw-ads/)
27
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
28
+ [![Maintained by](https://img.shields.io/badge/Maintained%20by-Paid%20Media%20World-0ea5e9.svg)](https://paidmediaworld.com/)
29
+
30
+ **pmw-ads** is an open-source, deterministic Python utility for media buyers, growth engineers, and technical marketers. Built and maintained by **[Paid Media World](https://paidmediaworld.com/)**, an engineered digital advertising agency founded by **[Subhranil Naskar](https://www.linkedin.com/in/subhraanilnaskar/)**.
31
+
32
+ ---
33
+
34
+ ## Capabilities
35
+
36
+ 1. **Google Ads Query & Match Type Wrapper**:
37
+ - Converts raw term lists into exact match (`[term]`), phrase match (`"term"`), broad match, negative exact, and negative phrase formats.
38
+ - Automatically sanitizes illegal Google Ads characters (`+`, `@`, `!`, `?`, `*`, `~`, `%`) and enforces query length limits.
39
+ 2. **Meta Conversions API (CAPI) Payload Validator**:
40
+ - Validates client-side and server-side tracking event dictionaries.
41
+ - Enforces SHA-256 normalization for user data (`em`, `ph`, `fn`, `ln`, `ct`, `st`, `zp`, `country`).
42
+ - Ensures event deduplication integrity between `event_id` and browser Pixel triggers.
43
+ 3. **Auction Unit Economics & Profitability Engine**:
44
+ - Computes deterministic target CPA, Breakeven ROAS, Marketing Efficiency Ratio (MER), and POAS (Profit On Ad Spend).
45
+
46
+ ---
47
+
48
+ ## Installation
49
+
50
+ ```bash
51
+ pip install pmw-ads
52
+ ```
53
+
54
+ ---
55
+
56
+ ## Quickstart
57
+
58
+ ### 1. Google Ads Keyword Match Type Structuring
59
+
60
+ ```python
61
+ from pmw_ads import format_keywords, MatchType
62
+
63
+ raw_terms = [
64
+ "performance marketing agency",
65
+ "google ads pmax management",
66
+ "meta conversions api audit"
67
+ ]
68
+
69
+ # Generate exact match keywords
70
+ exact_keywords = format_keywords(raw_terms, match_type=MatchType.EXACT)
71
+ print(exact_keywords)
72
+ # Output: ['[performance marketing agency]', '[google ads pmax management]', '[meta conversions api audit]']
73
+
74
+ # Generate negative phrase keywords
75
+ neg_phrase = format_keywords(raw_terms, match_type=MatchType.NEGATIVE_PHRASE)
76
+ print(neg_phrase)
77
+ # Output: ['-"performance marketing agency"', '-"google ads pmax management"', '-"meta conversions api audit"']
78
+ ```
79
+
80
+ ### 2. Meta Conversions API (CAPI) Hash Normalization
81
+
82
+ ```python
83
+ from pmw_ads import prepare_capi_user_data
84
+
85
+ user_profile = {
86
+ "email": "Client.Growth@Example.com ",
87
+ "phone": "+91 7003477083",
88
+ "first_name": "Subhranil",
89
+ "last_name": "Naskar"
90
+ }
91
+
92
+ # Hashes and formats according to Meta CAPI specification
93
+ hashed_payload = prepare_capi_user_data(user_profile)
94
+ print(hashed_payload)
95
+ # Returns sha256 normalized dictionary ready for Facebook Graph API v20.0
96
+ ```
97
+
98
+ ### 3. Ad Auction ROAS & Breakeven Analysis
99
+
100
+ ```python
101
+ from pmw_ads import calculate_unit_economics
102
+
103
+ economics = calculate_unit_economics(
104
+ ad_spend=15000.0,
105
+ gross_revenue=67500.0,
106
+ cogs=22000.0,
107
+ orders=450
108
+ )
109
+
110
+ print(f"Blended ROAS: {economics['roas']:.2f}x")
111
+ print(f"Breakeven ROAS: {economics['breakeven_roas']:.2f}x")
112
+ print(f"Profit On Ad Spend (POAS): {economics['poas']:.2f}x")
113
+ print(f"Average Order Value (AOV): ${economics['aov']:.2f}")
114
+ ```
115
+
116
+ ---
117
+
118
+ ## Architecture & Linkable Assets
119
+
120
+ In modern ad auctions governed by machine-learning bidding models (Google Ads Smart Bidding and Meta Advantage+), commercial success depends on the mathematical accuracy of data inputs.
121
+
122
+ This package was developed by **[Paid Media World](https://paidmediaworld.com/)** to eliminate browser-side pixel bleed, standardize keyword governance across enterprise accounts, and automate deterministic ad financial reporting.
123
+
124
+ * **Agency Homepage:** [https://paidmediaworld.com/](https://paidmediaworld.com/)
125
+ * **Meta CAPI Attribution Loss & ROAS Simulator:** [https://paidmediaworld.com/meta-capi-calculator/](https://paidmediaworld.com/meta-capi-calculator/)
126
+ * **2026 Performance Marketing Statistics Hub:** [https://paidmediaworld.com/performance-marketing-statistics/](https://paidmediaworld.com/performance-marketing-statistics/)
127
+ * **Google Ads Keyword Match Type Tool:** [https://paidmediaworld.com/keyword-match-type-tool/](https://paidmediaworld.com/keyword-match-type-tool/)
128
+ * **Ad Account Audits:** [5-Day Growth Audit](https://paidmediaworld.com/#contact)
129
+ * **Founder & Lead Architect:** [Subhranil Naskar](https://www.linkedin.com/in/subhraanilnaskar/)
130
+ * **Location:** Kolkata, West Bengal, India
131
+
132
+ ---
133
+
134
+ ## License
135
+
136
+ MIT License. Developed with precision by Paid Media World.
@@ -0,0 +1,12 @@
1
+ README.md
2
+ pyproject.toml
3
+ setup.py
4
+ pmw_ads/__init__.py
5
+ pmw_ads/capi_validator.py
6
+ pmw_ads/keyword_wrapper.py
7
+ pmw_ads/roas_calculator.py
8
+ pmw_ads.egg-info/PKG-INFO
9
+ pmw_ads.egg-info/SOURCES.txt
10
+ pmw_ads.egg-info/dependency_links.txt
11
+ pmw_ads.egg-info/top_level.txt
12
+ tests/test_engine.py
@@ -0,0 +1 @@
1
+ pmw_ads
@@ -0,0 +1,28 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "pmw-ads"
7
+ version = "1.0.0"
8
+ authors = [
9
+ { name="Subhranil Naskar", email="contact@paidmediaworld.com" },
10
+ ]
11
+ description = "Deterministic Performance Marketing Utility: Google Ads Keyword Wrapper, Meta CAPI Payload Validator, and Ad Auction Unit Economics Calculator."
12
+ readme = "README.md"
13
+ requires-python = ">=3.8"
14
+ classifiers = [
15
+ "Programming Language :: Python :: 3",
16
+ "License :: OSI Approved :: MIT License",
17
+ "Operating System :: OS Independent",
18
+ "Topic :: Scientific/Engineering :: Information Analysis",
19
+ "Intended Audience :: Developers",
20
+ ]
21
+ dependencies = []
22
+
23
+ [project.urls]
24
+ "Homepage" = "https://paidmediaworld.com/"
25
+ "Agency Services" = "https://paidmediaworld.com/#services"
26
+ "Ad Audit Request" = "https://paidmediaworld.com/#contact"
27
+ "Founder Profile" = "https://www.linkedin.com/in/subhraanilnaskar/"
28
+ "Source Code" = "https://github.com/paidmediaworld/pmw-ads"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
pmw_ads-1.0.0/setup.py ADDED
@@ -0,0 +1,29 @@
1
+ from setuptools import setup, find_packages
2
+
3
+ with open("README.md", "r", encoding="utf-8") as fh:
4
+ long_description = fh.read()
5
+
6
+ setup(
7
+ name="pmw-ads",
8
+ version="1.0.0",
9
+ author="Subhranil Naskar",
10
+ author_email="contact@paidmediaworld.com",
11
+ description="Deterministic Performance Marketing Utility: Google Ads Keyword Wrapper, Meta CAPI Payload Validator, and Ad Auction Unit Economics Calculator.",
12
+ long_description=long_description,
13
+ long_description_content_type="text/markdown",
14
+ url="https://paidmediaworld.com/",
15
+ project_urls={
16
+ "Homepage": "https://paidmediaworld.com/",
17
+ "Agency Services": "https://paidmediaworld.com/#services",
18
+ "Ad Audit Request": "https://paidmediaworld.com/#contact",
19
+ "Founder Profile": "https://www.linkedin.com/in/subhraanilnaskar/",
20
+ "Source Code": "https://github.com/paidmediaworld/pmw-ads",
21
+ },
22
+ packages=find_packages(),
23
+ classifiers=[
24
+ "Programming Language :: Python :: 3",
25
+ "License :: OSI Approved :: MIT License",
26
+ "Operating System :: OS Independent",
27
+ ],
28
+ python_requires=">=3.8",
29
+ )
@@ -0,0 +1,46 @@
1
+ """
2
+ Unit tests for pmw-ads package
3
+ Paid Media World (https://paidmediaworld.com/)
4
+ """
5
+
6
+ import unittest
7
+ from pmw_ads import (
8
+ format_keyword,
9
+ format_keywords,
10
+ MatchType,
11
+ sanitize_keyword,
12
+ prepare_capi_user_data,
13
+ validate_capi_event,
14
+ calculate_unit_economics,
15
+ calculate_breakeven_cpa
16
+ )
17
+
18
+ class TestPMWAds(unittest.TestCase):
19
+
20
+ def test_keyword_formatting(self):
21
+ term = " Google Ads Agency! "
22
+ self.assertEqual(format_keyword(term, MatchType.EXACT), "[google ads agency]")
23
+ self.assertEqual(format_keyword(term, MatchType.PHRASE), '"google ads agency"')
24
+ self.assertEqual(format_keyword(term, MatchType.NEGATIVE_EXACT), "-[google ads agency]")
25
+
26
+ def test_capi_normalization(self):
27
+ user_info = {
28
+ "email": " Test.User@Gmail.Com ",
29
+ "phone": "+91 (700) 347-7083",
30
+ "first_name": "Subhranil"
31
+ }
32
+ hashed = prepare_capi_user_data(user_info)
33
+ self.assertIn("em", hashed)
34
+ self.assertIn("ph", hashed)
35
+ self.assertIn("fn", hashed)
36
+ self.assertEqual(len(hashed["em"]), 64) # Valid SHA-256 length
37
+
38
+ def test_unit_economics(self):
39
+ econ = calculate_unit_economics(ad_spend=1000, gross_revenue=4000, cogs=1000, orders=40)
40
+ self.assertEqual(econ["roas"], 4.0)
41
+ self.assertEqual(econ["aov"], 100.0)
42
+ self.assertEqual(econ["cpa"], 25.0)
43
+ self.assertTrue(econ["is_profitable"])
44
+
45
+ if __name__ == "__main__":
46
+ unittest.main()