Skip to main content

Mintlify Documentation Setup

Publishing Your Python Tools Portfolio

What is Mintlify?

Mintlify auto-generates beautiful API documentation from your GitHub repos. Instead of maintaining docs manually, they pull from your code. Result: docs.yourname.dev with unified docs for all 50+ tools.

Setup: 5 Steps (30 minutes)

Step 1: Create Mintlify Account

  1. Go to mintlify.com
  2. Click “Sign up” → “Sign up with GitHub”
  3. Authorize Mintlify to access your GitHub org
  4. Create workspace: “Python Assets”

Step 2: Connect Your Tools

  1. In Mintlify dashboard: “New documentation”
  2. Select “GitHub” as source
  3. Choose organization: “yourname-tools”
  4. Select repositories to document:
    • async-retry
    • concur
    • … (all production tools)
  5. Click “Connect”

Step 3: Configure mint.json

Mintlify reads a mint.json file in your repo for configuration. Create: docs/mint.json in your main docs repo or in each tool repo.
{
  "name": "async-retry",
  "logo": {
    "light": "/logo/light.svg",
    "dark": "/logo/dark.svg"
  },
  "favicon": "/favicon.svg",
  "colors": {
    "primary": "#0D9373",
    "light": "#07C983",
    "dark": "#0D9373",
    "anchors": {
      "from": "#0D9373",
      "to": "#07C983"
    }
  },
  "topbarCtaButton": {
    "name": "Get Started",
    "url": "https://github.com/yourname-tools/async-retry"
  },
  "anchors": [
    {
      "name": "GitHub",
      "icon": "github",
      "url": "https://github.com/yourname-tools/async-retry"
    },
    {
      "name": "Discord",
      "icon": "discord",
      "url": "https://discord.gg/yourserver"
    }
  ],
  "navigation": [
    {
      "group": "Getting Started",
      "pages": [
        "introduction",
        "installation",
        "quickstart"
      ]
    },
    {
      "group": "Core Concepts",
      "pages": [
        "concepts/retry-strategies",
        "concepts/backoff-algorithms",
        "concepts/error-handling"
      ]
    },
    {
      "group": "API Reference",
      "pages": [
        "api/retry-decorator",
        "api/retry-async",
        "api/configuration"
      ]
    },
    {
      "group": "Examples",
      "pages": [
        "examples/basic-usage",
        "examples/advanced-patterns",
        "examples/integration-tests"
      ]
    },
    {
      "group": "FAQ",
      "pages": [
        "faq/common-issues",
        "faq/performance-tuning",
        "faq/contributing"
      ]
    }
  ]
}

Step 4: Create Documentation Files

Mintlify reads markdown files. Here’s the structure:
docs/
├── mint.json
├── introduction.mdx
├── installation.mdx
├── quickstart.mdx
├── concepts/
│   ├── retry-strategies.mdx
│   └── backoff-algorithms.mdx
├── api/
│   ├── retry-decorator.mdx
│   ├── retry-async.mdx
│   └── configuration.mdx
├── examples/
│   ├── basic-usage.mdx
│   └── advanced-patterns.mdx
└── faq/
    ├── common-issues.mdx
    └── contributing.mdx

Step 5: Deploy

In Mintlify dashboard:
  1. Click “Deploy”
  2. Select your docs folder
  3. Choose custom domain: docs.yourname.dev
  4. Wait 5 minutes
  5. ✅ Live!

Documentation Template Files

1. introduction.mdx

---
title: Introduction
description: "Robust retry patterns for async Python code"
---

# async-retry

Async-retry is a lightweight library for adding robust retry logic to async Python applications.

<CardGroup cols={2}>
  <Card
    title="Getting Started"
    icon="rocket"
    href="/quickstart"
  >
    Install and run your first retry in minutes
  </Card>
  <Card
    title="API Reference"
    icon="code"
    href="/api"
  >
    Complete reference for all functions and classes
  </Card>
  <Card
    title="Examples"
    icon="flask"
    href="/examples/basic-usage"
  >
    Real-world examples and patterns
  </Card>
  <Card
    title="GitHub"
    icon="github"
    href="https://github.com/yourname-tools/async-retry"
  >
    Source code and issue tracking
  </Card>
</CardGroup>

## Why async-retry?

<Tabs>
  <Tab title="Problem">
    Network requests fail. APIs timeout. Services go down.
    
    Without proper retry logic, your app fails too.
  </Tab>
  <Tab title="Solution">
    async-retry handles retries automatically:
    - Exponential backoff
    - Jitter support (avoid thundering herd)
    - Custom retry conditions
    - Async/await compatible
  </Tab>
  <Tab title="Result">
    Your app recovers gracefully from transient failures.
  </Tab>
</Tabs>

## Features

-**Lightweight**: No external dependencies
- 🔄 **Exponential backoff**: Configurable retry intervals
- 🎲 **Jitter**: Spread retries to avoid thundering herd
- 📊 **Metrics**: Built-in tracking of retry attempts
- 🧪 **Well-tested**: 95%+ code coverage
- 📖 **Well-documented**: Tons of examples

