<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Pranjul Chaurasiya</title>
    <description>The latest articles on DEV Community by Pranjul Chaurasiya (@pranjul_chaurasiya).</description>
    <link>https://dev.to/pranjul_chaurasiya</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2275353%2F66999788-4f32-474c-b8f5-eca01e6dd8c9.png</url>
      <title>DEV Community: Pranjul Chaurasiya</title>
      <link>https://dev.to/pranjul_chaurasiya</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pranjul_chaurasiya"/>
    <language>en</language>
    <item>
      <title>Software Supply Chain Memory: Connecting JFrog Artifactory to Cognee GraphRAG</title>
      <dc:creator>Pranjul Chaurasiya</dc:creator>
      <pubDate>Sat, 31 Oct 2026 17:57:32 +0000</pubDate>
      <link>https://dev.to/pranjul_chaurasiya/software-supply-chain-memory-connecting-jfrog-artifactory-to-cognee-graphrag-6g0</link>
      <guid>https://dev.to/pranjul_chaurasiya/software-supply-chain-memory-connecting-jfrog-artifactory-to-cognee-graphrag-6g0</guid>
      <description>&lt;p&gt;In modern enterprise DevOps and platform engineering, the software supply chain is vast and complex. Binary artifact repositories like &lt;strong&gt;JFrog Artifactory&lt;/strong&gt; store thousands of container images, language packages (npm, PyPI, Maven), and Helm charts alongside critical CI/CD build execution logs and SBOM dependencies.&lt;/p&gt;

&lt;p&gt;When vulnerabilities arise (such as zero-day CVEs in upstream dependencies) or release rollbacks occur, platform engineers and security analysts need to rapidly answer connected questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Which Docker images deployed in staging were compiled from Git commit &lt;code&gt;9f8a2b&lt;/code&gt;?&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;What published modules declare dependencies on a specific vulnerable package version?&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;What is the SHA-256 cryptographic checksum and build timeline for our payment microservice release?&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because software supply chains are intrinsically hierarchical and relational (&lt;code&gt;Repository&lt;/code&gt; $\rightarrow$ &lt;code&gt;Artifact&lt;/code&gt; $\rightarrow$ &lt;code&gt;Module&lt;/code&gt; $\rightarrow$ &lt;code&gt;Build Run&lt;/code&gt; $\rightarrow$ &lt;code&gt;Dependencies&lt;/code&gt;), flat text search often misses the full dependency context. &lt;/p&gt;

&lt;p&gt;As part of the &lt;strong&gt;WeMakeDevs × Cognee Mergetober Hackathon&lt;/strong&gt;, I developed and submitted the &lt;strong&gt;JFrog Artifactory data-source connector&lt;/strong&gt; (&lt;code&gt;cognee-community-connector-artifactory&lt;/code&gt;) for &lt;a href="https://github.com/topoteretes/cognee" rel="noopener noreferrer"&gt;Cognee&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here is an architectural deep dive into how we bridge Artifactory repository topologies and build provenance into Cognee's GraphRAG engine.&lt;/p&gt;




&lt;h2&gt;
  
  
  Architecture: Supply Chain Knowledge Graph
&lt;/h2&gt;

&lt;p&gt;The connector extracts repository topologies, artifact metadata, and build provenance directly from Artifactory's REST and AQL (Artifactory Query Language) endpoints:&lt;br&gt;
&lt;/p&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;flowchart TD
    subgraph ArtifactoryAPI ["JFrog Artifactory REST &amp;amp; AQL"]
        A["/api/repositories (Local, Remote, Virtual)"]
        B["/api/search/aql (Artifact Metadata &amp;amp; Checksums)"]
        C["/api/build/{name}/{number} (Build Runs &amp;amp; SBOM)"]
    end

    subgraph ConnectorCore ["Security &amp;amp; Normalization Layer"]
        D["Pre-Ingestion Credential Scrubbing (Tokens &amp;amp; API Keys)"]
        E["Zero Code Execution (Passive JSON AST Parsing)"]
        F["Selective Scoping Filter (repo_keys, repo_type, ecosystems)"]
        G["Structured Markdown Document Serializer"]
    end

    subgraph CogneeEngine ["Cognee GraphRAG Ingestion"]
        H["dlt Source (DOCUMENT_SOURCE_ATTR='artifactory')"]
        I["Cognify Pipeline (LLM Relationship Extraction)"]
        J["Software Supply Chain Knowledge Graph (FalkorDB / NetworkX)"]
        K["Vector Store (Semantic Memory)"]
        L["write_disposition='replace' (Orphan Cleanup)"]
    end

    A &amp;amp; B &amp;amp; C --&amp;gt; D --&amp;gt; E --&amp;gt; F --&amp;gt; G --&amp;gt; H
    H --&amp;gt; I --&amp;gt; J &amp;amp; K
    H --&amp;gt; L&lt;/code&gt;&lt;/pre&gt;






&lt;h2&gt;
  
  
  1. Multi-Resource Ingestion: Repositories, Artifacts, &amp;amp; Build Runs
&lt;/h2&gt;

&lt;p&gt;The connector captures three synchronized levels of the software supply chain:&lt;/p&gt;

