Update the node class to reference the integration:
class GetWeatherNode(BaseNode[GetWeatherConfig]): node_name = "get_weather" title = "Get Weather" description = "Returns weather data for a given city" category = NodeCategory.DATA color = "#4A90E2" integrations = {"weather_api": ["api_key"]} # integration_type: [required_fields] # ... same inputs/outputs ... async def call(self, ctx: RemoteExecutionContext, city: str) -> dict: import httpx # Get credentials from the execution context creds = ctx.get_integration_credentials("weather_api") api_key = creds.get("api_key", "") if not api_key: raise ValueError("Weather API key not configured") # Call the real API async with httpx.AsyncClient() as client: response = await client.get( "https://api.openweathermap.org/data/2.5/weather", params={"q": city, "appid": api_key, "units": "metric"}, ) response.raise_for_status() data = response.json() return { "temperature": f"{data['main']['temp']}°C", "description": data["weather"][0]["description"].capitalize(), }
integrations = {"weather_api": ["api_key"]} — declares this node depends on the weather_api integration. The platform will show a connection prompt in the editor if credentials aren’t configured.
ctx.get_integration_credentials("weather_api") — retrieves the decrypted credentials at runtime. Returns a dict with the fields from your BaseCredentials model.
Credentials are never stored in the plugin. They’re decrypted by the platform at execution time and passed through the RemoteExecutionContext for that specific run.
Always validate that credentials exist before using them:
async def call(self, ctx: RemoteExecutionContext, city: str) -> dict: creds = ctx.get_integration_credentials("weather_api") if not creds or not creds.get("api_key"): raise ValueError( "Weather API credentials not configured. " "Go to Workspace Settings → Integrations to add your API key." ) # Safe to use credentials...