discogs4s


License

License

GPL
GroupId

GroupId

io.bartholomews
ArtifactId

ArtifactId

discogs4s_2.13
Last Version

Last Version

0.1.1
Release Date

Release Date

Type

Type

jar
Description

Description

discogs4s
discogs4s
Project Organization

Project Organization

io.bartholomews
Source Code Management

Source Code Management

https://github.com/bartholomews/discogs4s

Download discogs4s_2.13

How to add to project

<!-- https://jarcasting.com/artifacts/io.bartholomews/discogs4s_2.13/ -->
<dependency>
    <groupId>io.bartholomews</groupId>
    <artifactId>discogs4s_2.13</artifactId>
    <version>0.1.1</version>
</dependency>
// https://jarcasting.com/artifacts/io.bartholomews/discogs4s_2.13/
implementation 'io.bartholomews:discogs4s_2.13:0.1.1'
// https://jarcasting.com/artifacts/io.bartholomews/discogs4s_2.13/
implementation ("io.bartholomews:discogs4s_2.13:0.1.1")
'io.bartholomews:discogs4s_2.13:jar:0.1.1'
<dependency org="io.bartholomews" name="discogs4s_2.13" rev="0.1.1">
  <artifact name="discogs4s_2.13" type="jar" />
</dependency>
@Grapes(
@Grab(group='io.bartholomews', module='discogs4s_2.13', version='0.1.1')
)
libraryDependencies += "io.bartholomews" % "discogs4s_2.13" % "0.1.1"
[io.bartholomews/discogs4s_2.13 "0.1.1"]

Dependencies

compile (2)

Group / Artifact Type Version
org.scala-lang : scala-library jar 2.13.3
io.bartholomews : fsclient-circe_2.13 jar 0.1.0

test (1)

Group / Artifact Type Version
io.bartholomews : scalatestudo_2.13 jar 0.0.3

Project Modules

There are no modules declared in this project.

Actions Status codecov License: GPL v3

discogs4s

Early stage Discogs client wrapping sttp

The client is using the library fsclient which is a wrapper around sttp with circe and OAuth handling.

Maven Central

libraryDependencies += "io.bartholomews" %% "discogs4s" % "0.1.1"

NOTE

The following snippets are based on the latest snapshot which has been migrated to sttp3

Simple client

  import io.bartholomews.discogs4s.DiscogsClient
  import io.bartholomews.discogs4s.entities.{SimpleUser, Username}
  import io.bartholomews.fsclient.core.config.UserAgent
  import io.bartholomews.fsclient.core.http.SttpResponses.SttpResponse
  import io.circe
  import sttp.client3.{HttpURLConnectionBackend, Identity, SttpBackend}

  type F[X] = Identity[X]
  val backend: SttpBackend[F, Any] = HttpURLConnectionBackend()

  /*
    create a basic client ready to make (unsigned) requests:
    you can also use `basicFromConfig` but need to have user-agent in config
   */
  private val client = DiscogsClient.basic(
    UserAgent(appName = "my-app", appVersion = None, appUrl = None)
  )(backend)

  // run a request with your client
  val response: F[SttpResponse[circe.Error, SimpleUser]] =
    client.users.getSimpleUserProfile(Username("_.bartholomews"))

OAuth

Read the discogs OAuth Flow

Client Credentials

If you want to use consumer credentials from config, add them in your application.conf:

user-agent {
    app-name = "your-consumer-app"
    app-version = "0.0.1-SNAPSHOT (optional)"
    app-url = "your-app-url (optional)"
}

discogs {
    consumer {
        key: ${?APP_CONSUMERY_KEY}
        secret: ${?APP_CONSUMER_SECRET}
    }
}

Then you can create a client with Client Credentials:

  import io.bartholomews.discogs4s.DiscogsClient
  import io.bartholomews.discogs4s.entities.{SimpleUser, Username}
  import io.bartholomews.fsclient.core.http.SttpResponses.SttpResponse
  import io.circe
  import sttp.client3.{HttpURLConnectionBackend, Identity, SttpBackend}

  type F[X] = Identity[X]
  val backend: SttpBackend[F, Any] = HttpURLConnectionBackend()

  // you could also pass the credentials directly in `DiscogsClient.clientCredentials`
  private val client = DiscogsClient.clientCredentialsFromConfig(backend)

  val response: F[SttpResponse[circe.Error, SimpleUser]] =
    client.users.getSimpleUserProfile(Username("_.bartholomews"))

