Skip to content

refactor: acled - #218

Open
nikbpetrov wants to merge 9 commits into
forecastingresearch:mainfrom
nikbpetrov:acled
Open

nikbpetrov wants to merge 9 commits into
forecastingresearch:mainfrom
nikbpetrov:acled

Conversation

@nikbpetrov

@nikbpetrov nikbpetrov commented Jun 11, 2026 •

Copy link
Copy Markdown
Collaborator
  • note the requirements.txt change for base_eval - unavaoidable w/o a ton of additional hassle; comments explain why/what; will repeat for wikipedia
  • the repetition of AcledFetchFrame as well as the explicit dtype columns is smelly but can't be avoided unless we do a full refactor of acled
  • acled is the only source that requires email/passwords creds so these are private (c.f. _require_api_key() on the base class)
  • _io._read_acled_dfr() is refactored to reuse acled._prepare_resolution_data() (DRY); this means that resolve and base_eval/naive and dummy forecaster jobs both bring in the heavy acled deps
    • note that acled uses requests and numpy modules but both resolve/base eval bring those in implicitly (google-cloud-storage brings in requests, pandas brings in numpy) - this is behaviour not tied to this PR
  • note the @backoff.on_exception on _get_access_token behaviour change: instead of manual handling, we let backoff handle retries/erroring, matching other sources' behaviour

@nikbpetrov

Copy link
Copy Markdown
Collaborator Author

Parity test only on update job (not running fetch!): old vs new (main branch code vs pr code) is perfectly identical; both disagree partially (712 file diffs out of 3374) with prod but only because prod's computation of freeze_datetime_value depends on today and the last time acled ran was on June 10 (tests ran on June 13). That key, namely freeze_datetime_value is the only discrepancy.

…b entrypoints

`AGENTS.md` (added on main after this branch forked) says new ForecastBench Python files should
not add it, and neither entrypoint needs postponed annotations.
…uirements

The update job needed it only because `orchestration/_io` imported `helpers.keys` at module
level. Main now imports `keys` lazily inside the one function that uses it, and the acled update
job never reads a secret. This matches `func_fred_update`, which also omits it.
de28285 returned an empty frame so the fetch job's `if dff.empty` guard could log and exit 0. That
turned a broken fetch into a success, and the nightly worker then ran the update job on the
previous week's fetch file, recomputing freeze values against stale data.

Raise instead, as legacy did (via `pd.concat([])`) and as `DbnomicsSource.fetch()` does, and drop
the job guard. Explicit handling of empty fetch results is what forecastingresearch#319 asks for.
`_prepare_resolution_data` was annotated as returning a `list` of countries but returned the
ndarray from `.unique()`, so convert it to a list and type both sequences as `list[str]`.
@nikbpetrov

Copy link
Copy Markdown
Collaborator Author

Note the change (33840de) to empty fetch handling: now raises an error, similar to other sources. Related: #319

Separate commits for review-ability. Merge by squashing.

@nikbpetrov
nikbpetrov marked this pull request as ready for review October 3, 2026 12:24
@nikbpetrov
nikbpetrov requested a review from houtanb October 3, 2026 12:24
…lers

`id_hash` and `upload_hash_mapping` were called only by the legacy update job this branch deletes;
the new update job hashes on its own `AcledSource` instance. They were kept for fidelity with main
during the refactor. `base_eval` still uses `populate_hash_mapping` and `id_unhash`, which stay.
@nikbpetrov

Copy link
Copy Markdown
Collaborator Author

Tests pass again (same pattern as before).

@nikbpetrov nikbpetrov mentioned this pull request Oct 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant