Update Multi-Source Integration notebook: separate install, add MCP, remove Advanced keyword

This commit is contained in:
KaifAhmad1
2025-12-19 22:33:15 +05:30
parent 859f4765fd
commit d73bcd52c4
@@ -4,38 +4,23 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/Hawksight-AI/semantica/blob/main/cookbook/advanced/06_Multi_Source_Data_Integration.ipynb)\n",
"# Real-World Multi-Source Integration\n",
"\n",
"# Multi-Source Data Integration\n",
"This cookbook demonstrates a production-grade workflow for integrating data from distinct sources using Semantica.\n",
"\n",
"## Overview\n",
"We will simulate a complex Enterprise Knowledge Graph construction scenario for **Nexus AI** by aggregating data from:\n",
"\n",
"This notebook demonstrates advanced multi-source data integration using multiple ingestion types, entity resolution, conflict detection, and provenance tracking.\n",
"1. **Corporate Database (SQLite)**: Financial records and employee counts.\n",
"2. **Public Web (HTML)**: News articles and press releases.\n",
"3. **Source Code (Markdown)**: Engineering activity and documentation.\n",
"4. **Market Data API (JSON)**: Live stock prices and market cap.\n",
"5. **Web Search MCP (Tool)**: Live competitor analysis from a search agent.\n",
"\n",
"\n",
"**Documentation**: [API Reference](https://semantica.readthedocs.io/reference/ingest/)\n",
"\n",
"### Learning Objectives\n",
"\n",
"- Ingest data from multiple sources (files, web, databases, streams, feeds)\n",
"- Resolve entities across sources using EntityResolver\n",
"- Detect conflicts using ConflictDetector\n",
"- Track provenance using ProvenanceTracker\n",
"- Integrate data into a unified knowledge graph\n",
"\n",
"## Installation\n",
"\n",
"Install Semantica from PyPI:\n",
"\n",
"```bash\n",
"pip install semantica\n",
"# Or with all optional dependencies:\n",
"pip install semantica[all]\n",
"```\n",
"\n",
"---\n",
"\n",
"## Workflow: Multi-Source Ingestion → Entity Resolution → Conflict Detection → Provenance Tracking → Unified KG\n"
"**Key Semantica Modules Used:**\n",
"* `ingest`: For loading data from disparate sources (including MCP).\n",
"* `kg.GraphBuilder`: For constructing the graph and merging entities.\n",
"* `conflicts.ConflictResolver`: For resolving data discrepancies.\n",
"* `visualization.KGVisualizer`: For visualizing the final network."
]
},
{
@@ -44,7 +29,8 @@
"metadata": {},
"outputs": [],
"source": [
"!pip install semantica\n"
"# Installation & Setup\n",
"!pip install semantica mcp"
]
},
{
@@ -53,38 +39,29 @@
"metadata": {},
"outputs": [],
"source": [
"from semantica.ingest import FileIngestor, WebIngestor, DBIngestor, StreamIngestor, FeedIngestor\n",
"from semantica.parse import DocumentParser, StructuredDataParser\n",
"from semantica.kg import GraphBuilder, EntityResolver, ProvenanceTracker\n",
"import tempfile\n",
"import os\n",
"import json\n",
"import sqlite3\n",
"import tempfile\n",
"import pandas as pd\n",
"\n",
"file_ingestor = FileIngestor()\n",
"web_ingestor = WebIngestor()\n",
"db_ingestor = DBIngestor()\n",
"stream_ingestor = StreamIngestor()\n",
"feed_ingestor = FeedIngestor()\n",
"# Import Semantica Modules\n",
"from semantica.ingest import DBIngestor, WebIngestor, FileIngestor, MCPIngestor\n",
"from semantica.kg import GraphBuilder\n",
"from semantica.visualization import KGVisualizer\n",
"\n",
"temp_dir = tempfile.mkdtemp()\n",
"\n",
"file1 = os.path.join(temp_dir, \"source1.txt\")\n",
"with open(file1, 'w') as f:\n",
" f.write(\"Apple Inc. is a technology company. Tim Cook is the CEO.\")\n",
"\n",
"file_objects = file_ingestor.ingest_file(file1, read_content=True)\n",
"\n",
"print(f\"Ingested {len([file_objects]) if file_objects else 0} files\")\n",
"print(f\"Multi-source ingestion initialized\")\n"
"# Create a temporary workspace\n",
"WORKSPACE_DIR = tempfile.mkdtemp()\n",
"print(f\"Workspace created at: {WORKSPACE_DIR}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Step 2: Entity Resolution\n",
"## Phase 1: Creating Data Sources\n",
"\n",
"Resolve entities across multiple sources.\n"
"We generate files on disk to simulate the disparate enterprise systems."
]
},
{
@@ -93,33 +70,53 @@
"metadata": {},
"outputs": [],
"source": [
"entity_resolver = EntityResolver()\n",
"# 1. SQLite Database (Financials)\n",
"db_path = os.path.join(WORKSPACE_DIR, \"corporate.db\")\n",
"conn = sqlite3.connect(db_path)\n",
"conn.execute(\"CREATE TABLE financials (company_name TEXT, revenue REAL, employees INTEGER)\")\n",
"conn.execute(\"INSERT INTO financials VALUES ('Nexus AI', 5500000.00, 45)\")\n",
"conn.commit()\n",
"conn.close()\n",
"\n",
"entities_from_source1 = [\n",
" {\"id\": \"e1\", \"name\": \"Apple Inc.\", \"type\": \"Organization\", \"source\": \"file1\"},\n",
" {\"id\": \"e2\", \"name\": \"Tim Cook\", \"type\": \"Person\", \"source\": \"file1\"}\n",
"]\n",
"# 2. Public Web (HTML)\n",
"html_path = os.path.join(WORKSPACE_DIR, \"news.html\")\n",
"with open(html_path, \"w\") as f:\n",
" f.write(\"\"\"\n",
" <html><body>\n",
" <h1>Nexus AI Raises Series B</h1>\n",
" <p>Nexus AI (San Francisco) valuated at $100M.</p>\n",
" <p>CEO Jane Doe announces expansion.</p>\n",
" </body></html>\n",
" \"\"\")\n",
"\n",
"entities_from_source2 = [\n",
" {\"id\": \"e3\", \"name\": \"Apple Incorporated\", \"type\": \"Organization\", \"source\": \"web\"},\n",
" {\"id\": \"e4\", \"name\": \"Timothy Cook\", \"type\": \"Person\", \"source\": \"web\"}\n",
"]\n",
"# 3. Code Repository (Markdown)\n",
"repo_path = os.path.join(WORKSPACE_DIR, \"README.md\")\n",
"with open(repo_path, \"w\") as f:\n",
" f.write(\"\"\"\n",
" # Nexus AI Core\n",
" Maintained by: engineering@nexus.ai\n",
" Language: Python\n",
" \"\"\")\n",
"\n",
"all_entities = entities_from_source1 + entities_from_source2\n",
"# 4. Market Data API (JSON)\n",
"api_path = os.path.join(WORKSPACE_DIR, \"market.json\")\n",
"with open(api_path, \"w\") as f:\n",
" json.dump({\n",
" \"ticker\": \"NXAI\", \n",
" \"price\": 124.50, \n",
" \"employees\": 50 # Conflict with DB (45)\n",
" }, f)\n",
"\n",
"resolved_entities = entity_resolver.resolve(all_entities)\n",
"\n",
"print(f\"Original entities: {len(all_entities)}\")\n",
"print(f\"Resolved entities: {len(resolved_entities)}\")\n"
"print(\"Data sources created successfully.\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Step 3: Conflict Detection\n",
"## Phase 2: Ingestion & Extraction\n",
"\n",
"Detect conflicts between sources.\n"
"We use Semantica's ingestors to load data. In a real pipeline, we would attach an extractor (like an LLM) to parse the raw content into entities. Here, we simulate the extraction output for clarity."
]
},
{
@@ -128,22 +125,140 @@
"metadata": {},
"outputs": [],
"source": [
"conflict_detector = ConflictDetector()\n",
"# Simulate extracted entities from our sources\n",
"\n",
"conflicts = conflict_detector.detect_value_conflicts(all_entities, \"name\")\n",
"source_db = {\n",
" \"name\": \"Corporate Database\",\n",
" \"type\": \"structured\",\n",
" \"entities\": [\n",
" {\n",
" \"name\": \"Nexus AI\",\n",
" \"type\": \"Organization\",\n",
" \"properties\": {\"revenue\": 5500000.00, \"employees\": 45},\n",
" \"source\": \"corporate_db\"\n",
" }\n",
" ]\n",
"}\n",
"\n",
"print(f\"Detected {len(conflicts)} conflicts\")\n",
"for conflict in conflicts[:3]:\n",
" print(f\" Conflict: {conflict.entity_id} - {conflict.conflict_type}\")\n"
"source_web = {\n",
" \"name\": \"Web News\",\n",
" \"type\": \"unstructured\",\n",
" \"entities\": [\n",
" {\n",
" \"name\": \"Nexus AI\",\n",
" \"type\": \"Organization\",\n",
" \"properties\": {\"valuation\": \"$100M\", \"location\": \"San Francisco\"},\n",
" \"source\": \"public_web\"\n",
" },\n",
" {\n",
" \"name\": \"Jane Doe\",\n",
" \"type\": \"Person\",\n",
" \"properties\": {\"role\": \"CEO\"},\n",
" \"source\": \"public_web\"\n",
" }\n",
" ],\n",
" \"relationships\": [\n",
" {\"source\": \"Jane Doe\", \"target\": \"Nexus AI\", \"type\": \"is_ceo_of\"}\n",
" ]\n",
"}\n",
"\n",
"source_api = {\n",
" \"name\": \"Market API\",\n",
" \"type\": \"structured\",\n",
" \"entities\": [\n",
" {\n",
" \"name\": \"Nexus AI\",\n",
" \"type\": \"Organization\",\n",
" \"properties\": {\"ticker\": \"NXAI\", \"employees\": 50}, # Note conflict: 50 vs 45\n",
" \"source\": \"market_api\"\n",
" }\n",
" ]\n",
"}\n",
"\n",
"source_repo = {\n",
" \"name\": \"GitHub Repo\",\n",
" \"type\": \"semi-structured\",\n",
" \"entities\": [\n",
" {\n",
" \"name\": \"Nexus AI Core\",\n",
" \"type\": \"Software\",\n",
" \"properties\": {\"language\": \"Python\"},\n",
" \"source\": \"github\"\n",
" }\n",
" ],\n",
" \"relationships\": [\n",
" {\"source\": \"Nexus AI Core\", \"target\": \"Nexus AI\", \"type\": \"owned_by\"}\n",
" ]\n",
"}\n",
"\n",
"# 5. Web Search MCP\n",
"# We use Semantica's MCPIngestor to connect to a Web Search MCP server.\n",
"# This allows us to fetch live competitor data (e.g., from Brave Search).\n",
"\n",
"try:\n",
" # Initialize MCP Ingestor\n",
" mcp = MCPIngestor()\n",
" \n",
" # Attempt to connect to a local MCP server (e.g., running on port 8000)\n",
" # Example: `fastmcp run search_server.py`\n",
" mcp.connect(\"web_search\", url=\"http://localhost:8000/sse\")\n",
" \n",
" print(\"Connected to MCP Server. Ingesting live data...\")\n",
" \n",
" # Ingest data using the search tool\n",
" mcp_data = mcp.ingest_tool_output(\n",
" \"web_search\", \n",
" \"search\", \n",
" {\"query\": \"Nexus AI competitors valuation\"}\n",
" )\n",
" \n",
" # Process the output (assuming the tool returns structured entities)\n",
" # In a real app, you might need an LLM to extract entities from search results.\n",
" # Here we assume the MCP server returns ready-to-use entities.\n",
" source_mcp = {\n",
" \"name\": \"Web Search MCP\",\n",
" \"type\": \"agent-tool\",\n",
" \"entities\": mcp_data.get(\"entities\", []),\n",
" \"source\": \"mcp_search\"\n",
" }\n",
"\n",
"except Exception as e:\n",
" print(f\"MCP Server connection failed ({e}). Using simulated data.\")\n",
" print(\"To enable live data, ensure an MCP server is running at http://localhost:8000/sse\")\n",
" \n",
" # Fallback to simulated data\n",
" source_mcp = {\n",
" \"name\": \"Web Search MCP\",\n",
" \"type\": \"agent-tool\",\n",
" \"entities\": [\n",
" {\n",
" \"name\": \"Nexus AI\",\n",
" \"type\": \"Organization\",\n",
" \"properties\": {\n",
" \"competitors\": [\"Cyberdyne Systems\", \"Massive Dynamic\"],\n",
" \"valuation\": \"$120M\" # Note conflict: $120M (newer) vs $100M (older web)\n",
" },\n",
" \"source\": \"mcp_search_agent\"\n",
" }\n",
" ],\n",
" \"relationships\": [\n",
" {\"source\": \"Nexus AI\", \"target\": \"Cyberdyne Systems\", \"type\": \"competes_with\"}\n",
" ]\n",
"}\n",
"\n",
"all_sources = [source_db, source_web, source_api, source_repo, source_mcp]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Step 4: Provenance Tracking\n",
"## Phase 3: Graph Construction & Resolution\n",
"\n",
"Track data provenance across sources.\n"
"We use `GraphBuilder` to:\n",
"1. **Merge Entities**: Combine the 4 \"Nexus AI\" records into one canonical node.\n",
"2. **Resolve Conflicts**: Handle discrepancies (Employee count: 45 vs 50; Valuation: $100M vs $120M).\n",
"3. **Build Graph**: Link related entities (CEO, Software, Competitors)."
]
},
{
@@ -152,28 +267,34 @@
"metadata": {},
"outputs": [],
"source": [
"provenance_tracker = ProvenanceTracker()\n",
"# Initialize GraphBuilder with resolution enabled\n",
"builder = GraphBuilder(\n",
" merge_entities=True,\n",
" resolve_conflicts=True,\n",
" entity_resolution_strategy=\"fuzzy\"\n",
")\n",
"\n",
"for entity in all_entities:\n",
" provenance_tracker.track_entity(entity.get(\"id\"), entity.get(\"source\"), entity)\n",
"# Build the graph\n",
"print(\"Building Knowledge Graph...\")\n",
"kg = builder.build(sources=all_sources)\n",
"\n",
"relationships = [\n",
" {\"source\": \"e2\", \"target\": \"e1\", \"type\": \"CEO_of\", \"source\": \"file1\"}\n",
"]\n",
"print(f\"Graph built with {len(kg['nodes'])} nodes and {len(kg['edges'])} edges.\")\n",
"\n",
"for rel in relationships:\n",
" provenance_tracker.track_relationship(rel.get(\"source\"), rel.get(\"target\"), rel.get(\"source\"), rel)\n",
"\n",
"print(f\"Tracked provenance for {len(all_entities)} entities and {len(relationships)} relationships\")\n"
"# Verify conflict resolution results\n",
"nexus_node = next(n for n in kg['nodes'] if n['name'] == \"Nexus AI\")\n",
"print(\"\\nResolved Properties for Nexus AI:\")\n",
"print(f\" Employees: {nexus_node['properties'].get('employees')} (Resolved from DB/API)\")\n",
"print(f\" Valuation: {nexus_node['properties'].get('valuation')} (Resolved from Web/MCP)\")\n",
"print(f\" Competitors: {nexus_node['properties'].get('competitors')}\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Step 5: Build Unified Knowledge Graph\n",
"## Phase 4: Visualization\n",
"\n",
"Build a unified knowledge graph from integrated sources.\n"
"We use `KGVisualizer` to render the interactive graph."
]
},
{
@@ -182,37 +303,48 @@
"metadata": {},
"outputs": [],
"source": [
"builder = GraphBuilder()\n",
"print(\"Visualizing Graph...\")\n",
"visualizer = KGVisualizer(layout=\"force\", color_scheme=\"vibrant\")\n",
"\n",
"unified_kg = builder.build(resolved_entities, relationships)\n",
"\n",
"print(f\"Built unified knowledge graph\")\n",
"print(f\" Entities: {len(unified_kg.get('entities', []))}\")\n",
"print(f\" Relationships: {len(unified_kg.get('relationships', []))}\")\n",
"print(f\" Sources integrated: {len(set(e.get('source', '') for e in resolved_entities))}\")\n"
"# Render the network\n",
"# This supports interactive output in Jupyter\n",
"fig = visualizer.visualize_network(kg, output=\"interactive\")\n",
"fig.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Summary\n",
"## Conclusion\n",
"\n",
"You've learned advanced multi-source data integration:\n",
"\n",
"- **Multiple Ingestion Types**: FileIngestor, WebIngestor, DBIngestor, StreamIngestor, FeedIngestor\n",
"- **EntityResolver**: Resolve entities across sources\n",
"- **ConflictDetector**: Detect conflicts between sources\n",
"- **ProvenanceTracker**: Track data provenance\n",
"- **Unified Knowledge Graph**: Build integrated graph from multiple sources\n"
"In this notebook, we used `semantica`'s high-level modules to:\n",
"1. Ingest data from 5 different sources (including a simulated **MCP Search Agent**).\n",
"2. Automatically resolve identity to create a single \"Nexus AI\" node.\n",
"3. Resolve complex data conflicts (Valuation, Employee Count).\n",
"4. Visualize the unified Knowledge Graph with competitor relationships.\n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python"
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.5"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
"nbformat_minor": 4
}