-
Notifications
You must be signed in to change notification settings - Fork 1
OpenAI wrapper service review #18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 2 commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
85c88a7
Add OpenAI wrapper service
lakshay6666 4df300c
Add OpenAI wrapper CI workflow
lakshay6666 80d0995
Remove stdin shortcut from OpenAI wrapper CLI
lakshay6666 e957a92
Scope OpenAI wrapper to responses API
lakshay6666 767f52c
refactor(openai-wrapper): organize service package layout
lakshay6666 71bcdd4
fix(openai-wrapper): mirror health endpoint in CLI
lakshay6666 383b566
fix(openai-wrapper): address review feedback
lakshay6666 5802b6d
test(openai-wrapper): drop redundant openapi smoke test
lakshay6666 167c3fb
fix(openai-wrapper): make docker port configurable
lakshay6666 31a45ee
feat(openai-wrapper): expose client provider settings
lakshay6666 13c2797
fix: exclude .kilo from being version controlled
plc-dev 7a63a94
feat: AI-rewrite for LLM-Gateway service
plc-dev File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,107 @@ | ||
| name: openai-wrapper-service | ||
|
|
||
| on: | ||
| push: | ||
| branches: ["master"] | ||
| paths: | ||
| - "services/openai-wrapper-service/**" | ||
| - ".github/workflows/service-openai-wrapper-service.yml" | ||
| pull_request: | ||
| branches: ["master"] | ||
| paths: | ||
| - "services/openai-wrapper-service/**" | ||
| - ".github/workflows/service-openai-wrapper-service.yml" | ||
|
|
||
| defaults: | ||
| run: | ||
| working-directory: services/openai-wrapper-service | ||
|
|
||
| jobs: | ||
| lint: | ||
| name: Lint | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - uses: actions/setup-python@v5 | ||
| with: | ||
| python-version: "3.12" | ||
| - uses: astral-sh/setup-uv@v5 | ||
| - name: Install dependencies | ||
| run: uv sync | ||
| - name: Lint | ||
| run: make lint | ||
|
|
||
| test: | ||
| name: Test | ||
| runs-on: ubuntu-latest | ||
| needs: lint | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - uses: actions/setup-python@v5 | ||
| with: | ||
| python-version: "3.12" | ||
| - uses: astral-sh/setup-uv@v5 | ||
| - name: Install dependencies | ||
| run: uv sync | ||
| - name: Run tests | ||
| run: make test | ||
| - name: Upload coverage to Codecov | ||
| uses: codecov/codecov-action@v4 | ||
| with: | ||
| files: services/openai-wrapper-service/coverage.xml | ||
| flags: openai-wrapper-service | ||
| token: ${{ secrets.CODECOV_TOKEN }} | ||
| fail_ci_if_error: false | ||
| if: always() | ||
|
|
||
| generate-openapi: | ||
| name: Generate OpenAPI Spec | ||
| runs-on: ubuntu-latest | ||
| needs: test | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - uses: actions/setup-python@v5 | ||
| with: | ||
| python-version: "3.12" | ||
| - uses: astral-sh/setup-uv@v5 | ||
| - name: Install dependencies | ||
| run: uv sync | ||
| - name: Generate OpenAPI spec | ||
| run: make generate-openapi | ||
| - name: Upload OpenAPI spec | ||
| uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: openapi-spec-openai-wrapper-service | ||
| path: services/openai-wrapper-service/openai-wrapper-service.openapi.json | ||
|
|
||
| build: | ||
| name: Build & Push Docker Image | ||
| runs-on: ubuntu-latest | ||
| needs: generate-openapi | ||
| if: github.event_name == 'push' && github.ref == 'refs/heads/master' | ||
| permissions: | ||
| contents: read | ||
| packages: write | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - name: Log in to GitHub Container Registry | ||
| uses: docker/login-action@v3 | ||
| with: | ||
| registry: ghcr.io | ||
| username: ${{ github.actor }} | ||
| password: ${{ secrets.GITHUB_TOKEN }} | ||
| - name: Extract Docker metadata | ||
| id: meta | ||
| uses: docker/metadata-action@v5 | ||
| with: | ||
| images: ghcr.io/${{ github.repository_owner }}/openai-wrapper-service | ||
| tags: | | ||
| type=sha,prefix=sha- | ||
| type=raw,value=latest | ||
| - name: Build and push Docker image | ||
| uses: docker/build-push-action@v6 | ||
| with: | ||
| context: services/openai-wrapper-service | ||
| push: true | ||
| tags: ${{ steps.meta.outputs.tags }} | ||
| labels: ${{ steps.meta.outputs.labels }} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| .venv | ||
| .uv-cache | ||
| __pycache__ | ||
| .pytest_cache | ||
| .ruff_cache | ||
| .coverage | ||
| coverage.xml | ||
| htmlcov | ||
| .git | ||
| .DS_Store |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| .venv/ | ||
| .uv-cache/ | ||
| __pycache__/ | ||
| .pytest_cache/ | ||
| .ruff_cache/ | ||
| .coverage | ||
| coverage.xml | ||
| htmlcov/ | ||
| openai-wrapper-service.openapi.json |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| 3.12 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| FROM python:3.12-slim-trixie | ||
|
|
||
| RUN apt-get update && apt-get install -y --no-install-recommends curl ca-certificates \ | ||
| && rm -rf /var/lib/apt/lists/* | ||
|
|
||
| ADD https://astral.sh/uv/install.sh /uv-installer.sh | ||
| RUN sh /uv-installer.sh && rm /uv-installer.sh | ||
|
|
||
| ENV PATH="/root/.local/bin/:$PATH" | ||
|
|
||
| COPY . /app | ||
| WORKDIR /app | ||
| RUN uv sync --locked --no-dev | ||
|
|
||
| EXPOSE 8002 | ||
|
|
||
| CMD ["uv", "run", "--no-sync", "uvicorn", "api:app", "--host", "0.0.0.0", "--port", "8002", "--app-dir", "src"] | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| IMAGE_NAME := openai-wrapper-service | ||
| OPENAPI_OUT := openai-wrapper-service.openapi.json | ||
| PORT ?= 8002 | ||
|
|
||
| .PHONY: prep build test lint start clean docker-build generate-openapi | ||
|
|
||
| prep: | ||
| uv sync | ||
|
|
||
| build: | ||
| @echo "No build step required for Python" | ||
|
|
||
| test: | ||
| uv run pytest --cov=src --cov-report=xml --cov-report=term-missing | ||
|
|
||
| lint: | ||
| uv run ruff check src/ test/ | ||
| uv run ruff format --check src/ test/ | ||
|
|
||
| start: | ||
| uv run uvicorn api:app --reload --port $(PORT) --app-dir src | ||
|
|
||
| clean: | ||
| rm -rf .coverage coverage.xml htmlcov/ .pytest_cache $(OPENAPI_OUT) | ||
| find . -type d -name __pycache__ -exec rm -rf {} + | ||
|
|
||
| docker-build: | ||
| docker build -t $(IMAGE_NAME) . | ||
|
|
||
| generate-openapi: | ||
| uv run python src/generate_openapi.py |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,120 @@ | ||
| # OpenAI Wrapper Service | ||
|
|
||
| HTTP and CLI wrapper around the official OpenAI API for services that need text generation or embeddings. | ||
|
|
||
| The service uses the OpenAI Python SDK through the adapter in `src/openai_wrapper_service/client.py`. | ||
|
|
||
| - Text generation through the OpenAI Responses API | ||
| - Embeddings through the OpenAI Embeddings API | ||
| - A CLI that mirrors the REST behavior | ||
| - A generated OpenAPI specification | ||
|
|
||
| ## Configuration | ||
|
|
||
| Set an OpenAI API key before using the API or CLI: | ||
|
|
||
| ```sh | ||
| export OPENAI_API_KEY=... | ||
| ``` | ||
|
|
||
| Optional environment variables: | ||
|
|
||
| | Variable | Default | Description | | ||
| | --- | --- | --- | | ||
| | `OPENAI_WRAPPER_DEFAULT_RESPONSE_MODEL` | `gpt-5.2` | Default model for `/generate` | | ||
| | `OPENAI_WRAPPER_DEFAULT_EMBEDDING_MODEL` | `text-embedding-3-small` | Default model for `/embeddings` | | ||
| | `OPENAI_WRAPPER_TIMEOUT_SECONDS` | `60` | OpenAI SDK request timeout | | ||
|
|
||
| ## API | ||
|
|
||
| Start the service: | ||
|
|
||
| ```sh | ||
| make start | ||
| ``` | ||
|
|
||
| The API listens on port `8002` by default. | ||
|
|
||
| OpenAPI docs: | ||
|
|
||
| ```text | ||
| http://localhost:8002/docs | ||
| ``` | ||
|
|
||
| Endpoints: | ||
|
|
||
| | Method | Path | Description | | ||
| | --- | --- | --- | | ||
| | `GET` | `/health` | Liveness probe | | ||
| | `POST` | `/generate` | Generate text through the OpenAI Responses API | | ||
| | `POST` | `/embeddings` | Create embeddings through the OpenAI Embeddings API | | ||
|
|
||
| Example generation request: | ||
|
|
||
| ```json | ||
| { | ||
| "input": "Summarize the purpose of ALADIN in one sentence.", | ||
| "instructions": "Answer concisely.", | ||
| "max_output_tokens": 120 | ||
| } | ||
| ``` | ||
|
|
||
| Example embeddings request: | ||
|
|
||
| ```json | ||
| { | ||
| "input": ["fermentation simulation", "graph rewriting"], | ||
| "model": "text-embedding-3-small" | ||
| } | ||
| ``` | ||
|
|
||
| ## CLI | ||
|
|
||
| The CLI mirrors the API: | ||
|
|
||
| ```sh | ||
| uv run openai-wrapper generate "Write a short explanation of graph rewriting." | ||
| uv run openai-wrapper generate "Write a short explanation of graph rewriting." --text-only | ||
| uv run openai-wrapper embeddings "fermentation simulation" "graph rewriting" | ||
| ``` | ||
|
|
||
| Use `-` to read generation input from stdin: | ||
|
|
||
| ```sh | ||
| printf "Explain embeddings" | uv run openai-wrapper generate - --text-only | ||
| ``` | ||
|
|
||
| ## Docker | ||
|
|
||
| Build: | ||
|
|
||
| ```sh | ||
| make docker-build | ||
| ``` | ||
|
|
||
| Run: | ||
|
|
||
| ```sh | ||
| docker run --rm -p 8002:8002 -e OPENAI_API_KEY openai-wrapper-service | ||
| ``` | ||
|
|
||
| ## Hardware Requirements | ||
|
|
||
| Minimal requirements for the wrapper itself: | ||
|
|
||
| | Resource | Requirement | | ||
| | --- | --- | | ||
| | CPU | 1 vCPU | | ||
| | Memory | 256 MB RAM | | ||
| | Disk | < 200 MB image/runtime overhead, excluding Docker base layers | | ||
|
|
||
| Generation and embedding latency, availability, and cost are governed by OpenAI API calls rather than local compute. Deployments should enforce request-size and rate limits appropriate for their API budget. | ||
|
|
||
| ## Development | ||
|
|
||
| ```sh | ||
| make prep | ||
| make lint | ||
| make test | ||
| make generate-openapi | ||
| ``` |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.