Skip to content

Commit d29df93

Browse files
committed
documentation (+ builder)
1 parent 83fe83f commit d29df93

File tree

7 files changed

+104
-14
lines changed

7 files changed

+104
-14
lines changed

build.gradle.kts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ java {
2222
withJavadocJar()
2323
}
2424

25+
tasks.withType<Test> {
26+
this.testLogging {
27+
this.showStandardStreams = true
28+
}
29+
}
30+
2531
repositories {
2632
mavenCentral()
2733
jcenter()

samples/src/main/kotlin/public/BrowseApiSample.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* Spotify Web API - Kotlin Wrapper; MIT License, 2019; Original author: Adam Ratzman */
12
package public
23

34
import com.adamratzman.spotify.spotifyAppApi
@@ -7,4 +8,4 @@ fun main() {
78
System.getenv("SPOTIFY_CLIENT_ID"),
89
System.getenv("SPOTIFY_CLIENT_SECRET")
910
)
10-
}
11+
}

src/commonMain/kotlin/com.adamratzman.spotify/Builder.kt

Lines changed: 90 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,12 @@ fun spotifyAppApi(block: SpotifyAppApiBuilder.() -> Unit) =
2727

2828
@Deprecated("Builder methods are now found in SpotifyBuilder", ReplaceWith("SpotifyBuilder.spotifyClientApi"))
2929
fun spotifyAppApi(clientId: String, clientSecret: String, redirectUri: String, block: SpotifyClientApiBuilder.() -> Unit = {}) =
30-
SpotifyBuilder.spotifyClientApi(clientId, clientSecret,redirectUri, block)
30+
SpotifyBuilder.spotifyClientApi(clientId, clientSecret, redirectUri, block)
3131

3232
@Deprecated("Builder methods are now found in SpotifyBuilder", ReplaceWith("SpotifyBuilder.spotifyClientApi"))
3333
fun spotifyAppApi(block: SpotifyClientApiBuilder.() -> Unit) =
3434
SpotifyBuilder.spotifyClientApi(block)
3535

