Skip to content

Commit da29529

Browse files
feat(api): add file content endpoint (#198)
1 parent c09f4be commit da29529

File tree

8 files changed

+278
-1
lines changed

8 files changed

+278
-1
lines changed

.stats.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
configured_endpoints: 60
1+
configured_endpoints: 61
22
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai-6204952a29973265b9c0d66fc67ffaf53c6a90ae4d75cdacf9d147676f5274c9.yml
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
// File generated from our OpenAPI spec by Stainless.
2+
3+
package com.openai.models
4+
5+
import com.openai.core.NoAutoDetect
6+
import com.openai.core.Params
7+
import com.openai.core.checkRequired
8+
import com.openai.core.http.Headers
9+
import com.openai.core.http.QueryParams
10+
import java.util.Objects
11+
12+
/** Returns the contents of the specified file. */
13+
class FileContentParams
14+
private constructor(
15+
private val fileId: String,
16+
private val additionalHeaders: Headers,
17+
private val additionalQueryParams: QueryParams,
18+
) : Params {
19+
20+
fun fileId(): String = fileId
21+
22+
fun _additionalHeaders(): Headers = additionalHeaders
23+
24+
fun _additionalQueryParams(): QueryParams = additionalQueryParams
25+
26+
override fun _headers(): Headers = additionalHeaders
27+
28+
override fun _queryParams(): QueryParams = additionalQueryParams
29+
30+
fun getPathParam(index: Int): String {
31+
return when (index) {
32+
0 -> fileId
33+
else -> ""
34+
}
35+
}
36+
37+
fun toBuilder() = Builder().from(this)
38+
39+
companion object {
40+
41+
@JvmStatic fun builder() = Builder()
42+
}
43+
44+
/** A builder for [FileContentParams]. */
45+
@NoAutoDetect
46+
class Builder internal constructor() {
47+
48+
private var fileId: String? = null
49+
private var additionalHeaders: Headers.Builder = Headers.builder()
50+
private var additionalQueryParams: QueryParams.Builder = QueryParams.builder()
51+
52+
@JvmSynthetic
53+
internal fun from(fileContentParams: FileContentParams) = apply {
54+
fileId = fileContentParams.fileId
55+
additionalHeaders = fileContentParams.additionalHeaders.toBuilder()
56+
additionalQueryParams = fileContentParams.additionalQueryParams.toBuilder()
57+
}
58+
59+
fun fileId(fileId: String) = apply { this.fileId = fileId }
60+
61+
fun additionalHeaders(additionalHeaders: Headers) = apply {
62+
this.additionalHeaders.clear()
63+
putAllAdditionalHeaders(additionalHeaders)
64+
}
65+
66+
fun additionalHeaders(additionalHeaders: Map<String, Iterable<String>>) = apply {
67+
this.additionalHeaders.clear()
68+
putAllAdditionalHeaders(additionalHeaders)
69+
}
70+
71+
fun putAdditionalHeader(name: String, value: String) = apply {
72+
additionalHeaders.put(name, value)
73+
}
74+
75+
fun putAdditionalHeaders(name: String, values: Iterable<String>) = apply {
76+
additionalHeaders.put(name, values)
77+
}
78+
79+
fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply {
80+
this.additionalHeaders.putAll(additionalHeaders)
81+
}
82+
83+
fun putAllAdditionalHeaders(additionalHeaders: Map<String, Iterable<String>>) = apply {
84+
this.additionalHeaders.putAll(additionalHeaders)
85+
}
86+
87+
fun replaceAdditionalHeaders(name: String, value: String) = apply {
88+
additionalHeaders.replace(name, value)
89+
}
90+
91+
fun replaceAdditionalHeaders(name: String, values: Iterable<String>) = apply {
92+
additionalHeaders.replace(name, values)
93+
}
94+
95+
fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply {
96+
this.additionalHeaders.replaceAll(additionalHeaders)
97+
}
98+
99+
fun replaceAllAdditionalHeaders(additionalHeaders: Map<String, Iterable<String>>) = apply {
100+
this.additionalHeaders.replaceAll(additionalHeaders)
101+
}
102+
103+
fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) }
104+
105+
fun removeAllAdditionalHeaders(names: Set<String>) = apply {
106+
additionalHeaders.removeAll(names)
107+
}
108+
109+
fun additionalQueryParams(additionalQueryParams: QueryParams) = apply {
110+
this.additionalQueryParams.clear()
111+
putAllAdditionalQueryParams(additionalQueryParams)
112+
}
113+
114+
fun additionalQueryParams(additionalQueryParams: Map<String, Iterable<String>>) = apply {
115+
this.additionalQueryParams.clear()
116+
putAllAdditionalQueryParams(additionalQueryParams)
117+
}
118+
119+
fun putAdditionalQueryParam(key: String, value: String) = apply {
120+
additionalQueryParams.put(key, value)
121+
}
122+
123+
fun putAdditionalQueryParams(key: String, values: Iterable<String>) = apply {
124+
additionalQueryParams.put(key, values)
125+
}
126+
127+
fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply {
128+
this.additionalQueryParams.putAll(additionalQueryParams)
129+
}
130+
131+
fun putAllAdditionalQueryParams(additionalQueryParams: Map<String, Iterable<String>>) =
132+
apply {
133+
this.additionalQueryParams.putAll(additionalQueryParams)
134+
}
135+
136+
fun replaceAdditionalQueryParams(key: String, value: String) = apply {
137+
additionalQueryParams.replace(key, value)
138+
}
139+
140+
fun replaceAdditionalQueryParams(key: String, values: Iterable<String>) = apply {
141+
additionalQueryParams.replace(key, values)
142+
}
143+
144+
fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply {
145+
this.additionalQueryParams.replaceAll(additionalQueryParams)
146+
}
147+
148+
fun replaceAllAdditionalQueryParams(additionalQueryParams: Map<String, Iterable<String>>) =
149+
apply {
150+
this.additionalQueryParams.replaceAll(additionalQueryParams)
151+
}
152+
153+
fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) }
154+
155+
fun removeAllAdditionalQueryParams(keys: Set<String>) = apply {
156+
additionalQueryParams.removeAll(keys)
157+
}
158+
159+
fun build(): FileContentParams =
160+
FileContentParams(
161+
checkRequired("fileId", fileId),
162+
additionalHeaders.build(),
163+
additionalQueryParams.build(),
164+
)
165+
}
166+
167+
override fun equals(other: Any?): Boolean {
168+
if (this === other) {
169+
return true
170+
}
171+
172+
return /* spotless:off */ other is FileContentParams && fileId == other.fileId && additionalHeaders == other.additionalHeaders && additionalQueryParams == other.additionalQueryParams /* spotless:on */
173+
}
174+
175+
override fun hashCode(): Int = /* spotless:off */ Objects.hash(fileId, additionalHeaders, additionalQueryParams) /* spotless:on */
176+
177+
override fun toString() =
178+
"FileContentParams{fileId=$fileId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}"
179+
}

