Skip to content

Commit ec4662f

Browse files
committed
add jwt and model dependent queue
add JSON Web Token as a user login service. This makes it easier to make the proxy distributed and does not need any user text file. And users can be added without restarting the server. It also make it more secure in a non https env. Extracted the queue part of the code to a subset of classes so different queues can easily be implemented and used. As long as they conform to an API. Add a model depended queue, it prioritize the servers which have a certain model already loaded. It also can have black list and white list of which model it can handle due to cpu/ram/gpu. It conforms to the shortest queue principle of the simple queue Add logging instead of prints to the stderr output. Add github-ci Signed-off-by: Robert Marklund <robbelibobban@gmail.com>
1 parent 6b63597 commit ec4662f

27 files changed

+3687
-139
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
---
2+
name: build wheel
3+
4+
"on":
5+
push:
6+
branches:
7+
- main
8+
pull_request:
9+
branches:
10+
- main
11+
12+
defaults:
13+
run:
14+
shell: bash
15+
16+
jobs:
17+
18+
build-wheel:
19+
retry: 2
20+
runs-on: ubuntu-latest
21+
22+
steps:
23+
- name: Checkout
24+
uses: actions/checkout@v4
25+
26+
- name: Set up Python 3.13
27+
uses: actions/setup-python@v5
28+
with:
29+
python-version: 3.13
30+
31+
- name: Set up the cache
32+
uses: actions/cache@v4
33+
with:
34+
path: .venv
35+
key: cache-python-packages
36+
37+
- name: Set up the project
38+
run: |
39+
pip install poetry
40+
# poetry config virtualenvs.in-project true
41+
42+
# build for all versions of python ?
43+
- name: build
44+
run: poetry build
45+
46+
- name: Archive build and wheel
47+
uses: actions/upload-artifact@v4
48+
with:
49+
name: build-and-wheel
50+
path: dist
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
---
2+
name: build docker images
3+
4+
"on":
5+
push:
6+
branches:
7+
- main
8+
pull_request:
9+
branches:
10+
- main
11+
12+
defaults:
13+
run:
14+
shell: bash
15+
16+
jobs:
17+
18+
docker:
19+
retry: 2
20+
runs-on: ubuntu-latest
21+
steps:
22+
- name: Checkout
23+
uses: actions/checkout@v4
24+
25+
# - name: Login to Docker Hub
26+
# uses: docker/login-action@v3
27+
# with:
28+
# username: ${{ vars.DOCKERHUB_USERNAME }}
29+
# password: ${{ secrets.DOCKERHUB_TOKEN }}
30+
31+
- name: Set up QEMU
32+
uses: docker/setup-qemu-action@v3
33+
34+
- name: Set up Docker Buildx
35+
uses: docker/setup-buildx-action@v3
36+
37+
- name: Build and push
38+
uses: docker/build-push-action@v6
39+
with:
40+
context: .
41+
push: false
42+
tags: ollama_proxy_server:latest
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
---
2+
name: run quality tests
3+
4+
"on":
5+
push:
6+
branches:
7+
- main
8+
pull_request:
9+
branches:
10+
- main
11+
12+
defaults:
13+
run:
14+
shell: bash
15+
16+
jobs:
17+
18+
quality:
19+
retry: 2
20+
runs-on: ubuntu-latest
21+
22+
steps:
23+
- name: Checkout
24+
uses: actions/checkout@v4
25+
26+
- name: Set up Python 3.13
27+
uses: actions/setup-python@v5
28+
with:
29+
python-version: 3.13
30+
31+
- name: Set up the cache
32+
uses: actions/cache@v4
33+
with:
34+
path: .venv
35+
key: cache-python-packages
36+
37+
- name: Set up the project
38+
run: |
39+
pip install poetry safety tox
40+
# poetry config virtualenvs.in-project true
41+
42+
- name: Run ruff lint
43+
run: tox -e lint
44+
45+
- name: Run pylint
46+
run: tox -e pylint
47+
48+
code-saftey:
49+
retry: 2
50+
runs-on: ubuntu-latest
51+
steps:
52+
- name: Check out master
53+
uses: actions/checkout@v4
54+
55+
- name: Assign variable
56+
id: safety_api_key
57+
run: echo '::set-output name=secret::${{secrets.SAFETY_API_KEY}}'
58+
59+
- name: Run Safety CLI to check for vulnerabilities
60+
if: steps.secret.outputs.safety_api_key
61+
uses: pyupio/safety-action@v1
62+
with:
63+
# api-key: ${{ secrets.SAFETY_API_KEY }}
64+
# To always see detailed output from this action
65+
args: --detailed-output
66+
env: # Or as an environment variable
67+
SAFETY_API_KEY: ${{ secrets.SAFETY_API_KEY }}
68+
69+
shell-check:
70+
retry: 2
71+
runs-on: ubuntu-latest
72+
steps:
73+
- name: Check out master
74+
uses: actions/checkout@v4
75+
76+
- name: install shellcheck
77+
run: apt install shellcheck
78+
79+
- name: Run shellcheck
80+
run: |
81+
./scripts/run-shellcheck.sh
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
---
2+
name: run tox test
3+
4+
"on":
5+
push:
6+
branches:
7+
- main
8+
pull_request:
9+
branches:
10+
- main
11+
12+
defaults:
13+
run:
14+
shell: bash
15+
16+
jobs:
17+
tests:
18+
retry: 2
19+
strategy:
20+
max-parallel: 6
21+
matrix:
22+
os: [ubuntu-latest, macos-latest, windows-latest]
23+
python-version: ["3.10", "3.11", "3.12", "3.13"] # , "3.14"]
24+
25+
runs-on: ${{ matrix.os }}
26+
27+
steps:
28+
- name: Checkout
29+
uses: actions/checkout@v4
30+
31+
- name: Set up Python ${{ matrix.python-version }}
32+
uses: actions/setup-python@v5
33+
with:
34+
python-version: ${{ matrix.python-version }}
35+
36+
- name: Set up the cache
37+
uses: actions/cache@v4
38+
env:
39+
cache-name: cache-python-packages
40+
with:
41+
path: .venv
42+
key: ${{ matrix.os }}-${{ matrix.python-version }}-${{ env.cache-name }}
43+
restore-keys: |
44+
${{ matrix.os }}-${{ matrix.python-version }}-
45+
${{ matrix.os }}-
46+
47+
- name: Set up the project
48+
run: |
49+
pip install poetry tox
50+
# poetry config virtualenvs.in-project true
51+
52+
- name: Run the test suite
53+
run: tox -f test -l | tr '\n' ',' | xargs tox -e
54+
55+
- name: Archive coverage report
56+
uses: actions/upload-artifact@v4
57+
with:
58+
name: code-coverage-report
59+
path: coverage.xml