36-
3736
/**
3837
* Contains static methods to instantiate [SpotifyAppApi] and [SpotifyClientApi] instances
3938
*/
@@ -91,10 +90,10 @@ class SpotifyBuilder {
9190
* @return Configurable [SpotifyClientApiBuilder] that, when built, creates a new [SpotifyClientApi]
9291
*/
9392
fun spotifyClientApi(
94-
clientId: String,
95-
clientSecret: String,
96-
redirectUri: String,
97-
block: SpotifyClientApiBuilder.() -> Unit
93+
clientId: String,
94+
clientSecret: String,
95+
redirectUri: String,
96+
block: SpotifyClientApiBuilder.() -> Unit
9897
) = SpotifyClientApiBuilder().apply(block).apply {
9998
credentials {
10099
this.clientId = clientId
@@ -117,7 +116,6 @@ class SpotifyBuilder {
117116
}
118117
}
119118

120-
121119
/**
122120
* Spotify API builder
123121
*/
@@ -126,7 +124,15 @@ class SpotifyApiBuilder(
126124
private var clientSecret: String?,
127125
private var redirectUri: String?
128126
) {
127+
/**
128+
* Allows you to authenticate a [SpotifyClientApi] with an authorization code
129+
* or build [SpotifyApi] using a refresh token
130+
*/
129131
var authorization: SpotifyUserAuthorization = SpotifyUserAuthorizationBuilder().build()
132+
133+
/**
134+
* Allows you to override default values for caching, token refresh, and logging
135+
*/
130136
var options: SpotifyApiOptions = SpotifyApiOptionsBuilder().build()
131137

132138
/**
@@ -237,14 +243,48 @@ class SpotifyApiBuilder(
237243
}.build()
238244
}
239245

246+
/**
247+
* The type of Spotify authorization used to build an Api instance
248+
*/
240249
enum class AuthorizationType {
250+
/**
251+
* Authorization through explicit affirmative action taken by a client (user) allowing the application to access a/multiple [SpotifyScope]
252+
*
253+
* [Spotify application settings page](https://developer.spotify.com/documentation/general/guides/app-settings/)
254+
*/
241255
CLIENT,
256+
257+
/**
258+
* Authorization through application client id and secret, allowing access only to public endpoints and data
259+
*
260+
* [Spotify application settings page](https://developer.spotify.com/documentation/general/guides/app-settings/)
261+
*/
242262
APPLICATION;
243263
}
244264

265+
/**
266+
* Spotify Api builder interface
267+
*
268+
* @property T The type of [SpotifyApi] to be built
269+
* @property B The associated Api builder for [T]
270+
*/
245271
interface ISpotifyApiBuilder<T : SpotifyApi<T, B>, B : ISpotifyApiBuilder<T, B>> {
272+
/**
273+
* A block in which Spotify application credentials (accessible via the Spotify [dashboard](https://developer.spotify.com/dashboard/applications))
274+
* should be put
275+
*/
246276
var credentials: SpotifyCredentials
277+
278+
/**
279+
* Allows you to authenticate a [SpotifyClientApi] with an authorization code
280+
* or build [SpotifyApi] using a refresh token
281+
*/
247282
var authorization: SpotifyUserAuthorization
283+
284+
285+
/**
286+
* Allows you to override default values for caching, token refresh, and logging
287+
*/
248288
var options: SpotifyApiOptions
249289

250290
/**
@@ -276,13 +316,15 @@ interface ISpotifyApiBuilder<T : SpotifyApi<T, B>, B : ISpotifyApiBuilder<T, B>>
276316
/**
277317
* Allows you to override default values for caching, token refresh, and logging
278318
*/
319+
@Deprecated("Succeeded by the options method", ReplaceWith("options"))
279320
fun utilities(block: SpotifyApiOptionsBuilder.() -> Unit) {
280321
options = SpotifyApiOptionsBuilder().apply(block).build()
281322
}
282323

283324
/**
284325
* Allows you to override default values for caching, token refresh, and logging
285326
*/
327+
@Deprecated("Succeeded by the options method", ReplaceWith("options"))
286328
fun config(block: SpotifyApiOptionsBuilder.() -> Unit) {
287329
options = SpotifyApiOptionsBuilder().apply(block).build()
288330
}
@@ -294,6 +336,9 @@ interface ISpotifyApiBuilder<T : SpotifyApi<T, B>, B : ISpotifyApiBuilder<T, B>>
294336
options = SpotifyApiOptionsBuilder().apply(block).build()
295337
}
296338

339+
/**
340+
* Allows you to override default values for caching, token refresh, and logging
341+
*/
297342
fun options(options: SpotifyApiOptions) = apply { this.options = options }
298343

299344
/**
@@ -323,6 +368,9 @@ interface ISpotifyApiBuilder<T : SpotifyApi<T, B>, B : ISpotifyApiBuilder<T, B>>
323368
}
324369
}
325370

371+
/**
372+
* Client interface exposing [getAuthorizationUrl]
373+
*/
326374
interface ISpotifyClientApiBuilder : ISpotifyApiBuilder<SpotifyClientApi, SpotifyClientApiBuilder> {
327375
/**
328376
* Create a Spotify authorization URL from which API access can be obtained
@@ -333,6 +381,9 @@ interface ISpotifyClientApiBuilder : ISpotifyApiBuilder<SpotifyClientApi, Spotif
333381
fun getAuthorizationUrl(vararg scopes: SpotifyScope): String
334382
}
335383

384+
/**
385+
* [SpotifyClientApi] builder for api creation using client authorization
386+
*/
336387
class SpotifyClientApiBuilder(
337388
override var credentials: SpotifyCredentials = SpotifyCredentialsBuilder().build(),
338389
override var authorization: SpotifyUserAuthorization = SpotifyUserAuthorizationBuilder().build(),
@@ -348,6 +399,7 @@ class SpotifyClientApiBuilder(
348399
val clientSecret = credentials.clientSecret
349400
val redirectUri = credentials.redirectUri
350401

402+
// either application credentials, or a token is required
351403
require((clientId != null && clientSecret != null && redirectUri != null) || authorization.token != null || authorization.tokenString != null) { "You need to specify a valid clientId, clientSecret, and redirectUri in the credentials block!" }
352404
return when {
353405
authorization.authorizationCode != null -> try {
@@ -427,8 +479,16 @@ class SpotifyClientApiBuilder(
427479
}
428480
}
429481

482+
483+
/**
484+
* App Api builder interface
485+
*/
430486
interface ISpotifyAppApiBuilder : ISpotifyApiBuilder<SpotifyAppApi, SpotifyAppApiBuilder>
431487

488+
489+
/**
490+
* [SpotifyAppApi] builder for api creation using client authorization
491+
*/
432492
class SpotifyAppApiBuilder(
433493
override var credentials: SpotifyCredentials = SpotifyCredentialsBuilder().build(),
434494
override var authorization: SpotifyUserAuthorization = SpotifyUserAuthorizationBuilder().build(),
@@ -547,6 +607,17 @@ class SpotifyUserAuthorizationBuilder(
547607
fun build() = SpotifyUserAuthorization(authorizationCode, tokenString, token, refreshTokenString)
548608
}
549609

610+
/**
611+
* User-defined authorization parameters
612+
*
613+
* @property authorizationCode Only available when building [SpotifyClientApi]. Spotify auth code
614+
* @property token Build the API using an existing token. If you're building [SpotifyClientApi], this
615+
* will be your **access** token. If you're building [SpotifyApi], it will be your **refresh** token
616+
* @property tokenString Build the API using an existing token (string). If you're building [SpotifyClientApi], this
617+
* will be your **access** token. If you're building [SpotifyApi], it will be your **refresh** token. There is a *very*
618+
* limited time constraint on these before the API automatically refreshes them
619+
* @property refreshTokenString Refresh token, given as a string, to be exchanged to Spotify for a new token
620+
*/
550621
data class SpotifyUserAuthorization(
551622
var authorizationCode: String?,
552623
var tokenString: String?,
@@ -598,6 +669,18 @@ class SpotifyApiOptionsBuilder(
598669
)
599670
}
600671

672+
/**
673+
* API Utilities
674+
*
675+
* @property useCache Set whether to cache requests. Default: true
676+
* @property cacheLimit The maximum amount of cached requests allowed at one time. Null means no limit
677+
* @property automaticRefresh Enable or disable automatic refresh of the Spotify access token
678+
* @property retryWhenRateLimited Set whether to block the current thread and wait until the API can retry the request
679+
* @property enableLogger Set whether to enable to the exception logger
680+
* @property testTokenValidity After API creation, test whether the token is valid by performing a lightweight request
681+
* @property enableAllOptions Whether to enable all provided utilities
682+
*/
683+
601684
data class SpotifyApiOptions(
602685
var useCache: Boolean,
603686
var cacheLimit: Int?,

src/commonMain/kotlin/com.adamratzman.spotify/SpotifyApi.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ import com.adamratzman.spotify.models.TokenValidityResponse
3030
import com.adamratzman.spotify.models.serialization.toObject
3131
import com.adamratzman.spotify.utils.asList
3232
import com.adamratzman.spotify.utils.runBlocking
33-
import kotlinx.coroutines.Dispatchers
34-
import kotlinx.serialization.json.Json
3533
import kotlin.coroutines.CoroutineContext
3634
import kotlin.jvm.JvmOverloads
35+
import kotlinx.coroutines.Dispatchers
36+
import kotlinx.serialization.json.Json
3737

3838
internal const val base = "https://api.spotify.com/v1"
3939

src/commonMain/kotlin/com.adamratzman.spotify/models/PagingObjects.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import com.adamratzman.spotify.http.SpotifyEndpoint
66
import com.adamratzman.spotify.models.serialization.toCursorBasedPagingObject
77
import com.adamratzman.spotify.models.serialization.toPagingObject
88
import com.adamratzman.spotify.utils.runBlocking
9+
import kotlin.reflect.KClass
910
import kotlinx.coroutines.Dispatchers
1011
import kotlinx.coroutines.ExperimentalCoroutinesApi
1112
import kotlinx.coroutines.flow.Flow
@@ -17,7 +18,6 @@ import kotlinx.coroutines.flow.toList
1718
import kotlinx.serialization.SerialName
1819
import kotlinx.serialization.Serializable
1920
import kotlinx.serialization.Transient
20-
import kotlin.reflect.KClass
2121

2222
/*
2323
Types used in PagingObjects and CursorBasedPagingObjects:
@@ -209,7 +209,7 @@ abstract class AbstractPagingObject<T : Any>(
209209
@Transient open val offset: Int = 0,
210210
@Transient open val previous: String? = null,
211211
@Transient open val total: Int = -1
212-
): List<T> by items {
212+
) : List<T> by items {
213213
@Transient
214214
internal var endpoint: SpotifyEndpoint? = null
215215

src/commonTest/kotlin/com.adamratzman/spotify/public/PublicUserAPITest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class PublicUserAPITest : Spek({
1212
describe("Public User test") {
1313
describe("get user") {
1414
it("available user should return author name") {
15-
assertTrue { catch { api.users.getProfile("adamratzman1").complete()!!.followers.total } != null }
15+
assertTrue { catch { api.users.getProfile("adamratzman1").complete()!!.followers.total } != null }
1616
}
1717
it("unknown user should throw exception") {
1818
assertNull(api.users.getProfile("non-existant-user").complete())

src/commonTest/kotlin/com.adamratzman/spotify/utilities/UtilityTests.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@ import com.adamratzman.spotify.SpotifyClientAPI
77
import com.adamratzman.spotify.api
88
import com.adamratzman.spotify.block
99
import com.adamratzman.spotify.getEnvironmentVariable
10+
import kotlin.test.assertFailsWith
1011
import kotlinx.coroutines.GlobalScope
1112
import org.spekframework.spek2.Spek
1213
import org.spekframework.spek2.style.specification.describe
13-
import kotlin.test.assertFailsWith
1414

1515
class UtilityTests : Spek({
1616
describe("Utility tests") {

0 commit comments

Comments
 (0)