# AI Skills Source: https://docs.datazone.co/ai-skills Install the official Datazone agent skills so your AI coding assistant can build pipelines, endpoints, flows, and apps correctly # AI Skills Datazone publishes a set of **public agent skills** that teach AI coding assistants how to work with Datazone. Install them once, and your agent knows the YAML schemas, the `config.yml` registration rules, the deploy loop, and the mistakes that produce a project which validates and then fails at runtime. Without them, an assistant guesses at Datazone's conventions. With them, it writes a `@transform` that deploys, an endpoint YAML that resolves, and a Studio App that does not 404 on its own assets. Eight skills covering pipelines, endpoints, flows, objects, apps, and the API ## Install Run this in the root of your Datazone project repository: ```bash theme={null} npx skills add datazoneco/datazone-skills ``` The CLI detects which assistant you use and installs the skills where it expects to find them. Supported clients include **Claude Code**, **Cursor**, **Codex**, **GitHub Copilot**, **Windsurf**, **Gemini**, **Cline**, **AMP**, and **Antigravity**. To install a single skill instead of the whole collection, pass `--skill`: ```bash theme={null} npx skills add datazoneco/datazone-skills --skill datazone-pipeline ``` Skills are instructions, not credentials. They tell your agent how Datazone works — they do not grant it access. Your agent still authenticates with your own [API key](/reference/development/api-key) or `datazone` CLI [profile](/reference/development/command-line), under your existing [policies](/reference/development/policy). ## What's included | Skill | Use it for | Reference | | --------------------------- | ------------------------------------------------------------------------------------------ | ---------------------------------------------------------- | | `datazone-project-setup` | Installing the CLI, creating profiles, cloning a project, and the edit-deploy-verify loop | [Command line](/reference/development/command-line) | | `datazone-pipeline` | Python `@transform` functions, `input_mapping`, `output_mapping`, materialization | [Pipelines](/reference/development/pipeline) | | `datazone-knowledge-object` | Versioned business entities in YAML — fields, primary keys, relationships, action handlers | [Knowledge Objects](/reference/knowledge-objects/overview) | | `datazone-endpoint` | Exposing a query, action, or vector search as an authenticated REST API | [Endpoints](/reference/integration/endpoints) | | `datazone-flow` | Declarative orchestration — `llm_call`, `rest_call`, `for_each`, Python nodes, connections | [Flows](/reference/flows/overview) | | `datazone-intelligent-app` | YAML dashboards — charts, filters, tabs, widgets | [Intelligent Apps](/reference/intelligent-apps/overview) | | `datazone-studio-app` | Vite + React SPAs served behind your organisation's session | [Studio Apps](/reference/studio-apps/overview) | | `datazone-api` | Calling the REST API — `x-api-key` auth, filtering, sorting, pagination, linked documents | [API reference](/api-reference/introduction) | Each skill loads only when it is relevant. Ask your agent to "add a chart to the sales app" and it reads `datazone-intelligent-app`; ask it to "expose this query as an API" and it reads `datazone-endpoint`. You do not choose between them by hand. ## Using them Once installed, work in plain language. The skill supplies the schema and the conventions. ```text theme={null} Add a pipeline that reads the orders dataset, aggregates revenue by region, and materializes the result. ``` The agent writes `pipelines/revenue_by_region.py`, registers it in `config.yml` under `pipelines:` with a unique alias, commits, and pushes — because pushing is what deploys. It then checks the deploy result, since validation is server-side and asynchronous. Some further examples that map cleanly onto a single skill: * *"Create a Knowledge Object for Contract with a relationship to Customer."* * *"This flow fails validation — the `for_each` node isn't receiving its input."* * *"Expose the unpaid-invoices query as an endpoint and show me how to call it."* * *"My Studio App builds but shows a blank page."* Skills are most useful inside your project repository, where the agent can read your actual `config.yml`, datasets, and existing definitions. Several skills begin by confirming they are in a Datazone project — one with a `config.yml` at the root — and will stop and ask if they are not. ## Keeping them current Datazone's YAML schemas and CLI evolve. Re-run the install command to pull the latest published versions: ```bash theme={null} npx skills add datazoneco/datazone-skills ``` The collection is versioned alongside the platform, so refreshing after a [release](/changelog) keeps your agent's knowledge aligned with what your deployment actually accepts. ## Related resources Install the `datazone` CLI and manage profiles How a project repository is structured and deployed Datazone's built-in assistant for queries and apps The REST API your agents and scripts call # Change Logs Source: https://docs.datazone.co/changelog Release notes and feature updates for Datazone Studio Apps * **[Studio Apps](reference/studio-apps/overview)**: When a dashboard is not enough, write the app. A Studio App is a **Vite + React single-page application that lives in your project repository** — Datazone installs its dependencies, builds it in a sandboxed job, and serves the bundle at a real URL **behind your organisation's session**. The browser sends the signed-in user's session with every API call, so the app ships **no API key** and runs with that user's permissions. Each branch builds and serves its own version, so you can review a change before it reaches `main`. Routing, Tailwind, the shadcn setup, and a small Datazone client are **scaffolded for you** — there is no Dockerfile, no deployment pipeline, and no CDN to configure. Use it for the things a declarative dashboard cannot express: multi-step forms, write-back to [Knowledge Objects](reference/knowledge-objects/overview), and bespoke internal tools. See [Getting Started](reference/studio-apps/getting-started). * **[Intelligent App Builder](reference/intelligent-apps/overview)**: Intelligent Apps no longer have to start in YAML. Build them **visually** — drag a chart onto the grid, then edit its query, metrics, and dimensions **directly in the UI**. [Orion](reference/intelligent-apps/orion-ai) is still there and does considerably more than help you write config: ask it to *"add a new customer trend"* and it **adds the chart to your app**, query and all. The YAML has not gone anywhere — the builder and the file are two views of the same app, so you can lay an app out by hand and still review it as a diff. Intelligent App Builder * **Generate policies with Orion**: [Policies](reference/development/policy) give you very granular control — per resource, per action, per project, down to row- and column-level restrictions — but writing that JSON by hand is tedious and easy to get subtly wrong. Now you describe the access you want in plain language and **Orion drafts the policy statements** for you. You review the suggestion before it is applied, so you still decide what gets granted. Generate policy with Orion Flows * **[Flows](reference/flows/overview)**: Orchestrate work as a **directed graph of typed nodes** instead of glue code. Call an **LLM**, hit a **REST API**, branch with `if`, loop with `for_each`, run **Python**, or invoke a project [Action](reference/development/actions) — wired together on the Flow Builder canvas or written directly as **declarative YAML**. The document you edit is exactly what executes, so every run is **reproducible and versionable**, triggered **manually or on a schedule**, with per-node step status for each run. Knowledge Objects * **[Knowledge Objects](reference/knowledge-objects/overview)**: Until now, Datazone could store and transform your data — now it can **create** it. Define your own tables in a couple of clicks and start inserting rows right away. Model the entities of your domain — `Employee`, `Invoice`, `Company` — as declarative YAML, get a governed CRUD API over every instance, with versioning, relationships, and branch awareness built in. * **SQL Explorer — Generate Query**: Write SQL without writing SQL. Click the sparkles icon, type what you want in plain language — "show me unpaid orders" — and Orion generates the query and inserts it straight into your tab. "Show me all orders above \$10,000 in the last 30 days, grouped by region" becomes a working `SELECT` statement before you've opened a second tab. No syntax lookup, no schema guessing. Embedded Agents * **[Embedded Agents](reference/agents/embedding)**: Take the agents you've built on top of your lakehouse and drop them straight into **your own apps, websites, or any third-party tool** — with **just one line of code**. The embedded agent connects to the **same data sources, tools, and model configuration** you set up in Datazone, so your users get the full conversational experience without ever leaving your product. Choose between **Full**, **Bot**, or **Drawer** widget styles, and generate a secure, signed snippet right from the **Embedding** tab of any agent. Vectors Overview * **[Vectors](reference/development/vectors)**: Transform your data into searchable embeddings for AI-powered applications. Create vector indexes from datasets or file containers, configure embedding models and chunking strategies, and enable semantic search that understands meaning and context. Attach vectors to [Agents](reference/agents/overview) for RAG-powered conversations or create [Vector Endpoints](reference/integration/endpoints#vector-based-endpoints) to build semantic search backends for your applications. Vector Search Interface * **[Dynamic Chart Inputs](reference/intelligent-apps/components#dynamic-charts-with-chart-inputs)**: Add interactive dropdown controls directly to charts for dynamic query modification. Users can switch dimensions, change grouping levels, or adjust filters without leaving the chart view. Works seamlessly with Jinja templating for powerful, flexible visualizations. * **Data Profiling**: Understand your data at a glance without manual exploration. Data profiling automatically analyzes your datasets and views, revealing key insights through visual charts. For categorical columns, see value distribution with histograms and pie charts. For numeric columns, view statistical metrics like average and standard deviation. Get instant visibility into your data's characteristics. Datazone Agents * **[Channels](reference/platform/channels)**: Integrate Datazone with external communication platforms. Configure Slack or email channels to deliver scheduled reports and notifications to your team. * **[Reports](reference/platform/reports)**: Automate Intelligent App delivery on a schedule. Generate reports as PDF or PNG and send them via Slack or email using cron expressions for flexible scheduling. * **[Quotas](reference/platform/resources/quotas)**: Set resource limits to control costs and prevent unexpected usage. Create quotas for DCU, tokens, storage, queries, and actions. Get email notifications at 80% usage and automatic service pause at 100% to stay in control of consumption. Datazone Actions * **[Actions](reference/development/actions)**: Deploy **serverless Python functions** that execute on-demand via **API endpoints** or as **tools for AI agents**. Write custom logic with the `@action` decorator, use the **context API** for logging, and automate workflows like **sending notifications**, **processing data**, or **calling external APIs**. Datazone Agents * **[Datazone Agents](reference/agents/overview)**: Create **custom AI assistants** that interact with your data through **natural language**. Agents can execute **SQL queries**, run **Python code**, generate **charts**, and **search the web** automatically. Supports **multiple languages** and remembers **conversation context** for intelligent, multi-step analysis. * **[Model Accounts](reference/development/model-accounts)**: Securely manage **AI provider credentials** for **OpenAI**, **Anthropic (Claude)**, and **AWS Bedrock**. Configure once and reuse across projects and agents with **encrypted storage** and **organization-level access control**. New UI Layout * **[New Clear Layout](reference/ui-overview)**: Redesigned interface with **card-based home page**, **streamlined project workspace**, and **⌘K quick search** for instant navigation to any resource from anywhere in the app. Scatter Plot Feature * **[Scatter Plot Chart Type](reference/intelligent-apps/components#scatter-plot-charts)**: Introduced a new scatter plot chart type for visualizing relationships between two numerical variables. Each point represents a data record positioned according to two metrics on the x and y axes, ideal for identifying correlations, patterns, or outliers in your data. * **[Custom Theme Styling](reference/intelligent-apps/yaml-reference#custom-style-attributes)**: Added `custom_style_attributes` for advanced theme customization. Override specific theme colors using Tailwind CSS variables in OKLCH format, giving you fine-grained control over backgrounds, foregrounds, and chart color palettes. * **[Conditional Chart Visibility](reference/intelligent-apps/yaml-reference#example-conditional-chart-visibility)**: Added `hide_expression` to `chart_config`, allowing you to conditionally hide charts based on query results. Use JavaScript expressions to control chart visibility dynamically (e.g., hide charts with insufficient data). Policy Feature * **[Policy System](reference/development/policy)**: Introduced a comprehensive role-based access control system with hierarchical permissions! Define fine-grained access policies with support for **flat and hierarchical resource patterns** (e.g., `project::*`), explicit allow/deny rules, and resource-specific constraints. Policies support wildcards for flexible matching, branch-aware permissions, and extra constraints like **row-level security** for views and **path restrictions** for projects. Bind policies to roles for scalable permission management across your organization. Views Feature * **[Views](reference/integration/views)**: Introduced a powerful new feature - Views! Transform your datasets into optimized relational database structures with advanced configurations like **partitioning, primary keys, and ordering**. Choose between **materialized views** for lightning-fast query performance or **non-materialized views** for real-time data access. Create views by replicating datasets or writing custom SQL queries that combine multiple datasets and views. Access your views through SQL interface, endpoints, and intelligent apps for enhanced performance and flexibility. * **[Heatmap Chart Type](reference/intelligent-apps/components#heatmap-charts)**: Introduced a new heatmap chart type for visualizing data where values are represented as colors. Heatmaps require exactly two dimensions and one metric, making them perfect for showing relationships between categorical dimensions. Heatmap Chart Example * **[Markdown Component](reference/intelligent-apps/components#text-markdown)**: Added support for Markdown components in Intelligent Apps. Users can now add rich text sections with formatting, headers, lists, and more to their dashboards. Markdown Component Example * **[Multiple Selection Filters](reference/intelligent-apps/filters#handling-multiple-selection-filters)**: Enhanced dropdown filters with multiple selection capability. Users can now select multiple values from a dropdown filter, with proper handling in SQL queries using Jinja templates. Multiple Selection Filter Animation Embedded Intelligent App * **[Embedded Intelligent Apps](reference/intelligent-apps/embedding)**: Introduced the ability to embed Intelligent Apps into external applications via iframes. Generate a secure JWT token containing app and user details, and easily integrate dashboards into your own products. * **[Theme selection for Intelligent Apps](reference/intelligent-apps/yaml-reference#style-configuration)**: Added theme customization options for Intelligent Apps with multiple color schemes: default, teal, blue, green, purple, orange, amber, and mono. Set themes through the `style.theme` configuration property. * **[Chart export features](reference/intelligent-apps/yaml-reference#config-section)**: Added export capabilities for Intelligent App charts. Users can now download chart data as CSV files or save visualizations as PNG images. Enable with the `chart_export_enabled` configuration property. export File Container Cover * **[File Container](reference/development/file-container)**: Introduced File Container, a **storage solution** for managing files in Datazone. It allows you to create, update, and delete file containers, and use them to store data for your pipelines and notebooks. You can interact with file containers like AWS S3 buckets or Google Cloud Storage buckets using the `FileContainerClient` toolkit. * **Orion Notebook Assistant:** Added support for **code suggestion** and **error suggestions** in Orion Notebooks. Just click to Sparkles ✨ and tell what you want to do, and Orion will suggest code snippets. Orion Assistant Animation Endpoint Animation * **[Endpoints](reference/integration/endpoints)**: Introduced a new core concept - Endpoints! Users can now create secure, controlled API interfaces for their datasets. Define endpoints using YAML configuration with filters, queries, and authentication. Perfect for exposing analytical results, feeding data to downstream systems, or creating data products that other teams can consume. Endpoint Animation * **[chart\_config](reference/intelligent-apps/components#chart-configuration) attribute**: The `chart_config` attribute is now available for all chart types, allowing you to customize chart appearance with options like `fill_donut`, `show_labels`, and `show_legend`. * **[Stacked bar charts](reference/intelligent-apps/components#stacked-bar-charts)**: Added support for stacked bar charts using the `is_stacked` attribute, allowing you to visualize multiple metrics in a single bar Stacked Bar Chart Example * **[fill\_donut](reference/intelligent-apps/components#chart-configuration) for pie charts**: The `fill_donut` attribute is now available for pie charts, allowing you to fill the donut area for a more visually appealing design. * **[Radial chart type](reference/intelligent-apps/components#radial-charts)**: Added support for the new `radial` chart type, perfect for displaying progress or completion metrics in a circular format. Requires exactly two metrics where the first represents the current value and the second represents the total. Radial Chart Example * **[Filter dependencies and cascading filters](reference/intelligent-apps/filters#filter-dependencies)**: Enhanced filter functionality with dependent filters that create cascading effects. Filters can now reference other filter variables in their SQL queries, enabling hierarchical filtering like country → city relationships. * **AI-driven deployment error assistance**: New deployment activity feature allows users to directly ask Orion Code Assistant for help when encountering deployment errors, providing intelligent troubleshooting and fix suggestions. Suggest Fix Animation * **[Icon feature for number charts](reference/intelligent-apps/components#number-charts)**: You can now add Lucide icons next to number values in number charts using the `icon` and `icon_variant` attributes. Intelligent App Example * **[metric\_format to format](reference/intelligent-apps/yaml-reference#charts)**: The `metric_format` attribute is deprecated. Use the new `format` attribute under each metric instead. * **[Composed (combined) chart type](reference/intelligent-apps/components#composed-charts)**: Added support for the new `composed` chart type, allowing you to combine line and bar series in a single chart. Intelligent App Example * **[Axis support for line, bar, and composed charts](reference/intelligent-apps/components#axis)**: You can now define multiple axes using the `axis` property and assign metrics to axes with `axis_name`. * **[affected\_filter for bar and pie charts](reference/intelligent-apps/components#bar-charts)**: Add `affected_filter` under a dimension to allow users to update filter values by clicking chart items (bars or pie slices). Intelligent App Example # Private Cloud Source: https://docs.datazone.co/deployment/private-cloud Enterprise deployment of Datazone in your cloud environment # Private Cloud Deployment Private cloud deployment allows enterprises to run Datazone in their own cloud infrastructure with enhanced security, control, and customization options. ## Supported Cloud Providers ### AWS * EKS for container orchestration * S3 for data lake storage ### Azure * AKS for container orchestration * Blob Storage for data lake ## Enterprise Features ### Enhanced Security * VPC/VNET integration * Customer-managed encryption keys * LDAP/Active Directory integration * IP whitelisting * Audit logging * Custom security policies ### Advanced Operations * Multi-region deployment * Custom backup policies * Disaster recovery options * Load balancing configuration * Auto-scaling policies * Resource quotas ### Data Governance * Data lineage tracking * Access control policies * Compliance monitoring * Data retention rules * Audit trails * Custom metadata ## System Requirements ### Kubernetes Cluster * Minimum 3 nodes * 4 CPU cores per node * 16GB RAM per node * 100GB storage per node ### Object Storage * S3-compatible storage * Minimum 1TB capacity * High availability setup ## Support & SLA ### Enterprise Support * 24/7 technical support * 1-hour response for critical issues * Dedicated support engineer * Quarterly review meetings * Custom feature development ### SLA Terms * 99.99% uptime guarantee * 15-minute RPO * 1-hour RTO # Public Cloud Source: https://docs.datazone.co/deployment/public-cloud Datazone public cloud deployment for community and pro users # Public Cloud Deployment Datazone's public cloud offering is hosted at [https://app.datazone.co](https://app.datazone.co), providing a fully managed solution for community and professional users. ## Available Tiers ### Community Edition * Free tier for individual users and small teams * 1 Data Project * 2 Users * 5 DCU Compute * 250 MB of Hot Storage * 1GB of Cold Storage * Community support ### Professional Edition * Suitable for growing teams * Including all Community features * Unlimited Data Projects * Orchestration * Data Branching & Time Travel * API access * Email support ## Features ### Infrastructure * Hosted on AWS infrastructure * Automatic scaling * Daily backups * 99.9% uptime SLA (Professional) * Global CDN ### Security * SOC2 compliant * Data encryption at rest and in transit * Regular security audits * Two-factor authentication * Single Sign-On (Professional) ### Maintenance * Automatic updates * 24/7 monitoring * Zero-downtime deployments * Automated backups ## Getting Started 1. Sign up at [https://app.datazone.co/app/sign-up](https://app.datazone.co/app/sign-up) 2. Create your organization and choose your plan 3. Create your first project 4. Configure data sources 5. Start building pipelines ## Support Options ### Community Edition * Documentation access * Bug reporting/Feedback system ### Professional Edition * Email support (24-hour response) * Screen sharing sessions * Priority bug fixes # From Zero to Production! Source: https://docs.datazone.co/from-zero-to-production In this guide, you will learn how to build a Data Lakehouse from scratch using Datazone, including creating intelligent apps, deploying AI agents, and exposing data via secure endpoints. ## Prerequisites Before you start building your Data Lakehouse, make sure you have the following prerequisites: * A Datazone account. If you don't have one, you can sign up [here](https://app.datazone.co/app/sign-up). * Datazone CLI installed on your local machine. You can install it by following the instructions [here](/installation). ## Task List To understand how to build a Data Lakehouse from scratch using Datazone, let's follow these steps: 1. 🔌 **Connecting your data source**: Start by connecting AWS S3 as a data source. 2. 📁 **Initialize first project**: Set up your first project and add an Extract component. 3. 🚀 **Run first execution**: Launch your first execution to fetch data from the source. 4. 📄 **Create first pipeline**: Design a simple pipeline to process the data. 5. 🚂 **Run first pipeline**: Execute the pipeline to transform your data. 6. ⏰ **Create first schedule**: Configure periodic runs for automated processing. 7. 🧠 **Create an Intelligent App**: Turn your data pipelines into context-aware applications that observe, reason, and act — not just visualize. 8. 🤖 **Deploy an Agent**: Set up AI-powered automation for monitoring and insights. 9. 🔗 **Expose data via Endpoints**: Create secure APIs for your processed data. 10. 🏆 **Access the data**: Learn how to query and use the processed data. ## 🔌 Connect Source 1.Go to **Settings** from the top-right user menu, then select **Sources** under the **Integrations** section. source-empty 1. Click on the **Create Source** button. source-form 1. Fill in the required fields and click on the **Create** button. And you are done! You have successfully connected your source. Check your source in the **Settings** > **Sources** page. source-success ## 📁 Create Project 1. Go to the **Projects** page by clicking on the **Projects** tab in the sidebar. source-success 1. Click on the **Create Project** button. source-success 1. Fill in the required fields and click on the **Create** button. Boom! 🚀 You have successfully created your first project. source-success ### Define your Extract 1. On your project page, click on the **Add** button in the top right corner to add a new entity. 2. Select **Extract** as the entity type. source-success 1. Fill in the required fields and click on the **Create** button. You have successfully created your first Extract entity. source-success **Base Attributes** * `name`: The name of the extract. * `source`: The source you want to extract data from. (It is already selected) * `mode`: The mode of the extract. Options are; * `Overwrite`: Fetch all the data from the source every time. * `Append`: Fetch only the new data from the source. **Source Dependent Attributes** (In this case, AWS S3). Check the [AWS S3](/sources/awss3) page for more details. * `search_prefix`: The prefix you want to search for in the bucket. * `search_pattern`: The pattern you want to search for in the bucket. ## 🚀 Run First Execution and Check the Data 1. Click to the created Extract entity and move to the **Executions** tab. Via clicking the **Run** button, you can start your first execution. source-success 1. Simultaneously, you can check the execution logs and the other details in the **Logs** tab. You can cancel the execution if you want. After a while, execution will be completed and you notice the new dataset in left explorer. You can check the data by clicking on the dataset. source-success 1. On the dataset drawer, you can see the data fetched from the source. You can also check the schema and make queries on the data to explore it. source-success 1. With above way, we can fetch the other csv files from the source and create the datasets for each of them. ## ⌨️ Click Less, Code More: Create First Pipeline If you have already created your project on the UI, open the project page and move to the "Code" section in the left tabs. For local development, clone it using the Datazone CLI. ```shell theme={null} datazone project clone ``` You will see: ```text theme={null} Repository has initialized 👉 Go to repository directory: cd ecommerce-project/ ``` Check your project folder ```shell theme={null} > cd ecommerce-project/ > ls -ll ecommerce-project/ ├── README.md ├── hello-world.py ├── config.yml ``` 1. We can create our pipeline file in the project folder. Let's create a new file named `order_reports.py` in the project folder. ```python order_reports.py theme={null} from datazone import transform, Input, Dataset from pyspark.sql import functions as F @transform( input_mapping={ "orders": Input(Dataset(alias="orders_c90dc0")), "order_lines": Input(Dataset(alias="order_lines_8c5238")), "customers": Input(Dataset(alias="customers_9cd9ab")), } ) def join_tables(orders, order_lines, customers): return orders.join(order_lines, on="OrderID", how="inner").join( customers, on="CustomerID", how="inner" ) @transform(input_mapping={"joined": Input(join_tables)}, materialized=True) def sales_by_country(joined): country_report = ( joined.groupBy("Country") .agg( F.sum("TotalAmount").alias("TotalSales"), F.count("OrderID").alias("OrderCount"), ) .orderBy("TotalSales", ascending=False) ) return country_report @transform(input_mapping={"joined": Input(join_tables)}, materialized=True) def most_popular_products(joined): product_report = ( joined.groupBy("ProductID") .agg( F.sum("TotalAmount").alias("TotalSales"), F.sum("Quantity").alias("TotalQuantity"), F.avg("UnitPrice").alias("AveragePrice"), F.count("OrderID").alias("OrderCount"), ) .orderBy("TotalSales", ascending=False) ) return product_report ``` Above code is a simple pipeline that joins three tables and creates two reports. * You can see that we have two functions that are decorated with `@transform`. These functions are the steps of the pipeline. You can specify the input datasets and the output dataset of the function by using the `input_mapping` and `output_mapping` classes. * The first function `join_tables` joins the `orders`, `order_lines`, and `customers` tables. * The second function `sales_by_country` calculates the total sales and order count by country. * The third function `most_popular_products` calculates the total sales, total quantity, average price, and order count by product. You can create your own pipeline according to your needs. Also you can check the [Transform Functions](/transform-functions) page to see the available functions. 1. Then you need to reference this pipeline in the `config.yml` file. ```yaml config.yml theme={null} project_name: ecommerce-project project_id: 673f8ef62a466524757a7de1 pipelines: - alias: order_reports path: order_reports.py ``` 1. Write your code in the "Code" section of the project page and click the Deploy button. And you will see the deployed pipeline if you click the newly created pipeline in the project page. source-success 1. Click the Execute button in the pipeline page. There are many ways to do something in Datazone. You can run your pipeline via UI, CLI or API. 1. While execution is running, you can check the logs both in the terminal and in the UI. After the execution is completed, you can check the logs and the output dataset in the **Executions** tab. source-success 1. Our new **Dataset** is ready to use. You can check and explore the data in the dataset drawer. source-success ## ⏰ Orchestrate Your Pipeline 1. Select the pipeline you want to schedule in the Explorer. 2. Open the **Schedules** tab and click on the **+ Set Schedule** button. 3. Attributes are: * `pipeline`: The pipeline you want to schedule. (It is already selected) * `name`: The name of the schedule. * `expression`: The cron expression for the schedule. You can use the presets or write your own. source-success ## 🧠 Create an Intelligent App At this point, your pipelines are producing reliable and structured datasets. In Datazone, an Intelligent App is built on top of these pipelines to turn data into **context-aware applications**. An Intelligent App can: * Observe changes in datasets over time * Understand relationships between entities * Surface meaningful insights without manual queries This layer moves your system beyond data processing and enables it to support decisions and workflows. *** ## 🤖 Deploy an Agent Agents bring automation and intelligence into your Datazone applications. An Agent continuously monitors selected datasets, pipelines, or executions and reacts based on context. Typical use cases include: * Detecting anomalies in data or execution behavior * Monitoring pipeline health and failures * Identifying unusual trends or patterns * Providing proactive insights without user interaction Once deployed, agents run continuously and become part of your production system. *** ## 🔗 Expose Data via Endpoints After processing and enriching your data, you can expose it using Endpoints. Endpoints allow external applications and services to securely access your datasets via APIs. Key benefits: * Secure access using API keys * Controlled exposure at dataset or view level * No direct database access required This enables frontend applications, integrations, and services to consume trusted data safely. ## 🏆 Access the Data ### SQL Interfaces ```sql Clickhouse theme={null} clickhouse-connect --host=app.datazone.co --port=8443 --user=your-user --password=your-password ``` ```sql MySQL theme={null} mysql -h app.datazone.co -P 3306 -u your-user -p ``` ```sql PostgreSQL theme={null} psql -h app.datazone.co -U your-user -d your-database ``` ## Related Resources Create secure, controlled API interfaces for your datasets Generate and manage API keys for programmatic access Connect to Datazone using Clickhouse ODBC or JDBC drivers Transform datasets into optimized relational database structures # Installation Source: https://docs.datazone.co/installation Before starting to use Datazone, you need to install the Datazone Python CLI. The client is a Python package that provides a simple interface to interact with the Datazone API. ## Requirements Use the following command to check that you have a supported Python version installed: ```bash theme={null} python --version ``` Currently, Python 3.8, 3.9, 3.10, 3.11 and 3.12 are supported ## Installation * You can install the Datazone Python SDK using pip: ```bash theme={null} pip install datazone ``` * Check that the installation was successful by running the following command: ```bash theme={null} datazone --version ``` Check Datazone CLI section for more information on how to use the CLI. ## Get API Key To use the Datazone CLI, you need to create an API key. You can do this by following these steps: 1. Go to the **Settings** page by clicking on the **Settings** tab in the sidebar. 2. Click on the **API Keys** tab in the left sidebar. 3. Click on the **+Create** button. ## Login via CLI If you have already created an account, you can log in to the Datazone CLI using the following command: ```text theme={null} datazone profile create > Profile [default]: > Host [app.datazone.co]: (If you are using a self-hosted version) > API Key: > Password: > Repeat for confirmation: You logged in successfully 🎉 ``` After you have successfully logged in, you can start using the Datazone CLI to interact with the Datazone API. You can check you session status by running the following command: ```bash theme={null} datazone project list ``` For more information on how to use the Datazone CLI, check the [Command Line](/reference/development/command-line) section. # Introduction Source: https://docs.datazone.co/introduction Build, manage, and serve your data pipelines and intelligent applications with ease using Datazone in minutes. hero Datazone is a modern data platform that empowers you to create, orchestrate, and analyze data workflows with a few clicks, while building interactive apps and deploying AI-powered agents. * Create your **[Sources](/key-concepts#source)** and integrate them with your data lakehouse. * Define your source entities with **[Extracts](/key-concepts#extract)**. * Build **[Pipelines](/key-concepts#pipeline)** to clean, filter, and manipulate your data. * Orchestrate your pipelines with the **[Schedule](/key-concepts#schedule)** feature. * Analyze your data with the **[Notebook](/key-concepts#notebook)**. * Create **[Intelligent Apps](/key-concepts#intelligent-app)** for interactive dashboards, charts, and real-time insights. * Deploy **[Agents](/key-concepts#agent)** for automated data processing, AI-driven analytics, and custom workflows. ## Getting Started Start your journey by setting up your environment and building your first project. You need an account to create and manage your data pipelines and apps. Install the Datazone Python CLI to interact with the Datazone API via command line. ## Next Steps Follow our step-by-step guide to create your first project, pipelines, and schedules. Build interactive dashboards from your pipelines with drag-and-drop components and AI chat. Integrate Datazone with your applications using REST APIs, webhooks, and embedding options. Learn more about how Datazone handles Sources, Extracts, Pipelines, and Agents. # Key Concepts Source: https://docs.datazone.co/key-concepts Datazone is a modern data platform that simplifies your data engineering journey by providing a unified environment for data ingestion, processing, analysis, and AI-driven automation. It seamlessly connects your data sources to a robust data lakehouse while offering powerful tools for transformation, orchestration, exploration, interactive apps, and intelligent agents. ## Core Entities ### Source Think of Sources as secure gateways to your data. They act as bridges between your external data systems (databases, cloud storage, streaming platforms) and Datazone. Sources handle the crucial task of credential management and access control, typically managed by organization administrators. They ensure your data connections are both secure and efficient. ### Project Projects are your data initiatives home base. They provide a structured workspace where you can organize related data work - from ingestion to analysis. Each project is a self-contained environment housing **Extracts**, **Pipelines**, **Notebooks**, **Datasets**, **Schedules**, **Intelligent Apps**, and **Agents**. With flexible permission settings, you can control who accesses what, making it perfect for both team collaboration and data governance. ### Extract Extracts are your data ingestion powerhouses. Connected to Sources and living within Projects, they define how data should be pulled from external systems. When executed, Extracts create standardized Datasets in your data Lakehouse. Think of them as smart data movers that handle the heavy lifting of data ingestion while ensuring data quality and consistency. extracts ### Pipeline Pipelines are where data engineering magic happens. Built as Directed Acyclic Graphs (DAGs), they represent your data transformation workflows. Pipelines are defined in code, making them version-controlled, reusable, and maintainable. They can clean, filter, join, and reshape your data, turning raw information into valuable insights. pipeline ### Schedule Schedules bring automation to your data workflows. Using cron expressions, they orchestrate when your Extracts and Pipelines should run. They're the timekeepers of your data platform, ensuring your data processes run like clockwork, whether it's hourly updates or monthly aggregations. ### Notebook Notebooks are your interactive playground for data exploration and analysis. Similar to Jupyter notebooks but integrated into Datazone, they provide a user-friendly interface where you can write code, visualize data, and debug your transformations. They're perfect for both quick data investigations and detailed analysis. pipeline ### Intelligent App Intelligent Apps transform your data into interactive dashboards and applications without requiring frontend development. Using declarative YAML configuration, you can create multi-tab dashboards with charts, filters, and dynamic visualizations that query your datasets directly. They're perfect for building executive dashboards, operational monitoring tools, or self-service analytics interfaces that stakeholders can interact with through filters and drill-down capabilities. Intelligent App Example ### Agent Agents are AI-powered assistants that automate data processing, analysis, and insights generation. Configured with custom instructions, they can monitor data pipelines, generate reports, trigger actions based on data conditions, and provide intelligent recommendations. Agents integrate with your data workflows to enable proactive data management, anomaly detection, and automated decision-making processes. extracts ### Endpoints Endpoints enable you to create secure, controlled API interfaces for your datasets. They transform your processed data into RESTful APIs that can be consumed by external applications, services, or third-party integrations. With built-in authentication and authorization controls, Endpoints ensure your data is shared securely while maintaining governance standards. They're perfect for exposing analytical results, feeding data to downstream systems, or creating data products that other teams can reliably consume. ## How It All Fits Together Your data journey in Datazone typically flows like this: 1. Connect to external systems through **Sources** 2. Organize your work in **Projects** 3. Ingest data using **Extracts** 4. Transform data with **Pipelines** 5. Automate workflows using **Schedules** 6. Analyze results in **Notebooks** 7. Share insights through **Intelligent Apps** 8. Deploy intelligent automation with **Agents** 9. Expose data via secure **Endpoints** This integrated approach ensures a smooth data lifecycle, from ingestion to insights and automation, while maintaining security, scalability, and ease of use. Each entity in Datazone is designed to solve specific data engineering challenges while working harmoniously with others. This modular yet integrated approach makes Datazone powerful enough for complex data operations and AI-driven automation yet simple enough for quick data tasks. # Best Practices Source: https://docs.datazone.co/reference/agents/best-practices Optimize your agents for better performance, accuracy, and cost efficiency # Best Practices Follow these guidelines to build **effective, efficient agents** that deliver **accurate insights** while **managing costs**. ## Model Selection ### Choosing the Right Model Different models excel at different tasks: | Model Type | Best For | Cost | Speed | | --------------------- | ---------------------------------------- | ------ | ------ | | **GPT-4** | **Complex reasoning**, detailed analysis | High | Slower | | **GPT-4o** | **Balanced performance**, general use | Medium | Medium | | **GPT-4o-mini** | **Simple queries**, high volume | Low | Fast | | **Claude 3.5 Sonnet** | **Code generation**, structured data | Medium | Medium | | **Claude 3 Haiku** | **Quick answers**, basic queries | Low | Fast | ### Use Case Guidelines **Complex Analysis** → GPT-4 or Claude 3.5 Sonnet * **Multi-step reasoning** required * **Deep data analysis** * **Code generation** needs **General Use** → GPT-4o or Claude 3.5 Sonnet * **Balanced performance** * Most common questions * **Good for production** agents **High Volume** → GPT-4o-mini or Claude 3 Haiku * **Simple queries** * **Cost-sensitive** applications * **Fast response times** needed Start with a **mid-tier model** (GPT-4o or Claude 3.5 Sonnet) and adjust based on actual usage patterns. ## Model Parameters ### Temperature **Temperature** controls how **creative** or **focused** the agent's responses are: Temperature Scale * **0.0 - 0.3** (Focused) * **Consistent, deterministic** answers * Best for: **Data queries**, factual analysis * Use when **accuracy is critical** * **0.4 - 0.7** (Balanced) * Mix of **consistency and creativity** * Best for: **General purpose** agents * **Recommended default** * **0.8 - 1.0** (Creative) * **Varied, exploratory** responses * Best for: Brainstorming, recommendations * Use **sparingly for data agents** For most data analysis agents, keep temperature between **0.2 and 0.5** for reliable results. ### Max Tokens **Max Tokens** controls the **maximum response length**: * **1,000 - 2,000** - **Short, focused** answers * **2,000 - 4,000** - **Standard responses** (recommended) * **4,000+** - **Detailed analysis** and long explanations **Higher limits = more cost**. Set based on expected answer complexity. ## Data Source Optimization ### Use Views Instead of Datasets **Why Views Are Better:** * ✅ **Faster query execution** * ✅ **Pre-filtered**, relevant data only * ✅ **Better security** (control data access) * ✅ **Lower token usage** * ✅ **More accurate** agent responses **Example:** ``` Instead of: Full "orders" dataset (millions of rows) Create: "recent_orders" view (last 90 days, key columns) ``` The agent queries **faster** and gets **relevant data immediately**. **Always use Views instead of raw datasets** for better performance and cost efficiency. ### Limit Data Sources Only grant access to **necessary datasets/views**: **Too Broad:** * Sales data * HR data * Marketing data * Finance data **Focused:** * Sales summary view * Revenue trends view **Fewer sources = faster decisions + lower costs**. ### Optimize View Definitions Create views with: * **Only necessary columns** * **Pre-aggregated data** where possible * **Relevant date ranges** * **Indexed fields** ## Agent Instructions ### Write Clear System Prompts **Good Instructions:** ``` You are a sales analytics expert. Help users analyze: - Revenue trends and forecasting - Customer behavior and segmentation - Product performance metrics Always provide specific numbers and dates. When showing trends, create visualizations. Be concise and actionable. ``` **Poor Instructions:** ``` You are helpful. Answer questions about data. ``` ### Define Scope Tell the agent: * **What data** it has access to * **What questions** it should handle * **What format** responses should take * Any **business rules** to follow ### Include Examples Provide **specific examples** in instructions: ``` When asked about "top customers," show: 1. Customer name 2. Total revenue 3. Number of orders 4. Comparison to average Example format: "Top 5 customers by revenue: 1. Acme Corp - $150K (45 orders) - 3x average ..." ``` ## Cost Optimization ### Control Token Usage **Input Tokens:** * Keep **system instructions concise** * Limit **conversation history** length * Use **focused data sources** **Output Tokens:** * Set **appropriate max\_tokens** * Request **concise answers** when possible * Avoid asking for **repeated information** ### Monitor Spending * Review **token usage per conversation** * **Track costs by agent** * Set up **alerts for high usage** * Regularly **audit agent performance** ### Batch Similar Questions If running automated analysis: * **Group related queries** * **Reuse context** where possible * **Cache frequently** accessed data ## Agent Configuration ### Tool Selection Enable **only what you need**: **Optional Tools:** * **Chart Generator** - For data visualizations (recommended for most agents) * **Python Executor** - For complex calculations and advanced analytics * **Web Search** - For external context and current information **Query Executor** is enabled by default and cannot be disabled. ### Data Access Control * Grant **minimum necessary access** * Use **views to restrict data** * **Separate agents** by use case * **Review permissions** regularly ### Regular Maintenance * **Update instructions** based on user feedback * **Refine data sources** as needs change * **Adjust model selection** for cost/performance * **Archive unused agents** ## Query Performance ### Faster Queries 1. **Use Views** - **Pre-filtered, optimized data** 2. **Limit Result Sets** - Ask for **"top 10"** not "all" 3. **Specific Time Ranges** - **"last month"** not "all time" 4. **Indexed Columns** - Ensure views use **indexed fields** ### Example Optimizations **Slow:** "Show all customer transactions" **Fast:** "Show top 20 customers by revenue this quarter" ## Testing & Validation ### Test Common Questions Before deploying: * Ask **typical user questions** * **Verify data accuracy** * Check **tool usage patterns** * Measure **response times** ### Validate Answers * Compare agent responses to **known results** * **Verify calculations** manually * Check **chart accuracy** * Test **edge cases** ### Iterate * Gather **user feedback** * **Refine instructions** * **Adjust parameters** * **Optimize data sources** ## Security ### Data Access * Only grant **necessary permissions** * Use **views to limit sensitive data** * **Review agent access** regularly * **Audit query logs** ### Credentials * **Secure model account** API keys * **Rotate credentials** periodically * **Monitor for unusual usage** * Implement **access controls** ## Next Steps * [Create Your First Agent](/reference/agents/overview) * [Configure Model Accounts](/reference/development/model-accounts) * [Set Up Data Views](/reference/integration/views) * [Chat with Your Agent](/reference/agents/chat) # Chat Interface Source: https://docs.datazone.co/reference/agents/chat Interact with your agents through conversational AI # Chatting with Agents The chat interface is where you **interact with your agents**. Ask questions, get insights, and explore your data through **natural language conversations**. Agent Chat Interface ## Starting a Conversation 1. In home page, find your agent in **Agents** section 2. Select an agent from your list 3. Click **New Chat** to start a fresh conversation 4. Type your question and press **Enter** ## Chat Features ### Real-Time Streaming Responses **stream in real-time** as the agent thinks and processes: * See the agent's **thought process** * Watch **tool executions** happen * Get answers **progressively** ### Tool Indicators **Visual indicators** show when the agent uses tools: * **🔧 Using Tool** - Agent is **executing a query** or running code * **💭 Analyzing** - Agent is **processing information** * **✓ Completed** - Tool execution **finished** These indicators help you understand **what the agent is doing** behind the scenes. ### Follow-Up Questions After each response, the agent **automatically suggests** relevant follow-up questions: ``` 💡 Suggested follow-ups: • What is the revenue trend for the top customer? • How do these customers compare to last quarter? • Which products do these customers buy most? ``` Click any suggestion to **automatically ask** that question. ### Conversation History Each chat maintains **full conversation history**: * Return to **previous conversations** anytime * Agent **remembers context** from earlier messages * **Build on previous analysis** ### Token Usage & Cost Each response shows: * **Token count** (input + output) * **Estimated cost** * **Model used** Monitor usage to **manage costs effectively**. ## Asking Effective Questions ### Be Specific **Good:** "What were sales in California last month?" **Vague:** "Tell me about sales" ### Context Helps **Good:** "Show revenue by product category for Q4 2025" **Unclear:** "Show revenue" ### Build on Context ``` You: "What were our top 5 products last month?" Agent: [Provides list] You: "Now show their profit margins" Agent: [Analyzes same products from previous context] ``` ### Ask for Visuals ``` "Show me..." → Agent generates charts "Create a chart of..." → Visual response "Compare..." → Comparison visualization ``` ## Response Types ### Text Answers **Simple, direct responses** to straightforward questions. ### Data Tables **Structured data** presented in table format with: * Column headers * **Formatted numbers** * Sortable results ### Visualizations **Charts and graphs** embedded directly in responses: * **Line charts** for trends * **Bar charts** for comparisons * **Pie charts** for distributions ### Multi-Part Answers **Complex questions** get comprehensive responses: 1. **Initial analysis** 2. **Data query results** 3. **Visualization** 4. **Summary and insights** ## Managing Chats ### Chat List View **all your conversations**: * **Recent chats** appear first * See chat **titles and timestamps** * Preview **last message** ### Automatic Chat Titles Chat titles **auto-generate** from your first question. The agent creates a **concise, descriptive title** automatically. ### Deleting Chats Remove conversations you no longer need: 1. Open the chat 2. Click **delete option** 3. Confirm deletion Deleted chats **cannot be recovered**. All messages and history will be **permanently removed**. ## Tips * **Start broad, then narrow** - Begin with overview questions, then dive into specifics * **Use follow-up suggestions** - Click suggested questions to explore deeper * **Reference previous results** - Agent remembers context, build on earlier answers * **Monitor token usage** - Check costs per response to manage budget ## Next Steps * [Optimize Agent Performance](/reference/agents/best-practices) * [Set Up Model Accounts](/reference/development/model-accounts) # Embedding Source: https://docs.datazone.co/reference/agents/embedding Embed your agents into any website, app, or third-party tool with a single line of code # Embedding Agents You already have the ability to **create agents on top of your lakehouse**. With **embedding**, you can take those same agents and drop them into **your own apps, websites, or any third-party tool** — with **just one line of code**. Embedded agents The embedded agent connects to the **same data sources, tools, and model configuration** you set up in Datazone, so your users get the full conversational experience without ever leaving your product. Embedded agent in drawer mode ## Overview Embedding works through a secure, token-based mechanism: 1. Your server generates a **signed JWT token** containing the agent ID and embedding configuration. 2. The token is used to build a **signed script URL**. 3. You drop a single ` ``` Replace `{scriptUrl}` with the signed URL generated on your server. The container `
` is only needed for the **full** widget. The **bot** and **drawer** widgets render their own floating UI and ignore the container. ## Embedding Parameters The JWT token payload can include the following parameters: | Parameter | Type | Description | | ------------------ | ------ | -------------------------------------------------------------------------------- | | `agent_id` | string | **Required.** The ID of your agent. | | `email` | string | Email of the user interacting with the agent (for access control and analytics). | | `user_id` | string | Optional, instead of email — a unique identifier for the user. | | `embedding_config` | object | Configuration for how the widget renders. See below. | ### `embedding_config` Options | Option | Type | Description | | -------- | ------ | -------------------------------------------------- | | `widget` | string | The widget type: `"full"`, `"bot"`, or `"drawer"`. | ## Example: Full Server-Side Implementation Here's a more complete example using Node.js / Express: ```javascript theme={null} const express = require("express"); const jwt = require("jsonwebtoken"); const app = express(); // Configuration const DATAZONE_SITE_URL = "https://dev.datazone.co"; const DATAZONE_SECRET_KEY = process.env.DATAZONE_SECRET_KEY; // Store in environment variables app.get("/agent", (req, res) => { // Get user information from your auth system const currentUser = req.user; // Create the token const payload = { agent_id: "6a0e502103bdcc40271925f1", email: currentUser.email, embedding_config: { widget: "drawer", }, }; const token = jwt.sign(payload, DATAZONE_SECRET_KEY); const scriptUrl = DATAZONE_SITE_URL + "/app/api/widget/agent?token=" + token; // Render your page with the script URL res.render("agent", { scriptUrl }); }); app.listen(3000, () => console.log("Server running on port 3000")); ``` ## Security Considerations * Keep your Datazone secret key secure and **never expose it in client-side code**. * Generate tokens **server-side** and pass the complete script URL to your frontend. * Use the `email` or `user_id` field to scope access and track usage per user. * Set appropriate content security policies for embedding. ## Troubleshooting If your embedded agent isn't loading correctly: 1. Check that your token is signed correctly with the right secret key. 2. Verify that the agent ID is correct. 3. For the **full** widget, ensure the `datazone-agent-embed-container` div exists on the page. 4. Look for CORS or CSP issues in your browser's developer tools. ## Next Steps * [Agents Overview](/reference/agents/overview) - Learn how to create and configure agents * [Chat Interface](/reference/agents/chat) - Explore the conversational experience * [Contact Support](mailto:support@datazone.co) - Get help with embedding setup # Overview Source: https://docs.datazone.co/reference/agents/overview Create custom AI agents to interact with your data through natural language # Datazone Agents Datazone Agents are **custom AI assistants** that can interact with your data through **natural language conversations**. Each agent is configured with specific **data sources**, **tools**, and **models** to help users explore, analyze, and extract insights from their data. Agents Overview ## What is an Agent? An agent is an AI-powered assistant that: * **Understands natural language** - Ask questions in any language * **Accesses your data** - Queries datasets and views you've configured * **Uses tools** - Executes SQL queries, runs Python code, creates charts, and more * **Provides insights** - Analyzes data and delivers actionable answers Agents Overview Unlike **static dashboards**, agents **adapt to your questions in real-time** and can handle **complex, multi-step analysis** automatically. ## Creating an Agent 1. Navigate to your **Project** page 2. Click the **Add** button (+ icon) 3. Select **Agent** from the dropdown Create Agent The agent creation flow will guide you through **4 steps**: ### Step 1: Basic Information Agent Basic Info Configure the basic settings: * **Name** - A descriptive name for your agent (e.g., "Sales Analyzer", "Customer Support Assistant") * **Instructions** - System prompt that defines the agent's **behavior**, **personality**, and **expertise** * **Response Tone** - How the agent communicates: * **Casual** - Informal, conversational style * **Friendly** - Warm and approachable * **Technical** - Precise and technical (default) * **Educational** - Explanatory and teaching-focused * **Professional** - Formal and business-like * **Response Length** - How detailed responses should be: * **Brief** - Short, concise answers * **Moderate** - Balanced detail (default) * **Detailed** - Comprehensive, in-depth responses * **Language** - The language your agent will use (supports multiple languages) Write **clear instructions**. For example: "You are a sales analytics expert. Help users analyze revenue trends, customer behavior, and product performance. Always provide specific numbers and actionable insights." ### Step 2: Model Configuration Model Configuration Select your **AI model provider** and configure parameters: * **Model Account** - Choose from configured [Model Accounts](/reference/development/model-accounts) (OpenAI, Anthropic, AWS Bedrock) * **Model** - Select the specific model (e.g., GPT-4, Claude 3.5 Sonnet, GPT-4o-mini) * **Temperature** - Controls creativity and randomness (0 = **focused and consistent**, 1 = **creative and varied**) * **Max Tokens** - Maximum response length (higher = longer responses, higher cost) ### Step 3: Data Sources Data Sources Choose which data sources the agent can access: * **Datasets** - Direct access to raw datasets * **Views** - Optimized, filtered data views * **Vectors** - Semantic search on vectorized data for RAG (Retrieval Augmented Generation) The agent will **only be able to access data** from these selected sources. Use **[Views](/reference/integration/views)** instead of raw datasets for **better performance** and security. Views are **faster to query** and let you **control what data** the agent can access. Add **[Vectors](/reference/development/vectors)** to enable **semantic search** and provide contextual information to your agent. ### Step 4: Tools Agent Tools Enable **optional tools** that extend what your agent can do: * **Python Code Executor** - Execute Python code for calculations and analysis * **Chart Generator** - Create visualizations (line, bar, pie charts) * **Web Search** - Search the internet for external information * **Actions** - Call custom functions you've deployed (e.g., send emails, trigger workflows) **Query Executor** is enabled by default and allows the agent to run SQL queries on your data. Select **Actions** to give your agent access to specific custom functions from your project. After completing all steps, click **Create** to save your agent. You can modify any of these settings later from the agent's detail page. ## Using Your Agent Once created, you can start chatting with your agent: Agent Detail 1. Click on your agent from the **agents list** in the **project page**. 2. Click to **Go to Agent** to open the chat interface. 3. Then click to **New Chat** to start a fresh conversation 4. Ask questions in **natural language** (in any language you configured) 5. The agent will **automatically use its tools** to analyze data and provide answers ## Agent Capabilities ### Natural Language Queries Ask questions in **any language**: * "What were our top 5 customers last month?" * "Show me the revenue trend for Q4" * "Which products have declining sales?" * "Compare this quarter to last year" ### Semantic Search with Vectors (RAG) When you add **[Vectors](/reference/development/vectors)** as data sources, agents can perform **semantic similarity search** to retrieve relevant context from your vectorized data. This enables: * **Context-aware responses** - Agent finds relevant information based on meaning, not just keywords * **Document retrieval** - Search through documents, knowledge bases, and unstructured data * **Enhanced accuracy** - Provide agents with precise contextual information for better answers The agent **automatically decides** when to use vector search based on the question and available data sources. ### Action Tools Agents can **call custom actions** you've deployed: * **Send notifications** when certain conditions are met * **Trigger workflows** based on data analysis * **Integrate with external services** (Slack, email, APIs) * **Process or transform data** using custom logic The agent **automatically decides** when to use actions based on the conversation context. Learn more about [creating actions](/reference/development/actions). ### Multi-Step Analysis Agents can perform **complex analysis automatically**: 1. **Execute SQL queries** to fetch data 2. **Run Python code** for calculations 3. **Generate visualizations** automatically 4. **Provide insights** and recommendations Multi-Step Analysis ### Context Awareness Agents **remember conversation history** and can: * Reference previous questions * Build on earlier analysis * Maintain context throughout the chat session ## Best Practices 1. **Clear Instructions** - Write **specific system instructions** that define the agent's expertise and behavior 2. **Right Data Sources** - Only grant access to **relevant datasets/views** 3. **Appropriate Model** - Choose models that **balance cost and capability** for your use case 4. **Use Views** - Configure views for **faster queries** and better data access control 5. **Test Thoroughly** - Ask various questions to ensure the agent **understands your data correctly** ## Next Steps * [Chat with Your Agent](/reference/agents/chat) * [Optimize Performance](/reference/agents/best-practices) * [Configure Model Accounts](/reference/development/model-accounts) # Kernels Source: https://docs.datazone.co/reference/analysis/kernel Kernels are the execution environments for your Datazone notebooks. ## Overview A kernel is the computational engine that executes the code contained in a notebook. It acts as an isolated environment that: * Processes the code you write * Manages the memory and computations * Returns the results back to your notebook kernel-options ## Available Kernel Images Datazone provides two main kernel images: * **Python**: Standard Python environment with common data science libraries * **Python Pyspark**: Python environment with Apache Spark support for distributed computing ## Compute Resources You can select from different compute sizes based on your workload: | Size | Resources | Best for | | ----------- | ------------------- | --------------------------------------- | | **X-Small** | 2 vCPU, 8 GB RAM | Light data processing, simple scripts | | **Small** | 4 vCPU, 16 GB RAM | Standard data analysis, medium datasets | | **Medium** | 8 vCPU, 32 GB RAM | Heavy computations, large datasets | | **Large** | 16 vCPU, 64 GB RAM | Big data processing, complex analytics | | **X-Large** | 32 vCPU, 128 GB RAM | Enterprise-level distributed computing | ## Environment Variables Before initializing a kernel, you can set custom environment variables to: * Configure access credentials * Set runtime parameters * Define application-specific settings * Control library behaviors # Notebooks Source: https://docs.datazone.co/reference/analysis/notebook Notebooks are the interactive documents that you can write and run your code in Datazone. ## Overview A Jupyter notebook is an interactive computing environment that enables you to create and share documents containing: * Live code that you can run * Rich text explanations * Visualizations and charts * Mathematical equations notebook-overview The notebook is divided into cells, which can contain either: * **Code cells**: Where you write and execute code * **Markdown cells**: Where you write formatted text, images and equations When you run a code cell, the results appear directly below the cell, making it easy to: * Experiment with data analysis * Document your workflow * Share your findings with others * Create interactive reports Datazone's integrated Jupyter notebook environment provides several key benefits: * **Direct Data Access**: Instant connection to your data lakehouse * **Security & Governance**: Built-in security controls and policies * **Collaboration**: Easy notebook sharing and version control * **Resource Management**: Fully managed compute resources * **Pre-configured Environment**: Ready-to-use data science tools # Toolkit Source: https://docs.datazone.co/reference/analysis/toolkit The Toolkit is a collection of tools and utilities that help you manage your notebooks in Datazone. ## Overview The Toolkit provides utilities to help you work with data in Datazone notebooks. Currently, it includes the Dataset class for accessing datasets. ## Dataset The Dataset class allows you to easily load datasets into your notebooks as Pandas or PySpark DataFrames. ```python theme={null} from datazone import Dataset dataset = Dataset(id="") # or dataset = Dataset(alias="") ``` You can also load a dataset by providing a specific branch name: ```python theme={null} from datazone import Dataset dataset = Dataset(id="", branch="") ``` Thanks to the Dataset class, you can now easily load datasets into your notebooks as Pandas or PySpark DataFrames. ```python theme={null} from datazone import Dataset pandas_df = dataset.get_pandas_df() # or pyspark_df = dataset.get_pyspark_df() ``` `get_pyspark_df()` is only available in the PySpark kernel. dataset-cell-example ## Variable You can access the Variables from the kernel environment using the `Variable` class. ```python theme={null} from datazone import Variable variable = Variable(key="") ``` ### Example ```python theme={null} from datazone import Variable api_key = Variable(key="OPENAI_API_KEY") client = OpenAI(api_key=str(api_key)) ... ``` Also you can check the [Variables](/reference/development/variables) # Access Keys Source: https://docs.datazone.co/reference/development/access-keys Create and manage access keys for programmatic access to your project resources ## Overview **Access Keys** provide **programmatic access** to your project's file containers and resources. Each access key consists of an **Access Key ID** and a **Secret Access Key** that work like AWS credentials for S3-compatible operations. ## Creating an Access Key 1. Open your **Project** 2. Click **Settings** in the project navigation 3. Navigate to **Access Keys** section 4. Click **Create Access Key** Create Access Key 5. **Copy both credentials immediately** - the secret key won't be shown again Access Key Details **Save your Secret Access Key immediately!** For security reasons, it cannot be retrieved after creation. If lost, you'll need to create a new access key. ## Access Key Components Each access key has two parts: * **Access Key ID** - Public identifier (can be viewed anytime) * **Secret Access Key** - Private credential (shown only once at creation) Both are required for **S3-compatible authentication**. ## Usage Use access keys to connect to **File Containers** via: * **AWS CLI** - Standard AWS S3 commands * **Python (boto3)** - S3 client operations * **JavaScript (AWS SDK)** - Node.js applications * **Java (AWS SDK)** - Java applications See the [File Container Connection Guide](/reference/development/file-container#local-access) for detailed examples. Access keys are **project-specific**. Each project has its own set of access keys that only work with that project's resources. ## Environment Variables Store credentials securely using environment variables: ```bash theme={null} export AWS_ACCESS_KEY_ID="your-access-key-id" export AWS_SECRET_ACCESS_KEY="your-secret-access-key" ``` Most AWS SDKs automatically read these variables. ## Next Steps * [Connect to File Container](/tutorial/file-container-connection) * [Learn About File Containers](/reference/development/file-container) * [Explore AWS CLI Operations](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3/index.html) # Actions Source: https://docs.datazone.co/reference/development/actions Deploy serverless Python functions to automate workflows and extend agent capabilities Datazone Agents ## Overview **Actions** allow you to deploy **serverless Python functions** that can be **triggered on-demand** by endpoints or used as **tools by AI agents**. Think of actions as **lambda-like functions** that run in isolated environments. ```python send_mail_action.py theme={null} from datazone.actions import action @action def send_email(to: str, subject: str, body: str): """ Send an email to a recipient. """ # Your email sending logic here print(f"Sending email to {to}") # Return structured result return { "status": "sent", "recipient": to, "timestamp": "2026-02-11T10:00:00Z" } ``` ```yaml config.yaml theme={null} project_name: my-project project_id: proj_abc123 actions: - path: actions/send_mail_action.py ``` * **Project Structure** ## What Are Actions? Actions are **custom Python functions** that run in **isolated environments**, accept **parameters**, return **structured results**, and can be **triggered via endpoints** or **used as agent tools**. ## Use Cases Inside an action you can: * **[Invoke an LLM](/reference/development/actions#agent)** — call a model through your model account with `Agent`, optionally with structured output * **[Run SQL queries](/reference/development/actions#execute_query)** — read from your datasets with `execute_query` * **[Read and write knowledge objects](/reference/development/actions#knowledgeobject)** — get, list, update and batch upsert instances with `KnowledgeObject` * **[Use secure variables](/reference/development/actions#variable-api)** — access API keys and credentials with `Variable`, without hardcoding them * **[Log execution details](/reference/development/actions#context-api)** — emit info, warning and error logs with `context` * **[Connect to SAP](/reference/development/actions#cloudfeedclient)** — read tables and execute function modules with `CloudFeedClient` * **Call any external API** — the runtime ships with `requests`, so any HTTP service is one call away Which makes actions a good fit for sending notifications, processing data, generating reports, automating workflows, and extending AI agent capabilities with custom logic. ### Action with Logging Use **`context`** to log information during execution: ```python theme={null} from datazone.actions import action, context @action def process_data(dataset_id: str, operation: str = "transform"): """ Process dataset with specified operation. Args: dataset_id: ID of dataset to process operation: Type of operation (default: transform) """ context.log_info(f"Starting {operation} on dataset {dataset_id}") try: # Your processing logic result_count = 42 context.log_info(f"Processed {result_count} records") return { "status": "success", "dataset_id": dataset_id, "records_processed": result_count } except Exception as e: context.log_error(f"Processing failed: {str(e)}") raise ``` ### Action with Optional Parameters ```python theme={null} from datazone.actions import action, context @action def generate_report(report_type: str, format: str = "pdf", email: str = None): """ Generate and optionally email a report. Args: report_type: Type of report to generate format: Output format (default: pdf) email: Optional email address to send report """ context.log_info(f"Generating {report_type} report in {format} format") report_url = f"https://example.com/reports/{report_type}.{format}" if email: context.log_info(f"Sending report to {email}") # Send email logic return { "report_url": report_url, "format": format, "emailed": email is not None } ``` ## Actions SDK Reference ### Decorator ```python theme={null} from datazone.actions import action @action def my_function(): """Your function logic""" pass ``` The **`@action`** decorator marks a function as executable by Datazone. ### Context API The **context** object provides logging capabilities during action execution: ```python theme={null} from datazone.actions import context ``` Log informational messages during action execution. ```python theme={null} context.log_info("Processing started") context.log_info(f"Processed {count} records") ``` Log warning messages for potential issues. ```python theme={null} context.log_warning("Potential issue detected") context.log_warning(f"Unusual data pattern in {field}") ``` Log error messages when operations fail. ```python theme={null} context.log_error("Operation failed") context.log_error(f"Failed to connect: {str(e)}") ``` All logs are **collected and returned** with the action response. ### Variable API The **Variable** class allows actions to access **secure variables** stored in Datazone: ```python theme={null} from datazone.actions import Variable ``` Access workspace variables securely within actions. ```python theme={null} # Access a variable api_key = Variable("API_KEY") # Use as a string (Variable stringifies to its value) headers = {"Authorization": f"Bearer {Variable('AUTH_TOKEN')}"} ``` Variables are **workspace-scoped** and can be marked as **secret** to encrypt sensitive data like API keys, passwords, and tokens. Learn more in the [Variables documentation](/reference/development/variables). #### Example: Using Variables ```python theme={null} from datazone.actions import action, Variable @action def send_notification(message: str): """Send notification using API key from Variables.""" api_key = str(Variable("API_KEY")) print(f"Sending notification with key: {api_key[:4]}...") return {"status": "sent", "message": message} ``` **Security Best Practice**: Always store sensitive credentials as Variables rather than hardcoding them in your action code. ### execute\_query The **`execute_query`** function runs SQL queries against your Datazone datasets and returns structured results: ```python theme={null} from datazone.actions import execute_query ``` Execute a SQL query against Datazone datasets. ```python theme={null} result = execute_query("SELECT * FROM my_dataset LIMIT 10") print(result.data) # list of row dicts print(result.status) # query status string ``` Returns a `QueryResult` object with: * **`data`** — list of row dictionaries * **`status`** — execution status string #### Example: Query and Transform ```python theme={null} from datazone.actions import action, context, execute_query @action def summarize_orders(min_amount: float = 100.0): """Return order totals above a threshold.""" context.log_info(f"Querying orders with amount >= {min_amount}") result = execute_query(f""" SELECT customer_id, SUM(amount) AS total FROM orders WHERE amount >= {min_amount} GROUP BY customer_id ORDER BY total DESC LIMIT 20 """) context.log_info(f"Found {len(result.data)} customers") return { "status": result.status, "row_count": len(result.data), "rows": result.data } ``` ### Agent The **`Agent`** class invokes an LLM through one of your [Model Accounts](/reference/development/model-accounts), without any provider SDK or API key in your code — the call is proxied by Datazone and billed against your workspace. ```python theme={null} from datazone.actions import Agent ``` Create an agent bound to a model account and model. Parameters: * **`model`** *(optional)* — model to use, e.g. `CLAUDE_45_SONNET`. Defaults to your organisation's default model. * **`model_account`** *(optional)* — model account id. Defaults to your organisation's AI settings account. * **`response_format`** *(optional)* — a Pydantic model or JSON schema dict for structured output. ```python theme={null} agent = Agent(model="CLAUDE_45_SONNET") result = agent.invoke("Summarize this in one sentence: ...") result["content"] ``` Invoke the model and return a result dictionary. Accepts either a plain string or a message list: ```python theme={null} agent.invoke("Say hi") agent.invoke({ "messages": [ {"role": "system", "content": "You are concise."}, {"role": "user", "content": "Say hi"}, ] }) ``` Message roles are **`system`**, **`user`** and **`assistant`**. Returns a dict with: * **`content`** — the raw text answer (empty when `response_format` is used) * **`structured_response`** — the parsed object when `response_format` is used, otherwise `None` * **`model`** — the model that produced the answer Raises `RuntimeError` if the invocation fails. #### Example: Summarize Text ```python theme={null} from datazone.actions import action, Agent @action def summarize(text: str): """Summarize a piece of text in one sentence.""" agent = Agent(model="CLAUDE_45_SONNET") result = agent.invoke(f"Summarize in one sentence:\n\n{text}") return {"summary": result["content"]} ``` #### Example: Structured Output Pass a **Pydantic model** as `response_format` to get a validated object back instead of raw text: ```python theme={null} from typing import Literal from pydantic import BaseModel, Field from datazone.actions import action, context, Agent class TicketTriage(BaseModel): """Triage decision for a support ticket.""" priority: Literal["low", "medium", "high"] = Field(description="Urgency of the ticket") team: str = Field(description="Team that should own it, e.g. billing, platform, data") summary: str = Field(description="One sentence summary of the problem") @action def triage_ticket(subject: str, body: str): """Classify an incoming support ticket.""" agent = Agent(model="CLAUDE_45_SONNET", response_format=TicketTriage) result = agent.invoke({ "messages": [ {"role": "system", "content": "You triage incoming support tickets. Be concise."}, {"role": "user", "content": f"Subject: {subject}\n\n{body}"}, ] }) triage = result["structured_response"] context.log_info(f"Triaged as {triage.priority} for {triage.team}") return {"priority": triage.priority, "team": triage.team, "summary": triage.summary} ``` `response_format` also accepts a plain JSON schema dict — in that case `structured_response` is returned as a dict rather than a model instance. Token usage is recorded per invocation and attributed to the action, so LLM costs show up alongside your other workspace usage. ### KnowledgeObject The **`KnowledgeObject`** client reads and writes [Knowledge Object](/reference/knowledge-objects/overview) instances from within an action. Instances are addressed by their opaque `_key`, and operations run on the action's project (main branch by default). ```python theme={null} from datazone.actions import KnowledgeObject ``` Access instances of a knowledge object by name. ```python theme={null} employees = KnowledgeObject("Employee") # main branch employees = KnowledgeObject("Employee", branch="feature-x") ``` Methods: * **`get(key, add_relationships=False)`** — fetch one instance (a `dict`) by its `_key`. * **`list(filters=None, page=1, page_size=50, fields=None)`** — iterate pages of instances (see below). * **`update(key, payload)`** — partially update an instance; returns the updated instance. * **`delete(key)`** — delete an instance by its `_key`. * **`batch_upsert(payloads)`** — insert/update up to 1000 instances in one call; returns `{"created", "updated", "total"}`. **Filtering and pagination.** `list(...)` returns an iterator of pages; each page exposes `.items` and `.total_count`. `filters` is a list of `{"column", "operator", "value"}` objects combined with **AND** (operators: `equal`, `not_equal`, `contains`, `not_contains`, `greater_than`, `less_than`). ```python theme={null} from datazone.actions import action, context, KnowledgeObject @action def deactivate_inactive_employees(): """Mark employees with no recent login as inactive.""" employees = KnowledgeObject("Employee") updated = 0 for page in employees.list( filters=[{"column": "is_active", "operator": "equal", "value": True}] ): for employee in page.items: context.log_info(f"Checking {employee['name']}") employees.update(key=employee["_key"], payload={"is_active": False}) updated += 1 return {"updated": updated} ``` #### Example: Read and upsert ```python theme={null} from datazone.actions import action, KnowledgeObject @action def sync_employee(employee_id: int, email: str): """Read one employee and upsert a batch.""" employees = KnowledgeObject("Employee") # Read a single instance by its key existing = employees.get(key="8A3F9C2E1B4D6F7A8A3F9C2E1B4D6F7A") # Insert or update many at once result = employees.batch_upsert([ {"id": employee_id, "name": "John", "email": email}, {"id": employee_id + 1, "name": "Jane", "email": "jane@acme.com"}, ]) return {"existing": existing, "upsert": result} ``` See the [Actions SDK](/reference/knowledge-objects/actions-sdk) page under Knowledge Objects for the full method reference. ### FileContainerClient **`FileContainerClient`** provides access to files stored in the Datazone file container (LakeFS/S3-compatible storage). It is **automatically initialized** as `file_client` in agent code execution environments — no import is required. `file_client` is pre-initialized in agent code execution contexts. It is **not** available inside `@action` decorated functions. Fetch raw bytes for a file from the file container. ```python theme={null} # path is relative to the file container root raw = file_client.read("reports/data.csv") ``` * **`path`** — path relative to the file container root * Returns raw `bytes` * Raises `ValueError` if the file exceeds 10 MB or cannot be fetched #### Examples: Reading Different File Types ```python theme={null} # CSV / plain text text = file_client.read("data.csv").decode("utf-8") print(text[:500]) # JSON import json config = json.loads(file_client.read("config.json")) print(config["setting"]) # Excel import io import openpyxl wb = openpyxl.load_workbook(io.BytesIO(file_client.read("report.xlsx"))) ws = wb.active for row in ws.iter_rows(values_only=True): print(row) # Agent-uploaded file raw = file_client.read(f"agent-uploads/{agent_id}/{upload_id}/{filename}") ``` ### CloudFeedClient **`CloudFeedClient`** is a simplified SAP connector for reading tables and executing function modules from within actions: ```python theme={null} from datazone.actions.clients import CloudFeedClient ``` SAP CloudFeed client for table access and function execution. Constructor parameters: * **`base_url`** — base URL of the SAP system * **`username`** — SAP username * **`password`** — SAP password * **`timeout`** *(optional)* — request timeout in seconds (default: 30) * **`max_retries`** *(optional)* — max retries on failure (default: 10) * **`backoff_factor`** *(optional)* — exponential backoff factor (default: 0.3) | Method | Description | | --------------------------------------------------------------- | ---------------------------------------------------- | | `get_table_list(filter_name, filter_desc, rows)` | List available SAP tables, supports wildcard filters | | `get_table_schema(table_name)` | Get field definitions for a table | | `preview_table(table_name, rows)` | Preview table contents | | `execute_function(obj_name, input_data, output_fields, commit)` | Execute a SAP function module | #### Example: Query SAP Sales Orders ```python theme={null} from datazone.actions import action, context, Variable from datazone.actions.clients import CloudFeedClient @action def fetch_sap_orders(table_name: str = "VBAP", preview_rows: int = 10): """Fetch sales order data from SAP.""" client = CloudFeedClient( base_url=str(Variable("SAP_BASE_URL")), username=str(Variable("SAP_USERNAME")), password=str(Variable("SAP_PASSWORD")), ) context.log_info(f"Fetching schema for {table_name}") schema = client.get_table_schema(table_name) fields = [f["FIELDNAME"] for f in schema] context.log_info(f"Previewing {preview_rows} rows") preview = client.preview_table(table_name, rows=preview_rows) return { "table": table_name, "fields": fields, "preview": preview } ``` #### Example: Execute SAP Function Module ```python theme={null} from datazone.actions import action, context, Variable from datazone.actions.clients import CloudFeedClient import json @action def create_sap_order(material: str, quantity: int, plant: str): """Create a purchase order in SAP via function module.""" with CloudFeedClient( base_url=str(Variable("SAP_BASE_URL")), username=str(Variable("SAP_USERNAME")), password=str(Variable("SAP_PASSWORD")), ) as client: input_data = json.dumps({ "MATERIAL": material, "QUANTITY": quantity, "PLANT": plant }) context.log_info(f"Creating order for {material} x{quantity} at {plant}") result = client.execute_function( obj_name="Z_CREATE_PO", input_data=input_data, commit=True ) context.log_info("Order created successfully") return {"result": result, "material": material, "quantity": quantity} ``` #### Example: Search and Inspect SAP Tables ```python theme={null} from datazone.actions import action, context, Variable from datazone.actions.clients import CloudFeedClient @action def search_sap_tables(name_filter: str = "VBAP*"): """List SAP tables matching a filter and return their schemas.""" client = CloudFeedClient( base_url=str(Variable("SAP_BASE_URL")), username=str(Variable("SAP_USERNAME")), password=str(Variable("SAP_PASSWORD")), ) tables = client.get_table_list(filter_name=name_filter, rows=20) context.log_info(f"Found {len(tables)} tables matching '{name_filter}'") result = [] for table in tables[:5]: # inspect first 5 name = table["TABNAME"] schema = client.get_table_schema(name) result.append({"table": name, "field_count": len(schema)}) return result ``` ## Configuration ### Add to config.yaml Register your actions in **`config.yaml`**: ```yaml theme={null} project_name: my-project project_id: proj_abc123 actions: - path: actions/send_email.py - path: actions/process_data.py - path: actions/generate_report.py - path: workflows/cleanup_data.py ``` ### Repository Structure Each file should contain **one `@action` decorated function**. Action function names must be **unique within your project**. ## Return Values Actions should return **structured data** (dict, list, or primitives): ```python theme={null} @action def my_action(): # Good - structured dictionary return { "status": "success", "data": [1, 2, 3], "metadata": {"count": 3} } # Good - simple values return 42 # Good - lists return [{"id": 1}, {"id": 2}] ``` ## Error Handling Actions can **raise exceptions** - they'll be captured and returned: ```python theme={null} @action def validate_input(value: int): """Validate input value.""" if value < 0: raise ValueError("Value must be positive") return {"validated": True, "value": value} ``` ## Using Actions ### 1. In Endpoints Connect actions to **API endpoints** for webhook-style triggers: ```yaml theme={null} endpoint: name: send-notification type: action config: action_id: "507f1f77bcf86cd799439011" ``` When the endpoint is called, the action **executes automatically**. Learn more in the [Endpoints documentation](/reference/integration/endpoints#action-based-endpoints). ### 2. In Agents Enable actions as **tools for AI agents**: When creating an agent: 1. Select **"Action"** in the tools section 2. Choose which actions the agent can use 3. The agent will **automatically call actions** when needed The AI agent decides **when and how** to use actions based on user questions. Learn more in the [Agents documentation](/reference/agents/overview#action-tools). ## Examples ### Slack Notification ```python theme={null} from datazone.actions import action, context import requests @action def send_slack_message(channel: str, message: str, webhook_url: str): """ Send message to Slack channel. Args: channel: Slack channel name message: Message to send webhook_url: Slack webhook URL """ context.log_info(f"Sending message to {channel}") payload = { "channel": channel, "text": message } response = requests.post(webhook_url, json=payload) if response.status_code == 200: context.log_info("Message sent successfully") return {"status": "sent", "channel": channel} else: context.log_error(f"Failed to send: {response.text}") raise Exception(f"Slack API error: {response.status_code}") ``` ### Data Validation ```python theme={null} from datazone.actions import action, context @action def validate_customer_data(customer_id: str, email: str, age: int): """ Validate customer data before processing. Args: customer_id: Customer identifier email: Customer email address age: Customer age """ errors = [] # Validate email if "@" not in email: errors.append("Invalid email format") # Validate age if age < 18 or age > 120: errors.append("Age must be between 18 and 120") if errors: context.log_error(f"Validation failed: {', '.join(errors)}") return { "valid": False, "errors": errors } context.log_info("Validation passed") return { "valid": True, "customer_id": customer_id } ``` ### API Integration ```python theme={null} from datazone.actions import action, context, Variable import requests @action def fetch_weather(city: str): """ Fetch current weather for a city. Args: city: City name """ context.log_info(f"Fetching weather for {city}") api_key = str(Variable("WEATHER_API_KEY")) url = f"https://api.weather.com/data?city={city}&key={api_key}" try: response = requests.get(url, timeout=10) response.raise_for_status() data = response.json() context.log_info("Weather data retrieved") return { "city": city, "temperature": data["temp"], "conditions": data["conditions"], "humidity": data["humidity"] } except requests.exceptions.RequestException as e: context.log_error(f"API request failed: {str(e)}") raise ``` ## Next Steps * [Create Action Endpoints](/reference/integration/endpoints#action-based-endpoints) * [Use Actions in Agents](/reference/agents/overview#action-tools) * [Manage Variables](/reference/development/variables) - Store secure credentials and configuration * [Learn About Projects](/reference/development/project) # API Keys Source: https://docs.datazone.co/reference/development/api-key API keys are used to authenticate requests to the Datazone API. You can create and manage your API keys from the Datazone dashboard. API Keys is only available for the Professional and Enterprise plans. Check the [plans](https://www.datazone.co/pricing) for more information. ## Overview api-key 1. Click **Settings** in the top right corner session context menu. 2. Click **API Keys** in the left sidebar. 3. Click **Create** to create a new API key. 4. Enter a name for the API key and click **Create**. 5. Copy the API key with `dz-xxxxxx` format and store it in a secure place. ## Usage You can use the API key to authenticate requests to the Datazone API. You can pass the API key in the `x-api-key` header. ```bash theme={null} curl -X GET "https://app.datazone.co/api/v1/dataset/list" -H "x-api-key: dz-xxxxxx" ``` # Command Line Source: https://docs.datazone.co/reference/development/command-line One of the interaction way with Datazone is using Command Line Interface. You can manage your projects, datasets, and models with Datazone CLI commands. ## Installation You can install the **Datazone Python SDK** using pip: ```bash theme={null} pip install datazone ``` Check that the installation was successful by running the following command: ```bash theme={null} datazone --version ``` ## Common Command Pattern On the Datazone CLI, generally, the command pattern is as follows: ```bash theme={null} datazone [options] ``` ## Help You can get help about the Datazone CLI commands by add `--help` flag to the command. ```bash theme={null} datazone --help datazone project --help datazone dataset list --help ``` ## Commands ### `profile` ```bash theme={null} ## Create a new profile. It will ask you some questions to create a new profile. datazone profile create ## List all profiles datazone profile list ## Delete a profile datazone profile delete ## Set default profile datazone profile set-default ``` ### `source` ```bash theme={null} ## List all sources datazone source list ## Create a new source. It will ask you some questions to create a new source. datazone source create ## Delete a source datazone source delete ``` ### `project` ```bash theme={null} ## List all projects datazone project list ## Create a new project datazone project create ## Clone a project datazone project clone ## Deploy a project datazone project deploy [--commit-message ] [--file ] ## Pull the project datazone project pull ## Show the summary of the project datazone project summary ``` ### `dataset` ```bash theme={null} ## List all datasets datazone dataset list ## Show sample data of a dataset datazone dataset show ## List all transactions of a dataset datazone dataset transactions ``` ### `pipeline` ```bash theme={null} ## Create a new pipeline datazone pipeline create ``` ### `extract` ```bash theme={null} ## Create a new extract datazone extract create ## List all extract datazone extract list ## Delete an extract datazone extract delete ## Run an execution for an extract datazone extract execute ``` ### `execution` ```bash theme={null} ## List all executions datazone execution list ## Show logs of an execution datazone execution logs ## Run an execution datazone execution run [--extract-id ] [--pipeline-id ] ``` ### `auth` ```bash theme={null} ## Test the authentication datazone auth test ``` ### `version` ```bash theme={null} ## Show the version of the Datazone CLI datazone version ``` ### `info` ```bash theme={null} ## Show the information of the current session datazone info ``` # Context Source: https://docs.datazone.co/reference/development/context Each pipeline in Datazone has a context object that provides access to resources and configuration settings. ```python theme={null} @transform def my_transform(context): context.state.write(key="my_key", value="my_value") ``` ## State The context object provides a `state` attribute that allows you to read and write key-value pairs. The state is stored in database and can be accessed in any transform function in the pipeline. Also you can access the state in the next executions of the pipeline. ```python theme={null} from datazone import transform @transform def my_transform(context): context.state.write(key="my_key", value="my_value") @transform(depends=[my_transform]) def my_transform(context): value = context.state.read(key="my_key") print(value) ``` ### State Callbacks You can write your states by various conditions like `success`, `failure`, `now`. ```python theme={null} from datazone import transform @transform def my_transform(context): context.state.write(key="my_key", value="my_value", on="success") raise Exception("Error") ``` In this example, the state will not be written because the transform function raises an exception. ## Resources ### PySpark Session You can access the PySpark session using the `pyspark` attribute of the `resources` object. ```python theme={null} from datazone import transform @transform def my_transform(context): spark = context.resources["pyspark"].spark # Use the PySpark session df = spark.createDataFrame({ "name": ["Alice", "Bob"], "age": [25, 30] }) return df ``` # File Container Source: https://docs.datazone.co/reference/development/file-container File Container is a storage solution in the Datazone platform that allows you to manage and store files. You can create, update, and delete file containers, and use them to store data for your pipelines and notebooks. file-container-cover ## Overview File Containers allows you to manage and store files. Each project has its own isolated file container. You can interact with file containers like **AWS S3 buckets** or **Google Cloud Storage buckets**. Also, Datazone provides **toolkits** to interact with file containers. You can use the `FileContainerClient` in notebooks and pipelines to interact with file containers. 1. Click **Projects** in the left sidebar. 2. Choose a project from the card list. 3. Click **File Containers** tab in the left sidebar. file-container ## Client Usage The `FileContainerClient` provides a convenient interface to interact with file containers using S3-compatible storage. It handles authentication and bucket management automatically. The `FileContainerClient` is **only available in the execution environment** (pipelines and notebooks running on Datazone). For **local development and external applications**, see the [Local Access](#local-access) section below. You can access the `FileContainerClient` in your **pipelines** and **notebooks** like this: ```python theme={null} from datazone import FileContainerClient ``` #### `list_objects` Lists the files and directories directly under a path in the file container. ```python theme={null} from datazone import FileContainerClient # List everything at the root of the file container objects = FileContainerClient.list_objects() # List the contents of a directory documents = FileContainerClient.list_objects("documents/") ``` **Parameters:** * `prefix` (str): Optional directory to list, such as `documents/`. Should end with `/`. Defaults to the file container root. **Returns:** * `list`: List of entries, each tagged with a `Type` field of either `file` or `directory`. Directory entries carry only a `Key`, file entries also carry their S3 metadata. Example: ``` [ { 'Key': 'documents/', 'Type': 'directory' }, { 'Key': 'customer_list.csv', 'Type': 'file', 'LastModified': datetime.datetime(2025, 7, 24, 19, 44, 12, 475000, tzinfo=tzlocal()), 'ETag': '"bf36dc829c4229254b7df3c428d0a349"', 'Size': 18311622, 'StorageClass': 'STANDARD' } ] ``` The listing is **one level deep**, like `ls`. It does not descend into subdirectories — pass a directory's `Key` back as the `prefix` to list what is inside it. To walk the whole tree, recurse into every directory you get back: ```python theme={null} from datazone import FileContainerClient def walk_file_container(prefix: str = ""): for entry in FileContainerClient.list_objects(prefix): if entry["Type"] == "directory": yield from walk_file_container(entry["Key"]) else: yield entry for file in walk_file_container(): print(file["Key"], file["Size"]) ``` #### `get_object` Retrieves an object from the file container by its key. ```python theme={null} # Get a file's content file_data = FileContainerClient.get_object("data/sample.csv") # Convert bytes to string for text files content = file_data.decode('utf-8') ``` **Parameters:** * `key` (str): The key/path of the object to retrieve **Returns:** * `bytes`: The object's raw data Objects are stored as bytes, so you may need to encode/decode text data appropriately #### `put_object` Stores data in the file container at the specified key. ```python theme={null} # Store text data text_data = "Hello, World!".encode('utf-8') FileContainerClient.put_object("messages/hello.txt", text_data) # Store binary data with open("local_file.pdf", "rb") as f: file_data = f.read() FileContainerClient.put_object("documents/file.pdf", file_data) ``` **Parameters:** * `key` (str): The key/path where the object will be stored * `data` (bytes): The data to store #### `delete_object` Removes an object from the file container. ```python theme={null} # Delete a specific file FileContainerClient.delete_object("temp/old_file.txt") ``` **Parameters:** * `key` (str): The key/path of the object to delete ## Examples ### Periodically Uploading Files in a Pipeline You can use the FileContainerClient to periodically upload files to your file container. This can be useful for tasks like logging, data collection, or backups. ```python theme={null} from datazone import transform, FileContainerClient import requests from datetime import datetime import io @transform def fetch_and_store_llm_data(): # URL to fetch the data from url = "https://docs.datazone.co/llms-full.txt" # Get the current timestamp in ISO format timestamp_as_iso = datetime.now().isoformat() # Fetch the data from the URL response = requests.get(url) # Check if the request was successful if response.status_code == 200: # Get the content content = response.text # Store the content in the file system FileContainerClient.put_object(f"daily_llm/{timestamp_as_iso}/llm.txt", io.BytesIO(content.encode('utf-8'))) return f"Successfully stored LLM data with timestamp {timestamp_as_iso}" else: raise Exception(f"Failed to fetch data: HTTP {response.status_code}") ``` ### Read a Parquet File in a Notebook ```python theme={null} import io import pandas as pd from datazone import FileContainerClient # Read a Parquet file from the file container data = FileContainerClient.get_object("datasets/sample.parquet") # Convert bytes to a Pandas DataFrame df = pd.read_parquet(io.BytesIO(data)) ``` ## Local Access For **local development** and **external applications**, you can access File Containers using **S3-compatible tools** and SDKs. This requires **Access Keys** for authentication. ### Prerequisites Before connecting locally, you need: 1. **Access Keys** - Create from your project settings ([Learn how](/reference/development/access-keys)) 2. **Endpoint URL** - Your Datazone instance URL (e.g., `your-instance.datazone.co:3333`) 3. **Project Path** - Format: `{project-name}/main/file-container/` ### AWS CLI #### Install AWS CLI ```bash theme={null} # macOS brew install awscli # Linux curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" unzip awscliv2.zip sudo ./aws/install # Windows msiexec.exe /i https://awscli.amazonaws.com/AWSCLIV2.msi ``` #### Configure Credentials Set your **access keys** as environment variables: ```bash theme={null} export AWS_ACCESS_KEY_ID="your-access-key-id" export AWS_SECRET_ACCESS_KEY="your-secret-access-key" ``` #### List Files ```bash theme={null} aws s3 ls --endpoint-url https://your-instance.datazone.co:3333 \ your-project-bucket/main/file-container/ ``` #### Upload a File ```bash theme={null} aws s3 cp local-file.txt \ --endpoint-url https://your-instance.datazone.co:3333 \ s3://your-project-bucket/main/file-container/local-file.txt ``` #### Download a File ```bash theme={null} aws s3 cp --endpoint-url https://your-instance.datazone.co:3333 \ s3://your-project-bucket/main/file-container/remote-file.txt \ local-file.txt ``` #### Sync Directory ```bash theme={null} # Upload entire directory aws s3 sync ./local-folder \ --endpoint-url https://your-instance.datazone.co:3333 \ s3://your-project-bucket/main/file-container/remote-folder/ # Download entire directory aws s3 sync --endpoint-url https://your-instance.datazone.co:3333 \ s3://your-project-bucket/main/file-container/remote-folder/ \ ./local-folder ``` ### Python (boto3) #### Install boto3 ```bash theme={null} pip install boto3 ``` #### Configure S3 Client ```python theme={null} import boto3 s3_client = boto3.client( 's3', endpoint_url='https://your-instance.datazone.co:3333', aws_access_key_id='your-access-key-id', aws_secret_access_key='your-secret-access-key' ) bucket_name = 'your-project-bucket' prefix = 'main/file-container/' ``` #### List Files ```python theme={null} response = s3_client.list_objects_v2( Bucket=bucket_name, Prefix=prefix ) for obj in response.get('Contents', []): print(obj['Key']) ``` #### Upload a File ```python theme={null} s3_client.upload_file( 'local-file.txt', bucket_name, f'{prefix}local-file.txt' ) print('File uploaded successfully') ``` #### Download a File ```python theme={null} s3_client.download_file( bucket_name, f'{prefix}remote-file.txt', 'local-file.txt' ) print('File downloaded successfully') ``` #### Upload with Metadata ```python theme={null} s3_client.upload_file( 'data.csv', bucket_name, f'{prefix}data.csv', ExtraArgs={ 'Metadata': { 'source': 'analytics', 'date': '2026-01-20' } } ) ``` ### JavaScript (AWS SDK) #### Install AWS SDK ```bash theme={null} npm install aws-sdk ``` #### Configure S3 Client ```javascript theme={null} const AWS = require('aws-sdk'); const s3 = new AWS.S3({ endpoint: 'https://your-instance.datazone.co:3333', accessKeyId: 'your-access-key-id', secretAccessKey: 'your-secret-access-key', s3ForcePathStyle: true, signatureVersion: 'v4' }); const bucketName = 'your-project-bucket'; const prefix = 'main/file-container/'; ``` #### List Files ```javascript theme={null} s3.listObjectsV2({ Bucket: bucketName, Prefix: prefix }, (err, data) => { if (err) console.error(err); else { data.Contents.forEach(obj => { console.log(obj.Key); }); } }); ``` #### Upload a File ```javascript theme={null} const fs = require('fs'); const fileContent = fs.readFileSync('local-file.txt'); s3.putObject({ Bucket: bucketName, Key: `${prefix}local-file.txt`, Body: fileContent }, (err, data) => { if (err) console.error(err); else console.log('File uploaded successfully'); }); ``` #### Download a File ```javascript theme={null} s3.getObject({ Bucket: bucketName, Key: `${prefix}remote-file.txt` }, (err, data) => { if (err) console.error(err); else { fs.writeFileSync('local-file.txt', data.Body); console.log('File downloaded successfully'); } }); ``` ### Java (AWS SDK) #### Add Dependency ```xml theme={null} com.amazonaws aws-java-sdk-s3 1.12.400 ``` #### Configure S3 Client ```java theme={null} import com.amazonaws.auth.AWSStaticCredentialsProvider; import com.amazonaws.auth.BasicAWSCredentials; import com.amazonaws.client.builder.AwsClientBuilder; import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.AmazonS3ClientBuilder; import com.amazonaws.services.s3.model.*; import java.io.File; BasicAWSCredentials credentials = new BasicAWSCredentials( "your-access-key-id", "your-secret-access-key" ); AmazonS3 s3Client = AmazonS3ClientBuilder.standard() .withEndpointConfiguration( new AwsClientBuilder.EndpointConfiguration( "https://your-instance.datazone.co:3333", "us-east-1" ) ) .withCredentials(new AWSStaticCredentialsProvider(credentials)) .withPathStyleAccessEnabled(true) .build(); String bucketName = "your-project-bucket"; String prefix = "main/file-container/"; ``` #### List Files ```java theme={null} ListObjectsV2Request listRequest = new ListObjectsV2Request() .withBucketName(bucketName) .withPrefix(prefix); ListObjectsV2Result result = s3Client.listObjectsV2(listRequest); for (S3ObjectSummary objectSummary : result.getObjectSummaries()) { System.out.println(objectSummary.getKey()); } ``` #### Upload a File ```java theme={null} File file = new File("local-file.txt"); s3Client.putObject( bucketName, prefix + "local-file.txt", file ); System.out.println("File uploaded successfully"); ``` #### Download a File ```java theme={null} S3Object s3Object = s3Client.getObject( bucketName, prefix + "remote-file.txt" ); S3ObjectInputStream inputStream = s3Object.getObjectContent(); // Save to file or process the input stream System.out.println("File downloaded successfully"); ``` ## Common Operations ### Check if File Exists **Python:** ```python theme={null} try: s3_client.head_object(Bucket=bucket_name, Key=f'{prefix}file.txt') print('File exists') except: print('File does not exist') ``` ### Delete a File **AWS CLI:** ```bash theme={null} aws s3 rm --endpoint-url https://your-instance.datazone.co:3333 \ s3://your-project-bucket/main/file-container/file.txt ``` **Python:** ```python theme={null} s3_client.delete_object( Bucket=bucket_name, Key=f'{prefix}file.txt' ) ``` ### Get File Metadata **Python:** ```python theme={null} response = s3_client.head_object( Bucket=bucket_name, Key=f'{prefix}file.txt' ) print(f"Size: {response['ContentLength']} bytes") print(f"Last Modified: {response['LastModified']}") ``` ## Best Practices 1. **Use Environment Variables** - Never hardcode credentials in code 2. **Handle Errors** - Always wrap operations in try-catch blocks 3. **Stream Large Files** - Use streaming uploads/downloads for large files 4. **Set Timeouts** - Configure appropriate timeouts for your use case 5. **Clean Up** - Delete temporary files after processing 6. **Monitor Usage** - Track file operations for cost management ## Next Steps * [Create Access Keys](/reference/development/access-keys) * [AWS S3 CLI Reference](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3/index.html) * [boto3 Documentation](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html) # Model Accounts Source: https://docs.datazone.co/reference/development/model-accounts Configure and manage AI model provider credentials for building intelligent applications with Datazone ## Overview Model Accounts allow you to securely store and manage API credentials for AI model providers like OpenAI, Anthropic (Claude), and AWS Bedrock. Once configured, these credentials can be used across your Datazone projects to build intelligent applications, data pipelines with AI capabilities, and automated workflows. Model Accounts Dashboard ## Supported Providers Datazone supports the following AI model providers: | Provider | Description | Required Credentials | | --------------- | ------------------------------------------------- | -------------------------------------------- | | **OpenAI** | Access to GPT models (GPT-4, GPT-3.5, etc.) | API Key | | **Anthropic** | Access to Claude models (Claude 3.5 Sonnet, etc.) | API Key | | **AWS Bedrock** | Access to multiple models via AWS Bedrock service | AWS Access Key ID, Secret Access Key, Region | ## Creating a Model Account 1. Click **Settings** in the top right corner session context menu. 2. Click **Model Accounts** in the left sidebar. 3. Click **Create Model Account** to add a new provider. Create Model Account 4. Enter a descriptive name for your model account (e.g., "Production OpenAI", "Development Claude"). 5. Select your AI provider from the dropdown. 6. Enter the required credentials based on the provider: Configure Provider Credentials ### OpenAI Configuration * **API Key** (required): Your OpenAI API key starting with `sk-` * **API Base** (optional): Custom API endpoint if using a proxy or Azure OpenAI ### Anthropic Configuration * **API Key** (required): Your Anthropic API key starting with `sk-ant-` * **API Base** (optional): Custom API endpoint if needed ### AWS Bedrock Configuration * **AWS Access Key ID** (required): Your AWS access key * **AWS Secret Access Key** (required): Your AWS secret access key * **AWS Region** (required): The AWS region for Bedrock (e.g., `us-east-1`, `us-west-2`) * **AWS Session Token** (optional): Temporary session token if using STS 7. Click **Create** to save your model account. ## Security Datazone takes security seriously when handling your AI provider credentials: * **Encrypted Storage**: All API keys and sensitive credentials are encrypted at rest using industry-standard encryption. * **Access Control**: Only organization members with MANAGE permissions can view or modify model accounts. * **Organization Isolation**: Model accounts are scoped to your organization and cannot be accessed by other organizations. Never share your API keys or credentials publicly. Each model account is tied to your organization, so treat credentials with the same care as database passwords. ## Managing Model Accounts ### Viewing Model Accounts All your configured model accounts are listed in the Model Accounts page. Each entry shows: * Account name * Provider type * Creation date * Last updated date ### Updating Credentials To update a model account: 1. Click on the account you want to update. 2. Modify the account name or credentials as needed. 3. Click **Update** to save changes. Updating credentials will affect all projects and pipelines currently using this model account. Ensure the new credentials are valid before saving. ### Deleting Model Accounts To delete a model account: 1. Click on the account you want to remove. 2. Click the **Delete** button. 3. Confirm the deletion. Deleting a model account is permanent. Any projects or pipelines using this account will fail until reconfigured with a different model account. ## Next Steps * [Build Intelligent Apps](/reference/intelligent-apps/overview) powered by AI * [Create Data Pipelines](/reference/development/pipeline) with AI transformations * [Manage Variables](/reference/development/variables) to reference model accounts in projects # Pipeline Source: https://docs.datazone.co/reference/development/pipeline Define data processing steps using transforms and dependencies to build workflows ```python theme={null} from datazone import transform @transform def say_hello(): print("Hello, World!") @transform(depends=[say_hello]) def say_goodbye(): print("Goodbye, World!") ``` * Each pipeline should have a **unique alias** and should be defined in the different files. * A pipeline should have at least one transform function. * You can define dependencies between pipelines using the `depends` or `input_mapping` parameter to create a directed acyclic graph (DAG). ### Complex Pipeline Example ```python theme={null} from datazone import transform @transform def prepare(): print("Preparing data...") @transform(depends=[prepare]) def build_project(): print("Building project...") @transform(depends=[prepare]) def build_report(): print("Building report...") @transform(depends=[build_project, build_report]) def notify_email(): print("Sending email notification...") ``` ```mermaid theme={null} graph LR; prepare-->build_project; prepare-->build_report; build_project-->notify_email; build_report-->notify_email; ``` ### Data Flow Management The `@transform` decorator enables you to define data transformation functions efficiently. Each function should: * Accept input data as arguments * Process the data * Return the transformed data Data is handled as PySpark DataFrames both for input and output operations. ```python theme={null} from datazone import transform @transform(input_mapping={'data': Input(Dataset(alias='input_data')}) def clean_data(data): return data.filter(data['column'] > 0) @transform(input_mapping={'clean_data': Input(clean_data)}, materialized=True) def aggregate_data(clean_data): return clean_data.groupBy('column').agg({'column': 'sum'}) ``` In above example, 1. `clean_data` function takes `input_data` as input. You can check the dataset alias in the Datazone UI or use the `datazone dataset list` command to list all datasets. 2. After cleaning the data, the `clean_data` function returns the cleaned data PySpark DataFrame as lazy evaluation. 3. The `aggregate_data` function takes the cleaned data as input and aggregates it and returns the aggregated data. 4. Since the `materialized` parameter is set to `True`, the `aggregate_data` function will be materialized and create a new dataset in Datazone. Check the [Transform](/reference/development/transform) section for more information on how to define a transform decorator. ### Invoking LLM Models Transforms can call an LLM through one of your [Model Accounts](/reference/development/model-accounts) with the **`Agent`** class — no provider SDK or API key in your pipeline code. The call is proxied by Datazone and its token usage is attributed to the pipeline. ```python theme={null} import pandas as pd from datazone import transform, Agent, logger TEXT = """ Datazone connects data sources to a lakehouse and provides tools for transformation, orchestration and exploration. """ @transform(materialized=True, engine="pandas") def summarize_text(): agent = Agent(model="CLAUDE_45_SONNET") summary = agent.invoke(f"Summarize this in one sentence:\n\n{TEXT}")["content"] logger.info(f"Summary: {summary}") return pd.DataFrame([{"text": TEXT.strip(), "summary": summary}]) ``` Create an agent bound to a model account and model. Parameters: * **`model`** *(optional)* — model to use, e.g. `CLAUDE_45_SONNET`. Defaults to your organisation's default model. * **`model_account`** *(optional)* — model account id. Defaults to your organisation's AI settings account. * **`response_format`** *(optional)* — a Pydantic model or JSON schema dict for structured output. Invoke the model and return a result dictionary. Accepts either a plain string or a message list: ```python theme={null} agent.invoke("Say hi") agent.invoke({ "messages": [ {"role": "system", "content": "You are concise."}, {"role": "user", "content": "Say hi"}, ] }) ``` Message roles are **`system`**, **`user`** and **`assistant`**. Returns a dict with: * **`content`** — the raw text answer (empty when `response_format` is used) * **`structured_response`** — the parsed object when `response_format` is used, otherwise `None` * **`model`** — the model that produced the answer Raises `RuntimeError` if the invocation fails. #### Structured Output Pass a **Pydantic model** as `response_format` to get a validated object back instead of raw text: ```python theme={null} from typing import Literal import pandas as pd from pydantic import BaseModel, Field from datazone import Dataset, Input, Output, transform, Agent reviews = Dataset(alias="product_reviews") class ProductReview(BaseModel): """Analysis of a product review.""" rating: int | None = Field(description="The rating of the product", ge=1, le=5) sentiment: Literal["positive", "negative"] = Field(description="The sentiment of the review") key_points: list[str] = Field(description="Key points of the review, 1-3 words each") @transform( input_mapping={"data": Input(reviews)}, output_mapping={"result": Output(materialized=True)}, engine="pandas", ) def analyze_reviews(data): agent = Agent(model="CLAUDE_45_SONNET", response_format=ProductReview) rows = [] for comment in data["comment"]: analysis = agent.invoke(f"Analyze this review: '{comment}'")["structured_response"] rows.append({ "comment": comment, "rating": analysis.rating, "sentiment": analysis.sentiment, "key_points": ", ".join(analysis.key_points), }) return pd.DataFrame(rows) ``` Each `invoke` is one request, so a row-by-row loop over a large dataset is slow and costly. Filter the input first, or batch several records into a single prompt and ask for a list back. ### Transform Selection When executing a pipeline, you can selectively run specific transforms using the `transform_selection` parameter in the "Run with Config" modal. This allows you to execute only the transforms you need, along with their dependencies if required. #### Selection Patterns | Pattern | Description | | ------------------- | -------------------------------------------------------------- | | `some_transform` | Select the transform only | | `*some_transform` | Select transform and all ancestors (upstream dependencies) | | `some_transform*` | Select transform and all descendants (downstream dependencies) | | `*some_transform*` | Select transform with all ancestors and descendants | | `+some_transform` | Select transform and its direct parents | | `some_transform+` | Select transform and direct children | | `some_transform++` | Select transform and 2 levels of children | | `some_transform+++` | Select transform and 3 levels of children | Use transform selection to optimize execution time by running only the necessary parts of your pipeline during development and testing. #### Usage Examples For the pipeline example above with `prepare`, `build_project`, `build_report`, and `notify_email`: * `build_project` - Runs only the `build_project` transform * `*build_project` - Runs `prepare` and `build_project` (transform with all ancestors) * `prepare*` - Runs `prepare`, `build_project`, and `build_report` (transform with all descendants) * `*notify_email*` - Runs the entire pipeline (transform with all ancestors and descendants) # Policy Source: https://docs.datazone.co/reference/development/policy Role-based access control with hierarchical permissions for fine-grained authorization Policy Cover Datazone's policy system provides flexible, fine-grained access control through role-based permissions. Policies define what actions users can perform on resources, supporting both flat and hierarchical resource patterns with explicit allow/deny rules. ### Key Features * **Role-based**: Policies are bound to roles, not individual users * **Hierarchical**: Support for project-scoped resources (e.g., `project::dataset:*`) * **Explicit deny**: Deny statements override allow statements * **Extra constraints**: Resource-specific restrictions (row-level security, column filtering, path prefixes) * **Wildcard support**: Use `*` for flexible matching across resources and actions * **Branch-aware**: Optional branch specification for version control Policy Diagram ## Policy Structure A policy is a **list of statements** that define access rules: ```json theme={null} [ { "resource": "", "branch": "", "actions": [""], "effect": "allow" | "deny", "extra_constraints": { "": "" } } ] ``` ### Fields | Field | Type | Description | | ------------------- | -------------- | --------------------------------------------------------------- | | `resource` | string | Resource pattern (supports wildcards and hierarchical patterns) | | `branch` | string \| null | Optional branch name (defaults to `main`) | | `actions` | array | List of actions in `:` format | | `effect` | enum | Either `"allow"` or `"deny"` | | `extra_constraints` | object | Resource-specific constraints (optional) | ## Resource Patterns Resources follow a hierarchical pattern that supports various levels of specificity: ### Flat Resources | Pattern | Scope | Description | | -------------- | ------------- | -------------------------------------- | | `*` | All | All resources in the organization | | `dataset` | Type | Dataset type (for creation permission) | | `dataset:*` | All instances | All dataset instances | | `dataset:` | Specific | A specific dataset by ID | ### Hierarchical Resources Hierarchical patterns enable project-scoped permissions: | Pattern | Scope | Description | | --------------------------- | -------------- | ----------------------------------- | | `project::*` | All children | All entities within the project | | `project::dataset:*` | Typed children | All datasets within the project | | `project::dataset:` | Specific child | Specific dataset within the project | ### Supported Resource Types * `dataset` - Data tables in the lakehouse * `project` - Project containers * `view` - Virtual views over datasets * `schedule` - Automated execution schedules * `extract` - Data ingestion jobs * `compute` - Compute resources * `api_key` - API authentication keys * `user` - User accounts * `role` - User roles * `notebook` - Interactive analysis notebooks * `pipeline` - Data transformation pipelines * `endpoint` - REST API endpoints * `intelligent_app` - Dashboard applications * `variable` - Environment variables * `agent` - AI agents * `action` - Executable actions * `organisation` - Organisation-level administration * `orion` - Orion logs * `source` - Data source connections * `notification` - Notification channels and settings * `tag` - Resource tags ## Actions Actions follow the `:` format and define what operations can be performed: ### Action Patterns * `dataset:read` - Read access to datasets * `dataset:write` - Modify datasets * `dataset:delete` - Delete datasets * `dataset:execute` - Execute operations on datasets * `dataset:manage` - Full management access * `dataset:create` - Create new datasets * `dataset:*` - All dataset actions * `*:read` - Read access to all resources * `*:*` - All actions on all resources ### Common Actions | Action | Description | | -------------------- | --------------------------------- | | `:read` | View the resource | | `:write` | Modify the resource | | `:delete` | Delete the resource | | `:create` | Create new instances | | `:execute` | Execute operations | | `:manage` | Full control (includes all above) | | `:*` | All actions for that resource | ### Exceptional Actions Some resources support custom actions beyond the standard CRUD operations: * `project:read_repository` - Read access to project code repository * `project:write_repository` - Write access to project code repository (push commits, merge pull requests) * `project:pr_create` - Permission to open a pull request targeting a branch * `project:deploy` - Permission to deploy a project * `endpoint:invoke` - Permission to call an API endpoint * `agent:ask` - Permission to ask (query) an AI agent ## Manage Permissions and Settings Access Some parts of the application — mainly the **Settings** area — are gated by the `manage` action rather than by `read`. A user who holds `:manage` sees that resource's menu in Settings and can view its entries. `manage` grants **visibility only**. It does not imply creating, editing, or deleting — grant `:create`, `:write`, or `:delete` alongside it for those operations. Previously these areas were visible only to users with `organisation:manage`. Now each resource can be delegated independently, so you can grant access to a single Settings menu without handing over organisation-wide administration. ### Resources that support `manage` | Resource | Action | Grants access to | | -------------- | --------------------- | ---------------------------------------------------------------------------------- | | `organisation` | `organisation:manage` | Organisation-wide administration (users, roles, all Settings menus) | | `orion` | `orion:manage` | Orion logs | | `source` | `source:manage` | Source menu in Settings | | `api_key` | `api_key:manage` | API Keys menu in Settings (keys are user-owned, so this also covers creating them) | | `notification` | `notification:manage` | Notification settings and channels | | `compute` | `compute:manage` | Compute resource configuration | | `variable` | `variable:manage` | Variable management | | `tag` | `tag:manage` | Tag management | ### Example: access to API keys and sources This policy reveals the **API Keys** and **Source** menus in Settings without granting any other organisation administration: ```json theme={null} [ { "resource": "api_key", "actions": ["api_key:manage"], "effect": "allow" }, { "resource": "source", "actions": ["source:manage"], "effect": "allow" } ] ``` The user can open both menus and see their contents. All other Settings menus stay hidden. Because API keys belong to the user who owns them, `api_key:manage` is enough to create and revoke their own keys. Sources are shared organisation resources, so this policy does **not** let them create or delete a source. ### Example: adding source create permission To let the same role also create sources, add `source:create` on the resource type: ```json theme={null} [ { "resource": "api_key", "actions": ["api_key:manage"], "effect": "allow" }, { "resource": "source", "actions": ["source:manage", "source:create"], "effect": "allow" } ] ``` Deleting or editing existing sources requires `source:delete` and `source:write` on the instances (for example `source:*`). `organisation:manage` still implies access to every Settings menu. Use the per-resource `manage` actions when you want to delegate one area only. ## Row-Level and Column-Level Security Datazone supports fine-grained data access control through row-level and column-level restrictions using the `extra_constraints` field. This enables you to restrict what data users can see within a dataset or view, beyond just granting or denying access to the entire resource. ### Extra Constraints Structure For datasets and views, you can specify columnar constraints: ```json theme={null} { "resource": "dataset:", "actions": ["dataset:read"], "effect": "allow", "extra_constraints": { "row_level_restrictions": [""], "column_level_restrictions": [""] } } ``` ### Fields | Field | Type | Description | | --------------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------ | | `row_level_restrictions` | array of strings | SQL WHERE conditions to filter rows - only matching rows are accessible (e.g., `["region = 'US'", "status = 'active'"]`) | | `column_level_restrictions` | array of strings | Column names to allow - only these columns are accessible (e.g., `["id", "name", "email"]`) | ### Row-Level Restrictions Row-level restrictions apply SQL conditions to filter which rows a user can access: ```json theme={null} { "resource": "dataset:507f1f77bcf86cd799439011", "actions": ["dataset:read"], "effect": "allow", "extra_constraints": { "row_level_restrictions": ["country = 'USA'", "department = 'Sales'"] } } ``` When a user queries this dataset, these conditions are automatically appended to the WHERE clause: ```sql theme={null} SELECT * FROM dataset WHERE (country = 'USA') AND (department = 'Sales') ``` ### Column-Level Restrictions Column-level restrictions specify which columns users can access (allowlist): ```json theme={null} { "resource": "view:507f1f77bcf86cd799439012", "actions": ["view:read"], "effect": "allow", "extra_constraints": { "column_level_restrictions": ["id", "name", "email", "department"] } } ``` Only the specified columns will be accessible in query results. All other columns will be filtered out automatically. ### Combined Restrictions You can use both row and column restrictions together: ```json theme={null} { "resource": "dataset:507f1f77bcf86cd799439011", "actions": ["dataset:read"], "effect": "allow", "extra_constraints": { "row_level_restrictions": ["region = 'EMEA'"], "column_level_restrictions": ["id", "name", "region", "department"] } } ``` **Important Restrictions for Row/Column-Level Security:** When using `extra_constraints` with `row_level_restrictions` or `column_level_restrictions`: 1. **Must target a specific resource**: Use `dataset:` or `view:`, not wildcards like `dataset:*` 2. **Read-only actions**: Only `dataset:read` or `view:read` actions are allowed 3. **Single action**: Statement must contain exactly one action 4. **Single resource**: Statement must target exactly one dataset or view Invalid examples: * ❌ `"resource": "dataset:*"` (wildcard not allowed) * ❌ `"actions": ["dataset:read", "dataset:write"]` (multiple actions) * ❌ `"actions": ["dataset:*"]` (wildcard action not allowed) * ❌ `"actions": ["dataset:write"]` (write action not allowed) Valid example: * ✅ `"resource": "dataset:507f1f77bcf86cd799439011"` with `"actions": ["dataset:read"]` ## Policy Examples ### Read-Only Access Grant read access to all resources: ```json theme={null} [ { "resource": "*", "actions": ["*:read"], "effect": "allow" } ] ``` ### Dataset Admin Full control over all datasets: ```json theme={null} [ { "resource": "dataset", "actions": ["dataset:create"], "effect": "allow" }, { "resource": "dataset:*", "actions": ["dataset:*"], "effect": "allow" } ] ``` ### Project Admin Full control over a specific project and all its resources: ```json theme={null} [ { "resource": "project:66be5fc75158d037e9970c6d", "actions": ["project:*"], "effect": "allow" }, { "resource": "project:66be5fc75158d037e9970c6d:*", "actions": ["*:*"], "effect": "allow" } ] ``` This allows the user to: * Manage the project itself (`project:*`) * Create and manage all child resources (datasets, notebooks, pipelines, etc.) ### Restricted Access with Deny Allow read access to all datasets except one specific dataset: ```json theme={null} [ { "resource": "dataset:*", "actions": ["dataset:read"], "effect": "allow" }, { "resource": "dataset:507f1f77bcf86cd799439011", "actions": ["dataset:read"], "effect": "deny" } ] ``` Deny statements always override allow statements, regardless of order. ### Project-Scoped Dataset Access Grant access to datasets within a specific project only: ```json theme={null} [ { "resource": "project:66be5fc75158d037e9970c6d:dataset:*", "actions": ["dataset:read", "dataset:write"], "effect": "allow" } ] ``` ### Branch Protection Repository permissions can be scoped to a branch with the `branch` field. Combined with the separation between `project:write_repository` (pushing commits and merging pull requests) and `project:pr_create` (opening a pull request), this lets you protect a branch such as `main` while keeping the rest of the project fully editable. ```json theme={null} [ { "effect": "allow", "actions": ["project:*"], "resource": "project:6a2ac2b4b45557181b0ecf04" }, { "effect": "allow", "actions": ["*:*"], "resource": "project:6a2ac2b4b45557181b0ecf04:*" }, { "effect": "deny", "actions": ["project:write_repository"], "resource": "project:6a2ac2b4b45557181b0ecf04", "branch": "main" } ] ``` How this evaluates: | Operation | Result | Why | | ------------------------------------ | ------- | ---------------------------------------------------------- | | Push a commit to a feature branch | Allowed | The deny only applies to `main` | | Push a commit directly to `main` | Denied | `project:write_repository` is denied on `main` | | Create a branch from `main` | Allowed | Branch creation writes a new ref, not `main` itself | | Open a pull request targeting `main` | Allowed | `project:pr_create` on `main` still comes from `project:*` | | Merge a pull request into `main` | Denied | Merging requires `project:write_repository` on `main` | The result is a familiar protected-branch workflow: contributors work on feature branches and open pull requests into `main`, but nobody with this policy can push or merge into `main` directly. Grant merge rights to a separate reviewer role that is not denied `project:write_repository` on `main`. `project:pr_create` is checked against the **base** branch of the pull request — the branch being merged into. To block pull requests into `main` entirely, add `project:pr_create` to the deny statement's actions. ### Data Analyst Role Typical permissions for a data analyst: ```json theme={null} [ { "resource": "dataset:*", "actions": ["dataset:read"], "effect": "allow" }, { "resource": "notebook", "actions": ["notebook:create"], "effect": "allow" }, { "resource": "notebook:*", "actions": ["notebook:*"], "effect": "allow" }, { "resource": "view:*", "actions": ["view:read"], "effect": "allow" } ] ``` ## Built-in Policies Datazone provides several built-in policies for common use cases: ### Admin Policy Full access to all resources: ```json theme={null} [ { "resource": "*", "actions": ["*:*"], "effect": "allow" } ] ``` ## Best Practices ### Policy Design 1. **Start restrictive**: Begin with minimal permissions and add as needed 2. **Use hierarchical patterns**: Organize permissions by project for better management 3. **Leverage deny sparingly**: Use deny for exceptions to broad allow rules 4. **Document policies**: Add clear descriptions to explain policy intent ### Role Assignment 1. **Bind to roles only**: Policies are assigned to roles, not individual users 2. **Create role hierarchies**: Use multiple roles for different permission levels (Viewer, Editor, Admin) 3. **Audit regularly**: Review policy assignments periodically ### Performance 1. **Cache aware**: Policies are cached; changes may take a few seconds to propagate 2. **Granular resources**: Use specific resource IDs when possible to reduce evaluation complexity 3. **Minimize deny statements**: They require checking all policies ### Security 1. **Principle of least privilege**: Grant only necessary permissions 2. **Explicit denies**: Use deny statements to override broad allows for sensitive resources 3. **Extra constraints**: Apply row-level and column-level security for sensitive data 4. **Path restrictions**: Use `path_prefix` constraints to sandbox project access ## Validation Rules Policies are validated automatically to ensure correctness: ### Action Format * Must follow `:` pattern * Both parts must be lowercase with underscores * Wildcards allowed: `*:*`, `dataset:*`, `*:read` **Valid:** * `dataset:read` * `project:*` * `*:*` **Invalid:** * `dataset` (missing action) * `Dataset:Read` (uppercase) * `read` (missing resource) ### Resource Pattern * Must be valid resource type or wildcard * ObjectIds must be valid MongoDB ObjectIds * Hierarchical patterns must follow `parent::child` format **Valid:** * `dataset:*` * `project:507f1f77bcf86cd799439011` * `project:507f1f77bcf86cd799439011:dataset:*` **Invalid:** * `dataset:invalid-id` * `project::dataset:*` ### Action-Resource Matching Actions must match the resource type they're applied to: ```json theme={null} { "resource": "dataset:*", "actions": ["dataset:read"], // ✓ Valid "effect": "allow" } ``` ```json theme={null} { "resource": "dataset:*", "actions": ["project:read"], // ✗ Invalid - mismatched types "effect": "allow" } ``` Exception: Wildcard actions (`*:*`) can be used on any resource. ## Troubleshooting ### Permission Denied Errors If you encounter permission denied errors: 1. **Check user roles**: Verify the user has the appropriate role assigned 2. **Review policy statements**: Ensure the policy includes the required action and resource 3. **Look for deny statements**: Check if an explicit deny is overriding an allow 4. **Verify resource IDs**: Ensure you're using the correct resource identifier 5. **Check cache**: Wait a few seconds for policy changes to propagate ### Hierarchical Permissions Not Working If project-scoped permissions aren't working: 1. **Verify pattern format**: Use `project::*` not `project:*:` 2. **Check parent context**: Ensure the resource creation includes project reference 3. **Review cache**: Hierarchical relationships are cached; wait 5 minutes or invalidate cache 4. **Validate ObjectIds**: All IDs must be valid MongoDB ObjectIds ### Performance Issues If policy evaluation is slow: 1. **Reduce policy complexity**: Simplify nested hierarchies 2. **Use specific resources**: Prefer `dataset:` over broad wildcards when possible 3. **Monitor cache health**: Ensure Redis is functioning properly 4. **Check database queries**: Hierarchical policies should use cache, not database ## Related Resources Learn about role management and user assignment Understand authentication and token management Generate and manage API keys for programmatic access Organize resources within projects # Project Repository Source: https://docs.datazone.co/reference/development/project Organize and deploy your pipelines, actions, apps, and endpoints in a single project structure. ## Overview A Datazone project is a **Git repository** containing your data pipelines, actions, apps, knowledge objects, flows, and endpoints. All project components are defined in a central **`config.yml`** file. ## Project Structure * Each project **must have** a `config.yml` file * Each pipeline should have a **unique alias** and be defined in separate files * Aliases must be unique within `pipelines` and within `studio_apps` * Unknown keys are **rejected** on deploy rather than ignored, so a typo fails loudly * You can organize your code with utility files for shared logic ## Configuration File The `config.yml` file defines all project resources: ```yaml config.yml theme={null} project_name: my-pretty-project project_id: 67280ba2f4a0960d02159675 pipelines: - alias: hello_world path: pipelines/hello_world.py compute: LARGE spark_config: deploy_mode: client executor_instances: 3 python_dependencies: - name: pandas version: 1.3.3 actions: - path: actions/send_notification.py apps: - path: apps/my_app.py objects: - path: objects/order.yml flows: - path: flows/daily_report.yml studio_apps: - alias: orders name: Orders path: studio/orders endpoints: - path: endpoints/api_config.yml ``` ## Configuration Reference ### Project Fields Name of your project. Used for display and identification. ```yaml theme={null} project_name: data-processing-platform ``` Unique identifier for your project. Generated when you create a project. ```yaml theme={null} project_id: 67280ba2f4a0960d02159675 ``` List of data pipeline definitions. Each pipeline processes and transforms data. ```yaml theme={null} pipelines: - alias: etl_pipeline path: pipelines/etl.py ``` List of serverless action functions. Actions can be triggered by endpoints or used by AI agents. ```yaml theme={null} actions: - path: actions/send_email.py ``` Learn more in the [Actions documentation](/reference/development/actions). List of intelligent AI applications. ```yaml theme={null} apps: - path: apps/customer_support.py ``` List of Knowledge Object definitions — versioned business entities with a CRUD API. ```yaml theme={null} objects: - path: objects/order.yml ``` Removing an entry deletes the object and schedules cleanup of its data. Learn more in the [Knowledge Objects documentation](/reference/knowledge-objects/overview). List of declarative YAML orchestration flows. ```yaml theme={null} flows: - path: flows/daily_report.yml ``` Learn more in the [Flows documentation](/reference/flows/overview). List of Studio Apps — React applications built and served by Datazone. ```yaml theme={null} studio_apps: - alias: orders name: Orders path: studio/orders ``` Learn more in the [Studio Apps documentation](/reference/studio-apps/overview). List of API endpoint configurations. ```yaml theme={null} endpoints: - path: endpoints/webhooks.yml ``` Learn more in the [Endpoints documentation](/reference/integration/endpoints). ### Pipeline Configuration Short, unique identifier for the pipeline. Used in CLI commands and UI. ```yaml theme={null} alias: daily_etl ``` Relative path to the pipeline Python file from project root. ```yaml theme={null} path: pipelines/etl_pipeline.py ``` Compute instance size for pipeline execution. **Available sizes:** * `XSMALL` - 2 vCPU, 8 GB RAM * `SMALL` - 4 vCPU, 16 GB RAM * `MEDIUM` - 8 vCPU, 32 GB RAM * `LARGE` - 16 vCPU, 64 GB RAM * `XLARGE` - 32 vCPU, 128 GB RAM (Enterprise only) ```yaml theme={null} compute: LARGE ``` Spark deployment mode for distributed processing. **Options:** * `local` - Runs on a single machine (default) * `client` - Driver runs in the same process, executors run separately * `cluster` - Both driver and executors run in separate processes (Enterprise only) ```yaml theme={null} spark_config: deploy_mode: client ``` Number of Spark executors for parallel processing. Only applies when `deploy_mode` is `client` or `cluster`. ```yaml theme={null} spark_config: deploy_mode: client executor_instances: 5 ``` Additional Spark configuration properties. Pass any custom Spark configuration key-value pairs. ```yaml theme={null} spark_config: deploy_mode: client executor_instances: 3 extra_spark_config: spark.sql.shuffle.partitions: "200" spark.default.parallelism: "100" spark.sql.adaptive.enabled: "true" ``` Python packages required by the pipeline. Installed before execution. ```yaml theme={null} python_dependencies: - name: pandas version: 2.0.0 - name: requests version: 2.31.0 index_url: https://pypi.org/simple - name: my-package extra_arguments: - "--no-dependencies" ``` ### Python Dependency Fields Python package name from PyPI or custom index. ```yaml theme={null} - name: numpy ``` Specific package version. If omitted, installs the latest version. ```yaml theme={null} - name: pandas version: 2.0.0 ``` Custom Python package index URL. Useful for private packages or mirrors. ```yaml theme={null} - name: my-private-package version: 1.2.3 index_url: https://pypi.mycompany.com/simple ``` Additional arguments passed directly to the package installer for this dependency. ```yaml theme={null} - name: my-package version: 1.2.3 extra_arguments: - "--no-dependencies" ``` ### Action Configuration Relative path to the action Python file containing an `@action` decorated function. ```yaml theme={null} actions: - path: actions/send_notification.py - path: workflows/data_validator.py ``` Each file should contain **one action function**. Learn more in the [Actions documentation](/reference/development/actions). ### App Configuration Relative path to the intelligent app Python file. ```yaml theme={null} apps: - path: apps/customer_assistant.py ``` ### Studio App Configuration Short, unique identifier for the app. Used in its served URL. ```yaml theme={null} alias: orders ``` Display name shown in Datazone. Defaults to the alias. ```yaml theme={null} name: Orders ``` Relative path to the app directory — the folder holding `package.json`. ```yaml theme={null} studio_apps: - alias: orders name: Orders path: studio/orders ``` The entry is created for you when you add a Studio App, and removing it deletes the app and its directory. Each app is built per branch; see the [Studio Apps documentation](/reference/studio-apps/overview). ### Knowledge Object Configuration Relative path to the object definition YAML file. One file may hold several objects, separated by `---`. ```yaml theme={null} objects: - path: objects/order.yml - path: objects/customer.yml ``` Learn more in the [Knowledge Objects documentation](/reference/knowledge-objects/overview). ### Flow Configuration Relative path to the flow definition YAML file. ```yaml theme={null} flows: - path: flows/daily_report.yml ``` Learn more in the [Flows documentation](/reference/flows/overview). ### Endpoint Configuration Relative path to the endpoint configuration YAML file. ```yaml theme={null} endpoints: - path: endpoints/webhooks.yml - path: endpoints/api_routes.yml ``` Learn more in the [Endpoints documentation](/reference/integration/endpoints). ## Example Projects ### Data Processing Pipeline ```yaml theme={null} project_name: sales-analytics project_id: 67280ba2f4a0960d02159675 pipelines: - alias: daily_sales_etl path: pipelines/sales_pipeline.py compute: MEDIUM spark_config: deploy_mode: client executor_instances: 3 python_dependencies: - name: pandas version: 2.0.0 - name: sqlalchemy version: 2.0.0 ``` ### Multi-Component Project ```yaml theme={null} project_name: customer-platform project_id: 67280ba2f4a0960d02159675 pipelines: - alias: customer_data_sync path: pipelines/sync.py compute: SMALL python_dependencies: - name: requests - name: pydantic version: 2.0.0 actions: - path: actions/send_welcome_email.py - path: actions/validate_customer.py apps: - path: apps/support_chatbot.py objects: - path: objects/customer.yml flows: - path: flows/onboarding.yml studio_apps: - alias: customer_portal name: Customer Portal path: studio/customer_portal endpoints: - path: endpoints/customer_api.yml ``` ## Next Steps * [Learn about Pipelines](/reference/development/pipeline) * [Create Actions](/reference/development/actions) * [Build Intelligent Apps](/reference/intelligent-apps/overview) * [Build Studio Apps](/reference/studio-apps/overview) * [Define Knowledge Objects](/reference/knowledge-objects/overview) * [Orchestrate with Flows](/reference/flows/overview) * [Set up Endpoints](/reference/integration/endpoints) # Transform Source: https://docs.datazone.co/reference/development/transform Transform functions are the bricks of your pipeline. You can atomize your data processing steps into small functions and chain them together to build a pipeline. | Parameter Name | Default | Description | | ------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------- | | **compute\_fn** | - | The main computation function to be transformed. | | **name** | - | Name of the transform function. If not provided, uses the function name. | | **description** | - | Description of the transform function for documentation purposes. | | **materialized** | False | If True, the output will be persisted/cached for reuse. | | **input\_mapping** | - | Dictionary defining input dependencies and their sources. Maps input parameter names to their corresponding datasets or transforms. | | **depends** | - | List of transform functions that must complete before this transform can run. | | **partition\_by** | - | List of column names to partition the output data by. | | **output\_mapping** | - | Dictionary defining how the output should be mapped or stored. | | **tags** | - | List of tags for categorizing and organizing transforms. | | **engine** | pyspark | The computation engine to use. Options are 'pyspark' or 'pandas'. | ### Basic Transform Example ```python theme={null} from datazone import transform @transform(name="say_hello", description="Prints 'Hello, World!'") def say_hello(): print("Hello, World!") ``` ## Transform Engines The transform decorator supports two computation engines: PySpark and Pandas. You can specify the engine using the `engine` parameter. ```python theme={null} from datazone import transform @transform( input_mapping={"user_data": Input(Dataset(id="66280b3f49ae018b4c0c904a"))}, engine="pandas" ) def filter_by_age(user_data): adult_users = user_data[user_data.age >= 30] return adult_users ``` When using transforms with dependencies (via `input_mapping` or `depends`), all connected transforms must use the same engine. For example, if a transform uses the Pandas engine, all transforms it depends on or that depend on it must also use the Pandas engine. ### Engine Characteristics * **PySpark (default)**: * Distributed processing capabilities * Better for large-scale data processing * Supports all materialization features * **Pandas**: * Better for smaller datasets * More intuitive Python-native syntax * Ideal for local development and testing ## Materialization Materialization is the process of storing the output of a transform function for reuse. This can be useful when a transform function is computationally expensive and its output is used multiple times in the pipeline. Materialization is allowed for PySpark DataFrames only. So the output of the transform function should be a PySpark DataFrame. ```python theme={null} from datazone import transform @transform(name="fetch_data", materialized=True) def fetch_data(context): data = [("Alice", 9), ("Bob", 6), ("Charlie", 3), ("Maria", 7)] columns = ["Name", "Score"] spark = context.resources["pyspark"].spark return spark.createDataFrame(data, columns) ``` In above code, we used `context.resources["pyspark"].spark` to access the PySpark session. For more information, check the [Context](/reference/development/context) section. After running the pipeline, the output of the `fetch_data` function will be stored in Datazone as a dataset. You can check the dataset alias in the Datazone UI or use the `datazone dataset list` command to list all datasets. ## Input Mapping You can define input mappings to specify the data sources and dependencies for your transform functions. Input mappings enable you to: * Chain multiple transform functions * Create directed acyclic graphs (DAGs) * Connect to different data sources * Apply data transformations sequentially | Parameter Name | Default | Description | | ---------------- | ------- | ---------------------------------------------------------------------------------- | | **entity** | - | The entity to be used as input. It can be a dataset or another transform function. | | **output\_name** | - | If you use a transform that has multiple outputs, you can specify the output name. | Here are the common input mapping patterns: ```python theme={null} from datazone import transform @transform(input_mapping={"data": Input(Dataset(alias="raw_data"))}) def clean_data(data): return data.filter(data["column"] > 0) @transform( input_mapping={ "clean_data": Input(clean_data), "another_data": Input(Dataset(alias="another_data")), } ) def aggregate_data(clean_data, another_data): return ( clean_data.join(another_data, "column") .groupBy("column") .agg({"column": "sum"}) .select("column", "sum(column)") ) ``` * Input mappings should be defined as a dictionary where the key is the input parameter name and the value is an instance of the `Input` class. * The `Input` class accepts a `Dataset` or another transform function as an argument. ```mermaid theme={null} graph LR subgraph Pipeline clean[clean_data
filter column > 0] --> agg[aggregate_data
join and groupBy] end data[(Dataset
raw_data)]-->clean another[(Dataset
another_data)]-->agg style Pipeline fill:#f0f0f0,stroke:#333,stroke-width:2px style data fill:#b8e994,stroke:#333,stroke-width:1px style another fill:#b8e994,stroke:#333,stroke-width:1px ``` ## Output Mapping Output mapping defines how the output of a transform function should be stored or mapped. You can specify the output mapping using the `output_mapping` parameter. | Parameter Name | Default | Description | | ----------------- | --------- | ---------------------------------------------------------------------- | | **dataset** | - | The dataset where the output should be stored. | | **materialized** | False | If True, the output will be stored as a materialized dataset. | | **partition\_by** | - | List of column names to partition the output data by. | | **mode** | overwrite | The write mode for the output data. Options are `overwrite`, `append`. | ```python theme={null} from datazone import transform, Output, Dataset @transform(output_mapping={dataset: Output(dataset=Dataset(alias="clean_data"))}) def clean_data(data): return data.filter(data["column"] > 0) ``` * Output mapping should be defined as a dictionary where the key is the output parameter name and the value is an instance of the `Output` class. ### Multiple Outputs ```python theme={null} @transform( input_mapping={"orders": Input(Dataset(alias="orders"))}, output_mapping={ "daily_sales": Output(materialized=True), "monthly_sales": Output(materialized=True), "yearly_sales": Output( partition_by=["year"], materialized=True ) } ) def process_sales(orders): daily = orders.groupBy("date").agg(...) monthly = orders.groupBy("year", "month").agg(...) yearly = orders.groupBy("year").agg(...) return daily, monthly, yearly ``` ```mermaid theme={null} graph LR subgraph Transform process_sales end orders[(orders)]-->process_sales process_sales-->daily[(daily_sales)] process_sales-->monthly[(monthly_sales)] process_sales-->yearly[(yearly_sales)] ``` ## Transform Hooks Transform hooks allow you to execute custom logic on success or failure of a transform function. You can define hooks using the `on_success` and `on_failure` parameters in the `transform` decorator. ```python theme={null} from datazone import transform @transform(name="example_transform") def generate_sales_data(): return [("Alice", 100), ("Bob", 150), ("Charlie", 200)] @generate_sales_data.on_success def log_success(context): print(f"Transform {context.state.name} completed successfully.") @generate_sales_data.on_failure def log_failure(context): print(f"Transform {context.state.name} failed with error: {context.error}") ``` ## Partitioning Partitioning helps organize and optimize your datasets in our data platform. When you create a transform function, you can specify partition columns using the `partition_by` parameter. ```python theme={null} @transform( partition_by=["date", "country"], materialized=True ) def sales_by_country(data): return data.filter(...) ``` ### Why Partition? * Improve query performance when filtering by partition columns * Efficiently manage large datasets * Enable data retention policies by date partitions ### Common Partition Strategies ```python theme={null} # Daily partitioning for time-series data @transform(partition_by=["date"]) # Geographic partitioning @transform(partition_by=["country", "region"]) # Multiple partition columns @transform(partition_by=["date", "customer_type"]) ``` All transformed datasets are stored in Delta Lake format. Choose partition columns based on your most common filtering needs, typically date-based or categorical columns with reasonable cardinality. If you partition by a high-cardinality column, it may lead to a large number of small files, which can impact query performance. ### Best Practices * Use date partitioning for time-series data * Avoid partitioning by columns with high cardinality * Consider your query patterns when choosing partition columns ## Generator Transforms Generator transforms allow you to yield data multiple times from a single transform function. This is useful for processing data in chunks, creating multiple batches from a single input, or streaming incremental results. ### Usage Use Python's `yield` statement to return data in chunks. Each yielded value creates a separate batch that gets written to the output dataset. ```python theme={null} @transform( input_mapping={"user_data": Input(Dataset(alias="users"))}, output_mapping={"processed_data": Output(Dataset(alias="processed-users"), materialized=True, mode="append")}, ) def process_in_chunks(user_data): # Split data into chunks of 1000 rows chunk_size = 1000 total_rows = user_data.count() for offset in range(0, total_rows, chunk_size): chunk = user_data.limit(chunk_size).offset(offset) processed_chunk = chunk.filter(chunk.age >= 18) yield processed_chunk ``` ```mermaid theme={null} graph TD input[(users
10,000 rows)] --> start[Start Transform] start --> loop{For each chunk} loop -->|offset 0-999| process1[Process & Filter
chunk 1] loop -->|offset 1000-1999| process2[Process & Filter
chunk 2] loop -->|offset 2000-2999| process3[Process & Filter
chunk 3] loop -->|offset N| processN[Process & Filter
chunk N] process1 -->|yield| output1[(Append to
processed-users)] process2 -->|yield| output2[(Append to
processed-users)] process3 -->|yield| output3[(Append to
processed-users)] processN -->|yield| outputN[(Append to
processed-users)] output1 --> check1{More chunks?} output2 --> check2{More chunks?} output3 --> check3{More chunks?} outputN --> end1[End] check1 -->|Yes| loop check2 -->|Yes| loop check3 -->|Yes| loop ``` **Multiple Transactions**: Each `yield` creates a separate transaction. If your transform fails after some yields have succeeded, the already-written batches will remain in the output dataset. Consider idempotency in your pipeline design. **Mode Must Be Append**: Generator transforms require `mode="append"` in the output mapping. Using `mode="overwrite"` will cause each yielded batch to overwrite the previous one, leaving only the last batch in the output dataset. # Variables Source: https://docs.datazone.co/reference/development/variables Variables are used to store and manage data in the Datazone platform. You can define variables in the Datazone dashboard and use them in your pipelines. ## Overview api-key 1. Click **Settings** in the top right corner session context menu. 2. Click **Variables** in the left sidebar. 3. Click **Create** to create a new Variable. 4. Enter a name for the Variable and value. Also, you can define whether the variable is secret or not. If you define the variable as secret, the value will be encrypted and will not be shown in the UI. 5. Click **Create**. api-key ## Usage You can use the Variable in your pipelines and notebooks. You can access the Variable value using the `Variable` class. ```python theme={null} from datazone import Variable, transform @transform def my_transform(): variable = Variable(key="my-secret-variable") print(str(variable)) ``` Also in Notebooks, you can use the `Variable` class to access the Variable value. # Vectors Source: https://docs.datazone.co/reference/development/vectors Transform your data into searchable embeddings for AI-powered applications Vectors Overview Datazone Vectors enable you to **transform your data into embeddings** and store them in a vector database. This allows you to build **AI-powered search**, **RAG (Retrieval Augmented Generation)** applications, and **semantic similarity** features on top of your data. ## What are Vectors? Vectors convert your text data into **numerical representations** (embeddings) that capture **semantic meaning**. This enables: * **Semantic search** - Find relevant content based on meaning, not just keywords * **RAG applications** - Enhance AI agents with contextual information from your data * **Similarity matching** - Identify related documents or records Vector Overview Unlike traditional keyword search, vector-based search understands **context and intent**, delivering more accurate and relevant results. ## Creating a Vector Index 1. Navigate to your **Project** page 2. Click the **Add** button (+ icon) 3. Select **Vector** from the dropdown The vector creation flow guides you through **configuring your vector index**: ### Step 1: Choose Data Source Vector Source Select what data to vectorize: * **Dataset** - Index data from a dataset (CSV format) * Select the dataset you want to vectorize * Choose a **primary key column** to uniquely identify records * Select one or more **text columns** to embed * **File Container** - Index files from a file container path * Supported formats: **PDF**, **CSV**, **DOCX**, **XLSX**, **Markdown**, **TXT** * Files will be automatically processed and chunked For large datasets, consider using **Views** or filtered datasets to index only the most relevant data. ### Step 2: Embedding Configuration Embedding Settings Configure how your data will be embedded: * **Model Account** - Select a configured [Model Account](/reference/development/model-accounts) with embedding support * **Embedding Model** - Choose the embedding model (e.g., `text-embedding-3-small`, `text-embedding-ada-002`) * **Vector Dimension** - Embedding dimension (typically 1536 for OpenAI models) ### Step 3: Chunking Strategy Configure how your text is split into chunks before embedding: * **Text Splitting** - Split by character count * **Chunk Size** - Number of characters per chunk * **Chunk Overlap** - Characters shared between chunks (helps maintain context) * **Length Splitting** - Split by token count using a specific encoding * **Encoding Name** - Tokenizer to use (e.g., `cl100k_base` for GPT models) * **Chunk Size** - Number of tokens per chunk * **Chunk Overlap** - Tokens shared between chunks * **Document Splitting** - Split based on document structure * **Document Type** - Choose format: Markdown, JSON, Code, or HTML * Preserves logical document boundaries Smaller chunks provide more precise search results but may lose broader context. Larger chunks retain more context but may be less specific. A typical chunk size is **500-1000 characters** with **10-20% overlap**. After completing configuration, click **Create** to start the indexing process. ## Indexing Process Once created, your vector index goes through several states: 1. **Not Indexed** - Initial state after creation 2. **Scheduled** - Queued for indexing 3. **Indexing** - Currently processing and embedding your data 4. **Indexed** - Successfully completed, ready to use 5. **Failed** - Error occurred during indexing (check error details) You can monitor the **indexing status** and view **statistics** including: * Total chunks created * Total chunks indexed * Total tokens processed ## Using Vectors Once indexed, your vectors can be used for: ### Semantic Search Vector Search Search your data using **natural language queries** that understand meaning and context, not just exact keyword matches. The **Explore** tab provides an interface to: * Enter search queries in natural language * View semantically similar results ranked by relevance * See matching chunks with their context and metadata * Test and refine your vector search results ### Agent RAG Attach vectors as data sources for your [Agents](/reference/agents/overview), enabling them to retrieve relevant context from your data to provide more accurate and informed responses. Agents can automatically perform semantic search when answering questions. ### Similarity Endpoints Create [API endpoints](/reference/integration/endpoints#vector-based-endpoints) that return similar records based on vector similarity, enabling semantic search in your applications. Perfect for building search features or recommendation systems. ## Best Practices 1. **Choose the Right Source** - Use datasets for structured data and file containers for documents 2. **Optimize Chunk Size** - Balance between context (larger chunks) and precision (smaller chunks) 3. **Add Overlap** - Include 10-20% overlap to maintain context across chunk boundaries 4. **Select Appropriate Models** - Smaller embedding models are faster and cheaper, larger models may provide better quality 5. **Use Cosine Similarity** - Works well for most text similarity use cases 6. **Monitor Indexing** - Check indexing status and statistics to ensure successful processing ## Next Steps * [Configure Model Accounts](/reference/development/model-accounts) for embedding models * [Create Agents](/reference/agents/overview) to leverage your vectors * [File Containers](/reference/development/file-container) for document management # Node Reference Source: https://docs.datazone.co/reference/flows/nodes Detailed reference for every node type available in Datazone Flows ## Common Properties Every node in a flow document shares the same envelope: | Property | Type | Description | | -------- | ------ | ---------------------------------------------------------------------------------------------------------------------- | | `id` | string | Unique identifier for the node within the flow | | `type` | string | Node type: `start`, `if`, `for_each`, `llm_call`, `rest_call`, `action_call`, `python`, `sql`, `response`, or `output` | | `label` | string | (Optional) Display name shown on the canvas | | `config` | object | Type-specific configuration, validated against that node type's schema | Each node type also declares a fixed set of **input** and **output** ports (e.g. `in` / `out`). [Connections](/reference/flows/yaml-reference#connections) wire an upstream node's output port to a downstream node's input port. ## Start The entry point of a flow. It takes no configuration and no inputs — it simply emits the run's parameters and a trigger timestamp so downstream nodes have a well-defined starting payload. | Property | Category | Inputs | Outputs | | -------- | -------- | ------ | ------- | | `start` | trigger | — | `out` | ```yaml theme={null} - id: trigger type: start label: Start config: {} ``` **Output:** ```json theme={null} { "kind": "start", "parameters": { "...": "the run's parameters" }, "triggered_at": "2026-07-24T12:00:00+00:00" } ``` Every flow must have exactly one `start` node as its entry point. ## If Branches the flow based on a condition evaluated against upstream data and flow parameters. | Property | Category | Inputs | Outputs | | -------- | ----------------------- | ------ | --------------- | | `if` | control (**branching**) | `in` | `true`, `false` | | Attribute | Type | Default | Description | | ---------- | ------ | ------- | ----------------------------------------------------------------------------------------------------------- | | `left` | string | — | Python expression evaluated with `inputs`/`parameters` in scope (required) | | `operator` | string | `eq` | One of `eq`, `neq`, `gt`, `gte`, `lt`, `lte`, `contains`, `is_true`, `is_false`, `is_empty`, `is_not_empty` | | `right` | any | `null` | Right-hand operand. Ignored for `is_true`/`is_false`/`is_empty`/`is_not_empty` | ```yaml theme={null} - id: check_status type: if label: Is approved? config: left: "inputs['in']['status']" operator: eq right: "approved" ``` Because `if` is a **branching** node, every outgoing connection from it must set `from_port` to `true` or `false`: ```yaml theme={null} connections: - from: check_status to: send_email from_port: "true" - from: check_status to: log_rejection from_port: "false" ``` A connection leaving a branching node without a valid `from_port` fails validation. Nodes only reachable through the branch that isn't chosen at run time are marked `SKIPPED` instead of executed. When the upstream input is a dict, its fields are merged into the output alongside `branch` and `value`, so downstream nodes on either branch still see the original payload. ## For Each Iterates over a list, re-running a nested **body** sub-flow once per item. | Property | Category | Inputs | Outputs | | ---------- | ----------------------- | ------ | ------- | | `for_each` | control (**container**) | `in` | `out` | | Attribute | Type | Default | Description | | ---------------- | ------ | --------- | ------------------------------------------------------------------------------------------------------------ | | `items` | string | — | Python expression evaluated with `inputs`/`parameters` in scope; must evaluate to a list/iterable (required) | | `item_as` | string | `item` | Parameter name the current item is exposed under inside the body, as `parameters[item_as]` | | `index_as` | string | `index` | Parameter name the current index is exposed under inside the body (omit to disable) | | `max_iterations` | int | `1000` | Safety cap — exceeding it raises a run error | | `save_as` | string | `results` | Output key the collected per-iteration results are stored under | | `body` | object | — | A full nested flow document (its own `nodes`/`connections`), required | ```yaml theme={null} - id: process_orders type: for_each label: Process each order config: items: "inputs['in']['orders']" item_as: order index_as: index max_iterations: 500 save_as: results body: flow: name: process_orders_body nodes: - id: body_start type: start config: {} - id: format_order type: python config: code: | def handler(inputs, parameters): order = parameters["order"] return {"id": order["id"], "total": order["amount"] * 1.1} - id: body_response type: response config: {} connections: - from: body_start to: format_order - from: format_order to: body_response ``` The `body` document is validated the exact same way a top-level flow is, including supporting another `for_each` nested inside it (up to a max depth of 5). It **must contain exactly one `response` node** — that node's output is what gets collected into `save_as` for each iteration. ## LLM Call Calls a Large Language Model through a configured [Model Account](/reference/development/model-accounts), or the organization's Orion AI default account when omitted. | Property | Category | Inputs | Outputs | | ---------- | ---------------------- | ------ | ------- | | `llm_call` | ai (needs credentials) | `in` | `out` | | Attribute | Type | Default | Description | | ------------------ | ------ | ---------- | -------------------------------------------------------------------------------------- | | `model_account_id` | string | `null` | Model account to use. Omit to use the organization's Orion AI settings | | `model` | string | `null` | Model enum value (e.g. `GPT_4O`). Omit to use the organization default | | `prompt` | string | — | Prompt template, required. Supports `{inputs[...]}` / `{parameters[...]}` substitution | | `system_prompt` | string | `null` | (Optional) System prompt, same templating support | | `save_as` | string | `response` | Output key the model's response text is stored under | | `timeout_sec` | int | `60` | Request timeout in seconds | ```yaml theme={null} - id: summarize type: llm_call label: Summarize ticket config: model_account_id: "664f1c2e5a2ac9f0d39326" model: GPT_4O system_prompt: "You are a support triage assistant." prompt: "Summarize this ticket in one sentence: {inputs[in][body]}" save_as: summary timeout_sec: 45 ``` `prompt`/`system_prompt` use Python's `str.format()` templating (not Jinja) — see [Templating & Expressions](/reference/flows/templating#llm_call-and-action_call-templating) for the exact rules and error behavior when a referenced field is missing. ## REST Call Calls an external HTTP/REST endpoint. | Property | Category | Inputs | Outputs | | ----------- | ----------- | ------ | ---------- | | `rest_call` | integration | `in` | `response` | | Attribute | Type | Default | Description | | -------------------------------- | ------ | ---------- | -------------------------------------------------------------------------------------------------------------------------------- | | `url` | string | — | Target URL, required. Must start with `http://` or `https://` | | `method` | string | `GET` | One of `GET`, `POST`, `PUT`, `PATCH`, `DELETE` | | `headers` | object | `{}` | Request headers | | `query` | object | `{}` | Query parameters. Values that reference `inputs`/`parameters` are evaluated as Python expressions; plain literals are sent as-is | | `json_body` | object | `null` | JSON request body | | `timeout_sec` | int | `30` | Request timeout in seconds | | `save_as` | string | `response` | Output key the parsed response body is stored under | | `auth_type` | string | `none` | One of `none`, `basic`, `bearer`, `api_key` | | `username` / `password` | string | `null` | Used when `auth_type: basic` | | `token` | string | `null` | Used when `auth_type: bearer` — sent as `Authorization: Bearer ` | | `api_key_name` / `api_key_value` | string | `null` | Used when `auth_type: api_key` — sent as a `: ` header | ```yaml theme={null} - id: fetch_weather type: rest_call label: Fetch London weather config: url: "https://api.open-meteo.com/v1/forecast" method: GET query: latitude: "51.5074" longitude: "-0.1278" current_weather: "true" timeout_sec: 30 save_as: weather ``` Authenticated example: ```yaml theme={null} - id: call_billing_api type: rest_call label: Get invoice config: url: "https://billing.example.com/api/invoices/{parameters[invoice_id]}" method: GET auth_type: bearer token: "sk_live_..." save_as: invoice ``` The response is always returned alongside its `status_code`: ```json theme={null} { "response": { "...": "parsed JSON or raw text" }, "status_code": 200 } ``` ## Action Call Calls a project [Action](/reference/development/actions) — a user-defined Python function — with parameters. | Property | Category | Inputs | Outputs | | ------------- | ------------------------------- | ------ | ------- | | `action_call` | integration (needs credentials) | `in` | `out` | | Attribute | Type | Default | Description | | ------------- | ------ | -------- | ----------------------------------------------------------------------------------------------------- | | `action_id` | string | — | Id of the Action to call, required | | `parameters` | object | `{}` | Parameters passed to the action. String values support `{inputs[...]}`/`{parameters[...]}` templating | | `save_as` | string | `result` | Output key the action's return value is stored under | | `timeout_sec` | int | `30` | Timeout in seconds | ```yaml theme={null} - id: send_welcome_email type: action_call label: Send welcome email config: action_id: "664f1c2e5a2ac9f0d39326" parameters: to: "{inputs[in][email]}" name: "{inputs[in][full_name]}" save_as: email_result timeout_sec: 30 ``` Actions are audited the same way as when an agent calls them — every `action_call` node execution appears in the Action's call history. ## Python Runs custom Python against upstream data and flow parameters, in an isolated subprocess. | Property | Category | Inputs | Outputs | | -------- | --------- | ------ | ------- | | `python` | transform | `in` | `out` | | Attribute | Type | Description | | --------- | ------ | ------------------------------------------------------------------------------------- | | `code` | string | A complete Python module defining a `handler(inputs, parameters)` function (required) | ```yaml theme={null} - id: convert_temperature type: python label: Convert temperature config: code: | def handler(inputs, parameters): # inputs – dict of upstream node outputs, keyed by port name # parameters – dict of flow run parameters weather = inputs.get("in", {}).get("weather", {}) celsius = weather.get("current_weather", {}).get("temperature") fahrenheit = round(celsius * 9 / 5 + 32, 1) return {"celsius": celsius, "fahrenheit": fahrenheit} ``` `code` must define a `handler(inputs, parameters)` function and be valid Python — both are checked before the flow can run. ## SQL Runs a read-only SQL `SELECT` against the project's own datasets, the same way SQL Explorer does, and returns the rows to the flow. | Property | Category | Inputs | Outputs | | -------- | ------------------------ | ------ | ------- | | `sql` | data (needs credentials) | `in` | `out` | | Attribute | Type | Default | Description | | ------------- | ------ | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `query` | string | — | The `SELECT` query, required. Supports `str.format()` templating — see [Templating & Expressions](/reference/flows/templating#llm_call-action_call-and-sql-templating) | | `save_as` | string | `result` | Output key the query result is stored under | | `timeout_sec` | int | `60` | Request timeout in seconds | ```yaml theme={null} - id: get_orders type: sql label: Fetch recent orders config: query: "SELECT * FROM orders WHERE id = {parameters[order_id]} LIMIT 100" save_as: result timeout_sec: 60 ``` **Output:** ```json theme={null} { "result": { "data": [{ "id": 1, "amount": 10 }, { "id": 2, "amount": 20 }], "columns": ["id", "amount"], "row_count": 2 } } ``` `query` uses the same `str.format()` templating as `llm_call`/`action_call` — a field referenced in `query` but missing from `inputs`/`parameters` fails the node with a clear error naming the missing key, rather than sending a malformed query. Only `SELECT` (and `UNION`/`INTERSECT`/`EXCEPT`) queries are accepted — multi-statement queries and `INTO OUTFILE`/`INTO DUMPFILE` are rejected. The query runs with the permissions of whoever triggered the flow run, against the project's own datasets — there's no separate connection or data source to configure. Unlike SQL Explorer, **no default row limit is applied** to a flow's `sql` node, so add your own `LIMIT` or a large result set can be slow to return. Every `sql` node execution is recorded as an auditable query result against the flow run, and counts against the organization's query quota — a run made while that quota is exceeded fails with `Query quota exceeded for this account`. ## Response A terminal node that returns the upstream result, unchanged, to the flow's caller. | Property | Category | Inputs | Outputs | | ---------- | -------- | --------------- | ------- | | `response` | terminal | `in` (required) | — | ```yaml theme={null} - id: finish type: response label: Response config: {} ``` A flow may contain **at most one** top-level `response` node. Inside a `for_each` body, exactly **one** `response` node is required — it defines that iteration's result. ## Output A sink node — writes the upstream result to a dataset, webhook, or file. | Property | Category | Inputs | Outputs | | -------- | -------- | --------------- | ------- | | `output` | sink | `in` (required) | — | | Attribute | Type | Default | Description | | --------------- | ------ | ------- | ------------------------------------------------------------------------- | | `kind` | string | — | One of `dataset`, `webhook`, `file` (required) | | `dataset_alias` | string | `null` | Required when `kind: dataset` | | `materialized` | bool | `false` | Reserved for a future materialized dataset write path — not yet supported | | `url` | string | `null` | Required when `kind: webhook`. Must start with `http://` or `https://` | | `path` | string | `null` | Required when `kind: file` | ```yaml theme={null} - id: post_result type: output label: Send to webhook config: kind: webhook url: "https://hooks.example.com/flow-result" ``` ```yaml theme={null} - id: write_dataset type: output label: Write to dataset config: kind: dataset dataset_alias: "processed_orders" ``` Setting `materialized: true` on a `kind: dataset` output currently fails validation — materialized dataset writes are not supported yet. ## Next Steps * [Overview](/reference/flows/overview) - flow structure and core concepts * [Templating & Expressions](/reference/flows/templating) - exactly how each node type consumes `inputs`/`parameters` * [YAML Reference](/reference/flows/yaml-reference) - the complete flow document schema # Overview Source: https://docs.datazone.co/reference/flows/overview Build orchestration graphs that call LLMs, REST APIs, and Actions with a declarative YAML flow Flows # Flows A Flow is a **directed graph of typed nodes** you connect together to orchestrate a task: call an LLM, hit an external API, branch on a condition, loop over a list, or invoke a project [Action](/reference/development/actions). Flows are defined declaratively — the same document your Flow Builder canvas edits is what gets executed — so every run is reproducible and versionable.