You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
MXmap (mxmap.ch) — an automated system that classifies where ~2100 Swiss municipalities host their email by fingerprinting DNS records and network infrastructure. Results are displayed on an interactive Leaflet map.
4
+
5
+
## Commands
6
+
7
+
```bash
8
+
# Setup
9
+
uv sync --group dev
10
+
11
+
# Run pipeline (two stages, in order)
12
+
uv run resolve-domains # Stage 1: resolve municipality domains
13
+
uv run classify-providers # Stage 2: classify email providers
14
+
15
+
# Test
16
+
uv run pytest --cov --cov-report=term-missing # 90% coverage threshold enforced
17
+
uv run pytest tests/test_probes.py -k test_mx # single test
18
+
uv run pytest tests/test_data_validation.py -v # data validation (requires JSON files)
19
+
20
+
# Lint & format
21
+
uv run ruff check src tests
22
+
uv run ruff format src tests
23
+
```
24
+
25
+
### Data Files
26
+
27
+
-`overrides.json` — manual classification corrections with reasons
28
+
-`municipality_domains.json` — intermediate output from resolve stage
29
+
-`data.json` — final classifications served to the frontend
30
+
31
+
32
+
### What not to do
33
+
34
+
- modify any data files directly without approval (especially `data.json` and `municipality_domains.json`, which are generated by the pipeline)
35
+
- run the pipeline directly since it can time out and hides warnings
An interactive map showing where Swiss municipalities host their email — whether with US hyperscalers (Microsoft, Google, AWS) or Swiss providers or other solutions.
7
6
@@ -11,66 +10,57 @@ An interactive map showing where Swiss municipalities host their email — wheth
11
10
12
11
## How it works
13
12
14
-
The data pipeline has three steps:
13
+
The data pipeline has two stages:
15
14
16
-
1.**Preprocess**-- Fetches all ~2100 Swiss municipalities from Wikidata, performs MX and SPF DNS lookups on their official domains, and classifies each municipality's email provider.
17
-
2.**Postprocess** -- Applies manual overrides for edge cases, retries DNS for unresolved domains, checks SMTP banners of independent MX hosts for hidden providers, then scrapes websites of still-unclassified municipalities for email addresses.
18
-
3.**Validate**-- Cross-validates MX and SPF records, assigns a confidence score (0-100) to each entry, and generates a validation report.
15
+
1.**Resolve domains**— Fetches all ~2100 Swiss municipalities from Wikidata and the BFS (Swiss Statistics) API, applies manual overrides, scrapes municipal websites for email addresses, guesses domains from municipality names, and verifies candidates with MX lookups. Scores source agreement to pick the best domain. Outputs `municipality_domains.json`.
16
+
17
+
2.**Classify providers**— For each resolved domain, looks up all MX hosts, pattern-matches them, then runs 10 concurrent probes (SPF, DKIM, DMARC, Autodiscover, CNAME chain, SMTP banner, Tenant, ASN, TXT verification, SPF IP). Aggregates weighted evidence, computes confidence scores (0–100). Outputs `data.json` (full) and `data.min.json` (minified for the frontend).
0 commit comments