> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mage.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Mage tips & tricks

> Here are some neat ways you can make the most of Mage! Tips and tricks to help you make the most magical pipelines possible.

<AccordionGroup>
  <Accordion title="Version Control" icon="cat">
    Mage has native version control for your files, so you'll never lose work again!
    Check it out in our docs [here](/getting-started/file-versions) or see the video below for a tutorial.

    <Frame>
      <iframe width="560" height="315" src="https://www.youtube.com/embed/bz8xLeoKzFo" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen />
    </Frame>
  </Accordion>

  <Accordion title="DuckDB integration" icon="duck">
    Mage integrates with DuckDB! Watch the video below to learn more or read on [here](/integrations/databases/DuckDB).

    <Frame>
      <iframe width="560" height="315" src="https://www.youtube.com/embed/FmATfXoWudM" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen />
    </Frame>
  </Accordion>

  <Accordion title="Edit Pipelines with AI" icon="robot">
    Mage has an integration with the OpenAI API. Watch the video to learn about how you can generate pipelines using the power of AI.

    See our full docs [here](/development/ai/overview) for more info.

    <Frame>
      <iframe width="560" height="315" src="https://www.youtube.com/embed/KNBkVhtflzU" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen />
    </Frame>
  </Accordion>

  <Accordion title="Stream data to any destination" icon="water">
    Mage supports streaming data to any of our destinations. Watch the video below to learn about configuring a streaming pipeline in under a minute!

    See our full docs [here](/streaming/overview) for more info.

    <Frame>
      <iframe width="560" height="315" src="https://www.youtube.com/embed/9STvcYIBXdc" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen />
    </Frame>
  </Accordion>

  <Accordion title="Use Conditional Blocks" icon="question">
    Watch this video to learn how you can use Conditional Blocks to add conditional execution and branching logic to your next data pipeline!

    See our full docs [here](/design/blocks/conditionals) for more info.

    <Frame>
      <iframe width="560" height="315" src="https://www.youtube.com/embed/D05C7atfCRQ" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen />
    </Frame>
  </Accordion>

  <Accordion title="Replicate Blocks" icon="block">
    Watch this video to learn how you can use Replica Blocks to add conditional execution and branching logic to your next data pipeline!

    See our full docs [here](/guides/blocks/replicate-blocks) for more info.

    <Frame>
      <iframe width="560" height="315" src="https://www.youtube.com/embed/M_bBCSTNDw4" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen />
    </Frame>
  </Accordion>

  <Accordion title="Use Split Pane View" icon="window">
    The Mage pipeline editor can be used in a single, notebook-style interface *or* in a split-pane view, with block output displayed on the right and blocks themselves on the left.

    Split pane view can be enabled by selecting the "split" icon in the pipeline editor, as shown below:

    <Frame>
      <img src="https://mage-ai.github.io/assets/split-pane-view.png" />
    </Frame>

    Can't wait to try it out? Check out the video below for a demo!

    <Frame>
      <iframe width="560" height="315" src="https://www.youtube.com/embed/x4VLyIG6fCc" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen />
    </Frame>
  </Accordion>

  <Accordion title="Group & Filter Pipelines" icon="folder">
    This week's Mage tip is all about organization!

    Did you know you can tag, group, and filter your pipelines from the overview page? Watch the video below to learn more 😀

    Read more in our docs [here](/pipelines/pipeline-tagging)!

    <Frame>
      <iframe width="560" height="315" src="https://www.youtube.com/embed/QG88AWdB-Mo" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen />
    </Frame>
  </Accordion>

  <Accordion title="New Tree View" icon="tree">
    We've received a ton of feedback from our users, and we've been hard at work making updates to the tree view based on your suggestions. So, what's new? Let me give you the lowdown. 👇

    🔹 Enhanced Functionality: The tree view now comes with a whole right-click menu that allows you to easily run, rename, insert, or delete blocks. You have more control than ever before!

    🔹 Seamless Connections: You can now remove and add connections with a simple click. Plus, you can insert new blocks between existing ones effortlessly.

    🔹 Enhanced Visualizations: With the new tree view, you get grouping and better lineage for certain block types 🔄

    Not only does the new tree view offer improved functionality, but it also makes your pipelines look absolutely stunning! After all, our goal is to make data beautiful. 💫

    <Frame>
      <iframe width="560" height="315" src="https://www.youtube.com/embed/G0OjD38MnXE" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen />
    </Frame>
  </Accordion>

  <Accordion title="Dynamic Blocks" icon="bomb">
    What are dynamic blocks? Think of them as the magical way to create tasks dynamically in our tool. If you're familiar with Airflow and the concept of Dynamic Task Mapping, this is pretty similar.

    If you have a bunch of small tasks that you want to execute in parallel, Dynamic Blocks are here to save the day!

    Dynamic Blocks in Mage give you the power to parallelize your workflow and reduce output effortlessly. It's a pattern that has been around in data engineering, but we've made it incredibly easy and efficient.

    Learn more [here](/design/blocks/dynamic-blocks).

    <Frame>
      <iframe width="560" height="315" src="https://www.youtube.com/embed/jQZb3lrAb8w" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen />
    </Frame>
  </Accordion>

  <Accordion title="API Triggers" icon="code">
    Did you know you can trigger pipelines directly with API calls in Mage? 🧙‍♂️💻

    With API Triggers, you can kick-off your ETL runs in just about any way possible— a Python request, a cURL command, or a well-timed carrier pigeon (hopefully not). 🐦‍⬛

    API triggers carry the added benefit of supporting runtime parameters, meaning you can trigger your pipelines and supply external variables to customize functionality/output.

    You can read more in our docs [here](/orchestration/triggers/trigger-pipeline-api) & get started today.

    <Frame>
      <iframe width="560" height="315" src="https://www.youtube.com/embed/cHNTyGW51j8" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen />
    </Frame>
  </Accordion>

  <Accordion title="Backfills" icon="truck">
    Managing pipelines can be tricky, especially when it comes to backfilling missing data or re-running pipelines. But with Mage, backfills are a breeze! No need for custom scripts or complex setups. 🙌

    You can easily define a backfill for a specific date range. Whether you're missing data or want to add new columns, Mage has got you covered. Simply specify the start and end dates, and let Mage do the rest.

    Backfills simulate multiple runs with different execution dates, fetching the data you need and transforming it as required. 📅 🔃

    To learn more about backfills using Mage, check out our documentation [here](/orchestration/backfills/overview).

    <Frame>
      <iframe width="560" height="315" src="https://www.youtube.com/embed/V-wUccaafEo" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowFullScreen />
    </Frame>
  </Accordion>