This client will sign by default with consumer key/secret:
you cannot make authenticated requests, but you can benefit from higher rate limiting.

Personal access token

If you have a personal access token you could just create a client with that:

user-agent {
    app-name = "your-consumer-app"
    app-version = "0.0.1-SNAPSHOT (optional)"
    app-url = "your-app-url (optional)"
}

discogs {
    consumer {
        key: ${?APP_CONSUMERY_KEY}
        secret: ${?APP_CONSUMER_SECRET}
    }
    access-token:${?PERSONAL_TOKEN_VALUE}
}

This way you can create a client with Personal access token:

  import io.bartholomews.discogs4s.DiscogsClient
  import io.bartholomews.discogs4s.entities.UserIdentity
  import io.bartholomews.fsclient.core.http.SttpResponses.SttpResponse
  import io.bartholomews.fsclient.core.oauth.OAuthSigner
  import io.circe
  import sttp.client3.{HttpURLConnectionBackend, Identity, SttpBackend}

  type F[X] = Identity[X]
  val backend: SttpBackend[F, Any] = HttpURLConnectionBackend()

  private val discogs = DiscogsClient.personalFromConfig(backend)
  implicit val personalToken: OAuthSigner = discogs.client.signer

  // You can make authenticated (for your user only) calls with the implicit signer
  val response: F[SttpResponse[circe.Error, UserIdentity]] = discogs.users.me

You could also create a client manually passing directly UserAgent and Signer.

Full OAuth 1.0a with access token/secret

  import io.bartholomews.discogs4s.DiscogsClient
  import io.bartholomews.fsclient.core.oauth.v2.OAuthV2.RedirectUri
  import io.bartholomews.fsclient.core.oauth.{AccessTokenCredentials, SignerV1, TemporaryCredentialsRequest}
  import sttp.client3.{HttpURLConnectionBackend, Identity, SttpBackend, UriContext}
  import sttp.model.Uri

  type F[X] = Identity[X]
  val backend: SttpBackend[F, Any] = HttpURLConnectionBackend()

  val discogsClient: DiscogsClient[F, SignerV1] =
    DiscogsClient.clientCredentialsFromConfig(backend)

  // the uri to be redirected after the user will grant permissions for your app
  private val redirectUri = RedirectUri(uri"http://localhost:9000/discogs/callback")

  val temporaryCredentialsRequest: TemporaryCredentialsRequest =
    discogsClient.temporaryCredentialsRequest(redirectUri)

  for {
    temporaryCredentials <- discogsClient.auth.getRequestToken(temporaryCredentialsRequest).body

    // Send the uri to discogs token uri to give permissions to your app
    sendTheUserTo: Uri = temporaryCredentials.resourceOwnerAuthorizationRequest

    /*
      After the user accept/reject permissions for your app at `sendTheUserTo` uri,
      they will be redirected to `redirectUri`: the url will have
      query parameters with the token key and verifier;
      it doesn't seem to have the token secret,
      that's why you need to keep the temporary credentials in the previous step
     */
    resourceOwnerAuthorizationUriResponse: Uri = redirectUri.value.withParams(
      Map("oauth_token" -> "AAA", "oauth_verifier" -> "ZZZ")
    )

    /*
      finally get the access token credentials:
      you could serialize it in the client session cookies or store it somewhere
      (it doesn't expire).
      By default the OAuth signature is using SHA1, you can override and use PLAINTEXT instead
      (for more info see https://tools.ietf.org/html/rfc5849#section-3.4).
     */
    accessToken <- discogsClient.auth.fromUri(resourceOwnerAuthorizationUriResponse, temporaryCredentials).body

  } yield {
    implicit val token: AccessTokenCredentials = accessToken
    // you need to provide an accessToken to make user-authenticated calls
    discogsClient.users.me.body match {
      case Left(error) => println(error.getMessage)
      case Right(user) => println(user.username)
    }
  }

Implemented endpoints:

Contributing

Any request / issue / help / PR is most welcome.

CI/CD Pipeline

This project is using sbt-ci-release plugin:

  • Every push to master will trigger a snapshot release.

  • In order to trigger a regular release you need to push a tag:

    ./scripts/release.sh v1.0.0
  • If for some reason you need to replace an older version (e.g. the release stage failed):

    TAG=v1.0.0
    git push --delete origin ${TAG} && git tag --delete ${TAG} \
    && ./scripts/release.sh ${TAG}

Versions

Version
0.1.1
0.1.0
0.0.1