Skip to main content

HistWarDB 🌍⚔️

Historical & Sovereign War Dataset powered by Wikidata

Tests Python Version License: MIT DOI

HistWarDB is a Python toolkit that extracts, cleans and analyses war participation data from Wikidata, from 1700 to the present, for both modern sovereign states and historical states. It produces a table of who took part in which war and a Country × Year panel derived from it.

The coding rules are written down in the codebook, and agreement with Correlates of War and UCDP/PRIO is measured in the validation report. Please read both before using the data for research: coverage is bounded by Wikidata.


Key Features

  • Wars and their subclasses: every Wikidata item typed as war or a subclass (world war, civil war, proxy war, ...), minus peacekeeping missions, military exercises and fictional wars.
  • Conflict structure: each conflict's Wikidata type, the war it is part of, and its top-level war; fronts and campaigns can be kept, dropped or rolled up into their war.
  • Sides where Wikidata has them: coalition participants (Allies, Axis, Central Powers, ...) are expanded into member states with a side, giving a dyadic table of opposing states.
  • State belligerents only: participants must be typed as sovereign state, historical country or country.
  • Stable identifiers: every conflict and country carries its Wikidata QID; countries also carry Correlates of War and Gleditsch–Ward codes from a bundled crosswalk, and an ISO 3166-1 alpha-3 code where Wikidata has one.
  • Lifespan-aware: a state is never counted at war in a year in which it did not exist, and the panel says which country-years fall outside a state's lifespan.
  • Explicit uncertainty: conflicts with no recorded end date are flagged, and the rule used to extend them is a parameter.
  • Fails loudly: queries are retried with backoff; a chunk that cannot be fetched raises an error instead of silently leaving a gap.
  • Frozen snapshots: save and reload a dataset with retrieval metadata and a checksum, so published results can be reproduced.
  • Analytical views and plots: long format, binary matrix, conflict names, lists, and a Plotly heatmap.

Project layout

src/histwardb/
    query.py      # SPARQL query construction (pure, no I/O)
    core.py       # HistWarDB class: fetch, parse, clean, analytical views
    relations.py  # part-of chains, coalitions, sides, dyads (pure)
    data/         # COW / Gleditsch-Ward crosswalk
data/snapshots/  # frozen, checksummed copies of the dataset
scripts/       # crosswalk builder, validation against COW and UCDP
validation/    # validation report
tests/         # pytest suite (parsing, filtering, views, mocked network)
CODEBOOK.md    # coding rules and column definitions
HistWarDB.ipynb  # usage demo notebook (Colab-compatible)

Installation

pip install git+https://github.com/VincenzoManto/histwardb.git

For local development (editable install + test/lint tooling):

git clone https://github.com/VincenzoManto/histwardb.git
cd histwardb
pip install -e ".[dev]"

Quick Start

from histwardb import HistWarDB

# Fetch live from Wikidata, 1700 to 2026 (about 20 queries, 2-3 minutes)
gwd = HistWarDB(start_year=1700, end_year=2026)

# Who took part in what: one row per conflict x country, with QIDs and dates
print(gwd.participations.head())

# Country x Year panel for specific countries (exact match on name, QID or ISO code)
france_uk_wars = gwd(countries=["France", "United Kingdom"], view="long", only_in_war=True)

# Binary matrix for a period; years outside the state's lifespan read <NA>
binary_view = gwd(countries="German Empire", view="binary", from_date=1900, to_date=1925, only_existing=True)

# Heatmap for the 15 states with most war-years
gwd.plot_heatmap(top_n=15, from_year=1800, to_year=2026).show()

Reproducible use: snapshots

Wikidata changes every day, so two live fetches can differ. For anything you intend to publish, work from a frozen snapshot and cite it:

# Load the snapshot shipped with the repository (no network access)
gwd = HistWarDB.from_snapshot("data/snapshots/2026-10-14")

# Or freeze your own fetch
gwd = HistWarDB(start_year=1700, end_year=2026)
gwd.save_snapshot("my_snapshot")   # participations.csv + metadata.json

metadata.json records the retrieval time, parameters, query text, row counts and a SHA-256 checksum that from_snapshot verifies.

Wars, fronts and sides

