Singularity Checker
Singularity Checker (Redeem Checker) is a high-performance, asynchronous bulk validation tool designed to verify thousands of redeem codes. It leverages a hybrid approach—pairing high-speed HTTP checks with an automated Playwright browser fallback—to handle rate limits, logins, and human-verification blocks efficiently.
Overview
Singularity Checker 🎫
Singularity Checker is a bulk validation web application designed for operations and non-technical staff who need to verify large batches (10,000+) of promotional or redeem codes:
- Deduplication & Bulk Processing: Cleans and filters pasted inputs or uploaded files (.txt/.csv) to prevent redundant validations.
- Two-Stage Validation Engine: Leverages light, concurrent HTTP requests first, falling back to real browser automation only when required.
- Logged-In Session Support: Uses Playwright storage state JSON uploads to seamlessly validate behind user authentication.
- Persistent Job System: Runs validations asynchronously in the background, saving live results and progress metrics into a local database.
- Uncertain Rerunning: Lets users easily recheck only items that were blocked, rate-limited, or returned errors without restarting the entire job.
Key Features
- Bulk Upload: Pastes plain-text code lists or parses column-based
.csvfiles automatically. - Adaptive Concurrency Control: Allows users to fine-tune HTTP and browser worker counts, delays, and retries in real-time.
- Playwright Fallback Engine: Launches headless Chromium instances to interact with pages (forms, inputs, button clicks) and inspect dynamic layout elements.
- Profile-Driven Rules: Custom site validation logic is configured externally in declarative YAML profiles.
- Live Progress & Stats: Updates the browser dashboard dynamically using server-polled SQLite job updates.
- Detailed Export: Downloads final jobs into standardized CSV reports showing final code status, source (HTTP/Browser), reason, and response URLs.
Tech Stack
- Backend Framework: FastAPI + Uvicorn (Python 3.10+)
- Asynchronous HTTP Client: HTTPX
- Browser Automation: Playwright (Python API)
- Database Storage: SQLite (via aiosqlite in WAL mode)
- Declarative Profiles: PyYAML
- Frontend Layer: Vanilla HTML5, CSS3, and JavaScript
Architecture
Singularity Checker operates as a decoupled background worker system coordinating tasks via a database queue (SQLite) and dynamic async queues.
1. Verification State Machine Pipeline
Rather than launching heavy browser instances for every code, the system processes codes through a dual-stage state-machine flow. This minimizes overhead, avoiding resource bottlenecks and target-site rate limiting.
stateDiagram-v2
[*] --> Pending : Bulk Upload (Deduplicated)
state "Stage 1: Async HTTP Check" as HTTP
Pending --> HTTP : Lightweight Async Clients
state "Stage 2: Playwright Browser Fallback" as Browser
HTTP --> Browser : Catch Blocked/Uncertain/Error (≤10% of codes)
HTTP --> Valid : Success Rule Match (≥90% of codes)
HTTP --> Invalid : Failure Rule Match
Browser --> Valid : Content Success Match
Browser --> Invalid : Content Failure Match
Browser --> Blocked : Security/CAPTCHA Block
Browser --> Error : Timeout/Network Exception
Valid --> [*]
Invalid --> [*]
Blocked --> [*]
Error --> [*]
2. SQLite as a Persistent Job Ledger
All jobs and code-level statuses are tracked in a SQLite database with WAL (Write-Ahead Logging) mode activated. This enables safe, concurrent write access as multiple async background workers update code check outcomes simultaneously.
3. Asynchronous Worker Coordination
The backend handles concurrent execution limits dynamically using asyncio.Queue workers. HTTP workers run concurrently up to the selected threshold and push failures or challenges directly into a secondary browser worker queue.
Below is the core loop from app/services/worker.py coordinating the lifetime of the concurrent worker pools:
# Create concurrent worker pools based on job configuration
http_workers = [
asyncio.create_task(
self._http_worker(job, profile, http_queue, browser_queue),
name=f"http-worker-{job_id}-{index}",
)
for index in range(max(1, int(job["http_concurrency"])))
]
browser_enabled = bool(profile["browser"].get("enabled", True)) and int(job["browser_concurrency"]) > 0
browser_workers: list[asyncio.Task[None]] = []
if browser_enabled:
browser_workers = [
asyncio.create_task(
self._browser_worker(job, profile, browser_queue),
name=f"browser-worker-{job_id}-{index}",
)
for index in range(max(1, int(job["browser_concurrency"])))
]
# Await completion of HTTP stage, then safely signal workers to shut down
await http_queue.join()
for _ in http_workers:
await http_queue.put(None)
await asyncio.gather(*http_workers, return_exceptions=True)
# Await completion of Browser stage and stop browser processes
if browser_workers:
await browser_queue.join()
for _ in browser_workers:
await browser_queue.put(None)
await asyncio.gather(*browser_workers, return_exceptions=True)