Skip to content
Draft
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions .github/actions/setup-uv/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: 'Setup UV (Manual)'
description: 'Manually install UV package manager'
inputs:
uv-version:
description: 'UV version to install'
required: false
default: 'latest'
python-version:
description: 'Python version to use'
required: false
default: '3.12'

runs:
using: 'composite'
steps:
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ inputs.python-version }}

- name: Install UV
shell: bash
run: |
if [ "${{ inputs.uv-version }}" = "latest" ]; then
curl -LsSf https://astral.sh/uv/install.sh | sh
else
curl -LsSf https://astral.sh/uv/${{ inputs.uv-version }}/install.sh | sh
fi
echo "$HOME/.local/bin" >> $GITHUB_PATH

Comment on lines +23 to +30
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Semgrep identified an issue in your code:
Using variable interpolation ${{...}} with github context data in a run: step could allow an attacker to inject their own code into the runner. This would allow them to steal secrets and code. github context data can have arbitrary user input and should be treated as untrusted. Instead, use an intermediate environment variable with env: to store the data and use the environment variable in the run: script. Be sure to use double-quotes the environment variable, like this: "$ENVVAR".

To resolve this comment:

🔧 No guidance has been designated for this issue. Fix according to your organization's approved methods.

💬 Ignore this finding

Reply with Semgrep commands to ignore this finding.

  • /fp <comment> for false positive
  • /ar <comment> for acceptable risk
  • /other <comment> for all other reasons

Alternatively, triage in Semgrep AppSec Platform to ignore the finding created by run-shell-injection.

You can view more details about this finding in the Semgrep AppSec Platform.

- name: Verify UV installation
shell: bash
run: |
uv --version
50 changes: 9 additions & 41 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,9 @@ jobs:
if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
steps:
- uses: actions/checkout@v4

- name: Install Rye
run: |
curl -sSf https://rye.astral.sh/get | bash
echo "$HOME/.rye/shims" >> $GITHUB_PATH
env:
RYE_VERSION: '0.44.0'
RYE_INSTALL_OPTION: '--yes'

- name: Install dependencies
run: rye sync --all-features

- name: Run lints
run: ./scripts/lint
- uses: ./.github/actions/setup-uv
- run: uv sync --all-extras --group dev
- run: uv run task ci-lint

