Getting Started

ApiKey

You will need to obtain an ApiKey from Unstructured

By default, an apikey is needed to make the client; however, individual requests can also be provided a separate apikey, which will override the default, when passed a header.

Instantiating the Client

In addition to the unstructured4s-core module, you will need to provide an sttp backend, you can use any of the backends provided by sttp as long as you can provide a client with the effect capability F[_] that has a Functor instance (this will typical require some kind of interoperability module with the cats typeclass hierarchy if you aren’t using cats-effect)


First obtain the necessary dependencies for sttp, here are the ones for ZIO:

sbt
libraryDependencies ++= Seq(
  "com.softwaremill.sttp.client3" %% "async-http-client-backend-zio" % "3.9.4",
  "dev.zio" %% "zio-interop-cats" % "23.0.0.8"
)
Maven
<dependencies>
  <dependency>
    <groupId>com.softwaremill.sttp.client3</groupId>
    <artifactId>async-http-client-backend-zio_3</artifactId>
    <version>3.9.4</version>
  </dependency>
  <dependency>
    <groupId>dev.zio</groupId>
    <artifactId>zio-interop-cats_3</artifactId>
    <version>23.0.0.8</version>
  </dependency>
</dependencies>
Gradle
dependencies {
  implementation "com.softwaremill.sttp.client3:async-http-client-backend-zio_3:3.9.4"
  implementation "dev.zio:zio-interop-cats_3:23.0.0.8"
}

Here is the one for the fs2 backend:

sbt
libraryDependencies += "com.softwaremill.sttp.client3" %% "async-http-client-backend-fs2" % "3.9.4"
Maven
<dependencies>
  <dependency>
    <groupId>com.softwaremill.sttp.client3</groupId>
    <artifactId>async-http-client-backend-fs2_3</artifactId>
    <version>3.9.4</version>
  </dependency>
</dependencies>
Gradle
dependencies {
  implementation "com.softwaremill.sttp.client3:async-http-client-backend-fs2_3:3.9.4"
}

To instantiate the client, first include these imports:

import org.twelvehart.unstructured4s.*
import org.twelvehart.unstructured4s.model.*
import sttp.client3.*

Next, declare the backend and retrieve the apikey from the environment:

object BasicApp extends App {
  private val backend = HttpClientSyncBackend()
  private val client = Unstructured4s.make(backend, ApiKey(apiKey))
}

For ZIO you will likely be making a ZLayer:

import zio.*
import zio.interop.catz.*
import org.twelvehart.unstructured4s.*
import org.twelvehart.unstructured4s.model.*
import sttp.client3.asynchttpclient.zio.*
import sttp.client3.*

object ZIOApp extends ZIOAppDefault {
  private val live = AsyncHttpClientZioBackend.layer()

  def program: ZIO[SttpClient, Throwable, Unit] =
    for {
      backend <- ZIO.service[SttpClient]
      apiKey  <- ZIO.fromEither(apiKeyEnv)
      client  = Unstructured4s.make(backend, ApiKey(apiKey))
    } yield ()
}

For fs2 you will likely be making a cats.effect.Resource:

import cats.effect.*
import org.twelvehart.unstructured4s.*
import org.twelvehart.unstructured4s.model.*
import sttp.capabilities
import sttp.capabilities.fs2.Fs2Streams
import sttp.client3.SttpBackend
import sttp.client3.httpclient.fs2.HttpClientFs2Backend
import sttp.client3.logging.slf4j.Slf4jLoggingBackend

object CatsEffectApp extends IOApp.Simple {
  private val backendResource: Resource[IO, SttpBackend[IO, Fs2Streams[IO] & capabilities.WebSockets]] =
    HttpClientFs2Backend
      .resource[IO]()
      .map(backend =>
        // You can even use logged backends as an example
        Slf4jLoggingBackend(
          backend,
          logRequestHeaders = false,
          logRequestBody = true
        )
      )

  override def run: IO[Unit] =
    backendResource.use { backend =>
      for {
        apiKey <- IO.fromEither(apiKeyEnv)
        client = Unstructured4s.make(backend, ApiKey(apiKey))
      } yield ()
    }