Skip to main content
Glama
northernvariables

FedMCP - Federal Parliamentary Information

lobbying.py5.81 kB
"""Lobbying network relationships: WORKS_FOR, LOBBIED_ON, MET_WITH.""" from typing import Dict, Any from ..utils.neo4j_client import Neo4jClient from ..utils.progress import logger def build_lobbying_network(neo4j_client: Neo4jClient, batch_size: int = 10000) -> Dict[str, int]: """ Build lobbying network relationships. Creates: - (Lobbyist)-[:WORKS_FOR]->(Organization) - (Lobbyist)-[:REGISTERED_FOR]->(LobbyRegistration) - (LobbyRegistration)-[:ON_BEHALF_OF]->(Organization) - (LobbyCommunication)-[:COMMUNICATION_BY]->(Organization) - (LobbyCommunication)-[:CONDUCTED_BY]->(Lobbyist) - (LobbyCommunication)-[:CONTACTED]->(MP) - (Lobbyist)-[:MET_WITH]->(MP) with date properties Args: neo4j_client: Neo4j client batch_size: Batch size for operations Returns: Dict with counts of created relationships """ logger.info("=" * 60) logger.info("BUILDING LOBBYING NETWORK") logger.info("=" * 60) stats = {} # 1. Link Lobbyists to Organizations (WORKS_FOR) # Match lobbyist names from registrations to link them to organizations logger.info("Creating WORKS_FOR relationships (Lobbyist -> Organization)...") works_for_query = """ MATCH (l:Lobbyist), (r:LobbyRegistration) WHERE l.name = r.registrant_name MATCH (o:Organization) WHERE o.name = r.client_org_name MERGE (l)-[:WORKS_FOR]->(o) RETURN count(*) as count """ result = neo4j_client.run_query(works_for_query) stats["works_for"] = result[0]["count"] if result else 0 logger.info(f"Created {stats['works_for']:,} WORKS_FOR relationships") # 2. Link Lobbyists to LobbyRegistrations (REGISTERED_FOR) logger.info("Creating REGISTERED_FOR relationships (Lobbyist -> LobbyRegistration)...") registered_for_query = """ MATCH (l:Lobbyist), (r:LobbyRegistration) WHERE l.name = r.registrant_name MERGE (l)-[:REGISTERED_FOR]->(r) RETURN count(*) as count """ result = neo4j_client.run_query(registered_for_query) stats["registered_for"] = result[0]["count"] if result else 0 logger.info(f"Created {stats['registered_for']:,} REGISTERED_FOR relationships") # 3. Link LobbyRegistrations to Organizations (ON_BEHALF_OF) logger.info("Creating ON_BEHALF_OF relationships (LobbyRegistration -> Organization)...") on_behalf_of_query = """ MATCH (r:LobbyRegistration), (o:Organization) WHERE o.name = r.client_org_name MERGE (r)-[:ON_BEHALF_OF]->(o) RETURN count(*) as count """ result = neo4j_client.run_query(on_behalf_of_query) stats["on_behalf_of"] = result[0]["count"] if result else 0 logger.info(f"Created {stats['on_behalf_of']:,} ON_BEHALF_OF relationships") # 4. Link LobbyCommunications to Organizations (COMMUNICATION_BY) logger.info("Creating COMMUNICATION_BY relationships (LobbyCommunication -> Organization)...") comm_by_org_query = """ MATCH (c:LobbyCommunication), (o:Organization) WHERE o.name = c.client_org_name MERGE (c)-[:COMMUNICATION_BY]->(o) RETURN count(*) as count """ result = neo4j_client.run_query(comm_by_org_query) stats["communication_by"] = result[0]["count"] if result else 0 logger.info(f"Created {stats['communication_by']:,} COMMUNICATION_BY relationships") # 5. Link LobbyCommunications to Lobbyists (CONDUCTED_BY) logger.info("Creating CONDUCTED_BY relationships (LobbyCommunication -> Lobbyist)...") conducted_by_query = """ MATCH (c:LobbyCommunication), (l:Lobbyist) WHERE l.name = c.registrant_name MERGE (c)-[:CONDUCTED_BY]->(l) RETURN count(*) as count """ result = neo4j_client.run_query(conducted_by_query) stats["conducted_by"] = result[0]["count"] if result else 0 logger.info(f"Created {stats['conducted_by']:,} CONDUCTED_BY relationships") # 6. Link LobbyCommunications to MPs (CONTACTED) # Match DPOH names to MP names - this is fuzzy matching logger.info("Creating CONTACTED relationships (LobbyCommunication -> MP)...") contacted_query = """ MATCH (c:LobbyCommunication), (mp:MP) WHERE any(dpoh IN c.dpoh_names WHERE mp.name CONTAINS dpoh OR dpoh CONTAINS mp.name) MERGE (c)-[:CONTACTED]->(mp) RETURN count(*) as count """ result = neo4j_client.run_query(contacted_query) stats["contacted"] = result[0]["count"] if result else 0 logger.info(f"Created {stats['contacted']:,} CONTACTED relationships") # 7. Link Lobbyists to MPs (MET_WITH) with date properties from communications logger.info("Creating MET_WITH relationships (Lobbyist -> MP)...") met_with_query = """ MATCH (l:Lobbyist)-[:CONDUCTED_BY]-(c:LobbyCommunication)-[:CONTACTED]->(mp:MP) MERGE (l)-[r:MET_WITH]->(mp) ON CREATE SET r.first_contact = c.date, r.last_contact = c.date ON MATCH SET r.last_contact = CASE WHEN r.last_contact IS NULL OR c.date > r.last_contact THEN c.date ELSE r.last_contact END RETURN count(DISTINCT r) as count """ result = neo4j_client.run_query(met_with_query) stats["met_with"] = result[0]["count"] if result else 0 logger.info(f"Created {stats['met_with']:,} MET_WITH relationships") logger.info("=" * 60) logger.success("✅ LOBBYING NETWORK COMPLETE") logger.info(f"WORKS_FOR: {stats.get('works_for', 0):,}") logger.info(f"REGISTERED_FOR: {stats.get('registered_for', 0):,}") logger.info(f"ON_BEHALF_OF: {stats.get('on_behalf_of', 0):,}") logger.info(f"COMMUNICATION_BY: {stats.get('communication_by', 0):,}") logger.info(f"CONDUCTED_BY: {stats.get('conducted_by', 0):,}") logger.info(f"CONTACTED: {stats.get('contacted', 0):,}") logger.info(f"MET_WITH: {stats.get('met_with', 0):,}") logger.info("=" * 60) return stats

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/northernvariables/FedMCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server