fix: Copy confluence-collab package instead of symlink for Docker build

Symlinks dont resolve on remote VM during Docker build context.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Christian Gick
2026-02-24 11:38:39 +02:00
parent 3ea4d5abc8
commit b492abe0c9
10 changed files with 741 additions and 1 deletions

View File

@@ -0,0 +1,93 @@
"""Confluence REST API v1 client using httpx."""
from __future__ import annotations
import os
from dataclasses import dataclass
import httpx
@dataclass
class PageData:
"""Confluence page data."""
page_id: str
title: str
body_html: str
version: int
@dataclass
class Auth:
"""Confluence authentication credentials."""
base_url: str
username: str
api_token: str
@classmethod
def from_env(cls) -> Auth:
"""Load auth from environment variables."""
return cls(
base_url=os.environ.get("CONFLUENCE_URL", ""),
username=os.environ.get("CONFLUENCE_USERNAME", os.environ.get("CONFLUENCE_USER", "")),
api_token=os.environ.get("CONFLUENCE_API_TOKEN", ""),
)
@property
def httpx_auth(self) -> tuple[str, str]:
return (self.username, self.api_token)
async def get_page(page_id: str, auth: Auth) -> PageData:
"""Fetch a Confluence page with body.storage and version."""
url = f"{auth.base_url}/rest/api/content/{page_id}"
params = {"expand": "body.storage,version,title"}
async with httpx.AsyncClient(timeout=15.0) as client:
resp = await client.get(url, params=params, auth=auth.httpx_auth)
resp.raise_for_status()
data = resp.json()
return PageData(
page_id=str(data["id"]),
title=data["title"],
body_html=data["body"]["storage"]["value"],
version=data["version"]["number"],
)
async def put_page(
page_id: str,
title: str,
body_html: str,
version: int,
auth: Auth,
) -> PageData:
"""Update a Confluence page with version increment.
Raises httpx.HTTPStatusError on 409 (version conflict) or other errors.
"""
url = f"{auth.base_url}/rest/api/content/{page_id}"
payload = {
"version": {"number": version},
"title": title,
"type": "page",
"body": {
"storage": {
"value": body_html,
"representation": "storage",
}
},
}
async with httpx.AsyncClient(timeout=15.0) as client:
resp = await client.put(url, json=payload, auth=auth.httpx_auth)
resp.raise_for_status()
data = resp.json()
return PageData(
page_id=str(data["id"]),
title=data["title"],
body_html=data["body"]["storage"]["value"],
version=data["version"]["number"],
)