gwd = HistWarDB.from_snapshot("data/snapshots/2026-10-14")
gwd.conflicts                       # one row per conflict: type, parent/root war, dates, death toll
gwd.dyads                           # pairs of states on opposing coalition sides
HistWarDB(subconflicts="roll_up")   # attribute fronts and campaigns to their top-level war
HistWarDB(series_of_wars="drop")    # leave out "series of wars" items such as the Balkan Wars

Sides come only from coalitions that Wikidata lists as participants, so most conflicts have none; see the codebook.

Conflicts with no end date

Some Wikidata conflicts have a start date and no end date. The missing_end parameter decides how far they are extended:

HistWarDB(missing_end="heuristic")   # default: to the present if started 1800 or later, else 5 years
HistWarDB(missing_end="start_only")  # conservative: start year only
HistWarDB(missing_end="open")        # always to the present
HistWarDB(missing_end="drop")        # discard them

Whatever the rule, affected rows are flagged (duration_estimated in the participation table, Duration_Estimated and War_Imputed in the panel), so you can filter them out. The cutoff year and pre-cutoff duration of the default rule are parameters too (heuristic_cutoff_year, pre_cutoff_duration_years).

Severity threshold

HistWarDB(min_casualties=1000)  # drop conflicts with a recorded death toll below 1,000

Conflicts without a recorded toll (Wikidata P1120) are kept. Few conflicts have one, so this filter currently changes little; see the codebook.


Supported Views (view parameter)

  • "long": tidy DataFrame with Country, Year, War_State, Active_Conflicts, Duration_Estimated, Country_QID, ISO3, State_Exists, War_Imputed.
  • "binary": countries as rows, years as columns, 1 = at war, 0 = no war recorded.
  • "names": same shape, with the names of the active conflicts.
  • "list": alphabetical list of the conflict names under the current filters.
  • "countries" / "conflicts": sorted lists of countries at war, or of conflicts, under the current filters.

War_State = 0 means "no war recorded in Wikidata", not "peace". Use State_Exists (or only_existing=True) to separate years in which the state did not exist. See the codebook.


Testing

The default test suite never queries the live Wikidata endpoint. The HistWarDB class accepts an injectable session object for its HTTP calls, and all parsing/filtering logic is pure and tested against static fixtures:

pip install -e ".[dev]"
pytest --cov=histwardb

A small opt-in suite checks the real endpoint: that every QID constant means what the code says, and that well-known wars, states and sides come back. It also runs weekly in CI (.github/workflows/live-tests.yml).

pytest -m network

See CONTRIBUTING.md for details.


Citation

If you use HistWarDB in your academic research, working paper, or data science project, please cite it using the following format (also available in machine-readable form in CITATION.cff), and state which snapshot you used:

@software{histwardb2026,
  author = {Manto, Vincenzo and Dal Cero, Riccardo},
  title = {HistWarDB: A Dynamic Wikidata-Based Historical War Dataset},
  year = {2026},
  url = {https://github.com/VincenzoManto/histwardb}
}

License

Code is distributed under the MIT License. See LICENSE for more information. The data comes from Wikidata, which is released under CC0.

Metadata

Release files for histwardb 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for histwardb 0.4.0
File Size Uploaded
histwardb-0.4.0.tar.gz 53.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for histwardb 0.4.0
File Interpreter ABI Platform
histwardb-0.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 91.0 kB

Release files / histwardb-0.4.0.tar.gz

Download URL histwardb-0.4.0.tar.gz
Size 53.8 kB
Tags Source
SHA-256 checksum
How to use checksums
4ba6f22bf3e57197875da349fee35d723fb7c66774bc380c860cc4a3be7c06f4
BLAKE2b-256 checksum
How to use checksums
d11f152b58deb27fbe1d47c7035e6687c3e72aca35159417698ddaa944d21a35
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.

Transparency log

Release files / histwardb-0.4.0-py3-none-any.whl

Download URL histwardb-0.4.0-py3-none-any.whl
Size 37.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b95666a385f7ef54251dd0485b72c62440e9c49d9230f553482da71f5d40e40f
BLAKE2b-256 checksum
How to use checksums
164d9c9aef40f535b5268b0e39b3b9f1042c8869d09f8ab43995ee6b2ddc2e4d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.

Transparency log

Release history Release notifications | RSS feed

0.5.2

2 release files

This release

0.4.0 This release

2 release files

0.3.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page