build:
if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
Expand All @@ -45,20 +34,9 @@ jobs:
runs-on: ${{ github.repository == 'stainless-sdks/agentex-sdk-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
steps:
- uses: actions/checkout@v4

- name: Install Rye
run: |
curl -sSf https://rye.astral.sh/get | bash
echo "$HOME/.rye/shims" >> $GITHUB_PATH
env:
RYE_VERSION: '0.44.0'
RYE_INSTALL_OPTION: '--yes'

- name: Install dependencies
run: rye sync --all-features

- name: Run build
run: rye build
- uses: ./.github/actions/setup-uv
- run: uv sync --all-extras --group dev
- run: uv run task ci-build

- name: Get GitHub OIDC Token
if: github.repository == 'stainless-sdks/agentex-sdk-python'
Expand All @@ -83,16 +61,6 @@ jobs:
steps:
- uses: actions/checkout@v4

- name: Install Rye
run: |
curl -sSf https://rye.astral.sh/get | bash
echo "$HOME/.rye/shims" >> $GITHUB_PATH
env:
RYE_VERSION: '0.44.0'
RYE_INSTALL_OPTION: '--yes'

- name: Bootstrap
run: ./scripts/bootstrap

- name: Run tests
run: ./scripts/test
- uses: ./.github/actions/setup-uv
- run: uv sync --all-extras --group dev
- run: uv run task ci-test
19 changes: 3 additions & 16 deletions .github/workflows/publish-pypi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,15 @@
name: Publish PyPI
on:
workflow_dispatch:

release:
types: [published]

jobs:
publish:
name: publish
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Install Rye
run: |
curl -sSf https://rye.astral.sh/get | bash
echo "$HOME/.rye/shims" >> $GITHUB_PATH
env:
RYE_VERSION: '0.44.0'
RYE_INSTALL_OPTION: '--yes'

- name: Publish to PyPI
run: |
bash ./bin/publish-pypi
env:
PYPI_TOKEN: ${{ secrets.AGENTEX_PYPI_TOKEN || secrets.PYPI_TOKEN }}
- uses: ./.github/actions/setup-uv
- run: uv build
- run: uv publish --token ${{ secrets.AGENTEX_PYPI_TOKEN || secrets.PYPI_TOKEN }}
6 changes: 5 additions & 1 deletion .github/workflows/release-doctor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ jobs:

- name: Check release environment
run: |
bash ./bin/check-release-environment
if [ -z "$PYPI_TOKEN" ]; then
echo "Error: The PYPI_TOKEN secret has not been set. Please set it in either this repository's secrets or your organization secrets."
exit 1
fi
echo "The environment is ready to push releases!"
env:
PYPI_TOKEN: ${{ secrets.AGENTEX_PYPI_TOKEN || secrets.PYPI_TOKEN }}
26 changes: 26 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
repos:
- repo: local
hooks:
- id: format
name: Format code and docs
entry: uv run task format
language: system
types: [python]
pass_filenames: false

- id: lint
name: Lint code and type check
entry: uv run task lint
language: system
types: [python]
pass_filenames: false

- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-yaml
- id: check-toml
- id: check-merge-conflict
- id: check-added-large-files
1 change: 0 additions & 1 deletion .python-version

This file was deleted.

2 changes: 1 addition & 1 deletion Brewfile
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
brew "rye"
brew "uv"

26 changes: 13 additions & 13 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,26 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co

## Development Commands

### Package Management in the top level repo
- Use `rye` for dependency management (preferred)
- Run `./scripts/bootstrap` to set up the environment
- Or use `rye sync --all-features` directly
### Package Management
- Use `uv` for dependency management
- Run `uv sync --all-extras --group dev` to set up the environment
- Run `uv run task setup-pre-commit` to install pre-commit hooks

Special note: the individual tutorials maintain their own tutorial specific virtualenv using `uv`. So when testing/running tutorials, you `uv run` instead of `rye run`. Everything else is similar.
Both the main repo and individual tutorials use `uv` for consistency.

#### Testing
- Run tests: `rye run pytest` or `./scripts/test`
- Run specific test: `rye run pytest path/to/test_file.py::TestClass::test_method -v`
- Run tests: `uv run task test` (with mock server) or `uv run pytest` (direct)
- Run specific test: `uv run pytest path/to/test_file.py::TestClass::test_method -v`
- Mock server is automatically started for tests, runs on port 4010

#### Linting and Formatting
- Format code: `rye run format` or `./scripts/format`
* The repository is still in flux, so running format might accidentally change files that aren't part of your scope of changes. So always run `run rye format` with additional arguments to constrain the formatting to the files that you are modifying.
- Lint code: `rye run lint` or `./scripts/lint`
- Type check: `rye run typecheck` (runs both pyright and mypy)
- Format code: `uv run task format`
* The repository is still in flux, so running format might accidentally change files that aren't part of your scope of changes. So always run `uv run task format` with additional arguments to constrain the formatting to the files that you are modifying.
- Lint code: `uv run task lint`
- Type check: `uv run task typecheck` (runs both pyright and mypy)

### Building and Running
- Build package: `rye build`
- Build package: `uv build`



Expand Down Expand Up @@ -89,5 +89,5 @@ Most SDK code is auto-generated. Manual changes are preserved in:

### Environment Requirements
- Python 3.12+ required
- Uses Rye for dependency management
- Uses UV for dependency management
- Supports both sync and async client patterns
91 changes: 55 additions & 36 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,37 +1,39 @@
## Setting up the environment

### With Rye
We use [UV](https://docs.astral.sh/uv/) for fast, modern Python package management. UV automatically handles Python installation and virtual environment management.

We use [Rye](https://rye.astral.sh/) to manage dependencies because it will automatically provision a Python environment with the expected Python version. To set it up, run:
### Quick Setup

```sh
$ ./scripts/bootstrap
# Setup environment and dependencies
$ uv sync --all-extras --group dev

# Install pre-commit hooks
$ uv run task setup-pre-commit
```

Or [install Rye manually](https://rye.astral.sh/guide/installation/) and run:
### Manual Setup

If you prefer to install UV manually:

```sh
$ rye sync --all-features
# Install UV - https://docs.astral.sh/uv/getting-started/installation/
$ curl -LsSf https://astral.sh/uv/install.sh | sh

# Install dependencies
$ uv sync --all-extras --group dev
```

You can then run scripts using `rye run python script.py` or by activating the virtual environment:
You can then run commands using `uv run` or by activating the virtual environment:

```sh
# Activate the virtual environment - https://docs.python.org/3/library/venv.html#how-venvs-work
# Activate the virtual environment
$ source .venv/bin/activate

# now you can omit the `rye run` prefix
# Now you can omit the `uv run` prefix
$ python script.py
```

### Without Rye

Alternatively if you don't want to install `Rye`, you can stick with the standard `pip` setup by ensuring you have the Python version specified in `.python-version`, create a virtual environment however you desire and then install dependencies using this command:

```sh
$ pip install -r requirements-dev.lock
```

## Modifying/Adding code

Most of the SDK is generated code. Modifications to code will be persisted between generations, but may
Expand All @@ -45,7 +47,7 @@ All files in the `examples/` directory are not modified by the generator and can
```py
# add an example to examples/<your-example>.py

#!/usr/bin/env -S rye run python
#!/usr/bin/env -S uv run python
```

Expand All @@ -72,9 +74,9 @@ Building this package will create two files in the `dist/` directory, a `.tar.gz
To create a distributable version of the library, all you have to do is run this command:

```sh
$ rye build
$ uv build
# or
$ python -m build
$ uv run task ci-build
```

Then to install:
Expand All @@ -83,36 +85,49 @@ Then to install:
$ pip install ./path-to-wheel-file.whl
```

## Running tests
## Development Workflow

Most tests require you to [set up a mock server](https://github.com/stoplightio/prism) against the OpenAPI spec to run the tests.
We use [Taskipy](https://github.com/taskipy/taskipy) to manage development tasks. All commands are defined in `pyproject.toml` and can be run with `uv run task <command>`.

```sh
# you will need npm installed
$ npx prism mock path/to/your/openapi.yml
```
### Running tests

```sh
$ ./scripts/test
```
# Run tests with automatic mock server management
$ uv run task test

## Linting and formatting
# Or run tests directly (no mock server setup)
$ uv run pytest
```

This repository uses [ruff](https://github.com/astral-sh/ruff) and
[black](https://github.com/psf/black) to format the code in the repository.
The test command automatically handles [Prism mock server](https://github.com/stoplightio/prism) setup and teardown using the OpenAPI spec.

To lint:
### Linting and formatting

```sh
$ ./scripts/lint
# Format code and documentation
$ uv run task format

# Run all linting checks
$ uv run task lint

# Run type checking only
$ uv run task typecheck
```

To format and fix all ruff issues automatically:
### Available Tasks

```sh
$ ./scripts/format
# See all available tasks
$ uv run task --list
```

Key tasks:
- `format` - Format code with Ruff and documentation
- `lint` - Run all checks (Ruff + type checking + import validation)
- `test` - Run tests with mock server orchestration
- `mock` - Start standalone mock API server
- `setup-pre-commit` - Install pre-commit hooks

## Publishing and releases

Changes made to this repository via the automated release PR pipeline should publish to PyPI automatically. If
Expand All @@ -124,8 +139,12 @@ You can release to package managers by using [the `Publish PyPI` GitHub action](

### Publish manually

If you need to manually release a package, you can run the `bin/publish-pypi` script with a `PYPI_TOKEN` set on
the environment.
If you need to manually release a package, you can use UV directly:

```sh
$ uv build
$ uv publish --token $PYPI_TOKEN
```

## 🤖 **Vibe Coding Setup**

Expand Down
Loading
Loading