-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(BE-174): integrate anthropic api
- Loading branch information
Showing
31 changed files
with
315 additions
and
82 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
plugins { | ||
alias(libs.plugins.kotlinx.serialization) | ||
alias(libs.plugins.kover) | ||
// `maven-publish` | ||
} | ||
|
||
kotlin { | ||
jvm() | ||
macosArm64() | ||
macosX64() | ||
|
||
sourceSets { | ||
commonMain.dependencies { | ||
// put your Multiplatform dependencies here | ||
api(libs.kotlinx.serialization.json) | ||
api(libs.bundles.ktor.client) | ||
} | ||
|
||
commonTest.dependencies { | ||
implementation(libs.ktor.client.mock) | ||
} | ||
|
||
macosMain.dependencies { | ||
api(libs.ktor.client.darwin) | ||
} | ||
|
||
jvmMain.dependencies { | ||
api(libs.ktor.client.cio) | ||
} | ||
|
||
jvmTest.dependencies { | ||
implementation(project.dependencies.platform(libs.junit.bom)) | ||
implementation(libs.bundles.jvm.test) | ||
implementation(libs.app.cash.turbine) | ||
implementation("com.tngtech.archunit:archunit-junit5:1.1.0") | ||
implementation("org.reflections:reflections:0.10.2") | ||
} | ||
} | ||
} | ||
|
||
tasks { | ||
named<Test>("jvmTest") { | ||
useJUnitPlatform() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
plugins { | ||
alias(libs.plugins.kover) | ||
// `maven-publish` | ||
} | ||
|
||
kotlin { | ||
jvm() | ||
sourceSets { | ||
commonMain { | ||
dependencies { | ||
api(projects.anthropicClient.anthropicClientCore) | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
plugins { | ||
alias(libs.plugins.kotlinx.serialization) | ||
alias(libs.plugins.kover) | ||
// alias(libs.plugins.touchlab.kmmbridge) | ||
// id("module.publication") | ||
`maven-publish` | ||
} | ||
|
||
kotlin { | ||
jvm() | ||
macosArm64() | ||
macosX64() | ||
|
||
sourceSets { | ||
commonMain.dependencies { | ||
// put your Multiplatform dependencies here | ||
api(libs.kotlinx.serialization.json) | ||
api(libs.bundles.ktor.client) | ||
} | ||
|
||
commonTest.dependencies { | ||
implementation(libs.ktor.client.mock) | ||
} | ||
|
||
macosMain.dependencies { | ||
api(libs.ktor.client.darwin) | ||
} | ||
|
||
jvmMain.dependencies { | ||
api(libs.ktor.client.cio) | ||
} | ||
|
||
jvmTest.dependencies { | ||
implementation(project.dependencies.platform(libs.junit.bom)) | ||
implementation(libs.bundles.jvm.test) | ||
implementation(libs.app.cash.turbine) | ||
implementation("com.tngtech.archunit:archunit-junit5:1.1.0") | ||
implementation("org.reflections:reflections:0.10.2") | ||
} | ||
} | ||
} | ||
|
||
tasks { | ||
named<Test>("jvmTest") { | ||
useJUnitPlatform() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...ddworks/openai/api/common/ListResponse.kt → ...mmon/network/api/ktor/api/ListResponse.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
28 changes: 28 additions & 0 deletions
28
common/src/commonMain/kotlin/com/tddworks/common/network/api/ktor/api/Stream.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package com.tddworks.common.network.api.ktor.api | ||
|
||
import com.tddworks.common.network.api.ktor.internal.JsonLenient | ||
import io.ktor.client.call.* | ||
import io.ktor.client.statement.* | ||
import io.ktor.utils.io.* | ||
import kotlinx.coroutines.flow.FlowCollector | ||
|
||
const val STREAM_PREFIX = "data:" | ||
private const val STREAM_END_TOKEN = "$STREAM_PREFIX [DONE]" | ||
|
||
/** | ||
* Get data as [Server-Sent Events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events#Event_stream_format). | ||
*/ | ||
suspend inline fun <reified T> FlowCollector<T>.streamEventsFrom(response: HttpResponse) { | ||
val channel: ByteReadChannel = response.body() | ||
while (!channel.isClosedForRead) { | ||
channel.readUTF8Line()?.let { streamResponse -> | ||
if (notEndStreamResponse(streamResponse)) { | ||
emit(JsonLenient.decodeFromString(streamResponse.removePrefix(STREAM_PREFIX))) | ||
} | ||
} ?: break | ||
} | ||
} | ||
|
||
private fun isStreamResponse(line: String) = line.startsWith(STREAM_PREFIX) | ||
|
||
fun notEndStreamResponse(line: String) = line != STREAM_END_TOKEN && isStreamResponse(line) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...tddworks/openai/api/common/JsonLenient.kt → .../network/api/ktor/internal/JsonLenient.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...work/ktor/exception/OpenAIAPIException.kt → ...internal/exception/OpenLLMAPIException.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...work/ktor/exception/OpenAIErrorDetails.kt → ...internal/exception/OpenLLMErrorDetails.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...network/ktor/exception/OpenAIException.kt → ...or/internal/exception/OpenLLMException.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...twork/ktor/exception/OpenAIIOException.kt → .../internal/exception/OpenLLMIOException.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
4 changes: 2 additions & 2 deletions
4
.../network/ktor/DefaultHttpRequester.jvm.kt → ...ktor/internal/DefaultHttpRequester.jvm.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
65 changes: 65 additions & 0 deletions
65
common/src/jvmTest/kotlin/com/tddworks/common/network/api/InternalPackageTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package com.tddworks.common.network.api | ||
|
||
import com.tngtech.archunit.core.importer.ClassFileImporter | ||
import com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses | ||
import org.assertj.core.api.Assertions.assertThat | ||
import org.junit.jupiter.api.Test | ||
import org.reflections.Reflections | ||
import org.reflections.scanners.Scanners | ||
import java.io.IOException | ||
|
||
class InternalPackageTest { | ||
|
||
companion object { | ||
private val BASE_PACKAGE = InternalPackageTest::class.java.`package`.name | ||
} | ||
|
||
private val analyzedClasses = ClassFileImporter().importPackages(BASE_PACKAGE) | ||
|
||
@Test | ||
@Throws(IOException::class) | ||
fun internalPackagesAreNotAccessedFromOutside() { | ||
|
||
// so that the test will break when the base package is re-named | ||
assertPackageExists(BASE_PACKAGE) | ||
val internalPackages = internalPackages(BASE_PACKAGE) | ||
for (internalPackage in internalPackages) { | ||
assertPackageExists(internalPackage) | ||
assertPackageIsNotAccessedFromOutside(internalPackage) | ||
} | ||
} | ||
|
||
/** | ||
* Finds all packages named "internal". | ||
*/ | ||
private fun internalPackages(basePackage: String): List<String> { | ||
val scanner = Scanners.SubTypes | ||
val reflections = Reflections(basePackage, scanner) | ||
return reflections.getSubTypesOf(Object::class.java).map { | ||
it.`package`.name | ||
}.filter { | ||
it.endsWith(".internal") | ||
} | ||
} | ||
|
||
private fun assertPackageIsNotAccessedFromOutside(internalPackage: String) { | ||
noClasses() | ||
.that() | ||
.resideOutsideOfPackage(packageMatcher(internalPackage)) | ||
.should() | ||
.dependOnClassesThat() | ||
.resideInAPackage(packageMatcher(internalPackage)) | ||
.check(analyzedClasses) | ||
} | ||
|
||
private fun assertPackageExists(packageName: String?) { | ||
assertThat(analyzedClasses.containPackage(packageName)) | ||
.`as`("package %s exists", packageName) | ||
.isTrue() | ||
} | ||
|
||
private fun packageMatcher(fullyQualifiedPackage: String): String? { | ||
return "$fullyQualifiedPackage.." | ||
} | ||
|
||
} |
23 changes: 23 additions & 0 deletions
23
common/src/jvmTest/kotlin/com/tddworks/common/network/api/JsonUtils.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package com.tddworks.common.network.api | ||
|
||
import kotlinx.serialization.json.Json | ||
|
||
val prettyJson = Json { // this returns the JsonBuilder | ||
prettyPrint = true | ||
ignoreUnknownKeys = true | ||
// optional: specify indent | ||
prettyPrintIndent = " " | ||
} | ||
|
||
/** | ||
* Represents a JSON object that allows for leniency and ignores unknown keys. | ||
* | ||
* @property isLenient Removes JSON specification restriction (RFC-4627) and makes parser more liberal to the malformed input. In lenient mode quoted boolean literals, and unquoted string literals are allowed. | ||
* Its relaxations can be expanded in the future, so that lenient parser becomes even more permissive to invalid value in the input, replacing them with defaults. | ||
* false by default. | ||
* @property ignoreUnknownKeys Specifies whether encounters of unknown properties in the input JSON should be ignored instead of throwing SerializationException. false by default.. | ||
*/ | ||
internal val JsonLenient = Json { | ||
isLenient = true | ||
ignoreUnknownKeys = true | ||
} |
44 changes: 44 additions & 0 deletions
44
common/src/jvmTest/kotlin/com/tddworks/common/network/api/MockHttpClient.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package com.tddworks.common.network.api | ||
|
||
|
||
import io.ktor.client.* | ||
import io.ktor.client.engine.mock.* | ||
import io.ktor.client.plugins.* | ||
import io.ktor.client.plugins.contentnegotiation.* | ||
import io.ktor.client.request.* | ||
import io.ktor.http.* | ||
import io.ktor.serialization.kotlinx.* | ||
|
||
/** | ||
* See https://ktor.io/docs/http-client-testing.html#usage | ||
*/ | ||
fun mockHttpClient(mockResponse: String) = HttpClient(MockEngine) { | ||
|
||
val headers = headersOf("Content-Type" to listOf(ContentType.Application.Json.toString())) | ||
|
||
install(ContentNegotiation) { | ||
register(ContentType.Application.Json, KotlinxSerializationConverter(JsonLenient)) | ||
} | ||
|
||
engine { | ||
addHandler { request -> | ||
if (request.url.encodedPath == "/v1/chat/completions" | ||
|| request.url.encodedPath == "/v1/images/generations" | ||
) { | ||
respond(mockResponse, HttpStatusCode.OK, headers) | ||
} else { | ||
error("Unhandled ${request.url.encodedPath}") | ||
} | ||
} | ||
} | ||
|
||
defaultRequest { | ||
url { | ||
protocol = URLProtocol.HTTPS | ||
host = "api.lemonsqueezy.com" | ||
} | ||
|
||
header(HttpHeaders.ContentType, ContentType.Application.Json) | ||
contentType(ContentType.Application.Json) | ||
} | ||
} |
6 changes: 4 additions & 2 deletions
6
.../network/ktor/DefaultHttpRequesterTest.kt → ...work/api/ktor/DefaultHttpRequesterTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.