Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .clineignore
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
.git/
222 changes: 0 additions & 222 deletions .github/workflows/release.yml

This file was deleted.

16 changes: 12 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,13 @@
pip install docbuddy
```

## Quick Start
Run the standalone page locally with the command:

```bash
docbuddy --port 9000
```

## Python Integration

```python
from fastapi import FastAPI
Expand Down Expand Up @@ -55,10 +61,12 @@ Enable tool calling in the settings to allow the assistant to make API requests

## Standalone Mode

DocBuddy has a standalone webpage (e.g. hosted on GitHub Pages) that connects to any OpenAPI schema and LLM provider. However, due to browser security restrictions (CORS), if you want to use local LLMs, you must run DocBuddy locally instead of from GitHub Pages.
1. Run `python3 -m http.server 8080` from the repo root
2. Visit in your browser [http://localhost:8080/docs/index.html](http://localhost:8080/docs/index.html)
If you prefer manual control, run DocBuddy from the repo root:

1. Run `python3 -m http.server 8080` from the repo root
2. Visit in your browser [http://localhost:8080/docs/index.html](http://localhost:8080/docs/index.html)

> **Note:** Due to browser security restrictions (CORS), if you want to use local LLMs (Ollama, LM Studio, vLLM), you must run DocBuddy locally instead of from the GitHub Pages hosted version.

## LLM Settings

Expand Down
18 changes: 15 additions & 3 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -435,15 +435,27 @@ <h3>Example APIs</h3>
</div>

<div class="install-section">
<h3>Python Plugin</h3>
<h3>🚀 Run Locally with CLI</h3>
<p>
Replace your FastAPI <code>/docs</code> page with DocBuddy — get AI chat, workflows,
and agent tools directly alongside your API explorer.
Launch this page locally in order to connect to local LLMs (Ollama, LM Studio, vLLM).
</p>
<div class="install-code" onclick="navigator.clipboard.writeText('pip install docbuddy').then(function(){var h=this.querySelector('.copy-hint');h.textContent='Copied!';setTimeout(function(){h.textContent='Click to copy'},1500)}.bind(this))">
<span>pip install docbuddy</span>
<span class="copy-hint">Click to copy</span>
</div>
<div class="install-code" onclick="navigator.clipboard.writeText('docbuddy').then(function(){var h=this.querySelector('.copy-hint');h.textContent='Copied!';setTimeout(function(){h.textContent='Click to copy'},1500)}.bind(this))">
<span>docbuddy</span>
<span class="copy-hint">Click to copy</span>
</div>
<p style="font-size: 12px; color: var(--theme-text-secondary); margin-top: 8px;">
Opens at the address shown in the terminal (default port <code>8008</code>)
</p>

<h3>Python Plugin</h3>
<p>
Replace your FastAPI <code>/docs</code> page with DocBuddy — get AI chat, workflows,
and agent tools directly alongside your API explorer.
</p>
<div class="code-snippet"><span class="kw">from</span> fastapi <span class="kw">import</span> FastAPI
<span class="kw">from</span> docbuddy <span class="kw">import</span> setup_docs

Expand Down
5 changes: 4 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ build-backend = "hatchling.build"

[project]
name = "docbuddy"
version = "0.5.0"
version = "0.6.0"
description = "Add an AI Assistant to your `/docs` page."
description-content-type = "text/markdown"
readme = "README.md"
Expand Down Expand Up @@ -49,6 +49,9 @@ Repository = "https://github.com/pearsonkyle/docbuddy"
[tool.hatch.build.targets.wheel]
packages = ["src/docbuddy"]

[project.scripts]
docbuddy = "docbuddy.cli:main"

[tool.pytest.ini_options]
testpaths = ["tests"]

Expand Down
78 changes: 78 additions & 0 deletions src/docbuddy/cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#!/usr/bin/env python3
"""CLI entry point for launching DocBuddy standalone webpage."""

import argparse
import functools
import http.server
import pathlib
import sys
import threading
import time
import webbrowser


def _pkg_dir() -> pathlib.Path:
"""Return the directory that contains standalone.html and static/."""
return pathlib.Path(__file__).parent


def main():
"""Launch DocBuddy standalone webpage on port 8008."""
parser = argparse.ArgumentParser(
prog="docbuddy",
Comment on lines +19 to +22
description="Launch the DocBuddy standalone AI-enhanced API documentation page.",
epilog="Example: docbuddy --host 127.0.0.1 --port 9000",
)
parser.add_argument(
"--host",
type=str,
default="localhost",
help="Host to bind the server to (default: localhost)",
)
parser.add_argument(
"--port",
"-p",
type=int,
default=8008,
help="Port to run the server on (default: 8008)",
)

args = parser.parse_args()

# Locate the package directory using __file__ – this is the most reliable
# way to find the installed package assets regardless of Python version,
# install method (editable, wheel, sdist), or platform.
pkg_dir = _pkg_dir()
standalone_path = pkg_dir / "standalone.html"

if not standalone_path.is_file():
print(
f"Error: Could not find 'standalone.html' in the docbuddy package ({pkg_dir})",
file=sys.stderr,
)
sys.exit(1)

# Serve only the package directory – not the whole repo/site-packages root.
handler = functools.partial(
http.server.SimpleHTTPRequestHandler, directory=str(pkg_dir)
)

url = f"http://{args.host}:{args.port}/standalone.html"

print(f"Serving DocBuddy at {url}")
print("Press Ctrl+C to stop the server")

with http.server.HTTPServer((args.host, args.port), handler) as httpd:

def open_browser():
time.sleep(0.5)
webbrowser.open(url)

thread = threading.Thread(target=open_browser, daemon=True)
thread.start()

try:
httpd.serve_forever()
except KeyboardInterrupt:
print("\nServer stopped.")
sys.exit(0)
Loading
Loading