Skip to content

Commit 8f3657f

Browse files
release: 5.3.0 (#466)
* docs: update documentation links to be more uniform * docs(client): update jackson compat error message * docs: explain jackson compat in readme * perf(internal): improve compilation+test speed * docs: explain http client customization * feat(api): api update * codegen metadata * release: 5.3.0 --------- Co-authored-by: stainless-app[bot] <142633134+stainless-app[bot]@users.noreply.github.com>
1 parent 1fb3167 commit 8f3657f

File tree

19 files changed

+176
-107
lines changed

19 files changed

+176
-107
lines changed

.github/workflows/publish-sonatype.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ jobs:
3333
export -- GPG_SIGNING_KEY_ID
3434
printenv -- GPG_SIGNING_KEY | gpg --batch --passphrase-fd 3 --import 3<<< "$GPG_SIGNING_PASSWORD"
3535
GPG_SIGNING_KEY_ID="$(gpg --with-colons --list-keys | awk -F : -- '/^pub:/ { getline; print "0x" substr($10, length($10) - 7) }')"
36-
./gradlew publishAndReleaseToMavenCentral --stacktrace -PmavenCentralUsername="$SONATYPE_USERNAME" -PmavenCentralPassword="$SONATYPE_PASSWORD"
36+
./gradlew publishAndReleaseToMavenCentral --stacktrace -PmavenCentralUsername="$SONATYPE_USERNAME" -PmavenCentralPassword="$SONATYPE_PASSWORD" --no-configuration-cache
3737
env:
3838
SONATYPE_USERNAME: ${{ secrets.FINCH_SONATYPE_USERNAME || secrets.SONATYPE_USERNAME }}
3939
SONATYPE_PASSWORD: ${{ secrets.FINCH_SONATYPE_PASSWORD || secrets.SONATYPE_PASSWORD }}

.release-please-manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
".": "5.2.0"
2+
".": "5.3.0"
33
}

.stats.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
configured_endpoints: 45
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/finch%2Ffinch-ff61a38530dfae03860bceb49379e84bfc7434eeb5d2f1dc9677cb162014faf1.yml
3-
openapi_spec_hash: df3bdaf4acf575bb07767cae7ca24d69
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/finch%2Ffinch-46640c1b468813b828be61b1af5cb5450f9555c4c757c5a740189906a8d56672.yml
3+
openapi_spec_hash: 1d5845ae61d2c0a143db43d579b048c5
44
config_hash: 53778a0b839c4f6ad34fbba051f5e8a6

CHANGELOG.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,26 @@
11
# Changelog
22