openai-java-core/src/main/kotlin/com/openai/services/async/FileServiceAsync.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
package com.openai.services.async
66

77
import com.openai.core.RequestOptions
8+
import com.openai.core.http.HttpResponse
9+
import com.openai.models.FileContentParams
810
import com.openai.models.FileDeleteParams
911
import com.openai.models.FileDeleted
1012
import com.openai.models.FileListPageAsync
@@ -35,4 +37,11 @@ interface FileServiceAsync {
3537
params: FileDeleteParams,
3638
requestOptions: RequestOptions = RequestOptions.none()
3739
): CompletableFuture<FileDeleted>
40+
41+
/** Returns the contents of the specified file. */
42+
@JvmOverloads
43+
fun content(
44+
params: FileContentParams,
45+
requestOptions: RequestOptions = RequestOptions.none()
46+
): CompletableFuture<HttpResponse>
3847
}

openai-java-core/src/main/kotlin/com/openai/services/async/FileServiceAsyncImpl.kt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@ import com.openai.core.handlers.jsonHandler
99
import com.openai.core.handlers.withErrorHandler
1010
import com.openai.core.http.HttpMethod
1111
import com.openai.core.http.HttpRequest
12+
import com.openai.core.http.HttpResponse
1213
import com.openai.core.http.HttpResponse.Handler
1314
import com.openai.core.json
1415
import com.openai.core.prepareAsync
1516
import com.openai.errors.OpenAIError
17+
import com.openai.models.FileContentParams
1618
import com.openai.models.FileDeleteParams
1719
import com.openai.models.FileDeleted
1820
import com.openai.models.FileListPageAsync
@@ -111,4 +113,20 @@ internal constructor(
111113
}
112114
}
113115
}
116+
117+
/** Returns the contents of the specified file. */
118+
override fun content(
119+
params: FileContentParams,
120+
requestOptions: RequestOptions
121+
): CompletableFuture<HttpResponse> {
122+
val request =
123+
HttpRequest.builder()
124+
.method(HttpMethod.GET)
125+
.addPathSegments("files", params.getPathParam(0), "content")
126+
.build()
127+
.prepareAsync(clientOptions, params)
128+
return request.thenComposeAsync {
129+
clientOptions.httpClient.executeAsync(it, requestOptions)
130+
}
131+
}
114132
}

openai-java-core/src/main/kotlin/com/openai/services/blocking/FileService.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
package com.openai.services.blocking
66

