참고소스 수정본

This commit is contained in:
LASTA_DEV01\lasta
2026-05-12 19:40:31 +09:00
parent 0f34a451fc
commit 2e9204243d
8708 changed files with 3259488 additions and 869 deletions

View File

@@ -0,0 +1,29 @@
---
name: Bug report
about: Create a report to help us improve
title: "[bug]"
labels: bug
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. RAIL spec
2. Runtime arguments (e.g. `guard(...)`)
**Expected behavior**
A clear and concise description of what you expected to happen.
**Libraries used w/ versions:**
Example: guardrails-ai==0.7.2, guardrails-api==0.1.0a2, any Hub validators, etc.
**Environment details:**
Example: Docker python:3.13-slim vs Windows Server 2022 w/ python 3.11, etc
_Are you using a virtual environment? If so what kind (venv, conda, etc.)?_
**Additional context**
Add any other context about the problem here.

View File

@@ -0,0 +1,14 @@
blank_issues_enabled: false
contact_links:
- name: Guardrails Documentation
url: https://www.guardrailsai.com/guardrails/docs
about: Check our documentation for answers to common questions and usage guides.
- name: Guardrails Hub
url: https://guardrailsai.com/hub
about: Explore pre-built validators and guards for specific types of risks.
- name: GitHub Discussions
url: https://github.com/guardrails-ai/guardrails/discussions
about: Ask questions and discuss with other community members about Guardrails.
- name: Join our Discord Community
url: https://discord.com/invite/gw4cR9QvYE
about: Connect with other Guardrails users and get real-time support.

View File

@@ -0,0 +1,25 @@
---
name: Documentation issue
about: Report a problem or suggest an improvement for Guardrails documentation
title: "[docs]"
labels: documentation
assignees: ''
---
**Description**
[Add a clear description of the documentation issue or improvement suggestion]
**Current documentation**
[Provide a link to the current documentation page or section that needs attention]
**Suggested changes**
[If you have specific changes in mind, describe them here. Be as detailed as possible]
**Additional context**
[Add any other context, screenshots, or examples that could help explain the issue or improvement]
**Checklist**
- [ ] I have checked that this issue hasn't already been reported
- [ ] I have checked the latest version of the documentation to ensure this issue still exists
- [ ] For simple typos or fixes, I have considered submitting a pull request instead

View File

@@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: "[feat]"
labels: enhancement
assignees: ''
---
**Description**
[Add a description of the feature]
**Why is this needed**
[If you have a concrete use case, add details here.]
**Implementation details**
[If known, describe how this change should be implemented in the codebase]
**End result**
[How should this feature be used?]

View File

