opensanctions / opensanctions/poliloom

Enhance country filtering to include positions linked to countries

Open
#67 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

loom
Dominant language
Python
Stars
22
Forks
2
PR merge metrics
No merged PRs in 30d

Description

Summary

Currently, politician country filtering only considers citizenship (P27) properties. However, positions that politicians hold are often linked to countries via WikidataRelation (P17 - Country relation). We should enhance the country filter to also include politicians who hold positions in the specified countries.

Current Implementation

In poliloom/api/politicians.py:86-95, country filtering works as follows:

# Apply country filtering
if countries:
    citizenship_subquery = select(Property.politician_id).where(
        and_(
            Property.type == PropertyType.CITIZENSHIP,
            Property.entity_id.in_(countries),
        )
    )
    politician_ids_query = politician_ids_query.where(
        Politician.id.in_(citizenship_subquery)
    )

This only filters by Property.type == PropertyType.CITIZENSHIP.

Data Structure

Positions have WikidataRelations that link them to countries:

  • Position entities are stored in the positions table
  • WikidataRelation table tracks various relation types including RelationType.COUNTRY (P17)
  • Relations link parent_entity_id (country) to child_entity_id (position)

From models.py:55:

COUNTRY = "P17"  # Country relation

Politicians have position properties that reference these position entities via Property.entity_id.

Proposed Enhancement

Expand the country filter to include politicians who:

  1. Have citizenship in the specified countries (current behavior), OR
  2. Hold positions that are linked to the specified countries via WikidataRelation P17

This would require joining:

  • properties (type=POSITION) → wikidata_relations (relation_type=COUNTRY) → filter by country

Example Query Logic

# Subquery for citizenship-based filtering (existing)
citizenship_subquery = select(Property.politician_id).where(
    and_(
        Property.type == PropertyType.CITIZENSHIP,
        Property.entity_id.in_(countries),
    )
)

# Subquery for position-based filtering (new)
position_subquery = (
    select(Property.politician_id)
    .join(WikidataRelation, Property.entity_id == WikidataRelation.child_entity_id)
    .where(
        and_(
            Property.type == PropertyType.POSITION,
            WikidataRelation.relation_type == RelationType.COUNTRY,
            WikidataRelation.parent_entity_id.in_(countries),
        )
    )
)

# Combine both
politician_ids_query = politician_ids_query.where(
    or_(
        Politician.id.in_(citizenship_subquery),
        Politician.id.in_(position_subquery)
    )
)

Benefits

  • More comprehensive country filtering
  • Captures politicians who serve in a country's government but may not be citizens
  • Better alignment with how Wikidata models political relationships

Files to Modify

  • poliloom/api/politicians.py - Update the country filtering logic in get_politicians() endpoint
  • Potentially add tests in poliloom/tests/test_politicians_endpoint.py

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in poliloom/api/politicians.py:86-95 and inspect get_politicians(), then review the Property, WikidataRelation, and RelationType models in models.py. Run the relevant tests in poliloom/tests/test_politicians_endpoint.py, adding coverage for citizenship and position-country matches. Done means country filtering returns politicians matching either relationship without losing current citizenship behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
api, backend, database
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.