Skip to content

Commit 5cdf0d0

Browse files
Merge pull request #1 from elhio/feature/eval-local-model
Feature/eval local model
2 parents 4607c23 + 88693b6 commit 5cdf0d0

57 files changed

Lines changed: 19792 additions & 134 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.env.example

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# Guard Python client — environment template
2+
#
3+
# Copy this file to `.env` and fill in your values:
4+
#
5+
# cp .env.example .env
6+
#
7+
# `.env` is git-ignored so your secrets never leave your machine. This file is
8+
# committed, so it must only ever contain placeholders — never a real key.
9+
#
10+
11+
# (REQUIRED) API key
12+
GUARD_API_KEY=
13+
14+
# (REQUIRED) Default space the media will be processed
15+
GUARD_SPACE_ID=
16+
17+
# (OPTIONAL) Default organization which owns new spaces, and scopes runner listings
18+
#GUARD_ORGANIZATION_ID=
19+
20+
# (OPTIONAL) API root
21+
#GUARD_BASE_URL=https://api.elhio.com
22+
23+
# (OPTIONAL) Engine used, either "cloud" or "local"
24+
#GUARD_ENGINE=cloud
25+
26+
# (OPTIONAL) Language
27+
#GUARD_LOCALE=en
28+
29+
# (OPTIONAL) Per-request HTTP timeout, in seconds
30+
#GUARD_TIMEOUT=30.0
31+
32+
# (OPTIONAL) Retries on connection errors and 429/5xx responses
33+
#GUARD_MAX_RETRIES=3
34+
35+
# (OPTIONAL) Path to the ONNX model for the local engine
36+
#GUARD_LOCAL_MODEL_PATH=
37+
38+
# (OPTIONAL) Read a different env file instead of `.env`
39+
#GUARD_ENV_FILE=.env.staging
40+
41+
# (OPTIONAL) Default media file to analyze
42+
# Used only by scripts/create_activity.py
43+
#GUARD_MEDIA=path/to/photo.jpg

