Skip to content

release: 0.1.0 #5

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 22 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
9a98381
chore(docs): improve security documentation (#4)
stainless-app[bot] Mar 25, 2025
e478bcd
chore: add request options to client tests (#6)
stainless-app[bot] Mar 26, 2025
e163f84
fix(test): return early after test failure (#7)
stainless-app[bot] Mar 26, 2025
a327a76
chore: fix typos (#8)
stainless-app[bot] Mar 27, 2025
ff74940
codegen metadata
stainless-app[bot] Mar 27, 2025
2f32d03
fix: pluralize `list` response variables (#9)
stainless-app[bot] Apr 2, 2025
8edf5ec
fix(client): return error on bad custom url instead of panic (#10)
stainless-app[bot] Apr 3, 2025
b7b678c
feat(client): support custom http clients (#11)
stainless-app[bot] Apr 8, 2025
825a88c
chore(internal): expand CI branch coverage
stainless-app[bot] Apr 10, 2025
2f052f3
chore(internal): reduce CI branch coverage
stainless-app[bot] Apr 10, 2025
04176d5
docs: update documentation links to be more uniform
stainless-app[bot] Apr 15, 2025
20574c5
chore(docs): document pre-request options
stainless-app[bot] Apr 16, 2025
da52f00
feat(client): add support for reading base URL from environment variable
stainless-app[bot] Apr 16, 2025
482d0da
chore(ci): add timeout thresholds for CI jobs
stainless-app[bot] Apr 23, 2025
d36116e
chore(internal): codegen related update
stainless-app[bot] Apr 24, 2025
142cc65
chore(ci): only use depot for staging repos
stainless-app[bot] Apr 24, 2025
63aa3d5
chore(internal): codegen related update
stainless-app[bot] Apr 29, 2025
43b0734
fix: handle empty bodies in WithJSONSet
stainless-app[bot] Apr 30, 2025
3190e17
fix(client): correctly update body in WithJSONSet
stainless-app[bot] May 7, 2025
02e8b5f
fix(client): clean up reader resources
stainless-app[bot] May 7, 2025
3435e12
feat(client): add support for endpoint-specific base URLs in python
stainless-app[bot] May 14, 2025
0ca3bc1
release: 0.1.0
stainless-app[bot] May 14, 2025
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
20 changes: 10 additions & 10 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
name: CI
on:
push:
branches:
- main
pull_request:
branches:
- main
- next
branches-ignore:
- 'generated'
- 'codegen/**'
- 'integrated/**'
- 'stl-preview-head/**'
- 'stl-preview-base/**'

jobs:
lint:
timeout-minutes: 10
name: lint
runs-on: ubuntu-latest

runs-on: ${{ github.repository == 'stainless-sdks/oxp-go' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}

steps:
- uses: actions/checkout@v4
Expand All @@ -25,9 +25,9 @@ jobs:
- name: Run lints
run: ./scripts/lint
test:
timeout-minutes: 10
name: test
runs-on: ubuntu-latest

runs-on: ${{ github.repository == 'stainless-sdks/oxp-go' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
steps:
- uses: actions/checkout@v4

Expand Down
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "0.0.2"
".": "0.1.0"
}
2 changes: 2 additions & 0 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
configured_endpoints: 3
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/oxp%2Foxp-40d99ea9c623ae3faf290164274b8d9a85b078d85a71718afba833e7218502a8.yml
openapi_spec_hash: 0e452b918e63bb906a2886dfc2109a82
config_hash: 4267724890db00da87d77d1a951b86f4
39 changes: 39 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,44 @@
# Changelog

## 0.1.0 (2025-05-14)

Full Changelog: [v0.0.2...v0.1.0](https://github.com/OpenExecProtocol/oxp-go/compare/v0.0.2...v0.1.0)

### Features

* **client:** add support for endpoint-specific base URLs in python ([3435e12](https://github.com/OpenExecProtocol/oxp-go/commit/3435e12d250ba62a5fb9d2fba16fe91e97b789e4))
* **client:** add support for reading base URL from environment variable ([da52f00](https://github.com/OpenExecProtocol/oxp-go/commit/da52f0027c05cc6be43fd7293589dfc7ebb14837))
* **client:** support custom http clients ([#11](https://github.com/OpenExecProtocol/oxp-go/issues/11)) ([b7b678c](https://github.com/OpenExecProtocol/oxp-go/commit/b7b678c5f4d9c146dd23871c0662b9ef5403ad5b))


### Bug Fixes

* **client:** clean up reader resources ([02e8b5f](https://github.com/OpenExecProtocol/oxp-go/commit/02e8b5fb02559a8c9add291312b9f9877cae7f53))
* **client:** correctly update body in WithJSONSet ([3190e17](https://github.com/OpenExecProtocol/oxp-go/commit/3190e17794373f3889eb2c28c8c0f90de3fd3ac4))
* **client:** return error on bad custom url instead of panic ([#10](https://github.com/OpenExecProtocol/oxp-go/issues/10)) ([8edf5ec](https://github.com/OpenExecProtocol/oxp-go/commit/8edf5eced0206863e5ae85870a85cff7e548d087))
* handle empty bodies in WithJSONSet ([43b0734](https://github.com/OpenExecProtocol/oxp-go/commit/43b073417aa7257ab842d7ce7859f29f780905a1))
* pluralize `list` response variables ([#9](https://github.com/OpenExecProtocol/oxp-go/issues/9)) ([2f32d03](https://github.com/OpenExecProtocol/oxp-go/commit/2f32d03bbadb69b873b8c57ac444b09d467d32dc))
* **test:** return early after test failure ([#7](https://github.com/OpenExecProtocol/oxp-go/issues/7)) ([e163f84](https://github.com/OpenExecProtocol/oxp-go/commit/e163f841e7943677016c18bd60f21de10a0eaa0e))


### Chores

* add request options to client tests ([#6](https://github.com/OpenExecProtocol/oxp-go/issues/6)) ([e478bcd](https://github.com/OpenExecProtocol/oxp-go/commit/e478bcd482587882013395d08abd22df061b4d12))
* **ci:** add timeout thresholds for CI jobs ([482d0da](https://github.com/OpenExecProtocol/oxp-go/commit/482d0dac6399b0e7816505e79db2336e7796f43c))
* **ci:** only use depot for staging repos ([142cc65](https://github.com/OpenExecProtocol/oxp-go/commit/142cc659c7157b718fec883d9985c89d8076d2c7))
* **docs:** document pre-request options ([20574c5](https://github.com/OpenExecProtocol/oxp-go/commit/20574c517ada77d8e9cc532842090674609b704e))
* **docs:** improve security documentation ([#4](https://github.com/OpenExecProtocol/oxp-go/issues/4)) ([9a98381](https://github.com/OpenExecProtocol/oxp-go/commit/9a98381e85ec1abb6297303695a01bf5b0bb0806))
* fix typos ([#8](https://github.com/OpenExecProtocol/oxp-go/issues/8)) ([a327a76](https://github.com/OpenExecProtocol/oxp-go/commit/a327a76a39b0c7ea966e429d769f96cda6086c5d))
* **internal:** codegen related update ([63aa3d5](https://github.com/OpenExecProtocol/oxp-go/commit/63aa3d57eb4c8ce13fa441d9e0f416ba8aee5f3e))
* **internal:** codegen related update ([d36116e](https://github.com/OpenExecProtocol/oxp-go/commit/d36116ef0fbe894a5e4e8b23e3c38a8524b4883d))
* **internal:** expand CI branch coverage ([825a88c](https://github.com/OpenExecProtocol/oxp-go/commit/825a88c183de7e804d22b0e0e34531bdddeefe03))
* **internal:** reduce CI branch coverage ([2f052f3](https://github.com/OpenExecProtocol/oxp-go/commit/2f052f3bc440f8df016ec45fd2a324748e427267))


### Documentation

* update documentation links to be more uniform ([04176d5](https://github.com/OpenExecProtocol/oxp-go/commit/04176d5fae7f921179aac873854a2ee02fd09cf0))

## 0.0.2 (2025-03-16)

Full Changelog: [v0.0.1-alpha.0...v0.0.2](https://github.com/OpenExecProtocol/oxp-go/compare/v0.0.1-alpha.0...v0.0.2)
Expand Down
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

<a href="https://pkg.go.dev/github.com/OpenExecProtocol/oxp-go"><img src="https://pkg.go.dev/badge/github.com/OpenExecProtocol/oxp-go.svg" alt="Go Reference"></a>

The Oxp Go library provides convenient access to [the Oxp REST
API](https://openexecprotocol.org) from applications written in Go. The full API of this library can be found in [api.md](api.md).
The Oxp Go library provides convenient access to the [Oxp REST API](https://openexecprotocol.org)
from applications written in Go.

It is generated with [Stainless](https://www.stainless.com/).

Expand All @@ -24,7 +24,7 @@ Or to pin the version:
<!-- x-release-please-start-version -->

```sh
go get -u 'github.com/OpenExecProtocol/oxp-go@v0.0.2'
go get -u 'github.com/OpenExecProtocol/oxp-go@v0.1.0'
```

<!-- x-release-please-end -->
Expand Down Expand Up @@ -52,11 +52,11 @@ func main() {
client := oxp.NewClient(
option.WithBearerToken("My Bearer Token"), // defaults to os.LookupEnv("OXP_API_KEY")
)
tool, err := client.Tools.List(context.TODO(), oxp.ToolListParams{})
tools, err := client.Tools.List(context.TODO(), oxp.ToolListParams{})
if err != nil {
panic(err.Error())
}
fmt.Printf("%+v\n", tool.Items)
fmt.Printf("%+v\n", tools.Items)
}

```
Expand Down Expand Up @@ -250,15 +250,15 @@ you need to examine response headers, status codes, or other details.
```go
// Create a variable to store the HTTP response
var response *http.Response
tool, err := client.Tools.List(
tools, err := client.Tools.List(
context.TODO(),
oxp.ToolListParams{},
option.WithResponseInto(&response),
)
if err != nil {
// handle error
}
fmt.Printf("%+v\n", tool)
fmt.Printf("%+v\n", tools)

fmt.Printf("Status Code: %d\n", response.StatusCode)
fmt.Printf("Headers: %+#v\n", response.Header)
Expand Down
13 changes: 8 additions & 5 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,23 @@ type Client struct {
Tools *ToolService
}

// DefaultClientOptions read from the environment (OXP_API_KEY). This should be
// used to initialize new clients.
// DefaultClientOptions read from the environment (OXP_API_KEY, OXP_BASE_URL). This
// should be used to initialize new clients.
func DefaultClientOptions() []option.RequestOption {
defaults := []option.RequestOption{option.WithEnvironmentProduction()}
if o, ok := os.LookupEnv("OXP_BASE_URL"); ok {
defaults = append(defaults, option.WithBaseURL(o))
}
if o, ok := os.LookupEnv("OXP_API_KEY"); ok {
defaults = append(defaults, option.WithBearerToken(o))
}
return defaults
}

// NewClient generates a new client with the default option read from the
// environment (OXP_API_KEY). The option passed in as arguments are applied after
// these default arguments, and all option will be passed down to the services and
// requests that this client makes.
// environment (OXP_API_KEY, OXP_BASE_URL). The option passed in as arguments are
// applied after these default arguments, and all option will be passed down to the
// services and requests that this client makes.
func NewClient(opts ...option.RequestOption) (r *Client) {
opts = append(DefaultClientOptions(), opts...)

Expand Down
8 changes: 8 additions & 0 deletions client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ func (t *closureTransport) RoundTrip(req *http.Request) (*http.Response, error)
func TestUserAgentHeader(t *testing.T) {
var userAgent string
client := oxp.NewClient(
option.WithBearerToken("My Bearer Token"),
option.WithHTTPClient(&http.Client{
Transport: &closureTransport{
fn: func(req *http.Request) (*http.Response, error) {
Expand All @@ -46,6 +47,7 @@ func TestUserAgentHeader(t *testing.T) {
func TestRetryAfter(t *testing.T) {
retryCountHeaders := make([]string, 0)
client := oxp.NewClient(
option.WithBearerToken("My Bearer Token"),
option.WithHTTPClient(&http.Client{
Transport: &closureTransport{
fn: func(req *http.Request) (*http.Response, error) {
Expand Down Expand Up @@ -79,6 +81,7 @@ func TestRetryAfter(t *testing.T) {
func TestDeleteRetryCountHeader(t *testing.T) {
retryCountHeaders := make([]string, 0)
client := oxp.NewClient(
option.WithBearerToken("My Bearer Token"),
option.WithHTTPClient(&http.Client{
Transport: &closureTransport{
fn: func(req *http.Request) (*http.Response, error) {
Expand Down Expand Up @@ -108,6 +111,7 @@ func TestDeleteRetryCountHeader(t *testing.T) {
func TestOverwriteRetryCountHeader(t *testing.T) {
retryCountHeaders := make([]string, 0)
client := oxp.NewClient(
option.WithBearerToken("My Bearer Token"),
option.WithHTTPClient(&http.Client{
Transport: &closureTransport{
fn: func(req *http.Request) (*http.Response, error) {
Expand Down Expand Up @@ -137,6 +141,7 @@ func TestOverwriteRetryCountHeader(t *testing.T) {
func TestRetryAfterMs(t *testing.T) {
attempts := 0
client := oxp.NewClient(
option.WithBearerToken("My Bearer Token"),
option.WithHTTPClient(&http.Client{
Transport: &closureTransport{
fn: func(req *http.Request) (*http.Response, error) {
Expand All @@ -162,6 +167,7 @@ func TestRetryAfterMs(t *testing.T) {

func TestContextCancel(t *testing.T) {
client := oxp.NewClient(
option.WithBearerToken("My Bearer Token"),
option.WithHTTPClient(&http.Client{
Transport: &closureTransport{
fn: func(req *http.Request) (*http.Response, error) {
Expand All @@ -181,6 +187,7 @@ func TestContextCancel(t *testing.T) {

func TestContextCancelDelay(t *testing.T) {
client := oxp.NewClient(
option.WithBearerToken("My Bearer Token"),
option.WithHTTPClient(&http.Client{
Transport: &closureTransport{
fn: func(req *http.Request) (*http.Response, error) {
Expand Down Expand Up @@ -208,6 +215,7 @@ func TestContextDeadline(t *testing.T) {

go func() {
client := oxp.NewClient(
option.WithBearerToken("My Bearer Token"),
option.WithHTTPClient(&http.Client{
Transport: &closureTransport{
fn: func(req *http.Request) (*http.Response, error) {
Expand Down
52 changes: 44 additions & 8 deletions internal/requestconfig/requestconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,12 @@ func UseDefaultParam[T any](dst *param.Field[T], src *T) {
}
}

// This interface is primarily used to describe an [*http.Client], but also
// supports custom HTTP implementations.
type HTTPDoer interface {
Do(req *http.Request) (*http.Response, error)
}

// RequestConfig represents all the state related to one request.
//
// Editing the variables inside RequestConfig directly is unstable api. Prefer
Expand All @@ -202,6 +208,10 @@ type RequestConfig struct {
Context context.Context
Request *http.Request
BaseURL *url.URL
// DefaultBaseURL will be used if BaseURL is not explicitly overridden using
// WithBaseURL.
DefaultBaseURL *url.URL
CustomHTTPDoer HTTPDoer
HTTPClient *http.Client
Middlewares []middleware
BearerToken string
Expand Down Expand Up @@ -241,7 +251,7 @@ func shouldRetry(req *http.Request, res *http.Response) bool {
return true
}

// If the header explictly wants a retry behavior, respect that over the
// If the header explicitly wants a retry behavior, respect that over the
// http status code.
if res.Header.Get("x-should-retry") == "true" {
return true
Expand Down Expand Up @@ -367,7 +377,11 @@ func retryDelay(res *http.Response, retryCount int) time.Duration {

func (cfg *RequestConfig) Execute() (err error) {
if cfg.BaseURL == nil {
return fmt.Errorf("requestconfig: base url is not set")
if cfg.DefaultBaseURL != nil {
cfg.BaseURL = cfg.DefaultBaseURL
} else {
return fmt.Errorf("requestconfig: base url is not set")
}
}

cfg.Request.URL, err = cfg.BaseURL.Parse(strings.TrimLeft(cfg.Request.URL.String(), "/"))
Expand Down Expand Up @@ -399,6 +413,9 @@ func (cfg *RequestConfig) Execute() (err error) {
}

handler := cfg.HTTPClient.Do
if cfg.CustomHTTPDoer != nil {
handler = cfg.CustomHTTPDoer.Do
}
for i := len(cfg.Middlewares) - 1; i >= 0; i -= 1 {
handler = applyMiddleware(cfg.Middlewares[i], handler)
}
Expand Down Expand Up @@ -498,6 +515,7 @@ func (cfg *RequestConfig) Execute() (err error) {
}

contents, err := io.ReadAll(res.Body)
res.Body.Close()
if err != nil {
return fmt.Errorf("error reading response body: %w", err)
}
Expand Down Expand Up @@ -579,17 +597,35 @@ func (cfg *RequestConfig) Apply(opts ...RequestOption) error {
return nil
}

// PreRequestOptions is used to collect all the options which need to be known before
// a call to [RequestConfig.ExecuteNewRequest], such as path parameters
// or global defaults.
// PreRequestOptions will return a [RequestConfig] with the options applied.
//
// Only request option functions of type [PreRequestOptionFunc] are applied.
func PreRequestOptions(opts ...RequestOption) (RequestConfig, error) {
cfg := RequestConfig{}
for _, opt := range opts {
if _, ok := opt.(PreRequestOptionFunc); !ok {
continue
if opt, ok := opt.(PreRequestOptionFunc); ok {
err := opt.Apply(&cfg)
if err != nil {
return cfg, err
}
}
}
return cfg, nil
}

err := opt.Apply(&cfg)
// WithDefaultBaseURL returns a RequestOption that sets the client's default Base URL.
// This is always overridden by setting a base URL with WithBaseURL.
// WithBaseURL should be used instead of WithDefaultBaseURL except in internal code.
func WithDefaultBaseURL(baseURL string) RequestOption {
u, err := url.Parse(baseURL)
return RequestOptionFunc(func(r *RequestConfig) error {
if err != nil {
return cfg, err
return err
}
}
return cfg, nil
r.DefaultBaseURL = u
return nil
})
}
2 changes: 1 addition & 1 deletion internal/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

package internal

const PackageVersion = "0.0.2" // x-release-please-version
const PackageVersion = "0.1.0" // x-release-please-version
Loading