nehanims / notes

Backend for voice-notes
0 stars 0 forks source link

Ollama REST Client #34

Open nehanims opened 2 months ago

nehanims commented 2 months ago

Ollama API reference: https://github.com/ollama/ollama/blob/main/docs/api.md Ollama github discussion about the difference between /api/generate and /api/chat, specifically, this comment explaining the difference based on Ollama's implementation of those APIs, and this interesting point about summarization

Someone has published this (possibly older) YAML for Ollama API for use with OpenAPI client code generator. It may be different now so reference the official API docs from Ollama above in case there are errors. And only use the generated code as a reference or/to generate request response body models and such. Edit: Issue to provide an official YAML for codegen integration is open in Ollama's repo :https://github.com/ollama/ollama/issues/3383

Use the declarative HTTPInterface to reduce boilerplate: https://medium.com/digitalfrontiers/declarative-rest-clients-with-spring-framework-6-c671be1dfee https://howtodoinjava.com/spring-webflux/http-declarative-http-client-httpexchange/

Some examples from others using Kotlin to talk to Ollama: UsingOkHttp3 UsingOkHTTP Using springAI

nehanims commented 2 months ago

To build a REST client in a Kotlin Spring Boot application using Spring's HttpExchange library, follow these steps:

1. Add Required Dependencies

Ensure that you have the necessary dependencies in your build.gradle.kts file:

dependencies {
    implementation("org.springframework.boot:spring-boot-starter-web")
    implementation("org.springframework.boot:spring-boot-starter-webflux")
}

2. Enable HTTP Interface

Since Spring 6 introduced the @HttpExchange annotation, you don't need to enable anything explicitly. Just make sure you're using Spring Boot 3 or later, which includes Spring 6.

3. Create an Interface for the API Client

Define an interface to represent your API client. Use the @HttpExchange annotation to declare HTTP requests.

import org.springframework.web.service.annotation.HttpExchange
import org.springframework.web.service.annotation.GetExchange
import org.springframework.web.bind.annotation.RequestHeader
import org.springframework.web.bind.annotation.RequestParam

@HttpExchange("/endpoint")
interface OllamaClient {

    @GetExchange
    fun getSomething(
        @RequestHeader("Authorization") token: String,
        @RequestParam("param1") param1: String,
        @RequestParam("param2") param2: String
    ): ApiResponse
}

In this example:

4. Define a Response Data Class

Define a data class that matches the structure of the API response:

data class ApiResponse(
    val field1: String,
    val field2: Int,
    // other fields...
)

5. Configure the HTTP Client Bean

To create an instance of your API client, you'll need to define a @Bean in a configuration class:

import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.web.reactive.function.client.WebClient
import org.springframework.web.service.invoker.HttpServiceProxyFactory
import org.springframework.web.service.invoker.HttpServiceProxyFactoryBuilder

@Configuration
class OllamaClientConfig {

    @Bean
    fun ollamaClient(): OllamaClient {
        val webClient = WebClient.builder()
            .baseUrl("https://api.ollama.com")
            .build()

        val factory: HttpServiceProxyFactory = HttpServiceProxyFactoryBuilder.builder(WebClient.builder()).build()
        return factory.createClient(OllamaClient::class.java)
    }
}

6. Use the Client in a Service

Inject the OllamaClient into a service class and use it to make API calls:

import org.springframework.stereotype.Service

@Service
class OllamaService(private val ollamaClient: OllamaClient) {

    fun getApiData(param1: String, param2: String): ApiResponse {
        val token = "Bearer your_token_here" // Replace with your actual token or use a more secure approach
        return ollamaClient.getSomething(token, param1, param2)
    }
}

7. Test the Client

Finally, test the client by calling the service method in a controller or a test class:

import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RestController

@RestController
class OllamaController(private val ollamaService: OllamaService) {

    @GetMapping("/api-data")
    fun getApiData(
        @RequestParam param1: String,
        @RequestParam param2: String
    ): ApiResponse {
        return ollamaService.getApiData(param1, param2)
    }
}

Summary

By using Spring's HttpExchange library, you can create a type-safe and declarative HTTP client to interact with external APIs like the Ollama API. This approach is more streamlined and modern compared to older libraries, and it integrates well with the rest of the Spring ecosystem.

nehanims commented 2 months ago

Moshi is a JSON parser for Java/Kotlin (like GSON with some differences). Read details here