.yamllint.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
extends: default
3+
ignore: ".tox*\n.git*"
4+
rules:
5+
line-length:
6+
max: 120
7+
level: warning

Dockerfile

Lines changed: 58 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,67 @@
1-
FROM python:3.11
1+
FROM python:3.13 AS python-base
22

3-
# Update packagtes, install necessary tools into the base image, clean up and clone git repository
4-
RUN apt update \
5-
&& apt install -y --no-install-recommends --no-install-suggests git apache2 \
6-
&& apt autoremove -y --purge \
7-
&& apt clean \
8-
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
9-
&& git clone https://github.com/ParisNeo/ollama_proxy_server.git
3+
# https://python-poetry.org/docs#ci-recommendations
4+
ENV POETRY_VERSION=2.1.3
5+
ENV POETRY_HOME=/opt/poetry
6+
ENV POETRY_VENV=/opt/poetry-venv
107

11-
# Change working directory to cloned git repository
12-
WORKDIR ollama_proxy_server
8+
# Tell Poetry where to place its cache and virtual environment
9+
ENV POETRY_CACHE_DIR=/opt/.cache
1310

14-
# Install all needed requirements
15-
RUN pip3 install -e .
11+
# Create stage for Poetry installation
12+
FROM python-base AS poetry-base
1613