3+
## 5.3.0 (2025-04-18)
4+
5+
Full Changelog: [v5.2.0...v5.3.0](https://github.com/Finch-API/finch-api-kotlin/compare/v5.2.0...v5.3.0)
6+
7+
### Features
8+
9+
* **api:** api update ([925bbef](https://github.com/Finch-API/finch-api-kotlin/commit/925bbef7b02aa1491f2a74cf773272c9ae2a03ad))
10+
11+
12+
### Performance Improvements
13+
14+
* **internal:** improve compilation+test speed ([d02a977](https://github.com/Finch-API/finch-api-kotlin/commit/d02a9774127d594c1298887d5a3a559588772114))
15+
16+
17+
### Documentation
18+
19+
* **client:** update jackson compat error message ([7ed0ef6](https://github.com/Finch-API/finch-api-kotlin/commit/7ed0ef6f37865422c4106ac2522462acca655909))
20+
* explain http client customization ([56d4a3e](https://github.com/Finch-API/finch-api-kotlin/commit/56d4a3e3613e8c7610153df6c17dcc7adf168faa))
21+
* explain jackson compat in readme ([a398943](https://github.com/Finch-API/finch-api-kotlin/commit/a3989439c70f8d2fd9b0b627e11ed77f59403243))
22+
* update documentation links to be more uniform ([362f869](https://github.com/Finch-API/finch-api-kotlin/commit/362f869d455eeebc71b5bf2d772a1a37d1221ce5))
23+
324
## 5.2.0 (2025-04-12)
425

526
Full Changelog: [v5.1.0...v5.2.0](https://github.com/Finch-API/finch-api-kotlin/compare/v5.1.0...v5.2.0)

README.md

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
<!-- x-release-please-start-version -->
44

5-
[![Maven Central](https://img.shields.io/maven-central/v/com.tryfinch.api/finch-kotlin)](https://central.sonatype.com/artifact/com.tryfinch.api/finch-kotlin/5.2.0)
6-
[![javadoc](https://javadoc.io/badge2/com.tryfinch.api/finch-kotlin/5.2.0/javadoc.svg)](https://javadoc.io/doc/com.tryfinch.api/finch-kotlin/5.2.0)
5+
[![Maven Central](https://img.shields.io/maven-central/v/com.tryfinch.api/finch-kotlin)](https://central.sonatype.com/artifact/com.tryfinch.api/finch-kotlin/5.3.0)
6+
[![javadoc](https://javadoc.io/badge2/com.tryfinch.api/finch-kotlin/5.3.0/javadoc.svg)](https://javadoc.io/doc/com.tryfinch.api/finch-kotlin/5.3.0)
77

88
<!-- x-release-please-end -->
99

@@ -15,7 +15,7 @@ It is generated with [Stainless](https://www.stainless.com/).
1515

1616
<!-- x-release-please-start-version -->
1717

18-
The REST API documentation can be found on [developer.tryfinch.com](https://developer.tryfinch.com/). KDocs are also available on [javadoc.io](https://javadoc.io/doc/com.tryfinch.api/finch-kotlin/5.2.0).
18+
The REST API documentation can be found on [developer.tryfinch.com](https://developer.tryfinch.com/). KDocs are available on [javadoc.io](https://javadoc.io/doc/com.tryfinch.api/finch-kotlin/5.3.0).
1919

2020
<!-- x-release-please-end -->
2121

@@ -26,7 +26,7 @@ The REST API documentation can be found on [developer.tryfinch.com](https://deve
2626
### Gradle
2727

2828
```kotlin
29-
implementation("com.tryfinch.api:finch-kotlin:5.2.0")
29+
implementation("com.tryfinch.api:finch-kotlin:5.3.0")
3030
```
3131

3232
### Maven
@@ -35,7 +35,7 @@ implementation("com.tryfinch.api:finch-kotlin:5.2.0")
3535
<dependency>
3636
<groupId>com.tryfinch.api</groupId>
3737
<artifactId>finch-kotlin</artifactId>
38-
<version>5.2.0</version>
38+
<version>5.3.0</version>
3939
</dependency>
4040
```
4141

@@ -288,6 +288,17 @@ both of which will raise an error if the signature is invalid.
288288
Note that the "body" parameter must be the raw JSON string sent from the server (do not parse it first).
289289
The `.unwrap()` method can parse this JSON for you.
290290

291+
## Jackson
292+
293+
The SDK depends on [Jackson](https://github.com/FasterXML/jackson) for JSON serialization/deserialization. It is compatible with version 2.13.4 or higher, but depends on version 2.18.2 by default.
294+
295+
The SDK throws an exception if it detects an incompatible Jackson version at runtime (e.g. if the default version was overridden in your Maven or Gradle config).
296+
297+
If the SDK threw an exception, but you're _certain_ the version is compatible, then disable the version check using the `checkJacksonVersionCompatibility` on [`FinchOkHttpClient`](finch-kotlin-client-okhttp/src/main/kotlin/com/tryfinch/api/client/okhttp/FinchOkHttpClient.kt) or [`FinchOkHttpClientAsync`](finch-kotlin-client-okhttp/src/main/kotlin/com/tryfinch/api/client/okhttp/FinchOkHttpClientAsync.kt).
298+
299+
> [!CAUTION]
300+
> We make no guarantee that the SDK works correctly when the Jackson version check is disabled.
301+
291302
## Network options
292303

293304
### Retries
@@ -365,6 +376,42 @@ val client: FinchClient = FinchOkHttpClient.builder()
365376
.build()
366377
```
367378

379+
### Custom HTTP client
380+
381+
The SDK consists of three artifacts:
382+
383+
- `finch-kotlin-core`
384+
- Contains core SDK logic
385+
- Does not depend on [OkHttp](https://square.github.io/okhttp)
386+
- Exposes [`FinchClient`](finch-kotlin-core/src/main/kotlin/com/tryfinch/api/client/FinchClient.kt), [`FinchClientAsync`](finch-kotlin-core/src/main/kotlin/com/tryfinch/api/client/FinchClientAsync.kt), [`FinchClientImpl`](finch-kotlin-core/src/main/kotlin/com/tryfinch/api/client/FinchClientImpl.kt), and [`FinchClientAsyncImpl`](finch-kotlin-core/src/main/kotlin/com/tryfinch/api/client/FinchClientAsyncImpl.kt), all of which can work with any HTTP client
387+
- `finch-kotlin-client-okhttp`
388+
- Depends on [OkHttp](https://square.github.io/okhttp)
389+
- Exposes [`FinchOkHttpClient`](finch-kotlin-client-okhttp/src/main/kotlin/com/tryfinch/api/client/okhttp/FinchOkHttpClient.kt) and [`FinchOkHttpClientAsync`](finch-kotlin-client-okhttp/src/main/kotlin/com/tryfinch/api/client/okhttp/FinchOkHttpClientAsync.kt), which provide a way to construct [`FinchClientImpl`](finch-kotlin-core/src/main/kotlin/com/tryfinch/api/client/FinchClientImpl.kt) and [`FinchClientAsyncImpl`](finch-kotlin-core/src/main/kotlin/com/tryfinch/api/client/FinchClientAsyncImpl.kt), respectively, using OkHttp
390+
- `finch-kotlin`
391+
- Depends on and exposes the APIs of both `finch-kotlin-core` and `finch-kotlin-client-okhttp`
392+
- Does not have its own logic
393+
394+
This structure allows replacing the SDK's default HTTP client without pulling in unnecessary dependencies.
395+
396+
#### Customized [`OkHttpClient`](https://square.github.io/okhttp/3.x/okhttp/okhttp3/OkHttpClient.html)
397+
398+
> [!TIP]
399+
> Try the available [network options](#network-options) before replacing the default client.
400+
401+
To use a customized `OkHttpClient`:
402+
403+
1. Replace your [`finch-kotlin` dependency](#installation) with `finch-kotlin-core`
404+
2. Copy `finch-kotlin-client-okhttp`'s [`OkHttpClient`](finch-kotlin-client-okhttp/src/main/kotlin/com/tryfinch/api/client/okhttp/OkHttpClient.kt) class into your code and customize it
405+
3. Construct [`FinchClientImpl`](finch-kotlin-core/src/main/kotlin/com/tryfinch/api/client/FinchClientImpl.kt) or [`FinchClientAsyncImpl`](finch-kotlin-core/src/main/kotlin/com/tryfinch/api/client/FinchClientAsyncImpl.kt), similarly to [`FinchOkHttpClient`](finch-kotlin-client-okhttp/src/main/kotlin/com/tryfinch/api/client/okhttp/FinchOkHttpClient.kt) or [`FinchOkHttpClientAsync`](finch-kotlin-client-okhttp/src/main/kotlin/com/tryfinch/api/client/okhttp/FinchOkHttpClientAsync.kt), using your customized client
406+
407+
### Completely custom HTTP client
408+
409+
To use a completely custom HTTP client:
410+
411+
1. Replace your [`finch-kotlin` dependency](#installation) with `finch-kotlin-core`
412+
2. Write a class that implements the [`HttpClient`](finch-kotlin-core/src/main/kotlin/com/tryfinch/api/core/http/HttpClient.kt) interface
413+
3. Construct [`FinchClientImpl`](finch-kotlin-core/src/main/kotlin/com/tryfinch/api/client/FinchClientImpl.kt) or [`FinchClientAsyncImpl`](finch-kotlin-core/src/main/kotlin/com/tryfinch/api/client/FinchClientAsyncImpl.kt), similarly to [`FinchOkHttpClient`](finch-kotlin-client-okhttp/src/main/kotlin/com/tryfinch/api/client/okhttp/FinchOkHttpClient.kt) or [`FinchOkHttpClientAsync`](finch-kotlin-client-okhttp/src/main/kotlin/com/tryfinch/api/client/okhttp/FinchOkHttpClientAsync.kt), using your new client class
414+
368415
## Undocumented API functionality
369416

370417
The SDK is typed for convenient usage of the documented API. However, it also supports working with undocumented or not yet supported parts of the API.

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ repositories {
88

99
allprojects {
1010
group = "com.tryfinch.api"
11-
version = "5.2.0" // x-release-please-version
11+
version = "5.3.0" // x-release-please-version
1212
}
1313

1414
subprojects {

buildSrc/src/main/kotlin/finch.kotlin.gradle.kts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ plugins {
99

1010
kotlin {
1111
jvmToolchain {
12-
languageVersion.set(JavaLanguageVersion.of(17))
12+
languageVersion.set(JavaLanguageVersion.of(21))
1313
}
1414

1515
compilerOptions {
@@ -19,6 +19,8 @@ kotlin {
1919
// Suppress deprecation warnings because we may still reference and test deprecated members.
2020
// TODO: Replace with `-Xsuppress-warning=DEPRECATION` once we use Kotlin compiler 2.1.0+.
2121
"-nowarn",
22+
// Use as many threads as there are CPU cores on the machine for compilation.
23+
"-Xbackend-threads=0",
2224
)
2325
jvmTarget.set(JvmTarget.JVM_1_8)
2426
languageVersion.set(KotlinVersion.KOTLIN_1_8)
@@ -34,8 +36,7 @@ configure<SpotlessExtension> {
3436
}
3537
}
3638

37-
// Run tests in parallel to some degree.
3839
tasks.withType<Test>().configureEach {
39-
maxParallelForks = (Runtime.getRuntime().availableProcessors() / 2).coerceAtLeast(1)
40-
forkEvery = 100
40+
systemProperty("junit.jupiter.execution.parallel.enabled", true)
41+
systemProperty("junit.jupiter.execution.parallel.mode.default", "concurrent")
4142
}

finch-kotlin-core/src/main/kotlin/com/tryfinch/api/core/Check.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ internal fun checkJacksonVersionCompatibility() {
5252
}
5353
check(incompatibleJacksonVersions.isEmpty()) {
5454
"""
55-
This SDK depends on Jackson version $MINIMUM_JACKSON_VERSION, but the following incompatible Jackson versions were detected at runtime:
55+
This SDK requires a minimum Jackson version of $MINIMUM_JACKSON_VERSION, but the following incompatible Jackson versions were detected at runtime:
5656
5757
${incompatibleJacksonVersions.asSequence().map { (version, incompatibilityReason) ->
5858
"- `${version.toFullString().replace("/", ":")}` ($incompatibilityReason)"
@@ -63,6 +63,8 @@ This can happen if you are either:
6363
2. Depending on some library that depends on different Jackson versions, potentially transitively
6464
6565
Double-check that you are depending on compatible Jackson versions.
66+
67+
See https://www.github.com/Finch-API/finch-api-kotlin#jackson for more information.
6668
"""
6769
.trimIndent()
6870
}

finch-kotlin-core/src/main/kotlin/com/tryfinch/api/core/http/RetryingHttpClient.kt

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import kotlinx.coroutines.delay
2121
class RetryingHttpClient
2222
private constructor(
2323
private val httpClient: HttpClient,
24+
private val sleeper: Sleeper,
2425
private val clock: Clock,
2526
private val maxRetries: Int,
2627
private val idempotencyHeader: String?,
@@ -60,10 +61,10 @@ private constructor(
6061
null
6162
}
6263

63-
val backoffMillis = getRetryBackoffMillis(retries, response)
64+
val backoffDuration = getRetryBackoffDuration(retries, response)
6465
// All responses must be closed, so close the failed one before retrying.
6566
response?.close()
66-
Thread.sleep(backoffMillis.toMillis())
67+
sleeper.sleep(backoffDuration)
6768
}
6869
}
6970

@@ -104,10 +105,10 @@ private constructor(
104105
null
105106
}
106107

107-
val backoffMillis = getRetryBackoffMillis(retries, response)
108+
val backoffDuration = getRetryBackoffDuration(retries, response)
108109
// All responses must be closed, so close the failed one before retrying.
109110
response?.close()
110-
delay(backoffMillis.toKotlinDuration())
111+
sleeper.sleepAsync(backoffDuration)
111112
}
112113
}
113114

@@ -162,7 +163,7 @@ private constructor(
162163
// retried.
163164
throwable is IOException || throwable is FinchIoException
164165

165-
private fun getRetryBackoffMillis(retries: Int, response: HttpResponse?): Duration {
166+
private fun getRetryBackoffDuration(retries: Int, response: HttpResponse?): Duration {
166167
// About the Retry-After header:
167168
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Retry-After
168169
response
@@ -215,12 +216,22 @@ private constructor(
215216
class Builder internal constructor() {
216217

217218
private var httpClient: HttpClient? = null
219+
private var sleeper: Sleeper =
220+
object : Sleeper {
221+
222+
override fun sleep(duration: Duration) = Thread.sleep(duration.toMillis())
223+
224+
override suspend fun sleepAsync(duration: Duration) =
225+
delay(duration.toKotlinDuration())
226+
}
218227
private var clock: Clock = Clock.systemUTC()
219228
private var maxRetries: Int = 2
220229
private var idempotencyHeader: String? = null
221230

222231
fun httpClient(httpClient: HttpClient) = apply { this.httpClient = httpClient }
223232

233+
internal fun sleeper(sleeper: Sleeper) = apply { this.sleeper = sleeper }
234+
224235
fun clock(clock: Clock) = apply { this.clock = clock }
225236

226237
fun maxRetries(maxRetries: Int) = apply { this.maxRetries = maxRetries }
@@ -230,9 +241,17 @@ private constructor(
230241
fun build(): HttpClient =
231242
RetryingHttpClient(
232243
checkRequired("httpClient", httpClient),
244+
sleeper,
233245
clock,
234246
maxRetries,
235247
idempotencyHeader,
236248
)
237249
}
250+
251+
internal interface Sleeper {
252+
253+
fun sleep(duration: Duration)
254+
255+
suspend fun sleepAsync(duration: Duration)
256+
}
238257
}

finch-kotlin-core/src/main/kotlin/com/tryfinch/api/models/Company.kt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,8 @@ private constructor(
129129
fun primaryEmail(): String? = primaryEmail.getNullable("primary_email")
130130

131131
/**
132-
* The phone number of the main administrator on the account. Format: `XXXXXXXXXX`
132+
* The phone number of the main administrator on the account. Format: E.164, with extension
133+
* where applicable, e.g. `+NNNNNNNNNNN xExtension`
133134
*
134135
* @throws FinchInvalidDataException if the JSON field has an unexpected type (e.g. if the
135136
* server responded with an unexpected value).
@@ -405,7 +406,10 @@ private constructor(
405406
this.primaryEmail = primaryEmail
406407
}
407408

408-
/** The phone number of the main administrator on the account. Format: `XXXXXXXXXX` */
409+
/**
410+
* The phone number of the main administrator on the account. Format: E.164, with extension
411+
* where applicable, e.g. `+NNNNNNNNNNN xExtension`
412+
*/
409413
fun primaryPhoneNumber(primaryPhoneNumber: String?) =
410414
primaryPhoneNumber(JsonField.ofNullable(primaryPhoneNumber))
411415

0 commit comments

Comments
 (0)