platekit · "Adjacent" · plates + 5 OCR plugins
"Adjacent" pulls the entire M2 + M3 capability horizon into code. Five new adjacent-OCR plugins (shipping containers, VINs, make/model/colour, rail reporting marks, hazmat placards) and a Protocol scaffold for learned super-resolution sit alongside the 215-export plate-OCR core. The same library powers Hearth, Curb, YardSight, Eyrie — and now ports, rail terminals, fleets and parking yards too. Per-deployment commercial licensing with OEM authorisation, indemnity, and a written SLA on every tier.
from platekit import ANPR for e in ANPR().stream("rtsp://gate-1/main"): print(e.plate, e.confidence, e.region)
01 — The pipeline
Sources, the ANPR class, trackers, aggregators, and sinks compose into a single declarative pipeline. Every link is a protocol you can replace — detector, OCR, sink, tracker, backend — so you can grow into the SDK rather than fight it.
Files, folders, webcams, RTSP cameras, ONVIF discovery. Open via open_source(uri) or instantiate directly. The same Source ABC underpins every input.
The default Backend is FastALPR — fast, CPU-friendly, ships with bundled weights. Bring your own via the Detector + OCR protocols.
ByteTrackTracker associates detections across frames so a single car driving past produces one tracked read, not twenty fragments.
TrackAggregator promotes the best per-track read into a single PlateEvent, with confidence and OCR-confidence fields preserved.
Stdout, NDJSON, files, rotating files, MQTT, webhooks, Slack, Kafka, S3, Prometheus, WebSocket broadcast — composable as wrappers.
StreamProcessor wires source → ANPR → tracker → aggregator → sinks and runs the loop until you stop it. CLI uses the same runner.
02 — Streaming & sinks
Sinks compose. Every filter is also a sink — wrap one in the next, end with your destination. Operators get rate limits, kill switches, confidence floors, deduplication, hotlists, schema enforcement, and observability hooks. All in one ABC.
Sinks · destinations
Wrappers · filters & observability
from platekit import ANPR, open_source, StreamProcessor from platekit.sinks import StdoutSink, RotatingFileSink, MultiSink from platekit.network_sinks import WebhookSink, MQTTSink source = open_source("rtsp://10.0.0.10/main") anpr = ANPR.from_default(region="auto") sinks = MultiSink([ ConfidenceFilterSink(StdoutSink(), min_confidence=0.85), KillSwitchSink(WebhookSink("https://ops/api", secret="…")), BloomDeduperSink(RotatingFileSink("logs/anpr.ndjson"), window_seconds=90), MQTTSink("mqtt://broker.lan/anpr"), ]) StreamProcessor(source, anpr, sinks).run()
03 — Region packs
Region packs encode the syntax rules, common OCR noises, and common-pattern lists for a specific
market. At runtime, region="auto" picks the most plausible pack per read; you can also
force a region per source or pin one globally. Adding a new region is minor; per the Stability Policy
a pack's region code is stable from 1.0.
04 — India
India isn't a generic region. It has state codes, BH-series, HSRP holograms, FASTag classes, state-specific e-Challan portals, the Vahan database, PUC certificates, RTO tiers, and a wholly distinct OCR-noise profile. PlateKit ships 18 dedicated modules that capture all of it.
| Module | What it does |
|---|---|
| platekit.india | IndianPlate dataclass · STATE_CODES · BH-series helpers · two-row reassembly |
| platekit.india_hsrp | HSRP code parsing + verifier protocol |
| platekit.india_fastag | FASTag class enum · NETC tag-colour mapping · guess_class() |
| platekit.india_echallan | Per-state e-Challan portal URLs (national fallback) |
| platekit.india_vahan | Vahan adapter · StubVahanClient + rate-limited bulk-fetch |
| platekit.india_districts | RTO district codes · known_districts_for_state() |
| platekit.india_rto_tier | Tier classification for every RTO |
| platekit.india_zone | North / south / east / west classifier per RTO |
| platekit.india_population | State population + tier (official census tables) |
| platekit.india_speed | State-level default speed limits (highway / urban) |
| platekit.india_toll | Major NHAI toll plaza directory |
| platekit.india_compliance | PUC status · MLFF pay-by helpers · DPDP retention cutoff |
| platekit.india_normalize | Strip Devanagari overlays, HSRP prefixes, frame noise |
| platekit.india_form_factor | Aspect-ratio classifier for one-row vs two-row plates |
| platekit.india_fancy | Detect "fancy" / VIP plate patterns (0001, AB-007, …) |
| platekit.india_origin | Out-of-state vehicle detection by state-code mismatch |
| platekit.india_category | Vehicle-category inference from plate colour bands |
| platekit.india_pipeline | End-to-end India post-processing — chain all of the above |
A separate proprietary wheel — platekit-india-pro — ships the live Masters India Vahan
client with retry, auth, and envelope handling. See Commercial License.
05 — "Adjacent" capability horizon · M2 / M3, pulled forward
Five adjacent-OCR plugins ship in the "Adjacent" release. Each is a small module exposing a clean Protocol, a deterministic stub adapter for tests, and well-defined inputs / outputs — so production model adapters plug in without changing the rest of the pipeline. The math (check digits, banned characters, UN-number ranges) is pure-Python and exhaustively tested.
For ports, intermodal, rail yards
3-letter owner code, U/J/Z category, 6-digit serial plus the mod-11 check digit. ContainerOCR Protocol + StubContainerOCR adapter; pure-Python check-digit calculator + is_valid() + parse() helpers. Powers YardSight container OCR; available standalone as a PlateKit plugin.
For auction lots, fleet yards, warranty checks
17-char Vehicle Identification Numbers with transliteration-based check digit at position 9. VinOCR Protocol + StubVinOCR adapter. compute_check_digit() and decode_model_year() helpers. I / O / Q correctly excluded from the alphabet.
For Smart City, fleet tagging, parking analytics
MmrModel Protocol + StubMmr adapter. Top-50 Indian makes catalogue, 16-bucket colour palette, 20-body-style RTO taxonomy (auto-rickshaw, MUV, MCV, HCV included). Plug in vendor MMR models behind the Protocol without pipeline changes.
For intermodal terminals, Class-I railroads
15 major Class-I North American reporting marks (BNSF, UP, CSX, NS, CN, CP, KCS, GTW, IC, FXE, TFM, SAR, ARR, AC, WC). RailMarkOCR Protocol + StubRailMarkOCR adapter. parse() validator and is_known_mark() checker.
For weigh stations, customs, CTPAT
HazmatOCR Protocol + StubHazmatOCR adapter covering all 9 hazard classes + sub-divisions per UN Model Regulations §5.2.2. UN-number range validation (1001..3548). Placard-colour-for-class lookup for redundant verification.
For distant cameras, low-light, plate denoising
SuperResolver Protocol ready for LP-Diff, LCDNet, SwinIR, HAT and other diffusion / transformer adapters. Ships IdentitySuperResolver (passthrough) + NearestSuperResolver (numpy nearest-neighbour) as deterministic stubs; LanczosUpscale remains the recommended deterministic fallback. Production models plug in without pipeline changes.
+95 new tests across test_containers.py, test_vin.py, test_mmr.py, test_rail_mark.py, test_hazmat.py, test_super_res.py — every check-digit calculation, every alphabet exclusion, every UN-number range, every SR shape / dtype invariant covered. PRD-03 §9 M2 + M3 capability surface now in code.
06 — Backends + model zoo
FastALPR is the default Backend; bundled weights mean zero additional downloads on first run. For larger deployments, the model zoo lets you list, fetch, and pin to specific versions; for in-house models, you implement Detector + OCR protocols and PlateKit handles the rest.
ONNX-backed detect + OCR. Ships DEFAULT_DETECT and DEFAULT_OCR constants you can override per environment.
Pin to specific weights by name + version. Cache lives outside the package so containers stay small.
Composable preprocessors run before the detector. Easy to wedge your own (deblur, denoise, contrast equalisation).
When the primary OCR is uncertain, fall back to a vision-language model. Routes through the configured provider; never leaks images by default.
07 — Server & CLI
build_app(). Operationally complete.
platekit.serve.build_app() returns a FastAPI ASGI app exposing live events, recent
reads, regions, model info, and a /metrics scrape endpoint when PrometheusSink is wired. Every flag,
every exit code, every NDJSON event schema is stable under SemVer.
Broadcast of every PlateEvent through BroadcastSink. Dashboards subscribe; no polling.
Backfill new clients on connect. Optional region + camera filters.
Reflection — what AutoRegionPack will route to. Useful for debugging.
Liveness probe and embedded /metrics endpoint (when PrometheusSink is wired).
# Run a live RTSP source through the default pipeline: platekit run "rtsp://10.0.0.10/main" \ --region auto \ --sink "stdout" \ --sink "file:logs/anpr.ndjson" \ --sink "webhook:https://ops/api?secret=…" # Replay yesterday's NDJSON through a new sink set: platekit replay logs/2026-05-17.ndjson --sink "slack:#anpr-alerts" # Benchmark on a folder of frames: platekit benchmark frames/ --backend fastalpr --region in # List and pin model weights: platekit models list platekit models pin fastalpr-detect@1.2.0 # Run the operator console: platekit serve --host 0.0.0.0 --port 8080
08 — Stability
STABILITY.md is the contract: PlateEvent, ANPR, region packs,
sinks — none of these change shape inside a major version. Migrate up a major when you want to, not
when we feel like rewriting.
Stable surface
Bumps
09 — Why PlateKit
PlateKit is a licensed Python ANPR SDK. Five things included on every tier that off-the-shelf OCR services and generic CV vendors don't ship — any one of which is usually enough to make the choice.
— Reason · 01
Indian government and PSU RFPs in ANPR, ITMS, e-Challan, MLFF tolling and Smart Cities almost universally require an OEM letter naming the bidder as authorised SI. Generic OCR vendors don't issue one; PlateKit Solo includes one per year, Team and Enterprise are unlimited — all on company letterhead, DSC-signed.
— Reason · 02
Most OCR vendors ship as is with no warranty. Procurement teams at large enterprises and government agencies routinely require indemnity caps; PlateKit provides $50K, $250K, or negotiated caps — bound to the licence agreement, not a marketing page.
— Reason · 03
Generic OCR vendors offer email support with no contractual SLA. PlateKit provides response-time targets per severity, named engineering contacts, and a written escalation path on every tier.
— Reason · 04
platekit-india-pro connectorsAuthenticated, retry-aware adapters for Vahan (Masters India, Surepass, Signzy, KarzaTech), NPCI NETC FASTag, IRDAI IIB lookup, and the parivahan.gov.in e-Challan submission API. Bundled with the library; deployment count by tier.
— Reason · 05
Master service agreement, multi-year terms, source escrow, bespoke warranty caps, net-30 payment with PO workflow, and other arrangements typical of Enterprise procurement.
Most procurement teams care about three or more of these. Solo handles single-deployment requirements; Team scales across five sites with unlimited OEM letters; Enterprise is custom.
10 — Pricing
Three tiers, billed annually, all in USD with INR billing available via Paddle (registered seller of record). Indemnification, OEM authorisation letters, priority support, and written SLAs scale with the tier. Trial licences are available on written request to evaluate against your own corpus.
USD 2,000 / yr · ~₹1.7L
First commercial tier
USD 8,000 / yr · ~₹6.6L
Most companies
Negotiated
99.9% SLA available
Paddle bills in the licensee's local currency at the prevailing exchange rate. Indian licensees are billed in INR; Paddle as registered seller of record issues the GST-compliant tax invoice and captures the licensee's GSTIN at checkout for Input Tax Credit where applicable.
11 — How to buy
Two paths. Solo and Team self-serve through Paddle checkout. Enterprise gets a 30-minute scoping call, a master service agreement, and Paddle MoR or direct billing — whichever your procurement prefers.
— Path A · Paddle checkout
Email singh.anshuman@icycastle.com with your legal entity, GSTIN (Indian licensees) and tier. You receive a Paddle checkout link within one business day; on payment, the welcome email follows with private repo access for platekit-india-pro and your first OEM letter.
— Path B · Enterprise MSA
Email the same address with procurement context: expected deployment count, geography, custom terms required, target start date. 30-minute scoping call within 5 business days; MSA drafted within 10. Signed electronically via Zoho Sign or your preferred platform.
— Hours · à la carte
Paid engineering hours for Vahan / FASTag / e-Challan implementation, Kafka or S3 production wiring, threshold calibration on a labelled set, region-pack extension, OpenTelemetry roll-out, HMAC chain-of-custody. Minimum block 5 hours.
— SoW · fixed-price
Engagements above 40 hours can be scoped as a fixed-price statement of work. Typical work product is committed code in your repository, accompanied by tests and a brief design note.
12 — For Indian tender & RFP buyers
ICYCASTLE INFOTAINMENT PRIVATE LIMITED issues OEM authorisation letters on company letterhead, digitally signed with a DSC from a CCA-licensed Certifying Authority (eMudhra, Sify, or Capricorn). Each letter is tender-specific, valid through the award decision plus ninety days, and names the bidder as the authorised system integrator.
The OEM is an Indian Private Limited company registered with the Ministry of Corporate Affairs.
Statutory filings are publicly accessible at mca.gov.in for evaluators who prefer independent verification.
The complete buyer guide is at TENDER-COMPLIANCE.md.
13 — Install
ONNX everywhere. Reproducible benchmarks. The library that powers Hearth, Curb, YardSight and Eyrie — and now yours.