Skip to content
This repository was archived by the owner on Mar 16, 2026. It is now read-only.

OstinUA/Revenue-Recon-Ad-Discrepancy-Monitor

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Revenue Recon Ad Discrepancy Monitor

A Streamlit-based revenue reconciliation and discrepancy monitoring library-style toolkit for AdOps teams to ingest dual-source delivery reports, compute variance metrics, persist them, and visualize actionable anomalies in near real time.

Python Streamlit SQLAlchemy License: Apache-2.0 Status

Important

This repository currently ships as an executable Streamlit application. The core discrepancy computation logic is implemented in a reusable service module (services/calculator.py) and can be embedded as a lightweight internal logging/reconciliation component in larger data pipelines.

Table of Contents

Features

  • Dual-source CSV ingestion workflow for internal ad server data and external SSP/vendor data.
  • Deterministic reconciliation logic based on standardized dates and direct joins.
  • Automatic discrepancy calculations for both impressions and revenue (percentage delta).
  • SQLite-backed persistence using SQLAlchemy ORM, including schema bootstrap on startup.
  • At-a-glance executive dashboard with KPI cards for discrepancy average, revenue gap, and data-point count.
  • Interactive Plotly visualizations:
    • Time-series discrepancy trend chart.
    • Side-by-side revenue comparison bars.
  • Configurable discrepancy threshold for alert-style highlighting in charts and tabular views.
  • Conditional formatting in the tabular report for fast anomaly triage.
  • Minimal architecture with clear separation between:
    • UI layer (ui/)
    • Service/business logic layer (services/)
    • Persistence layer (database/)
    • Runtime constants (config/)

Tip

The DiscrepancyCalculator service is intentionally small and stateless, making it easy to reuse as a pure transformation component in cron jobs, Airflow DAGs, or serverless workflows.

Tech Stack & Architecture

Core Stack

  • Language: Python
  • Web/UI: Streamlit
  • Data Processing: Pandas
  • Visualization: Plotly Express
  • ORM/Data Access: SQLAlchemy
  • Storage Engine: SQLite
  • Packaging/Dependencies: pip + requirements.txt

Project Structure

Revenue-Recon-Ad-Discrepancy-Monitor/
├── main.py                  # Streamlit entrypoint and route switcher
├── requirements.txt         # Python dependency lock list (unpinned ranges)
├── LICENSE                  # Apache License 2.0
├── config/
│   └── settings.py          # Global constants (threshold, DB name)
├── database/
│   ├── db_manager.py        # Persistence manager (save/query workflow)
│   └── models.py            # SQLAlchemy ORM models
├── services/
│   └── calculator.py        # Core discrepancy merge-and-calculate engine
└── ui/
    ├── dashboard.py         # KPI, charts, and styled data table
    └── uploader.py          # CSV upload and reconciliation trigger

Key Design Decisions

  1. Simple-by-default persistence: SQLite is selected for zero-ops local execution and prototyping speed.
  2. Service isolation: Calculation logic is encapsulated in DiscrepancyCalculator to keep UI views thin.
  3. Single model table: DailyReport denormalizes reconciled metrics for direct dashboard rendering.
  4. Threshold-based observability: A global discrepancy threshold enables visual alerting without extra rule engines.
  5. UI workflow partitioning: Upload and dashboard experiences are split into dedicated pages for operational clarity.
flowchart LR
    A[Internal CSV
    Date, Impressions, Revenue] --> C[DiscrepancyCalculator.merge_and_calculate]
    B[External CSV
    Date, Impressions, Revenue] --> C
    C --> D[Reconciled DataFrame
    internal/external + discrepancy fields]
    D --> E[DatabaseManager.save_report]
    E --> F[(SQLite daily_reports)]
    F --> G[DatabaseManager.get_all_data]
    G --> H[Dashboard KPIs]
    G --> I[Discrepancy Trend Chart]
    G --> J[Revenue Comparison Chart]
    G --> K[Styled Recon Table]
Loading

Note

Current join behavior is an inner merge on Date, meaning dates absent in either source are excluded from final output.

Getting Started

Prerequisites

  • Python 3.10+ recommended
  • pip for dependency installation
  • Optional: virtual environment tooling (venv, pipenv, or poetry)

Installation

