Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
33 changes: 0 additions & 33 deletions .devcontainer/devcontainer.json

This file was deleted.

10 changes: 0 additions & 10 deletions .devcontainer/postCreateCommand.sh

This file was deleted.

13 changes: 8 additions & 5 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
LLM_API="http://localhost:9000/v1"
WHISPER_API="http://localhost:50001/v1"
API_KEY="your api token here"
LLM_API_PORT=8001
LLM_BASE_URL=http://localhost:${LLM_API_PORT}/v1
API_KEY='none'
WHISPER_URL="http://localhost:50001/v1"
LLM_MODEL='Qwen/Qwen3-32B-AWQ'
HMAC_SECRET="YOUR HMAC SECRET" # Used to pseudonymize user id. Create with openssl rand 32 | base64
HF_AUTH_TOKEN=""
CLIENT_PORT=3000
CLIENT_URL=http://localhost:${CLIENT_PORT}
PORT=""
LLM_HEALTH_CHECK="http://localhost:9000/health"
WHISPER_HEALTH_CHECK="http://localhost:50001/healthz"
IS_PROD=False
13 changes: 2 additions & 11 deletions .github/workflows/docker-publish.yml
Original file line number Diff line number Diff line change
@@ -1,26 +1,17 @@
name: Build and Publish Docker Image
on:
workflow_dispatch:
inputs:
version_bump:
description: Version bump type
required: true
default: patch
type: choice
options: [major, minor, patch]

permissions:
contents: write
contents: read
packages: write

jobs:
publish:
uses: DCC-BS/ci-workflows/.github/workflows/publish-docker.yml@v4
uses: DCC-BS/ci-workflows/.github/workflows/publish-docker.yml@v7
secrets: inherit
with:
release_type: ${{ inputs.version_bump }} # major|minor|patch
version_project_type: "python" # or "node"
version_uv_version: "0.9.14"
registry: ghcr.io
image_name: ghcr.io/${{ github.repository }}
context: .
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ on:

jobs:
backend-ci:
uses: DCC-BS/ci-workflows/.github/workflows/python-backend-ci.yml@v4
uses: DCC-BS/ci-workflows/.github/workflows/python-backend-ci.yml@v7
with:
python_versions: '["3.10","3.11","3.12","3.13"]'
quality_python_version: "3.12"
Expand Down
6 changes: 3 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Stage 1: Builder
FROM python:3.14-alpine AS builder
COPY --from=ghcr.io/astral-sh/uv:0.9.14 /uv /uvx /bin/
FROM python:3.13-alpine AS builder
COPY --from=ghcr.io/astral-sh/uv:0.9.25 /uv /uvx /bin/

ENV UV_COMPILE_BYTECODE=1
ENV UV_LINK_MODE=copy
Expand Down Expand Up @@ -28,7 +28,7 @@ RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --locked --no-dev

# Stage 2: Runtime
FROM python:3.14-alpine
FROM python:3.13-alpine

ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
Expand Down
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ check: ## Run code quality tools.
@uv lock --locked
@echo "🚀 Linting code: Running pre-commit"
@uv run pre-commit run -a
@echo "🚀 Static type checking: Running pyrefly"
@uv run pyrefly check ./src/transcribo_backend
@echo "🚀 Static type checking: Running ty"
@uv run ty check

.PHONY: test
test: ## Test the code with pytest
Expand All @@ -36,7 +36,7 @@ run: ## Run the application
.PHONY: dev
dev: ## Run the application in development mode
@echo "🚀 Running the application in development mode"
@uv run fastapi dev ./src/transcribo_backend/app.py --port 8000
@uv run --env-file .env fastapi dev ./src/transcribo_backend/app.py --port 8000

.PHONY: build
build: clean-build ## Build wheel file
Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# TODO
returns library
api error from backend common


# Transcribo Backend

