import gradio as gr import networkx as nx import matplotlib.pyplot as plt import io from PIL import Image # Your sample Jus Mundi data (same as before) jusmundi_data = { "data": [ {"type": "cases", "id": "46690", "attributes": {"commencement_date": "2025-03-31T00:00:00Z", "organization": "ICSID", "outcome": "Pending", "title": "United Operations v. Comoros"}, "links": {"self": "http://stanford.service.gra.prod.consul/cases/46690"}, "relationships": {"decisions": {"data": [{"type": "decisions", "id": "79078"}], "links": {"related": "http://stanford.service.gra.prod.consul/cases/46690/decisions"}}, "parties": {"data": [{"type": "parties", "id": "3535"}, {"type": "parties", "id": "64825"}], "links": {"related": "http://stanford.service.gra.prod.consul/cases/46690/parties"}}}}, {"type": "cases", "id": "46609", "attributes": {"commencement_date": "1913-07-31T00:00:00Z", "organization": "PCA", "outcome": "Concluded", "title": "Expropriated Religious Properties"}, "links": {"self": "http://stanford.service.gra.prod.consul/cases/46609"}, "relationships": {"decisions": {"data": [{"type": "decisions", "id": "78948"}], "links": {"related": "http://stanford.service.gra.prod.consul/cases/46609/decisions"}}, "parties": {"data": [{"type": "parties", "id": "7302"}, {"type": "parties", "id": "7319"}, {"type": "parties", "id": "7790"}], "links": {"related": "http://stanford.service.gra.prod.consul/cases/46609/parties"}}}}, {"type": "cases", "id": "46542", "attributes": {"commencement_date": "2025-03-20T00:00:00Z", "organization": "ICSID", "outcome": "Pending", "title": "Bellwether and Tecnipetrol v. Ecuador and Petroecuador"}, "links": {"self": "http://stanford.service.gra.prod.consul/cases/46542"}, "relationships": {"decisions": {"data": [{"type": "decisions", "id": "78809"}], "links": {"related": "http://stanford.service.gra.prod.consul/cases/46542/decisions"}}, "parties": {"data": [{"type": "parties", "id": "7569"}, {"type": "parties", "id": "13856"}, {"type": "parties", "id": "64647"}, {"type": "parties", "id": "64648"}], "links": {"related": "http://stanford.service.gra.prod.consul/cases/46542/parties"}}}}, {"type": "cases", "id": "46486", "attributes": {"commencement_date": "2025-03-14T00:00:00Z", "organization": "ICSID", "outcome": "Pending", "title": "Dirk Andres as insolvency administrator regarding the assets of HBH v. Algeria"}, "links": {"self": "http://stanford.service.gra.prod.consul/cases/46486"}, "relationships": {"decisions": {"data": [{"type": "decisions", "id": "78693"}], "links": {"related": "http://stanford.service.gra.prod.consul/cases/46486/decisions"}}, "parties": {"data": [{"type": "parties", "id": "7345"}, {"type": "parties", "id": "64617"}], "links": {"related": "http://stanford.service.gra.prod.consul/cases/46486/parties"}}}}, {"type": "cases", "id": "46422", "attributes": {"commencement_date": "2025-03-12T00:00:00Z", "organization": "ICSID", "outcome": "Pending", "title": "Brookfield v. Peru"}, "links": {"self": "http://stanford.service.gra.prod.consul/cases/46422"}, "relationships": {"decisions": {"data": [{"type": "decisions", "id": "78955"}], "links": {"related": "http://stanford.service.gra.prod.consul/cases/46422/decisions"}}, "parties": {"data": [{"type": "parties", "id": "1479"}, {"type": "parties", "id": "64717"}], "links": {"related": "http://stanford.service.gra.prod.consul/cases/46422/parties"}}}}, {"type": "cases", "id": "42525", "attributes": {"commencement_date": "2025-03-05T00:00:00Z", "organization": "ICSID", "outcome": "Pending", "title": "Orano v. Niger (III)"}, "links": {"self": "http://stanford.service.gra.prod.consul/cases/42525"}, "relationships": {"decisions": {"data": [{"type": "decisions", "id": "73961"}], "links": {"related": "http://stanford.service.gra.prod.consul/cases/42525/decisions"}}, "parties": {"data": [{"type": "parties", "id": "5442"}, {"type": "parties", "id": "58131"}], "links": {"related": "http://stanford.service.gra.prod.consul/cases/42525/parties"}}}}, {"type": "cases", "id": "42289", "attributes": {"commencement_date": "2021-03-08T00:00:00Z", "organization": "ICSID", "outcome": "Discontinued", "title": "Ahmed Hussein v. Egypt (I)"}, "links": {"self": "http://stanford.service.gra.prod.consul/cases/42289"}, "relationships": {"parties": {"data": [{"type": "parties", "id": "352"}, {"type": "parties", "id": "59703"}, {"type": "parties", "id": "59703"}], "links": {"related": "http://stanford.service.gra.prod.consul/cases/42289/parties"}}}}, {"type": "cases", "id": "42131", "attributes": {"commencement_date": "2020-01-01T00:00:00Z", "organization": "PCA", "outcome": "Concluded", "title": "Claimant v. Respondent"}, "links": {"self": "http://stanford.service.gra.prod.consul/cases/42131"}, "relationships": {"decisions": {"data": [{"type": "decisions", "id": "73273"}], "links": {"related": "http://stanford.service.gra.prod.consul/cases/42131/decisions"}}, "parties": {"data": [{"type": "parties", "id": "59479"}, {"type": "parties", "id": "59480"}], "links": {"related": "http://stanford.service.gra.prod.consul/cases/42131/parties"}}}}, {"type": "cases", "id": "42025", "attributes": {"commencement_date": "2025-02-18T00:00:00Z", "organization": "ICSID", "outcome": "Pending", "title": "Draslovka Holding v. Mexico"}, "links": {"self": "http://stanford.service.gra.prod.consul/cases/42025"}, "relationships": {"decisions": {"data": [{"type": "decisions", "id": "73113"}], "links": {"related": "http://stanford.service.gra.prod.consul/cases/42025/decisions"}}, "parties": {"data": [{"type": "parties", "id": "11038"}, {"type": "parties", "id": "59408"}], "links": {"related": "http://stanford.service.gra.prod.consul/cases/42025/parties"}}}}, {"type": "cases", "id": "41696", "attributes": {"commencement_date": "2025-02-06T00:00:00Z", "organization": "ICSID", "outcome": "Pending", "title": "Togo v. ContourGlobal"}, "links": {"self": "http://stanford.service.gra.prod.consul/cases/41696"}, "relationships": {"decisions": {"data": [{"type": "decisions", "id": "72520"}], "links": {"related": "http://stanford.service.gra.prod.consul/cases/41696/decisions"}}, "parties": {"data": [{"type": "parties", "id": "14333"}, {"type": "parties", "id": "59179"}], "links": {"related": "http://stanford.service.gra.prod.consul/cases/41696/parties"}}}} ], "links": {"self": "http://stanford.service.gra.prod.consul/cases?page=1&count=10", "first": "http://stanford.service.gra.prod.consul/cases?page=1&count=10", "next": "http://stanford.service.gra.prod.consul/cases?page=2&count=10", "last": "http://stanford.service.gra.prod.consul/cases?page=154&count=10"}, "meta": {"totalPages": 154, "totalRecords": 1539, "currentPage": 1, "perPage": 10} } def get_common_cases_and_parties(party_id_1, party_id_2): common_cases = [] for case in jusmundi_data['data']: parties_in_case = [party['id'] for party in case['relationships']['parties']['data']] if party_id_1 in parties_in_case and party_id_2 in parties_in_case: common_cases.append(case) return common_cases def visualize_relationships(common_cases, party_id_1, party_id_2): if not common_cases: return "No common cases found to visualize." graph = nx.Graph() all_involved_parties = set([party_id_1, party_id_2]) for case in common_cases: case_title = case['attributes']['title'] parties_in_case = [party['id'] for party in case['relationships']['parties']['data']] for party_id in parties_in_case: graph.add_node(party_id) all_involved_parties.add(party_id) # Create edges between all pairs of parties within the same case for i in range(len(parties_in_case)): for j in range(i + 1, len(parties_in_case)): u, v = parties_in_case[i], parties_in_case[j] graph.add_edge(u, v, case=case_title) if not graph.nodes(): return "No parties to visualize." # Highlight the input parties node_colors = ['red' if node == party_id_1 or node == party_id_2 else 'lightblue' for node in graph.nodes()] plt.figure(figsize=(10, 8)) pos = nx.spring_layout(graph) # You can try other layouts like circular_layout nx.draw(graph, pos, with_labels=True, node_color=node_colors, node_size=2000, font_size=10, font_weight='bold') edge_labels = nx.get_edge_attributes(graph, 'case') nx.draw_networkx_edge_labels(graph, pos, edge_labels=edge_labels, font_size=8) # Save the plot to a BytesIO object buf = io.BytesIO() plt.savefig(buf, format='png') buf.seek(0) img = Image.open(buf) plt.close() return img def combined_function(party_id_1, party_id_2): common_cases = get_common_cases_and_parties(party_id_1, party_id_2) result_text = "" if common_cases: case_titles = [case['attributes']['title'] for case in common_cases] result_text = f"Parties '{party_id_1}' and '{party_id_2}' appear together in the following cases: {', '.join(case_titles)}" graph_image = visualize_relationships(common_cases, party_id_1, party_id_2) return result_text, graph_image else: result_text = f"Parties '{party_id_1}' and '{party_id_2}' do not appear together in any of the cases in this sample data." return result_text, None iface = gr.Interface( fn=combined_function, inputs=[ gr.Textbox(label="Enter Party ID 1"), gr.Textbox(label="Enter Party ID 2") ], outputs=[ gr.Textbox(label="Result"), gr.Image(label="Relationship Graph of Common Cases") ], title="Jus Mundi Party Relationship Checker", description="Enter two Party IDs to see if they appear together in any cases in the sample data and visualize their relationships within those cases." ) iface.launch()