## Quick Example

```python
import asyncio
from async_retry import retry

@retry(max_attempts=3, backoff_factor=2)
async def fetch_data(url):
    async with httpx.AsyncClient() as client:
        return await client.get(url)

# Use it
result = await fetch_data("https://api.example.com/data")
That’s it! Retries handled automatically.

What’s Next?


### 2. installation.mdx

```mdx
---
title: Installation
description: "Get async-retry up and running"
---

# Installation

## Requirements

- Python 3.8+
- pip or poetry

## Using pip

```bash
pip install async-retry

Using poetry

poetry add async-retry

Verify Installation

python -c "import async_retry; print(async_retry.__version__)"
# Output: 1.2.3

Optional Dependencies

For development

pip install async-retry[dev]
This includes:
  • pytest (testing)
  • pytest-asyncio (async testing)
  • black (formatting)
  • mypy (type checking)

For documentation

pip install async-retry[docs]

Next Steps


### 3. quickstart.mdx

```mdx
---
title: Quick Start
description: "Get up and running in 5 minutes"
---

# Quick Start

## Basic Retry

The simplest way to add retries:

```python
import asyncio
from async_retry import retry

@retry(max_attempts=3)
async def fetch_api():
    # Your code here
    async with httpx.AsyncClient() as client:
        return await client.get("https://api.example.com")

# Use it
result = asyncio.run(fetch_api())
That’s it! If the function fails, it retries up to 3 times.

With Exponential Backoff

Add delays between retries:
@retry(
    max_attempts=5,
    backoff_factor=2  # 1s, 2s, 4s, 8s delays
)
async def fetch_with_backoff():
    async with httpx.AsyncClient() as client:
        return await client.get("https://api.example.com")

With Jitter

Spread out retries to avoid thundering herd:
@retry(
    max_attempts=5,
    backoff_factor=2,
    jitter=True  # Add randomness to delays
)
async def fetch_with_jitter():
    async with httpx.AsyncClient() as client:
        return await client.get("https://api.example.com")

Custom Retry Condition

Retry only on specific exceptions:
@retry(
    max_attempts=3,
    retry_on=(
        httpx.ConnectError,
        httpx.TimeoutException,
        ConnectionError
    )
)
async def fetch_selective():
    async with httpx.AsyncClient() as client:
        return await client.get("https://api.example.com")

With Logging

Track retry attempts:
import logging
from async_retry import retry

logger = logging.getLogger(__name__)

@retry(
    max_attempts=3,
    on_retry=lambda attempt, delay: 
        logger.warning(f"Retry {attempt}, waiting {delay}s")
)
async def fetch_logged():
    async with httpx.AsyncClient() as client:
        return await client.get("https://api.example.com")

Next Steps


### 4. api/retry-decorator.mdx

```mdx
---
title: "@retry Decorator"
description: "Main decorator for adding retry logic"
---

# @retry Decorator

The `@retry` decorator adds automatic retry logic to any async function.

## Signature

```python
@retry(
    max_attempts: int = 3,
    backoff_factor: float = 1,
    jitter: bool = False,
    retry_on: tuple[Exception] = (Exception,),
    on_retry: Callable[[int, float], Awaitable] = None,
)
async def your_function():
    pass

Parameters

ParameterTypeDefaultDescription
max_attemptsint3Maximum number of retry attempts
backoff_factorfloat1Multiplier for delay between retries (1s, 2s, 4s, etc.)
jitterboolFalseAdd random jitter to delays to avoid thundering herd
retry_ontuple[Exception](Exception,)Only retry on these exception types
on_retryCallableNoneCallback function called before each retry

Examples

Basic Retry

@retry(max_attempts=3)
async def basic():
    return await some_operation()

With Backoff

@retry(max_attempts=5, backoff_factor=2)
async def with_backoff():
    return await some_operation()
    # Retries at: 1s, 2s, 4s, 8s

With Jitter

@retry(max_attempts=5, backoff_factor=2, jitter=True)
async def with_jitter():
    return await some_operation()
    # Retries at: ~1s, ~2s, ~4s, ~8s (randomized)

Selective Retries

@retry(
    max_attempts=3,
    retry_on=(ConnectionError, TimeoutError)
)
async def selective():
    # Only retries on ConnectionError or TimeoutError
    # Other exceptions immediately fail
    return await some_operation()

With Logging

import logging

logger = logging.getLogger(__name__)

def log_retry(attempt: int, delay: float):
    logger.warning(f"Retry attempt {attempt}, waiting {delay}s")

@retry(
    max_attempts=3,
    on_retry=log_retry
)
async def logged():
    return await some_operation()

Return Value

The decorator preserves the original function’s return type.
@retry(max_attempts=3)
async def fetch_json() -> dict:
    async with httpx.AsyncClient() as client:
        response = await client.get("https://api.example.com/data")
        return response.json()

# Type is preserved
result: dict = await fetch_json()

Exceptions

If all retries fail, the original exception is raised:
@retry(max_attempts=2)
async def failing():
    raise ValueError("Always fails")

try:
    await failing()
except ValueError as e:
    print(f"Failed after 2 attempts: {e}")

Next Steps


---

## Portfolio Docs: Root mint.json

For a master docs site covering all 50+ tools:

**Create: `docs-site/mint.json`**

```json
{
  "name": "Python Assets Portfolio",
  "logo": {
    "light": "/logo/light.svg",
    "dark": "/logo/dark.svg"
  },
  "favicon": "/favicon.svg",
  "colors": {
    "primary": "#0D9373",
    "light": "#07C983",
    "dark": "#0D9373"
  },
  "navigation": [
    {
      "group": "Tools by Category",
      "pages": [
        {
          "group": "Concurrency",
          "pages": [
            "tools/concur",
            "tools/threading-helpers"
          ]
        },
        {
          "group": "Async",
          "pages": [
            "tools/async-retry",
            "tools/async-patterns"
          ]
        },
        {
          "group": "Data",
          "pages": [
            "tools/data-structures",
            "tools/data-validation"
          ]
        },
        {
          "group": "DevOps",
          "pages": [
            "tools/deployment-helpers",
            "tools/monitoring"
          ]
        }
      ]
    },
    {
      "group": "Learning",
      "pages": [
        "learning/async-guide",
        "learning/concurrency-patterns",
        "learning/best-practices"
      ]
    },
    {
      "group": "Resources",
      "pages": [
        "resources/github",
        "resources/contributing",
        "resources/contact"
      ]
    }
  ]
}

