Skip to content

CLI Reference

gdeltforge <command> [options]

The CLI intentionally does not chain stages automatically: you run each one explicitly to maintain full control. python main.py <command> is kept as a backward-compatible alias.

Command Description
scrape Download raw GDELT data (ZIP -> CSV)
convert Convert downloaded CSV files to Parquet
filter Apply row-column filtering to Parquet files
sample Efficient, reproducible sampling
codes Look up valid CAMEO/FIPS codes for filter values

scrape, convert, and filter all exit non-zero if any individual file failed, even though the ones that succeeded are kept, so a partial failure never gets missed in a &&-chained or scripted run. The failed filenames are included in the error message; the per-file reason is in the log output above it.

Any command that fails prints Error: <message> to stderr and exits with status 1, rather than a raw Python traceback; interrupting a command with Ctrl+C prints Interrupted. and exits with status 130.

Global options

--config PATH

: Path to settings.yaml. Defaults to the GDELTFORGE_CONFIG environment variable, then ./config/settings.yaml relative to the current working directory. Use this (or the env var) to run gdeltforge from outside the repo checkout, pointing at a config file anywhere on disk.

gdeltforge scrape

Download the entire archive:

gdeltforge scrape

Download only files within a date range (any combination of bounds is valid):

gdeltforge scrape --start-date 2020-01-01 --end-date 2023-12-31
gdeltforge scrape --start-date 2022-01-01          # from date onward
gdeltforge scrape --end-date   2015-12-31          # up to date
Flag Description
--dataset {events,gkg-v1,gkg-v2,mentions} Which GDELT dataset to scrape (default events; see --dataset below)
--start-date YYYY-MM-DD Only download files whose period starts on or after this date
--end-date YYYY-MM-DD Only download files whose period ends on or before this date

--dataset gkg-v2/mentions publish every 15 minutes rather than daily, so a wide date range can imply far more files than the equivalent Events scrape; see --dataset below.

The date filter applies to all three file types the GDELT archive provides:

File type Example filename Included when
Daily 20200315.export.CSV.zip day falls within range
Monthly 202003.zip month overlaps range
Yearly 2020.zip year overlaps range

Files already present in the download directory are skipped regardless of the date filter, so re-running scrape is safe and incremental.

Downloads run concurrently (scraping.max_workers, default 8) and are checksum-verified against the MD5 GDELT publishes for each file: a mismatch is treated like a network failure and retried, so a corrupted or truncated download never silently ends up in the dataset. See Configuration for the requests vs selenium link-collection method and the full list of scraping settings.

gdeltforge convert

gdeltforge convert

Extracts all CSV files from the downloaded ZIP archives and converts them to Parquet. Each ZIP is processed independently, so conversion runs across a pool of worker processes (converter.max_workers; null, the default, uses all available CPU cores).

See Configuration for the optional Hive-partitioning feature for pre-2013 yearly/monthly source files.

gdeltforge filter

gdeltforge filter

Drops rows with missing values in the columns defined under filter.columns_to_check.<dataset> in settings.yaml.

--dataset

scrape, convert, filter, and sample all accept --dataset {events,gkg-v1,gkg-v2,mentions} (default events).

  • events: the daily/monthly/yearly Events archive, as always.
  • gkg-v2: GKG 2.1, the current, actively-produced Global Knowledge Graph (themes, tone, GCAM, people, organizations; see Configuration). Discovered and downloaded differently from Events under the hood (a 15-minute-interval master file list, not a directory listing); see Configuration.
  • mentions: every re-report of an Event by a different article over time, the bridge table a real Events↔GKG join goes through, since GKG 2.1 itself carries no event ID (see Comparison).
  • gkg-v1: reserved for the legacy pre-2015 GKG format, not yet implemented (see Limitations & Roadmap).

gdeltforge sample

All sampling modes read from the filtered directory by default; pass --source converted to sample from raw converted Parquet instead, before the filter stage's NaN-dropping.

Flag Applies to Description
--dataset {events,gkg-v1,gkg-v2,mentions} all Which GDELT dataset to sample from (default events; see --dataset above)
--mode {indexed,daily,filtered} all Sampling strategy (required)
--source {filtered,converted} all Which stage's output to read from (default filtered)
-n N indexed, filtered Number of rows to sample (default 1000)
--seed N all RNG seed (default 42)
--per-day N daily Rows per day (default 10)
--filter JSON filtered JSON filter dict, e.g. '{"QuadClass": [1,2]}'
--columns COL [COL ...] all Restrict output to these columns; cuts I/O and memory on the full archive
--stratify COLUMN filtered Stratify by this column; requires --n-per-group
--n-per-group N filtered Rows per stratum when --stratify is set
--out PATH all Output parquet file (default sample.parquet)

Indexed sampling (uniform random)

gdeltforge sample --mode indexed -n 10000 --seed 123 --out sample.parquet

Samples 10,000 rows uniformly across the entire dataset.

Daily sampling (N rows per day)

gdeltforge sample --mode daily --per-day 20 --out daily.parquet

Samples 20 rows per day across the entire period covered by your downloaded data.

Filtered sampling (JSON filters)

5,000 events whose QuadClass is in {1, 2}:

