Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
f093f28
:sparkles: feat: Add async httpx gateway runtime and test
YashGaykar0309 May 18, 2026
d715e3e
:recycle: refactor: Organize sync and async runtime and test layout
YashGaykar0309 May 18, 2026
7f8d953
:memo: docs: add async gateway usage examples
YashGaykar0309 May 18, 2026
d5c5406
:recycle: refactor: load OSC spec from service resources
YashGaykar0309 May 18, 2026
14b95ae
:sparkles: feat: add OKS client support
YashGaykar0309 May 18, 2026
489ecda
:bookmark: release: add OKS spec update automation
YashGaykar0309 May 18, 2026
653069c
:white_check_mark: test: add test for async security group lifecycle
YashGaykar0309 May 20, 2026
85e8622
:sparkles: feat: Add generator for oks to create models, funs to inte…
YashGaykar0309 May 21, 2026
61c939f
:sparkles: feat: add generater for clients and schemas
YashGaykar0309 May 26, 2026
504180d
:sparkles: feat: add generated clients and models
YashGaykar0309 May 26, 2026
feca815
:fire: chore: remove unnecessary error codes file
YashGaykar0309 May 26, 2026
7d59e49
:sparkles: feat: Update Gateway/Client to support multi service async…
YashGaykar0309 May 26, 2026
22a96e8
:white_check_mark: test: Update osc sync tests using new client
YashGaykar0309 May 26, 2026
aaa0da8
:white_check_mark: test: Add a test for sync oks(project lifecycle)
YashGaykar0309 May 26, 2026
f1208e6
:white_check_mark: test: Add a test for async oks(project lifecycle)
YashGaykar0309 May 26, 2026
95df31d
:white_check_mark: test: Add a tests for usage of osc using async client
YashGaykar0309 May 26, 2026
88f12a4
:white_check_mark: test: Add a tests for openapi based generator
YashGaykar0309 May 26, 2026
488d44a
:white_check_mark: test: Add a test to uniquely marked fields
YashGaykar0309 May 26, 2026
0f52570
:test_tube: test: cover retry timeout and retry-after behavior
YashGaykar0309 May 27, 2026
190f737
:lock: fix: make rate limiter concurrency safe and add tests
YashGaykar0309 May 28, 2026
a4a26bf
:test_tube: test: cover clients lifecycle cleanup
YashGaykar0309 May 28, 2026
a32a671
:test_tube: test: cover authentication behavior
YashGaykar0309 May 28, 2026
4933bac
:test_tube: test: cover profile config loading
YashGaykar0309 May 28, 2026
697cab8
:rotating_light: fix: address CodeQL findings in async gateway and ge…
YashGaykar0309 Jun 1, 2026
9d75a01
:pencil2: fix: address review comments
YashGaykar0309 Jun 1, 2026
b1f38c4
:bookmark: fix: support per-service release builds
YashGaykar0309 Jun 1, 2026
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
41 changes: 34 additions & 7 deletions .github/scripts/release-build.sh
Original file line number Diff line number Diff line change
@@ -1,13 +1,30 @@
#!/bin/env bash
set -e
osc_api_version=${1#v}
service=${1:-all}
osc_api_version=${2#v}
oks_api_url=${3:-https://docs.outscale.com/_attachments/oks.yaml}

if [ -z "$osc_api_version" ]; then
echo "run $0 with version tag as argument, abort."
case "$service" in
osc|oks|all)
;;
*)
echo "Unknown service '$service'. Expected one of: osc, oks, all."
exit 1
;;
esac

if [ "$service" != "oks" ] && [ -z "$osc_api_version" ]; then
echo "run $0 with an OSC API version when building service '$service', abort."
exit 1
fi

if [ "$service" != "osc" ] && [ -z "$oks_api_url" ]; then
echo "run $0 with an OKS OpenAPI URL when building service '$service', abort."
exit 1
fi

root=$(cd "$(dirname $0)/../.." && pwd)
cd "$root"

# build new version number
local_sdk_version=$(cat $root/osc_sdk_python/VERSION)
Expand All @@ -17,14 +34,24 @@ local_sdk_version_patch=$(echo $local_sdk_version | cut -d '.' -f 3)
new_sdk_version_minor=$(( local_sdk_version_minor + 1 ))
new_sdk_version="$local_sdk_version_major.$new_sdk_version_minor.0"

# Update osc-api version
curl --retry 10 -o "${root}/osc_sdk_python/resources/outscale.yaml" "https://raw.githubusercontent.com/outscale/osc-api/refs/tags/${osc_api_version}/outscale.yaml"
git add "${root}/osc_sdk_python/resources/outscale.yaml"
if [ "$service" = "osc" ] || [ "$service" = "all" ]; then
# Update osc-api version
curl --retry 10 -o "${root}/osc_sdk_python/resources/osc/api.yaml" "https://raw.githubusercontent.com/outscale/osc-api/refs/tags/${osc_api_version}/outscale.yaml"
uv run python -m osc_sdk_python.codegen.generator osc
git add "${root}/osc_sdk_python/resources/osc/api.yaml" "${root}/osc_sdk_python/generated/osc"
fi

if [ "$service" = "oks" ] || [ "$service" = "all" ]; then
# Update oks-api version
curl --retry 10 -o "${root}/osc_sdk_python/resources/oks/api.yaml" "${oks_api_url}"
uv run python -m osc_sdk_python.codegen.generator oks
git add "${root}/osc_sdk_python/resources/oks/api.yaml" "${root}/osc_sdk_python/generated/oks"
fi

# Setup new SDK version
for f in "$root/README.md" "$root/osc_sdk_python/VERSION"; do
sed -i "s/$local_sdk_version_major\.$local_sdk_version_minor\.$local_sdk_version_patch/$local_sdk_version_major\.$new_sdk_version_minor\.0/g" "$f"
git add "$f"
done

uv version $(cat osc_sdk_python/VERSION)
uv version "$(cat osc_sdk_python/VERSION)"
30 changes: 25 additions & 5 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,22 @@ name: osc-sdk-python release build
on:
workflow_dispatch:
inputs:
api_version:
description: 'Outscale API version'
service:
description: 'Service to build'
required: true
type: choice
default: all
options:
- osc
- oks
- all
api_version:
description: 'Outscale API version, required for osc or all'
required: false
oks_api_url:
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Both services can have different release plan, so we should be able to build and release one without the other

description: 'OKS OpenAPI URL, used for oks or all'
required: false
default: 'https://docs.outscale.com/_attachments/oks.yaml'

permissions:
contents: write
Expand All @@ -24,9 +37,11 @@ jobs:
- name: Set up Python
run: uv python install
- name: Build release
run: .github/scripts/release-build.sh "$API_VERSION"
run: .github/scripts/release-build.sh "$SERVICE" "$API_VERSION" "$OKS_API_URL"
env:
SERVICE: ${{ github.event.inputs.service }}
API_VERSION: ${{ github.event.inputs.api_version }}
OKS_API_URL: ${{ github.event.inputs.oks_api_url }}
- name: Get SDK version
id: get-sdk-version
run: |
Expand All @@ -38,11 +53,16 @@ jobs:
author: "Outscale Bot <opensource+bot@outscale.com>"
commit-message: "🔖 release: osc-sdk-python v${{ env.sdk_version }}"
body: |
Automatic build of SDK v${{ env.sdk_version }} version based on Outscale API ${{ env.api_version }}.
title: "SDK v${{ env.sdk_version }}"
Automatic ${{ env.service }} build of SDK v${{ env.sdk_version }}.

Outscale API version: ${{ env.api_version }}
OKS API URL: ${{ env.oks_api_url }}
title: "SDK v${{ env.sdk_version }} (${{ env.service }})"
token: "${{ env.token }}"
labels: "kind/feature"
env:
sdk_version: ${{ steps.get-sdk-version.outputs.sdk_version }}
service: ${{ github.event.inputs.service }}
api_version: ${{ github.event.inputs.api_version }}
oks_api_url: ${{ github.event.inputs.oks_api_url }}
token: ${{ secrets.GH_TOKEN || secrets.GITHUB_TOKEN }}
3 changes: 1 addition & 2 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
include osc_sdk_python/osc-api/outscale.yaml
include osc_sdk_python/resources/gateway_errors.yaml
recursive-include osc_sdk_python/resources *.yaml
include osc_sdk_python/VERSION
72 changes: 62 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
It allows you to:

- Configure multiple profiles through environment variables or credential files.
- Use either the synchronous `Client` or asynchronous `AsyncClient`.
- Customize retry and rate-limit behavior.
- Enable detailed logging of requests and responses.

Expand Down Expand Up @@ -146,15 +147,65 @@ Note that some API calls may be blocked with this method. See the [authenticatio
Example:

```python
from osc_sdk_python import Gateway
from osc_sdk_python import Client

with Gateway(email="your@email.com", password="yourAccountPassword") as gw:
keys = gw.ReadAccessKeys()
with Client(email="your@email.com", password="yourAccountPassword") as client:
keys = client.osc.ReadAccessKeys()
```

### Async Usage

Use `AsyncClient` when calling the SDK from async Python code:

```python
import asyncio

from osc_sdk_python import AsyncClient


async def main():
async with AsyncClient(profile="default") as client:
vms = await client.osc.read_vms()
print(vms)


if __name__ == "__main__":
asyncio.run(main())
```

### Multi-Service Client

Use `Client` or `AsyncClient` to access multiple services from one SDK object:

```python
from osc_sdk_python import Client

with Client(profile="default") as client:
vms = client.osc.ReadVms()
projects = client.oks.ListProjects()
```

Async example:

```python
import asyncio

from osc_sdk_python import AsyncClient


async def main():
async with AsyncClient(profile="default") as client:
vms = await client.osc.read_vms()
projects = await client.oks.list_projects()


if __name__ == "__main__":
asyncio.run(main())
```

### Retry Options

The following options can be provided when initializing the `Gateway` to customize the retry behavior of the SDK:
The following options can be provided when initializing the `Client` or `AsyncClient` to customize the retry behavior of the SDK:

* `max_retries` (integer, default `3`)
* `retry_backoff_factor` (float, default `1.0`)
Expand All @@ -166,9 +217,9 @@ These correspond to their counterparts in [`urllib3.util.Retry`](https://urllib3
Example:

```python
from osc_sdk_python import Gateway
from osc_sdk_python import Client

gw = Gateway(
client = Client(
max_retries=5,
retry_backoff_factor=0.5,
retry_backoff_jitter=1.0,
Expand All @@ -178,17 +229,17 @@ gw = Gateway(

### Rate Limit Options

You can also configure rate limiting when initializing the `Gateway`:
You can also configure rate limiting when initializing the `Client`:

* `limiter_max_requests` (integer, default `5`)
* `limiter_window` (integer, default `1`)

Example:

```python
from osc_sdk_python import Gateway
from osc_sdk_python import Client

gw = Gateway(
client = Client(
limiter_max_requests=20,
limiter_window=5,
)
Expand All @@ -205,8 +256,9 @@ More usage patterns and logging examples are documented in:
Some example topics covered in `docs/examples.md`:

* Listing VMs and volumes
* Async usage with `AsyncClient`
* Using profiles and regions
* Raw calls with `gw.raw("ActionName", **params)`
* Raw calls with `client.osc.raw("ActionName", **params)`
* Enabling and reading logs

---
Expand Down
Loading