[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
Expand Down
23 changes: 9 additions & 14 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
name = "transcribo-backend"
version = "0.5.8"
description = "The backend of the transcribo app"
authors = [{name = "Data Competence Center Basel-Stadt", email = "dcc@bs.ch" },{ name = "Tobias Bollinger", email = "tobias.bollinger@gmail.com" }]
authors = [{name = "Data Competence Center Basel-Stadt", email = "dcc@bs.ch" },{ name = "Tobias Bollinger", email = "tobias.bollinger@bs.ch" }, { name = "Yanick Schraner", email = "yanick.schraner@bs.ch" }]
readme = "README.md"
keywords = ['python']
requires-python = ">=3.12,<4.0"
requires-python = ">=3.12,<3.14"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Locate Python version pins in CI/Docker/config files.
rg -nP --hidden -g '!**/.git/**' -g '!**/.venv/**' -g '!**/dist/**' -g '!**/build/**' -g '!**/node_modules/**' \
  'python-version|PYTHON_VERSION|python:3\.\d+'

Repository: DCC-BS/transcribo-backend

Length of output: 251


🏁 Script executed:

#!/bin/bash
# Check GitHub Actions workflows
find .github/workflows -type f -name '*.yml' -o -name '*.yaml' 2>/dev/null | head -20

# Read tox.ini to see Python version matrix
echo "=== tox.ini content ==="
cat tox.ini 2>/dev/null

# Check renovate.json for Python settings
echo "=== renovate.json relevant sections ==="
jq '.python // .dockerfile // empty' renovate.json 2>/dev/null || cat renovate.json 2>/dev/null | head -100

Repository: DCC-BS/transcribo-backend

Length of output: 574


🏁 Script executed:

#!/bin/bash
# Check main.yml for test matrix
echo "=== .github/workflows/main.yml ==="
cat .github/workflows/main.yml

echo ""
echo "=== .github/workflows/docker-publish.yml ==="
cat .github/workflows/docker-publish.yml

Repository: DCC-BS/transcribo-backend

Length of output: 921


Update tox.ini and CI matrix to exclude Python 3.10–3.11.

Docker is correctly pinned to python:3.13-alpine, but the CI matrix in .github/workflows/main.yml and tox.ini still test Python 3.10 and 3.11, which violate the requires-python = ">=3.12,<3.14" constraint. Remove py310 and py311 from tox.ini envlist and update the CI workflow's python_versions to '["3.12","3.13"]'.

🤖 Prompt for AI Agents
In `@pyproject.toml` at line 8, The CI and tox configs currently test Python
3.10–3.11 which conflicts with pyproject's requires-python=">=3.12,<3.14";
update the tox envlist by removing the py310 and py311 entries from tox.ini (the
envlist variable) and update the GitHub Actions workflow's python_versions key
in .github/workflows/main.yml to '["3.12","3.13"]' so the matrix matches the
package Python range.

license = "MIT"
license-files = ["LICEN[CS]E*"]
classifiers = [
Expand All @@ -19,11 +19,13 @@ classifiers = [
"Topic :: Software Development :: Libraries :: Python Modules",
]
dependencies = [
"aiohttp>=3.11.13",
"fastapi[standard]>=0.123.5",
"structlog>=25.1.0",
"audioop-lts; python_version >= '3.13'",
"openai>=1.97.1",
"cachetools>=6.2.4",
"dcc-backend-common[fastapi]>=0.0.2",
"dependency-injector>=4.48.3",
"fastapi[standard]>=0.128.0",
"pydantic-ai>=1.43.0",
"returns>=0.26.0",
]

[project.urls]
Expand All @@ -38,14 +40,12 @@ dev = [
"pre-commit>=2.20.0",
"tox-uv>=1.11.3",
"deptry>=0.22.0",
"basedpyright>=1.27.1",
"pytest-cov>=6.0.0",
"ruff>=0.9.2",
"mkdocs>=1.4.2",
"mkdocs-material>=8.5.10",
"mkdocstrings[python]>=0.26.1",
"mypy>=1.15.0",
"pyrefly>=0.43.1",
"ty>=0.0.12",
]

[build-system]
Expand Down Expand Up @@ -100,11 +100,6 @@ ignore = [
"E731",
]

[tool.pyrefly]
project-includes = [
"src/**.py*",
]

[tool.ruff.lint.per-file-ignores]
"tests/*" = ["S101"]

Expand Down
10 changes: 0 additions & 10 deletions pyrefly.toml

This file was deleted.

41 changes: 28 additions & 13 deletions run.sh
Original file line number Diff line number Diff line change
@@ -1,43 +1,52 @@
#!/bin/sh
set -e

if [ -f .env ]; then
# Load environment variables from .env file
. .env
fi

# Ensure PORT has a value (in case .env sets it to empty)
PORT="${PORT:-8000}"
# Default values (allow env overrides)
DEV_MODE=${DEV_MODE:-false}
PORT=${PORT:-8000}

# Function to display help information
show_help() {
echo "Usage: $0 [options]"
echo ""
echo "Options:"
echo " --dev Run in development mode using 'fastapi dev'"
echo " --port NUMBER Specify the port number (default: 8000)"
echo " --help Display this help message"
echo ""
echo "Examples:"
echo " $0 # Run in production mode on port 8000"
echo " $0 --dev # Run in development mode on port 8000"
echo " $0 --port 9000 # Run in production mode on port 9000"
echo " $0 --dev --port 5000 # Run in development mode on port 5000"
echo ""
}

# Parse command line arguments
while [ "$#" -gt 0 ]; do
case $1 in
case "$1" in
--dev) DEV_MODE=true; shift ;;
--port)
if [ -z "$2" ] || echo "$2" | grep -q "^-"; then
if [ -z "${2:-}" ]; then
echo "Error: --port requires a numeric argument"
show_help
exit 1
fi
if ! echo "$2" | grep -Eq "^[0-9]+$"; then
case "$2" in
''|*[!0-9]*)
echo "Error: port must be a valid number"
show_help
exit 1
;;
esac
if [ "$2" -lt 1 ] || [ "$2" -gt 65535 ]; then
echo "Error: port must be a valid number"
show_help
exit 1
fi
PORT="$2"; shift 2 ;;
PORT="$2"
shift 2
;;
--help)
show_help
exit 0
Expand All @@ -50,5 +59,11 @@ while [ "$#" -gt 0 ]; do
esac
done