gdeltforge sample \
    --mode filtered \
    --filter '{"QuadClass": [1, 2]}' \
    -n 5000 \
    --out qc12.parquet

2,000 "Verbal Cooperation" events that happened in the USA:

gdeltforge sample \
    --mode filtered \
    --filter '{"ActionGeo_CountryCode": ["US"], "QuadClass": [1]}' \
    -n 2000

Selecting specific columns keeps memory use down:

gdeltforge sample \
    --mode filtered \
    --filter '{"ActionGeo_CountryCode": ["US"], "QuadClass": [1]}' \
    --columns GlobalEventID Year Actor1Code \
    -n 1000

Filters support nested AND/OR blocks; see the example pipelines below for an OR example across multiple columns.

GDELT has two distinct country-code schemes that are easy to mix up: Actor1CountryCode/Actor2CountryCode use 3-letter CAMEO codes (USA), while ActionGeo_CountryCode, Actor1Geo_CountryCode, and Actor2Geo_CountryCode use 2-letter FIPS 10-4 codes (US). A value that doesn't match the right scheme for its column logs a warning rather than failing outright (FIPS 10-4 was retired in 2008 and can lag newer countries), but it also means the filter silently matches nothing. Run gdeltforge codes to check.

Stratified sampling (fixed N per group)

Combines a filter with stratified reservoir sampling: draws exactly --n-per-group rows for each distinct value of a chosen column, producing a class-balanced dataset regardless of the natural distribution.

gdeltforge sample \
    --mode filtered \
    --filter '{"ActionGeo_CountryCode": ["US"]}' \
    --stratify QuadClass \
    --n-per-group 500 \
    --out stratified.parquet

This produces 500 USA events per QuadClass value. --stratify requires --n-per-group; -n is ignored when --stratify is set.

gdeltforge codes

Looks up valid codes for GDELT's CAMEO-coded actor, geo, and event columns, so a filter value can be checked before running a sample. Needs no config file: it's a static reference lookup, usable before settings.yaml even exists.

Covers seven code families, each with its own reference list:

Family Columns
CAMEO actor-country (3-letter) Actor1CountryCode, Actor2CountryCode
FIPS geo-country (2-letter) ActionGeo_CountryCode, Actor1Geo_CountryCode, Actor2Geo_CountryCode
CAMEO ethnic Actor1EthnicCode, Actor2EthnicCode
CAMEO known-group (IGOs, NGOs, and similar organizations) Actor1KnownGroupCode, Actor2KnownGroupCode
CAMEO religion Actor1Religion1Code, Actor1Religion2Code, Actor2Religion1Code, Actor2Religion2Code
CAMEO actor-type Actor1Type1Code, Actor1Type2Code, Actor1Type3Code, Actor2Type1Code, Actor2Type2Code, Actor2Type3Code
CAMEO event (2-digit root, 3-digit base, up to 4-digit fully specified) EventCode, EventBaseCode, EventRootCode

FIPS 10-4 country codes are a different scheme from CAMEO's own 3-letter actor-country codes (UK not GBR, RS not RUS), so a value valid on one family can be silently wrong on another; gdeltforge codes <column> disambiguates before you run a sample.

A handful of real EventCode/EventBaseCode/EventRootCode values ("X", "--", "---") are GDELT's own markers for rows its event coder couldn't classify, not CAMEO codes, so gdeltforge codes deliberately won't list them and a filter using one will still warn.

List which columns have a reference list:

gdeltforge codes

List every code for a column:

gdeltforge codes ActionGeo_CountryCode

Search within a column by code or name (case-insensitive substring match):

gdeltforge codes ActionGeo_CountryCode --search korea
Flag Description
column Positional, optional. A CAMEO/FIPS-coded column, e.g. ActionGeo_CountryCode
--search TERM Filter results to codes or names containing this substring

Full pipeline examples

Sample 10,000 rows end-to-end:

gdeltforge scrape
gdeltforge convert
gdeltforge filter
gdeltforge sample --mode indexed -n 10000

Reproducible sampling (fixed seed):

gdeltforge scrape
gdeltforge convert
gdeltforge filter
gdeltforge sample --mode indexed -n 5000 --seed 42

USA-only events:

gdeltforge scrape
gdeltforge convert
gdeltforge filter
gdeltforge sample \
    --mode filtered \
    --filter '{"ActionGeo_CountryCode": ["US"]}' \
    -n 3000

30 events per day:

gdeltforge scrape
gdeltforge convert
gdeltforge filter
gdeltforge sample --mode daily --per-day 30

Date-restricted pipeline (the date flags apply only to scrape; later stages operate on whatever files are already on disk):

gdeltforge scrape --start-date 2020-01-01 --end-date 2023-12-31
gdeltforge convert
gdeltforge filter
gdeltforge sample --mode indexed -n 10000

Bash one-liner:

gdeltforge scrape && \
gdeltforge convert && \
gdeltforge filter && \
gdeltforge sample --mode indexed -n 10000

PowerShell loop:

foreach ($c in "scrape", "convert", "filter") {
    gdeltforge $c
}
gdeltforge sample --mode indexed -n 10000

For the complete filter syntax (nested AND/OR blocks, all operators) see Filtered Sampling; for complete runnable examples see Recipes.