DEV Community

Nexus Intelligence Research
Nexus Intelligence Research

Posted on

📚 Dev.to Article

Title: Instant AI Summaries for $29/month – How I Built It

Tags: python, fastapi, ai, data-analysis


TL;DR

I built a tiny FastAPI micro‑service that calls Groq’s LLM to turn any block of text into a concise summary. The service lives in a Docker container on my VPS‑2 (the same machine that hosts an Ollama server). I’m now selling it as a PRO plan – just $29 / month – via Stripe Checkout. Below you’ll find the full source, deployment steps, a ready‑to‑use Stripe link, and a quick YouTube‑short script to promote it.


1️⃣ The Problem

When you’re juggling research papers, crypto white‑papers, or geopolitical reports, you often need a quick read‑through. Copy‑pasting the whole thing into ChatGPT or another UI is clunky, especially if you’re working on a remote server without a GUI. I wanted a single‑line API that could be called from any script, notebook, or CI pipeline and return a clean, human‑readable summary in seconds.

2️⃣ Solution Overview

Component What it does
FastAPI Exposes a single POST /summarize endpoint that accepts raw text.
Groq LLM The heavy‑lifting LLM (e.g., mixtral-8x7b-32768) that generates the summary.
Docker Packs the service together with its dependencies, making deployment on VPS‑2 a breeze.
Stripe Checkout Handles subscription billing for the PRO tier ($29 / month).
YouTube Short A 60‑second promo video to drive traffic.

All the code lives in a single repository so you can clone, build, and run in under a minute.


3️⃣ FastAPI Service Code

# app/main.py
import os
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import httpx

app = FastAPI(title="Instant AI Summaries")

# -------------------------------------------------
#   Pydantic models
# -------------------------------------------------
class SummarizeRequest(BaseModel):
    text: str
    max_tokens: int = 150          # optional: limit summary length

class SummarizeResponse(BaseModel):
    summary: str
    model: str
    usage: dict

# -------------------------------------------------
#   Helper: call Groq LLM
# -------------------------------------------------
GROQ_API_KEY = os.getenv("GROQ_API_KEY")
GROQ_ENDPOINT = "https://api.groq.com/openai/v1/chat/completions"

def call_groq(prompt: str, max_tokens: int) -> dict:
    headers = {
        "Authorization": f"Bearer {GROQ_API_KEY}",
        "Content-Type": "application/json"
    }
    payload = {
        "model": "mixtral-8x7b-32768",   # change to your preferred model
        "messages": [{"role": "user", "content": prompt}],
        "max_tokens": max_tokens,
        "temperature": 0.2
    }
    resp = httpx.post(GROQ_ENDPOINT, json=payload, headers=headers, timeout=30)
    if resp.status_code != 200:
        raise HTTPException(status_code=502, detail="Groq API error")
    return resp.json()

# -------------------------------------------------
#   Endpoint
# -------------------------------------------------
@app.post("/summarize", response_model=SummarizeResponse)
async def summarize(req: SummarizeRequest):
    if not req.text.strip():
        raise HTTPException(status_code=400, detail="Text payload cannot be empty")

    prompt = (
        "Summarize the following text in a concise paragraph (max "
        f"{req.max_tokens} tokens). Preserve key facts and numbers.\n\n"
        f"{req.text}"
    )
    result = call_groq(prompt, req.max_tokens)

    # Groq follows the OpenAI schema
    summary = result["choices"][0]["message"]["content"].strip()
    usage = result.get("usage", {})
    model = result.get("model", "unknown")

    return SummarizeResponse(summary=summary, model=model, usage=usage)
Enter fullscreen mode Exit fullscreen mode

Key points

  • The service reads the GROQ_API_KEY from the environment – keep it secret!
  • max_tokens defaults to 150 but can be overridden per request.
  • Errors from Groq are turned into a 502 Bad Gateway so callers know it’s an upstream issue.

4️⃣ Dockerfile & Quick Deploy

# Dockerfile
FROM python:3.12-slim

# Install system deps (curl for health checks)
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*

# Create a non‑root user
RUN useradd -m appuser
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY app/ ./app
ENV PYTHONUNBUFFERED=1

# Expose the FastAPI port
EXPOSE 8000

# Run with uvicorn
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]
Enter fullscreen mode Exit fullscreen mode

requirements.txt

fastapi==0.112.0
uvicorn[standard]==0.30.1
httpx==0.27.0
pydantic==2.8.2
Enter fullscreen mode Exit fullscreen mode

Deploy Steps (run on VPS‑2)

# 1️⃣ Clone the repo
git clone https://github.com/yourname/instant-ai-summaries.git
cd instant-ai-summaries

# 2️⃣ Set your Groq API key (replace with your real key)
export GROQ_API_KEY="gsk_XXXXXXXXXXXXXXXXXXXXXXXX"

# 3️⃣ Build the image
docker build -t ai-summarizer .

# 4️⃣ Run the container (replace <YOUR_DOMAIN> with your DNS)
docker run -d \
  --name ai-summarizer \
  -p 8000:8000 \
  -e GROQ_API_KEY=$GROQ_API_KEY \
  ai-summarizer
Enter fullscreen mode Exit fullscreen mode

Your service is now reachable at http://<YOUR_DOMAIN>:8000/summarize.


5️⃣ Stripe Checkout – $29 / month PRO Plan

Below is a

Top comments (0)