A lightweight Python project for validating daily paid media campaign files before they feed executive dashboards, pacing reports, or downstream attribution models.
This repo is framed for a Marketing Data Operations Analyst role at a streaming company: the sample data models the kind of cross-platform media delivery exports used to monitor subscriber acquisition, launch campaigns, and always-on performance marketing.
The monitor validates CSV rows at the campaign-date-platform grain and flags:
- Missing or invalid dates
- Duplicate campaign/date/platform rows
- Negative spend
- Spend recorded with zero impressions
- Clicks greater than impressions
- Conversions greater than clicks
- Stale data, based on the latest available reporting date
- Spend spikes versus recent campaign/platform history
The goal is not to replace a warehouse test framework. It is a practical first line of defense for recurring file drops from platforms, agencies, or internal media teams.
paid-media-data-quality-monitor/
data/
sample_paid_media.csv
paid_media_quality/
__init__.py
checks.py
cli.py
tests/
test_checks.py
pyproject.toml
README.md
The validator expects a header row with these columns:
| Column | Type | Notes |
|---|---|---|
date |
YYYY-MM-DD |
Daily reporting date |
campaign_id |
string | Stable campaign identifier |
campaign_name |
string | Human-readable campaign name |
platform |
string | Example: Meta, TikTok, YouTube, Google Ads |
spend |
number | Media spend for the date |
impressions |
integer | Delivered impressions |
clicks |
integer | Delivered clicks |
conversions |
integer | Conversion count, such as sign-ups or trials |
The included sample file is synthetic and modeled after common public paid media export schemas. It intentionally contains quality issues so the CLI has meaningful output.
For a real public dataset path, this repo includes data/public_facebook_ads_sample.csv, a validator-ready 150-row sample from the Facebook ads conversion dataset mirror hosted on Hugging Face, originally associated with Kaggle's Sales Conversion Optimization data. To regenerate it:
python scripts/fetch_public_facebook_ads_sample.py
python -m paid_media_quality.cli data/public_facebook_ads_sample.csv --fail-on errorThe included file maps Impressions, Clicks, Spent, and Total_Conversion into the validator schema. The synthetic files remain in the repo because they are better for demonstrating clean and intentionally broken checks.
Requires Python 3.10+.
cd paid-media-data-quality-monitor
python -m paid_media_quality.cli data/sample_paid_media.csvExpected behavior: the command prints a severity summary, issue details, and exits with status code 1 when issues are found. This makes it suitable for scheduled jobs or CI checks.
To allow warnings while still failing on errors only:
python -m paid_media_quality.cli data/sample_paid_media.csv --fail-on errorTo tune freshness and spike rules:
python -m paid_media_quality.cli data/sample_paid_media.csv --max-age-days 2 --spike-multiplier 2.5 --spike-lookback-days 7Paid Media Data Quality Report
Rows scanned: 16
Issues found: 7
Severity summary:
error: 5
warning: 2
[error] duplicate_grain row 3: Duplicate campaign/date/platform row for STRM-001 on Meta at 2026-04-25.
[error] negative_spend row 8: Spend cannot be negative for STRM-002 on TikTok.
cd paid-media-data-quality-monitor
python -m unittest discover -s testsMarketing teams at streaming companies often make daily decisions from paid media performance data: where to shift budget, which title launch needs support, whether acquisition costs are drifting, and whether platform delivery is healthy. A few bad rows can distort pacing, ROAS, or subscriber forecasts.
This project shows how I would operationalize data trust:
- Codify checks around business-critical grain and metric rules
- Keep validation explainable for non-engineering partners
- Make the CLI automation-friendly for scheduled pipelines
- Use small, focused tests to protect expected behavior
- Document assumptions so Marketing Ops, Data Engineering, and Analytics can align quickly
- Export results as JSON or Slack-ready Markdown
- Add per-platform schema adapters
- Store historical baselines for stronger anomaly detection
- Add CI workflow examples for automated validation on new CSV drops