For the complete documentation index, see llms.txt. This page is also available as Markdown.

Geo resolver

Design & Implementation

Part of writing a connector — for the end-to-end flow (implement the interface → extend the published Bridge Docker image → configure → deploy) see How to write your own connector.

Module Information

  • Module Name: openg2p-g2p-bridge-geo-resolver

  • Location: /openg2p-g2p-bridge-geo-resolver/

  • Primary Implementation: FarmerGeoResolverImpl


Interface Definition

File: interface/geo_resolver_interface.py

class GeoResolver(BaseService):
    def resolve_geo(self, batch_beneficiary_list: List[Dict[str, str]]) -> List[Dict[str, str]]:
        """
        Resolves geographic zones for beneficiaries.
        
        Args:
            batch_beneficiary_list: List of dicts with keys:
                - disbursement_id (str)
                - beneficiary_id (str)
        
        Returns:
            List of dicts with keys:
                - disbursement_id
                - beneficiary_id
                - administrative_zone_id_large
                - administrative_zone_mnemonic_large
                - administrative_zone_id_small
                - administrative_zone_mnemonic_small
        """
        raise NotImplementedError()

Reference Implementation: FarmerGeoResolverImpl

File: implementations/farmer_resolver_impl.py

Database Models Used

  • G2PFarmerRegistry - Farmer/beneficiary registry with geographic location data

Algorithm

The implementation uses a direct lookup and mapping approach:

Key Characteristics

  1. Direct Database Lookup: Uses SQLAlchemy's select() and where() with in_() operator

  2. Mapping-based Processing: Builds dict for O(1) lookups after initial query

  3. Handles Missing Records: Silently skips beneficiaries not found in registry

  4. Database Engine: Uses registry database

    • db_engine_registry - Registry database for farmer/beneficiary data

  5. Logging: Uses logger name "farmer_geo_resolver_impl"

Return Data Structure


Factory Pattern

File: factory/geo_resolution_factory.py


Database Model Details

G2PFarmerRegistry Fields Used:

  • link_registry_id - Beneficiary/farmer ID (lookup key)

  • large_area_id - State/Province ID

  • large_area_code - State/Province code

  • small_area_id - District/Block ID

  • small_area_code - District/Block code


Configuration

File: config.py

Standard OpenG2P configuration pattern. Database connection via Settings.


Key Behaviors

  1. No Exception on Missing Beneficiaries: If a beneficiary ID is not found in registry, it's silently skipped

  2. Order Not Preserved: Results may not be in same order as input

  3. No Validation: Does not validate if geographic zones exist/are valid

  4. Logging:

    • INFO: When resolution starts, how many beneficiaries input, how many farmer details fetched

    • WARNING: When no farmer details found for provided beneficiary IDs


Error Handling

  • No Exceptions Raised: Returns empty list if no matches found (doesn't error)

  • Graceful Degradation: Skips individual missing beneficiaries, returns partial results

  • Database Errors: Would propagate SQLAlchemy exceptions if database connection fails


Integration Notes

Input Format

The input is a simple list of dicts, typically coming from a disbursement batch:

Output Format

Returns matching records with geographic zone information, typically used for:

  • Agency allocation (which agency serves this zone)

  • Warehouse allocation (which warehouse serves this zone)

  • Reporting and analytics


Performance Considerations

  1. Single Batch Query: All beneficiary lookups done in one DB query (efficient)

  2. Dict-based Lookup: O(1) lookup time per beneficiary after initial query

  3. No N+1 Queries: Uses in_() clause instead of looping queries


Implementation Limitations/Notes

  1. Silently omits beneficiaries not found in registry - caller must handle partial results

  2. No de-duplication - if beneficiary appears twice in input, appears twice in output

  3. Direct mapping only - no fuzzy matching or fallback strategies

  4. Depends entirely on farmer registry data being present and accurate

  5. No caching - queries database every time (even for same beneficiaries)


Typical Celery Integration

Last updated

Was this helpful?