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

# Blog Generation Script

> Open source 6-pass AI pipeline that generates, humanises, and publishes blog content using Claude.

`generate_blogs.py` is an open source Python script that automates blog content creation end-to-end. It uses a multi-pass pipeline powered by Claude to generate high-quality, humanised blog posts and publish them to your Supabase database.

<Info>
  This script is open source. You can adapt it for your own content pipeline — replace the Supabase publishing step with your CMS of choice.
</Info>

## What it does

The pipeline runs in 6 passes, each building on the last:

| Pass  | What happens                                                                  |
| ----- | ----------------------------------------------------------------------------- |
| **0** | Fetch existing blog titles from Supabase (auto-runs before Pass 1)            |
| **1** | Identify topics — avoids duplicating existing posts                           |
| **2** | Plan blog structure per topic (comparison / technical / case-study / how-to)  |
| **3** | Generate full content for each blog                                           |
| **4** | Humanise — strip AI tells, vary sentence length, add real-world examples      |
| **5** | Add internal links across the batch and reference relevant product pages      |
| **6** | Push to Supabase DB with metadata (cover image, tags, SEO keywords, platform) |

Each pass caches its output to local JSON files (`_topics.json`, `_plans.json`, `_registry.json`) so you can resume from any pass if something fails.

## Requirements

* Python 3.9+
* An Anthropic API key (Claude)
* A Supabase project with a `blogs` table (for publishing)

Install dependencies:

```bash theme={null}
pip install anthropic
```

No other dependencies — the script uses only stdlib (`json`, `os`, `argparse`, `pathlib`, `urllib`) plus the `anthropic` package.

## Setup

Clone or install from the [nometria/blog-pipeline](https://github.com/nometria/blog-pipeline) repository:

```bash theme={null}
pip install blog-pipeline
```

Or clone the source:

```bash theme={null}
git clone https://github.com/nometria/blog-pipeline
cd blog-pipeline
pip install -e .
```

<Info>
  Also available on PyPI: [blog-pipeline](https://pypi.org/project/blog-pipeline/)
</Info>

Set environment variables:

```bash theme={null}
export ANTHROPIC_API_KEY=sk-ant-...

# Optional — defaults to Nometria's Supabase instance if not set
export SUPABASE_URL=https://xxxxxxxxxxxx.supabase.co
export SUPABASE_SERVICE_KEY=eyJ...
```

## Usage

```bash theme={null}
# Run all 6 passes (full pipeline)
python3 generate_blogs.py

# Run specific passes
python3 generate_blogs.py --passes 1-3    # Topics + planning + generation only
python3 generate_blogs.py --passes 4-6    # Humanise + link + publish only
python3 generate_blogs.py --passes 6      # Publish only (from cached content)

# Limit how many blogs to generate in this run
python3 generate_blogs.py --count 5

# Combine options
python3 generate_blogs.py --passes 1-3 --count 10
```

## Output

**Local files (in `blogs/` directory):**

* `_topics.json` — topic list with metadata
* `_plans.json` — structure plans per topic
* `_registry.json` — tracking which blogs exist locally vs in DB
* `<slug>.md` — one markdown file per generated blog

**Published to Supabase:**

Each blog is inserted into the `blogs` table with:

```json theme={null}
{
  "slug": "my-blog-post-title",
  "title": "My Blog Post Title",
  "content": "## Introduction\n\n...",
  "cover_image": "https://images.unsplash.com/photo-...",
  "tags": ["Tutorial", "Base44"],
  "seo_keywords": ["keyword 1", "keyword 2"],
  "platform": "base44",
  "author": "Nometria Team",
  "published": true,
  "created_at": "2025-01-01T00:00:00Z"
}
```

## Blog types

The pipeline generates three blog formats:

| Type                  | Description                                           | Example use                                           |
| --------------------- | ----------------------------------------------------- | ----------------------------------------------------- |
| `comparison`          | A vs B — compares two tools, platforms, or approaches | "Base44 vs Lovable: Which is better for..."           |
| `technical-deep-dive` | In-depth tutorial or explanation                      | "How two-way GitHub sync works under the hood"        |
| `case-study`          | Real-world scenario with outcomes                     | "How we deployed 50 no-code apps to AWS in a weekend" |
| `how-to`              | Step-by-step guide                                    | "How to add Stripe payments to your Lovable app"      |

Type is determined by Claude in Pass 2 based on topic suitability.

## Customising for your project

**Change the niche/focus:**

Edit the system prompt in `generate_blogs.py` around the `CATEGORY_MAP` and topic generation sections. Replace references to Nometria and vibe coding with your own product and subject matter.

**Change the publishing destination:**

Replace the `push_to_supabase()` function with your own CMS integration. The function receives a dict with `slug`, `title`, `content`, `tags`, `cover_image`, etc.

**Adjust the cover image pool:**

The `_COVER_POOL` dict maps blog categories to curated Unsplash photo IDs. Add or remove photo IDs to change the visual style of generated posts.

## Supabase table schema

If you want to use the built-in Supabase publishing:

```sql theme={null}
create table blogs (
  id uuid primary key default gen_random_uuid(),
  slug text unique not null,
  title text not null,
  content text not null,
  cover_image text,
  tags text[],
  seo_keywords text[],
  platform text,
  author text default 'Nometria Team',
  author_title text,
  author_image text,
  published boolean default true,
  created_at timestamptz default now()
);
```

## Example run output

```
Pass 0: Fetching existing blogs from Supabase...
  Found 47 existing blogs.

Pass 1: Identifying topics...
  Skipping 47 existing topics.
  Generated 8 new topics.

Pass 2: Planning blog structure...
  [1/8] "How to migrate from Firebase to Supabase" → how-to
  [2/8] "Lovable vs Bolt: which is faster for..." → comparison
  ...

Pass 3: Generating content...
  [1/8] Writing "How to migrate from Firebase to Supabase"... done (2,847 words)
  ...

Pass 4: Humanising...
  [1/8] Humanising... done

Pass 5: Adding internal links...
  Added 12 internal links across 8 blogs.

Pass 6: Publishing to Supabase...
  [1/8] Pushed "how-to-migrate-from-firebase-to-supabase" ✓
  ...
  Done. 8 blogs published.
```