echo "Starting in production mode on port $PORT"
fastapi run ./src/transcribo_backend/app.py --port "$PORT"
# Choose command based on dev mode
if [ "$DEV_MODE" = true ]; then
echo "Starting in development mode on port $PORT"
fastapi dev ./src/transcribo_backend/app.py --port "$PORT"
else
echo "Starting in production mode on port $PORT"
fastapi run ./src/transcribo_backend/app.py --port "$PORT"
fi
Empty file.
34 changes: 34 additions & 0 deletions src/transcribo_backend/agents/summarize_agent.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from openai import AsyncOpenAI
from pydantic_ai import Agent, TextOutput
from pydantic_ai.models.openai import OpenAIChatModel
from pydantic_ai.providers.openai import OpenAIProvider

from transcribo_backend.utils.app_config import AppConfig


def transform_to_swissgerman_style(text: str) -> str:
return text.replace("ß", "ss")


def create_summarize_agent(app_config: AppConfig) -> Agent:
client = AsyncOpenAI(max_retries=3, base_url=app_config.llm_base_url, api_key=app_config.api_key)
model = OpenAIChatModel(model_name=app_config.llm_model, provider=OpenAIProvider(openai_client=client))
summarize_agent: Agent = Agent(
model=model,
output_type=TextOutput(transform_to_swissgerman_style),
)

@summarize_agent.instructions
def get_instructions() -> str:
return """
You are a meeting summary expert.
You are given a transcript of a meeting and you need to summarize it.
You need to summarize the meeting in a way that is easy to understand and use.
You need to include the main points of the meeting, the decisions made, and the action items.
You need to include the names of the participants.
You use markdown to format the summary.
Use the same language as used in the transcript to summarize the meeting.
If you are not sure about the language, use German.
"""

return summarize_agent
Loading