Deployment

Option 1: Mintlify Cloud (Easiest)

  1. In Mintlify dashboard: “Settings” → “Deployment”
  2. Select “Mintlify Cloud”
  3. Add custom domain: docs.yourname.dev
  4. Point DNS CNAME to Mintlify servers
  5. ✅ Done! Docs deploy automatically on push

Option 2: Self-Hosted (GitHub Pages)

# Install Mintlify CLI
npm install -g mintlify

# In docs folder
mintlify build

# Commit to GitHub Pages
git add dist/
git commit -m "Update docs"
git push

# Enable GitHub Pages in Settings

Option 3: Vercel

# Deploy to Vercel
vercel --prod

# Or connect GitHub repo to Vercel
# Auto-deploys on push

Tips for Great Docs

1. Add Code Blocks with Syntax Highlighting

```python
# Python example
@retry(max_attempts=3)
async def my_function():
    pass
```

```javascript
// JavaScript example
await retry(myFunction, {maxAttempts: 3});
```

2. Use Cards for Navigation

<CardGroup cols={2}>
  <Card
    title="Installation"
    icon="download"
    href="/installation"
  >
    Get started in 2 minutes
  </Card>
  <Card
    title="API Reference"
    icon="code"
    href="/api"
  >
    Complete API docs
  </Card>
</CardGroup>

3. Use Tabs for Different Examples

<Tabs>
  <Tab title="Basic">
    Simple example here
  </Tab>
  <Tab title="Advanced">
    Complex example here
  </Tab>
</Tabs>

4. Use Callouts for Important Info

<Note>
  This is important information
</Note>

<Warning>
  Be careful with this
</Warning>

<Tip>
  Pro tip for power users
</Tip>
See also: [async-retry](/tools/async-retry)
Related: [concurrency patterns](/learning/concurrency-patterns)

Auto-Generate API Docs

Use Mintlify’s auto-generation feature with docstrings:

Python Docstring Format

def retry(
    max_attempts: int = 3,
    backoff_factor: float = 1,
    jitter: bool = False,
) -> Callable:
    """
    Retry decorator for async functions.
    
    Args:
        max_attempts: Maximum number of retry attempts
        backoff_factor: Multiplier for delay between retries
        jitter: Add random jitter to delays
    
    Returns:
        Decorated async function with retry logic
    
    Example:
        ```python
        @retry(max_attempts=3)
        async def my_function():
            pass
Raises: ValueError: If max_attempts < 1 """ pass

Mintlify auto-generates API reference from these docstrings!

---

## SEO Optimization

In mint.json:

```json
{
  "seo": {
    "indexHiddenPages": false,
    "og": {
      "image": "/og-image.png"
    }
  }
}

Analytics

Track docs usage:
{
  "analytics": {
    "plausible": {
      "domain": "docs.yourname.dev"
    }
  }
}

Slack Integration

Notify Slack when docs are updated:
  1. GitHub Actions → Create workflow
  2. On push to docs/
  3. Call Slack webhook
  4. Message: “Docs updated! 📖“

Next Steps

  1. ✅ Create Mintlify account (2 min)
  2. ✅ Connect your GitHub org (1 min)
  3. ✅ Create mint.json (5 min)
  4. ✅ Write 3 core docs (15 min)
  5. ✅ Deploy (2 min)
  6. ✅ Custom domain (5 min)
Total: ~30 minutes to beautiful docs for all tools Your docs site is your portfolio. Make it count. 📚