git clone https://github.com/<your-org>/Revenue-Recon-Ad-Discrepancy-Monitor.git
cd Revenue-Recon-Ad-Discrepancy-Monitor

python -m venv .venv
source .venv/bin/activate  # Windows: .venv\Scripts\activate

pip install --upgrade pip
pip install -r requirements.txt

Start the app:

streamlit run main.py

After launch, open the provided local URL (typically http://localhost:8501).

Testing

This repository does not currently include a formal tests/ suite. Recommended validation commands:

# Static syntax validation
python -m compileall .

# Streamlit app smoke run
streamlit run main.py

If you add test modules, suggested conventions are:

pytest -q
pytest tests/test_calculator.py -q

Warning

Because no dedicated lint/test config is committed yet, CI pipelines should initially enforce at minimum python -m compileall . and application startup checks.

Deployment

Production Deployment Guidelines

  1. Containerize the app for deterministic runtime behavior.
  2. Externalize the database if multi-user or high-volume ingestion is expected.
  3. Pin dependency versions in requirements.txt for reproducible builds.
  4. Run behind a reverse proxy (e.g., Nginx) with TLS termination.

Example Dockerfile

FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8501
CMD ["streamlit", "run", "main.py", "--server.address=0.0.0.0", "--server.port=8501"]

CI/CD Recommendations

  • On pull requests:
    • Install dependencies.
    • Run python -m compileall ..
    • Optionally run pytest once tests are added.
  • On merge:
    • Build/push Docker image.
    • Deploy to staging/production via your preferred orchestrator.

Caution

The current default database (adops_data.db) is file-based. For horizontally scaled deployments, migrate to PostgreSQL/MySQL and update engine configuration accordingly.

Usage

Run as a Streamlit App

  1. Launch the app with streamlit run main.py.
  2. Open the Upload Data tab.
  3. Upload both required CSV files.
  4. Click Run Reconciliation Process.
  5. Navigate to Dashboard to review KPIs, trends, and detailed report rows.

Use the Discrepancy Engine Programmatically

import pandas as pd
from services.calculator import DiscrepancyCalculator

# Internal ad server export
internal_df = pd.DataFrame(
    {
        "Date": ["2026-01-01", "2026-01-02"],
        "Impressions": [100000, 120000],
        "Revenue": [230.50, 255.10],
    }
)

# External SSP/vendor export
external_df = pd.DataFrame(
    {
        "Date": ["2026-01-01", "2026-01-02"],
        "Impressions": [97000, 118500],
        "Revenue": [225.10, 250.30],
    }
)

# Reconcile and compute discrepancy percentages
result_df = DiscrepancyCalculator.merge_and_calculate(internal_df, external_df)

print(result_df[["date", "discrepancy_imps", "discrepancy_rev"]])

Configuration

Application Constants

The following constants are defined in config/settings.py:

  • DISCREPANCY_THRESHOLD: alert threshold used for chart markers and table highlighting.
  • DB_NAME: SQLite filename used by persistence components.

Database Configuration

DatabaseManager currently initializes SQLAlchemy with:

create_engine(f"sqlite:///{db_name}")

To migrate to another RDBMS, inject a full SQLAlchemy URI and update initialization logic in database/db_manager.py.

Input Data Contract

Both uploaded CSVs must contain these columns with exact names:

  • Date
  • Impressions
  • Revenue

Expected behavior:

  • Date is parsed with pandas.to_datetime.
  • Merge key is Date.
  • Output fields include:
    • internal_imps, external_imps, discrepancy_imps
    • internal_rev, external_rev, discrepancy_rev
    • partner_name (currently placeholder: Demo Partner)

Optional .env Pattern

The project does not currently load environment variables, but a production-ready extension is to support:

DB_URL=sqlite:///adops_data.db
DISCREPANCY_THRESHOLD=5.0
STREAMLIT_SERVER_PORT=8501

License

This project is licensed under the Apache License 2.0. See LICENSE for full terms.

Contacts & Community Support

Support the Project

Patreon Ko-fi Boosty YouTube Telegram

If you find this tool useful, consider leaving a star on GitHub or supporting the author directly.

About

AdOps reconciliation engine for automated discrepancy analysis. Compares internal (GAM) and external (SSP) revenue data, identifies impression/revenue gaps based on custom thresholds, and provides executive analytics dashboards using Streamlit and SQLAlchemy.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages