Skip to content
This repository has been archived by the owner on Jul 18, 2024. It is now read-only.

Commit

Permalink
Merge pull request #7 from defenseunicorns/create-lfai-api-zarf-package
Browse files Browse the repository at this point in the history
Create LFAI-api Zarf package
  • Loading branch information
YrrepNoj authored Oct 31, 2023
2 parents 4f50951 + 40d57ec commit 1a12472
Show file tree
Hide file tree
Showing 22 changed files with 409 additions and 42 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/environment.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: Run tests
on: [push, pull_request]
on: [pull_request]

jobs:
Run-Tests:
Expand Down
40 changes: 40 additions & 0 deletions .github/workflows/publish-zarf-package.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: Publish Artifacts

on:
push:
tags:
- "*"

jobs:
zarf:
runs-on: ubuntu-latest

steps:
- name: Check out code
uses: actions/checkout@v2

- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Login to Registry1
uses: docker/login-action@v3
with:
registry: registry1.dso.mil
username: ${{ secrets.REGISTRY1_USERNAME }}
password: ${{ secrets.REGISTRY1_PASSWORD }}

- name: Build API Image
run: make docker-build docker-push VERSION=$GITHUB_REF_NAME

- name: Install Zarf
uses: defenseunicorns/setup-zarf@main

- name: Build Zarf Package
run: zarf package create . --confirm

- name: Publish Zarf Package
run: zarf package publish zarf-package-*.zst oci://ghcr.io/defenseunicorns/packages
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@
leapfrogai_api.egg-info
__pycache__
.vscode
config.yaml
config.yaml
*.tar.zst
.python-version
12 changes: 6 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
VERSION := $(shell git describe --abbrev=0 --tags)
VERSION ?= $(shell git describe --abbrev=0 --tags)

create-venv:
python -m venv .venv
Expand All @@ -16,16 +16,16 @@ build-requirements:
pip-compile -o requirements.txt pyproject.toml

build-requirements-dev:
pip-compile --extra dev -o requirements-dev.txt pyproject.toml
pip-compile --extra dev -o requirements-dev.txt pyproject.toml --allow-unsafe

