Skip to content

Commit c8824de

Browse files
committed
feat: project rate limits data source
1 parent b77d633 commit c8824de

File tree

5 files changed

+274
-0
lines changed

5 files changed

+274
-0
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title: "openai_project_rate_limits Data Source - terraform-provider-openai"
4+
subcategory: ""
5+
description: |-
6+
Returns the rate limits per model for a project.
7+
---
8+
9+
# openai_project_rate_limits (Data Source)
10+
11+
Returns the rate limits per model for a project.
12+
13+
## Example Usage
14+
15+
```terraform
16+
data "openai_project_rate_limits" "example" {
17+
project_id = "proj_000000000000000000000000"
18+
}
19+
```
20+
21+
<!-- schema generated by tfplugindocs -->
22+
## Schema
23+
24+
### Required
25+
26+
- `project_id` (String) The ID of the project.
27+
28+
### Read-Only
29+
30+
- `rate_limits` (Attributes Set) List of users. (see [below for nested schema](#nestedatt--rate_limits))
31+
32+
<a id="nestedatt--rate_limits"></a>
33+
### Nested Schema for `rate_limits`
34+
35+
Read-Only:
36+
37+
- `batch_1_day_max_input_tokens` (Number) The maximum batch input tokens per day. Only present for relevant models.
38+
- `id` (String) The rate limit identifier.
39+
- `max_audio_megabytes_per_1_minute` (Number) The maximum audio megabytes per minute. Only present for relevant models.
40+
- `max_images_per_1_minute` (Number) The maximum images per minute. Only present for relevant models.
41+
- `max_requests_per_1_day` (Number) The maximum requests per day. Only present for relevant models.
42+
- `max_requests_per_1_minute` (Number) The maximum requests per minute.
43+
- `max_tokens_per_1_minute` (Number) The maximum tokens per minute.
44+
- `model` (String) The model this rate limit applies to.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
data "openai_project_rate_limits" "example" {
2+
project_id = "proj_000000000000000000000000"
3+
}
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
package provider
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"net/http"
7+
8+
"github.com/hashicorp/terraform-plugin-framework/datasource"
9+
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
10+
"github.com/hashicorp/terraform-plugin-framework/types"
11+
"github.com/jianyuan/terraform-provider-openai/internal/apiclient"
12+
"github.com/jianyuan/terraform-provider-openai/internal/ptr"
13+
)
14+
15+
type ProjectRateLimitModel struct {
16+
Id types.String `tfsdk:"id"`
17+
Model types.String `tfsdk:"model"`
18+
MaxRequestsPer1Minute types.Int64 `tfsdk:"max_requests_per_1_minute"`
19+
MaxTokensPer1Minute types.Int64 `tfsdk:"max_tokens_per_1_minute"`
20+
MaxImagesPer1Minute types.Int64 `tfsdk:"max_images_per_1_minute"`
21+
MaxAudioMegabytesPer1Minute types.Int64 `tfsdk:"max_audio_megabytes_per_1_minute"`
22+
MaxRequestsPer1Day types.Int64 `tfsdk:"max_requests_per_1_day"`
23+
Batch1DayMaxInputTokens types.Int64 `tfsdk:"batch_1_day_max_input_tokens"`
24+
}
25+
26+
func (m *ProjectRateLimitModel) Fill(rl apiclient.ProjectRateLimit) error {
27+
m.Id = types.StringValue(rl.Id)
28+
m.Model = types.StringValue(rl.Model)
29+
m.MaxRequestsPer1Minute = types.Int64Value(int64(rl.MaxRequestsPer1Minute))
30+
m.MaxTokensPer1Minute = types.Int64Value(int64(rl.MaxTokensPer1Minute))
31+
if rl.MaxImagesPer1Minute == nil {
32+
m.MaxImagesPer1Minute = types.Int64Null()
33+
} else {
34+
m.MaxImagesPer1Minute = types.Int64Value(int64(*rl.MaxImagesPer1Minute))
35+
}
36+
if rl.MaxAudioMegabytesPer1Minute == nil {
37+
m.MaxAudioMegabytesPer1Minute = types.Int64Null()
38+
} else {
39+
m.MaxAudioMegabytesPer1Minute = types.Int64Value(int64(*rl.MaxAudioMegabytesPer1Minute))
40+
}
41+
if rl.MaxRequestsPer1Day == nil {
42+
m.MaxRequestsPer1Day = types.Int64Null()
43+
} else {
44+
m.MaxRequestsPer1Day = types.Int64Value(int64(*rl.MaxRequestsPer1Day))
45+
}
46+
if rl.Batch1DayMaxInputTokens == nil {
47+
m.Batch1DayMaxInputTokens = types.Int64Null()
48+
} else {
49+
m.Batch1DayMaxInputTokens = types.Int64Value(int64(*rl.Batch1DayMaxInputTokens))
50+
}
51+
return nil
52+
}
53+
54+
type ProjectRateLimitsDataSourceModel struct {
55+
ProjectId types.String `tfsdk:"project_id"`
56+
RateLimits []ProjectRateLimitModel `tfsdk:"rate_limits"`
57+
}
58+
59+
func (m *ProjectRateLimitsDataSourceModel) Fill(rateLimits []apiclient.ProjectRateLimit) error {
60+
m.RateLimits = make([]ProjectRateLimitModel, len(rateLimits))
61+
for i, rl := range rateLimits {
62+
if err := m.RateLimits[i].Fill(rl); err != nil {
63+
return err
64+
}
65+
}
66+
return nil
67+
}
68+
69+
var _ datasource.DataSource = &ProjectRateLimitsDataSource{}
70+
71+
func NewProjectRateLimitsDataSource() datasource.DataSource {
72+
return &ProjectRateLimitsDataSource{}
73+
}
74+
75+
type ProjectRateLimitsDataSource struct {
76+
baseDataSource
77+
}
78+
79+
func (d *ProjectRateLimitsDataSource) Metadata(ctx context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
80+
resp.TypeName = req.ProviderTypeName + "_project_rate_limits"
81+
}
82+
83+
func (d *ProjectRateLimitsDataSource) Schema(ctx context.Context, req datasource.SchemaRequest, resp *datasource.SchemaResponse) {
84+
resp.Schema = schema.Schema{
85+
MarkdownDescription: "Returns the rate limits per model for a project.",
86+
87+
Attributes: map[string]schema.Attribute{
88+
"project_id": schema.StringAttribute{
89+
MarkdownDescription: "The ID of the project.",
90+
Required: true,
91+
},
92+
"rate_limits": schema.SetNestedAttribute{
93+
MarkdownDescription: "List of users.",
94+
Computed: true,
95+
NestedObject: schema.NestedAttributeObject{
96+
Attributes: map[string]schema.Attribute{
97+
"id": schema.StringAttribute{
98+
MarkdownDescription: "The rate limit identifier.",
99+
Computed: true,
100+
},
101+
"model": schema.StringAttribute{
102+
MarkdownDescription: "The model this rate limit applies to.",
103+
Computed: true,
104+
},
105+
"max_requests_per_1_minute": schema.Int64Attribute{
106+
MarkdownDescription: "The maximum requests per minute.",
107+
Computed: true,
108+
},
109+
"max_tokens_per_1_minute": schema.Int64Attribute{
110+
MarkdownDescription: "The maximum tokens per minute.",
111+
Computed: true,
112+
},
113+
"max_images_per_1_minute": schema.Int64Attribute{
114+
MarkdownDescription: "The maximum images per minute. Only present for relevant models.",
115+
Computed: true,
116+
},
117+
"max_audio_megabytes_per_1_minute": schema.Int64Attribute{
118+
MarkdownDescription: "The maximum audio megabytes per minute. Only present for relevant models.",
119+
Computed: true,
120+
},
121+
"max_requests_per_1_day": schema.Int64Attribute{
122+
MarkdownDescription: "The maximum requests per day. Only present for relevant models.",
123+
Computed: true,
124+
},
125+
"batch_1_day_max_input_tokens": schema.Int64Attribute{
126+
MarkdownDescription: "The maximum batch input tokens per day. Only present for relevant models.",
127+
Computed: true,
128+
},
129+
},
130+
},
131+
},
132+
},
133+
}
134+
}
135+
136+
func (d *ProjectRateLimitsDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
137+
var data ProjectRateLimitsDataSourceModel
138+
139+
resp.Diagnostics.Append(req.Config.Get(ctx, &data)...)
140+
141+
if resp.Diagnostics.HasError() {
142+
return
143+
}
144+
145+
var rateLimits []apiclient.ProjectRateLimit
146+
params := &apiclient.ListProjectRateLimitsParams{
147+
Limit: ptr.Ptr(100),
148+
}
149+
150+
for {
151+
httpResp, err := d.client.ListProjectRateLimitsWithResponse(
152+
ctx,
153+
data.ProjectId.ValueString(),
154+
params,
155+
)
156+
if err != nil {
157+
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to read, got error: %s", err))
158+
return
159+
}
160+
161+
if httpResp.StatusCode() != http.StatusOK {
162+
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to read, got status code %d: %s", httpResp.StatusCode(), string(httpResp.Body)))
163+
return
164+
}
165+
166+
rateLimits = append(rateLimits, httpResp.JSON200.Data...)
167+
168+
if !httpResp.JSON200.HasMore {
169+
break
170+
}
171+
172+
params.After = &httpResp.JSON200.LastId
173+
}
174+
175+
if err := data.Fill(rateLimits); err != nil {
176+
resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Unable to fill data: %s", err))
177+
return
178+
}
179+
180+
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
181+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package provider
2+
3+
import (
4+
"testing"
5+
6+
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
7+
"github.com/hashicorp/terraform-plugin-testing/knownvalue"
8+
"github.com/hashicorp/terraform-plugin-testing/statecheck"
9+
"github.com/hashicorp/terraform-plugin-testing/tfjsonpath"
10+
"github.com/jianyuan/terraform-provider-openai/internal/acctest"
11+
)
12+
13+
func TestAccProjectRateLimitsDataSource(t *testing.T) {
14+
rn := "data.openai_project_rate_limits.test"
15+
16+
resource.Test(t, resource.TestCase{
17+
PreCheck: func() { acctest.PreCheck(t) },
18+
ProtoV6ProviderFactories: testAccProtoV6ProviderFactories,
19+
Steps: []resource.TestStep{
20+
{
21+
Config: testAccProjectRateLimitsDataSourceConfig,
22+
ConfigStateChecks: []statecheck.StateCheck{
23+
statecheck.ExpectKnownValue(rn, tfjsonpath.New("project_id"), knownvalue.NotNull()),
24+
statecheck.ExpectKnownValue(rn, tfjsonpath.New("rate_limits"), knownvalue.SetPartial([]knownvalue.Check{
25+
knownvalue.ObjectPartial(map[string]knownvalue.Check{
26+
"id": knownvalue.NotNull(),
27+
"model": knownvalue.NotNull(),
28+
"max_requests_per_1_minute": knownvalue.NotNull(),
29+
"max_tokens_per_1_minute": knownvalue.NotNull(),
30+
}),
31+
})),
32+
},
33+
},
34+
},
35+
})
36+
}
37+
38+
var testAccProjectRateLimitsDataSourceConfig = `
39+
data "openai_projects" "test" {
40+
}
41+
42+
data "openai_project_rate_limits" "test" {
43+
project_id = tolist(data.openai_projects.test.projects)[0].id
44+
}
45+
`

internal/provider/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ func (p *OpenAIProvider) DataSources(ctx context.Context) []func() datasource.Da
122122
NewInviteDataSource,
123123
NewInvitesDataSource,
124124
NewProjectDataSource,
125+
NewProjectRateLimitsDataSource,
125126
NewProjectsDataSource,
126127
NewUserDataSource,
127128
NewUsersDataSource,

0 commit comments

Comments
 (0)