</AccordionGroup>

## Run asynchronous code in blocks

```python theme={"system"}
import asyncio
from typing import Any, Dict

import aiohttp


@data_loader
def load_data_sync(*args, **kwargs) -> Dict[str, Any]:
    """
    Synchronously load data from a remote API endpoint using aiohttp and asyncio.
    Uses a configurable URL with a fallback to a working test endpoint.
    Includes error handling to gracefully manage connection issues.

    Returns:
        Dict[str, Any]: The JSON response from the API as a dictionary, or error info.
    """
    url: str = kwargs.get('url', 'https://jsonplaceholder.typicode.com/todos/1')

    async def fetch_data(url: str) -> Dict[str, Any]:
        # Create an aiohttp session and fetch the data
        async with aiohttp.ClientSession() as session:
            async with session.get(url) as response:
                response.raise_for_status()
                data: Dict[str, Any] = await response.json()
                return data

    # Check if there's already a running event loop
    try:
        loop = asyncio.get_running_loop()
    except RuntimeError:
        loop = None

    if loop and loop.is_running():
        # If running in an existing event loop (e.g., Jupyter), use create_task and await
        result: Dict[str, Any] = loop.run_until_complete(fetch_data(url))
    else:
        # If no running event loop, use asyncio.run
        result: Dict[str, Any] = asyncio.run(fetch_data(url))
    return result
```