test:
pytest **/*.py

dev:
uvicorn main:app --port 3000 --reload

make docker-build:
docker build -t ghcr.io/defenseunicorns/leapfrogai-api:${VERSION} .
docker-build:
docker build -t ghcr.io/defenseunicorns/leapfrogai/leapfrogai-api:${VERSION} .

make docker-push:
docker push ghcr.io/defenseunicorns/leapfrogai-api:${VERSION}
docker-push:
docker push ghcr.io/defenseunicorns/leapfrogai/leapfrogai-api:${VERSION}
7 changes: 4 additions & 3 deletions backends/openai/grpc_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,16 @@ async def stream_completion(model: Model, request: leapfrogai.CompletionRequest)
async def completion(model: Model, request: leapfrogai.CompletionRequest):
async with grpc.aio.insecure_channel(model.backend) as channel:
stub = leapfrogai.CompletionServiceStub(channel)
response: leapfrogai.CompletionResponse = stub.Complete(request)
response: leapfrogai.CompletionResponse = await stub.Complete(request)

return CompletionResponse(
model=model.name,
choices=[
CompletionChoice(
index=0,
text=response.choices[0].text,
finish_reason=response.choices[0].finish_reason,
finish_reason=str(response.choices[0].finish_reason),
logprobs=None,
)
],
)
Expand All @@ -63,7 +64,7 @@ async def stream_chat_completion(
async def chat_completion(model: Model, request: leapfrogai.ChatCompletionRequest):
async with grpc.aio.insecure_channel(model.backend) as channel:
stub = leapfrogai.CompletionServiceStub(channel)
response: leapfrogai.ChatCompletionResponse = stub.Complete(request)
response: leapfrogai.ChatCompletionResponse = await stub.Complete(request)

return ChatCompletionResponse(
model=model.name,
Expand Down
6 changes: 3 additions & 3 deletions backends/openai/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ class CompletionRequest(BaseModel):
class CompletionChoice(BaseModel):
index: int
text: str
logprobs: object | None
finish_reason: str
logprobs: object = None
finish_reason: str = ""


class CompletionResponse(BaseModel):
Expand All @@ -37,7 +37,7 @@ class CompletionResponse(BaseModel):
created: int = 0
model: str = ""
choices: list[CompletionChoice]
usage: Usage
usage: Usage = None


##########
Expand Down
24 changes: 24 additions & 0 deletions chart/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
apiVersion: v2
name: leapfrogai
description: A deployment of AI tools

# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application

# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.4.0

# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "1.16.0"
68 changes: 68 additions & 0 deletions chart/templates/api/deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-deployment
spec:
replicas: {{ .Values.api.replcias }}
strategy:
type: Recreate
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
spec:
serviceAccountName: read-configmaps
containers:
- name: sidecar
image: registry1.dso.mil/ironbank/kiwigrid/k8s-sidecar:{{ .Values.image.kiwigridTag }}
volumeMounts:
- name: api-model
mountPath: /config/
env:
- name: LABEL
value: "leapfrogai"
- name: FOLDER
value: /config/
- name: RESOURCE
value: both
- name: UNIQUE_FILENAMES
value: "true"
- name: NAMESPACE
value: leapfrogai
- name: api-container
image: ghcr.io/defenseunicorns/leapfrogai-api:{{ .Values.image.lfaiAPITag }}
imagePullPolicy: Always
env:
- name: LFAI_CONFIG_PATH
value: /config/
- name: LFAI_CONFIG_FILENAME
value: "*.toml"
- name: PORT
value: "{{ .Values.api.port }}"
ports:
- containerPort: 8080
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 10
periodSeconds: 10
readinessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 10
periodSeconds: 10
volumeMounts:
- name: api-model
mountPath: /config
volumes:
- name: api-model
emptyDir: {}




31 changes: 31 additions & 0 deletions chart/templates/api/permissions.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: read-configmaps
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: read-configmaps
rules:
- apiGroups:
- ""
resources:
- configmaps
- secrets
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-configmaps
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: read-configmaps
subjects:
- kind: ServiceAccount
name: read-configmaps
18 changes: 18 additions & 0 deletions chart/templates/api/service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
apiVersion: v1
kind: Service
metadata:
name: api
annotations:
zarf.dev/connect-description: "Load the OpenAPI spec for the LFAI API"
zarf.dev/connect-url: "/docs"
labels:
zarf.dev/connect-name: lfai-api
spec:
selector:
app: api
ports:
- name: http
protocol: TCP
port: 8080
targetPort: 8080
type: ClusterIP
6 changes: 6 additions & 0 deletions chart/templates/namespace.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
apiVersion: v1
kind: Namespace
metadata:
labels:
istio-injection: {{ .Values.istio.injection }}
name: leapfrogai
18 changes: 18 additions & 0 deletions chart/templates/vs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{{- if .Values.istio.enabled }}
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: leapfrogai
spec:
gateways:
- istio-system/{{ .Values.istio.gateway }}
hosts:
- leapfrogai.{{ .Values.domain }}
http:
- route:
- destination:
host: api
port:
number: 8080
{{- end }}
---
17 changes: 17 additions & 0 deletions chart/values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
domain: bigbang.dev

image:
lfaiAPITag: 0.1.2
kiwigridTag: 1.23.3

istio:
enabled: false
gateway: tenant
injection: disabled

api:
replicas: 1
port: 8080

monitoring:
enabled: false
10 changes: 10 additions & 0 deletions lfai-values.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
domain: ###ZARF_VAR_DOMAIN###

image:
lfaiAPITag: ###ZARF_CONST_LEAPFROGAI_API_VERSION###
kiwigridTag: ###ZARF_CONST_KIWIGRID_VERSION###

istio:
enabled: ###ZARF_VAR_ISTIO_ENABLED###
gateway: ###ZARF_VAR_ISTIO_GATEWAY###
injection: ###ZARF_VAR_ISTIO_INJECTION###
17 changes: 16 additions & 1 deletion main.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,22 @@
from backends.openai import router as openai_router
from backends.openai.routes import *
from utils import get_model_config
import asyncio

app = FastAPI()

# super simple healthz check
@app.get("/healthz")
async def healthz():
return {"status": "ok"}

@app.get("/models")
async def models():
return get_model_config()


@app.on_event('startup')
async def watch_for_configs():
asyncio.create_task(get_model_config().watch_and_load_configs())

app.include_router(openai_router)
get_model_config().load()
6 changes: 5 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,15 @@ dependencies = [
"pyyaml >= 6.0.1",
"leapfrogai >= 0.3.3",
"python-multipart >= 0.0.6",
"toml >= 0.10.2",
]
requires-python = ">=3.11.4"
requires-python = ">=3.11.6 <3.12.0"

[project.optional-dependencies]
dev = ["pip-tools", "pytest", "black", "isort"]

[tool.pip-tools]
generate-hashes = true

[tool.setuptools.packages.find]
exclude = ["chart"]
Loading

0 comments on commit 1a12472

Please sign in to comment.