@@ -0,0 +1,81 @@
name: Publish to Guardrails Hub
description: Re-Usable action to publish a Validator to Guardrails PyPi
inputs:
validator_id:
description: 'Validator ID ex. guardrails/detect_pii'
required: true
guardrails_token:
description: 'Guardrails Token'
required: true
pypi_repository_url:
description: 'PyPi Repository URL'
required: false
default: 'https://pypi.guardrailsai.com'
package_directory:
description: 'Package Directory "validator" or "some_parent_folder/package"'
required: false
default: 'validator'
runs:
using: "composite"
steps:
- name: Checkout "Validator" Repository
uses: actions/checkout@v3
with:
path: ${{ inputs.package_directory }}
- name: Checkout "Action" repository
uses: actions/checkout@v3
with:
repository: guardrails-ai/guardrails
ref: main
path: shared-ci-scripts
sparse-checkout: |
.github
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Install Twine & Build
shell: bash
run: |
python -m pip install --upgrade pip
pip install twine build toml
- name: Create .pypirc
shell: bash
run: |
touch ~/.pypirc
echo "[distutils]" >> ~/.pypirc
echo "index-servers =" >> ~/.pypirc
echo " private-repository" >> ~/.pypirc
echo "" >> ~/.pypirc
echo "[private-repository]" >> ~/.pypirc
echo "repository = ${{ inputs.pypi_repository_url }}" >> ~/.pypirc
echo "username = __token__" >> ~/.pypirc
echo "password = ${{ inputs.guardrails_token }}" >> ~/.pypirc
- name: Move CI Scripts to Validator
shell: bash
run: |
mv shared-ci-scripts/.github/actions/validator_pypi_publish/*.py ./${{ inputs.package_directory }}
- name: Rename Package
shell: bash
run: |
cd ${{ inputs.package_directory }}
CONCATANATED_NAME=$(python concat_name.py ${{ inputs.validator_id }})
NEW_PEP_PACKAGE_NAME=$(python package_name_normalization.py $CONCATANATED_NAME)
VALIDATOR_FOLDER_NAME=$(echo $NEW_PEP_PACKAGE_NAME | tr - _)
mv ./${{ inputs.package_directory }} ./$VALIDATOR_FOLDER_NAME
python add_build_prefix.py ./pyproject.toml $NEW_PEP_PACKAGE_NAME $VALIDATOR_FOLDER_NAME
- name: Build & Upload
shell: bash
run: |
cd ${{ inputs.package_directory }}
python -m build
twine upload dist/* -u __token__ -p ${{ inputs.guardrails_token }} -r private-repository

View File

@@ -0,0 +1,71 @@
import re
import sys
import toml
def add_package_name_prefix(
pyproject_path, pep_503_new_package_name, validator_folder_name
):
# Read the existing pyproject.toml file
with open(pyproject_path, "r") as f:
content = f.read()
parsed_toml = toml.loads(content)
# get the existing package name
existing_name = parsed_toml.get("project", {}).get("name")
# Update the project name to the new PEP 503-compliant name
# The package name would've been converted to PEP 503-compliant anyways
# But we use this name since it's been concatenated with the seperator
updated_content = re.sub(
rf'(^name\s*=\s*")({re.escape(existing_name)})(")',
rf"\1{pep_503_new_package_name}\3",
content,
flags=re.MULTILINE,
)
# Now we manually add the [tool.setuptools] section with the new folder name
# If the section already exists, we append the correct package name
setuptools_section = f"""
[tool.setuptools]
packages = ["{validator_folder_name}"]
"""
# Check if the [tool.setuptools] section already exists
if "[tool.setuptools]" in updated_content:
# If it exists, update the packages value
updated_content = re.sub(
r"(^\[tool\.setuptools\].*?^packages\s*=\s*\[.*?\])",
f'[tool.setuptools]\npackages = ["{validator_folder_name}"]',
updated_content,
flags=re.DOTALL | re.MULTILINE,
)
else:
# If the section doesn't exist, append it at the end of the file
updated_content += setuptools_section
# Write the modified content back to the pyproject.toml file
with open(pyproject_path, "w") as f:
f.write(updated_content)
print(f"Updated project name to '{pep_503_new_package_name}'.")
print(f"Added package folder '{validator_folder_name}' in {pyproject_path}")
if __name__ == "__main__":
if len(sys.argv) < 3:
print(
"Usage: python script.py <pyproject_path>"
" <pep_503_new_package_name> <validator-folder-name>"
)
sys.exit(1)
pyproject_path = sys.argv[1]
pep_503_new_package_name = sys.argv[2]
validator_folder_name = sys.argv[3]
add_package_name_prefix(
pyproject_path, pep_503_new_package_name, validator_folder_name
)

View File

@@ -0,0 +1,16 @@
def concat_name(validator_id):
validator_id_parts = validator_id.split("/")
namespace = validator_id_parts[0]
package_name = validator_id_parts[1]
return f"{namespace}-grhub-{package_name}"
if __name__ == "__main__":
import sys
if len(sys.argv) < 2:
print("Usage: python concat_name.py <validator-id>")
sys.exit(1)
package_name = sys.argv[1]
print(concat_name(package_name))

View File

@@ -0,0 +1,16 @@
from packaging.utils import canonicalize_name # PEP 503
def normalize_package_name(concatanated_name: str) -> str:
return canonicalize_name(concatanated_name)
if __name__ == "__main__":
import sys
if len(sys.argv) < 2:
print("Usage: python package_name_normalization.py <concat-name>")
sys.exit(1)
concatenated_name = sys.argv[1]
print(normalize_package_name(concatenated_name))

View File

@@ -0,0 +1,27 @@
name: 'Close stale issues and PRs'
on:
schedule:
- cron: '30 3 * * *'
# modify permissions to allow writing to issues and PRs
permissions:
contents: write # only for delete-branch option
issues: write
pull-requests: write
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v9
with:
stale-issue-message: 'This issue is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 14 days.'
stale-pr-message: 'This PR is stale because it has been open 30 days with no activity. Remove stale label or comment or this will be closed in 14 days.'
close-issue-message: 'This issue was closed because it has been stalled for 14 days with no activity.'
close-pr-message: 'This PR was closed because it has been stalled for 14 days with no activity.'
days-before-issue-stale: 60
days-before-pr-stale: 60
days-before-issue-close: 30
days-before-pr-close: 30
repo-token: ${{ secrets.GITHUB_TOKEN }}
operations-per-run: 300

View File

@@ -0,0 +1,20 @@
name: AutoPR
on:
issues:
types: [edited]
jobs:
autopr:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: AutoPR
uses: irgolic/AutoPR@v0.1.0
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
openai_api_key: ${{ secrets.OPENAI_API_KEY }}
issue_number: ${{ github.event.issue.number }}
issue_title: ${{ github.event.issue.title }}
issue_body: ${{ github.event.issue.body }}

View File

@@ -0,0 +1,156 @@
name: CI
on:
push:
branches:
- main
- dev
pull_request:
branches:
- main
- dev
- feat/*
- 0.*.*
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
jobs:
LicenseChecks:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13"]
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install Poetry
uses: snok/install-poetry@v1
- name: Install Dependencies
# TODO: fix errors so that we can run `make dev` instead
run: |
# Setup Virtual Environment
python3 -m venv ./.venv
source .venv/bin/activate
make dev
- name: Check license
run: |
source .venv/bin/activate
.venv/bin/pip install greenlet "setuptools<81"
.venv/bin/liccheck
Linting:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13"]
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install Poetry
uses: snok/install-poetry@v1
- name: Install Dependencies
run: |
# Setup Virtual Environment
python3 -m venv ./.venv
source .venv/bin/activate
make dev
- name: Lint with ruff
run: |
source .venv/bin/activate
make lint
Typing:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13"]
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install Poetry
uses: snok/install-poetry@v1
- name: Install Dependencies
run: |
# Setup Virtual Environment
python3 -m venv ./.venv
source .venv/bin/activate
make full
- name: Static analysis with pyright
run: |
source .venv/bin/activate
make type
Pytests:
runs-on: LargeBois
strategy:
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13"]
# TODO: fix errors so that we can run both `make dev` and `make full`
# dependencies: ['dev', 'full']
# dependencies: ["full"]
steps:
- uses: actions/checkout@v4
- name: Create .guardrailsrc
run: |
echo 'id="SYSTEM TESTING"' > ~/.guardrailsrc
echo 'enable_metrics=false' >> ~/.guardrailsrc
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install Poetry
uses: snok/install-poetry@v1
- name: Install Dependencies
run: |
# Setup Virtual Environment
python3 -m venv ./.venv
source .venv/bin/activate
make full
if [ "${{ matrix.python-version }}" == "3.12" ]; then
echo "Installing latest langchain-core and langsmith from PyPI"
pip install "langchain-core>=0.2" "langsmith<0.2.0,>=0.1.75"
fi
- name: Run Pytests
run: |
source .venv/bin/activate
echo "langchain-core version:"
pip show langchain-core
echo "langsmith version:"
pip show langsmith
make test-cov
- name: Upload to codecov.io
uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
file: ./coverage.xml
flags: unittests
name: codecov-umbrella
fail_ci_if_error: true

View File

@@ -0,0 +1,83 @@
name: CLI Compatibility Tests
on:
push:
branches: [ main ]
paths:
- guardrails/**
- pyproject.toml
workflow_dispatch:
jobs:
CLI-Compatibility:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13"]
typer-version: ["0.16.0", "0.17.0", "0.18.0", "0.19.2"]
click-version: ["8.1.0", "8.2.0"]
exclude:
- typer-version: "0.16.0"
click-version: "8.2.0"
- typer-version: "0.16.0"
click-version: "8.2.1"
- typer-version: "0.16.0"
click-version: "8.3.0"
steps:
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install Poetry
uses: snok/install-poetry@v1
- name: Install Dependencies
run: |
# Setup Virtual Environment
python3 -m venv ./.venv
source .venv/bin/activate
# Install dev dependencies
poetry install --extras dev
# Install specific typer and click versions
pip install typer==${{ matrix.typer-version }} click==${{ matrix.click-version }}
- name: Test CLI Commands
run: |
source .venv/bin/activate
# Test basic CLI help
guardrails --help
# Test validate command help
guardrails validate --help
# Test hub command help
guardrails hub --help
# Test configure command help
guardrails configure --help
# Test hub list command (end-to-end)
guardrails hub list
# Create a simple RAIL spec for testing validate command
cat > test_spec.rail << 'EOF'
<rail version="0.1">
<output>
<string name="answer" description="A simple answer"/>
</output>
<prompt>
Answer the question: What is 2+2?
</prompt>
</rail>
EOF
# Test validate command end-to-end with the RAIL spec
echo '{"answer": "4"}' | guardrails validate test_spec.rail -
# Clean up
rm test_spec.rail

View File

@@ -0,0 +1,50 @@
# Simple workflow for deploying static content to GitHub Pages
name: Deploy static content to Pages
on:
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
group: "pages"
cancel-in-progress: false
jobs:
# Single deploy job since we're just deploying
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Pages
uses: actions/configure-pages@v3
- name: Poetry cache
uses: actions/cache@v3
with:
path: ~/.cache/pypoetry
key: poetry-cache-${{ runner.os }}-${{ steps.setup_python.outputs.python-version }}-${{ env.POETRY_VERSION }}
- name: Install Poetry
uses: snok/install-poetry@v1
- name: Install dependencies
run: poetry install --with docs
- name: Build
run: poetry run mkdocs build
- name: Upload artifact
uses: actions/upload-pages-artifact@v2
with:
# Upload build folder
path: 'site'
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v2

View File

@@ -0,0 +1,73 @@
name: Notebook Execution and Error Check
on:
schedule:
- cron: "0 0 * * *"
push:
branches:
- main
- dev
paths:
- guardrails/**
- pyproject.toml
workflow_dispatch: # This enables manual triggering
jobs:
execute_notebooks:
runs-on: ubuntu-latest
strategy:
matrix:
# this line is automatically generated by the script in .github/workflows/scripts/update_notebook_matrix.sh
notebook: ["bug_free_python_code.ipynb","check_for_pii.ipynb","competitors_check.ipynb","constrained_decoding.ipynb","extracting_entities.ipynb","generate_structured_data_cohere.ipynb","generate_structured_data.ipynb","guard_use.ipynb","guardrails_with_chat_models.ipynb","input_validation.ipynb","json_function_calling_tools.ipynb","langchain_integration.ipynb","lite_llm_defaults.ipynb","llamaindex-output-parsing.ipynb","no_secrets_in_generated_text.ipynb","provenance.ipynb","recipe_generation.ipynb","regex_validation.ipynb","response_is_on_topic.ipynb","secrets_detection.ipynb","select_choice_based_on_action.ipynb","summarizer.ipynb","syntax_error_free_sql.ipynb","text_summarization_quality.ipynb","toxic_language.ipynb","translation_to_specific_language.ipynb","valid_chess_moves.ipynb","value_within_distribution.ipynb"]
env:
COHERE_API_KEY: ${{ secrets.COHERE_API_KEY }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
HUGGINGFACE_API_KEY: ${{ secrets.HUGGINGFACE_API_KEY }}
MISTRAL_API_KEY: ${{ secrets.MISTRAL_API_KEY }}
GUARDRAILS_API_KEY: ${{ secrets.GUARDRAILS_API_KEY }}
NLTK_DATA: /tmp/nltk_data
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: ${{ github.head_ref }}
fetch-depth: 0
- name: Create .guardrailsrc
run: |
echo 'id="SYSTEM TESTING"' > ~/.guardrailsrc
echo 'no_metrics=false' >> ~/.guardrailsrc
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: 3.13.x
- name: Install dependencies
run: |
# Setup Virtual Environment
python3 -m venv ./.venv
source .venv/bin/activate
# Install the current branch
pip install .
# Install extra stuff for notebook runs
pip install "huggingface_hub[cli]" jupyter nbconvert cohere==5.3.2
pip install nltk
- name: Huggingface Hub Login
run: |
source .venv/bin/activate
huggingface-cli login --token $HUGGINGFACE_API_KEY
- name: download nltk data
run: |
source .venv/bin/activate
mkdir /tmp/nltk_data;
python -m nltk.downloader -d /tmp/nltk_data punkt;
- name: Login to Guardrails
run: |
source .venv/bin/activate
guardrails configure --token $GUARDRAILS_API_KEY --disable-metrics --enable-remote-inferencing
- name: Execute notebooks and check for errors
run: |
source .venv/bin/activate
bash ./.github/workflows/scripts/run_notebooks.sh ${{ matrix.notebook }}

View File

@@ -0,0 +1,12 @@
on:
schedule:
- cron: 0 12 * * * # run monthly
workflow_dispatch:
name: Broken Link Check
jobs:
check:
name: Broken Link Check
runs-on: ubuntu-latest
steps:
- name: Broken Link Check
uses: technote-space/broken-link-checker-action@v2

View File

@@ -0,0 +1,29 @@
name: Install from Hub
on:
push:
branches:
- main
paths:
- guardrails/**
- pyproject.toml
workflow_dispatch: # This enables manual triggering
jobs:
install_from_hub:
runs-on: ubuntu-latest
env:
GUARDRAILS_API_KEY: ${{ secrets.GUARDRAILS_API_KEY }}
steps:
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: 3.13.x
- name: pip install from main
run: pip install git+https://github.com/guardrails-ai/guardrails.git@main
- name: Install PII validator
run: |
guardrails configure --token $GUARDRAILS_API_KEY --disable-metrics --enable-remote-inferencing;
guardrails hub install hub://guardrails/detect_pii;
- name: Verify PII validator is addressable
run: echo 'from guardrails.hub import DetectPII' | python

View File

@@ -0,0 +1,30 @@
name: Release PyPi Version
on:
workflow_dispatch: # This event allows manual triggering
jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v2
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: 3.13.x
- name: Install Poetry
uses: snok/install-poetry@v1
with:
version: 2.1.1
- name: Install dependencies
run: make full
- name: Upload to PyPI
env:
PYPI_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
run: poetry publish --build -u __token__ -p $PYPI_PASSWORD

View File

@@ -0,0 +1,26 @@
#!/bin/bash
export NLTK_DATA=/tmp/nltk_data;
# Remove the local guardrails directory and use the installed version
rm -rf ./guardrails
# Navigate to notebooks
cd docs/examples
# Get the notebook name from the matrix variable
notebook="$1"
# Check if the notebook should be processed
invalid_notebooks=("llamaindex-output-parsing.ipynb" "competitors_check.ipynb" "guardrails_server.ipynb" "valid_chess_moves.ipynb")
if [[ ! " ${invalid_notebooks[@]} " =~ " ${notebook} " ]]; then
echo "Processing $notebook..."
# poetry run jupyter nbconvert --to notebook --execute "$notebook"
jupyter nbconvert --to notebook --execute "$notebook"
if [ $? -ne 0 ]; then
echo "Error found in $notebook"
echo "Error in $notebook. See logs for details." >> errors.txt
exit 1
fi
fi
exit 0

View File

@@ -0,0 +1,23 @@
#!/bin/bash
ignore=(chatbot.ipynb translation_with_quality_check.ipynb guardrails_server.ipynb)
# Array to store notebook names
notebook_names="["
# Compile list of file names
for file in $(ls docs/examples/*.ipynb); do
# Add the full filename with extension
filename=$(basename "$file")
if ! [[ ${ignore[*]} =~ "$filename" ]]
then
notebook_names+="\"$filename\","
fi
done
notebook_names="${notebook_names%,}]"
# echo $notebook_names
# find line that begins with "notebook:" and replace it with notebook: $notebook_names
sed "s/notebook: \[.*\]/notebook: $notebook_names/" .github/workflows/examples_check.yml > .github/workflows/examples_check.yml.tmp
mv .github/workflows/examples_check.yml.tmp .github/workflows/examples_check.yml

View File

@@ -0,0 +1,63 @@
name: Server CI
on:
push:
branches:
- main
paths:
- guardrails/**
- pyproject.toml
workflow_dispatch:
jobs:
build-test-server:
runs-on: ubuntu-latest
steps:
- name: Check out head
uses: actions/checkout@v5
with:
persist-credentials: false
- name: Set up QEMU
uses: docker/setup-qemu-action@master
with:
platforms: linux/amd64
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@master
with:
platforms: linux/amd64
- name: Build Docker image
uses: docker/build-push-action@v6
with:
context: .
file: server_ci/Dockerfile
platforms: linux/amd64
push: false
tags: guardrails:server-ci
load: true
build-args: |
GUARDRAILS_TOKEN=${{ secrets.GUARDRAILS_API_KEY }}
- name: Start Docker container
run: |
docker run -d --name guardrails-container -p 8000:8000 -e OPENAI_API_KEY=${{ secrets.OPENAI_API_KEY }} guardrails:server-ci
- name: Wait for Docker container to be ready
run: |
for i in {1..30}; do
if docker exec guardrails-container curl -s http://localhost:8000/; then
echo "Server is up!"
break
fi
echo "Waiting for server..."
sleep 5
done
- name: Run Pytest
run: |
pip install pytest pytest-asyncio openai ".[api]"
pytest server_ci/tests
docker stop guardrails-container
docker rm guardrails-container