98 lines
2.6 KiB
Python
98 lines
2.6 KiB
Python
|
|
#!/usr/bin/env python3
|
||
|
|
"""
|
||
|
|
Small helper to demonstrate creating a BookStack page via the BookStack HTTP API.
|
||
|
|
|
||
|
|
Usage:
|
||
|
|
- Create a Personal Access Token in BookStack (User Settings → API Tokens).
|
||
|
|
- Add the token and app URL to your `.env` or export env vars:
|
||
|
|
BOOKSTACK_APP_URL=http://124.local:6875
|
||
|
|
BOOKSTACK_API_TOKEN=your_token_here
|
||
|
|
- Run: python bookstack_api_create_page.py
|
||
|
|
|
||
|
|
This script will list available books and create a page in the chosen book.
|
||
|
|
"""
|
||
|
|
import os
|
||
|
|
import sys
|
||
|
|
import json
|
||
|
|
import requests
|
||
|
|
from urllib.parse import urljoin
|
||
|
|
|
||
|
|
try:
|
||
|
|
from dotenv import load_dotenv
|
||
|
|
load_dotenv()
|
||
|
|
except Exception:
|
||
|
|
pass
|
||
|
|
|
||
|
|
|
||
|
|
BOOKSTACK_APP_URL = os.environ.get("BOOKSTACK_APP_URL")
|
||
|
|
BOOKSTACK_API_TOKEN = os.environ.get("BOOKSTACK_API_TOKEN")
|
||
|
|
|
||
|
|
if not BOOKSTACK_APP_URL or not BOOKSTACK_API_TOKEN:
|
||
|
|
print("Please set BOOKSTACK_APP_URL and BOOKSTACK_API_TOKEN in the environment or .env file.")
|
||
|
|
sys.exit(1)
|
||
|
|
|
||
|
|
|
||
|
|
def auth_headers():
|
||
|
|
# BookStack expects: Authorization: Token token="<token>"
|
||
|
|
return {
|
||
|
|
"Authorization": f'Token token="{BOOKSTACK_API_TOKEN}"',
|
||
|
|
"Content-Type": "application/json",
|
||
|
|
"Accept": "application/json",
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
def list_books():
|
||
|
|
url = urljoin(BOOKSTACK_APP_URL, "/api/books")
|
||
|
|
r = requests.get(url, headers=auth_headers(), timeout=10)
|
||
|
|
r.raise_for_status()
|
||
|
|
data = r.json()
|
||
|
|
return data.get("data", [])
|
||
|
|
|
||
|
|
|
||
|
|
def create_page(book_id: int, name: str, html: str):
|
||
|
|
url = urljoin(BOOKSTACK_APP_URL, "/api/pages")
|
||
|
|
payload = {
|
||
|
|
"name": name,
|
||
|
|
"book_id": book_id,
|
||
|
|
"html": html,
|
||
|
|
"markdown": None,
|
||
|
|
"draft": False,
|
||
|
|
}
|
||
|
|
r = requests.post(url, headers=auth_headers(), data=json.dumps(payload), timeout=10)
|
||
|
|
r.raise_for_status()
|
||
|
|
return r.json()
|
||
|
|
|
||
|
|
|
||
|
|
def main():
|
||
|
|
print(f"Using BookStack: {BOOKSTACK_APP_URL}")
|
||
|
|
books = list_books()
|
||
|
|
if not books:
|
||
|
|
print("No books found. Create a book in BookStack first or verify token permissions.")
|
||
|
|
return
|
||
|
|
|
||
|
|
print("Available books:")
|
||
|
|
for i, b in enumerate(books):
|
||
|
|
print(f" [{i}] {b.get('name')} (id={b.get('id')})")
|
||
|
|
|
||
|
|
choice = input("Choose a book index to create the page in (default 0): ") or "0"
|
||
|
|
try:
|
||
|
|
idx = int(choice)
|
||
|
|
except ValueError:
|
||
|
|
idx = 0
|
||
|
|
|
||
|
|
book = books[idx]
|
||
|
|
book_id = book.get("id")
|
||
|
|
|
||
|
|
title = input("Page title: ") or "Automated Page"
|
||
|
|
content = input("Simple HTML content (or leave empty for a sample): ")
|
||
|
|
if not content:
|
||
|
|
content = f"<h2>{title}</h2><p>Created automatically via API.</p>"
|
||
|
|
|
||
|
|
resp = create_page(book_id, title, content)
|
||
|
|
print("Created page:")
|
||
|
|
print(json.dumps(resp, indent=2))
|
||
|
|
|
||
|
|
|
||
|
|
if __name__ == "__main__":
|
||
|
|
main()
|