# Changelog Source: https://docs.mage.ai/about/changelog Latest new features and changelog. > **[Changelog](https://github.com/mage-ai/mage-ai/releases)** > > Learn more about the latest features and improvements # Code of Conduct Source: https://docs.mage.ai/about/code-of-conduct We've adopted the [Contributor Covenant](https://www.contributor-covenant.org/) Code of Conduct for the Mage community. Please review the following to understand our standards and expectations for participation. ## Our Pledge We as members, contributors, and leaders pledge to make participation in our community a *magical* โœจ experience for everyone. We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community. ## Our Standards Examples of behavior that contributes to a positive environment for our community include: * ๐Ÿช„ Deliver magical experiences: demonstrating empathy and kindness toward others. Being respectful of differing opinions, viewpoints, and experiences * ๐Ÿ”‹ Give people power-ups: in data engineering *and* open-source development, doing your best to help others learn and grow * ๐Ÿ‘ฌ Victorious as a team: working together to build the best product possible, recognizing that teamwork can amplify outcomes beyond that of an individual * ๐Ÿ™…โ€โ™‚๏ธ No Ego: giving and gracefully accepting constructive feedback Examples of unacceptable behavior include: * The use of sexualized language or imagery, and sexual attention or advances of any kind * Trolling, insulting or derogatory comments, and personal or political attacks * Public or private harassment * Publishing others' private information, such as a physical or email address, without their explicit permission * Other conduct which could reasonably be considered inappropriate in a professional setting ## Enforcement Responsibilities Community leaders are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful. Community leaders have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, and will communicate reasons for moderation decisions when appropriate. ## Scope This Code of Conduct applies within all community spaces, and also applies when an individual is officially representing the community in public spaces. Examples of representing our community include using an official e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. ## Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcementโ€” please reach out to [the Mage team](mailto:hello@mage.ai) with any concerns. All complaints will be reviewed and investigated promptly and fairly. All community leaders are obligated to respect the privacy and security of the reporter of any incident. ## Enforcement Guidelines Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct: ### 1. Correction **Community Impact**: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community. **Consequence**: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. ### 2. Warning **Community Impact**: A violation through a single incident or series of actions. **Consequence**: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban. ### 3. Temporary Ban **Community Impact**: A serious violation of community standards, including sustained inappropriate behavior. **Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban. ### 4. Permanent Ban **Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. **Consequence**: A permanent ban from any sort of public interaction within the community. ## Attribution This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.1, available at [https://www.contributor-covenant.org/version/2/1/code\_of\_conduct.html][v2.1]. Community Impact Guidelines were inspired by [Mozilla's code of conduct enforcement ladder][Mozilla CoC]. For answers to common questions about this code of conduct, see the FAQ at [https://www.contributor-covenant.org/faq][FAQ]. Translations are available at [https://www.contributor-covenant.org/translations][translations]. [homepage]: https://www.contributor-covenant.org [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html [Mozilla CoC]: https://github.com/mozilla/diversity [FAQ]: https://www.contributor-covenant.org/faq [translations]: https://www.contributor-covenant.org/translations # Features Source: https://docs.mage.ai/about/features ![](https://user-images.githubusercontent.com/78053898/198751496-22d51f03-f09f-454c-8f98-409b5dbec8f9.svg) > **[Data pipeline management](/design/data-pipeline-management)** > **[Notebook for building data pipelines](/about/features#1-data-centric-editor)** > **[Changelog](https://github.com/mage-ai/mage-ai/releases)** > **[Roadmap](https://airtable.com/shrJS0cDOmQywb8vp)** ## Data pipeline management ๐Ÿ‘‰ See more [details here](/design/data-pipeline-management). ![](https://mage-ai.github.io/assets/orchestration-overview.gif) ## Notebook for building data pipelines ### 1. Data centric editor An interactive coding experience designed for preparing data to train ML models. Visualize the impact of your code every time you load, clean, and transform data. ![Data centric editor](https://mage-ai.github.io/assets/data-centric-editor.png) ### 2. Production ready code No more writing throw away code or trying to turn notebooks into scripts. Each block (aka cell) in this editor is a modular file that can be tested, reused, and chained together to create an executable data pipeline locally or in any environment. Read more about [blocks](/design/blocks) and how they work. ![Production ready code](https://mage-ai.github.io/assets/data-pipeline.png) Run your data pipeline end-to-end using the command line function: `$ mage run [project] [pipeline]` You can run your pipeline in production environments with the orchestration tools * [Airflow](/guides/integrate-mage-airflow) * [Prefect](/integrations/prefect) ### 3. Extensible Easily add new functionality directly in the source code or through plug-ins (coming soon). Adding new API endpoints ([Tornado](https://www.tornadoweb.org/en/stable/)), transformations (Python, PySpark, SQL), and charts (using [React](https://reactjs.org/)) is easy to do (tutorial coming soon). ![Extensible charts](https://mage-ai.github.io/assets/extensible-charts.gif) # Frequently Asked Questions Source: https://docs.mage.ai/about/frequently-asked-questions Here are some frequently asked questions about Mage and our best answers. ![](https://mage-ai.github.io/assets/notion-faq.png) > **What is Mage?** > > Mage is an open-source data pipeline tool for transforming and integrating data. > > ๐Ÿง™ A mage is someone who uses magic. Advanced technology is indistinguishable from magic. > > Weโ€™re on a mission to make AI technology more accessible by building data tools for engineers and scientists. > > Find out more about our story: [https://www.mage.ai/blog/mage-heros-journey-fantasy-epic-on-how-a-startup-rose-from-the-ashes](https://www.mage.ai/blog/mage-heros-journey-fantasy-epic-on-how-a-startup-rose-from-the-ashes) > **Who is the ideal user for this tool?** > > Our tool was built with data engineers and data scientists in mind, but is not limited to those roles. Other data professionals could find value in the tool. > **How difficult is Mage to setup?** > > You can quickly and easily get started by installing Mage using Docker (recommended),ย **`pip`**, orย **`conda`**. Click [here](https://docs.mage.ai/introduction/overview#quick-start) for details. > **How much does Mage cost?** > > Mage is free as long as you are self-hosted (AWS, GCP, Azure, or Digital Ocean). > **How is Mageโ€™s data pipeline engine software different from Airflow, Dagster, etc?** > > Our 4 [core design principles](/design/core-design-principles) that differentiate ourselves are: > > 1. Easy developer experience > > 2. Engineering best practices built-in > > 3. Data is a first-class citizen > > 4. Scaling is made simple > > Features that set us apart (some of the others might eventually have these features): > > 1. Mix and match SQL and Python in data pipeline tasks. > 2. UI/IDE for building and managing data pipelines. > 3. Data centric: we designed and built a pipeline engine ONLY for moving and transforming data. This makes it possible for us to make datasets a 1st class citizen; enabling native features such as partitioning, versioning, backfilling, data validation, testing, and data quality monitoring. > 4. Extensible: we designed and built the tool with developers in mind, making sure itโ€™s really easy to add new functionality to the source code or through plug-ins. > 5. Scalable: the tool can handle very, very large datasets while transforming the data or charting it. > 6. Production ready: when you build your data pipeline, it runs exactly the same in development as it does in production. Deploying the tool and managing the infrastructure in production is very easy and simple, unlike Airflow. > 7. Modular: every block/cell you write is a standalone file that is interoperable; meaning it can be used in other pipelines or in other code bases. > **Whatโ€™s the difference between Mage and Fivetran?** > > Check out our blog [Mage vs. Fivetran](https://www.mage.ai/blog/mage-vs-fivetran). > **Whatโ€™s the difference between Mage and Airbyte?** > > Check out our blog [Mage vs Airbyte](https://www.mage.ai/blog/mage-vs-airbyte). > **Whatโ€™s the difference between Mage and Prefect?** > > Mage provides an interactive notebook with built-in engineering best practices for building pipelines, which makes prototyping and building production-ready pipelines much easier. > > Mage supports writing pipelines in multiple languages which include Python, SQL, and R. > > Mage supports multiple types of pipelines natively such as: > > * Standard batch pipelines > * Data integration pipelines > * Streaming pipelines > * Spark pipelines > * DBT pipelines > **What languages does Mage support?** > > We currently support SQL, Python, R, and PySpark. Coming soon: Spark SQL. > **Does Mage integrate with Spark?** > > Yes! [Here](https://docs.mage.ai/integrations/spark-pyspark) is a step-by-step tutorial to use Mage withย Sparkย on EMR. > **Whatโ€™s the difference between Mage and Sagemaker?** > > Sagemaker is used to train machine learning models and serve them via api. > > Mage is an engine for running data pipelines that can move and transform data. That data can then be stored anywhere (e.g. S3) and used to train models in Sagemaker. > **Whatโ€™s the difference between Mage and Databricks?** > > Databricks provides infrastructure to run Spark. They also provide notebooks that can run your code in Spark as well. > > Mage can execute your code in a Spark cluster, managed by AWS, GCP, or even Databricks. > **How do I send pipeline notifications to Slack?** > > [Here is a doc](/integrations/observability/alerting-slack) to help you set up alerting for pipeline status updates in [Slack](https://www.mage.ai/chat). > **How can I contribute or request features?** > > We love and welcome community contributions! [Here is a doc](/contributing/overview) to get you started. > > To request features, add a โ€œFeature requestโ€ using the `New issue` button in GitHub from this [link](https://github.com/mage-ai/mage-ai/issues), or join our [feature-request](https://www.mage.ai/chat) Slack channel. *Canโ€™t find what youโ€™re looking for? [Ask a question here](https://github.com/mage-ai/mage-ai/discussions/categories/q-a) or [join our slack](https://mage.ai/chat) for additional support!* # Releases Source: https://docs.mage.ai/about/releases Latest new features and changelog. > **[Update Mage](/development/updating-mage)** > > Install the newest version of Mage Mage Pro may show a short feature highlight when you first open the app after an update. These highlights are available in Mage Pro only and spotlight selected features; the full release notes remain available below. Select **Next** to move through the highlights, then **Done**, or choose a feature action to continue into the app. The background stays locked until you finish or choose an action; Escape and clicking outside do not close the announcement. Finishing or choosing a feature action marks all highlights offered in that announcement as seen, including any remaining screens. This is remembered for your account and deployment in the current browser; clearing browser storage or using another browser can show them again. Older highlights can still appear if they remain included in the installed release and you have not completed them in that browser. Video previews play automatically without sound. Some previews may repeat. *** > **[All releases](https://github.com/mage-ai/mage-ai/releases)** > > Install the newest version of Mage **Kaos** 0.9.74 [Read full release notes](https://github.com/mage-ai/mage-ai/releases/tag/0.9.74) ### โ˜๏ธ Google cloud storage source You can now effortlessly configure your data integration source blocks to Google Cloud Storage using this snippet. It specifies the destination bucket, sets the file type to Parquet, and provides the path to your service account credentials needed for authentication. ![](https://mage-ai.github.io/assets/pipelines/integration-pipelines/gcs_integration_test.png) by @TalaatHasanin in [https://github.com/mage-ai/mage-ai/pull/5334](https://github.com/mage-ai/mage-ai/pull/5334) ### ๐ŸŒฌ๏ธ ๐Ÿฝ๏ธ Airtable Integration Effortlessly streamline your data data integration source blocks with Airtable using this tailored script. It establishes a connection to your Airtable base, designates the specific table for integration, and securely integrates your Airtable API key for access. ![](https://mage-ai.github.io/assets/pipelines/integration-pipelines/airtable_integration_test.png) by @TalaatHasanin in [https://github.com/mage-ai/mage-ai/pull/5404](https://github.com/mage-ai/mage-ai/pull/5404) ### โœ‚๏ธ Add trim reformat action to transformer block A new "trim reformat" action has been added to the Python transformer block, allowing for the removal of leading and trailing whitespace from specified text columns. This enhancement ensures cleaner and more consistent data formatting by automatically stripping unnecessary spaces around text entries. by @cristopheridlc in [https://github.com/mage-ai/mage-ai/pull/5321](https://github.com/mage-ai/mage-ai/pull/5321) ### ๐Ÿปโ€โ„๏ธ Enable polars dataframe in GCS data exporter This update enhances the export method of the GCS IO module, expanding its functionality to support exporting Polars DataFrames in addition to the previously supported Pandas DataFrames. This new capability allows users to seamlessly work with both data formats, offering greater flexibility in managing and exporting data from their workflows. ![](https://media0.giphy.com/media/v1.Y2lkPTc5MGI3NjExbDM2amtld2toajMxMmR2cmt2eHc4MmdlZ2V6Y3IxcXdncmI1ZGN5YSZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/aK4wh0UE3oddS/giphy.webp?raw=true) by @TalaatHasanin in [https://github.com/mage-ai/mage-ai/pull/5348](https://github.com/mage-ai/mage-ai/pull/5348) ### Add support to scheduler name on k8s executor This update adds the ability to customize Kubernetes scheduler options when using the Kubernetes Executor. Users can now directly configure scheduler settings, providing increased flexibility and control over how pods are scheduled within Kubernetes environments. by @messerzen in [https://github.com/mage-ai/mage-ai/pull/5412](https://github.com/mage-ai/mage-ai/pull/5412) **Deadpool & Wolverine** 0.9.73 [Read full release notes](https://github.com/mage-ai/mage-ai/releases/tag/0.9.73) ### ๐Ÿง  Memory management upgrade This feature enhances system performance and stability by optimizing allocation, deallocation, and overall utilization of RAM resources, resulting in improved efficiency and reduced memory-related errors. Check out the [doc](https://www.notion.so/mageai/Memory-management-upgrades-e6c5e6e360ce410094091e00c46e3bb6?pvs=4) for details. ### ๐Ÿ”„ Dynamic blocks 2.0 Introducing an enhanced Dynamic blocks feature for creating dynamic content blocks that can adapt based on user input or data changes, offering improved flexibility and interactivity for users. This update aims to streamline workflows and enhance the overall user experience by making content more responsive and customizable. Learn more in this [doc](https://www.notion.so/mageai/Dynamic-Blocks-2-0-d2fc11a4f48148d68b817e9bfb38a732). ### ๐Ÿ” Azure DB connection via Key Vault Securely retrieve a database connection URL stored in Azure Key Vault using environment variables for authentication. ``` AZURE_KEY_VAULT_URL AZURE_CLIENT_ID AZURE_CLIENT_SECRET AZURE_TENANT_ID ``` by [@wangxiaoyou1993](https://github.com/wangxiaoyou1993) in [#5302](https://github.com/mage-ai/mage-ai/pull/5302) ### ๐Ÿ‘๏ธ Workspace monitoring Add an "Overview" page and "Pipeline runs" page to the Workspace Management UI. This provides some overall monitoring for all of the pipeline runs in the different workspaces without having to individually open up each workspace instance. ![](https://github.com/user-attachments/assets/0b8a1d83-3292-4e10-928b-5d625f817d40) by @johnson-mage in [https://github.com/mage-ai/mage-ai/pull/5311](https://github.com/mage-ai/mage-ai/pull/5311) **House Targaryen** 0.9.72 [Read full release notes](https://github.com/mage-ai/mage-ai/releases/tag/0.9.72) [House Targaryen Release](https://www.youtube.com/embed/abiOckshzu8) **X-Men** 0.9.71 [Read full release notes](https://github.com/mage-ai/mage-ai/releases/tag/0.9.71) [X-Men Release](https://www.youtube.com/embed/m8iw0e8346k) **Fallout** 0.9.70 [Read full release notes](https://github.com/mage-ai/mage-ai/releases/tag/0.9.70) [Fallout Release](https://www.youtube.com/embed/rAp7psCTxC8) **Invincible** 0.9.68 [Read full release notes](https://github.com/mage-ai/mage-ai/releases/tag/0.9.68) [Invincible Release](https://www.youtube.com/embed/ck1UGjUeGGA) * [0.9.66 | Shogun Release](https://github.com/mage-ai/mage-ai/releases/tag/0.9.66) * [0.9.65 | Demon Slayer Release](https://github.com/mage-ai/mage-ai/releases/tag/0.9.65) * [0.9.64 | Maestro Release](https://github.com/mage-ai/mage-ai/releases/tag/0.9.64) * [0.9.63 | Halo Release](https://github.com/mage-ai/mage-ai/releases/tag/0.9.63) * [0.9.62 | The Beekeeper Release](https://github.com/mage-ai/mage-ai/releases/tag/0.9.62) * [0.9.60 | Yusuke Urameshi Release](https://github.com/mage-ai/mage-ai/releases/tag/0.9.60) * [0.9.59 | Year of the Dragon Release](https://github.com/mage-ai/mage-ai/releases/tag/0.9.59) * [0.9.50 | Wonka Release](https://github.com/mage-ai/mage-ai/releases/tag/0.9.50) * [0.9.48 | The Boy and the Heron Release](https://github.com/mage-ai/mage-ai/releases/tag/0.9.48) * [0.9.46 | Wish Release](https://github.com/mage-ai/mage-ai/releases/tag/0.9.46) * [0.9.45 | Yuji Itadori Release](https://github.com/mage-ai/mage-ai/releases/tag/0.9.45) * [0.9.43 | Attack on Titan Release](https://github.com/mage-ai/mage-ai/releases/tag/0.9.43) * [0.9.41 | Halloween Release](https://github.com/mage-ai/mage-ai/releases/tag/0.9.41) * [0.9.38 | Goosebumps Release](https://github.com/mage-ai/mage-ai/releases/tag/0.9.38) * [0.9.35 | Loki Release](https://github.com/mage-ai/mage-ai/releases/tag/0.9.35) * [0.9.34 | C-3PO Release](https://github.com/mage-ai/mage-ai/releases/tag/0.9.34) * [0.9.30 | Cowboy Bebop Release](https://github.com/mage-ai/mage-ai/releases/tag/0.9.30) * [0.9.28 | The Creator Release](https://github.com/mage-ai/mage-ai/releases/tag/0.9.28) * [0.9.26 | Expend4bles Release](https://github.com/mage-ai/mage-ai/releases/tag/0.9.26) * [0.9.23 | One Piece Release](https://github.com/mage-ai/mage-ai/releases/tag/0.9.23) * [0.9.21 | Ahsoka Release](https://github.com/mage-ai/mage-ai/releases/tag/0.9.21) * [0.9.19 | The Equalizer Release](https://github.com/mage-ai/mage-ai/releases/tag/0.9.19) * [0.9.16 | Gran Turismo Release](https://github.com/mage-ai/mage-ai/releases/tag/0.9.16) * [0.9.14 | Blue Beetle Release](https://github.com/mage-ai/mage-ai/releases/tag/0.9.14) * [0.9.11 | Mutant Mayhem Release](https://github.com/mage-ai/mage-ai/releases/tag/0.9.11) * [0.9.10 | Haunted Mansion Release](https://github.com/mage-ai/mage-ai/releases/tag/0.9.10) * [0.9.80 | Dead Reckoning Release](https://github.com/mage-ai/mage-ai/releases/tag/0.9.8) * [0.9.40 | Solar Flare Release](https://github.com/mage-ai/mage-ai/releases/tag/0.9.4) * [0.9.00 | The Dial of Destiny Release](https://github.com/mage-ai/mage-ai/releases/tag/0.9.0) * [0.8.93 | Rise of the Beasts Release](https://github.com/mage-ai/mage-ai/releases/tag/0.8.93) * [0.8.86 | Fast Release](https://github.com/mage-ai/mage-ai/releases/tag/0.8.86) * [0.8.83 | Fury of the Gods Release](https://github.com/mage-ai/mage-ai/releases/tag/0.8.83) * [0.8.78 | Rise of the Machines Release](https://github.com/mage-ai/mage-ai/releases/tag/0.8.78) * [0.8.75 | Guardians Release](https://github.com/mage-ai/mage-ai/releases/tag/0.8.75) * [0.8.69 | Hairy Otter Release](https://github.com/mage-ai/mage-ai/releases/tag/0.8.69) * [0.8.58 | Once & Always Release](https://github.com/mage-ai/mage-ai/releases/tag/0.8.58) * [0.8.52 | The Super Mario Bros. Release](https://github.com/mage-ai/mage-ai/releases/tag/0.8.52) * [0.8.44 | Dungeons and Dragons Release](https://github.com/mage-ai/mage-ai/releases/tag/0.8.44) * [0.8.37 | Foundation Release](https://github.com/mage-ai/mage-ai/releases/tag/0.8.37) * [0.8.29 | Wick Release](https://github.com/mage-ai/mage-ai/releases/tag/0.8.29) * [0.8.27 | Shazam Release](https://github.com/mage-ai/mage-ai/releases/tag/0.8.27) * [0.8.24 | Merlin Release](https://github.com/mage-ai/mage-ai/releases/tag/0.8.24) * [0.8.15 | Creed Release](https://github.com/mage-ai/mage-ai/releases/tag/0.8.15) * [0.8.11 | The Mandalorian Release](https://github.com/mage-ai/mage-ai/releases/tag/0.8.11) * [0.8.3 | Everything Everywhere All at Once Release](https://github.com/mage-ai/mage-ai/releases/tag/0.8.3) * [0.7.98 | Quantumania Release](https://github.com/mage-ai/mage-ai/releases/tag/0.7.98) * [0.7.90 | That '90s Show Release](https://github.com/mage-ai/mage-ai/releases/tag/0.7.90) * [0.7.84 | Rabbit Release](https://github.com/mage-ai/mage-ai/releases/tag/0.7.84) * [0.7.74 | Lunar Release](https://github.com/mage-ai/mage-ai/releases/tag/0.7.74) # Roadmap Source: https://docs.mage.ai/about/roadmap > **Roadmap** > > Mage's 2024 Roadmap coming soon! [https://airtable.com/embed/applEuqJsK4zF5yJK/shrJctaGt4tvU27uF?backgroundColor=red\&viewControls=on](https://airtable.com/embed/applEuqJsK4zF5yJK/shrJctaGt4tvU27uF?backgroundColor=red\&viewControls=on) # Help improve the tool Source: https://docs.mage.ai/about/statistics Please contribute usage statistics to help improve the developer experience for you and everyone in the community ๐Ÿค. > [!TIP] > > All usage statistics are completely **anonymous**. > > Itโ€™s **impossible** for Mage to know which statistics belongs to whom. ![Combine our powers](https://media2.giphy.com/media/0Av9l0VIc01y1isrDw/giphy.gif) ## ๐Ÿ™ Why is this important? By opting into sending usage statistics to [Mage](https://www.mage.ai/), itโ€™ll help the team and community of contributors (Magers) learn whatโ€™s going wrong with the tool and what improvements can be made. In addition to helping reduce potential errors, youโ€™ll help inform which features are useful and which need work. ## ๐Ÿค” What usage statistics am I sending? ### Project UUID Each project will have a universally unique identifier. This will help Mage count how many projects have been created. > [!NOTE] > > Itโ€™s **impossible** to associate a UUID with a project without knowing the pair together. Your project UUID is stored in the projectโ€™s `metadata.yaml` file, located at the root of your project: `[project_name]/metadata.yaml`. Here is an example of what it could look like: ```yaml theme={"system"} variables_dir: ~/.mage_data # ... project_uuid: 4279d28ab1f64644b1f2f4f779be7b7e ``` ### Number of pipelines Sending usage statistics will include the number of pipelines in a single project. This will help improve the coding experience when building pipelines. ### Number of pipeline runs Sending usage statistics will include the number of times any pipeline has ran in a single project. This will help add better pipeline management features. ### Number of users Sending usage statistics will include the number of users in a single project. This will help improve the collaboration capabilities of the tool. > [!NOTE] > > This usage statistic is only included if > [user authentication](/production/authentication/overview) is enabled. ### Errors When an application error occurs in Mage, the error type, error message, and offending line of code will be included in the usage statistics. This will help fix bugs and improve the developer experience. ### Platform The operating system, release, version, etc of the machine that Mage is running on. This information will help reproduce errors. ## ๐Ÿคทโ€โ™€๏ธ How does this work? Usage statistics are anonymously sent to Mageโ€™s online server. Hereโ€™s a sample of the JSON payload containing usage statistics that could be sent: ```json theme={"system"} { "usage_statistic": { "project_uuid": "4279d28ab1f64644b1f2f4f779be7b7e", "pipelines": 40, "pipeline_runs": 357, "users": 13, "platform": "Linux-5.15.49-linuxkit-aarch64-with-glibc2.31", "version": "0.8.70", "error": { "message": "...", "traceback": "..." } } } ``` ### Enable To enable sending usage statistics, add a key in the projectโ€™s `metadata.yaml` file called `help_improve_mage` with the value `true`. Here is an example: ```yaml theme={"system"} project_uuid: 4279d28ab1f64644b1f2f4f779be7b7e help_improve_mage: true ``` ### Disable To disable, change the value of `help_improve_mage` to `false`. Here is an example: ```yaml theme={"system"} project_uuid: 4279d28ab1f64644b1f2f4f779be7b7e help_improve_mage: false ``` # Authentication Source: https://docs.mage.ai/agent/authentication Log in to your Mage Pro cluster and manage credentials. ## Interactive login ```bash theme={"system"} mage-agent login ``` The CLI prompts for: 1. Your Mage Pro cluster URL (e.g. `https://app.mage.ai`) 2. Email 3. Password On success, mage-agent writes your credentials to `~/.mage-agent/config.json` and fetches remote skill files from the cluster. ## Non-interactive login Pass all values as flags to skip prompts โ€” useful in CI or scripted environments: ```bash theme={"system"} mage-agent login \ --cluster-url https://your-mage-url \ --email YOUR_EMAIL \ --password YOUR_PASSWORD ``` ## Credential file Credentials are stored at `~/.mage-agent/config.json` with `600` permissions (owner read/write only): ```json theme={"system"} { "cluster_url": "https://your-mage-url", "oauth_token": "YOUR_OAUTH_TOKEN" } ``` > [!WARNING] > > Do not commit `~/.mage-agent/config.json` to version control or share it. The OAuth token provides full access to your Mage Pro cluster. You can also create this file manually if you already have an OAuth token โ€” mage-agent will pick it up automatically. ## Re-authenticating If you see `AUTH_EXPIRED` errors, your session token has expired. Run `mage-agent login` again to get a fresh token. ## How authentication is used All MCP tool calls and sync operations send the OAuth token as a bearer credential to your cluster. You can override the default API key by adding an `api_key` field to the config file: ```json theme={"system"} { "cluster_url": "https://your-mage-url", "oauth_token": "YOUR_OAUTH_TOKEN", "api_key": "YOUR_API_KEY" } ``` # CLI Reference Source: https://docs.mage.ai/agent/cli-reference All mage-agent commands and their options. ## Global flags These flags apply to every command: | Flag | Default | Description | | - | - | - | | `--log-level` | `INFO` | Log verbosity: `DEBUG`, `INFO`, `WARNING`, `ERROR` | | `--format-output` | `json` | Output format: `json` or `human` | You can also set `MAGE_AGENT_LOG_LEVEL` as an environment variable: ```bash theme={"system"} MAGE_AGENT_LOG_LEVEL=DEBUG mage-agent sync-status ``` *** ## `mage-agent login` Authenticate with your Mage Pro cluster and save credentials. ```bash theme={"system"} mage-agent login [OPTIONS] ``` | Option | Description | | - | - | | `--cluster-url URL` | Mage Pro cluster URL | | `--email EMAIL` | Account email | | `--password PASSWORD` | Account password | If any option is omitted, the CLI prompts interactively. On success, writes `~/.mage-agent/config.json` and fetches remote skill files from the cluster. *** ## `mage-agent mcp` Start the MCP stdio server. This is the command your IDE or AI agent launches. ```bash theme={"system"} mage-agent mcp ``` No options. The server reads JSON-RPC requests from stdin and writes responses to stdout. Logs go to stderr. *** ## `mage-agent sync-project-to-local` Pull all remote project files to a local directory. ```bash theme={"system"} mage-agent sync-project-to-local [--local-project-dir PATH] ``` | Option | Default | Description | | - | - | - | | `--local-project-dir` | `.mage-agent/local_sync` | Destination directory | *** ## `mage-agent sync-status` Show what has changed between local and remote. ```bash theme={"system"} mage-agent sync-status [--local-project-dir PATH] ``` Output groups files into: `remote_to_local`, `local_to_remote`, `conflicts`, `in_sync`. Use `--format-output human` for a readable table. *** ## `mage-agent sync-local-to-remote` Push locally changed files to the cluster. ```bash theme={"system"} mage-agent sync-local-to-remote [--local-project-dir PATH] ``` Only files with `local_to_remote` status are uploaded. *** ## `mage-agent sync` Bidirectional sync with interactive conflict resolution. ```bash theme={"system"} mage-agent sync [--local-project-dir PATH] ``` For each conflicting file, prompts: `[r]emote / [l]ocal / [s]kip`. # IDE Integration Source: https://docs.mage.ai/agent/ide-integration Connect Cursor, Claude Code, Claude Desktop, OpenAI Codex CLI, or another MCP-compatible AI client to your Mage Pro cluster via MCP. Only in Mage Pro. Try our fully managed solution to access this advanced feature. [Get started for free](https://cloud.mage.ai/sign-up?source=mage-agent-ide-integration) mage-agent exposes a [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server over stdio. Any MCP-compatible AI client can connect by launching `mage-agent mcp` as a subprocess. ## Prerequisites For manual MCP configuration, complete [Installation](/agent/installation) and [Authentication](/agent/authentication) before setting up IDE integration. For Claude Desktop, use the [bundled Desktop extension](/agent/mage-agent-plugin#claude-desktop) and its setup flow. It includes the executable and does not require the Claude Code CLI or a Python installation. *** ## Cursor **1. Open MCP settings** In Cursor, go to **Settings โ†’ MCP** (or open the Command Palette and search for "MCP Servers"). **2. Add mage-agent** Add the following server config: ```json theme={"system"} { "mcpServers": { "mage-agent": { "command": "mage-agent", "args": ["mcp"] } } } ``` **3. Reload Cursor** Save the config and reload the window. Confirm that `mage-agent` tools appear in the MCP tool list. *** ## Claude Code **1. Add the MCP server via CLI** ```bash theme={"system"} claude mcp add mage-agent -- mage-agent mcp ``` Or add it manually to `.claude/settings.json` in your project (or `~/.claude/settings.json` globally): ```json theme={"system"} { "mcpServers": { "mage-agent": { "command": "mage-agent", "args": ["mcp"] } } } ``` **2. Restart Claude Code** Restart the Claude Code session. Run a quick sanity check: > "Use the `pipeline_list` tool to list my Mage pipelines" *** ## OpenAI Codex CLI **1. Edit your Codex config** Add `mage-agent` to the `mcpServers` section of your Codex config file: ```json theme={"system"} { "mcpServers": { "mage-agent": { "command": "mage-agent", "args": ["mcp"] } } } ``` **2. Restart Codex CLI** Restart Codex CLI and verify tools and resources are visible. ## PATH issues If `mage-agent` is not found when the IDE launches the MCP server, use the absolute path to the executable: ```bash theme={"system"} which mage-agent # e.g. /Users/you/.venv/bin/mage-agent ``` ```json theme={"system"} { "mcpServers": { "mage-agent": { "command": "/Users/you/.venv/bin/mage-agent", "args": ["mcp"] } } } ``` *** ## Skill resources When connected, your AI assistant can read bundled Markdown guidance through MCP resources. The catalog includes pipeline, execution, data preview, and chart guidance. Examples: | Resource URI | Content | | - | - | | `skill://pipeline` | Pipeline CRUD patterns and conventions | | `skill://blocks` | Block inspection and editing guidance | | `skill://executions` | Run triggers and log retrieval | | `skill://sync` | Sync operations and conflict handling | | `skill://data_previews` | Explore Data discovery and preview guidance | | `skill://visualization_charts` | Saved chart configuration and analysis | | Installed clients expose AI-ready data tools and guidance without a local | | | `AI_READY_DATA_ENABLED` flag. Operations still require support, configuration, | | | and permissions on the connected cluster; unsupported or disabled calls can | | | return API errors. Clients decide how to display or load MCP resources. | | # Installation Source: https://docs.mage.ai/agent/installation System requirements and install options for mage-agent. Only in Mage Pro. Try our fully managed solution to access this advanced feature. [Get started for free](https://cloud.mage.ai/sign-up?source=mage-agent-installation) ## Requirements * A Mage Pro cluster (URL + account credentials) * Your chosen AI client * Python **3.10** or newer for PyPI or source installation; bundled installers and the Claude Desktop extension include the Mage Agent executable ## Download from Mage Pro In Mage Pro, open **Settings** > **Plugins** > **Mage Agent** to download the latest Mage Agent installer for Claude Code or OpenAI Codex CLI. The page lists the latest GitHub release assets for macOS and Windows, including file sizes and checksums. Download links use GitHub's stable latest-release asset URLs, so Mage Pro does not need source changes when release tags or asset URLs change. Use the download that matches your operating system and AI coding client, then follow the prompts from the installer. ## Claude Desktop extension Claude Desktop uses a separate `.mcpb` extension for macOS or Windows. It includes the standalone Mage Agent executable and does not require Python or Claude Code. See the [plugin installation guide](/agent/mage-agent-plugin#claude-desktop) for package selection and setup. The Claude Code `.pkg` and `.zip` installers are for Claude Code. ## Install from PyPI ```bash theme={"system"} pip install mage-agent ``` We recommend installing inside a virtual environment: ```bash theme={"system"} python -m venv .venv source .venv/bin/activate # Windows: .venv\Scripts\activate pip install mage-agent ``` Verify: ```bash theme={"system"} mage-agent --version ``` ## Install from source ```bash theme={"system"} git clone https://github.com/mage-ai/mage-agent.git cd mage-agent python -m venv .venv source .venv/bin/activate pip install -e . ``` ## IDE PATH requirement When you configure your IDE to launch `mage-agent mcp`, the IDE may use a different `PATH` than your terminal. If the MCP server fails to start, use the absolute path to the executable: ```bash theme={"system"} which mage-agent # e.g. /Users/you/.venv/bin/mage-agent ``` Then update your IDE config: ```json theme={"system"} { "mcpServers": { "mage-agent": { "command": "/Users/you/.venv/bin/mage-agent", "args": ["mcp"] } } } ``` # Introduction Source: https://docs.mage.ai/agent/introduction Build and manage Mage data pipelines directly from your AI coding assistant. Only in Mage Pro. Try our fully managed solution to access this advanced feature. [Get started for free](https://cloud.mage.ai/sign-up?source=mage-agent) **Mage Agent** connects your local development environment to your Mage Pro cluster through the [Model Context Protocol (MCP)](https://modelcontextprotocol.io). Your AI assistant can inspect, create, modify, and run Mage pipelines using natural language โ€” and a built-in sync engine keeps local files in step with the cluster. > **[Quickstart](/agent/quickstart)** > > Get connected in under five minutes. > **[IDE Integration](/agent/ide-integration)** > > Connect Cursor, Claude Code, OpenAI Codex CLI, or another MCP-compatible client. > **[Sync](/agent/sync)** > > Mirror your Mage project to local files. > **[MCP Tools](/agent/mcp-tools)** > > Full reference for every tool your AI can call. ## How it works ``` Your AI assistant โ”€โ”€MCPโ”€โ”€โ–บ mage-agent โ”€โ”€RESTโ”€โ”€โ–บ Mage Pro cluster โ”‚ โ”‚ โ”‚ sync engine โ””โ”€โ”€ local files โ—„โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ ``` 1. **MCP server** โ€” mage-agent runs as a background stdio process. Your IDE or AI agent sends tool calls over JSON-RPC; mage-agent translates them into Mage Pro REST API requests. 2. **Skill resources** โ€” the server exposes Markdown guidance files that give your AI assistant context on how to interact with pipelines, blocks, runs, and sync operations. 3. **Sync engine** โ€” a separate CLI layer lets you pull the full remote project tree to a local directory, push local edits back, and resolve conflicts file by file. ## Supported clients > **Cursor** > **Claude Code** > **OpenAI Codex CLI** Any MCP-compatible client that can launch a subprocess will work with the same configuration. # Mage Agent Plugin Source: https://docs.mage.ai/agent/mage-agent-plugin Install the Mage Agent Plugin and connect it to a Mage cluster. # Mage Agent Plugin Installation Guide Only in Mage Pro. Try our fully managed solution to access this advanced feature. [Get started for free](https://cloud.mage.ai/sign-up?source=mage-agent-plugin) ## What It Is The Mage Agent Plugin connects an AI agent client to Mage so the agent can work with the Mage clusters you authorize. After installation and sign-in, the agent can help inspect and operate Mage workflows, including pipelines, blocks, schedules, runs, logs, outputs, files, and other Mage project resources. ## Where To Download It Download the installer from the public Mage Agent Plugin releases repository: ```text theme={"system"} https://github.com/mage-ai/agent-plugin/releases ``` The `mage-ai/agent-plugin` repository is the public release-asset repository. The plugin source and release automation are maintained in the Mage plugin source under: ```text theme={"system"} mage-pro/plugins/mage-agent-plugin ``` ## Choose The Correct Installer Use the package that matches your agent client and operating system. Claude Code and Claude Desktop use different packages. macOS: ```text theme={"system"} Mage-Agent-MacOS-Codex.pkg Mage-Agent-MacOS-Claude.pkg ``` Windows: ```text theme={"system"} Mage-Agent-Windows-Codex.zip Mage-Agent-Windows-Claude.zip ``` Use the Codex package if you are installing the plugin for Codex. Use the Claude package if you are installing it for Claude Code. For Claude Desktop, use the separate `.mcpb` extension described below. ### Claude Desktop The Claude Desktop extension bundles the standalone Mage Agent executable; it does not require Python or the Claude Code CLI. Choose the file for your computer: | Computer | Extension file | | - | - | | macOS with Apple silicon | `Mage-Agent-Claude-Desktop-darwin-arm64.mcpb` | | macOS with an Intel processor | `Mage-Agent-Claude-Desktop-darwin-x64.mcpb` | | Windows x64 | `Mage-Agent-Claude-Desktop-windows-x64.mcpb` | It exposes the same shared API-backed tools and bundled skill guidance through MCP. Claude Desktop decides how to display and load that guidance. Use a Desktop extension supplied with the release or test build you are installing. The `.pkg` and `.zip` files named for Claude Code install into Claude Code and do not register a Claude Desktop extension. 1. In Claude Desktop, open **Settings** > **Extensions** > **Advanced settings** > **Install Extension**, select the `.mcpb` file, and follow the installation prompts. 2. Enable the Mage extension, then start a conversation. 3. Ask: "Connect Mage to my cluster" and provide the cluster name or URL. 4. Complete the Mage sign-in in your browser when prompted, then return to Claude Desktop. 5. Ask: "What Mage tools are available?" or "List my Mage pipelines." The extension starts the bundled executable directly. You do not need to enter a token into extension settings. The first tool that needs authentication can also start browser sign-in automatically. If Mage Cloud tools are missing after your first sign-in, restart the extension to refresh its tool list. Claude Desktop reuses the Mage connection stored in `~/.mage/agent/config.json`. The selected cluster is shared with other Mage Agent clients on the same computer. To change it, ask "Connect Mage to `https://your-mage-cluster-url`"; this updates the shared connection. If a tool fails, check the active cluster, your access, and the server's feature configuration before retrying. ## Prerequisites Before installing, make sure you have: * Access to the Mage cluster you want the agent to use. * The cluster name or cluster URL. * The correct agent client installed, such as Codex, Claude Code, or Claude Desktop with desktop extension support. * For Claude Code, the Claude Code CLI must be installed and support plugins. For Claude Code, verify: ```bash theme={"system"} claude plugin --help ``` ## Install On macOS 1. Open the GitHub Releases page: ```text theme={"system"} https://github.com/mage-ai/agent-plugin/releases ``` 2. Download the correct `.pkg` file: ```text theme={"system"} Mage-Agent-MacOS-Codex.pkg Mage-Agent-MacOS-Claude.pkg ``` 3. Open the downloaded package. 4. Follow the installer prompts. 5. When the installer finishes, the Mage plugin is installed for the selected agent client. The macOS installer starts the Mage OAuth sign-in helper after installing the plugin. ## Install On Windows 1. Open the GitHub Releases page: ```text theme={"system"} https://github.com/mage-ai/agent-plugin/releases ``` 2. Download the correct `.zip` file: ```text theme={"system"} Mage-Agent-Windows-Codex.zip Mage-Agent-Windows-Claude.zip ``` 3. Extract the zip file. 4. Run the installer command inside the extracted folder. For Codex: ```powershell theme={"system"} .\Install-Codex.cmd ``` For Claude Code: ```powershell theme={"system"} .\Install-Claude-Code.cmd ``` ## Sign In To Mage After installing, sign in to Mage and connect the plugin to a cluster. If the installer opens the sign-in flow automatically, complete the browser login and select or provide the Mage cluster. If you need to sign in manually from the plugin source checkout, run: ```bash theme={"system"} ./plugins/mage-agent-plugin/scripts/mage-login ``` Example: ```bash theme={"system"} ./plugins/mage-agent-plugin/scripts/mage-login mageai-1-tutorials ``` You can also use a full cluster URL: ```bash theme={"system"} ./plugins/mage-agent-plugin/scripts/mage-login https://your-mage-cluster-url ``` ## Switch Clusters To connect the plugin to a different Mage cluster, run: ```bash theme={"system"} ./plugins/mage-agent-plugin/scripts/mage-switch-cluster ``` To skip the cluster selection screen, pass the cluster name or URL directly: ```bash theme={"system"} ./plugins/mage-agent-plugin/scripts/mage-switch-cluster ``` Example: ```bash theme={"system"} ./plugins/mage-agent-plugin/scripts/mage-switch-cluster mageai-1-tutorials ``` ## Verify The Active Cluster Check which Mage cluster is currently connected: ```bash theme={"system"} ./plugins/mage-agent-plugin/scripts/mage-current-cluster ``` List saved local cluster state: ```bash theme={"system"} ./plugins/mage-agent-plugin/scripts/mage-list-clusters ``` ## What Gets Saved Locally After sign-in, the plugin stores the active Mage connection locally at: ```text theme={"system"} ~/.mage/agent/config.json ``` That file stores the selected `cluster_url` and the token needed for the plugin to call Mage on your behalf. OAuth helper logs are written to: ```text theme={"system"} ~/.mage/agent/codex-oauth.log ``` ## Confirm It Works After installation and sign-in: 1. Open your agent client. 2. Ask the agent to use Mage. 3. Try a read-only request first, such as listing available Mage pipelines or checking the current cluster. 4. If the agent asks you to authenticate, complete the browser sign-in and retry the request. ## Quick Checklist * Download installer from `https://github.com/mage-ai/agent-plugin/releases`. * Pick Codex, Claude Code, or Claude Desktop. * Pick the matching macOS `.pkg`, Windows `.zip`, or Desktop `.mcpb` file. * Install the package. * Sign in to Mage. * Provide or select the Mage cluster name or URL. * Verify the active cluster. * Ask the agent to run a simple Mage read-only request. # MCP Tools Source: https://docs.mage.ai/agent/mcp-tools Full reference for every tool your AI assistant can call via mage-agent. Only in Mage Pro. Try our fully managed solution to access this advanced feature. [Get started for free](https://cloud.mage.ai/sign-up?source=mage-agent-mcp-tools) Once mage-agent is connected to your IDE, your AI assistant has access to the following tools. All tools require valid authentication. > [!NOTE] > > In MCP clients that support rendered tool output, mage-agent returns compact > resource widgets for supported resource actions. Widgets are currently > available for pipelines, blocks, pipeline runs, block runs, block outputs, > pipeline schedules, and pipeline triggers. They do not change the tool > arguments or authentication flow; clients that do not support rendered output > still receive the normal structured tool response. ## Resource Widget Contract The widget path is an additive MCP Apps enhancement for read-only resource tools. A widget-enabled tool descriptor includes both `_meta.ui.resourceUri` and `_meta["openai/outputTemplate"]` pointing at the registered HTML resource. When the tool succeeds, mage-agent returns: * `structuredContent.kind = "mage_resource_widget"` * `structuredContent.schema_version` for renderer compatibility * `structuredContent.resource` and `structuredContent.action` * `structuredContent.state` as `ok`, `empty`, `loading`, or `error` * sanitized `records`, `summary`, `columns`, `filters`, and `pagination` * optional sanitized `mutation` metadata for create, update, or delete results * optional sanitized `graph` data for pipeline-oriented detail widgets, using normalized `nodes` and `edges` instead of raw pipeline YAML * `content[0].text` as a JSON fallback for clients that do not render widgets * `_meta["openai/widgetData"]` with widget-only rendering hints List and get widgets render the normal table or detail view. Mutating actions may render the returned record with a mutation summary banner and footer, such as `Operation: Create`; delete results without a returned record render a compact success state. The adapter must redact sensitive fields before they enter `structuredContent`, fallback `content`, widget `_meta`, or activity logs. Pipeline-oriented widgets may include a compact graph preview when Mage returns block dependency metadata. The graph shape is: ```json theme={"system"} { "nodes": [ { "id": "load_customers", "label": "Load customers", "type": "data_loader", "status": "completed", "selected": false } ], "edges": [ { "source": "load_customers", "target": "segment_customers" } ], "totalNodes": 12, "truncated": false } ``` Renderers should treat graph data as optional. If it is missing, malformed, or too large, the widget must fall back to the existing list/detail table without blocking the tool response. ## Adding Widget Support To add another Mage resource widget: 1. Add the resource/action pair to `widget_contracts.py`. 2. Add presentation columns, summary fields, empty/error copy, and guidance in `widget_registry.py`. 3. Add adapter tests that cover populated, empty, malformed, large-result, and secret-bearing payloads. 4. Add renderer coverage in `widgets/resource_widget` and the app-shell preview route under `/apps/test/resource-widgets`. 5. Run the MCP protocol tests and an EKS mocked app-shell visual check before calling the change QA-ready. For normal Mage trigger inventory, active trigger counts, API/webhook trigger lists, run-once schedules, and next run dates, use `pipeline_schedules`. Use `pipeline_triggers` only when the user explicitly asks for the advanced `PipelineTriggerResource` config surface scoped to a pipeline. *** ## AI Chat context > **current\_page\_context** > > Read the visible non-chat text that Mage Pro AI Chat captured from the user's current browser page for the active chat turn. > > This tool is only registered when Mage Pro AI Chat starts with captured page context. Standard IDE MCP sessions do not expose it unless `MAGE_AGENT_CURRENT_PAGE_CONTEXT_PATH` points to a valid context sidecar file. > > | Parameter | Type | Required | Description | > | - | - | - | - | > | `include_text` | boolean | no | Return the captured page text. Set to `false` to return metadata only. | > > > [!NOTE] > > > > The context is scoped to the authenticated user and chat session, excludes the chat UI, and should only be used for page-relative requests such as "explain this page" or "what am I looking at?" *** ## Pipelines > **pipeline\_list** > > List all pipelines in the project. > > **Arguments:** none > > **Example prompt:** *"List all my Mage pipelines"* > **pipeline\_get** > > Get details for a single pipeline. > > | Parameter | Type | Required | Description | > | - | - | - | - | > | `uuid` | string | yes | Pipeline UUID | > **pipeline\_create** > > Create a new pipeline. > > | Parameter | Type | Required | Description | > | - | - | - | - | > | `name` | string | yes | Pipeline name | > | `type` | string | no | `python` (default), `streaming`, or `integration` | > > **Example prompt:** *"Create a new streaming pipeline called `realtime_events`"* > **pipeline\_update** > > Update fields on an existing pipeline. > > | Parameter | Type | Required | Description | > | - | - | - | - | > | `uuid` | string | yes | Pipeline UUID | > | `name` | string | no | New name | > | `description` | string | no | Updated description | > **pipeline\_delete** > > Delete a pipeline by UUID. > > | Parameter | Type | Required | Description | > | - | - | - | - | > | `uuid` | string | yes | Pipeline UUID | > > > [!WARNING] > > > > Deletion is permanent and cannot be undone. *** ## Blocks > **block\_list** > > List all blocks in a pipeline. > > | Parameter | Type | Required | Description | > | - | - | - | - | > | `pipeline_uuid` | string | yes | Pipeline UUID | > **block\_get** > > Get block details including source code. > > | Parameter | Type | Required | Description | > | - | - | - | - | > | `pipeline_uuid` | string | yes | Pipeline UUID | > | `uuid` | string | yes | Block UUID | > **block\_create** > > Create a new block in a pipeline. > > | Parameter | Type | Required | Description | > | - | - | - | - | > | `pipeline_uuid` | string | yes | Pipeline UUID | > | `name` | string | yes | Block name | > | `type` | string | yes | Block type (see below) | > | `language` | string | no | `python` (default), `sql`, `r`, `yaml`, `markdown` | > | `content` | string | no | Initial source code | > | `upstream_blocks` | array | no | UUIDs of upstream blocks | > | `config` | object | no | Additional block configuration | > > **Supported block types:** > `ai`, `data_loader`, `transformer`, `data_exporter`, `sensor`, `callback`, `chart`, `conditional`, `custom`, `dbt`, `extension`, `global_data_product`, `markdown`, `scratchpad` > > AI blocks are available in Mage Pro only. For Sidekick-powered agent blocks, use `type="ai"`, `language="yaml"`, and YAML content with top-level `type: agent`. > > > [!NOTE] > > > > If no `config` is provided, mage-agent automatically matches a block template for you. For `integration` pipelines, it also auto-detects available sources and destinations. > > **Example prompt:** *"Add a SQL transformer block to the `customer_etl` pipeline that filters rows where revenue > 1000"* > **block\_update** > > Update a block's code or configuration. > > | Parameter | Type | Required | Description | > | - | - | - | - | > | `pipeline_uuid` | string | yes | Pipeline UUID | > | `uuid` | string | yes | Block UUID | > | `content` | string | no | New source code | > | `name` | string | no | New name | > | `upstream_blocks` | array | no | Updated upstream block UUIDs | > **block\_templates\_list** > > List available block templates. > > | Parameter | Type | Required | Description | > | - | - | - | - | > | `force_refresh` | boolean | no | Bypass the daily cache and re-fetch from cluster | > > Templates are cached for 24 hours at `~/.mage-agent/cache/block_templates.json`. *** ## Runs & Logs > **run\_pipeline** > > Trigger a pipeline run. > > | Parameter | Type | Required | Description | > | - | - | - | - | > | `pipeline_uuid` | string | yes | Pipeline UUID | > | `payload` | object | no | Optional run payload (variables, etc.) | > > **Example prompt:** *"Run the `daily_refresh` pipeline"* > **run\_logs** > > Fetch logs for a specific pipeline run. > > | Parameter | Type | Required | Description | > | - | - | - | - | > | `pipeline_run_id` | string | yes | Pipeline run ID (returned by `run_pipeline`) | > > **Example prompt:** *"Show me the logs for the last run"* *** ## Sync > **sync\_project\_to\_local** > > Pull all remote project files to a local directory. > > | Parameter | Type | Required | Description | > | - | - | - | - | > | `local_project_dir` | string | no | Local directory path (default: `.mage-agent/local_sync`) | > **sync\_status** > > Show what has changed between local and remote. > > | Parameter | Type | Required | Description | > | - | - | - | - | > | `local_project_dir` | string | no | Local directory path | > **sync\_local\_to\_remote** > > Push locally changed files to the cluster. > > | Parameter | Type | Required | Description | > | - | - | - | - | > | `local_project_dir` | string | no | Local directory path | *** ## Mage Cloud Backend Mage Cloud Backend tools are exposed only for installed-agent sessions that have Cloud handoff credentials. These tools are generated from the Cloud Backend resource inventory, so call `mage_tool_contract` before invoking a Cloud tool when payload or query shape matters. > **Cloud Backend contracts** > > Cloud Backend create and update requests use the same resource-root envelope > that the backend API expects. Do not send flat mutation payloads. > > | Tool | Mutation payload root | > | - | - | > | `teams` | `team` | > | `cloud_users` | `user` | > | `team_memberships` | `team_membership` | > | `invitations` | `invitation` | > > Role fields use Cloud Backend integer values: owner `0`, admin `1`, > editor `2`, viewer `3`. > > For example, creating a team invitation uses: > > ```json theme={"system"} > { > "action": "create", > "identifiers": { > "team_id": "42" > }, > "payload": { > "invitation": { > "invitee_email": "user@example.com", > "role": 3 > } > } > } > ``` > > `cluster_stats` requires `query.cluster_uuid`; `cluster_uuid` is not a path > identifier for that tool. > > `cloud_users` supports `list`, `get`, and `update`. It does not expose > `create`, because Cloud Backend treats `users.create` as the public signup > path rather than a private team-admin user creation API. *** ## Error responses All tool errors return a structured envelope: ```json theme={"system"} { "status": "error", "error": { "code": "AUTH_EXPIRED", "message": "Session token expired. Run `mage-agent login` to re-authenticate." } } ``` | Error code | Cause | | - | - | | `CONFIG_INVALID` | Missing or malformed `~/.mage-agent/config.json` | | `AUTH_REQUIRED` | No credentials found | | `AUTH_EXPIRED` | 401/403 from cluster โ€” run `mage-agent login` | | `API_ERROR` | Cluster API returned an error | | `TOOL_NOT_FOUND` | Requested tool name is not registered | | `INTERNAL_ERROR` | Unexpected internal failure | # Quickstart Source: https://docs.mage.ai/agent/quickstart Install mage-agent, log in, and make your first AI-assisted pipeline call in under five minutes. **1. Install mage-agent** ```bash theme={"system"} pip install mage-agent ``` Verify the install: ```bash theme={"system"} mage-agent --version ``` **2. Log in to your Mage Pro cluster** ```bash theme={"system"} mage-agent login ``` The CLI prompts for your cluster URL, email, and password. On success, credentials are saved to `~/.mage-agent/config.json`. > [!TIP] > > To skip the prompts, pass flags directly: > > ```bash theme={"system"} > mage-agent login \ > --cluster-url https://your-mage-url \ > --email YOUR_EMAIL \ > --password YOUR_PASSWORD > ``` **3. Connect your AI assistant** Add the following to your IDE's MCP server config and restart the client: ```json theme={"system"} { "mcpServers": { "mage-agent": { "command": "mage-agent", "args": ["mcp"] } } } ``` See [IDE Integration](/agent/ide-integration) for client-specific setup instructions. **4. Try it** Ask your AI assistant: > "List all my Mage pipelines" > "Create a new Python transformer block in the `customer_etl` pipeline" > "Run the `daily_refresh` pipeline and show me the logs" The assistant calls the appropriate MCP tool automatically โ€” no manual API calls required. ## Next steps > **[Sync local files](/agent/sync)** > > Mirror your Mage project to your machine for local editing. > **[MCP tools reference](/agent/mcp-tools)** > > See every tool available to your AI assistant. # Syncing Local Files Source: https://docs.mage.ai/agent/sync Mirror your Mage Pro project to a local directory and push edits back to the cluster. The sync engine lets you work on pipeline files in your local IDE and keep them in sync with your Mage Pro cluster โ€” pulling remote changes down and pushing local edits back up. ## Supported file types `.py`, `.sql`, `.r`, `.yaml`, `.yml`, `.md`, `.txt` *** ## Pull remote files to local Download the full remote project tree to a local directory: ```bash theme={"system"} mage-agent sync-project-to-local --local-project-dir ./my-mage-project ``` If `--local-project-dir` is omitted, the CLI prompts for a path (default: `.mage-agent/local_sync`). *** ## Check sync status See what has changed between your local copy and the cluster: ```bash theme={"system"} mage-agent sync-status --local-project-dir ./my-mage-project ``` Files are grouped into four categories: | Status | Meaning | | - | - | | `remote_to_local` | Remote changed since last sync โ€” pull needed | | `local_to_remote` | Local changed since last sync โ€” push needed | | `conflicts` | Both sides changed since last sync | | `in_sync` | No changes on either side | For a human-readable table instead of JSON: ```bash theme={"system"} mage-agent sync-status --local-project-dir ./my-mage-project --format-output human ``` *** ## Push local changes to the cluster ```bash theme={"system"} mage-agent sync-local-to-remote --local-project-dir ./my-mage-project ``` Only files flagged as `local_to_remote` are uploaded. *** ## Bidirectional sync with conflict resolution Run a full two-way sync in one command: ```bash theme={"system"} mage-agent sync --local-project-dir ./my-mage-project ``` For each conflicting file, mage-agent prompts: ``` pipelines/customer_etl/transformers/clean_names.py โ€” CONFLICT Remote modified: 2024-11-01 14:32 Local modified: 2024-11-01 15:10 Keep [r]emote / [l]ocal / [s]kip? ``` Choose `r`, `l`, or `s` for each file. Conflicts are never silently overwritten. *** ## Sync via AI assistant You can also trigger sync operations through your AI assistant using MCP tools: | Tool | What it does | | - | - | | `sync_project_to_local` | Pull remote files to local directory | | `sync_status` | Show remote/local diff | | `sync_local_to_remote` | Push local changes to cluster | Example prompt: > "Pull the latest remote changes to my local project at `./my-mage-project`" *** ## How sync state is tracked mage-agent stores a state file at `/.mage-agent-sync-state.json` after each sync. This file records the last-known timestamps for all tracked files, enabling accurate detection of what changed on each side. Do not delete or edit it manually. > [!NOTE] > > Files inside hidden directories (`.git`, `.venv`, etc.) and `__pycache__` folders are automatically excluded from sync. # Troubleshooting Source: https://docs.mage.ai/agent/troubleshooting Solutions for common mage-agent issues. ## Authentication errors > **"AUTH\_EXPIRED" or "AUTH\_REQUIRED" errors** > > Your session token has expired or is missing. > > ```bash theme={"system"} > mage-agent login > ``` > > This fetches a new token and overwrites the existing config. > **"CONFIG\_INVALID" error** > > The config file at `~/.mage-agent/config.json` is missing or malformed. > > Re-run login to recreate it: > > ```bash theme={"system"} > mage-agent login > ``` > > Or create the file manually: > > ```json theme={"system"} > { > "cluster_url": "https://your-mage-url", > "oauth_token": "YOUR_OAUTH_TOKEN" > } > ``` *** ## MCP / IDE issues > **MCP tools not showing in the IDE** > > 1. Confirm `mage-agent` is accessible from the IDE's runtime PATH โ€” or use an absolute path (see [Installation](/agent/installation#ide-path-requirement)). > 2. Save the MCP config and **restart** the IDE or agent client. > 3. Test the server directly in a terminal: > > ```bash theme={"system"} > mage-agent mcp > ``` > > If it starts without errors, the issue is the IDE config. If it errors, check authentication first. > **"command not found: mage-agent" in IDE** > > The IDE cannot find the executable. Run: > > ```bash theme={"system"} > which mage-agent > ``` > > Copy the full path and use it in your IDE config: > > ```json theme={"system"} > { > "mcpServers": { > "mage-agent": { > "command": "/full/path/to/mage-agent", > "args": ["mcp"] > } > } > } > ``` > **Tools are listed but calls fail** > > Run login again โ€” the MCP server may have started before credentials were saved, or the token expired during the session: > > ```bash theme={"system"} > mage-agent login > ``` > > Then restart the IDE to pick up fresh credentials. *** ## Sync issues > **Unexpected conflicts after syncing** > > Conflicts are detected by comparing timestamps on each side. Small clock differences between your machine and the cluster can cause false positives. > > Check what the conflict looks like before choosing a side: > > ```bash theme={"system"} > mage-agent sync-status --local-project-dir ./my-project --format-output human > ``` > > Then run `mage-agent sync` and choose `r` (remote) or `l` (local) for each affected file. > **Files not appearing in sync-status** > > Only these file extensions are tracked: `.py`, `.sql`, `.r`, `.yaml`, `.yml`, `.md`, `.txt`. > > Also check that the files are not inside a hidden directory (`.git`, `.venv`) or a `__pycache__` folder โ€” those are always excluded. > **Sync state file is missing or corrupted** > > The state file lives at `/.mage-agent-sync-state.json`. If it is missing, mage-agent treats all files as new and will re-pull the full project on the next `sync-project-to-local`. Delete it intentionally only if you want a clean baseline. *** ## Enable debug logging Add `--log-level DEBUG` to any command to see full request/response traces: ```bash theme={"system"} mage-agent --log-level DEBUG sync-status --local-project-dir ./my-project mage-agent --log-level DEBUG mcp ``` Or set the environment variable permanently in your shell profile: ```bash theme={"system"} export MAGE_AGENT_LOG_LEVEL=DEBUG ``` *** ## Still stuck? Open an issue at [github.com/mage-ai/mage-agent](https://github.com/mage-ai/mage-agent/issues) and include the debug log output. # Agents Source: https://docs.mage.ai/ai/agents Create YAML-backed AI agents with a backing pipeline and API endpoint. Only in Mage Pro. Try our fully managed solution to access this advanced feature. [Get started for free](https://cloud.mage.ai/sign-up?source=agents) Agents are AI blocks stored as YAML files under the project `agents/` folder. Each agent YAML file is the source of truth for the agent name, description, default instructions, backing pipeline, saved actions, status, and published endpoint metadata. Creating an agent from the Agents page or Agents API creates one backing pipeline named after the agent and one YAML block file in `agents/`. When a UUID is omitted, Mage derives it from the cleaned agent name. If that UUID already exists, the request is rejected so you can choose a different name or UUID. ```yaml theme={"system"} type: agent uuid: customer_support_agent_a1b2 name: Customer support agent description: Routes support questions. instructions: | Classify the request and recommend the next support workflow. pipeline_uuid: customer_support_agent actions: - pipeline_uuid: support_workflows block_uuid: triage_ticket status: draft endpoint: {} ``` ## Fields Use `instructions` for the saved default prompt. Runtime requests use `message`, which can be sent when running the agent. Existing `type: agent` AI blocks can still use `message` as the per-run user request. * `name`: Display name for the agent. * `description`: Short summary shown in the Agents list and detail view. * `instructions`: Default instructions stored with the agent. * `pipeline_uuid`: Backing pipeline used to execute and publish the agent. * `actions`: List of action references. Mage stores this list but runtime handling is defined separately. * `status`: `draft`, `published`, or `paused`. * `endpoint`: API trigger metadata written when the agent is published. Only YAML files with `type: agent` and `pipeline_uuid` appear in the Agents list. This keeps standalone agent blocks hidden unless they are associated with a backing pipeline. ## Publishing Publishing an agent marks it live by upserting an API trigger on the backing pipeline. Mage stores the trigger metadata in the agent YAML under `endpoint`, including the schedule ID and streaming run path. Publishing is idempotent. Re-publishing the same agent reuses the existing API trigger when possible instead of creating duplicate triggers. ## Running Publish the agent to enable its streaming endpoint. On the agent's **Endpoint** page, edit the JSON request body, then select **Run agent**. Set `pipeline_run.variables.message` to the request for this run and add any other runtime variables your agent needs: ```json theme={"system"} { "pipeline_run": { "variables": { "message": "Summarize yesterday's support tickets." } } } ``` The button POSTs that payload to the displayed streaming endpoint and displays the server-sent events (SSE) from the same response. The endpoint still creates a backing pipeline run, so its run ID and execution history remain available. See [Run agent](/extensibility/api-reference/agents/run-agent) for authentication and API examples. ## Chatting with an agent **Chat with agent** opens a Sidekick conversation with the agent's saved instructions and allowed actions. The conversation carries out the agent's work directly; it does not start the agent's own backing pipeline. When an action is needed, Sidekick can execute the configured action pipeline and report its run separately. Asking the agent to run does not make every assigned action mandatory: the agent chooses actions based on its instructions and the available data. # AI Clients Source: https://docs.mage.ai/ai/ai-client Use and enable different AI clients. ## AI Client You now have the option to select from various AI clients to harness [the capabilities of Mage AI](https://docs.mage.ai/guides/ai/overview), as detailed in the Mage AI capabilities documentation. Currently, we offer support for OpenAI and Hugging Face, with the promise of additional AI clients being added in the future. ## Use Hugging Face Client ### Setup #### Hugging Face Inference Endpoint In order to utilize the Hugging Face AI Client, it is necessary to establish a Hugging Face inference endpoint. You can set it up following [this guide](https://huggingface.co/inference-endpoints). This process is quite straightforward. It entails * selecting the specific model you wish to use, * determining the hosting environment (AWS or Azure), * specifying the geographical region, * choosing the type of GPU. For your convenience and based on our testing, we recommend using the "mistralai/Mistral-7B-Instruct-v0.1" model. Once the Inference endpoint is operational, it will provide you with an API URL and a corresponding token for establishing a secure connection. #### Mage Project Setup Within your Mage project's metadata YAML configuration, please include the subsequent "ai\_config" section: ``` ai_config: mode: 'hugging_face' open_ai_config: openai_api_key: key hugging_face_config: huggingface_api: api_url huggingface_inference_api_token: api_token ``` The "mode" parameter determines your selection of the AI client to be employed. It can be specified as either "open\_ai" or "hugging\_face," with the default value being set to "open\_ai." "hugging\_face\_config" as a mandatory configuration if you choose to use the hugging face client. This configuration includes the two essential elements obtained from the Hugging Face inference endpoint, namely, the API and Token. You are ready to go once the "ai\_config" is setup. At this point, you can fully leverage Mage AI's capabilities, such as generating blocks with text description, automatically write comments for your functions, etc. ## How to add a new AI Client You may find it necessary to employ an AI client other than those offered by OpenAI and Hugging Face. Additionally, you might wish to make direct calls to your Language Model (LLM). This can be accomplished by enabling a new AI client for your specific needs. This is an [example PR](https://github.com/mage-ai/mage-ai/pull/3850). ### Create new AI config Create a dedicated configuration to save the params required to connect to LLM in the [config.py](https://github.com/mage-ai/mage-ai/blob/92c372b24e08148863d799d9afcdd44483c11c89/mage_ai/orchestration/ai/config.py#L19). For instance, when using the Hugging Face client, the LLM is hosted within the inference endpoint, mandating both the API and Token for invoking the service for inference. In the OpenAI client, the OpenAI key is required to facilitate model inference. ### Create dedicated AI Client Inherit the [AIClient interface](https://github.com/mage-ai/mage-ai/blob/master/mage_ai/ai/ai_client.py) and implements the two required functions: โ€œinference\_with\_promptโ€ and โ€œfind\_block\_paramsโ€. * Inference\_with\_prompt function does the LLM model inference. It takes the prompt template, required variables being used in the prompt and return the inference result. * Find\_block\_params function does a multi classification based on code description to generate required types including block\_type, pipeline\_type, language, action type and data source. You can read your configuration in the Setup function and initialize the client to talk to your service. ### Enable in llm\_pipeline\_wizard The last action to take is modifying the Setup function within "[mage\_ai/ai/llm\_pipeline\_wizard.py](https://github.com/mage-ai/mage-ai/blob/92c372b24e08148863d799d9afcdd44483c11c89/mage_ai/ai/llm_pipeline_wizard.py#L195)" to introduce a new mode of your client and initialize your AI client. # AI Blocks Source: https://docs.mage.ai/ai/blocks Use AI blocks to turn prompts, upstream data, and pipeline context into reusable pipeline outputs. Only in Mage Pro. Try our fully managed solution to access this advanced feature. [Get started for free](https://cloud.mage.ai/sign-up?source=ai-blocks) [AI Blocks](https://www.youtube.com/embed/28pRdPk2DAQ) AI blocks bring generative AI into the same pipeline canvas as your loaders, transformers, exporters, and monitors. Use them to summarize data, classify records, draft messages, create structured JSON, generate code, or hand work to Mage Pro AI Sidekick when a task needs project context. Because AI blocks run inside a Mage pipeline, their answers can become real pipeline outputs. Downstream blocks can consume the final response just like any other block result. ## Create an AI Block Add an AI block to a pipeline, then describe the job in YAML. ```yaml theme={"system"} prompt: | Summarize the customer feedback from upstream blocks. Return the top themes and recommended next actions. ``` Run the block from the editor, or run the full pipeline from a trigger. Mage sends the prompt to the configured AI runtime and stores the final response as the block output. Use AI blocks when you want to: * summarize reports, logs, feedback, or operational data * extract structured fields from text * classify rows or events into business categories * generate code or SQL for a controlled workflow * turn upstream block outputs into plain-language recommendations * automate a decision step before the next pipeline block runs ## Use an Agent Block Create an Agent block when you want a Mage Pro pipeline step to run through Mage Pro AI Sidekick. Agent blocks are useful when the block should understand pipeline context, inspect upstream block outputs, and produce a final answer with the same project awareness users expect from Sidekick. ```yaml theme={"system"} prompt: | Use the upstream customer rows to summarize churn risk. message: Summarize the highest-risk customers and recommend next steps. settings: speed: fast output: level: default runtime: report_name: weekly_churn_review ``` Agent blocks use the block type `agent` and are saved as YAML under the `agents/` folder. New Agent block YAML does not need a top-level `type: agent` field; existing AI blocks that already use YAML `type: agent` still run for compatibility. Agent blocks run as part of the pipeline and return the final Sidekick answer as the block output. While Sidekick works, Mage prints progress and streamed response events to the block logs so users can see that the agent is running. Use Agent blocks when the task benefits from pipeline context: * "Read the upstream customer output and explain the highest churn risk." * "Review this pipeline run's logs and summarize what failed." * "Compare the two upstream datasets and write a short executive summary." * "Use the runtime variables and upstream rows to draft a customer follow-up." ## Fields ### `prompt` and `instructions` The main instruction for a standard AI block is `prompt`. YAML-backed Agents use `instructions` for the saved default prompt stored in the `agents/` folder. Keep either field clear and specific. Multi-line prompts are easier to read and maintain. ```yaml theme={"system"} prompt: | Write a three-bullet summary of the upstream sales report. Include one recommended action for the revenue team. ``` ```yaml theme={"system"} type: agent instructions: | You are a customer retention analyst. ``` ### `message` An optional user-style request for `type: agent` blocks. Use `instructions` for saved standing instructions on YAML-backed Agents, or `prompt` on standalone AI blocks, and use `message` for the specific request to answer on this run. ```yaml theme={"system"} prompt: | You are a customer retention analyst. message: Which accounts need attention this week? ``` ### `settings` Controls how the AI runtime should behave. For agent blocks, `speed: fast` is a good default when you want a quick operational answer. ```yaml theme={"system"} settings: speed: fast ``` ### `runtime` Optional context that travels with the block run. Use it for business labels, report names, or request metadata that helps the AI understand the job. ```yaml theme={"system"} runtime: customer_segment: enterprise report_name: renewal_risk ``` ### `output` Use `output` when you need the response to follow a predictable shape or control agent block logs. For Agent blocks, `output.level` controls how much Sidekick runtime output Mage prints while the block runs: * `default`: print streamed answer, narration/status, tool call, and error events. * `all`: print every runtime event, including completion and other low-level events. * `none`: do not print Sidekick runtime output; the final answer still becomes the block output. ```yaml theme={"system"} prompt: Review the upstream data and summarize the result. message: What changed since the last run? output: level: all ``` Use `format` when a non-agent AI block should return structured data. ```yaml theme={"system"} prompt: Extract customer details from the text. output: format: name: type: string description: Customer's full name email: type: string format: email priority: type: string enum: - low - medium - high ``` ### `validation` Use validation when the answer has to meet a business rule before it moves downstream. ```yaml theme={"system"} prompt: Draft a customer escalation summary. validation: Make sure the response includes the customer name, issue, impact, and next step. ``` ### `tools` Use tools when a standard AI block should choose and trigger another pipeline as part of the workflow. ```yaml theme={"system"} prompt: Analyze the request and choose the next processing pipeline. tools: prompt: Choose the best pipeline for the request. required: true pipelines: - uuid: customer_follow_up description: Creates customer follow-up tasks. variables: customer_id: type: string ``` ## Upstream Data AI and Agent blocks can sit downstream of regular Mage blocks. For Agent blocks, Sidekick receives references to upstream block outputs and can inspect those outputs through Mage instead of copying raw datasets into the prompt. ```yaml theme={"system"} prompt: | Read the upstream customer scores and event history. Explain the biggest churn risk in plain English. message: What should the account team do next? settings: speed: fast ``` The final answer becomes the AI block output. Downstream blocks can store it, send it to another system, or combine it with additional data. ## Examples ### Minimal Summary ```yaml theme={"system"} prompt: Summarize this document in five bullet points. ``` ### Structured Extraction ```yaml theme={"system"} prompt: Extract the renewal request from the customer note. output: format: customer_name: type: string renewal_date: type: string format: date requested_discount: type: number risk_level: type: string enum: - low - medium - high ``` ### Agent Block With Upstream Outputs ```yaml theme={"system"} prompt: | You are reviewing customer health data from upstream blocks. Use the available customer scores and recent events to identify retention risk. message: Summarize the top risks and recommended outreach. settings: speed: fast runtime: audience: account_team ``` ### Agent Block With No Message ```yaml theme={"system"} prompt: | Use the upstream rows to produce a short operational summary. settings: speed: fast ``` Use this pattern when the prompt itself is the complete request. ## Best Practices * Give the block one clear job. * Put reusable instructions in `instructions` for YAML-backed Agents or `prompt` for standalone AI blocks. * Put the run-specific ask in `message` for Agent blocks. * Use upstream blocks for data and the AI block for interpretation. * Use structured output when downstream blocks need predictable fields. * Keep runtime context business-focused, such as segment, audience, or report name. * Use Agent blocks when project context or upstream block output matters. # Customized AI resources for training and inference Source: https://docs.mage.ai/ai/custom-resources ## Custom resources Customized GPU accelerated resources for running AI/ML/LLM pipelines. Only in Mage Pro. Try our fully managed solution to access this advanced feature. [Get started for free](https://cloud.mage.ai/sign-up?source=ai-resources) ## Inference endpoints Deploy high-performance, low-latency API endpoints for executing blocks and returning output data, such as inference endpoints. Only in Mage Pro. Try our fully managed solution to access this advanced feature. [Get started for free](https://cloud.mage.ai/sign-up?source=ai-endpoints) # Machine learning pipeline tutorial Source: https://docs.mage.ai/ai/ml/train-model Build a machine learning pipeline to train a model on the Titanic dataset. ![Titanic](https://media.graphcms.com/TIobzTjRniW8wUAna6Ht) In this tutorial, weโ€™ll create a pipeline that does the following: 1. Load data from an online endpoint 2. Select columns and fill in missing values 3. Train a model to predict which passengers will survive If you prefer to skip the tutorial and view the finished code, follow [this guide](/guides/train/complete-project). If you havenโ€™t setup a project before, check out the [setup guide](/getting-started/setup) before starting. ## 1. Setup ### 1a. Add Python packages to project In the left sidebar (aka file browser), click on the `requirements.txt` file under the `demo_project/` folder. ![requirements](https://mage-ai.github.io/assets/requirements.png) Then add the following dependencies to that file: ```text theme={"system"} matplotlib requests scikit-learn ``` Then, save the file by pressing `โŒ˜ + S`. ### 2a. Install dependencies The simplest way is to run pip install from the tool. Add a scratchpad block by pressing the `+ Scratchpad` button. Then run the following command: ```bash theme={"system"} pip install -r demo_project/requirements.txt ``` Alternatively, here are other ways of installing dependencies (depending on if you are using Docker or not): #### Docker Get the name of the container that is running the tool: ```bash theme={"system"} docker ps ``` Sample output: ```bash Sample output theme={"system"} CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 214e1155f5c3 mage/data "python mage_ai/commโ€ฆ" 5 seconds ago Up 2 seconds mage-ai_server_run_6f8d367ac405 ``` The container name in the above sample output is `mage-ai_server_run_6f8d367ac405`. Then run this command to install Python packages in the `demo_project/requirements.txt` file: ```bash theme={"system"} docker exec [container_name] pip3 install -r demo_project/requirements.txt ``` ### pip If you arenโ€™t using Docker, just run the following command in your terminal: ```bash theme={"system"} pip3 install -r demo_project/requirements.txt ``` ## 2. Create new pipeline In the top left corner, click `File > New pipeline`. Then, click the name of the pipeline next to the green dot to rename it to `titanic survivors`. ![create new pipeline](https://mage-ai.github.io/assets/create-new-pipeline.gif) ## 3. Play around with scratchpad There are 4 buttons, click on the `+ Scratchpad` button to add a block. Paste the following sample code in the block: ```python theme={"system"} import matplotlib.pyplot as plt import numpy as np t = np.arange(0.0, 2.0, 0.01) s = 1 + np.sin(2*np.pi*t) plt.plot(t, s) plt.xlabel('time (s)') plt.ylabel('voltage (mV)') plt.title('About as simple as it gets, folks') plt.grid(True) plt.show() ``` Then click the `Play button` on the right side of the block to run the code. Alternatively, you can use the following keyboard shortcuts to execute code in the block: * โŒ˜ + Enter * Control + Enter * Shift + Enter (run code and add a new block) ![](https://mage-ai.github.io/assets/scratchpad.gif) Now that weโ€™re done with the scratchpad, we can leave it there or delete it. To delete a block, click the trash can icon on the right side or use the keyboard shortcut by typing the letter D and then D again. ## 4. Load data 1. Click the `+ Data loader` button, select `Python`, then click the template called `API`. 2. Rename the block to `load dataset`. 3. In the function named `load_data_from_api`, set the `url` variable to: `https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv`. 4. Run the block by clicking the play icon button or using the keyboard shortcuts `โŒ˜ + Enter`, `Control + Enter`, or `Shift + Enter`. After you run the block (โŒ˜ + Enter), you can immediately see a sample of the data in the blockโ€™s output. ![load data](https://mage-ai.github.io/assets/load-data.gif) Here is what the code should look like: ```python theme={"system"} import io import pandas as pd import requests from pandas import DataFrame if 'data_loader' not in globals(): from mage_ai.data_preparation.decorators import data_loader if 'test' not in globals(): from mage_ai.data_preparation.decorators import test @data_loader def load_data_from_api(**kwargs) -> DataFrame: """ Template for loading data from API """ url = 'https://raw.githubusercontent.com/mage-ai/datasets/master/titanic_survival.csv' response = requests.get(url) return pd.read_csv(io.StringIO(response.text), sep=',') @test def test_output(df) -> None: """ Template code for testing the output of the block. """ assert df is not None, 'The output is undefined' ``` ## 5. Transform data Weโ€™re going to select numerical columns from the original dataset, then fill in missing values for those columns (aka impute). 1. Click the `+ Transformer` button, select `Python`, then click `Generic (no template)`. 2. Rename the block to `extract and impute numbers`. 3. Paste the following code in the block: ```python theme={"system"} from pandas import DataFrame import math if 'transformer' not in globals(): from mage_ai.data_preparation.decorators import transformer def select_number_columns(df: DataFrame) -> DataFrame: return df[['Age', 'Fare', 'Parch', 'Pclass', 'SibSp', 'Survived']] def fill_missing_values_with_median(df: DataFrame) -> DataFrame: for col in df.columns: values = sorted(df[col].dropna().tolist()) median_age = values[math.floor(len(values) / 2)] df[[col]] = df[[col]].fillna(median_age) return df @transformer def transform_df(df: DataFrame, *args) -> DataFrame: return fill_missing_values_with_median(select_number_columns(df)) ``` After you run the block (โŒ˜ + Enter), you can immediately see a sample of the data in the blockโ€™s output. ![Transform data](https://mage-ai.github.io/assets/transform-data.gif) ## 6. Train model In this part, weโ€™re going to accomplish the following: 1. Split the dataset into a training set and a test set. 2. Train logistic regression model. 3. Calculate the modelโ€™s accuracy score. 4. Save the training set, test set, and model artifact to disk. Here are the steps to take: 1. Add a new data exporter block by clicking `+ Data exporter` button, select `Python`, then click `Generic (no template)`. 2. Rename the block to `train model`. 3. Paste the following code in the block: ```python theme={"system"} from pandas import DataFrame from sklearn.linear_model import LogisticRegression from sklearn.metrics import accuracy_score from sklearn.model_selection import train_test_split import os import pickle if 'data_exporter' not in globals(): from mage_ai.data_preparation.decorators import data_exporter LABEL_COLUMN = 'Survived' def build_training_and_test_set(df: DataFrame) -> None: X = df.drop(columns=[LABEL_COLUMN]) y = df[LABEL_COLUMN] return train_test_split(X, y) def train_model(X, y) -> None: model = LogisticRegression() model.fit(X, y) return model def score_model(model, X, y) -> None: y_pred = model.predict(X) return accuracy_score(y, y_pred) @data_exporter def export_data(df: DataFrame) -> None: X_train, X_test, y_train, y_test = build_training_and_test_set(df) model = train_model(X_train, y_train) score = score_model(model, X_test, y_test) print(f'Accuracy: {score}') cwd = os.getcwd() filename = f'{cwd}/finalized_model.lib' print(f'Saving model to {filename}') pickle.dump(model, open(filename, 'wb')) print(f'Saving training and test set') X_train.to_csv(f'{cwd}/X_train') X_test.to_csv(f'{cwd}/X_test') y_train.to_csv(f'{cwd}/y_train') y_test.to_csv(f'{cwd}/y_test') ``` Run the block (โŒ˜ + Enter). ![Train model](https://mage-ai.github.io/assets/train-model.gif) ## 7. Run pipeline We can now run the entire pipeline end-to-end. In your terminal, execute the following command: ```bash Docker theme={"system"} ./scripts/run.sh demo_project titanic_survivors ``` ```bash pip theme={"system"} bash mage run demo_project titanic_survivors ``` You can also run the pipeline from the UI. Click on the **Execute pipeline ** from right bottom panel. ![](https://mage-ai.github.io/assets/execute-pipeline-button.png) Your output should look something like this: ```text theme={"system"} Executing data_loader block: load_dataset...DONE Executing transformer block: extract_and_impute_numbers...DONE Executing data_exporter block: train_model...Accuracy: 0.757847533632287 Saving model to /home/src/finalized_model.lib Saving training and test set DONE ``` *** ## Congratulations! Youโ€™ve successfully built an ML pipeline that consists of modular code blocks and is reproducible in any environment. If you have more questions or ideas, please live chat with us in [Slack](https://www.mage.ai/chat). # Retrieval Augmented Generation (RAG) pipeline builder Source: https://docs.mage.ai/ai/rag-pipeline Build and deploy RAG pipelines with ease. Only in Mage Pro. Try our fully managed solution to access this advanced feature. [Get started for free](https://cloud.mage.ai/sign-up?source=rag-pipeline) ![Mage Pro RAG pipeline builder](https://mage-ai.github.io/assets/pro/features/rag-pipeline.jpg) # Using AI (artificial intelligence) Source: https://docs.mage.ai/ai/setup Use AI to perform various actions in Mage. ![Using artificial intelligence](https://steamuserimages-a.akamaihd.net/ugc/813376249149384255/EC3222795DC2961599F7FC0B69E0241C8EC7293E/?imw=5000\&imh=5000\&ima=fit\&impolicy=Letterbox\&imcolor=%23000000\&letterbox=false) Mage uses AI to help you build data pipelines faster. With our OpenAI integration and Mage Pro AI Chat, you can automate the tedious parts of pipeline development and focus on the fun stuff. > [!NOTE] > > Some AI actions that use direct OpenAI integration require an OpenAI API key. Mage Pro AI Chat uses Mage Pro API proxy authentication for model requests. We currently support the following AI features: * Generate pipelines * Generate blocks * Chat with AI in Mage Pro * Document code * Block documentation * Block comments * Pipeline documentation * Simultaneously document *all* blocks in a pipeline ![](https://mage-ai.github.io/assets/overview/ai-demo.gif) To see examples of how to use AI in Mage, check out our [AI guides](/guides/ai/overview). ## Setup For AI actions that use direct OpenAI integration, add an OpenAI API key to your project. > [!NOTE] > > Read [OpenAIโ€™s documentation](https://help.openai.com/en/articles/4936850-where-do-i-find-my-secret-api-key) > to get your API key. Once you have your OpenAI API key, open the account menu and select **Settings** โ†’ **Workspace** โ†’ **Preferences**. Under **AI services**, enter the key in **OpenAI Key**. ## AI Chat in Mage Pro Only in Mage Pro. Try our fully managed solution to access this advanced feature. [Get started for free](https://cloud.mage.ai/sign-up?source=ai-sidekick) Mage Pro includes AI Chat for workspace assistance. Open AI Chat from Mage Pro, or visit `/ai/chat` in an authenticated workspace as a user with the Editor role or higher. ### Build dbt workflows with AI Chat Ask AI Chat to inspect an existing dbt project, create or update models and tests, build Mage dbt blocks, or run and validate a workflow. For example: ```text theme={"system"} Create a dbt project for daily customer revenue, add tests for its final model, and create a Mage pipeline that runs the production reporting scope. Then run it and summarize the result. ``` AI Chat reuses matching projects, pipelines, and blocks when they already exist, so a follow-up request can update or validate the workflow without creating duplicates. ### Models, selectors, and commands * When you ask to run one named model or one snapshot file, AI Chat creates a Mage SQL dbt block that points directly to that file. * When you ask for a selector, multiple models, tests, or bulk snapshots, it creates a Mage YAML dbt block with the requested scope. It includes upstream models only when they are needed for the requested block to run on its own. * `dbt docs generate` is not currently supported by Mage's native dbt blocks. AI Chat explains this limitation instead of creating a block that cannot run. ### When AI Chat runs dbt Creating or editing a dbt workflow does not run it automatically, even when the request says to create a block that runs a model or to add tests. To run it in the same request, explicitly say **run**, **execute**, **test**, or **validate through execution**; no separate mid-request approval is needed. When you authorize execution, AI Chat runs the requested block or pipeline and reports the result only after it finishes. Its response includes the outcome, relevant run identifiers, and a redacted dbt command when available. If you explicitly ask to run, test, or validate again, it starts a fresh execution; if a repair flow is incomplete or fails safely, it retries the original run. ### Credentials and production-quality work AI Chat does not display credentials, resolved environment-variable values, or raw dbt profile content. It asks for an adapter, profile name, or target only when that non-secret choice cannot be determined safely, and it tells you when it cannot verify that a project can run with its configured profile. Every dbt request uses existing project conventions, checks its changes, and explains assumptions. Requests for production readinessโ€”or higher-risk work such as incremental models, snapshots, backfills, sensitive data, destructive schema changes, and large or costly workloadsโ€”also receive deeper design, data-quality, security, reliability, and operational checks. AI Chat may ask for a decision only when it is necessary for a safe implementation. A production-quality result requires an explicitly authorized fresh execution and all applicable checks to pass; asking for production-ready work alone does not start execution. For each chat turn, Mage captures the visible non-chat text from the current browser page, along with the page title and URL, so AI Chat can answer page-relative prompts such as "explain this page" or "what am I looking at?" The captured context is scoped to the authenticated user and chat session, excludes the chat UI, and is capped at 20,000 characters. The AI Chat sidebar lists active and archived chats, lets you search chat history by title, and loads older chats with **Show more** when more results are available. Mage Pro remembers the selected chat and whether you were viewing active or archived chats for the current workspace, then restores that state when you refresh or reopen AI Chat. When AI Chat replies with Markdown image links that resolve through Mage Pro's authenticated preview flow, AI Chat renders those image previews inline. Markdown links to other workspace files still open in the code editor. ### Inspect delegated subagent work When a chat turn delegates work, select **Show work** in the AI Chat header. Its **Subagents** summary shows how many subagents are working and how many are done. Selecting **Subagents** opens the right panel, where subagents are grouped into **Active** and **Done**. Each row shows the subagent name and its latest activity. Select a row to inspect that subagent's turn output, tool activity, and generated outputs; use the back button to return to the grouped list. AI Chat supports session-scoped file attachments from the composer File action or paste, folder attachments from the composer Folder action, and file or folder attachments by drag and drop. Uploaded attachments remain available on follow-up messages in the same chat session, even after the composer clears for the next message. Folder uploads appear as a single folder attachment in the chat; for browser-selected folders, Mage Pro packages every browser-exposed file into one zip archive before upload, preserves the relative paths inside that archive, and does not filter files from the selected folder. AI Chat receives an uploaded-file manifest and bounded text previews from readable non-archive attachments so it can answer questions about uploaded files without guessing from workspace files. AI Chat supports push-to-record voice dictation when the Mage Pro API OpenAI proxy is configured and the signed-in user has the same Editor-or-higher permission required to send AI Chat messages. Click the microphone in the composer, then click the stop control to insert the transcription into the draft for editing, or click the send arrow while recording to stop capture, transcribe the audio, and send or queue the dictated message. Audio is sent from the browser to the Mage Pro workspace, then to the Mage Pro API proxy; the workspace and browser never receive the raw OpenAI API key. Use the execution settings menu beside the chat composer to choose a **Speed** and **Effort** level for the current chat. Choose **Standard** for the default response tier, or **Fast** to use the priority service tier for that chat. Choose **Light**, **Medium**, **High**, or **Extra High** effort based on how much model effort the task needs. The menu stays open after a selection so you can confirm both checked choices, and its button displays the active effort level. When **Fast** is selected, the button appends the speed after the effort level, such as **Medium Fast**. For guided Sidekick workflows in Mage Pro, AI Chat can show inline forms directly in the chat transcript. Use these forms to choose sources, streams, destinations, and connector settings without leaving the conversation. Required fields must be completed before continuing, large option lists include filtering, and **Cancel** stops the guided setup. Submitting or cancelling the form resolves the original Sidekick turn instead of adding a separate chat message. After submission, AI Chat replaces the form with a submitted summary that shows safe submitted values, truncates long values, and masks sensitive values such as passwords or credentials. When AI Chat returns a project-local PNG, JPEG, GIF, or WebP path, AI Chat renders the image inline. The path can be on its own line, embedded in prose, such as `Here it is: /home/src/demo/cyborg_mage.png`, or used as a Markdown link target, such as `[output/anime_styled_mage.png](output/anime_styled_mage.png)`. The preview is served through a short-lived authenticated URL, so the image file does not need a public URL. When Sidekick media tools generate image, audio, or video files, AI Chat renders them at the end of the assistant answer as chat artifacts instead of only inside tool-usage details. Images render inline, audio renders with browser playback controls, and video renders with browser playback controls. Media previews use five-minute authenticated tokens. Supported preview files are GIF, JPEG, PNG, and WebP images up to 25 MB; AAC, MP3, Opus, WAV, and WebM audio up to 50 MB; and MOV, MP4, and WebM video up to 250 MB. Files must be under the current project or the current Sidekick media directory. Mage Pro administrators configure AI Chat connectivity and model access when the workspace is deployed. Per-chat execution settings take precedence over the deployment defaults. Codex CLI commands launched independently from the Mage terminal continue to use that terminal's own Codex configuration. When Codex model capacity is temporarily unavailable, AI Chat shows a **Waiting for model capacity** status and automatically retries the run within the configured retry window. If the retry budget is exhausted, AI Chat shows the rate-limit error. Voice dictation is available when it is enabled by the Mage Pro administrator. The workspace validates supported audio formats and applies configured upload, duration, and usage limits before sending audio for transcription. ## Generate pipeline using AI When creating a new pipeline, select the option labeled **Using AI**. Then, type the description of what the pipeline should do. For example: *Load data from an API, then clean the column names, and finally export the dataframe to PostgreSQL.* ![Generate pipeline using AI](https://mage-ai.github.io/assets/guides/ai/generate-pipeline.png) ## Generate block using AI > [!NOTE] > > You must turn on the feature named `add_new_block_v2` > in **Settings** โ†’ **Workspace** โ†’ **Preferences**, available from the account menu. When adding a new block, type in the description of what you want the block to do. In the autocomplete dropdown list, select the 1st option with a label starting with **Generate block using AI: ...** ![Generate block using AI](https://mage-ai.github.io/assets/guides/ai/generate-block.png) ## Document code using AI ![Add documentation using AI](https://mage-ai.github.io/assets/guides/ai/document.png) ### Add documentation for a block On the edit pipeline page in the top right corner of a block, click the AI actions icon. Select the option labeled **Document block**. ### Add documentation for a pipeline and all its blocks On the edit pipeline page in the top right corner of a block, click the AI actions icon. Select the option labeled **Document pipeline and all blocks**. ### Add comments in a block On the edit pipeline page in the top right corner of a block, click the AI actions icon. Select the option labeled **Add comments in code**. # AI Sidekick Source: https://docs.mage.ai/ai/sidekick/index Use Mage Pro AI Sidekick to build, debug, operate, explore, and automate data work from inside Mage. Only in Mage Pro. Try our fully managed solution to access this advanced feature. [Get started for free](https://cloud.mage.ai/sign-up?source=ai-sidekick) AI Sidekick is the Mage Pro assistant built for data teams. It understands the Mage page you are viewing, the project you are working in, your pipelines, blocks, runs, logs, data outputs, connected sources, docs, and chat history, then turns natural-language requests into useful answers and real Mage actions. Use Sidekick when you want to move from an idea to a working pipeline, explain a production failure, explore data without opening a separate tool, generate an Analytics chart, update project files, or ask a teammate-style question about what is happening in Mage. ![AI Sidekick creating Titanic survival charts from inside Mage Pro.](https://mintcdn.com/mage/xlfFBQh2VT61fQmA/media/ai-sidekick/ai-sidekick-hero.png?fit=max\&auto=format\&n=xlfFBQh2VT61fQmA\&q=85\&s=2341d4aa5a13fc36e4df9228526a0553) In this example, Sidekick is working from the open analytics workflow. It turns plain-language chart requests into visual analysis, keeps the generated charts in context, and gives you a path to add useful results to a dashboard without leaving Mage. ## How to Access AI Sidekick AI Sidekick is available in Mage Pro wherever contextual help or automation is most useful. 1. Open a Mage Pro workspace. 2. Open a pipeline, block, run, Analytics page, data preview, or code page. 3. Click the AI Sidekick entry point in the page header, right panel, output toolbar, chart workflow, or contextual action menu. 4. Ask in plain English, choose a suggested prompt, or attach the current page, file, block output, chart, or data preview as context. Sidekick starts with the context of the page you are on. On a pipeline page, it can see the pipeline shape and active block. On an Analytics page, it can keep the target dashboard or chart in focus. In code-oriented surfaces, it can work with the active file and selected source text. When the prompt is ambiguous, it can ask you to choose the right source, table, pipeline, or action before making changes. ## How to Use It Start with the outcome you want, not the implementation details. ```text theme={"system"} Create a pipeline that loads Salesforce opportunities, joins them with Stripe invoices, calculates expansion revenue, and runs every weekday morning. ``` ```text theme={"system"} This run failed overnight. Explain the root cause, fix the broken block, and retry the failed work from the same run. ``` ```text theme={"system"} Show active customers by region from Snowflake, filter to enterprise accounts, then make a bar chart for the Analytics dashboard. ``` ```text theme={"system"} Open the current block output, find outliers in order_value, and explain what changed from the previous run. ``` Sidekick streams its progress as it works. For changes that affect Mage objects or project files, it can read back the result, refresh the open page, and keep the conversation tied to the exact run, block, preview, chart, or file it used. ## What AI Sidekick Can Do ### Build Pipelines from a Prompt Describe the data workflow you want and Sidekick can create the pipeline, choose the right block types, generate block code, wire dependencies, apply templates, and set up the supporting configuration. It can work with batch pipelines, streaming pipelines, integration pipelines, dbt workflows, dynamic blocks, callbacks, conditionals, sensors, charts, global data products, and custom project code. Examples: * "Build a daily customer health pipeline from HubSpot, Stripe, and Snowflake." * "Add a dbt model step after this loader and run only the selected model." * "Create a streaming pipeline for Kafka events and write clean records to S3." * "Split this block into dynamic children by country, then reduce the results." ### Generate, Edit, and Repair Blocks Sidekick can create blocks, update existing logic, refactor code, explain what a block does, change dependencies, and keep block metadata aligned with the pipeline. It understands common Mage block languages and patterns, including Python, SQL, R, YAML, Markdown, dbt, and data integration templates. Use it for everyday engineering work: * turn a plain-language transform into reusable code * add retries, timeouts, variables, secrets, or execution settings * convert exploratory code into production-ready blocks * update upstream or downstream dependencies * fix syntax errors, runtime exceptions, and broken imports * preserve the current editor context while applying file-backed updates ### Debug Runs and Self-Heal Failures When a pipeline run fails, Sidekick can inspect the run, block statuses, logs, outputs, and recent changes, then explain what happened in terms a data team can act on. If you ask it to fix the problem, it can update the broken code and retry the failed or incomplete work on the original run instead of creating a separate run with different context. Examples: * "Why did this run fail?" * "Fix the failed block and retry the downstream blocks." * "Summarize all ERROR logs for the last three runs." * "Find the schema change that caused this exporter to break." ### Explore Data in Chat Sidekick can discover authorized data sources and pipeline outputs, inspect schemas, ask for missing warehouse, database, schema, dataset, table, or catalog selection, and open a windowed data preview directly in chat. For SQL-capable sources, it can create read-only query previews for grouped results, joins, derived columns, filters, and comparisons. The preview stays interactive. You can sort, filter, select columns, ask follow-up questions, return to a parent preview, or branch into another refinement without copying a full dataset into the conversation. Examples: * "Show revenue by month from the warehouse." * "Only include enterprise accounts and sort by ARR descending." * "Compare this block output against yesterday's run." * "Count rows by status, then open the result as a table." ### Create Analytics and Data Products Sidekick can turn pipeline outputs, data previews, SQL results, and existing charts into Analytics assets. It can generate Plotly code, create chart metadata, save bounded chart-ready datasets, attach charts to the right dashboard, and refresh the open Analytics page after the chart is saved. Ask for: * operational dashboards from pipeline outputs * revenue, usage, churn, or conversion charts from warehouse data * chart edits such as new filters, titles, colors, or grouping * table-backed data products for analysts and stakeholders * chart explanations for people who did not build the pipeline ### Understand the Page You Are On Sidekick can answer page-relative questions such as "what am I looking at?", "why is this empty?", "what changed here?", or "what should I do next?" because Mage passes it scoped page context for the active chat turn. It can also use recent interaction context, selected text, current file context, active preview context, and chart workflow attachments when those are available. ![AI Sidekick response explaining a pipeline and recommending a monitoring chart.](https://mintcdn.com/mage/xlfFBQh2VT61fQmA/media/ai-sidekick/pipeline-sidekick-chat.jpg?fit=max\&auto=format\&n=xlfFBQh2VT61fQmA\&q=85\&s=e42b55ebf3982617dd9f5995d0f60ab2) This makes Sidekick useful for onboarding and review: * explain a pipeline graph to a new teammate * summarize the selected code in Apps Coder * describe why a chart or preview is filtered * compare what the UI shows with the last successful run * keep an Analytics edit focused on the selected chart ### Search Docs, Project Knowledge, and Chat History Sidekick can search Mage documentation, read relevant pages, inspect project instructions when they matter, and use previous chat turns or tool outputs to continue work without making you repeat context. When retrieval is enabled for a project, it can reference the project files, configuration, docs, and code that you permit it to read. Use this for: * "How should I configure this trigger?" * "Find the docs for dynamic blocks and apply the pattern here." * "Continue from the chart we created earlier." * "Read the last tool output and explain why it failed." ### Operate Production Workflows Sidekick can help with the operational surfaces around pipelines: schedules, triggers, backfills, runs, jobs, block runs, outputs, logs, variables, secrets, notifications, permissions, users, roles, deployments, compute, Spark, global hooks, version control, and workspace settings. It can list, inspect, create, or update supported Mage resources through the same authenticated Mage APIs that power the product. Examples: * "Create a weekday trigger for this pipeline with these runtime variables." * "Backfill this pipeline for the last seven days." * "Show active triggers and the next run time for each." * "Check whether this user has permission to view the workspace." * "Review Spark executor status for the slow run." ### Work with Files and Versioned Project Code Sidekick can read and update project files, upload or download supported files, record changes so Mage file versions stay accurate, inspect file history, and coordinate code changes with pipeline or block metadata updates. It can also use sync workflows when local and remote project files need to be reconciled. Use it when you want to: * update a utility module used by multiple blocks * change a YAML config and apply the related Mage metadata update * inspect file versions before accepting a change * create a new project file from a prompt * pull or push project changes through an agent workflow ### Coordinate Longer AI Workflows For larger requests, Sidekick can break work into smaller AI tasks, wait for results, cancel stale work, and summarize progress back into the main chat. This is useful for independent review, broad discovery, test-gap analysis, migration work, or multi-step implementation where several pieces can be investigated at the same time. Examples: * "Audit these five pipelines and summarize the risky patterns." * "Have one agent inspect docs and another inspect code before proposing a fix." * "Generate a migration plan and check the source project inventory." * "Run an independent review of the changes before I ship them." ### Generate and Understand Media In Sidekick sessions that enable media tools, Sidekick can transcribe audio, translate audio to English, create spoken audio from text, generate images, edit images, and create or download short videos. Generated files are saved to the Sidekick media area for the active chat and are returned through authenticated preview links. Use this for: * transcribing a stakeholder recording into requirements * generating a narrated explanation of a pipeline result * drafting images for reports, demos, or internal docs * editing chart screenshots or data-product visuals * producing short demo clips from a written prompt ## Built for Data Teams AI Sidekick is not a generic chatbot placed next to your pipeline editor. It is connected to Mage's data engineering model: projects, pipelines, blocks, dependencies, schedules, logs, previews, dashboards, files, users, roles, deployments, compute resources, and production history. That connection lets it answer with context and take action where the work already happens. ## Safety and Control Sidekick uses your Mage Pro authentication and respects the same project, workspace, and resource boundaries as the product. It uses redacted tool responses for sensitive fields, works with preview IDs and bounded row windows instead of dumping full datasets into chat, validates read-only SQL previews before execution, and asks clarifying questions when a request could target multiple resources. For changes that mutate pipelines, blocks, files, schedules, secrets, users, permissions, or other resources, review the proposed result in Mage and ask Sidekick to explain what changed, show the relevant diff or resource state, or run the affected workflow again. # Blog Source: https://docs.mage.ai/community/blog > **[Blog](https://www.mage.ai/blog)** > > Want to be entertained? # Contact Source: https://docs.mage.ai/community/contact > **[Contact](mailto:hello@mage.ai)** > > Send us an email # GitHub Source: https://docs.mage.ai/community/github > **[GitHub](https://github.com/mage-ai/mage-ai)** > > Open-source project # LinkedIn Source: https://docs.mage.ai/community/linkedin > **[LinkedIn](https://www.linkedin.com/company/magetech)** > > Letโ€™s connect professionally # Slack Source: https://docs.mage.ai/community/slack > **[Slack](https://www.mage.ai/chat)** > > Instantly chat with the team and other community members # Twitter Source: https://docs.mage.ai/community/twitter > **[Twitter](https://twitter.com/mage_ai)** > > Ready for funny memes? # Adding an IO class Source: https://docs.mage.ai/contributing/backend/io/adding-a-class IO classes power Mage sources and destinations. Read on to learn how you can contribute an IO class to Mage. ## What's an IO class? IO classes are at the heart of Mageโ€” they're the code that enables Mage to read and write data. When you configure your [`io_config`](https://docs.mage.ai/development/io_config) to use a source or destination, you're telling Mage to use a specific IO class. IO classes are defined [here](https://github.com/mage-ai/mage-ai/tree/master/mage_ai/io) in the Mage repository. You can see that there are a few different types of IO classesโ€” some are for reading data, some are for writing data, and some are for both. ## Why should I contribute? If you have a favorite IO class *that's not currently supported*, you can reach out *or* contribute it to Mage! Contributing is a great way to build your skills, become a part of the Mage community, and help others. ## How do I contribute? ### Configure your development environment The first step to contributing an IO class is to configure your development environment. You can find instructions for doing so [here](https://docs.mage.ai/contributing/development-environment). ### Create a new IO class Once configured, you'll want to create a new file in the `mage_ai/io` directory. The file should be named after the IO class you're contributing. For example, if you're contributing an IO class called `MyIOClass`, you should create a file called `my_io_class.py`. Some IO classes are relatively straightforward, like [exporting to local files](https://github.com/mage-ai/mage-ai/blob/master/mage_ai/io/file.py) or [writing to Google Sheets](https://github.com/mage-ai/mage-ai/blob/master/mage_ai/io/google_sheets.py). Others, like full database integrations, can be pretty complex. [Google BigQuery](https://github.com/mage-ai/mage-ai/blob/master/mage_ai/io/bigquery.py) is a good example of a complex IO class. Most classes are platform specific, but for a database, you might need the following methods: * `alter_table`: Alter the table schema * `load`: Load data from the database * `export`: Export data to the database * `execute`: Execute a query on the database * `execute_queries`: Execute multiple queries on the database Additionally, every class will need to have the following methods: * `__init__`: Initialize the class * `with_config`: Initialize the database client from the configuration loader. You'll notice that this method is used in *all* of our templates. * `test_connection`: Validate credentials or reachability with a lightweight, side-effect-free check. Return normally (`None`) when the probe succeeds and let connection or probe failures raise so callers can surface the underlying error. This method should not load preview data, export records, or mutate remote resources. If the safest probe depends on a target resource (for example a bucket, index, or sheet), accept that target as an optional argument and document any broader no-target fallback permissions. ### Test your IO class In order to test your class, you should perform all of the methods you defined in the class itself. Once you pass our linting checks (outlined in the development environment link above) *and* your tests pass, you're ready to submit a pull request! Learn more about pull requests on the contribution. ## Create a pull request # Contributing to the backend server Source: https://docs.mage.ai/contributing/backend/overview Mage backend code is written in Python ๐Ÿ and our server uses the Tornado ๐ŸŒช๏ธ framework. Here are some guides on adding features to the Mage backend. ## Guides ### API * [Overview](/api-reference/overview) ### Data integrations * [Add a new source to the data integration pipeline](/contributing/data-integrations/add-new-source) * [Add a new destination to the data integration pipeline](/contributing/data-integrations/add-new-destination) ### Streaming pipelines * [Add a new source or destination to the streaming pipeline](/contributing/backend/streaming/sources-and-destinations) ### IO classes * [Add a new IO class](/contributing/backend/io/adding-a-class) ## Style guide ### Linter Install `flake8` in your IDE to lint the Python code. To run the linter locally, execute this script: ```bash theme={"system"} ./scripts/server/lint.sh ``` ## Testing ### Unit tests Add unit tests for the feature in [mage\_ai/tests](https://github.com/mage-ai/mage-ai/tree/master/mage_ai/tests) directory. To run the tests locally, execute this script: ```bash theme={"system"} ./scripts/server/test.sh ``` It is also possible to run unit tests directly in a live docker instance, as given in the following steps. 1. Find out the backend server container name, with the command `docker container ls` in a terminal: ```bash theme={"system"} % docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8dbcfbe41755 mage/data "./scripts/install_aโ€ฆ" 5 days ago Up 38 minutes 0.0.0.0:3000->3000/tcp mage-ai-app-1 b9d811e1e3e8 mage/data "python mage_ai/servโ€ฆ" 5 days ago Up 38 minutes 0.0.0.0:6789->6789/tcp mage-ai-server-1 ``` 2. Start an interactive `bash` session with the backend server container: ```bash theme={"system"} % docker exec -it mage-ai-server-1 /bin/bash ``` 3. Run unit tests with the following command: ```bash theme={"system"} root@b9d811e1e3e8:/home/src# python3 -m pytest mage_ai -x ``` ## Debugging # Contributing Source: https://docs.mage.ai/contributing/backend/streaming/sources-and-destinations This doc talks about how to add a new source or destination to the streaming pipeline. ## Prerequisites Follow this [doc](/contributing/overview) to set up the development environment for Mage. ## Add a new source Example PR for adding a source: [https://github.com/mage-ai/mage-ai/pull/1953](https://github.com/mage-ai/mage-ai/pull/1953) * Add the new source type to [mage\_ai/streaming/constants.py](https://github.com/mage-ai/mage-ai/blob/master/mage_ai/streaming/constants.py). * Add the source file to the folder [https://github.com/mage-ai/mage-ai/tree/master/mage\_ai/streaming/sources](https://github.com/mage-ai/mage-ai/tree/master/mage_ai/streaming/sources) * Define the source class which inherits from the `BaseSource`. * Define the source config class. * Implement the methods: * `init_client`: Initialize the client used to connect to the source. * `batch_read`: Batch read messages from the source and use `handler` method to process the messages. * Add the new source to the [SourceFactory](https://github.com/mage-ai/mage-ai/blob/master/mage_ai/streaming/sources/source_factory.py). * Add a template file with example config to the folder: [https://github.com/mage-ai/mage-ai/tree/master/mage\_ai/data\_preparation/templates/data\_loaders/streaming](https://github.com/mage-ai/mage-ai/tree/master/mage_ai/data_preparation/templates/data_loaders/streaming) * Add new source type to the frontend code. * [https://github.com/mage-ai/mage-ai/blob/master/mage\_ai/frontend/components/PipelineDetail/AddNewBlocks/utils.tsx#L31](https://github.com/mage-ai/mage-ai/blob/master/mage_ai/frontend/components/PipelineDetail/AddNewBlocks/utils.tsx#L31) * [https://github.com/mage-ai/mage-ai/blob/master/mage\_ai/frontend/interfaces/DataSourceType.ts#L3](https://github.com/mage-ai/mage-ai/blob/master/mage_ai/frontend/interfaces/DataSourceType.ts#L3) * [https://github.com/mage-ai/mage-ai/blob/master/mage\_ai/frontend/interfaces/DataSourceType.ts#L22](https://github.com/mage-ai/mage-ai/blob/master/mage_ai/frontend/interfaces/DataSourceType.ts#L22) * Add unit tests: [https://github.com/mage-ai/mage-ai/tree/master/mage\_ai/tests/streaming/sources](https://github.com/mage-ai/mage-ai/tree/master/mage_ai/tests/streaming/sources) * Add doc: [https://github.com/mage-ai/mage-ai/tree/master/docs/guides/streaming/sources](https://github.com/mage-ai/mage-ai/tree/master/docs/guides/streaming/sources) *** ## Add a new destination (sink) Example PR for adding a sink: [https://github.com/mage-ai/mage-ai/pull/2121](https://github.com/mage-ai/mage-ai/pull/2121) * Add the new sink type to [mage\_ai/streaming/constants.py](https://github.com/mage-ai/mage-ai/blob/master/mage_ai/streaming/constants.py). * Add the sink file to the folder [https://github.com/mage-ai/mage-ai/tree/master/mage\_ai/streaming/sinks](https://github.com/mage-ai/mage-ai/tree/master/mage_ai/streaming/sinks) * Define the sink class which inherits from the `BaseSink`. * Define the sink config class. * Implement the methods: * `init_client`: Initialize the client used to connect to the destination. * `batch_write`: Batch write messages to destination. * Add the new sink to the [SinkFactory](https://github.com/mage-ai/mage-ai/blob/master/mage_ai/streaming/sinks/sink_factory.py). * Add a template file with example config to the folder: [https://github.com/mage-ai/mage-ai/tree/master/mage\_ai/data\_preparation/templates/data\_exporters/streaming](https://github.com/mage-ai/mage-ai/tree/master/mage_ai/data_preparation/templates/data_exporters/streaming) * Add new source type to the frontend code. * [https://github.com/mage-ai/mage-ai/blob/master/mage\_ai/frontend/components/PipelineDetail/AddNewBlocks/utils.tsx#L37](https://github.com/mage-ai/mage-ai/blob/master/mage_ai/frontend/components/PipelineDetail/AddNewBlocks/utils.tsx#L37) * [https://github.com/mage-ai/mage-ai/blob/master/mage\_ai/frontend/interfaces/DataSourceType.ts#L3](https://github.com/mage-ai/mage-ai/blob/master/mage_ai/frontend/interfaces/DataSourceType.ts#L3) * [https://github.com/mage-ai/mage-ai/blob/master/mage\_ai/frontend/interfaces/DataSourceType.ts#L22](https://github.com/mage-ai/mage-ai/blob/master/mage_ai/frontend/interfaces/DataSourceType.ts#L22) * Add unit tests: [https://github.com/mage-ai/mage-ai/tree/master/mage\_ai/tests/streaming/sinks](https://github.com/mage-ai/mage-ai/tree/master/mage_ai/tests/streaming/sinks) * Add doc: [https://github.com/mage-ai/mage-ai/tree/master/docs/guides/streaming/destinations](https://github.com/mage-ai/mage-ai/tree/master/docs/guides/streaming/destinations) # Testing Source: https://docs.mage.ai/contributing/backend/testing/overview Making Mage so invincible that nothing can break it, not even itself. ![Testing](https://i.pinimg.com/originals/05/70/56/057056dae3c4c8a5c5426f6c458ba001.gif) ## Errors ### SQL Alchemy migration error Delete the `test.db` file located in the directory where you are running the `python3 -m pytest ... -x` command. Example: ``` Traceback (most recent call last): File "/usr/local/lib/python3.10/site-packages/sqlalchemy/engine/base.py", line 1910, in _execute_context self.dialect.do_execute( File "/usr/local/lib/python3.10/site-packages/sqlalchemy/engine/default.py", line 736, in do_execute cursor.execute(statement, parameters) sqlite3.OperationalError: index ix_pipeline_run_execution_date already exists ... sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) index ix_pipeline_run_execution_date already exists [SQL: CREATE INDEX ix_pipeline_run_execution_date ON pipeline_run (execution_date)] (Background on this error at: https://sqlalche.me/e/14/e3q8) ---------------------------------------------------------------------- Ran 0 tests in 0.038s FAILED (errors=1) ``` # How to add a chart Source: https://docs.mage.ai/contributing/charts/how-to-add ## 1. Add a new chart type Add a new type in [`mage_ai/data_preparation/models/widget/constants.py`](https://github.com/mage-ai/mage-ai/blob/master/mage_ai/data_preparation/models/widget/constants.py): ```python theme={"system"} class ChartType(str, Enum): # ... PIE_CHART = 'pie_chart' ``` Add a new type in [`mage_ai/frontend/interfaces/ChartBlockType.ts`](https://github.com/mage-ai/mage-ai/blob/master/mage_ai/frontend/interfaces/ChartBlockType.ts): ```javascript theme={"system"} export enum ChartTypeEnum { // ... PIE_CHART = 'pie_chart', } export const CHART_TYPES = [ // ... ChartTypeEnum.PIE_CHART, ]; ``` ## 2. Define the configuration options for the chart In the file `mage_ai/frontend/components/ChartBlock/constants.ts`, add a list of options for the user to configure their chart with: ```javascript theme={"system"} export const CONFIGURATIONS_BY_CHART_TYPE = { [ChartTypeEnum.PIE_CHART]: [ { label: () => 'variable name of values', monospace: true, uuid: 'super_cool_uuid', }, ], }; ``` Also, add the new variable name to the following constant in the file `mage_ai/frontend/interfaces/ChartBlockType.ts`,: ```javascript theme={"system"} export const VARIABLE_NAMES = [ 'super_cool_uuid', ]; ``` If 1 or more of the configuration options is for a variable name that can be defined in the chart blockโ€™s code and referenced at presentation time, then you must add the following in the file `mage_ai/data_preparation/models/widget/constants.py`: ```python theme={"system"} VARIABLE_NAMES_BY_CHART_TYPE = { ChartType.PIE_CHART: [ 'super_cool_uuid', ], } ``` ### Add default settings to the configuration When a user selects a chart type, you can set default values for these options. In the file `mage_ai/frontend/interfaces/ChartBlockType.ts`, add the following: ```javascript theme={"system"} export const DEFAULT_SETTINGS_BY_CHART_TYPE = { [ChartTypeEnum.PIE_CHART]: { configuration: () => ({ [VARIABLE_NAME_X]: 'x', }), content: ({ upstream_blocks: upstreamBlocks = [], }: BlockType) => { const uuid = upstreamBlocks[0]; return `x = ${uuid}[${uuid}.columns[0]]`; }, }, }; ``` ### Add helpful information about the variable type that the chart expects Each chart requires 1 or more input values. The chart knows how to access those input values by referencing a variable name that the user inputs into the configuration options. Each variable can be of a certain type; array/list of strings, integers, etc. To help the user know how to set the variables properly, add the following information into the file `mage_ai/frontend/components/ChartBlock/constants.ts`: ```javascript theme={"system"} export const VARIABLE_INFO_BY_CHART_TYPE = { [ChartTypeEnum.PIE_CHART]: { [VARIABLE_NAME_X]: (): string => 'must be a list of booleans, dates, integers, floats, or strings.', }, }; ``` ## 3. Define post processing logic for chart data In the file `mage_ai/data_preparation/models/widget/__init__.py`, add additional logic for parsing the input values from the variables defined in the chart blockโ€™s code. The output of this method is provided to the front-end React components for rendering. ```python theme={"system"} class Widget(Block): def post_process_variables(self, variables): if ChartType.PIE_CHART == self.chart_type: variables = {} return variables ``` ## 4. Create React component for rendering chart In the file `mage_ai/frontend/components/ChartBlock/ChartController.tsx`, import your React component for your new chart and render it. For example: ```javascript theme={"system"} function ChartController({ block, data, width, }: ChartControllerProps) { const { configuration, } = block; const chartType = configuration?.chart_type; if (ChartTypeEnum.PIE_CHART === chartType) { return ; } } ``` # Adapt an existing source Source: https://docs.mage.ai/contributing/data-integrations/adapt-existing-source Mage builds data integrations from [Singer taps](https://www.singer.io/#taps), so if there's a Singer source you want to use that isn't supported yet, you can adapt it yourself! ## Getting started Mage sources live in the `/mage_integrations/mage_integrations` folder. To add a new source, you'll need to create a new folder in the `/sources` subdirectory. The folder name should be the name of the tap. For existing sources, that starts with pulling in the GitHub repo for the tap. For example, for the [GitHub tap](https://github.com/MeltanoLabs/tap-github), we would: ```bash theme={"system"} cd mage_integrations/mage_integrations git clone https://github.com/MeltanoLabs/tap-github.git sources/github ``` The result: ``` . โ”œโ”€โ”€ LICENSE โ”œโ”€โ”€ README.md โ”œโ”€โ”€ config-sample.json โ”œโ”€โ”€ config.json โ”œโ”€โ”€ meltano.yml โ”œโ”€โ”€ poetry.lock โ”œโ”€โ”€ pyproject.toml โ”œโ”€โ”€ pytest.ini โ”œโ”€โ”€ tap-github.sh โ”œโ”€โ”€ tap_github โ”‚ย ย  โ”œโ”€โ”€ __init__.py โ”‚ย ย  โ”œโ”€โ”€ authenticator.py โ”‚ย ย  โ”œโ”€โ”€ client.py โ”‚ย ย  โ”œโ”€โ”€ organization_streams.py โ”‚ย ย  โ”œโ”€โ”€ repository_streams.py โ”‚ย ย  โ”œโ”€โ”€ schema_objects.py โ”‚ย ย  โ”œโ”€โ”€ scraping.py โ”‚ย ย  โ”œโ”€โ”€ streams.py โ”‚ย ย  โ”œโ”€โ”€ tap.py โ”‚ย ย  โ”œโ”€โ”€ tests โ”‚ย ย  โ”œโ”€โ”€ user_streams.py โ”‚ย ย  โ””โ”€โ”€ utils โ””โ”€โ”€ tox.ini ``` ## Configuring the source We now have a folder with our tap and a bunch of miscellaneous files. Our first step is to clear out everything we *don't* need. We can delete all files/folders other than `tap_your_source` and `tests`, but hold onto anything that looks like a `config.json` file or a sample config. Next, we need to create a configuration file and an init file: ```bash theme={"system"} mkdir sources/github/templates \ && touch sources/github/templates/config.json \ && touch sources/github/__init__.py ``` We can now populate our `config.json` file with the sample from the tap. In the GitHub example, this is `config.sample.json`. It looks like this: ```json theme={"system"} { "access_token": "abcdefghijklmnopqrstuvwxyz1234567890ABCD", "repository": "singer-io/target-stitch", "start_date": "2021-01-01T00:00:00Z", "request_timeout": 300, "base_url": "https://api.github.com" } ``` These are the parameters we'll need to configure our tap. After cleanup, our tree looks like: ``` . โ”œโ”€โ”€ __init__.py โ”œโ”€โ”€ tap_github โ”‚ย ย  โ”œโ”€โ”€ __init__.py โ”‚ย ย  โ”œโ”€โ”€ authenticator.py โ”‚ย ย  โ”œโ”€โ”€ client.py โ”‚ย ย  โ”œโ”€โ”€ organization_streams.py โ”‚ย ย  โ”œโ”€โ”€ repository_streams.py โ”‚ย ย  โ”œโ”€โ”€ schema_objects.py โ”‚ย ย  โ”œโ”€โ”€ scraping.py โ”‚ย ย  โ”œโ”€โ”€ streams.py โ”‚ย ย  โ”œโ”€โ”€ tap.py โ”‚ย ย  โ”œโ”€โ”€ tests โ”‚ย ย  โ”œโ”€โ”€ user_streams.py โ”‚ย ย  โ””โ”€โ”€ utils โ””โ”€โ”€ templates โ””โ”€โ”€ config.json ``` Now, we need to override some methods in the class to make it work with Mage. This is where things get fun! Copy and paste the following template into `your_tap/__init__.py`: ```python theme={"system"} from typing import List from mage_integrations.sources.base import Source, main from mage_integrations.sources.catalog import Catalog class YourSource(Source): def discover(self, streams: List[str] = None) -> Catalog: pass def sync(self, catalog: Catalog) -> None: pass def test_connection(self) -> None: client = YourSource(YOUR_CONFIG) client.close() if __name__ == "__main__": main(YourSource, schemas_folder="tap_your_tap/schemas") ``` Replace YourSource with the name of your source, e.g. `Github` for Github, and `tap_your_tap` with the name of your tap, e.g. `tap_github`. ### Overwrite tap methods Our goal is to overwrite the `discover` and `sync` methods to make them work with Mage. Discover is likely in `tap_your_tap/discover.py` and sync is likely in `tap_your_tap/sync.py`. It requires a bit of nuance, but our job is to look through the existing Singer tap, understand how the `sync` and `discover` methods were implemented, then execute them in Mage `__init__.py` under the corresponding method. This is necessarily different for every tap, since each project is entirely independent. Don't forget to use absolute imports for these files. [HubSpot](https://github.com/mage-ai/mage-ai/tree/master/mage_integrations/mage_integrations/sources/hubspot) is another good example of a completed tap. ### Add test connection method ### Overwrite `write_schema` method Finally, we need to overwrite the `write_schema` method in the `tap_your_tap/sync.py` file. Add the following import: `from mage_integrations.sources.messages import write_schema` Now, switch out the default function (likely `singer.write_schema`) for the mage function using the default arguments. Here's an example: ```python theme={"system"} write_schema( stream_name=catalog['tap_stream_id'], schema=schema, key_properties=catalog.get('key_properties', ['id']), bookmark_properties=catalog.get('bookmark_properties'), disable_column_type_check=catalog.get('disable_column_type_check'), partition_keys=catalog.get('partition_keys'), replication_method=catalog.get('replication_method'), stream_alias=catalog.get('stream_alias'), unique_conflict_method=catalog.get('unique_conflict_method'), unique_constraints=catalog.get('unique_constraints'), ) ``` ### Add logging To add verbose logging to Mage, add a logger argument each tap file, `tap_github/sync.py`, `tap_github/discover.py`: ```python theme={"system"} def discover(client, logger=None): """ Run the discovery mode, prepare the catalog file and return catalog. """ mage_logger = logger or LOGGER ``` Then replace usage of `LOGGER` with `mage_logger`. ```python theme={"system"} for stream_name, schema_dict in schemas.items(): try: schema = Schema.from_dict(schema_dict) mdata = field_metadata[stream_name] except Exception as err: # These were LOGGER previously mage_logger.error(err) mage_logger.error('stream_name: %s', stream_name) mage_logger.error('type schema_dict: %s', type(schema_dict)) raise err ``` This will enable Mage to better log Singer taps! ๐Ÿฅณ ## Add source to the Mage UI Add the new source to the `SOURCES` list constant in [this](https://github.com/mage-ai/mage-ai/blob/master/mage_ai/data_integrations/sources/constants.py) file This will make your new source visible in the Mage UI. ## Test your source Sources should be tested both in the console and via the UI. Follow the directions [here](https://github.com/mage-ai/mage-ai/blob/master/mage_integrations/README.md#testing-sync-locally) to configure a lightweight test of your sources taps via a bash terminal and the Mage UI in the dev docker instance. This entails: * Setting up a sample source and connection locally. * Running the tap directly, via Python. * Writing to an intermediate file to inspect the output. * Performing an end-to-end sync. ## Populate `README.md` Finally, populate a README file in the source folder, e.g. `/sources/github/README.md`. This should include: * The name/logo of the tap. * A configuration section. * The method for accessing/creating an API key to use with the folder. * See [HubSpot](https://github.com/mage-ai/mage-ai/tree/master/mage_integrations/mage_integrations/sources/hubspot) or [GitHub](https://github.com/mage-ai/mage-ai/tree/master/mage_integrations/mage_integrations/sources/github) for examples. # Create a new destination Source: https://docs.mage.ai/contributing/data-integrations/add-new-destination Here is an example PR for adding a new destination: [https://github.com/mage-ai/mage-ai/pull/2277](https://github.com/mage-ai/mage-ai/pull/2277) In this guide, we'll build a sample destination called `SampleDest`. When you're building your own destination, you can swap out the `SampleDest` name for the real name of your new destination. 1. Create a directory for the new destination 2. Define custom destination class 3. Add main function 4. Add your destination to the UI (optional) 5. Test your destination ## 1. Create a directory for the new destination In the `mage_integrations/destinations/` directory, add a new directory named after your destination. Use snake case and lowercase for your directory name: `mage_integrations/destinations/sample_dest/`. In this new directory, create the following subdirectories and files: * `mage_integrations/destinations/sample_dest/templates/config.json` * `mage_integrations/destinations/sample_dest/__init__.py` * `mage_integrations/destinations/sample_dest/README.md` The directory structure should look like this: ``` mage_integrations/ | destinations/ | | sample_dest/ | | | templates/ | | | | config.json | | | __init__.py | | | README.md ``` ### Templates folder This folder contains a sample configuration JSON file thatโ€™s displayed to the user when they are setting up a synchronization using this destination. The `config.json` file contains keys and values that are used to configure the behavior of the destination as well as credentials to authenticate requests to the destination. #### Naming convention You must use the exact filename `config.json`. #### Examples ```json theme={"system"} { "api_key": "", "secret_key": "" } ``` ### `__init__.py` This is where majority of the destination logic will exist. #### Examples [`mage_integrations/destinations/amazon_s3/__init__.py`](https://github.com/mage-ai/mage-ai/blob/master/mage_integrations/mage_integrations/destinations/amazon_s3/__init__.py) ### `README.md` Document how to configure and use your destination in the `README.md` file. ## 2. Define custom destination class In the `mage_integrations/destinations/sample_dest/__init__.py`, create a new class named after your destination and subclass the [base destination class](https://github.com/mage-ai/mage-ai/blob/master/mage_integrations/mage_integrations/destinations/base.py). If you're adding a destination for a SQL data warehouse or database, you can subclass the [base sql destination class](https://github.com/mage-ai/mage-ai/blob/master/mage_integrations/mage_integrations/destinations/sql/base.py) ```python theme={"system"} from mage_integrations.destinations.base import Destination class SampleDest(Destination): pass ``` ### Override the `export_batch_data` method The base `Destination` class has an instance method called `export_batch_data`. Here is the interface: ```python theme={"system"} def export_batch_data(self, record_data: List[Dict], stream: str) -> None: ... ``` Override this method to contain the logic for exporting data that is specific to your destination. ## 3. Add main function In the file `mage_integrations/destinations/sample_dest/__init__.py`, add the main function to the bottom of the file like below: ```python theme={"system"} if __name__ == '__main__': destination = SampleDest( argument_parser=argparse.ArgumentParser(), batch_processing=True, ) destination.process(sys.stdin.buffer) ``` ## 4. Add your destination to the UI (optional) Add the new destination to the `DESTINATIONS` list constant in this file: [https://github.com/mage-ai/mage-ai/blob/master/mage\_ai/data\_integrations/destinations/constants.py](https://github.com/mage-ai/mage-ai/blob/master/mage_ai/data_integrations/destinations/constants.py) ## 5. Test your destination Follow this [doc](https://github.com/mage-ai/mage-ai/tree/master/mage_integrations) to test your new destination. To test the destination in the UI, you can install your updated `mage_integrations` module by running the following commands in Mage terminal: ```bash theme={"system"} pip uninstall -y mage_integrations pip install "git+https://github.com/your_repo.git@your_branch#egg=mage-integrations&subdirectory=mage_integrations" ``` # Create a new source Source: https://docs.mage.ai/contributing/data-integrations/add-new-source This guide details adding a new source to Mage. If your source already exists as a [Singer tap](https://www.singer.io/#taps), check out [our guide](/contributing/data-integrations/adapt-existing-source) for adapting an existing source instead. Mage Sources are built on Singer Taps. You can read more about the Singer spec [here](https://github.com/singer-io/getting-started). In this guide, we'll copy over our sample source to get started and build from there. If you haven't already, start by cloning the Mage repo and navigating to the folder: ```bash theme={"system"} git clone https://github.com/mage-ai/mage-ai.git cd mage-ai ``` For our source, we'll need: * A schema that represents the source data * A template configuration file * An `__init__.py` file that contains the logic for fetching data from the source. * A `test_connection` method that tests the connection to our source. * A `discover` method that returns a [Catalog](https://github.com/mage-ai/mage-ai/blob/master/mage_integrations/mage_integrations/sources/catalog.py) of streams. * A `load_data` method that yields data from the source as a dictionary. We'll start from a template to make things easy. ## Copy the template source Navigate to `/mage-ai/mage_integrations/mage_integrations/sources` and create a copy of the `titanic` directory: ```bash theme={"system"} cd ./mage_integrations/mage_integrations/sources cp -R titanic MY_SOURCE ``` Our titanic source simply reads data from a CSV file, but we'll modify it to do much more. You'll notice the following files and folders in the `MY_SOURCE` directory: ``` mage_integrations/sources/MY_SOURCE โ”œโ”€โ”€ README.md โ”œโ”€โ”€ __init__.py โ”œโ”€โ”€ schemas โ”‚ โ””โ”€โ”€ passengers.json โ””โ”€โ”€ templates โ””โ”€โ”€ config.json ``` So we'll need to update or overwrite each of these. ## Update schemas This folder contains all the known schemas from your source. For sources that have dynamic schemas (e.g. database tables from MySQL), this folder may be empty since the schema is dependent on the individual's source data. The JSON format of these schema files follows the [Singer spec](https://github.com/singer-io/getting-started/blob/master/docs/DISCOVERY_MODE.md#schemas). When naming schemas, use the plural name of the object you're referencing. This plural name will be displayed to the individual who is setting up a synchronization using this source. Take the [sample "passengers" schema](https://github.com/mage-ai/mage-ai/tree/master/mage_integrations/mage_integrations/sources/titanic/schemas/passengers.json) for example: ```json theme={"system"} { "properties": { "Survived": { "type": ["null", "integer"] }, "Name": { "type": ["null", "string"] } }, "type": ["null", "object"] } ``` ## Add templates This folder contains a sample configuration JSON file that's displayed to the user when they are setting up a synchronization using this source. The `config.json` file contains keys and values that are used to configure the behavior of the source as well as credentials to authenticate requests to the source. You must use the exact filename `config.json`, regardless of your source's name. The following simple example is present in the [Titanic source](https://github.com/mage-ai/mage-ai/tree/master/mage_integrations/mage_integrations/sources/titanic/templates/config.json). ```json theme={"system"} { "api_key": "", "secret_key": "" } ``` ## Update `__init__.py` A majority of source logic lives in the `__init__.py` file. Most of the work in adding your own source will involve creating/overwriting methods from `__init__.py`. [Our sample](https://github.com/mage-ai/mage-ai/tree/master/mage_integrations/mage_integrations/sources/titanic/__init__.py) contains the following: ```python theme={"system"} from mage_integrations.sources.base import Source, main from typing import Dict, Generator, List import requests URL = 'https://raw.githubusercontent.com/mage-ai/datasets/master/titanic_survival.csv' class Titanic(Source): def load_data( self, **kwargs, ) -> Generator[List[Dict], None, None]: text = requests.get(URL).text rows = [] lines = text.rstrip().split('\n') columns = lines[0].split(',') for line in lines[1:]: values = line.split(',') rows.append({col: values[idx] for idx, col in enumerate(columns)}) yield rows def test_connection(self): request = requests.get(URL) if request.status_code != 200: raise Exception('Could not fetch titanic data') if __name__ == '__main__': main(Titanic) ``` ### Rename source class First, rename the source class to match your new source ```python theme={"system"} from mage_integrations.sources.base import Source class MY_SOURCE(Source): pass ``` ### Edit methods #### The `load_data()` method Override this method to contain the logic for fetching data specific to your source. The `Titanic` source's `load_data` method reads data from a CSV file and yields a list of dictionaries: ```python theme={"system"} def load_data( self, **kwargs, ) -> Generator[List[Dict], None, None]: url = 'https://raw.githubusercontent.com/mage-ai/datasets/master/titanic_survival.csv' text = requests.get(url).text rows = [] lines = text.rstrip().split('\n') columns = lines[0].split(',') for line in lines[1:]: values = line.split(',') rows.append({col: values[idx] for idx, col in enumerate(columns)}) yield rows ``` Your `load_data` method should *also* yield a list of dictionaries. There is a keyword argument named `query` in the `load_data` method that is a dictionary. When Mage runs a source, the following keys and values are automatically available on each run: | Key | Description | Sample value | | - | - | - | | `_execution_date` | The date and time (in ISO format) of when the pipeline started running. | `2022-10-21T17:24:49.443559` | | `_execution_partition` | An automatically formatted partition of the pipeline run using the execution date. | `20221021T172557` (e.g. format `%Y%m%dT%H%M%S`) | | `_start_date` | You can define this variable as a [runtime variable](/getting-started/runtime-variable) in your pipeline or it'll be automatically filled in using the date and time your pipeline runs minus 1 hour, day, week, etc (based on your schedule's interval). | `2022-10-01T00:00:00.000000` | | `_end_date` | You can define this variable as a [runtime variable](/getting-started/runtime-variable) in your pipeline or it'll be automatically filled in using the date and time your pipeline runs. | `2022-10-02T00:00:00.000000` | #### The `discover()` method The discover method should return a [Catalog](https://github.com/mage-ai/mage-ai/blob/master/mage_integrations/mage_integrations/sources/catalog.py) of streams that define the data in your source. For example discover methods, see our [Google Sheets](https://github.com/mage-ai/mage-ai/blob/master/mage_integrations/mage_integrations/sources/google_sheets/__init__.py) source or our [DynamoDB source](https://github.com/mage-ai/mage-ai/blob/master/mage_integrations/mage_integrations/sources/dynamodb/__init__.py). #### The `test_connection()` method ### Update `main()` function Change the source name in the `main()` function to match your new source: ```python theme={"system"} if __name__ == '__main__': main(MY_SOURCE) ``` ## Add your source to the UI The list of sources is available [here](https://github.com/mage-ai/mage-ai/blob/master/mage_ai/data_integrations/sources/constants.py), add yours to make it accessible via the UI. ## Document your source Document how to configure and use your source in the `README.md` file at the source's root directory. Documentation helps Magers and future contributor understand exactly how your source works! Be sure to be thorough and descriptive. [Here's an example](https://github.com/mage-ai/mage-ai/blob/master/mage_integrations/mage_integrations/sources/salesforce/README.md) of documentation done well. ## Test your source You'll first need to configure your [development environment](https://docs.mage.ai/contributing/development-environment). Once complete, follow this [doc](https://github.com/mage-ai/mage-ai/tree/master/mage_integrations) to test your new source. # Configure your development environment Source: https://docs.mage.ai/contributing/development-environment Want to get started contributing code? You're in the right place! Read on to learn how to set up your development environment. ## Getting started Configuring a development environment can be *hard*, but at Mage we're trying to make things as simple and straightforward as possible. To get started, you'll need Docker installed on your machine. You can read more about Docker [here](https://www.docker.com/). ## Environment setup Next, you'll need to configure your development environment. This should be as simple as running a few commands. You can watch the video below or skip to the numbered instructions. [YouTube video player](https://www.youtube.com/embed/mxKh2062sTc) **1. Configure your development environment** Configure your coding environment for local development: `pyenv`, pre-commit hooks, etc. Follow the instructions [here](https://github.com/mage-ai/mage-ai/blob/master/README_dev.md). **2. Create a new project** ```bash theme={"system"} ./scripts/init.sh [project_name] ``` **3. Build the dev docker image and run all services** ```bash theme={"system"} ./scripts/dev.sh [project_name] ``` If you only work on backend, use the command below for better performance ```bash theme={"system"} ./scripts/start.sh [project_name] ``` **4. Open Mage** When developing frontend, use port 3000. If you only need to develop backend, you can use port 6789. Find these ports at [http://localhost:3000](http://localhost:3000) & [http://localhost:6789](http://localhost:6789). ## Push code changes Once your environment is configured, you can make edits and see changes in real time! Now you're ready to contribute to the Mage repo. This is very similar to contributing to other open source projects on GitHub. If you *don't* have any experience contributing code and this is confusing, feel free to reach out in Slack and we'll help you get started. Otherwise, follow the steps below to push your code changes to the Mage repo. ## Troubleshoot ### Permission denied If you get an error relating to permission denied when trying to execute a script, it might have something to do with SELinux. Two or more containers are trying to mount the same volume. With SELinux itโ€™s not possible without the `z` option. For more information about using the `z` option, read [Dockerโ€™s documentation](https://docs.docker.com/storage/bind-mounts/). ### No such file or directory for "install\_and\_run.sh" file If you are using a Windows machine and run into the following error while executing the `docker-compose.yml` file: `exec ./scripts/install_and_run.sh: no such file or directory`, it may be due to a difference in line-endings used on Windows versus Macs. You can check the `mage_ai/frontend/scripts/install_and_run.sh` file in VSCode to see if it is using CRLFs (carriage return line feeds), and if it is, change it to LFs (line feeds) and save the file. Then try running the `docker-compose` command again. ![](https://mage-ai.github.io/assets/development/windows/update-crlf-to-lf-vscode.gif) ### ModuleNotFoundError: No module named 'x' If there were added new libraries you should manually handle new dependencies. It can be done in 2 ways: 1. `docker-compose build` from project root will fully rebuild an image with new dependencies - it can take lots of time 2. `pip install x` from inside the container will only install the required dependency - it should be much faster # Documentation Source: https://docs.mage.ai/contributing/documentation/overview Like every other part of Mage, our documentation is open-source. Read on to learn how to make edits or even write entirely new docs for Mage! ![](https://github.com/mage-ai/mage-ai/assets/59450879/769a5faf-37ea-453c-8bd6-83270366fe00) ## Overview Mage uses [Mintlify](https://www.mintlify.com/) as our documentation framework. Mintlify provides hosting and deployment for our docs, which makes editing quite simple. In this guide, we'll discuss different "levels" of contributing to our docs, starting from simplest to most advanced. All of our docs are written in plain text as Markdown files. If you're not familiar with Markdown, check out [this guide](https://www.markdownguide.org/basic-syntax/) to get started. You can take a look at the structure and contents of our docs by navigating this site and checking out the [docs directory](https://github.com/mage-ai/mage-ai) on GitHub. ## Level 1: Suggesting Edits ๐Ÿฆธ๐Ÿปโ€โ™‚๏ธ The very simplest way to contribute to the Mage docs is directly in the browser, using GitHub's file editing feature. This is a great way to suggest small edits to existing docs, but it's not the best way to add entirely new docs or complex formatting, images, etc. To make edits, simply click on the "Suggest Edit" button at the bottom of every page. This will open a new tab with the file you're editing. Make your changes, then click "Commit changes." This will open a new pull request with your changes. Be sure to add appropriate details to your pull request & tag `@wangxiaoyou1993`. Once the pull request is merged, your changes will be live on the site! ![](https://mage-ai.github.io/assets/contributing-docs.png) ## Level 2: Add complex components ๐Ÿ’ช ### Images To add images to the Mage docs, you'll need to contact a team member or host the images in GitHub. Our assets currently live in a private repo to keep the docs repo lightweight. Reach out in [Slack](https://www.mage.ai/chat) if you're editing documentation that requires additional assets and we'll get them hosted for you. When adding images, we use centered divs or the Mintlify frame component. You can see the code in this page for examples of both. ### Mintlify elements To learn more about Mintlify-specific elements, visit the Mintlify docs [here](https://mintlify.com/docs/content/page). You can add things like accordion groups, interactive lists, html elements, and more. Anything you can do in Mintlify, you can do in our docs. ## Level 3: Add entirely new docs ๐Ÿช„ ### Adding a new page Each page is an MDX file that should begin with the following metadata syntax with `---` at the start and end. Here are basics to get you started: 1. [Page basics](https://mintlify.com/docs/content/page) 2. [Headers and text](https://mintlify.com/docs/content/text) 3. [Images and embeds](https://mintlify.com/docs/content/image-embeds) Once you add a new page in the appropriate folder in our `docs` directory, you'll need to add it to our site navigation. That is accomplished through the `mint.json` file in the root of our `docs` directory. You'll need to add a new entry to the `pages` array in that file. The `path` should be the relative path to your new page, and the `title` should be the title of your page. Paths in `mint.json` should *not* include file extensions. The best way to understand the structure is to read about it in the [Mintlify docs](https://mintlify.com/docs/settings/global) and to take a look at our `mint.json` file [here](https://github.com/mage-ai/mage-ai/blob/master/docs/mint.json). ### Developing locally in Mintlify If you *really* want to level up your docs contributions, you can create a local development environment. This will allow you to see changes *live* as you make them on your machine. Follow the instructions from Mintlify [here](https://mintlify.com/docs/quickstart#2-updating-your-docs) to get started. Once configured, you'll be able to run a local server that will allow you to see your changes in real-time. Simply `cd mage-ai/docs` + `mintlify dev` and you'll be able to navigate to a live version at `localhost:3000`. ### Adding icons Some elements in Mintlify have icons. Those are sourced from [fontawesome](https://fontawesome.com/). Any icon you find there can be added as an icon to the Mage docs, where appropriate. We only add icons to top-level items in our sidebar. ## Level 4: Adding entirely new sections ๐Ÿง™๐Ÿปโ€โ™‚๏ธ If you'd like to contribute a larger, more structured section of our documentation, please reach out to a member of our team via Slack. They'll be able to guide you through the process of making sweeping changes. # Contributing to the front-end client Source: https://docs.mage.ai/contributing/frontend/overview Guides on adding features to the front-end client. | | | | - | - | | Language | TypeScript | | Framework | React, Next.js | | Code directory | `mage_ai/frontend/` | ## Style guide Mage follows the [Airbnb JavaScript style guide](https://airbnb.io/javascript/react/). ### Linter To run the linter locally, execute this script: ```bash theme={"system"} ./scripts/test.sh ``` ## Setup ```bash theme={"system"} yarn global add eslint-config-next yarn global add eslint_d ``` # Frontend testing Source: https://docs.mage.ai/contributing/frontend/testing Making Mage invincible so that nothing can break it, not even itself. ## Prerequisites * It is not recommended to run tests on your working project, since failed tests can leave behind empty pipelines, triggers, etc. Set up your [development environment](https://docs.mage.ai/contributing/development-environment). * Make sure [user authentication](https://docs.mage.ai/production/authentication/overview) is enabled. * Make sure your development server is running. ## Configuration * Tests default to "fail" if a client error occurs. Add the following to the top of the test file to disable this check. ```ts theme={"system"} test.use({ failOnClientError: false }); ``` * Certain setting features are enabled by default. Refer to `base.ts` for more information, and use the following snippet when needed. ```ts theme={"system"} test.use({ settingFeaturesToDisable: { [FeatureUUIDEnum.LOCAL_TIMEZONE]: true } }); ``` ## Running the tests You have the option to just run one specific test or all tests at once. There are [several ways](https://playwright.dev/docs/running-tests) to run specific tests. ```bash theme={"system"} # Run everything, headless by default. yarn test # Run everything with a browser. yarn test:h # Run test files that have the word "pipelines" in their names. yarn test pipelines ``` You can run the frontend tests using the CI/CD Playwright configuration with the following command: ```bash theme={"system"} yarn test:ci ``` ## Creating a test Refer to the [Playwright docs](https://playwright.dev/docs/writing-tests) for examples on writing frontend tests. ## Debugging The easiest way to debug is to run tests in UI mode so you can see what went wrong. ```bash theme={"system"} yarn test --ui # Or yarn test:ci --ui ``` If you are running into issues with the app and would like to report it, you can tell us about it either on [GitHub](https://github.com/mage-ai/mage-ai/issues/new/choose) or [Slack](https://www.mage.ai/chat). # Contributing Source: https://docs.mage.ai/contributing/overview We welcome all contributions to Mage; from small UI enhancements to brand new cleaning actions. We love seeing community members level up and give people power-ups! ![Contributing](https://media.giphy.com/media/5cZbRBLhW4tc4/giphy.gif) ## ๐Ÿฅพ Choose your adventure There *so* many ways to contribute to Mage! We welcome all contributions, no matter how small. Start your contribution journey below, whether you're an *apprentice* or a *master of spells*. Once you feel confident in your path, [read on](/contributing/development-environment) to learn how to get started. > **๐Ÿงช Alchemist** > > Thanks for leading the charge! The easiest way to contribute is to report bugs or suggest new features. > > ### Report bugs > > Head on over to our [Slack](https://mage.ai/chat) and let us know what's up. We recommend the `#bugs-troubleshoot-questions` channel. > > ### Squash bugs > > We're always trying to make our project better, but we need your help! Take a look at our [GitHub issues](https://github.com/mage-ai/mage-ai/issues) for small to medium complexity projects and bugs that need fixing. > **๐Ÿคน Loremaster** > > ### Suggest new features > > We *love* your suggestions. First take a look at our [roadmap](/about/roadmap) to see if your idea is already planned. You might also consider checking out open issues on [GitHub](https://github.com/mage-ai/mage-ai). > > Otherwise, drop a line in our [Slack](https://mage.ai/chat) and let us know what you're thinking. We recommend the `#feature-requests` channel. > > ### Write documentation > > We have *a lot* of docs. We really hope they're fun to read, but we know they can be improved. > > The great news is that they're fun to write, too! The *easiest* way to contribute is by scrolling to the bottom of the page you'd like to edit (maybe this one) and clicking the "Edit this page" link. You'll be taken to GitHub where you can make your changes and submit a pull request. > > ![](https://mintcdn.com/mage/KCVtYQD46PIylqWZ/media/edit-docs.png?fit=max\&auto=format\&n=KCVtYQD46PIylqWZ\&q=85\&s=d7203cb15c020b1c930cb499473bd53d) > > If you like working in code, that's great too! All of our docs are written in markdown, so you can just pull Mage from [GitHub](https://github.com/mage-ai/mage-ai) and start writing. > **๐Ÿ—ฃ๏ธ Bard/Herald** > > ### Community Support > > If you're already an adept Mager, we need your help! We're looking for community members to help answer questions in our [Slack](https://mage.ai/chat). Check out the `#bugs-troubleshoot-questions`, `#general`, and `#feature-requests` channels to get started. Anything helps! > > If you want to take it up a notch, check out our GitHub issues! We have a lot of [open issues](https://github.com/mage-ai/mage-ai/issues) that need your help. > **๐Ÿงฑ Stonemason** > > ### Backend development > > We're always looking for help with the Mage backendโ€” that might look like refactoring code, adding new features, or fixing bugs. > > [Here's](https://github.com/mage-ai/mage-ai/pull/3497) an example of an *amazing* backend PR that drastically improved dbt functionality in Mage. > > Check out our [roadmap](https://airtable.com/shrJctaGt4tvU27uF/tbl5bIlFkk2KhCpL4) for small to large complexity projects that need your help! > > ### Data integration > > Mage supports [data integration](/data-integrations/overview) pipelines via the Singer spec. We're always looking for help adding/updating our sources and destinations. > > Here's an example of a [great community PR](https://github.com/mage-ai/mage-ai/pull/2277) & here's our [docs on adding a source](/contributing/data-integrations/adapt-existing-source). > > ### IO operations (SQL block) and templates > > Want to help build *awesome* tools *inside* the pipeline builder page? Help out with our IO operations by adding new SQL blocks! Here's a PR that implements a [DuckDB IO Class](https://github.com/mage-ai/mage-ai/pull/3463). > > The simplest way you can help is by adding data loader/exporter templates. Here's an example PR that adds a few for [DuckDB](https://github.com/mage-ai/mage-ai/pull/3553). > **๐Ÿ‘จโ€๐ŸŽจ Illuminator** > > ### Frontend development > > Want to help build the *future* of the Mage UI? Help out with our frontend development! We're always looking for help with UI/UX, accessibility, and more. Checkout our [frontend](/contributing/frontend/overview) page for more info. Got questions? Live chat with us in [Slack](https://www.mage.ai/chat) Anything you contribute, the Mage team and community will maintain. Weโ€™re in it together! # Styling Source: https://docs.mage.ai/contributing/styling ## Python Ruff is the repository's only canonical Python formatter. It uses single quotes and a 100-character line length. Run the pinned version from the repository environment only on the Python files changed by your PR: ```bash theme={"system"} isort pre-commit run ruff-format --files python -m ruff check flake8 pre-commit run --files ``` Do not use Black or format whole directories as part of a feature or bug-fix PR. Repository-wide formatting should be isolated in a dedicated formatting PR. ## Frontend ```bash theme={"system"} eslint_d --fix --ext .js,.jsx,.ts,.tsx git diff --name-status master | grep '^[AM?]' | awk '{$1=""; sub("^[ \t]+", ""); print}' | grep '\.\(js\|jsx\|ts\|tsx\)$' | xargs eslint_d --config mage_ai/frontend/.eslintrc.js --fix --ext .js,.jsx,.ts,.tsx ``` # Using data integrations in batch pipelines (in Beta) Source: https://docs.mage.ai/data-integrations/batch-pipelines Load data from data integration sources and export to data integration destinations as blocks inside batch pipelines. ![Data integrations combined with batch pipelines](https://img.wattpad.com/5ea336f507cf05c821ffbba96cf6c7739fe8dc3e/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f776174747061642d6d656469612d736572766963652f53746f7279496d6167652f4672554e706c504b46744b7469413d3d2d313038313931343836362e313638396434663466313232653937363936373434323438363033362e676966) > [!WARNING] > > Available in version **`0.9.35`** and greater. ## Overview You can use a [data integration source](/data-integrations/sources/overview) (e.g. Stripe) and/or a [data integration destination](/data-integrations/destinations/overview) (e.g. Trino) as a block in batch pipelines. ### Why is this important? Combine the low-code aspect and capabilities of data integrations with the flexibility and dynamic capabilities of a batch pipeline. ### Example 1. Use a Python data loader block to write custom code for fetching Stripe credentials. 2. Use a SQL data loader block to fetch data from a table in PostgreSQL. 3. Add a data integration source block to fetch data from Stripe. 4. Use the output from the Python data loader block and interpolate the Stripe credentials into the data integration source block. 5. Add a Python transformer block to merge, clean, and aggregate data fetched from PostgreSQL and Stripe. 6. Add a data integration destination block that writes the output data from the Python transformer block and export it to SalesForce. > [!TIP] > > The image below doesnโ€™t reflect the above example exactly. > > The image shows a different set of blocks than the example above. ![Example](https://mage-ai.github.io/assets/batch-pipelines/data-integrations/block-runs.png) *** ## Features * Use any data integration source. * Use any data integration destination. * Sources and destinations have capabilities of a normal Python block in a batch pipeline. * Dynamically calculate the source and destination credentials at runtime. * Dynamically build the source and destination catalog schema at runtime. * Source blocks can output its fetched data to any downstream block. * Any block can output its data to a destination block and have it exported to that destination. * Support incremental sync * `[Coming soon]` *Support log based sync*. * `[Coming soon]` *Replicate source and destination blocks*. * `[Coming soon]` *Support source and destination blocks as dynamic blocks*. *** ## How to use 1. Go to the [project preferences](http://localhost:6789/settings/workspace/preferences) and enable the feature labeled **`Data integration in batch pipeline`**. > [!TIP] > > This feature requires the `Add new block v2` feature to be enabled. 2. Create a new batch pipeline. 3. Add a new Data loader block by selecting: 1. **Templates** โ†’ 2. **Data loader** โ†’ 3. **Sources** โ†’ 4. Select the source to add to the pipeline. ![Add source block](https://mage-ai.github.io/assets/batch-pipelines/data-integrations/add-source-block.png) 4. Configure the source: 1. Add credentials. 2. Select 1 or more streams to sync. 3. Setup stream settings. 4. Select 1 or more columns to sync from stream. ![Source block](https://mage-ai.github.io/assets/batch-pipelines/data-integrations/source-block.png) 5. Add a new Data exporter block by selecting: 1. **Templates** โ†’ 2. **Data exporter** โ†’ 3. **Destinations** โ†’ 4. Select the source to add to the pipeline. ![Add destination block](https://mage-ai.github.io/assets/batch-pipelines/data-integrations/add-destination-block.png) 6. Configure the destination: 1. Add credentials. 2. Select 1 or more stre.ams to export. 3. Setup stream settings. 4. Select 1 or more columns to include in the destination table when exporting stream. ![Destination block](https://mage-ai.github.io/assets/batch-pipelines/data-integrations/destination-block.png) *** ## Configure source and destination For more information on how to configure and setup a data integration source and destination, refer back to the original [data integration guide](/guides/data-integration-pipeline). ### Credentials ![Configure credentials](https://mage-ai.github.io/assets/batch-pipelines/data-integrations/configuration-credentials.png) ### Upstream block settings ![Configure upstream block settings](https://mage-ai.github.io/assets/batch-pipelines/data-integrations/configuration-upstream-block-settings.png) ### Select streams ![Select streams](https://mage-ai.github.io/assets/batch-pipelines/data-integrations/streams.png) ### Streams overview with bulk editing ![Streams overview with bulk editing](https://mage-ai.github.io/assets/batch-pipelines/data-integrations/overview.png) ### Stream detail overview For more information on how to configure settings for a stream, refer back to the original [data integration guide](/guides/data-integration-pipeline). ![Stream detail overview](https://mage-ai.github.io/assets/batch-pipelines/data-integrations/stream-detail-overview.png) ### Stream detail schema properties with bulk editing For more information on how to configure schema properties for a stream, refer back to the original [data integration guide](/guides/data-integration-pipeline). ![Stream detail schema properties with bulk editing](https://mage-ai.github.io/assets/batch-pipelines/data-integrations/stream-detail-schema-properties.png) ### Stream detail sample data ![Stream detail sample data](https://mage-ai.github.io/assets/batch-pipelines/data-integrations/stream-detail-sample-data.png) *** ## Python blocks When adding a data integration source or destination block to a batch pipeline, you can choose the language to be YAML or Python (default option is YAML). If you choose Python as the language, you programmatically define the following settings of the data integration: | Configuration | Example | Decorator | Description | | - | - | - | - | | Source | `stripe` | `@data_integration_source` | The source to load data from. | | Destination | `salesforce` | `@data_integration_destination` | The destination to export data to. | | Config | `database='...'` | `@data_integration_config` | A dictionary containing the credentials and other settings specific to the source or destination. | | Selected streams | `['account']` | `@data_integration_selected_streams` | A list of stream names to be selected from the catalog. | | Catalog | `{...}` | `@data_integration_catalog` | A dictionary containing a list of streams and the streamโ€™s settings, schema properties, and metadata. | ### `@data_integration_source` > [!TIP] > > This decorated function is required. ```python theme={"system"} @data_integration_source def source(*args, **kwargs) -> str: return 'postgresql' ``` ### `@data_integration_destination` > [!TIP] > > This decorated function is required. ```python theme={"system"} @data_integration_destination def destination(*args, **kwargs) -> str: return 'postgresql' ``` ### `@data_integration_config` > [!TIP] > > This decorated function is required. ```python theme={"system"} @data_integration_config def config(*args, **kwargs) -> Dict: destination: str = kwargs.get('destination', None) return { 'database': '', 'host': '', 'password': '', 'port': 5432, 'schema': '', 'table': '', 'username': '', } ``` #### Keyword arguments inside the decorated function The following keyword arguments are only available in the decorated functionโ€™s body for sources. | | | | - | - | | Keyword | `source` | | Sample code | `kwargs['source']` | | Return value type | `str` | | Sample return value | `'postgresql'` | | Description | The name of the source | | Available in | Sources only | | | | | - | - | | Keyword | `destination` | | Sample code | `kwargs['destination']` | | Return value type | `str` | | Sample return value | `'postgresql'` | | Description | The name of the destination | | Available in | Destinations only | ### `@data_integration_selected_streams` > [!NOTE] > > This decorated function is optional. ```python theme={"system"} @data_integration_selected_streams(discover_streams: bool = False) def selected_streams(*args, **kwargs) -> List[str]: config: Dict = kwargs.get('config', None) discover_streams_func: Callable = kwargs.get('discover_streams_func', None) source: str = kwargs.get('source', None) return [] ``` #### Decorator arguments The following arguments are only available in the decorator `@data_integration_selected_streams` for sources. | | | | - | - | | Argument | `discover_streams` | | Argument values | `False`, `True` | | Description | If `True`, there will be a list of stream names available in the functionโ€™s body via the keyword argument `selected_streams`; e.g. `kwargs['selected_streams']`. This list of stream names are retrieved by the sourceโ€™s underlying code in the [Mage Integrations library](https://github.com/mage-ai/mage-ai/tree/master/mage_integrations/mage_integrations/sources). | | Available in | Sources only | #### Keyword arguments inside the decorated function The following keyword arguments are only available in the decorated functionโ€™s body. | | | | - | - | | Keyword | `source` | | Sample code | `kwargs['source']` | | Return value type | `str` | | Sample return value | `'postgresql'` | | Description | The name of the source | | Available in | Sources only | | | | | - | - | | Keyword | `destination` | | Sample code | `kwargs['destination']` | | Return value type | `str` | | Sample return value | `'postgresql'` | | Description | The name of the destination | | Available in | Destinations only | | | | | - | - | | Keyword | `config` | | Sample code | `kwargs['config']` | | Return value type | `dict` | | Sample return value | `{ 'database': '...' }` | | Description | The dictionary containing the credentials and other configurations. | | Available in | Sources and destinations | | | | | - | - | | Keyword | `selected_streams` | | Sample code | `kwargs['selected_streams']` | | Return value type | `List[str]` | | Sample return value | `['account', 'users']` | | Description | A list of strings containing all the available stream names for the source. This is only available if `discover_streams` is `True`. | | Available in | Sources only | | | | | - | - | | Keyword | `discover_streams_func` | | Sample code | `kwargs['discover_streams_func']` | | Return value type | `Callable` | | Sample return value | If function is invoked, the return value is the same as `selected_streams` above. | | Description | A list of stream names are retrieved by the sourceโ€™s underlying code in the [Mage Integrations library](https://github.com/mage-ai/mage-ai/tree/master/mage_integrations/mage_integrations/sources). | | Available in | Sources only | ### `@data_integration_catalog` > [!NOTE] > > The returned dictionary will override the catalog setup through the > user interface. ```python theme={"system"} @data_integration_catalog(discover: bool = False, select_all: bool = True) def catalog(*args, **kwargs) -> Dict: config: Dict = kwargs.get('config', None) selected_streams: List[str] = kwargs.get('selected_streams', None) source: str = kwargs.get('source', None) # catalog_from_discover is None unless discover=True catalog_from_discover: Dict = kwargs.get('catalog', None) # Executing this function will fetch and return the catalog discover_func: Callable = kwargs.get('discover_func', None) return { 'streams': [], } ``` #### Decorator arguments The following arguments are only available in the decorator `@data_integration_catalog` for sources. | | | | - | - | | Argument | `discover` | | Argument values | `False`, `True` | | Description | If `True`, the source will fetch the catalog and all stream schema properties then pass the returned value to the decorated functionโ€™s keyword arguments. | | Available in | Sources only | | | | | - | - | | Argument | `select_all` | | Argument values | `True`, `False` | | Description | If `False`, the streams in the catalog wonโ€™t be selected by default and youโ€™ll have to manually select the stream via the streamโ€™s metadata. | | Available in | Sources only | #### Keyword arguments inside the decorated function The following keyword arguments are only available in the decorated functionโ€™s body. | | | | - | - | | Keyword | `source` | | Sample code | `kwargs['source']` | | Return value type | `str` | | Sample return value | `'postgresql'` | | Description | The name of the source | | Available in | Sources only | | | | | - | - | | Keyword | `destination` | | Sample code | `kwargs['destination']` | | Return value type | `str` | | Sample return value | `'postgresql'` | | Description | The name of the destination | | Available in | Destinations only | | | | | - | - | | Keyword | `config` | | Sample code | `kwargs['config']` | | Return value type | `dict` | | Sample return value | `{ 'database': '...' }` | | Description | The dictionary containing the credentials and other configurations. | | Available in | Sources and destinations | | | | | - | - | | Keyword | `selected_streams` | | Sample code | `kwargs['selected_streams']` | | Return value type | `List[str]` | | Sample return value | `['account', 'users']` | | Description | A list of strings containing the available stream names returned from the decorated function under `@data_integration_selected_streams`. | | Available in | Sources and destinations | | | | | - | - | | Keyword | `catalog` | | Sample code | `kwargs['catalog']` | | Return value type | `dict` | | Sample return value | `{ 'streams': [] }` | | Description | A dictionary with a key named `streams` that is a list of dictionaries containing the stream schema properties and metadata. This is only available if `discover` is `True`. | | Available in | Sources only | | | | | - | - | | Keyword | `discover_func` | | Sample code | `kwargs['discover_func']` | | Return value type | `Callable` | | Sample return value | If function is invoked, the return value is the same as `catalog` above. | | Description | If function is invoked, the source will fetch the catalog and all stream schema properties. | | Available in | Sources only | *** ## Data from upstream blocks The data integration source and destination block can depend on upstream blocks. Those upstream blocks can pass its output data into the data integration source and destination, which then can be used as: * Input arguments to interpolate information in the credentials (or other decorated functions if source or destination block is a Python block). * Data to be exported to a destination. ### Input arguments Follow these steps to use the output of an upstream block as an input: 1. Open the data integration blockโ€™s configuration and click on the tab labeled **Upstream block settings**. ![Configure upstream block settings](https://mage-ai.github.io/assets/batch-pipelines/data-integrations/configuration-upstream-block-settings.png) 2. Toggle the name of the block you want as an input. 3. Check the box labeled **Use the blockโ€™s output data as an input**. > [!TIP] > > Inputs are available as positional arguments for all decorated functions in Python blocks. #### Other options > **Only use this blockโ€™s output data as an input** > > If checked, then the upstream blockโ€™s output data is only used as inputs and wonโ€™t be ingested > and exported to the destination. This is only applicable to destination blocks. > **Use catalog as an input** > > If checked, then the upstream blockโ€™s catalog will be included as part of the input argument(s) > for the data integration block. #### Examples using upstream data output as inputs If you have an upstream block, named `pg_credentials`, that has the following code: ```python theme={"system"} @custom def get_credentials(*args, **kwargs): return dict( database='dangerous', host='host.docker.internal', password='postgres', port=5432, schema='mage', username='postgres', ) ``` Here are examples on how to use the upstream blockโ€™s output to configure credentials at runtime: > **YAML blocks** > > If you have a data integration source or > destination block that depends on the above upstream block, > you can interpolate the output of the upstream block in the source or destination blockโ€™s > credentials like this: > > ```yaml theme={"system"} > database: | > {{ block_output('pg_credentials', parse='lambda x: x["database"]') }} > host: | > {{ block_output('pg_credentials', parse='lambda x: x["host"]') }} > password: | > {{ block_output('pg_credentials', parse='lambda x: x["password"]') }} > port: | > {{ block_output('pg_credentials', parse='lambda x: x["port"]') }} > schema: | > {{ block_output('pg_credentials', parse='lambda x: x["schema"]') }} > username: | > {{ block_output('pg_credentials', parse='lambda x: x["username"]') }} > ``` > **Python blocks** > > Depending on how many upstream blocks your source or destination block uses as an input, > itโ€™ll determine how many positional arguments are available in any of your decorated functions. > > ```python theme={"system"} > @data_integration_config > def config(credentials, *args, **kwargs) -> Dict: > return { > 'database': credentials['database'], > 'host': credentials['host'], > 'password': credentials['password'], > 'port': credentials['port'], > 'schema': credentials['schema'], > 'username': credentials['username'], > } > ``` #### Examples using upstream blockโ€™s catalog as input If you have an upstream block, named `titanic_survival`, that has the following code: ```python theme={"system"} import io import pandas as pd import requests @data_loader def load_data_from_api(*args, **kwargs): url = 'https://raw.githubusercontent.com/mage-ai/datasets/master/titanic_survival.csv' response = requests.get(url) return pd.read_csv(io.StringIO(response.text), sep=',') ``` And its output data has the following Pandas data types: | Column | Data type | Sample data | | - | - | - | | PassengerId | `int64` | 2 | | Survived | `int64` | 1 | | Pclass | `int64` | 1 | | Name | `object` | Mrs. John Bradley (Florence Briggs Thayer) | | Sex | `object` | female | | Age | `float64` | 38 | | SibSp | `int64` | 1 | | Parch | `int64` | 0 | | Ticket | `object` | PC 17599 | | Fare | `float64` | 71.2833 | | Cabin | `object` | C85 | | Embarked | `object` | C | Here are examples on how to use the upstream blockโ€™s catalog as an input to the data integrationโ€™s decorated functions: > **Python blocks** > > Depending on how many upstream blocks your source or destination block uses as an input, > itโ€™ll determine how many positional arguments are available in any of your decorated functions. > > ```python theme={"system"} > @data_integration_catalog > def catalog(titanic_survival_data_and_catalog, *args, **kwargs) -> Dict: > _data, catalog = titanic_survival_data_and_catalog > > return catalog > ``` > > The positional argument correlated to the upstream block that youโ€™re using as an input > will be either a single object or a tuple. Itโ€™s a tuple if you checked the box > labeled **Use catalog as an input** in the data integration blockโ€™s configuration on > the tab labeled **Upstream block settings**. > > In this example, the last item in the tuple from the 1st positional argument ( > e.g. `titanic_survival_data_and_catalog`) contains a Python dictionary that represents > the catalog from the upstream block named `titanic_survival`. > > This catalog contains a key named `streams` that is a list of dictionaries containing > stream settings, metadata, and schema properties of the output data from the upstream > block `titanic_survival`. > > Here is an example of that catalog (a lot of the metadata and schema properties are omitted > from this example so that itโ€™s not too lengthy): > > ```python theme={"system"} > { > 'streams': [ > { > 'metadata': [ > { > 'breadcrumb': [ > 'properties', > 'Embarked', > ], > 'metadata': { > 'inclusion': 'available', > 'selected': True, > }, > }, > ], > 'schema': { > 'properties': { > 'PassengerId': { > 'type': [ > 'null', > 'integer', > ], > }, > }, > 'type': 'object', > }, > 'stream': 'titanic', > 'type': 'SCHEMA', > 'replication_method': 'FULL_TABLE', > }, > ], > } > ``` ### Data to be exported > [!NOTE] > > Outputs from upstream blocks, as data to be exported, can only be used by destination blocks. The outputs from upstreams blocks will not only be available as an input, but itโ€™ll also be used as a data stream when ingesting and exporting to the destination. You can control which upstream blockโ€™s data is ingested and exported by configuring the destination blockโ€™s streams. ![Select streams](https://mage-ai.github.io/assets/batch-pipelines/data-integrations/streams.png) *** ## Output data from source blocks > [!NOTE] > > Destination blocks donโ€™t output any data to downstream blocks. A data integration source block will output the data fetched from the source and pass that data to its downstream blocks. A downstream data integration destination block will automatically know how to ingest the data and process it for exporting. ### Shape of output data All other types of blocks will receive the data integration source blockโ€™s output data either as a dictionary or as a list containing 2 or more dictionaries. The output data will be a dictionary if the source block is only fetching 1 stream. The output data will be a list of dictionaries if the source block is fetching 2 or more streams. The number of items in the list corresponds to the number of streams that the source block is configured to sync. #### Shape of dictionary Each item in the list is a dictionary with the following keys: | Key | Value data type | Sample value | Description | | - | - | - | - | | `stream` | `dict` | `{ 'stream': 'accounts' }` | The dictionary for key `stream` contains information about the streamโ€™s name (via the `stream` key), settings (e.g. replication method), metadata, and schema properties. | | `columns` | `List[str]` | `['id', 'power', 'created_at']` | A list of column names from the data that was fetched for the stream. | | `rows` | `List[List[Any]]` | `[[1, 3.5, '3000-01-01']]` | A list of lists where each item in the outer list is a row that was fetched from the stream. Each item in the inner list is a value from a column. The column that the value corresponds to is determined by the index of that value in its list and the column name at that same index in the `columns` list. | ### Sample output data > **JSON format** > > ```json theme={"system"} > { > "columns": [ > "passengerid", > "survived", > "pclass", > "name", > "sex", > "age", > "sibsp", > "parch", > "ticket", > "fare", > "cabin", > "embarked", > "_mage_created_at", > "_mage_updated_at" > ], > "stream": { > "tap_stream_id": "titanic", > "replication_method": "FULL_TABLE", > "key_properties": [], > "schema": { > "properties": { > "passengerid": { > "type": [ > "null", > "integer" > ] > } > }, > "type": "object" > }, > "stream": "titanic", > "metadata": [ > { > "breadcrumb": [], > "metadata": { > "table-key-properties": [], > "forced-replication-method": "FULL_TABLE", > "valid-replication-keys": [], > "inclusion": "available", > "schema-name": "titanic", > "selected": true > } > }, > { > "breadcrumb": [ > "properties", > "passengerid" > ], > "metadata": { > "inclusion": "available", > "selected": true > } > } > ], > "auto_add_new_fields": false, > "unique_conflict_method": "UPDATE", > "run_in_parallel": false > }, > "rows": [ > [ > 1, > 0, > 3, > "Braund, Mr. Owen Harris", > "male", > 22.0, > 1, > 0, > "A/5 21171", > 7.25, > null, > "S", > "2023-09-23T04:14:44.850136-07:00", > "2023-09-23T04:14:44.850136-07:00" > ], > [ > 1, > 0, > 3, > "Braund, Mr. Owen Harris", > "male", > 22.0, > 1, > 0, > "A/5 21171", > 7.25, > null, > "S", > "2023-09-23T04:37:30.366570-07:00", > "2023-09-23T04:37:30.366570-07:00" > ], > [ > 2, > 1, > 1, > "Cumings, Mrs. John Bradley (Florence Briggs Thayer)", > "female", > 38.0, > 1, > 0, > "PC 17599", > 71.2833, > "C85", > "C", > "2023-09-23T04:14:44.850153-07:00", > "2023-09-23T04:14:44.850153-07:00" > ], > [ > 2, > 1, > 1, > "Cumings, Mrs. John Bradley (Florence Briggs Thayer)", > "female", > 38.0, > 1, > 0, > "PC 17599", > 71.2833, > "C85", > "C", > "2023-09-23T04:37:30.366592-07:00", > "2023-09-23T04:37:30.366592-07:00" > ], > [ > 3, > 1, > 3, > "Heikkinen, Miss. Laina", > "female", > 26.0, > 0, > 0, > "STON/O2. 3101282", > 7.925, > null, > "S", > "2023-09-23T04:14:44.850155-07:00", > "2023-09-23T04:14:44.850155-07:00" > ], > [ > 3, > 1, > 3, > "Heikkinen, Miss. Laina", > "female", > 26.0, > 0, > 0, > "STON/O2. 3101282", > 7.925, > null, > "S", > "2023-09-23T04:37:30.366594-07:00", > "2023-09-23T04:37:30.366594-07:00" > ], > [ > 4, > 1, > 1, > "Futrelle, Mrs. Jacques Heath (Lily May Peel)", > "female", > 35.0, > 1, > 0, > "113803", > 53.1, > "C123", > "S", > "2023-09-23T04:14:44.850157-07:00", > "2023-09-23T04:14:44.850157-07:00" > ] > ] > } > ``` *** ## Load/Export stream data in parallel For each stream in a data integration source block, you can enable that stream to have its data fetched in parallel while other streams for that source is being fetched. For each stream in a data integration destination block, you can enable that stream to have its data exported in parallel while other streams for that destination is being exported. This option can be turned on by editing a specific streamโ€™s settings. ![Stream detail overview](https://mage-ai.github.io/assets/batch-pipelines/data-integrations/stream-detail-overview.png) This option can also be turned on or off for multiple streams at once by bulk editing all the streams at once in the **Overview** section: ![Streams overview with bulk editing](https://mage-ai.github.io/assets/batch-pipelines/data-integrations/overview.png) *** ## Incremental sync Synchronize your data incrementally after the 1st sync. When you choose 1 or more bookmark values in a stream, the value from that property will be saved after each successful sync. The next sync will use that value to compare to the next batch of records that need to be synced. ### Override bookmark values If you want to change the last saved bookmark value for the next sync, you can do this in 2 ways: > **Trigger pipeline to run once** > >