.github/workflows/release.yml

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
name: Release
2+
3+
on:
4+
release:
5+
types:
6+
- published
7+
8+
concurrency:
9+
group: release-${{ github.ref }}
10+
cancel-in-progress: false
11+
12+
permissions:
13+
contents: read
14+
15+
jobs:
16+
validate:
17+
uses: ./.github/workflows/validate.yml
18+
19+
build:
20+
needs: validate
21+
runs-on: ubuntu-latest
22+
steps:
23+
- name: Checkout
24+
uses: actions/checkout@v5
25+
- name: Set up uv
26+
uses: astral-sh/setup-uv@v9.0.0
27+
with:
28+
python-version: '3.12'
29+
- name: Check the release tag matches the package version
30+
env:
31+
TAG: ${{ github.event.release.tag_name }}
32+
run: |
33+
tag="${TAG#v}"
34+
version="$(uv version --short)"
35+
if [ "$tag" != "$version" ]; then
36+
echo "::error::Release tag '$TAG' does not match the version in pyproject.toml ('$version')."
37+
echo "Bump pyproject.toml, or retag the release."
38+
exit 1
39+
fi
40+
echo "Releasing guard-client $version"
41+
- name: Build the package
42+
run: uv build
43+
- name: Upload distributions
44+
uses: actions/upload-artifact@v7
45+
with:
46+
name: release-dist
47+
path: dist/
48+
retention-days: 7
49+
50+
publish-pypi:
51+
needs: build
52+
runs-on: ubuntu-latest
53+
environment:
54+
name: production
55+
permissions:
56+
id-token: write
57+
steps:
58+
- name: Download distributions
59+
uses: actions/download-artifact@v8
60+
with:
61+
name: release-dist
62+
path: dist
63+
- name: Publish package distributions to PyPI
64+
uses: pypa/gh-action-pypi-publish@release/v1
65+
66+
attach-assets:
67+
needs: build
68+
runs-on: ubuntu-latest
69+
permissions:
70+
contents: write
71+
steps:
72+
- name: Download distributions
73+
uses: actions/download-artifact@v8
74+
with:
75+
name: release-dist
76+
path: dist
77+
78+
- name: Upload assets to release
79+
uses: softprops/action-gh-release@v3
80+
with:
81+
files: |
82+
dist/*.whl
83+
dist/*.tar.gz
84+
85+
docs:
86+
needs: publish-pypi
87+
runs-on: ubuntu-latest
88+
environment:
89+
name: production
90+
steps:
91+
- name: Checkout
92+
uses: actions/checkout@v5
93+
- name: Set up uv
94+
uses: astral-sh/setup-uv@v9.0.0
95+
with:
96+
python-version: '3.12'
97+
- name: Install the docs group
98+
run: uv sync --locked --group docs
99+
- name: Build the documentation
100+
run: uv run python scripts/build_docs.py --strict
101+
- name: Upload the documentation to MinIO
102+
env:
103+
AWS_ACCESS_KEY_ID: ${{ secrets.MINIO_ACCESS_KEY }}
104+
AWS_SECRET_ACCESS_KEY: ${{ secrets.MINIO_SECRET_KEY }}
105+
AWS_DEFAULT_REGION: ${{ vars.MINIO_REGION || 'us-east-1' }}
106+
AWS_ENDPOINT_URL_S3: ${{ vars.MINIO_ENDPOINT }}
107+
BUCKET: ${{ vars.DOCS_BUCKET }}
108+
run: |
109+
set -euo pipefail
110+
111+
# Say which setting is missing, rather than failing later against AWS.
112+
: "${AWS_ENDPOINT_URL_S3:?set the MINIO_ENDPOINT repository variable}"
113+
: "${BUCKET:?set the DOCS_BUCKET repository variable}"
114+
115+
# MinIO serves path-style addressing. Virtual-host style needs wildcard DNS
116+
# that a self-hosted instance usually does not have, and no environment
117+
# variable controls this, so it goes in the runner's throwaway CLI config.
118+
aws configure set default.s3.addressing_style path
119+
120+
package="$(uv run python -c "import json; print(json.load(open('docs/docs.json'))['package'])")"
121+
version="$(uv run python -c "import json; print(json.load(open('docs/docs.json'))['version'])")"
122+
key="docs/${package}/${version}.json"
123+
124+
# `--endpoint-url` is passed explicitly even though AWS_ENDPOINT_URL_S3 is
125+
# normally picked up on its own: that variable needs AWS CLI v2.13+, and a
126+
# runner with anything older would silently upload to the real AWS instead.
127+
128+
# A released version's documentation is immutable. Re-running a failed
129+
# release job must not quietly rewrite what people have already read.
130+
if aws --endpoint-url "$AWS_ENDPOINT_URL_S3" s3api head-object \
131+
--bucket "$BUCKET" --key "$key" >/dev/null 2>&1; then
132+
echo "::notice::${key} already exists; leaving it untouched."
133+
else
134+
aws --endpoint-url "$AWS_ENDPOINT_URL_S3" \
135+
s3 cp docs/docs.json "s3://${BUCKET}/${key}" \
136+
--content-type application/json \
137+
--cache-control "public, max-age=31536000, immutable"
138+
echo "Uploaded ${key}"
139+
fi
140+
141+
aws --endpoint-url "$AWS_ENDPOINT_URL_S3" \
142+
s3 cp docs/docs.json "s3://${BUCKET}/docs/${package}/latest.json" \
143+
--content-type application/json \
144+
--cache-control "no-cache"
145+
echo "Updated docs/${package}/latest.json"

.github/workflows/validate.yml

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
name: Validate
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
types:
9+
- opened
10+
- synchronize
11+
- reopened
12+
workflow_call:
13+
14+
concurrency:
15+
group: ${{ github.workflow }}-${{ github.ref }}
16+
cancel-in-progress: true
17+
18+
permissions:
19+
contents: read
20+
21+
jobs:
22+
lint:
23+
runs-on: ubuntu-latest
24+
steps:
25+
- name: Checkout
26+
uses: actions/checkout@v5
27+
- name: Set up uv
28+
uses: astral-sh/setup-uv@v9.0.0
29+
with:
30+
python-version: '3.12'
31+
- name: Install dependencies
32+
run: uv sync --locked
33+
- name: Lint code
34+
run: uv run ruff check
35+
- name: Check formatting
36+
run: uv run ruff format --check
37+
- name: Type check
38+
run: uv run mypy src/
39+
- name: Install the docs group
40+
run: uv sync --locked --group docs
41+
- name: Build the documentation
42+
run: uv run python scripts/build_docs.py --strict
43+
44+
test:
45+
strategy:
46+
fail-fast: false
47+
matrix:
48+
os: [ubuntu-latest]
49+
python-version: ['3.10', '3.11', '3.12', '3.13']
50+
include:
51+
- os: macos-latest
52+
python-version: '3.13'
53+
- os: windows-latest
54+
python-version: '3.13'
55+
runs-on: ${{ matrix.os }}
56+
steps:
57+
- name: Checkout
58+
uses: actions/checkout@v5
59+
- name: Set up uv
60+
uses: astral-sh/setup-uv@v9.0.0
61+
with:
62+
python-version: ${{ matrix.python-version }}
63+
- name: Install dependencies
64+
run: uv sync --locked
65+
- name: Run unit tests
66+
run: uv run pytest -q
67+
68+
test-contract:
69+
runs-on: ubuntu-latest
70+
steps:
71+
- name: Checkout
72+
uses: actions/checkout@v5
73+
- name: Set up uv
74+
uses: astral-sh/setup-uv@v9.0.0
75+
with:
76+
python-version: '3.12'
77+
- name: Install dependencies with the local extra
78+
run: uv sync --locked --extra local
79+
- name: Run the shared contract test
80+
run: uv run pytest tests/test_contract.py -q
81+
82+
build:
83+
runs-on: ubuntu-latest
84+
steps:
85+
- name: Checkout
86+
uses: actions/checkout@v5
87+
- name: Set up uv
88+
uses: astral-sh/setup-uv@v9.0.0
89+
with:
90+
python-version: '3.12'
91+
- name: Build the package
92+
run: uv build
93+
- name: Import the built wheel in a clean environment
94+
run: |
95+
uv run --no-project --isolated --with dist/*.whl \
96+
python -c "import guard_client; print(guard_client.__version__)"
97+
- name: Upload distributions
98+
uses: actions/upload-artifact@v7
99+
with:
100+
name: dist-${{ github.sha }}
101+
path: dist/
102+
retention-days: 7

.gitignore

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
logs
99
*.log
1010

11+
# docs
12+
docs/docs.json
13+
1114
# editor directories and files
1215
.vscode/*
1316
!.vscode/extensions.json
@@ -41,4 +44,9 @@ htmlcov/
4144
test-results/
4245
junit.xml
4346
.tox/
44-
.nox/
47+
.nox/
48+
49+
# build artefacts
50+
dist/
51+
build/
52+
*.egg-info/

0 commit comments

Comments
 (0)