&lt;h3&gt;
  
  
  A. Repository Topologies (&lt;code&gt;artifactory_repositories&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;Ingests local, remote, and virtual repositories across container and package ecosystems (Docker, Maven, npm, PyPI, Helm, etc.), capturing package types, descriptions, repository layouts, and governance notes.&lt;/p&gt;

&lt;h3&gt;
  
  
  B. Cryptographic Artifact Integrity (&lt;code&gt;artifactory_artifacts&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;Serializes artifact coordinates, repository paths, file sizes, creation/modification timestamps, and cryptographic checksums:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Artifactory Artifact: services/auth-service/v1.4.0/manifest.json&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Repository:**&lt;/span&gt; docker-prod-local (docker / local)
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**File Size:**&lt;/span&gt; 2,048 bytes
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Created At:**&lt;/span&gt; 2026-09-15T08:30:00Z
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Checksums:**&lt;/span&gt;
&lt;span class="p"&gt;  -&lt;/span&gt; &lt;span class="sb"&gt;`SHA-256`&lt;/span&gt;: &lt;span class="sb"&gt;`e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855`&lt;/span&gt;
&lt;span class="p"&gt;  -&lt;/span&gt; &lt;span class="sb"&gt;`SHA-1`&lt;/span&gt;: &lt;span class="sb"&gt;`da39a3ee5e6b4b0d3255bfef95601890afd80709`&lt;/span&gt;
&lt;span class="p"&gt;  -&lt;/span&gt; &lt;span class="sb"&gt;`MD5`&lt;/span&gt;: &lt;span class="sb"&gt;`d41d8cd98f00b204e9800998ecf8427e`&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  C. CI/CD Build Provenance &amp;amp; SBOM (&lt;code&gt;artifactory_builds&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;Captures CI/CD execution metadata, build agent details, VCS commit SHAs, published modules, and declared dependency trees for end-to-end provenance.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Invariants &amp;amp; Security Standards
&lt;/h2&gt;

&lt;p&gt;To meet Cognee's strict maintainer standards, the connector enforces key architectural invariants:&lt;/p&gt;

&lt;h3&gt;
  
  
  Zero Code Execution
&lt;/h3&gt;

&lt;p&gt;Ingesting binary artifact metadata must never risk code execution. The connector parses REST API responses and AQL structures strictly as passive JSON data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pre-Ingestion Credential Masking
&lt;/h3&gt;

&lt;p&gt;Authentication headers (&lt;code&gt;X-JFrog-Art-Api&lt;/code&gt;, Bearer access tokens, basic auth credentials) are scrubbed before any records reach Cognee memory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;redact_credentials&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;replacement&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;REDACTION_PATTERNS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;replacement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  "Forget-on-Delete" via Snapshot Sync
&lt;/h3&gt;

&lt;p&gt;When obsolete packages are cleaned up by Artifactory retention policies, their graph nodes must not persist as ghost references in AI memory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;setattr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DOCUMENT_SOURCE_ATTR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;artifactory&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nd"&gt;@dlt.resource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;artifactory_artifacts&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;write_disposition&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;replace&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;artifacts_resource&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="bp"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With &lt;code&gt;write_disposition="replace"&lt;/code&gt;, Cognee's native orphan cleanup prunes deleted packages on each resync while preserving active dependency links.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Querying Supply Chain Memory in Python
&lt;/h2&gt;

&lt;p&gt;Connecting Artifactory to Cognee requires only a few lines of asynchronous code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;cognee&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;cognee_community_connector_artifactory&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;artifactory_source&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="c1"&gt;# 1. Initialize Artifactory source
&lt;/span&gt;    &lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;artifactory_source&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;base_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ARTIFACTORY_URL&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://company.jfrog.io/artifactory&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ARTIFACTORY_TOKEN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;repo_keys&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;docker-prod-local&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;libs-release-local&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;include_artifacts&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;include_builds&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# 2. Add to Cognee memory and build Knowledge Graph
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Ingesting software supply chain metadata...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;cognee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Running Cognify: Constructing Supply Chain Knowledge Graph...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;cognee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cognify&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;# 3. Ask natural language supply chain questions
&lt;/span&gt;    &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Which Docker image was built from commit 9f8a2b and what are its declared dependencies?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Querying Cognee: &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;cognee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;[Supply Chain Insight]:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Verification &amp;amp; Code Quality
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;100% Offline Passing Tests:&lt;/strong&gt; 18/18 unit tests pass offline with zero network calls (&lt;code&gt;tests/test_artifactory.py&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dependency Hygiene:&lt;/strong&gt; Configured with flexible dependency ranges (&lt;code&gt;cognee&amp;gt;=1.6.3,&amp;lt;2&lt;/code&gt; and &lt;code&gt;dlt&amp;gt;=1.9,&amp;lt;2&lt;/code&gt;) avoiding exact pins.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DCO Certified:&lt;/strong&gt; Verified Developer Certificate of Origin (&lt;code&gt;Signed-off-by&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Pull Request &amp;amp; Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pull Request:&lt;/strong&gt; &lt;a href="https://github.com/topoteretes/cognee-community/pull/601" rel="noopener noreferrer"&gt;topoteretes/cognee-community#601&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Upstream Discussion:&lt;/strong&gt; &lt;a href="https://github.com/topoteretes/cognee/issues/5728" rel="noopener noreferrer"&gt;topoteretes/cognee#5728&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;How is your team indexing software supply chain artifacts and SBOM metadata for AI agents? Share your thoughts below!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>devops</category>
      <category>ai</category>
      <category>python</category>
    </item>
    <item>
      <title>Bridging the Lakehouse: Ingesting Databricks Unity Catalog into Cognee Knowledge Graphs</title>
      <dc:creator>Pranjul Chaurasiya</dc:creator>
      <pubDate>Sat, 31 Oct 2026 17:13:49 +0000</pubDate>
      <link>https://dev.to/pranjul_chaurasiya/bridging-the-lakehouse-ingesting-databricks-unity-catalog-into-cognee-knowledge-graphs-1i7m</link>
      <guid>https://dev.to/pranjul_chaurasiya/bridging-the-lakehouse-ingesting-databricks-unity-catalog-into-cognee-knowledge-graphs-1i7m</guid>
      <description>&lt;p&gt;In large enterprise lakehouses, finding the right dataset, understanding table schemas, and tracing ML model lineage is often a major hurdle for data scientists, product managers, and AI agents.&lt;/p&gt;

&lt;p&gt;While catalog tools like &lt;strong&gt;Databricks Unity Catalog&lt;/strong&gt; centralize table schemas, storage locations, and column-level comments, interacting with these assets via natural language requires a structured knowledge layer. Vector similarity alone fails when users ask questions that span organizational boundaries:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;"Which production tables contain customer billing information, and what are their primary keys?"&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"What AI/ML models are registered under champion status for credit risk prediction?"&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;"Show me all schemas in the analytics catalog that partition by &lt;code&gt;event_date&lt;/code&gt;."&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To solve this, I designed and implemented the official &lt;strong&gt;Databricks Unity Catalog data-source connector&lt;/strong&gt; (&lt;code&gt;cognee-community-connector-unitycatalog&lt;/code&gt;) for &lt;a href="https://github.com/topoteretes/cognee" rel="noopener noreferrer"&gt;Cognee&lt;/a&gt; as part of the &lt;strong&gt;WeMakeDevs × Cognee Mergetober Hackathon&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here is how we turn Unity Catalog metadata into a connected GraphRAG layer.&lt;/p&gt;




&lt;h2&gt;
  
  
  Architectural Blueprint
&lt;/h2&gt;

&lt;p&gt;The connector traverses Unity Catalog’s three-level namespace hierarchy (&lt;code&gt;catalog.schema.table&lt;/code&gt;) along with the AI/ML Model Registry, converting tabular definitions into rich semantic markdown nodes:&lt;br&gt;
&lt;/p&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;flowchart TD
    subgraph UnityCatalog ["Databricks Unity Catalog API"]
        A["/api/2.1/unity-catalog/catalogs"]
        B["/api/2.1/unity-catalog/schemas"]
        C["/api/2.1/unity-catalog/tables (Managed, External, Views)"]
        D["/api/2.1/unity-catalog/models (Registered AI Models)"]
    end

    subgraph ConnectorEngine ["Connector Ingestion &amp;amp; Normalization"]
        E["Selective Scope Filter (catalogs / schemas)"]
        F["Column Schema Serializer (Types, Comments, Partitions)"]
        G["Model Registry Metadata (Aliases, Runs, Tags)"]
        H["Credential Scrubbing (Databricks PAT &amp;amp; Bearer Redaction)"]
    end

    subgraph CogneeGraph ["Cognee GraphRAG Ecosystem"]
        I["dlt Source (DOCUMENT_SOURCE_ATTR='unitycatalog')"]
        J["Cognify Entity Extractor"]
        K["Lakehouse Knowledge Graph (FalkorDB / NetworkX)"]
        L["Vector Index (Qdrant)"]
        M["Forget-on-Delete Orphan Pruner"]
    end

    A &amp;amp; B &amp;amp; C &amp;amp; D --&amp;gt; E --&amp;gt; F &amp;amp; G --&amp;gt; H --&amp;gt; I
    I --&amp;gt; J --&amp;gt; K &amp;amp; L
    I --&amp;gt; M&lt;/code&gt;&lt;/pre&gt;






&lt;h2&gt;
  
  
  1. Modeling the Three-Level Namespace &amp;amp; AI Models
&lt;/h2&gt;

&lt;p&gt;Databricks Unity Catalog organizes assets in a strict hierarchy: &lt;code&gt;catalog&lt;/code&gt; $\rightarrow$ &lt;code&gt;schema&lt;/code&gt; $\rightarrow$ &lt;code&gt;table/view&lt;/code&gt;. The connector extracts four distinct resource tiers:&lt;/p&gt;

&lt;h3&gt;
  
  
  A. Catalogs (&lt;code&gt;unitycatalog_catalogs&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;Captures top-level governance containers, storage roots, catalog owners, and business descriptions.&lt;/p&gt;

&lt;h3&gt;
  
  
  B. Schemas (&lt;code&gt;unitycatalog_schemas&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;Captures functional namespaces (e.g. &lt;code&gt;finance&lt;/code&gt;, &lt;code&gt;marketing&lt;/code&gt;, &lt;code&gt;ml_feature_store&lt;/code&gt;), properties, and regional metadata.&lt;/p&gt;

&lt;h3&gt;
  
  
  C. Tables &amp;amp; Views with Rich Column Types (&lt;code&gt;unitycatalog_tables&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;Tables are transformed into structured markdown documents detailing table types (&lt;code&gt;MANAGED&lt;/code&gt;, &lt;code&gt;EXTERNAL&lt;/code&gt;, &lt;code&gt;VIEW&lt;/code&gt;), underlying data formats (&lt;code&gt;DELTA&lt;/code&gt;, &lt;code&gt;PARQUET&lt;/code&gt;), and complete column schemas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Table: production.finance.settled_transactions&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Catalog:**&lt;/span&gt; production | &lt;span class="gs"&gt;**Schema:**&lt;/span&gt; finance
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Table Type:**&lt;/span&gt; MANAGED (DELTA)
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Owner:**&lt;/span&gt; finance-data-eng
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Storage Location:**&lt;/span&gt; s3://company-lakehouse/finance/settled_transactions

&lt;span class="gu"&gt;### Columns&lt;/span&gt;
| Column Name | Type | Nullable | Comment |
| :--- | :--- | :--- | :--- |
| &lt;span class="sb"&gt;`transaction_id`&lt;/span&gt; | STRING | No | Unique payment transaction identifier |
| &lt;span class="sb"&gt;`account_id`&lt;/span&gt; | STRING | No | Foreign key to core accounts |
| &lt;span class="sb"&gt;`amount_cents`&lt;/span&gt; | BIGINT | No | Settled amount in cents |
| &lt;span class="sb"&gt;`settled_at`&lt;/span&gt; | TIMESTAMP | No | Monotonic settlement timestamp |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  D. AI/ML Model Registry (&lt;code&gt;unitycatalog_models&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;Unity Catalog registers MLflow models directly within schemas. The connector ingests registered model names, current aliases (e.g., &lt;code&gt;champion&lt;/code&gt;, &lt;code&gt;challenger&lt;/code&gt;), model versions, run artifacts, and tags.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Dynamic Scoping &amp;amp; Forget-on-Delete Invariants
&lt;/h2&gt;

&lt;p&gt;Enterprise data lakehouses often host thousands of tables. Ingesting an entire data lake at once can create unnecessary overhead. The connector supports granular scoping:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;unitycatalog_source&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;catalogs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;production&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gold_analytics&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;schemas&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;finance&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;risk_modeling&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="n"&gt;include_tables&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;include_models&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Automatic Lifecycle Management ("Forget-on-Delete")
&lt;/h3&gt;

&lt;p&gt;When data engineers decommission legacy tables or drop experimental schemas, stale nodes shouldn't persist in company knowledge graphs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;setattr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DOCUMENT_SOURCE_ATTR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;unitycatalog&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nd"&gt;@dlt.resource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;unitycatalog_tables&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;write_disposition&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;replace&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;tables_resource&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="bp"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By tagging &lt;code&gt;DOCUMENT_SOURCE_ATTR = "unitycatalog"&lt;/code&gt; and &lt;code&gt;write_disposition="replace"&lt;/code&gt;, Cognee's internal diff engine detects removed tables upon each resync. Removed tables, columns, and model entries are automatically pruned from FalkorDB/NetworkX and Qdrant, guaranteeing 100% data consistency.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. End-to-End Implementation
&lt;/h2&gt;

&lt;p&gt;Here is how easily you can connect Databricks Unity Catalog to Cognee to query enterprise governance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;cognee&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;cognee_community_connector_unitycatalog&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;unitycatalog_source&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="c1"&gt;# 1. Connect to Databricks Workspace or Unity Catalog OSS
&lt;/span&gt;    &lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;unitycatalog_source&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;base_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DATABRICKS_HOST&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://adb-1234.azuredatabricks.net&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DATABRICKS_TOKEN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;catalogs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;production&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;include_tables&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;include_models&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# 2. Ingest into Cognee and build Knowledge Graph
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Ingesting Unity Catalog lakehouse metadata...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;cognee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Running Cognify to construct Governance Graph...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;cognee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cognify&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;# 3. Ask natural language questions across schemas &amp;amp; models
&lt;/span&gt;    &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;What columns exist in the production finance tables, and what is our champion credit model?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Querying Cognee: &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;cognee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;[Governance Answer]:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Verification &amp;amp; Standards
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;100% Offline Testing:&lt;/strong&gt; 18 comprehensive unit tests pass offline using mocked API payloads (&lt;code&gt;tests/test_unitycatalog.py&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security Guardrails:&lt;/strong&gt; Pre-ingestion credential masking strips Databricks tokens from all logs and error traces.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintainer Alignment:&lt;/strong&gt; Fully compliant with Cognee’s DCO sign-off guidelines and Hatchling packaging conventions.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Pull Request &amp;amp; Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pull Request:&lt;/strong&gt; &lt;a href="https://github.com/topoteretes/cognee-community/pull/472" rel="noopener noreferrer"&gt;topoteretes/cognee-community#472&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Repository:&lt;/strong&gt; &lt;a href="https://github.com/topoteretes/cognee" rel="noopener noreferrer"&gt;topoteretes/cognee&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;How is your organization approaching conversational governance across Databricks and Iceberg catalogs? Share your feedback below!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>databricks</category>
      <category>ai</category>
      <category>dataengineering</category>
      <category>python</category>
    </item>
    <item>
      <title>Automating Post-Mortems: Ingesting PagerDuty Incidents &amp; Service Topologies into Cognee GraphRAG</title>
      <dc:creator>Pranjul Chaurasiya</dc:creator>
      <pubDate>Sat, 31 Oct 2026 17:13:17 +0000</pubDate>
      <link>https://dev.to/pranjul_chaurasiya/automating-post-mortems-ingesting-pagerduty-incidents-service-topologies-into-cognee-graphrag-443a</link>
      <guid>https://dev.to/pranjul_chaurasiya/automating-post-mortems-ingesting-pagerduty-incidents-service-topologies-into-cognee-graphrag-443a</guid>
      <description>&lt;p&gt;Writing incident retrospectives (post-mortems) and debugging recurring production outages are two of the most time-consuming responsibilities for Site Reliability Engineers (SREs). &lt;/p&gt;

&lt;p&gt;Engineers often spend hours cross-referencing PagerDuty timelines, responder notes, service dependencies, and past incident histories. When teams attempt to solve this with standard LLMs, they quickly run into context window limits or hallucinated timelines because incidents are tightly bound to time, services, and escalation hierarchies.&lt;/p&gt;

&lt;p&gt;With &lt;strong&gt;GraphRAG (Knowledge Graph Retrieval-Augmented Generation)&lt;/strong&gt;, an AI system can traverse:&lt;br&gt;
&lt;code&gt;Incident&lt;/code&gt; $\rightarrow$ &lt;code&gt;AFFECTS&lt;/code&gt; $\rightarrow$ &lt;code&gt;Service&lt;/code&gt; $\rightarrow$ &lt;code&gt;ESCALATES_TO&lt;/code&gt; $\rightarrow$ &lt;code&gt;Escalation Policy&lt;/code&gt; $\rightarrow$ &lt;code&gt;RESOLVED_BY&lt;/code&gt; $\rightarrow$ &lt;code&gt;Responder&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;As part of the &lt;strong&gt;WeMakeDevs × Cognee Mergetober Hackathon&lt;/strong&gt;, I built and submitted the &lt;strong&gt;PagerDuty data-source connector&lt;/strong&gt; (&lt;code&gt;cognee-community-connector-pagerduty&lt;/code&gt;) for &lt;a href="https://github.com/topoteretes/cognee" rel="noopener noreferrer"&gt;Cognee&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here is an architectural walkthrough of how we bridged PagerDuty incidents and service topologies into Cognee.&lt;/p&gt;


&lt;h2&gt;
  
  
  Architectural Workflow
&lt;/h2&gt;

&lt;p&gt;The connector extracts live incident streams and service architecture from PagerDuty's v2 REST API, cleans and redacts the payloads, and routes them into Cognee's document ingestion pipeline:&lt;br&gt;
&lt;/p&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;flowchart TD
    subgraph PagerDutyAPI ["PagerDuty REST API v2"]
        A["/incidents (Urgencies, Statuses, Timelines)"]
        B["/incidents/{id}/notes (Responder Chronology)"]
        C["/services (Service Catalogs &amp;amp; Dependencies)"]
    end

    subgraph ConnectorCore ["Security &amp;amp; Normalization Core"]
        D["Rate-Limit Backoff (HTTP 429 &amp;amp; Retry-After)"]
        E["Secret Redaction (API Tokens, Keys, PATs)"]
        F["Structured Markdown Serializer"]
    end

    subgraph CogneeCore ["Cognee GraphRAG Layer"]
        G["dlt Resource (cognee_document_source='pagerduty')"]
        H["Cognify Pipeline (LLM Relationship Extraction)"]
        I["Service &amp;amp; Incident Graph (FalkorDB / NetworkX)"]
        J["Semantic Memory (Vector Search)"]
    end

    A &amp;amp; B &amp;amp; C --&amp;gt; D --&amp;gt; E --&amp;gt; F --&amp;gt; G --&amp;gt; H --&amp;gt; I &amp;amp; J&lt;/code&gt;&lt;/pre&gt;






&lt;h2&gt;
  
  
  1. Dual-Resource Ingestion: Incidents &amp;amp; Service Catalogs
&lt;/h2&gt;

&lt;p&gt;Incidents in isolation lack critical context without knowing the service topology. The connector ingests two synchronized resources:&lt;/p&gt;

&lt;h3&gt;
  
  
  A. Live &amp;amp; Historical Incidents (&lt;code&gt;pagerduty_incidents&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;Captures incident IDs, numbers, titles, urgency levels (&lt;code&gt;high&lt;/code&gt;, &lt;code&gt;low&lt;/code&gt;), lifecycle statuses (&lt;code&gt;triggered&lt;/code&gt;, &lt;code&gt;acknowledged&lt;/code&gt;, &lt;code&gt;resolved&lt;/code&gt;), created and resolved timestamps, assignees, and crucially, &lt;strong&gt;responder notes&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# PagerDuty Incident #48291: Payment Gateway Timeout Surge&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Urgency:**&lt;/span&gt; high | &lt;span class="gs"&gt;**Status:**&lt;/span&gt; resolved
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Service:**&lt;/span&gt; Checkout-API
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Escalation Policy:**&lt;/span&gt; Payments-Primary-Tier1
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Created At:**&lt;/span&gt; 2026-10-31T18:20:00Z
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Resolved At:**&lt;/span&gt; 2026-10-31T18:45:00Z
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Assignees:**&lt;/span&gt; Alex Chen, Maria Garcia

&lt;span class="gu"&gt;### Responder Timeline &amp;amp; Notes&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**2026-10-31T18:25:00Z (Alex Chen):**&lt;/span&gt; Identified 504 gateway timeouts originating from payment vendor webhook endpoint.
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**2026-10-31T18:35:00Z (Maria Garcia):**&lt;/span&gt; Toggled circuit breaker to secondary gateway; error rates normalized.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  B. Service Topologies (&lt;code&gt;pagerduty_services&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;Ingests registered microservices, descriptions, alert creation configurations, auto-resolve timeout limits, and team ownership.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Production Security &amp;amp; Pre-Ingestion Redaction
&lt;/h2&gt;

&lt;p&gt;Incident titles, descriptions, and responder notes frequently contain sensitive diagnostic payloads pasted during live triage—such as database connection strings, bearer tokens, or AWS credentials.&lt;/p&gt;

&lt;p&gt;The PagerDuty connector applies strict pre-ingestion regex redaction across all incident fields before emitting records:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;

&lt;span class="n"&gt;PATTERNS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bearer\s+[A-Za-z0-9\-._~+/]+=*&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IGNORECASE&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bearer [REDACTED_TOKEN]&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AKIA[0-9A-Z]{16}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[REDACTED_AWS_KEY]&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sk-[A-Za-z0-9]{20,}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[REDACTED_API_KEY]&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ghp_[A-Za-z0-9]{36}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[REDACTED_GITHUB_PAT]&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;redact_secrets&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;repl&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;PATTERNS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;repl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  3. Cognitive Integration with Cognee
&lt;/h2&gt;

&lt;p&gt;By tagging the source with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;setattr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DOCUMENT_SOURCE_ATTR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pagerduty&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cognee bypasses generic relational flattening and feeds the Markdown summaries into its entity extraction pipeline.&lt;/p&gt;

&lt;h3&gt;
  
  
  Querying Incident Memory in Python
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;cognee&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;cognee_community_connector_pagerduty&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;pagerduty_source&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="c1"&gt;# 1. Initialize PagerDuty connector
&lt;/span&gt;    &lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;pagerduty_source&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;PAGERDUTY_API_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;resources&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;incidents&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;services&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;urgencies&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;high&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# 2. Add to Cognee and run Cognify
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Ingesting PagerDuty incidents and service topologies...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;cognee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Building incident knowledge graph...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;cognee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cognify&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;# 3. Query past incidents to automate post-mortems
&lt;/span&gt;    &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;What caused the high urgency Checkout-API incident and how did Maria resolve it?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Querying: &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;cognee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;[Incident Memory]:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Verification &amp;amp; Compliance
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Complete Test Coverage:&lt;/strong&gt; Offline test suite mocking PagerDuty REST API endpoints with zero network dependencies (&lt;code&gt;tests/test_source.py&lt;/code&gt;, &lt;code&gt;tests/test_client.py&lt;/code&gt;, &lt;code&gt;tests/test_redaction.py&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resilient Rate-Limiting:&lt;/strong&gt; Exponential backoff with &lt;code&gt;Retry-After&lt;/code&gt; capping to avoid thread locks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DCO Certified:&lt;/strong&gt; Clean commit history with Developer Certificate of Origin sign-off.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Check Out the Code
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pull Request:&lt;/strong&gt; &lt;a href="https://github.com/topoteretes/cognee-community/pull/429" rel="noopener noreferrer"&gt;topoteretes/cognee-community#429&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Repository:&lt;/strong&gt; &lt;a href="https://github.com/topoteretes/cognee" rel="noopener noreferrer"&gt;topoteretes/cognee&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Have questions about integrating incident response into AI workflows? Feel free to connect in the comments!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>sre</category>
      <category>ai</category>
      <category>python</category>
    </item>
    <item>
      <title>Incident Intelligence: Connecting Atlassian Opsgenie to Cognee AI Memory &amp; Knowledge Graphs</title>
      <dc:creator>Pranjul Chaurasiya</dc:creator>
      <pubDate>Sat, 31 Oct 2026 17:12:27 +0000</pubDate>
      <link>https://dev.to/pranjul_chaurasiya/incident-intelligence-connecting-atlassian-opsgenie-to-cognee-ai-memory-knowledge-graphs-4hbp</link>
      <guid>https://dev.to/pranjul_chaurasiya/incident-intelligence-connecting-atlassian-opsgenie-to-cognee-ai-memory-knowledge-graphs-4hbp</guid>
      <description>&lt;p&gt;When high-severity incidents (P1/P2) trigger in production, engineering teams are inundated with fragmented information: fired alert payloads, escalation hops, on-call rotation schedules, and post-incident Slack threads. &lt;/p&gt;

&lt;p&gt;Traditional Retrieval-Augmented Generation (RAG) fails in incident response because incidents are fundamentally &lt;strong&gt;relational&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Which on-call engineer was paged when the authentication microservice breached latency thresholds?&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Has this specific database failover happened before across our escalation policies?&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;What services depend on the upstream system currently firing alerts?&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To answer these questions, AI systems need more than simple vector similarity over flat text—they need &lt;strong&gt;GraphRAG (Knowledge Graph RAG)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;As part of the &lt;strong&gt;WeMakeDevs × Cognee Mergetober Hackathon&lt;/strong&gt;, I built and submitted the &lt;strong&gt;Atlassian Opsgenie data-source connector&lt;/strong&gt; (&lt;code&gt;cognee-community-connector-opsgenie&lt;/code&gt;) for &lt;a href="https://github.com/topoteretes/cognee" rel="noopener noreferrer"&gt;Cognee&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this deep dive, we explore how to turn Opsgenie alert streams, on-call schedules, and escalation trees into an active AI knowledge graph while adhering to strict security and lifecycle invariants.&lt;/p&gt;




&lt;h2&gt;
  
  
  Architecture: Real-Time SRE Memory
&lt;/h2&gt;

&lt;p&gt;The Opsgenie connector bridges operational telemetry into Cognee’s semantic layer:&lt;br&gt;
&lt;/p&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;flowchart TD
    subgraph OpsgenieAPI ["Atlassian Opsgenie API"]
        A["/v2/alerts (P1-P5 Severities)"]
        B["/v2/schedules (On-Call Rotations)"]
        C["/v2/escalations (Routing Rules)"]
    end

    subgraph ConnectorGuard ["Connector Security &amp;amp; Hygiene"]
        D["SSRF Domain Validator (api.opsgenie.com / api.eu.opsgenie.com)"]
        E["Rate-Limit Backoff (Cap Retry-After at 60s)"]
        F["Credential Redaction (GenieKey &amp;amp; Auth Headers)"]
    end

    subgraph Formatting ["Document &amp;amp; Metadata Serialization"]
        G["Alert Markdown Documents + Entity Properties"]
        H["On-Call Schedule &amp;amp; Participant Trees"]
        I["Escalation Policy Nodes"]
    end

    subgraph CogneeEngine ["Cognee GraphRAG Pipeline"]
        J["dlt Source (DOCUMENT_SOURCE_ATTR='opsgenie')"]
        K["Cognify Pipeline (LLM Entity/Relation Extraction)"]
        L["Vector Store (Embeddings)"]
        M["Knowledge Graph (FalkorDB / NetworkX)"]
        N["Orphan Pruning (Forget-on-Delete)"]
    end

    A &amp;amp; B &amp;amp; C --&amp;gt; D --&amp;gt; E --&amp;gt; F
    F --&amp;gt; G &amp;amp; H &amp;amp; I --&amp;gt; J
    J --&amp;gt; K
    K --&amp;gt; L &amp;amp; M
    J --&amp;gt; N&lt;/code&gt;&lt;/pre&gt;






&lt;h2&gt;
  
  
  1. Multi-Resource Ingestion: Alerts, On-Call, &amp;amp; Escalations
&lt;/h2&gt;

&lt;p&gt;Opsgenie is not just a stream of alerts; it represents the operational topology of your engineering organization. The connector structures three distinct resources:&lt;/p&gt;

&lt;h3&gt;
  
  
  A. Alert Telemetry (&lt;code&gt;opsgenie_alerts&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;Ingests active and historical alerts, extracting priority (&lt;code&gt;P1&lt;/code&gt; through &lt;code&gt;P5&lt;/code&gt;), status (&lt;code&gt;open&lt;/code&gt;, &lt;code&gt;acknowledged&lt;/code&gt;, &lt;code&gt;closed&lt;/code&gt;), tags, source integrations, responder notes, and diagnostic details.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gh"&gt;# Opsgenie Alert: Database Connection Pool Exhausted (P1 - CRITICAL)&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Alert ID:**&lt;/span&gt; &lt;span class="sb"&gt;`4a9b...`&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Status:**&lt;/span&gt; open
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Created At:**&lt;/span&gt; 2026-10-31T20:15:00Z
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Responders:**&lt;/span&gt; SRE-Platform-Team
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Tags:**&lt;/span&gt; &lt;span class="sb"&gt;`database`&lt;/span&gt;, &lt;span class="sb"&gt;`postgres`&lt;/span&gt;, &lt;span class="sb"&gt;`payment-gateway`&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Description:**&lt;/span&gt; Active connections reached 100% capacity on primary read-write cluster.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  B. On-Call Rotations (&lt;code&gt;opsgenie_schedules&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;Ingests schedules, rotation layers (weekly/daily/custom), timezones, and active on-call participants. This allows Cognee to correlate who was on shift during an incident window.&lt;/p&gt;

&lt;h3&gt;
  
  
  C. Escalation Routing (&lt;code&gt;opsgenie_escalations&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;Maps out escalation policies, delay intervals, repeat counts, and notification rules across user and team targets.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Hardened Production Security &amp;amp; Maintainer Invariants
&lt;/h2&gt;

&lt;p&gt;Building enterprise connectors requires battle-tested engineering. Here are the core patterns implemented to meet Cognee maintainer review standards:&lt;/p&gt;

&lt;h3&gt;
  
  
  SSRF &amp;amp; Domain Validation
&lt;/h3&gt;

&lt;p&gt;When traversing pagination links or following &lt;code&gt;@odata.nextLink&lt;/code&gt; / &lt;code&gt;next&lt;/code&gt; URLs, the client explicitly validates hostnames before attaching credentials:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;urllib.parse&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;urlparse&lt;/span&gt;

&lt;span class="n"&gt;ALLOWED_HOSTS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;api.opsgenie.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;api.eu.opsgenie.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;validate_target_url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;parsed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;urlparse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;parsed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scheme&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Insecure scheme: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;parsed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;scheme&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;. HTTPS required.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;parsed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hostname&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;ALLOWED_HOSTS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;ValueError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SSRF violation: Host &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;parsed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hostname&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; is not an authorized Opsgenie endpoint.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Sanitized Error Messaging (Zero Leaks in Sentry/Logs)
&lt;/h3&gt;

&lt;p&gt;HTTP error bodies can contain echoed bearer tokens or sensitive system parameters. The connector never dumps raw HTTP bodies into exceptions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;raise_sanitized_error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Safe error message with HTTP status code only
&lt;/span&gt;    &lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Opsgenie API error: HTTP &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; (&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;reason_phrase&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;OpsgenieAPIError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# Store scrubbed details privately without exposing to standard str(err)
&lt;/span&gt;    &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Capped &lt;code&gt;Retry-After&lt;/code&gt; Handling
&lt;/h3&gt;

&lt;p&gt;Unbounded retry loops can hold process-wide staging locks in distributed environments. If Opsgenie returns an HTTP 429 with &lt;code&gt;Retry-After: 300&lt;/code&gt;, sleeping for 5 minutes can cause downstream deadlocks. The connector caps backoffs to a maximum of 60 seconds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;calculate_retry_delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;header&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Retry-After&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;header&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isdigit&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;header&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mf"&gt;60.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mf"&gt;2.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  3. The "Forget-on-Delete" Invariant in Action
&lt;/h2&gt;

&lt;p&gt;Incident management data is ephemeral: alerts close, schedules rotate, and temporary escalations expire. If an AI memory system retains resolved or deleted alerts forever, retrieval precision degrades.&lt;/p&gt;

&lt;p&gt;By configuring:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;setattr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DOCUMENT_SOURCE_ATTR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;opsgenie&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and tagging resources with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;write_disposition&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;replace&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cognee's ingestion engine recognizes when an alert is resolved or deleted upstream. During synchronization, Cognee computes the snapshot delta and triggers automatic &lt;strong&gt;orphan cleanup&lt;/strong&gt;, pruning stale entities and edges from FalkorDB/NetworkX and Qdrant without corrupting existing historical relationships.&lt;/p&gt;




&lt;h2&gt;
  
  
  Quickstart: SRE Knowledge Graph in 40 Lines of Python
&lt;/h2&gt;

&lt;p&gt;Here is how you can index your active Opsgenie alerts and on-call schedules into Cognee:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;cognee&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;cognee_community_connector_opsgenie&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;opsgenie_source&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="c1"&gt;# 1. Configure the Opsgenie source
&lt;/span&gt;    &lt;span class="c1"&gt;# Filters to open high-priority alerts while syncing active schedules
&lt;/span&gt;    &lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;opsgenie_source&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;api_key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;OPSGENIE_API_KEY&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="n"&gt;base_url&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;https://api.opsgenie.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status: open AND priority: P1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;include_schedules&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;include_escalations&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# 2. Add to Cognee memory and build the Knowledge Graph
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Ingesting Opsgenie telemetry...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;cognee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Running Cognify: Extracting SRE entities and building relationships...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;cognee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cognify&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;# 3. Query the SRE Memory
&lt;/span&gt;    &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Who is currently on-call for critical P1 database alerts, and what is the escalation path?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Querying Cognee: &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;cognee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;[Insight]: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What Happens Behind the Scenes?
&lt;/h3&gt;

&lt;p&gt;During &lt;code&gt;cognee.cognify()&lt;/code&gt;, Cognee extracts entity nodes like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Alert("Database Connection Pool Exhausted")&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Team("SRE-Platform-Team")&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Person("Jane Doe", role="Primary On-Call")&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;EscalationRule("Step 1 -&amp;gt; Page Jane Doe; Step 2 (5 min) -&amp;gt; Page Platform Lead")&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It establishes graph edges (&lt;code&gt;ASSIGNED_TO&lt;/code&gt;, &lt;code&gt;ESCALATES_TO&lt;/code&gt;, &lt;code&gt;AFFECTS_SERVICE&lt;/code&gt;), enabling the LLM to give grounded, deterministic operational answers.&lt;/p&gt;




&lt;h2&gt;
  
  
  Verification &amp;amp; Code Quality
&lt;/h2&gt;

&lt;p&gt;The connector is verified with a comprehensive offline test harness:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;14/14 Unit Tests Passing:&lt;/strong&gt; Zero live network calls using &lt;code&gt;respx&lt;/code&gt; HTTP mocking (&lt;code&gt;tests/test_opsgenie.py&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CodeQL CLI Security Audit:&lt;/strong&gt; 100% clean across 174 rules (&lt;code&gt;python-security-and-quality.qls&lt;/code&gt;) with 0 CWE findings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DCO Certified:&lt;/strong&gt; Verified Developer Certificate of Origin (&lt;code&gt;git commit -s&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Check Out the Code
&lt;/h2&gt;

&lt;p&gt;The Atlassian Opsgenie connector is open for review in the Cognee Community ecosystem:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pull Request:&lt;/strong&gt; &lt;a href="https://github.com/topoteretes/cognee-community/pull/478" rel="noopener noreferrer"&gt;topoteretes/cognee-community#478&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Upstream Discussion:&lt;/strong&gt; &lt;a href="https://github.com/topoteretes/cognee/issues/5682" rel="noopener noreferrer"&gt;topoteretes/cognee#5682&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Building SRE agents or interested in GraphRAG for operations? Let me know your thoughts or feedback in the comments!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>sre</category>
      <category>ai</category>
      <category>python</category>
    </item>
    <item>
      <title>Zero Code Execution: Building a Safe Jupyter Notebook Connector for Cognee GraphRAG</title>
      <dc:creator>Pranjul Chaurasiya</dc:creator>
      <pubDate>Sat, 31 Oct 2026 17:12:25 +0000</pubDate>
      <link>https://dev.to/pranjul_chaurasiya/zero-code-execution-building-a-safe-jupyter-notebook-connector-for-cognee-graphrag-ab6</link>
      <guid>https://dev.to/pranjul_chaurasiya/zero-code-execution-building-a-safe-jupyter-notebook-connector-for-cognee-graphrag-ab6</guid>
      <description>&lt;p&gt;In modern data science organizations, Jupyter Notebooks (&lt;code&gt;.ipynb&lt;/code&gt;) serve as the primary medium for exploratory data analysis (EDA), model training, hypothesis validation, and architectural experiments. However, standard enterprise knowledge graphs and LLM retrieval pipelines have historically struggled to ingest notebooks safely and meaningfully:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Security Vulnerabilities (OWASP LLM02):&lt;/strong&gt; Ingesting external notebooks that contain untrusted Python or shell magics (&lt;code&gt;!curl&lt;/code&gt;, &lt;code&gt;os.system&lt;/code&gt;) risks accidental code execution if runtime environments (&lt;code&gt;ipykernel&lt;/code&gt;, &lt;code&gt;exec()&lt;/code&gt;, &lt;code&gt;eval()&lt;/code&gt;) are triggered during parsing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Noise &amp;amp; Bloat:&lt;/strong&gt; A single uncleaned notebook can contain tens of megabytes of raw Base64 PNG plots, ANSI color codes from failed stack traces, and verbose progress bar outputs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stale Knowledge &amp;amp; Orphaned Entities:&lt;/strong&gt; When a data scientist deletes or refactors a notebook, stale entity nodes and outdated embeddings often remain indefinitely in vector and graph storage.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As part of the &lt;strong&gt;WeMakeDevs × Cognee Mergetober Hackathon&lt;/strong&gt;, I engineered and submitted the official &lt;strong&gt;Jupyter Notebook data-source connector&lt;/strong&gt; (&lt;code&gt;cognee-community-connector-jupyter&lt;/code&gt;) for &lt;a href="https://github.com/topoteretes/cognee" rel="noopener noreferrer"&gt;Cognee&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this article, I will break down how we solved these challenges through &lt;strong&gt;zero code execution passive parsing&lt;/strong&gt;, &lt;strong&gt;pre-ingestion secret redaction&lt;/strong&gt;, and Cognee’s native &lt;strong&gt;forget-on-delete graph lifecycle&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Architecture: From Raw &lt;code&gt;.ipynb&lt;/code&gt; to Knowledge Graph
&lt;/h2&gt;

&lt;p&gt;Here is the high-level ingestion pipeline from disk to Cognee's GraphRAG engine:&lt;br&gt;
&lt;/p&gt;

&lt;pre data-lang="mermaid"&gt;&lt;code&gt;flowchart TD
    A[".ipynb File on Disk"] --&amp;gt; B["Passive JSON Parser (nbformat v3/v4)"]
    B --&amp;gt; C["Cell Content Extractor"]

    subgraph Sanitization ["Pre-Ingestion Sanitization"]
        C --&amp;gt; D["Markdown Cells (Structured Prose)"]
        C --&amp;gt; E["Code Cells (Fenced Code Blocks)"]
        C --&amp;gt; F["Outputs (stdout / text/plain)"]
        F --&amp;gt; G["Noise Filter (Strip ANSI, Drop Base64 Images)"]
        D &amp;amp; E &amp;amp; G --&amp;gt; H["Regex Redactor (Bearer, API Keys, PATs)"]
    end

    H --&amp;gt; I["dlt Document Generator (cognee_document_source='jupyter')"]
    I --&amp;gt; J["Cognee Ingestion Engine"]

    subgraph Cognify ["Cognify Graph Processing"]
        J --&amp;gt; K["Entity &amp;amp; Relationship Extraction (LLM)"]
        K --&amp;gt; L["Knowledge Graph (NetworkX / FalkorDB)"]
        K --&amp;gt; M["Vector Store (Qdrant / LanceDB)"]
    end

    J --&amp;gt; N["write_disposition='replace' (Forget-on-Delete Orphan Cleanup)"]&lt;/code&gt;&lt;/pre&gt;






&lt;h2&gt;
  
  
  1. Zero Code Execution: Passive JSON AST Parsing
&lt;/h2&gt;

&lt;p&gt;A critical security requirement when building data pipelines for AI memory is &lt;strong&gt;never executing untrusted code&lt;/strong&gt;. Many naive notebook parsers inadvertently import kernel execution utilities or evaluate expressions.&lt;/p&gt;

&lt;p&gt;Under the hood, every &lt;code&gt;.ipynb&lt;/code&gt; file is simply a structured JSON document conforming to the Jupyter &lt;code&gt;nbformat&lt;/code&gt; schema. Our connector treats notebooks strictly as passive data using Python's standard library:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pathlib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;parse_notebook_statically&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Statically parse .ipynb as raw JSON with zero kernel interaction.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;encoding&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;utf-8&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;nb_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Validate nbformat version
&lt;/span&gt;    &lt;span class="n"&gt;nbformat_ver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nb_data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;nbformat&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;cells&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;nb_data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cells&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;version&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;nbformat_ver&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cells&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;cells&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By decoupling extraction from &lt;code&gt;ipykernel&lt;/code&gt;, the pipeline can ingest thousands of notebooks across legacy versions (&lt;code&gt;nbformat&lt;/code&gt; v3 and v4) with zero CPU execution risk and zero dependency overhead.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Noise Suppression &amp;amp; Output Filtering
&lt;/h2&gt;

&lt;p&gt;Raw notebook outputs are notoriously noisy. To keep LLM context windows efficient and prevent embedding pollution:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Base64 Image Suppression:&lt;/strong&gt; Base64-encoded PNG/JPEG plots (&lt;code&gt;image/png&lt;/code&gt;, &lt;code&gt;image/jpeg&lt;/code&gt;) are stripped entirely from outputs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ANSI Color Stripping:&lt;/strong&gt; Terminal escape sequences generated by Python tracebacks (&lt;code&gt;\u001b[0;31m&lt;/code&gt;) are removed with compiled regex patterns.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Character Caps:&lt;/strong&gt; Verbose stdout logs are capped to configurable lengths (&lt;code&gt;max_output_chars=2000&lt;/code&gt;) with explicit truncation markers.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;

&lt;span class="n"&gt;ANSI_REGEX&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;clean_traceback_output&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Remove ANSI terminal color escape sequences from traceback strings.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ANSI_REGEX&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  3. Pre-Ingestion Credential &amp;amp; Secret Redaction
&lt;/h2&gt;

&lt;p&gt;Data scientists frequently forget hardcoded test credentials in scratch cells before saving notebooks. Emitting unredacted API tokens into shared vector databases or external LLM inference endpoints violates enterprise privacy boundaries.&lt;/p&gt;

&lt;p&gt;The connector runs a compiled regex redaction pipeline over all Markdown prose, code blocks, and output buffers before records leave the local connector sandbox:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;OpenAI Keys:&lt;/strong&gt; &lt;code&gt;sk-[A-Za-z0-9]{20,}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GitHub PATs:&lt;/strong&gt; &lt;code&gt;ghp_[A-Za-z0-9]{36}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS Access Keys:&lt;/strong&gt; &lt;code&gt;AKIA[0-9A-Z]{16}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bearer Tokens:&lt;/strong&gt; &lt;code&gt;Bearer [A-Za-z0-9\-\._~\+\/]+=*&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;REDACTION_RULES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bearer\s+[A-Za-z0-9\-._~+/]+=*&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IGNORECASE&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Bearer [REDACTED_TOKEN]&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ghp_[A-Za-z0-9]{36}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[REDACTED_GITHUB_PAT]&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sk-[A-Za-z0-9]{20,}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[REDACTED_API_KEY]&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;re&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AKIA[0-9A-Z]{16}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[REDACTED_AWS_KEY]&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;redact_secrets&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;replacement&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;REDACTION_RULES&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;replacement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  4. The Cognee Graph Invariant: "Forget-on-Delete"
&lt;/h2&gt;

&lt;p&gt;In GraphRAG architectures, handling deletions and moves is just as important as handling additions. If a team removes an obsolete experimentation notebook, its graph nodes shouldn't mislead the LLM.&lt;/p&gt;

&lt;p&gt;To solve this, the connector integrates directly with Cognee's internal &lt;code&gt;DOCUMENT_SOURCE_ATTR&lt;/code&gt; mechanism:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;cognee.tasks.ingestion.dlt_utils&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;DOCUMENT_SOURCE_ATTR&lt;/span&gt;

&lt;span class="c1"&gt;# 1. Flag the source for document routing
&lt;/span&gt;&lt;span class="nf"&gt;setattr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DOCUMENT_SOURCE_ATTR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;jupyter&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# 2. Use full snapshot replacement disposition
&lt;/span&gt;&lt;span class="nd"&gt;@dlt.resource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;notebooks&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;write_disposition&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;replace&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;notebooks_resource&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;notebook&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;discover_and_parse_notebooks&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;notebook&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Why this matters:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Bypasses Relational Flattening:&lt;/strong&gt; &lt;code&gt;DOCUMENT_SOURCE_ATTR = "jupyter"&lt;/code&gt; signals to Cognee that incoming items are rich documents rather than relational database tables, automatically routing them to the &lt;strong&gt;Cognify&lt;/strong&gt; entity-extraction pipeline.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automated Graph Pruning:&lt;/strong&gt; Setting &lt;code&gt;write_disposition="replace"&lt;/code&gt; allows Cognee's background orphan cleanup job to compute differences between sync snapshots and automatically prune removed notebooks from both vector collections and the FalkorDB/NetworkX knowledge graph.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content Deduplication:&lt;/strong&gt; Unchanged notebooks retain identical deterministic &lt;code&gt;data_id&lt;/code&gt; content hashes, skipping redundant LLM inference calls on subsequent runs.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  In Action: Ingesting Notebooks and Querying the Knowledge Graph
&lt;/h2&gt;

&lt;p&gt;Using the connector in a Cognee pipeline takes just a few lines of asynchronous Python:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;asyncio&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;cognee&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;cognee_community_connector_jupyter&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;jupyter_source&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="c1"&gt;# 1. Initialize connector pointing to data science repositories
&lt;/span&gt;    &lt;span class="n"&gt;source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;jupyter_source&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;workspace_dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;./analytics_workspace&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;include_outputs&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;max_output_chars&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;redact_secrets&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# 2. Add source to Cognee staging and cognify into knowledge graph
&lt;/span&gt;    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Ingesting notebooks...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;cognee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Extracting entities and building graph relationships...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;cognee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cognify&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;# 3. Query the unified notebook knowledge graph
&lt;/span&gt;    &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;What data preprocessing steps and evaluation metrics were used for customer churn?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Querying: &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;'"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;cognee&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;[Result &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;]:&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="k"&gt;match&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;asyncio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When Cognee processes the notebooks, it identifies concepts like &lt;code&gt;RandomForestClassifier&lt;/code&gt;, &lt;code&gt;AUC-ROC&lt;/code&gt;, and &lt;code&gt;data_leakage_mitigation&lt;/code&gt;, creating cross-notebook edges that connect experimental hypotheses with quantitative findings.&lt;/p&gt;




&lt;h2&gt;
  
  
  Verification &amp;amp; Maintainer Standards
&lt;/h2&gt;

&lt;p&gt;Following the Cognee core maintainer review standards:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;100% Offline Testing:&lt;/strong&gt; 27 unit tests pass offline with zero external network or kernel dependencies (&lt;code&gt;tests/test_source.py&lt;/code&gt;, &lt;code&gt;tests/test_parser.py&lt;/code&gt;, &lt;code&gt;tests/test_redaction.py&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dependency Hygiene:&lt;/strong&gt; Clean separation using modern &lt;code&gt;pyproject.toml&lt;/code&gt; configuration with flexible bounds (&lt;code&gt;cognee&amp;gt;=1.6.3,&amp;lt;2&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DCO Certified:&lt;/strong&gt; Verified Developer Certificate of Origin (&lt;code&gt;git commit -s&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusion &amp;amp; What's Next
&lt;/h2&gt;

&lt;p&gt;By combining passive JSON parsing, pre-ingestion redaction, and Cognee's GraphRAG lifecycle, data science teams can safely turn their institutional notebook repositories into interactive, searchable memory.&lt;/p&gt;

&lt;p&gt;You can inspect the connector and open PR under the Cognee community repository:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pull Request:&lt;/strong&gt; &lt;a href="https://github.com/topoteretes/cognee-community/pull/373" rel="noopener noreferrer"&gt;topoteretes/cognee-community#373&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cognee Core:&lt;/strong&gt; &lt;a href="https://github.com/topoteretes/cognee" rel="noopener noreferrer"&gt;topoteretes/cognee&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Have questions about GraphRAG, Cognee connector architecture, or notebook sanitization? Drop a comment below or connect on GitHub!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>ai</category>
      <category>machinelearning</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