17-
# Copy config.ini and authorized_users.txt into project working directory
18-
COPY config.ini .
19-
COPY authorized_users.txt .
14+
# Creating a virtual environment just for poetry and install it with pip
15+
RUN python3 -m venv $POETRY_VENV \
16+
&& $POETRY_VENV/bin/pip install -U pip setuptools \
17+
&& $POETRY_VENV/bin/pip install poetry==${POETRY_VERSION}
18+
19+
# Copy Poetry to app image
20+
# COPY --from=poetry-base ${POETRY_VENV} ${POETRY_VENV}
21+
22+
# Add Poetry to PATH
23+
ENV PATH="${PATH}:${POETRY_VENV}/bin"
24+
25+
# temp dir
26+
WORKDIR /app-tmp
27+
28+
# Copy Dependencies
29+
COPY --chown=worker:worker poetry.lock pyproject.toml ./
30+
31+
# [OPTIONAL] Validate the project is properly configured
32+
RUN poetry check
33+
34+
# Copy Application
35+
COPY --chown=worker:worker . ./
36+
37+
# build and install the app
38+
RUN poetry build
2039

21-
# Start the proxy server as entrypoint
22-
ENTRYPOINT ["ollama_proxy_server"]
40+
# Create a new stage from the base python image
41+
FROM python-base AS ollama-proxy-server
42+
43+
RUN adduser worker
44+
WORKDIR /home/worker
45+
46+
# copy wheel and tgz
47+
COPY --from=poetry-base /app-tmp/dist ./dist
48+
49+
RUN pip install dist/*.whl
50+
51+
RUN rm -fr ./dist
52+
53+
# copy entry point
54+
COPY --from=poetry-base /app-tmp/entry-point.sh /
55+
56+
USER worker
57+
58+
# Copy config.ini and authorized_users.txt into project working directory
59+
COPY --chown=worker:worker config.ini .
60+
COPY --chown=worker:worker authorized_users.txt .
2361

2462
# Do not buffer output, e.g. logs to stdout
2563
ENV PYTHONUNBUFFERED=1
2664

27-
# Set command line parameters
28-
CMD ["--config", "./config.ini", "--users_list", "./authorized_users.txt", "--port", "8080"]
65+
# Run Application
66+
EXPOSE 8080
67+
ENTRYPOINT ["/entry-point.sh"]

config.ini

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
[DefaultServer]
22
url = http://localhost:11434
3+
model_white_list = ["llama3.2:1b"]
4+
model_black_list = ["llama3.2:800b"]
35

46
[SecondaryServer]
57
url = http://localhost:3002
8+
model_black_list = ["llama3.2:200b"]
69

710
# Add more servers as you need.
811

entry-point.sh

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/usr/bin/env bash
2+
3+
[[ -n "$DEBUG" ]] && set -x
4+
5+
JWT_KEY="${JWT_KEY:-}"
6+
JWT_KEY_FILE="$HOME/.jwt-key"
7+
8+
set -Euo pipefail
9+
set -e
10+
11+
if [[ -z "$JWT_KEY" ]] || [[ ! -s "$JWT_KEY_FILE" ]]; then
12+
>&2 echo "No jwt key file or env set creating key and saving in $JWT_KEY_FILE"
13+
JWT_KEY="$(openssl rand -hex 64)"
14+
echo -ne "$JWT_KEY" > "$HOME/.jwt-key"
15+
elif [[ -s "$JWT_KEY_FILE" ]]; then
16+
>&2 echo "found jwt key file '$JWT_KEY_FILE' setting to env"
17+
JWT_KEY="$(cat "$JWT_KEY_FILE")"
18+
fi
19+
20+
if (( ${#@} )) && [ -t 0 ]; then
21+
# user whants interactive
22+
"${@}"
23+
else
24+
ollama_proxy_server "--config=./config.ini" "--users_list=./authorized_users.txt" "--port=8080" "${@}"
25+
fi

0 commit comments

Comments
 (0)