Files
langflow/components-custom-components.html
github-merge-queue[bot] 74f987fca7 deploy: 332738a317
2025-06-23 16:30:37 +00:00

336 lines
84 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="en" dir="ltr" class="docs-wrapper plugin-docs plugin-id-default docs-version-current docs-doc-page docs-doc-id-Components/components-custom-components" data-has-hydrated="false">
<head>
<meta charset="UTF-8">
<meta name="generator" content="Docusaurus v3.7.0">
<title data-rh="true">Create custom Python components | Langflow Documentation</title><meta data-rh="true" name="viewport" content="width=device-width,initial-scale=1"><meta data-rh="true" name="twitter:card" content="summary_large_image"><meta data-rh="true" property="og:url" content="https://docs.langflow.org/components-custom-components"><meta data-rh="true" property="og:locale" content="en"><meta data-rh="true" name="docusaurus_locale" content="en"><meta data-rh="true" name="docsearch:language" content="en"><meta data-rh="true" name="docusaurus_version" content="current"><meta data-rh="true" name="docusaurus_tag" content="docs-default-current"><meta data-rh="true" name="docsearch:version" content="current"><meta data-rh="true" name="docsearch:docusaurus_tag" content="docs-default-current"><meta data-rh="true" property="og:title" content="Create custom Python components | Langflow Documentation"><meta data-rh="true" name="description" content="Custom components extend Langflow&#x27;s functionality through Python classes that inherit from Component. This enables integration of new features, data manipulation, external services, and specialized tools."><meta data-rh="true" property="og:description" content="Custom components extend Langflow&#x27;s functionality through Python classes that inherit from Component. This enables integration of new features, data manipulation, external services, and specialized tools."><link data-rh="true" rel="icon" href="/img/favicon.ico"><link data-rh="true" rel="canonical" href="https://docs.langflow.org/components-custom-components"><link data-rh="true" rel="alternate" href="https://docs.langflow.org/components-custom-components" hreflang="en"><link data-rh="true" rel="alternate" href="https://docs.langflow.org/components-custom-components" hreflang="x-default"><link data-rh="true" rel="preconnect" href="https://UZK6BDPCVY-dsn.algolia.net" crossorigin="anonymous"><link rel="preconnect" href="https://www.google-analytics.com">
<link rel="preconnect" href="https://www.googletagmanager.com">
<script async src="https://www.googletagmanager.com/gtag/js?id=G-SLQFLQ3KPT"></script>
<script>function gtag(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],gtag("js",new Date),gtag("config","G-SLQFLQ3KPT",{})</script>
<link rel="search" type="application/opensearchdescription+xml" title="Langflow Documentation" href="/opensearch.xml">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Sora:wght@550;600&amp;display=swap">
<script>!function(){window.semaphore=window.semaphore||[],window.ketch=function(){window.semaphore.push(arguments)};var e=document.createElement("script");e.type="text/javascript",e.src="https://global.ketchcdn.com/web/v3/config/datastax/langflow_org_web/boot.js",e.defer=e.async=!0,document.getElementsByTagName("head")[0].appendChild(e)}()</script>
<script defer="true">!function(){const e=e=>{if(window.gtag&&e.purposes&&"analytics"in e.purposes&&"targeted_advertising"in e.purposes){const n=!0===e.purposes.analytics?"granted":"denied",t=!0===e.purposes.targeted_advertising?"granted":"denied",a={analytics_storage:n,ad_personalization:t,ad_storage:t,ad_user_data:t};window.gtag("consent","update",a)}};window.ketch&&window.ketch("on","consent",e)}()</script><link rel="stylesheet" href="/assets/css/styles.556d0cc8.css">
<script src="/assets/js/runtime~main.f9deadf0.js" defer="defer"></script>
<script src="/assets/js/main.32dc3196.js" defer="defer"></script>
</head>
<body class="navigation-with-keyboard">
<script>!function(){function t(t){document.documentElement.setAttribute("data-theme",t)}var e=function(){try{return new URLSearchParams(window.location.search).get("docusaurus-theme")}catch(t){}}()||function(){try{return window.localStorage.getItem("theme")}catch(t){}}();null!==e?t(e):window.matchMedia("(prefers-color-scheme: dark)").matches?t("dark"):(window.matchMedia("(prefers-color-scheme: light)").matches,t("light"))}(),function(){try{const c=new URLSearchParams(window.location.search).entries();for(var[t,e]of c)if(t.startsWith("docusaurus-data-")){var a=t.replace("docusaurus-data-","data-");document.documentElement.setAttribute(a,e)}}catch(t){}}()</script><div id="__docusaurus"><div role="region" aria-label="Skip to main content"><a class="skipToContent_fXgn" href="#__docusaurus_skipToContent_fallback">Skip to main content</a></div><nav aria-label="Main" class="navbar navbar--fixed-top navbarHideable_m1mJ"><div class="navbar__inner"><div class="navbar__items"><button aria-label="Toggle navigation bar" aria-expanded="false" class="navbar__toggle clean-btn" type="button"><svg width="30" height="30" viewBox="0 0 30 30" aria-hidden="true"><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg></button><a class="navbar__brand" href="/"><div class="navbar__logo"><img src="/img/lf-docs-light.svg" alt="Langflow" class="themedComponent_mlkZ themedComponent--light_NVdE"><img src="/img/lf-docs-dark.svg" alt="Langflow" class="themedComponent_mlkZ themedComponent--dark_xIcU"></div></a></div><div class="navbar__items navbar__items--right"><a href="https://github.com/langflow-ai/langflow" target="_blank" class="navbar__item navbar__link header-github-link"></a><a href="https://twitter.com/langflow_ai" target="_blank" class="navbar__item navbar__link header-twitter-link"></a><a href="https://discord.gg/EqksyE2EX9" target="_blank" class="navbar__item navbar__link header-discord-link"></a><div class="toggle_vylO colorModeToggle_DEke"><button class="clean-btn toggleButton_gllP toggleButtonDisabled_aARS" type="button" disabled="" title="Switch between dark and light mode (currently light mode)" aria-label="Switch between dark and light mode (currently light mode)" aria-live="polite" aria-pressed="false"><svg viewBox="0 0 24 24" width="24" height="24" class="lightToggleIcon_pyhR"><path fill="currentColor" d="M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"></path></svg><svg viewBox="0 0 24 24" width="24" height="24" class="darkToggleIcon_wfgR"><path fill="currentColor" d="M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"></path></svg></button></div><div class="navbarSearchContainer_Bca1"><button type="button" class="DocSearch DocSearch-Button" aria-label="Search (Command+K)"><span class="DocSearch-Button-Container"><svg width="20" height="20" class="DocSearch-Search-Icon" viewBox="0 0 20 20" aria-hidden="true"><path d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z" stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"></path></svg><span class="DocSearch-Button-Placeholder">Search</span></span><span class="DocSearch-Button-Keys"></span></button></div></div></div><div role="presentation" class="navbar-sidebar__backdrop"></div></nav><div id="__docusaurus_skipToContent_fallback" class="main-wrapper mainWrapper_z2l0"><div class="docsWrapper_hBAB"><button aria-label="Scroll back to top" class="clean-btn theme-back-to-top-button backToTopButton_sjWU" type="button"></button><div class="docRoot_UBD9"><aside class="theme-doc-sidebar-container docSidebarContainer_YfHR"><div class="sidebarViewport_aRkj"><div class="sidebar_njMd sidebarWithHideableNavbar_wUlq"><a tabindex="-1" class="sidebarLogo_isFc" href="/"><img src="/img/lf-docs-light.svg" alt="Langflow" class="themedComponent_mlkZ themedComponent--light_NVdE"><img src="/img/lf-docs-dark.svg" alt="Langflow" class="themedComponent_mlkZ themedComponent--dark_xIcU"></a><nav aria-label="Docs sidebar" class="menu thin-scrollbar menu_SIkG"><ul class="theme-doc-sidebar-menu menu__list"><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/">Welcome to Langflow</a></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret" role="button" aria-expanded="false" href="/get-started-installation">Get started</a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret" role="button" aria-expanded="false" href="/basic-prompting">Templates</a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret" role="button" aria-expanded="false" href="/concepts-overview">Concepts</a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret menu__link--active" role="button" aria-expanded="true" href="/components-agents">Components</a></div><ul style="display:block;overflow:visible;height:auto" class="menu__list"><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/components-agents">Agents</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/components-bundle-components">Bundles</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link menu__link--active" aria-current="page" tabindex="0" href="/components-custom-components">Create custom Python components</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/components-data">Data</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/components-embedding-models">Embeddings</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/components-helpers">Helpers</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/components-io">Inputs and outputs</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/components-logic">Logic</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/components-memories">Memories</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/components-models">Models</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/components-processing">Processing</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/components-prompts">Prompts</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/components-tools">Tools</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/components-vector-stores">Vector stores</a></li></ul></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret" role="button" aria-expanded="false" href="/agents">Agents</a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret" role="button" aria-expanded="false" href="/mcp-server">Model Context Protocol (MCP)</a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret" role="button" aria-expanded="false" href="/configuration-api-keys">Configuration</a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret" role="button" aria-expanded="false" href="/develop-overview">Develop</a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret" role="button" aria-expanded="false" href="/deployment-overview">Deployment</a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret" role="button" aria-expanded="false" href="/api">API reference</a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret" role="button" aria-expanded="false" href="/integrations-apify">Integrations</a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret" role="button" aria-expanded="false" href="/contributing-community">Contribute</a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a href="https://github.com/langflow-ai/langflow/releases/latest" target="_blank" rel="noopener noreferrer" class="menu__link menu__link--sublist menu__link--sublist-caret" role="button" aria-expanded="false">Changelog</a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret" role="button" aria-expanded="false" href="/troubleshoot">Support</a></div></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 sidebar-ad">
<a href="https://astra.datastax.com/signup?type=langflow" target="_blank" class="menu__link">
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-cloud"><path d="M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z"/></svg>
<div class="sidebar-ad-text-container">
<span class="sidebar-ad-text">Use Langflow in the cloud</span>
<span class="sidebar-ad-text sidebar-ad-text-gradient">Sign up for DataStax Langflow</span>
</div>
</a>
</li></ul></nav></div></div></aside><main class="docMainContainer_TBSr"><div class="container padding-top--md padding-bottom--lg"><div class="row"><div class="col docItemCol_VOVn"><div class="docItemContainer_Djhp"><article><nav class="theme-doc-breadcrumbs breadcrumbsContainer_Z_bl" aria-label="Breadcrumbs"><ul class="breadcrumbs" itemscope="" itemtype="https://schema.org/BreadcrumbList"><li class="breadcrumbs__item"><a aria-label="Home page" class="breadcrumbs__link" href="/"><svg viewBox="0 0 24 24" class="breadcrumbHomeIcon_YNFT"><path d="M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z" fill="currentColor"></path></svg></a></li><li class="breadcrumbs__item"><span class="breadcrumbs__link">Components</span><meta itemprop="position" content="1"></li><li itemscope="" itemprop="itemListElement" itemtype="https://schema.org/ListItem" class="breadcrumbs__item breadcrumbs__item--active"><span class="breadcrumbs__link" itemprop="name">Create custom Python components</span><meta itemprop="position" content="2"></li></ul></nav><div class="tocCollapsible_ETCw theme-doc-toc-mobile tocMobile_ITEo"><button type="button" class="clean-btn tocCollapsibleButton_TO0P">On this page</button></div><div class="theme-doc-markdown markdown"><header><h1>Create custom Python components</h1></header><style>[data-ch-theme="github-dark"] { --ch-t-colorScheme: dark;--ch-t-foreground: #c9d1d9;--ch-t-background: #0d1117;--ch-t-lighter-inlineBackground: #0d1117e6;--ch-t-editor-background: #0d1117;--ch-t-editor-foreground: #c9d1d9;--ch-t-editor-lineHighlightBackground: #6e76811a;--ch-t-editor-rangeHighlightBackground: #ffffff0b;--ch-t-editor-infoForeground: #3794FF;--ch-t-editor-selectionBackground: #264F78;--ch-t-focusBorder: #1f6feb;--ch-t-tab-activeBackground: #0d1117;--ch-t-tab-activeForeground: #c9d1d9;--ch-t-tab-inactiveBackground: #010409;--ch-t-tab-inactiveForeground: #8b949e;--ch-t-tab-border: #30363d;--ch-t-tab-activeBorder: #0d1117;--ch-t-editorGroup-border: #30363d;--ch-t-editorGroupHeader-tabsBackground: #010409;--ch-t-editorLineNumber-foreground: #6e7681;--ch-t-input-background: #0d1117;--ch-t-input-foreground: #c9d1d9;--ch-t-input-border: #30363d;--ch-t-icon-foreground: #8b949e;--ch-t-sideBar-background: #010409;--ch-t-sideBar-foreground: #c9d1d9;--ch-t-sideBar-border: #30363d;--ch-t-list-activeSelectionBackground: #6e768166;--ch-t-list-activeSelectionForeground: #c9d1d9;--ch-t-list-hoverBackground: #6e76811a;--ch-t-list-hoverForeground: #c9d1d9; }</style>
<p>Custom components extend Langflow&#x27;s functionality through Python classes that inherit from <code>Component</code>. This enables integration of new features, data manipulation, external services, and specialized tools.</p>
<p>In Langflow&#x27;s node-based environment, each node is a &quot;component&quot; that performs discrete functions. Custom components are Python classes which define:</p>
<ul>
<li><strong>Inputs</strong> — Data or parameters your component requires.</li>
<li><strong>Outputs</strong> — Data your component provides to downstream nodes.</li>
<li><strong>Logic</strong> — How you process inputs to produce outputs.</li>
</ul>
<p>The benefits of creating custom components include unlimited extensibility, reusability, automatic UI field generation based on inputs, and type-safe connections between nodes.</p>
<p>Create custom components for performing specialized tasks, calling APIs, or adding advanced logic.</p>
<p>Custom components in Langflow are built upon:</p>
<ul>
<li>The Python class that inherits from <code>Component</code>.</li>
<li>Class-level attributes that identify and describe the component.</li>
<li>Input and output lists that determine data flow.</li>
<li>Internal variables for logging and advanced logic.</li>
</ul>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="class-level-attributes">Class-level attributes<a href="#class-level-attributes" class="hash-link" aria-label="Direct link to Class-level attributes" title="Direct link to Class-level attributes"></a></h2>
<p>Define these attributes to control a custom component&#x27;s appearance and behavior:</p>
<div class="ch-codeblock not-prose" data-ch-theme="github-dark"><div class="ch-code-wrapper ch-code" data-ch-measured="false"><code class="ch-code-scroll-parent"><br><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span>class MyCsvReader(Component):</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> display_name = &quot;CSV Reader&quot; # Shown in node header</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> description = &quot;Reads CSV files&quot; # Tooltip text</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> icon = &quot;file-text&quot; # Visual identifier</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> name = &quot;CSVReader&quot; # Unique internal ID</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> documentation = &quot;http://docs.example.com/csv_reader&quot; # Optional</span></div></div><br></code></div></div>
<ul>
<li><strong>display_name</strong>: A user-friendly label in the node header.</li>
<li><strong>description</strong>: A brief summary shown in tooltips.</li>
<li><strong>icon</strong>: A visual identifier from Langflow&#x27;s icon library.</li>
<li><strong>name</strong>: A unique internal identifier.</li>
<li><strong>documentation</strong>: An optional link to external docs.</li>
</ul>
<div class="theme-admonition theme-admonition-tip admonition_xJq3 alert alert--success"><div class="admonitionHeading_Gvgb"><span class="admonitionIcon_Rf37"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>Icon usage</div><div class="admonitionContent_BuS1"><p>Langflow uses <a href="https://lucide.dev/icons" target="_blank" rel="noopener noreferrer">Lucide</a> for icons. To assign an icon to your component, set the icon attribute to the name of a Lucide icon as a string, such as <code>icon = &quot;file-text&quot;</code>. Langflow renders icons from the Lucide library automatically.</p></div></div>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="structure-of-a-custom-component">Structure of a custom component<a href="#structure-of-a-custom-component" class="hash-link" aria-label="Direct link to Structure of a custom component" title="Direct link to Structure of a custom component"></a></h3>
<p>A <strong>Langflow custom component</strong> goes beyond a simple class with inputs and outputs. It includes an internal structure with optional lifecycle steps, output generation, front-end interaction, and logic organization.</p>
<p>A basic component:</p>
<ul>
<li>Inherits from <code>langflow.custom.Component</code>.</li>
<li>Declares metadata like <code>display_name</code>, <code>description</code>, <code>icon</code>, and more.</li>
<li>Defines <code>inputs</code> and <code>outputs</code> lists.</li>
<li>Implements methods matching output specifications.</li>
</ul>
<p>A minimal custom component skeleton contains the following:</p>
<div class="ch-codeblock not-prose" data-ch-theme="github-dark"><div class="ch-code-wrapper ch-code" data-ch-measured="false"><code class="ch-code-scroll-parent"><br><div><span class="ch-code-line-number">_<!-- -->14</span><div style="display:inline-block;margin-left:16px"><span>from langflow.custom import Component</span></div></div><div><span class="ch-code-line-number">_<!-- -->14</span><div style="display:inline-block;margin-left:16px"><span>from langflow.template import Output</span></div></div><div><span class="ch-code-line-number">_<!-- -->14</span><div style="display:inline-block;margin-left:16px"><span></span></div></div><div><span class="ch-code-line-number">_<!-- -->14</span><div style="display:inline-block;margin-left:16px"><span>class MyComponent(Component):</span></div></div><div><span class="ch-code-line-number">_<!-- -->14</span><div style="display:inline-block;margin-left:16px"><span> display_name = &quot;My Component&quot;</span></div></div><div><span class="ch-code-line-number">_<!-- -->14</span><div style="display:inline-block;margin-left:16px"><span> description = &quot;A short summary.&quot;</span></div></div><div><span class="ch-code-line-number">_<!-- -->14</span><div style="display:inline-block;margin-left:16px"><span> icon = &quot;sparkles&quot;</span></div></div><div><span class="ch-code-line-number">_<!-- -->14</span><div style="display:inline-block;margin-left:16px"><span> name = &quot;MyComponent&quot;</span></div></div><div><span class="ch-code-line-number">_<!-- -->14</span><div style="display:inline-block;margin-left:16px"><span></span></div></div><div><span class="ch-code-line-number">_<!-- -->14</span><div style="display:inline-block;margin-left:16px"><span> inputs = []</span></div></div><div><span class="ch-code-line-number">_<!-- -->14</span><div style="display:inline-block;margin-left:16px"><span> outputs = []</span></div></div><div><span class="ch-code-line-number">_<!-- -->14</span><div style="display:inline-block;margin-left:16px"><span></span></div></div><div><span class="ch-code-line-number">_<!-- -->14</span><div style="display:inline-block;margin-left:16px"><span> def some_output_method(self):</span></div></div><div><span class="ch-code-line-number">_<!-- -->14</span><div style="display:inline-block;margin-left:16px"><span> return ...</span></div></div><br></code></div></div>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="internal-lifecycle-and-execution-flow">Internal Lifecycle and Execution Flow<a href="#internal-lifecycle-and-execution-flow" class="hash-link" aria-label="Direct link to Internal Lifecycle and Execution Flow" title="Direct link to Internal Lifecycle and Execution Flow"></a></h3>
<p>Langflow&#x27;s engine manages:</p>
<ul>
<li><strong>Instantiation</strong>: A component is created and internal structures are initialized.</li>
<li><strong>Assigning Inputs</strong>: Values from the UI or connections are assigned to component fields.</li>
<li><strong>Validation and Setup</strong>: Optional hooks like <code>_pre_run_setup</code>.</li>
<li><strong>Outputs Generation</strong>: <code>run()</code> or <code>build_results()</code> triggers output methods.</li>
</ul>
<p><strong>Optional Hooks</strong>:</p>
<ul>
<li><code>initialize_data</code> or <code>_pre_run_setup</code> can run setup logic before the component&#x27;s main execution.</li>
<li><code>__call__</code>, <code>run()</code>, or <code>_run()</code> can be overridden to customize how the component is called or to define custom execution logic.</li>
</ul>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="inputs-and-outputs">Inputs and outputs<a href="#inputs-and-outputs" class="hash-link" aria-label="Direct link to Inputs and outputs" title="Direct link to Inputs and outputs"></a></h3>
<p>Custom component inputs are defined with properties like:</p>
<ul>
<li><code>name</code>, <code>display_name</code></li>
<li>Optional: <code>info</code>, <code>value</code>, <code>advanced</code>, <code>is_list</code>, <code>tool_mode</code>, <code>real_time_refresh</code></li>
</ul>
<p>For example:</p>
<ul>
<li><code>StrInput</code>: simple text input.</li>
<li><code>DropdownInput</code>: selectable options.</li>
<li><code>HandleInput</code>: specialized connections.</li>
</ul>
<p>Custom component <code>Output</code> properties define:</p>
<ul>
<li><code>name</code>, <code>display_name</code>, <code>method</code></li>
<li>Optional: <code>info</code></li>
</ul>
<p>For more information, see <a href="/components-custom-components#custom-component-inputs-and-outputs">Custom component inputs and outputs</a>.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="associated-methods">Associated Methods<a href="#associated-methods" class="hash-link" aria-label="Direct link to Associated Methods" title="Direct link to Associated Methods"></a></h3>
<p>Each output is linked to a method:</p>
<ul>
<li>The output method name must match the method name.</li>
<li>The method typically returns objects like Message, Data, or DataFrame.</li>
<li>The method can use inputs with <code>self.&lt;input_name&gt;</code>.</li>
</ul>
<p>For example:</p>
<div class="ch-codeblock not-prose" data-ch-theme="github-dark"><div class="ch-code-wrapper ch-code" data-ch-measured="false"><code class="ch-code-scroll-parent"><br><div><span class="ch-code-line-number">_<!-- -->12</span><div style="display:inline-block;margin-left:16px"><span>Output(</span></div></div><div><span class="ch-code-line-number">_<!-- -->12</span><div style="display:inline-block;margin-left:16px"><span> display_name=&quot;File Contents&quot;,</span></div></div><div><span class="ch-code-line-number">_<!-- -->12</span><div style="display:inline-block;margin-left:16px"><span> name=&quot;file_contents&quot;,</span></div></div><div><span class="ch-code-line-number">_<!-- -->12</span><div style="display:inline-block;margin-left:16px"><span> method=&quot;read_file&quot;</span></div></div><div><span class="ch-code-line-number">_<!-- -->12</span><div style="display:inline-block;margin-left:16px"><span>)</span></div></div><div><span class="ch-code-line-number">_<!-- -->12</span><div style="display:inline-block;margin-left:16px"><span>#...</span></div></div><div><span class="ch-code-line-number">_<!-- -->12</span><div style="display:inline-block;margin-left:16px"><span>def read_file(self) -&gt; Data:</span></div></div><div><span class="ch-code-line-number">_<!-- -->12</span><div style="display:inline-block;margin-left:16px"><span> path = self.filename</span></div></div><div><span class="ch-code-line-number">_<!-- -->12</span><div style="display:inline-block;margin-left:16px"><span> with open(path, &quot;r&quot;) as f:</span></div></div><div><span class="ch-code-line-number">_<!-- -->12</span><div style="display:inline-block;margin-left:16px"><span> content = f.read()</span></div></div><div><span class="ch-code-line-number">_<!-- -->12</span><div style="display:inline-block;margin-left:16px"><span> self.status = f&quot;Read {len(content)} chars from {path}&quot;</span></div></div><div><span class="ch-code-line-number">_<!-- -->12</span><div style="display:inline-block;margin-left:16px"><span> return Data(data={&quot;content&quot;: content})</span></div></div><br></code></div></div>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="components-with-multiple-outputs">Components with multiple outputs<a href="#components-with-multiple-outputs" class="hash-link" aria-label="Direct link to Components with multiple outputs" title="Direct link to Components with multiple outputs"></a></h3>
<p>A component can define multiple outputs.
Each output can have a different corresponding method.
For example:</p>
<div class="ch-codeblock not-prose" data-ch-theme="github-dark"><div class="ch-code-wrapper ch-code" data-ch-measured="false"><code class="ch-code-scroll-parent"><br><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span>outputs = [</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> Output(display_name=&quot;Processed Data&quot;, name=&quot;processed_data&quot;, method=&quot;process_data&quot;),</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> Output(display_name=&quot;Debug Info&quot;, name=&quot;debug_info&quot;, method=&quot;provide_debug_info&quot;),</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span>]</span></div></div><br></code></div></div>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="common-internal-patterns">Common internal patterns<a href="#common-internal-patterns" class="hash-link" aria-label="Direct link to Common internal patterns" title="Direct link to Common internal patterns"></a></h3>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="_pre_run_setup"><code>_pre_run_setup()</code><a href="#_pre_run_setup" class="hash-link" aria-label="Direct link to _pre_run_setup" title="Direct link to _pre_run_setup"></a></h4>
<p>To initialize a custom component with counters set:</p>
<div class="ch-codeblock not-prose" data-ch-theme="github-dark"><div class="ch-code-wrapper ch-code" data-ch-measured="false"><code class="ch-code-scroll-parent"><br><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span>def _pre_run_setup(self):</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> if not hasattr(self, &quot;_initialized&quot;):</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> self._initialized = True</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> self.iteration = 0</span></div></div><br></code></div></div>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="override-run-or-_run">Override <code>run</code> or <code>_run</code><a href="#override-run-or-_run" class="hash-link" aria-label="Direct link to override-run-or-_run" title="Direct link to override-run-or-_run"></a></h4>
<p>You can override <code>async def _run(self): ...</code> to define custom execution logic, although the default behavior from the base class usually covers most cases.</p>
<h4 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="store-data-in-selfctx">Store data in <code>self.ctx</code><a href="#store-data-in-selfctx" class="hash-link" aria-label="Direct link to store-data-in-selfctx" title="Direct link to store-data-in-selfctx"></a></h4>
<p>Use <code>self.ctx</code> as a shared storage for data or counters across the component&#x27;s execution flow:</p>
<div class="ch-codeblock not-prose" data-ch-theme="github-dark"><div class="ch-code-wrapper ch-code" data-ch-measured="false"><code class="ch-code-scroll-parent"><br><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span>def some_method(self):</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> count = self.ctx.get(&quot;my_count&quot;, 0)</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> self.ctx[&quot;my_count&quot;] = count + 1</span></div></div><br></code></div></div>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="directory-structure-requirements">Directory structure requirements<a href="#directory-structure-requirements" class="hash-link" aria-label="Direct link to Directory structure requirements" title="Direct link to Directory structure requirements"></a></h2>
<p>By default, Langflow looks for custom components in the <code>langflow/components</code> directory.</p>
<p>If you&#x27;re creating custom components in a different location using the <a href="/environment-variables#LANGFLOW_COMPONENTS_PATH">LANGFLOW_COMPONENTS_PATH</a> environment variable, components must be organized in a specific directory structure to be properly loaded and displayed in the UI:</p>
<div class="ch-codeblock not-prose" data-ch-theme="github-dark"><div class="ch-code-wrapper ch-code" data-ch-measured="false"><code class="ch-code-scroll-parent"><br><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span>/your/custom/components/path/ # Base directory set by LANGFLOW_COMPONENTS_PATH</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> └── category_name/ # Required category subfolder that determines menu name</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> └── custom_component.py # Component file</span></div></div><br></code></div></div>
<p>Components must be placed inside <strong>category folders</strong>, not directly in the base directory.
The category folder name determines where the component appears in the UI menu.</p>
<p>For example, to add a component to the <strong>Helpers</strong> menu, place it in a <code>helpers</code> subfolder:</p>
<div class="ch-codeblock not-prose" data-ch-theme="github-dark"><div class="ch-code-wrapper ch-code" data-ch-measured="false"><code class="ch-code-scroll-parent"><br><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span>/app/custom_components/ # LANGFLOW_COMPONENTS_PATH</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> └── helpers/ # Displayed within the &quot;Helpers&quot; menu</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> └── custom_component.py # Your component</span></div></div><br></code></div></div>
<p>You can have <strong>multiple category folders</strong> to organize components into different menus:</p>
<div class="ch-codeblock not-prose" data-ch-theme="github-dark"><div class="ch-code-wrapper ch-code" data-ch-measured="false"><code class="ch-code-scroll-parent"><br><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span>/app/custom_components/</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> ├── helpers/</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> │ └── helper_component.py</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> └── tools/</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> └── tool_component.py</span></div></div><br></code></div></div>
<p>This folder structure is required for Langflow to properly discover and load your custom components. Components placed directly in the base directory will not be loaded.</p>
<div class="ch-codeblock not-prose" data-ch-theme="github-dark"><div class="ch-code-wrapper ch-code" data-ch-measured="false"><code class="ch-code-scroll-parent"><br><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span>/app/custom_components/ # LANGFLOW_COMPONENTS_PATH</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> └── custom_component.py # Won&#x27;t be loaded - missing category folder!</span></div></div><br></code></div></div>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="custom-component-inputs-and-outputs">Custom component inputs and outputs<a href="#custom-component-inputs-and-outputs" class="hash-link" aria-label="Direct link to Custom component inputs and outputs" title="Direct link to Custom component inputs and outputs"></a></h2>
<p>Inputs and outputs define how data flows through the component, how it appears in the UI, and how connections to other components are validated.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="inputs">Inputs<a href="#inputs" class="hash-link" aria-label="Direct link to Inputs" title="Direct link to Inputs"></a></h3>
<p>Inputs are defined in a class-level <code>inputs</code> list. When Langflow loads the component, it uses this list to render fields and handles in the UI. Users or other components provide values or connections to fill these inputs.</p>
<p>An input is usually an instance of a class from <code>langflow.io</code> (such as <code>StrInput</code>, <code>DataInput</code>, or <code>MessageTextInput</code>). The most common constructor parameters are:</p>
<ul>
<li><strong><code>name</code></strong>: The internal variable name, accessed via <code>self.&lt;name&gt;</code>.</li>
<li><strong><code>display_name</code></strong>: The label shown to users in the UI.</li>
<li><strong><code>info</code></strong> <em>(optional)</em>: A tooltip or short description.</li>
<li><strong><code>value</code></strong> <em>(optional)</em>: The default value.</li>
<li><strong><code>advanced</code></strong> <em>(optional)</em>: If <code>True</code>, moves the field into the &quot;Advanced&quot; section.</li>
<li><strong><code>required</code></strong> <em>(optional)</em>: If <code>True</code>, forces the user to provide a value.</li>
<li><strong><code>is_list</code></strong> <em>(optional)</em>: If <code>True</code>, allows multiple values.</li>
<li><strong><code>input_types</code></strong> <em>(optional)</em>: Restricts allowed connection types (e.g., <code>[&quot;Data&quot;]</code>, <code>[&quot;LanguageModel&quot;]</code>).</li>
</ul>
<p>Here are the most commonly used input classes and their typical usage.</p>
<p><strong>Text Inputs</strong>: For simple text entries.</p>
<ul>
<li><strong><code>StrInput</code></strong> creates a single-line text field.</li>
<li><strong><code>MultilineInput</code></strong> creates a multi-line text area.</li>
</ul>
<p><strong>Numeric and Boolean Inputs</strong>: Ensures users can only enter valid numeric or boolean data.</p>
<ul>
<li><strong><code>BoolInput</code></strong>, <strong><code>IntInput</code></strong>, and <strong><code>FloatInput</code></strong> provide fields for boolean, integer, and float values, ensuring type consistency.</li>
</ul>
<p><strong>Dropdowns</strong>: For selecting from predefined options, useful for modes or levels.</p>
<ul>
<li><strong><code>DropdownInput</code></strong></li>
</ul>
<p><strong>Secrets</strong>: A specialized input for sensitive data, ensuring input is hidden in the UI.</p>
<ul>
<li><strong><code>SecretStrInput</code></strong> for API keys and passwords.</li>
</ul>
<p><strong>Specialized Data Inputs</strong>: Ensures type-checking and color-coded connections in the UI.</p>
<ul>
<li><strong><code>DataInput</code></strong> expects a <code>Data</code> object (typically with <code>.data</code> and optional <code>.text</code>).</li>
<li><strong><code>MessageInput</code></strong> expects a <code>Message</code> object, used in chat or agent-based flows.</li>
<li><strong><code>MessageTextInput</code></strong> simplifies access to the <code>.text</code> field of a <code>Message</code>.</li>
</ul>
<p><strong>Handle-Based Inputs</strong>: Used to connect outputs of specific types, ensuring correct pipeline connections.</p>
<ul>
<li><strong><code>HandleInput</code></strong></li>
</ul>
<p><strong>File Uploads</strong>: Allows users to upload files directly through the UI or receive file paths from other components.</p>
<ul>
<li><strong><code>FileInput</code></strong></li>
</ul>
<p><strong>Lists</strong>: Set <code>is_list=True</code> to accept multiple values, ideal for batch or grouped operations.</p>
<p>This example defines three inputs: a text field (<code>StrInput</code>), a boolean toggle (<code>BoolInput</code>), and a dropdown selection (<code>DropdownInput</code>).</p>
<div class="ch-codeblock not-prose" data-ch-theme="github-dark"><div class="ch-code-wrapper ch-code" data-ch-measured="false"><code class="ch-code-scroll-parent"><br><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span>from langflow.io import StrInput, BoolInput, DropdownInput</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span></span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span>inputs = [</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> StrInput(name=&quot;title&quot;, display_name=&quot;Title&quot;),</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> BoolInput(name=&quot;enabled&quot;, display_name=&quot;Enabled&quot;, value=True),</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> DropdownInput(name=&quot;mode&quot;, display_name=&quot;Mode&quot;, options=[&quot;Fast&quot;, &quot;Safe&quot;, &quot;Experimental&quot;], value=&quot;Safe&quot;)</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span>]</span></div></div><br></code></div></div>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="outputs">Outputs<a href="#outputs" class="hash-link" aria-label="Direct link to Outputs" title="Direct link to Outputs"></a></h3>
<p>Outputs are defined in a class-level <code>outputs</code> list. When Langflow renders a component, each output becomes a connector point in the UI. When you connect something to an output, Langflow automatically calls the corresponding method and passes the returned object to the next component.</p>
<p>An output is usually an instance of <code>Output</code> from <code>langflow.io</code>, with common parameters:</p>
<ul>
<li><strong><code>name</code></strong>: The internal variable name.</li>
<li><strong><code>display_name</code></strong>: The label shown in the UI.</li>
<li><strong><code>method</code></strong>: The name of the method called to produce the output.</li>
<li><strong><code>info</code></strong> <em>(optional)</em>: Help text shown on hover.</li>
</ul>
<p>The method must exist in the class, and it is recommended to annotate its return type for better type checking.
You can also set a <code>self.status</code> message inside the method to show progress or logs.</p>
<p><strong>Common Return Types</strong>:</p>
<ul>
<li><strong><code>Message</code></strong>: Structured chat messages.</li>
<li><strong><code>Data</code></strong>: Flexible object with <code>.data</code> and optional <code>.text</code>.</li>
<li><strong><code>DataFrame</code></strong>: Pandas-based tables (<code>langflow.schema.DataFrame</code>).</li>
<li><strong>Primitive types</strong>: <code>str</code>, <code>int</code>, <code>bool</code> (not recommended if you need type/color consistency).</li>
</ul>
<p>In this example, the <code>DataToDataFrame</code> component defines its output using the outputs list. The <code>df_out</code> output is linked to the <code>build_df</code> method, so when connected in the UI, Langflow calls this method and passes its returned DataFrame to the next node. This demonstrates how each output maps to a method that generates the actual output data.</p>
<div class="ch-codeblock not-prose" data-ch-theme="github-dark"><div class="ch-code-wrapper ch-code" data-ch-measured="false"><code class="ch-code-scroll-parent"><br><div><span class="ch-code-line-number">_<!-- -->37</span><div style="display:inline-block;margin-left:16px"><span>from langflow.custom import Component</span></div></div><div><span class="ch-code-line-number">_<!-- -->37</span><div style="display:inline-block;margin-left:16px"><span>from langflow.io import DataInput, Output</span></div></div><div><span class="ch-code-line-number">_<!-- -->37</span><div style="display:inline-block;margin-left:16px"><span>from langflow.schema import Data, DataFrame</span></div></div><div><span class="ch-code-line-number">_<!-- -->37</span><div style="display:inline-block;margin-left:16px"><span></span></div></div><div><span class="ch-code-line-number">_<!-- -->37</span><div style="display:inline-block;margin-left:16px"><span>class DataToDataFrame(Component):</span></div></div><div><span class="ch-code-line-number">_<!-- -->37</span><div style="display:inline-block;margin-left:16px"><span> display_name = &quot;Data to DataFrame&quot;</span></div></div><div><span class="ch-code-line-number">_<!-- -->37</span><div style="display:inline-block;margin-left:16px"><span> description = &quot;Convert multiple Data objects into a DataFrame&quot;</span></div></div><div><span class="ch-code-line-number">_<!-- -->37</span><div style="display:inline-block;margin-left:16px"><span> icon = &quot;table&quot;</span></div></div><div><span class="ch-code-line-number">_<!-- -->37</span><div style="display:inline-block;margin-left:16px"><span> name = &quot;DataToDataFrame&quot;</span></div></div><div><span class="ch-code-line-number">_<!-- -->37</span><div style="display:inline-block;margin-left:16px"><span></span></div></div><div><span class="ch-code-line-number">_<!-- -->37</span><div style="display:inline-block;margin-left:16px"><span> inputs = [</span></div></div><div><span class="ch-code-line-number">_<!-- -->37</span><div style="display:inline-block;margin-left:16px"><span> DataInput(</span></div></div><div><span class="ch-code-line-number">_<!-- -->37</span><div style="display:inline-block;margin-left:16px"><span> name=&quot;items&quot;,</span></div></div><div><span class="ch-code-line-number">_<!-- -->37</span><div style="display:inline-block;margin-left:16px"><span> display_name=&quot;Data Items&quot;,</span></div></div><div><span class="ch-code-line-number">_<!-- -->37</span><div style="display:inline-block;margin-left:16px"><span> info=&quot;List of Data objects to convert&quot;,</span></div></div><div><span class="ch-code-line-number">_<!-- -->37</span><div style="display:inline-block;margin-left:16px"><span> is_list=True</span></div></div><div><span class="ch-code-line-number">_<!-- -->37</span><div style="display:inline-block;margin-left:16px"><span> )</span></div></div><div><span class="ch-code-line-number">_<!-- -->37</span><div style="display:inline-block;margin-left:16px"><span> ]</span></div></div><div><span class="ch-code-line-number">_<!-- -->37</span><div style="display:inline-block;margin-left:16px"><span></span></div></div><div><span class="ch-code-line-number">_<!-- -->37</span><div style="display:inline-block;margin-left:16px"><span> outputs = [</span></div></div><div><span class="ch-code-line-number">_<!-- -->37</span><div style="display:inline-block;margin-left:16px"><span> Output(</span></div></div><div><span class="ch-code-line-number">_<!-- -->37</span><div style="display:inline-block;margin-left:16px"><span> name=&quot;df_out&quot;,</span></div></div><div><span class="ch-code-line-number">_<!-- -->37</span><div style="display:inline-block;margin-left:16px"><span> display_name=&quot;DataFrame Output&quot;,</span></div></div><div><span class="ch-code-line-number">_<!-- -->37</span><div style="display:inline-block;margin-left:16px"><span> method=&quot;build_df&quot;</span></div></div><div><span class="ch-code-line-number">_<!-- -->37</span><div style="display:inline-block;margin-left:16px"><span> )</span></div></div><div><span class="ch-code-line-number">_<!-- -->37</span><div style="display:inline-block;margin-left:16px"><span> ]</span></div></div><div><span class="ch-code-line-number">_<!-- -->37</span><div style="display:inline-block;margin-left:16px"><span></span></div></div><div><span class="ch-code-line-number">_<!-- -->37</span><div style="display:inline-block;margin-left:16px"><span> def build_df(self) -&gt; DataFrame:</span></div></div><div><span class="ch-code-line-number">_<!-- -->37</span><div style="display:inline-block;margin-left:16px"><span> rows = []</span></div></div><div><span class="ch-code-line-number">_<!-- -->37</span><div style="display:inline-block;margin-left:16px"><span> for item in self.items:</span></div></div><div><span class="ch-code-line-number">_<!-- -->37</span><div style="display:inline-block;margin-left:16px"><span> row_dict = item.data.copy() if item.data else {}</span></div></div><div><span class="ch-code-line-number">_<!-- -->37</span><div style="display:inline-block;margin-left:16px"><span> row_dict[&quot;text&quot;] = item.get_text() or &quot;&quot;</span></div></div><div><span class="ch-code-line-number">_<!-- -->37</span><div style="display:inline-block;margin-left:16px"><span> rows.append(row_dict)</span></div></div><div><span class="ch-code-line-number">_<!-- -->37</span><div style="display:inline-block;margin-left:16px"><span></span></div></div><div><span class="ch-code-line-number">_<!-- -->37</span><div style="display:inline-block;margin-left:16px"><span> df = DataFrame(rows)</span></div></div><div><span class="ch-code-line-number">_<!-- -->37</span><div style="display:inline-block;margin-left:16px"><span> self.status = f&quot;Built DataFrame with {len(rows)} rows.&quot;</span></div></div><div><span class="ch-code-line-number">_<!-- -->37</span><div style="display:inline-block;margin-left:16px"><span> return df</span></div></div><br></code></div></div>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="tool-mode">Tool mode<a href="#tool-mode" class="hash-link" aria-label="Direct link to Tool mode" title="Direct link to Tool mode"></a></h3>
<p>You can configure a Custom Component to work as a <strong>Tool</strong> by setting the parameter <code>tool_mode=True</code>. This allows the component to be used in Langflow&#x27;s Tool Mode workflows, such as by Agent components.</p>
<p>Langflow currently supports the following input types for Tool Mode:</p>
<ul>
<li><code>DataInput</code></li>
<li><code>DataFrameInput</code></li>
<li><code>PromptInput</code></li>
<li><code>MessageTextInput</code></li>
<li><code>MultilineInput</code></li>
<li><code>DropdownInput</code></li>
</ul>
<div class="ch-codeblock not-prose" data-ch-theme="github-dark"><div class="ch-code-wrapper ch-code" data-ch-measured="false"><code class="ch-code-scroll-parent"><br><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span>inputs = [</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> MessageTextInput(</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> name=&quot;message&quot;,</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> display_name=&quot;Mensage&quot;,</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> info=&quot;Enter the message that will be processed directly by the tool&quot;,</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> tool_mode=True,</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> ),</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span>]</span></div></div><br></code></div></div>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="typed-annotations">Typed annotations<a href="#typed-annotations" class="hash-link" aria-label="Direct link to Typed annotations" title="Direct link to Typed annotations"></a></h2>
<p>In Langflow, <strong>typed annotations</strong> allow Langflow to visually guide users and maintain flow consistency.</p>
<p>Typed annotations provide:</p>
<ul>
<li><strong>Color-coding</strong>: Outputs like <code>-&gt; Data</code> or <code>-&gt; Message</code> get distinct colors.</li>
<li><strong>Validation</strong>: Langflow blocks incompatible connections automatically.</li>
<li><strong>Readability</strong>: Developers can quickly understand data flow.</li>
<li><strong>Development tools</strong>: Better code suggestions and error checking in your code editor.</li>
</ul>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="common-return-types">Common Return Types<a href="#common-return-types" class="hash-link" aria-label="Direct link to Common Return Types" title="Direct link to Common Return Types"></a></h3>
<p><strong><code>Message</code></strong></p>
<p>For chat-style outputs.</p>
<div class="ch-codeblock not-prose" data-ch-theme="github-dark"><div class="ch-code-wrapper ch-code" data-ch-measured="false"><code class="ch-code-scroll-parent"><br><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span>def produce_message(self) -&gt; Message:</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> return Message(text=&quot;Hello! from typed method!&quot;, sender=&quot;System&quot;)</span></div></div><br></code></div></div>
<p>In the UI, connects only to Message-compatible inputs.</p>
<p><strong><code>Data</code></strong></p>
<p>For structured data like dicts or partial texts.</p>
<div class="ch-codeblock not-prose" data-ch-theme="github-dark"><div class="ch-code-wrapper ch-code" data-ch-measured="false"><code class="ch-code-scroll-parent"><br><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span>def get_processed_data(self) -&gt; Data:</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> processed = {&quot;key1&quot;: &quot;value1&quot;, &quot;key2&quot;: 123}</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> return Data(data=processed)</span></div></div><br></code></div></div>
<p>In the UI, connects only with DataInput.</p>
<p><strong><code>DataFrame</code></strong></p>
<p>For tabular data</p>
<div class="ch-codeblock not-prose" data-ch-theme="github-dark"><div class="ch-code-wrapper ch-code" data-ch-measured="false"><code class="ch-code-scroll-parent"><br><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span>def build_df(self) -&gt; DataFrame:</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> pdf = pd.DataFrame({&quot;A&quot;: [1, 2], &quot;B&quot;: [3, 4]})</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> return DataFrame(pdf)</span></div></div><br></code></div></div>
<p>In the UI, connects only to DataFrameInput.</p>
<p><strong>Primitive Types (<code>str</code>, <code>int</code>, <code>bool</code>)</strong></p>
<p>Returning primitives is allowed but wrapping in Data or Message is recommended for better UI consistency.</p>
<div class="ch-codeblock not-prose" data-ch-theme="github-dark"><div class="ch-code-wrapper ch-code" data-ch-measured="false"><code class="ch-code-scroll-parent"><br><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span>def compute_sum(self) -&gt; int:</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> return sum(self.numbers)</span></div></div><br></code></div></div>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="tips-for-typed-annotations">Tips for typed annotations<a href="#tips-for-typed-annotations" class="hash-link" aria-label="Direct link to Tips for typed annotations" title="Direct link to Tips for typed annotations"></a></h3>
<p>When using typed annotations, consider the following best practices:</p>
<ul>
<li><strong>Always Annotate Outputs</strong>: Specify return types like <code>-&gt; Data</code>, <code>-&gt; Message</code>, or <code>-&gt; DataFrame</code> to enable proper UI color-coding and validation.</li>
<li><strong>Wrap Raw Data</strong>: Use <code>Data</code>, <code>Message</code>, or <code>DataFrame</code> wrappers instead of returning plain structures.</li>
<li><strong>Use Primitives Carefully</strong>: Direct <code>str</code> or <code>int</code> returns are fine for simple flows, but wrapping improves flexibility.</li>
<li><strong>Annotate Helpers Too</strong>: Even if internal, typing improves maintainability and clarity.</li>
<li><strong>Handle Edge Cases</strong>: Prefer returning structured <code>Data</code> with error fields when needed.</li>
<li><strong>Stay Consistent</strong>: Use the same types across your components to make flows predictable and easier to build.</li>
</ul>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="enable-dynamic-fields">Enable dynamic fields<a href="#enable-dynamic-fields" class="hash-link" aria-label="Direct link to Enable dynamic fields" title="Direct link to Enable dynamic fields"></a></h2>
<p>In <strong>Langflow</strong>, dynamic fields allow inputs to change or appear based on user interactions. You can make an input dynamic by setting <code>dynamic=True</code>.
Optionally, setting <code>real_time_refresh=True</code> triggers the <code>update_build_config</code> method to adjust the input&#x27;s visibility or properties in real time, creating a contextual UI that only displays relevant fields based on the user&#x27;s choices.</p>
<p>In this example, the operator field triggers updates via <code>real_time_refresh=True</code>.
The <code>regex_pattern</code> field is initially hidden and controlled via <code>dynamic=True</code>.</p>
<div class="ch-codeblock not-prose" data-ch-theme="github-dark"><div class="ch-code-wrapper ch-code" data-ch-measured="false"><code class="ch-code-scroll-parent"><br><div><span class="ch-code-line-number">_<!-- -->22</span><div style="display:inline-block;margin-left:16px"><span>from langflow.io import DropdownInput, StrInput</span></div></div><div><span class="ch-code-line-number">_<!-- -->22</span><div style="display:inline-block;margin-left:16px"><span></span></div></div><div><span class="ch-code-line-number">_<!-- -->22</span><div style="display:inline-block;margin-left:16px"><span>class RegexRouter(Component):</span></div></div><div><span class="ch-code-line-number">_<!-- -->22</span><div style="display:inline-block;margin-left:16px"><span> display_name = &quot;Regex Router&quot;</span></div></div><div><span class="ch-code-line-number">_<!-- -->22</span><div style="display:inline-block;margin-left:16px"><span> description = &quot;Demonstrates dynamic fields for regex input.&quot;</span></div></div><div><span class="ch-code-line-number">_<!-- -->22</span><div style="display:inline-block;margin-left:16px"><span></span></div></div><div><span class="ch-code-line-number">_<!-- -->22</span><div style="display:inline-block;margin-left:16px"><span> inputs = [</span></div></div><div><span class="ch-code-line-number">_<!-- -->22</span><div style="display:inline-block;margin-left:16px"><span> DropdownInput(</span></div></div><div><span class="ch-code-line-number">_<!-- -->22</span><div style="display:inline-block;margin-left:16px"><span> name=&quot;operator&quot;,</span></div></div><div><span class="ch-code-line-number">_<!-- -->22</span><div style="display:inline-block;margin-left:16px"><span> display_name=&quot;Operator&quot;,</span></div></div><div><span class="ch-code-line-number">_<!-- -->22</span><div style="display:inline-block;margin-left:16px"><span> options=[&quot;equals&quot;, &quot;contains&quot;, &quot;regex&quot;],</span></div></div><div><span class="ch-code-line-number">_<!-- -->22</span><div style="display:inline-block;margin-left:16px"><span> value=&quot;equals&quot;,</span></div></div><div><span class="ch-code-line-number">_<!-- -->22</span><div style="display:inline-block;margin-left:16px"><span> real_time_refresh=True,</span></div></div><div><span class="ch-code-line-number">_<!-- -->22</span><div style="display:inline-block;margin-left:16px"><span> ),</span></div></div><div><span class="ch-code-line-number">_<!-- -->22</span><div style="display:inline-block;margin-left:16px"><span> StrInput(</span></div></div><div><span class="ch-code-line-number">_<!-- -->22</span><div style="display:inline-block;margin-left:16px"><span> name=&quot;regex_pattern&quot;,</span></div></div><div><span class="ch-code-line-number">_<!-- -->22</span><div style="display:inline-block;margin-left:16px"><span> display_name=&quot;Regex Pattern&quot;,</span></div></div><div><span class="ch-code-line-number">_<!-- -->22</span><div style="display:inline-block;margin-left:16px"><span> info=&quot;Used if operator=&#x27;regex&#x27;&quot;,</span></div></div><div><span class="ch-code-line-number">_<!-- -->22</span><div style="display:inline-block;margin-left:16px"><span> dynamic=True,</span></div></div><div><span class="ch-code-line-number">_<!-- -->22</span><div style="display:inline-block;margin-left:16px"><span> show=False,</span></div></div><div><span class="ch-code-line-number">_<!-- -->22</span><div style="display:inline-block;margin-left:16px"><span> ),</span></div></div><div><span class="ch-code-line-number">_<!-- -->22</span><div style="display:inline-block;margin-left:16px"><span> ]</span></div></div><br></code></div></div>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="implement-update_build_config">Implement <code>update_build_config</code><a href="#implement-update_build_config" class="hash-link" aria-label="Direct link to implement-update_build_config" title="Direct link to implement-update_build_config"></a></h3>
<p>When a field with <code>real_time_refresh=True</code> is modified, Langflow calls the <code>update_build_config</code> method, passing the updated field name, value, and the component&#x27;s configuration to dynamically adjust the visibility or properties of other fields based on user input.</p>
<p>This example will show or hide the <code>regex_pattern</code> field when the user selects a different operator.</p>
<div class="ch-codeblock not-prose" data-ch-theme="github-dark"><div class="ch-code-wrapper ch-code" data-ch-measured="false"><code class="ch-code-scroll-parent"><br><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span>def update_build_config(self, build_config: dict, field_value: str, field_name: str | None = None) -&gt; dict:</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> if field_name == &quot;operator&quot;:</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> if field_value == &quot;regex&quot;:</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> build_config[&quot;regex_pattern&quot;][&quot;show&quot;] = True</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> else:</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> build_config[&quot;regex_pattern&quot;][&quot;show&quot;] = False</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> return build_config</span></div></div><br></code></div></div>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="additional-dynamic-field-controls">Additional Dynamic Field Controls<a href="#additional-dynamic-field-controls" class="hash-link" aria-label="Direct link to Additional Dynamic Field Controls" title="Direct link to Additional Dynamic Field Controls"></a></h3>
<p>You can also modify other properties within <code>update_build_config</code>, such as:</p>
<ul>
<li>
<p><code>required</code>: Set <code>build_config[&quot;some_field&quot;][&quot;required&quot;] = True/False</code></p>
</li>
<li>
<p><code>advanced</code>: Set <code>build_config[&quot;some_field&quot;][&quot;advanced&quot;] = True</code></p>
</li>
<li>
<p><code>options</code>: Modify dynamic dropdown options.</p>
</li>
</ul>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="tips-for-managing-dynamic-fields">Tips for Managing Dynamic Fields<a href="#tips-for-managing-dynamic-fields" class="hash-link" aria-label="Direct link to Tips for Managing Dynamic Fields" title="Direct link to Tips for Managing Dynamic Fields"></a></h3>
<p>When working with dynamic fields, consider the following best practices to ensure a smooth user experience:</p>
<ul>
<li><strong>Minimize field changes</strong>: Hide only fields that are truly irrelevant to avoid confusing users.</li>
<li><strong>Test behavior</strong>: Ensure that adding or removing fields doesn&#x27;t accidentally erase user input.</li>
<li><strong>Preserve data</strong>: Use <code>build_config[&quot;some_field&quot;][&quot;show&quot;] = False</code> to hide fields without losing their values.</li>
<li><strong>Clarify logic</strong>: Add <code>info</code> notes to explain why fields appear or disappear based on conditions.</li>
<li><strong>Keep it manageable</strong>: If the dynamic logic becomes too complex, consider breaking it into smaller components, unless it serves a clear purpose in a single node.</li>
</ul>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="error-handling-and-logging">Error handling and logging<a href="#error-handling-and-logging" class="hash-link" aria-label="Direct link to Error handling and logging" title="Direct link to Error handling and logging"></a></h2>
<p>In Langflow, robust error handling ensures that your components behave predictably, even when unexpected situations occur, such as invalid inputs, external API failures, or internal logic errors.</p>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="error-handling-techniques">Error handling techniques<a href="#error-handling-techniques" class="hash-link" aria-label="Direct link to Error handling techniques" title="Direct link to Error handling techniques"></a></h3>
<ul>
<li><strong>Raise Exceptions</strong>:
If a critical error occurs, you can raise standard Python exceptions such as <code>ValueError</code>, or specialized exceptions like <code>ToolException</code>. Langflow will automatically catch these and display appropriate error messages in the UI, helping users quickly identify what went wrong.<!-- -->
<div class="ch-codeblock not-prose" data-ch-theme="github-dark"><div class="ch-code-wrapper ch-code" data-ch-measured="false"><code class="ch-code-scroll-parent"><br><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span>def compute_result(self) -&gt; str:</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> if not self.user_input:</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> raise ValueError(&quot;No input provided.&quot;)</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> # ...</span></div></div><br></code></div></div>
</li>
<li><strong>Return Structured Error Data</strong>:
Instead of stopping a flow abruptly, you can return a Data object containing an &quot;error&quot; field. This approach allows the flow to continue operating and enables downstream components to detect and handle the error gracefully.<!-- -->
<div class="ch-codeblock not-prose" data-ch-theme="github-dark"><div class="ch-code-wrapper ch-code" data-ch-measured="false"><code class="ch-code-scroll-parent"><br><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span>def run_model(self) -&gt; Data:</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> try:</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> # ...</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> except Exception as e:</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> return Data(data={&quot;error&quot;: str(e)})</span></div></div><br></code></div></div>
</li>
</ul>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="improve-debugging-and-flow-management">Improve debugging and flow management<a href="#improve-debugging-and-flow-management" class="hash-link" aria-label="Direct link to Improve debugging and flow management" title="Direct link to Improve debugging and flow management"></a></h3>
<ul>
<li>
<p><strong>Use <code>self.status</code></strong>:
Each component has a status field where you can store short messages about the execution result—such as success summaries, partial progress, or error notifications. These appear directly in the UI, making troubleshooting easier for users.</p>
<div class="ch-codeblock not-prose" data-ch-theme="github-dark"><div class="ch-code-wrapper ch-code" data-ch-measured="false"><code class="ch-code-scroll-parent"><br><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span>def parse_data(self) -&gt; Data:</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span># ...</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span>self.status = f&quot;Parsed {len(rows)} rows successfully.&quot;</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span>return Data(data={&quot;rows&quot;: rows})</span></div></div><br></code></div></div>
</li>
<li>
<p><strong>Stop specific outputs with <code>self.stop(...)</code></strong>:
You can halt individual output paths when certain conditions fail, without affecting the entire component. This is especially useful when working with components that have multiple output branches.</p>
<div class="ch-codeblock not-prose" data-ch-theme="github-dark"><div class="ch-code-wrapper ch-code" data-ch-measured="false"><code class="ch-code-scroll-parent"><br><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span>def some_output(self) -&gt; Data:</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span>if &lt;some condition&gt;:</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> self.stop(&quot;some_output&quot;) # Tells Langflow no data flows</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span> return Data(data={&quot;error&quot;: &quot;Condition not met&quot;})</span></div></div><br></code></div></div>
</li>
<li>
<p><strong>Log events</strong>:
You can log key execution details inside components. Logs are displayed in the &quot;Logs&quot; or &quot;Events&quot; section of the component&#x27;s detail view and can be accessed later through the flow&#x27;s debug panel or exported files, providing a clear trace of the component&#x27;s behavior for easier debugging.</p>
<div class="ch-codeblock not-prose" data-ch-theme="github-dark"><div class="ch-code-wrapper ch-code" data-ch-measured="false"><code class="ch-code-scroll-parent"><br><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span>def process_file(self, file_path: str):</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span>self.log(f&quot;Processing file {file_path}&quot;)</span></div></div><div><span class="ch-code-line-number">_<!-- -->10</span><div style="display:inline-block;margin-left:16px"><span># ...</span></div></div><br></code></div></div>
</li>
</ul>
<h3 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="tips-for-error-handling-and-logging">Tips for error handling and logging<a href="#tips-for-error-handling-and-logging" class="hash-link" aria-label="Direct link to Tips for error handling and logging" title="Direct link to Tips for error handling and logging"></a></h3>
<p>To build more reliable components, consider the following best practices:</p>
<ul>
<li><strong>Validate inputs early</strong>: Catch missing or invalid inputs at the start to prevent broken logic.</li>
<li><strong>Summarize with <code>self.status</code></strong>: Use short success or error summaries to help users understand results quickly.</li>
<li><strong>Keep logs concise</strong>: Focus on meaningful messages to avoid cluttering the UI.</li>
<li><strong>Return structured errors</strong>: When appropriate, return <code>Data(data={&quot;error&quot;: ...})</code> instead of raising exceptions to allow downstream handling.</li>
<li><strong>Stop outputs selectively</strong>: Only halt specific outputs with <code>self.stop(...)</code> if necessary, to preserve correct flow behavior elsewhere.</li>
</ul>
<h2 class="anchor anchorWithHideOnScrollNavbar_WYt5" id="contribute-custom-components-to-langflow">Contribute custom components to Langflow<a href="#contribute-custom-components-to-langflow" class="hash-link" aria-label="Direct link to Contribute custom components to Langflow" title="Direct link to Contribute custom components to Langflow"></a></h2>
<p>See <a href="/contributing-components">How to Contribute</a> to contribute your custom component to Langflow.</p></div></article><nav class="pagination-nav docusaurus-mt-lg" aria-label="Docs pages"><a class="pagination-nav__link pagination-nav__link--prev" href="/components-bundle-components"><div class="pagination-nav__sublabel">Previous</div><div class="pagination-nav__label">Bundles</div></a><a class="pagination-nav__link pagination-nav__link--next" href="/components-data"><div class="pagination-nav__sublabel">Next</div><div class="pagination-nav__label">Data</div></a></nav></div></div><div class="col col--3"><div class="tableOfContents_bqdL thin-scrollbar theme-doc-toc-desktop"><ul class="table-of-contents table-of-contents__left-border"><li><a href="#class-level-attributes" class="table-of-contents__link toc-highlight">Class-level attributes</a><ul><li><a href="#structure-of-a-custom-component" class="table-of-contents__link toc-highlight">Structure of a custom component</a></li><li><a href="#internal-lifecycle-and-execution-flow" class="table-of-contents__link toc-highlight">Internal Lifecycle and Execution Flow</a></li><li><a href="#inputs-and-outputs" class="table-of-contents__link toc-highlight">Inputs and outputs</a></li><li><a href="#associated-methods" class="table-of-contents__link toc-highlight">Associated Methods</a></li><li><a href="#components-with-multiple-outputs" class="table-of-contents__link toc-highlight">Components with multiple outputs</a></li><li><a href="#common-internal-patterns" class="table-of-contents__link toc-highlight">Common internal patterns</a></li></ul></li><li><a href="#directory-structure-requirements" class="table-of-contents__link toc-highlight">Directory structure requirements</a></li><li><a href="#custom-component-inputs-and-outputs" class="table-of-contents__link toc-highlight">Custom component inputs and outputs</a><ul><li><a href="#inputs" class="table-of-contents__link toc-highlight">Inputs</a></li><li><a href="#outputs" class="table-of-contents__link toc-highlight">Outputs</a></li><li><a href="#tool-mode" class="table-of-contents__link toc-highlight">Tool mode</a></li></ul></li><li><a href="#typed-annotations" class="table-of-contents__link toc-highlight">Typed annotations</a><ul><li><a href="#common-return-types" class="table-of-contents__link toc-highlight">Common Return Types</a></li><li><a href="#tips-for-typed-annotations" class="table-of-contents__link toc-highlight">Tips for typed annotations</a></li></ul></li><li><a href="#enable-dynamic-fields" class="table-of-contents__link toc-highlight">Enable dynamic fields</a><ul><li><a href="#implement-update_build_config" class="table-of-contents__link toc-highlight">Implement <code>update_build_config</code></a></li><li><a href="#additional-dynamic-field-controls" class="table-of-contents__link toc-highlight">Additional Dynamic Field Controls</a></li><li><a href="#tips-for-managing-dynamic-fields" class="table-of-contents__link toc-highlight">Tips for Managing Dynamic Fields</a></li></ul></li><li><a href="#error-handling-and-logging" class="table-of-contents__link toc-highlight">Error handling and logging</a><ul><li><a href="#error-handling-techniques" class="table-of-contents__link toc-highlight">Error handling techniques</a></li><li><a href="#improve-debugging-and-flow-management" class="table-of-contents__link toc-highlight">Improve debugging and flow management</a></li><li><a href="#tips-for-error-handling-and-logging" class="table-of-contents__link toc-highlight">Tips for error handling and logging</a></li></ul></li><li><a href="#contribute-custom-components-to-langflow" class="table-of-contents__link toc-highlight">Contribute custom components to Langflow</a></li></ul></div></div></div></div></main></div></div></div><footer class="footer"><div class="container container-fluid"><div class="row footer__links"><div class="col footer__col"><div class="footer__title"></div><ul class="footer__items clean-list"><li class="footer__item"><div class="footer-links">
<span>© 2025 Langflow</span>
<span id="preferenceCenterContainer"> ·&nbsp; <a href="https://langflow.org/preferences">Manage Privacy Choices</a></span>
</div></li></ul></div></div><div class="footer__bottom text--center"><div class="margin-bottom--sm"><img src="/img/lf-docs-light.svg" alt="Langflow" class="footer__logo themedComponent_mlkZ themedComponent--light_NVdE" width="160" height="40"><img src="/img/lf-docs-dark.svg" alt="Langflow" class="footer__logo themedComponent_mlkZ themedComponent--dark_xIcU" width="160" height="40"></div></div></div></footer><div style="position:fixed;right:20px;bottom:20px;z-index:100;display:flex;align-items:center;gap:10px;cursor:pointer"><div style="background-color:#f6f6f6;border-radius:50%;width:48px;height:48px;display:flex;align-items:center;justify-content:center;box-shadow:0 2px 4px rgba(0,0,0,0.1)"><img src="/img/langflow-icon-black-transparent.svg" style="width:40px" alt="Search"></div></div></div>
</body>
</html>