77
import com.openai.core.RequestOptions
8+
import com.openai.core.http.HttpResponse
9+
import com.openai.models.FileContentParams
810
import com.openai.models.FileDeleteParams
911
import com.openai.models.FileDeleted
1012
import com.openai.models.FileListPage
@@ -34,4 +36,11 @@ interface FileService {
3436
params: FileDeleteParams,
3537
requestOptions: RequestOptions = RequestOptions.none()
3638
): FileDeleted
39+
40+
/** Returns the contents of the specified file. */
41+
@JvmOverloads
42+
fun content(
43+
params: FileContentParams,
44+
requestOptions: RequestOptions = RequestOptions.none()
45+
): HttpResponse
3746
}

openai-java-core/src/main/kotlin/com/openai/services/blocking/FileServiceImpl.kt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@ import com.openai.core.handlers.jsonHandler
99
import com.openai.core.handlers.withErrorHandler
1010
import com.openai.core.http.HttpMethod
1111
import com.openai.core.http.HttpRequest
12+
import com.openai.core.http.HttpResponse
1213
import com.openai.core.http.HttpResponse.Handler
1314
import com.openai.core.json
1415
import com.openai.core.prepare
1516
import com.openai.errors.OpenAIError
17+
import com.openai.models.FileContentParams
1618
import com.openai.models.FileDeleteParams
1719
import com.openai.models.FileDeleted
1820
import com.openai.models.FileListPage
@@ -94,4 +96,15 @@ internal constructor(
9496
}
9597
}
9698
}
99+
100+
/** Returns the contents of the specified file. */
101+
override fun content(params: FileContentParams, requestOptions: RequestOptions): HttpResponse {
102+
val request =
103+
HttpRequest.builder()
104+
.method(HttpMethod.GET)
105+
.addPathSegments("files", params.getPathParam(0), "content")
106+
.build()
107+
.prepare(clientOptions, params)
108+
return clientOptions.httpClient.execute(request, requestOptions)
109+
}
97110
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// File generated from our OpenAPI spec by Stainless.
2+
3+
package com.openai.models
4+
5+
import org.assertj.core.api.Assertions.assertThat
6+
import org.junit.jupiter.api.Test
7+
8+
class FileContentParamsTest {
9+
10+
@Test
11+
fun createFileContentParams() {
12+
FileContentParams.builder().fileId("file_id").build()
13+
}
14+
15+
@Test
16+
fun getPathParam() {
17+
val params = FileContentParams.builder().fileId("file_id").build()
18+
assertThat(params).isNotNull
19+
// path param "fileId"
20+
assertThat(params.getPathParam(0)).isEqualTo("file_id")
21+
// out-of-bound path param
22+
assertThat(params.getPathParam(1)).isEqualTo("")
23+
}
24+
}

openai-java-core/src/test/kotlin/com/openai/services/blocking/FileServiceTest.kt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,25 @@
22

33
package com.openai.services.blocking
44

5+
import com.github.tomakehurst.wiremock.client.WireMock.anyUrl
6+
import com.github.tomakehurst.wiremock.client.WireMock.get
7+
import com.github.tomakehurst.wiremock.client.WireMock.ok
8+
import com.github.tomakehurst.wiremock.client.WireMock.stubFor
9+
import com.github.tomakehurst.wiremock.junit5.WireMockRuntimeInfo
10+
import com.github.tomakehurst.wiremock.junit5.WireMockTest
511
import com.openai.TestServerExtension
612
import com.openai.client.okhttp.OpenAIOkHttpClient
13+
import com.openai.core.http.HttpResponse
14+
import com.openai.models.FileContentParams
715
import com.openai.models.FileDeleteParams
816
import com.openai.models.FileListParams
917
import com.openai.models.FileRetrieveParams
18+
import org.assertj.core.api.Assertions.assertThat
1019
import org.junit.jupiter.api.Test
1120
import org.junit.jupiter.api.extension.ExtendWith
1221

1322
@ExtendWith(TestServerExtension::class)
23+
@WireMockTest
1424
class FileServiceTest {
1525

1626
@Test
@@ -52,4 +62,19 @@ class FileServiceTest {
5262
println(fileDeleted)
5363
fileDeleted.validate()
5464
}
65+
66+
@Test
67+
fun callContent(wmRuntimeInfo: WireMockRuntimeInfo) {
68+
val client =
69+
OpenAIOkHttpClient.builder()
70+
.baseUrl(wmRuntimeInfo.getHttpBaseUrl())
71+
.apiKey("My API Key")
72+
.build()
73+
stubFor(get(anyUrl()).willReturn(ok().withBody("abc")))
74+
val fileService = client.files()
75+
val response = fileService.content(FileContentParams.builder().fileId("file_id").build())
76+
println(response)
77+
assertThat(response).isInstanceOf(HttpResponse::class.java)
78+
assertThat(response.body()).hasContent("abc")
79+
}
5580
}

0 commit comments

Comments
 (0)