Best Fuel code snippet using com.github.kittinunf.fuel.coroutines.private.awaitObjectResult
ApiClientFuel.kt
Source:ApiClientFuel.kt
...3import android.graphics.Bitmap4import android.graphics.BitmapFactory5import android.util.Base646import com.github.kittinunf.fuel.core.*7import com.github.kittinunf.fuel.coroutines.awaitObjectResult8import com.github.kittinunf.fuel.json.jsonDeserializer9import com.github.kittinunf.result.Result10import org.json.JSONObject11import com.google.gson.Gson12import com.iproov.androidapiclient.AssuranceType13import com.iproov.androidapiclient.ClaimType14import com.iproov.androidapiclient.DemonstrationPurposesOnly15import com.iproov.androidapiclient.PhotoSource16import com.iproov.androidapiclient.merge17import java.io.ByteArrayInputStream18import java.io.ByteArrayOutputStream19import java.io.InputStream20/**21 * This code uses Coroutines and Fuel to demonstrate the iProov API.22 * It is ONLY intended to show how server code might work and we only use this in client code for demo convenience.23 *24 * Not for production!25 *26 * Note that in this example callbacks are used to support success and failure lambdas27 * It is equally possible to embrace coroutines further and return to linear code that instead returns or throws,28 * allowing blockingEnrolPhotoAndGetVerifyToken() to become linear code with a try catch instead of callback inside callback29 */30@DemonstrationPurposesOnly31class ApiClientFuel(32 context: Context, // do not make val, if we need to keep a context, keep "context.applicationContext"33 val baseUrl: String = "https://eu.rp.secure.iproov.me/api/v2/",34 val apiKey: String,35 val secret: String36) {37 // Transitory access to packageName38 private val appID = context.packageName39 private val fuelInstance: FuelManager = FuelManager()40 /**41 * Obtain a token, given a ClaimType and userID42 */43 @Throws(FuelError::class)44 suspend fun getToken(assuranceType: AssuranceType, type: ClaimType, userID: String, options: Map<String, Any>? = null): String =45 fuelInstance46 .post("${baseUrl.safelUrl}claim/${type.toString().toLowerCase()}/token")47 .header("Content-Type" to "application/json")48 .body(Gson().toJson(mapOf(49 "api_key" to apiKey,50 "secret" to secret,51 "resource" to appID,52 "client" to "android",53 "user_id" to userID,54 "assurance_type" to assuranceType.backendName55 ).merge(options)))56 .awaitObjectResult(jsonDeserializer())57 .let { response ->58 when (response) {59 is Result.Success -> return response.value.obj().getString("token")60 is Result.Failure -> throw (response.error)61 }62 }63 /**64 * Enrol with a Photo, given a token and a PhotoSource65 */66 @Throws(FuelError::class)67 suspend fun enrolPhoto(token: String, image: Bitmap, source: PhotoSource): String =68 fuelInstance69 .upload("${baseUrl.safelUrl}claim/enrol/image", Method.POST, listOf(70 "api_key" to apiKey,71 "secret" to secret,72 "rotation" to "0",73 "token" to token,74 "source" to source.code75 ))76 .add(BlobDataPart(image.jpegImageStream(), "image", filename = "image.jpeg", contentType="image/jpeg"))77 .header("Content-Type" to "multipart/form-data; boundary=-------kjqdgfljhsgdfljhgsdlfjhgasdf" )78 .awaitObjectResult(jsonDeserializer())79 .let { response ->80 when (response) {81 is Result.Success -> return response.value.obj().getString("token")82 is Result.Failure -> throw (response.error)83 }84 }85 /**86 * Validate given a token and userID87 */88 @Throws(FuelError::class)89 suspend fun validate(token: String, userID: String): ValidationResult =90 fuelInstance91 .post("${baseUrl.safelUrl}claim/verify/validate")92 .body(Gson().toJson(mapOf(93 "api_key" to apiKey,94 "secret" to secret,95 "user_id" to userID,96 "token" to token,97 "ip" to "127.0.0.1",98 "client" to "android"99 )))100 .awaitObjectResult(jsonDeserializer())101 .let { response ->102 when (response) {103 is Result.Success -> return response.value.obj().toValidationResult()104 is Result.Failure -> throw (response.error)105 }106 }107 /**108 * Invalidate given a token and reason109 */110 @Throws(FuelError::class)111 suspend fun invalidate(token: String, reason: String): InvalidationResult =112 fuelInstance113 .post("${baseUrl.safelUrl}claim/$token/invalidate")114 .body(Gson().toJson(mapOf(115// "api_key" to apiKey,116// "secret" to secret,117 "reason" to reason118 )))119 .awaitObjectResult(jsonDeserializer())120 .let { response ->121 when (response) {122 is Result.Success -> return response.value.obj().toInvalidationResult()123 is Result.Failure -> throw (response.error)124 }125 }126}127// Extensions ----128/**129 * Aggregate extension function to getToken and enrolPhoto in one call.130 * - Get enrol token for the user ID131 * - Enrol the photo against the enrolment token132 * - Get a verify token for the user ID133 */...
ServerApi.kt
Source:ServerApi.kt
...9import com.github.kittinunf.fuel.core.BlobDataPart10import com.github.kittinunf.fuel.core.FuelError11import com.github.kittinunf.fuel.core.FuelManager12import com.github.kittinunf.fuel.core.Request13import com.github.kittinunf.fuel.coroutines.awaitObjectResult14import com.github.kittinunf.fuel.httpGet15import com.github.kittinunf.fuel.httpPost16import com.github.kittinunf.fuel.httpUpload17import com.github.kittinunf.result.Result18import com.google.gson.Gson19import io.reactivex.disposables.Disposable20import ua.naiksoftware.stomp.Stomp21import ua.naiksoftware.stomp.StompClient22import ua.naiksoftware.stomp.dto.StompHeader23class ServerApi(private val context: Context, private val ipAddress: String) {24 private var listeningSocket: StompClient? = null25 private var listenForTasksTopic: Disposable? = null26 private val logTag: String = context.getString(R.string.server_api_tag)27 init {28 FuelManager.instance.basePath = "http://$ipAddress"29 }30 fun close() {31 stopListeningForTasks()32 disconnectListeningSocket()33 }34 private fun Request.addJsonBodyHeader(): Request =35 header("Content-Type" to "application/json")36 suspend fun register(username: String, password: String, name: String): Result<LoginResponseDTO, FuelError> {37 Log.i(logTag, "Registering new device: $name")38 val registerURL = context.getString(R.string.register)39 val bodyJson = Gson().toJson(40 mapOf(41 "login" to username,42 "password" to password,43 "name" to name44 )45 ).toString()46 return registerURL47 .httpPost()48 .addJsonBodyHeader()49 .body(bodyJson)50 .awaitObjectResult(LoginResponseDTO.Deserializer())51 }52 suspend fun login(username: String, password: String, uuid: String): Result<LoginResponseDTO, FuelError> {53 Log.i(logTag, "Logging in device: $uuid")54 val loginURL = context.getString(R.string.login)55 val bodyJson = Gson().toJson(56 mapOf(57 "login" to username,58 "password" to password,59 "uuid" to uuid60 )61 ).toString()62 return loginURL63 .httpPost()64 .addJsonBodyHeader()65 .body(bodyJson)66 .awaitObjectResult(LoginResponseDTO.Deserializer())67 }68 private fun Request.addAuthorizationHeader(token: String): Request =69 header("Authorization" to "Bearer $token")70 private fun Request.addUUIDHeader(uuid: String): Request =71 header("device-uuid" to uuid)72 suspend fun getTasks(token: String, uuid: String): Result<Array<GetTasksResponseDTO>, FuelError> {73 Log.i(logTag, "Getting tasks for device: $uuid")74 val getTasksURL = context.getString(R.string.get_tasks)75 return getTasksURL76 .httpGet()77 .addJsonBodyHeader()78 .addAuthorizationHeader(token)79 .addUUIDHeader(uuid)80 .awaitObjectResult(GetTasksResponseDTO.ArrayDeserializer())81 }82 private fun connectListeningSocket(token: String) {83 if (listeningSocket == null) {84 Log.i(logTag, "Creating listening socket")85 listeningSocket = Stomp.over(86 Stomp.ConnectionProvider.OKHTTP,87 "ws://$ipAddress${context.getString(R.string.device_web_socket)}"88 )89 }90 if (listeningSocket?.isConnected == false) {91 Log.i(logTag, "Connecting listening socket")92 listeningSocket?.connect(listOf(StompHeader("Authorization", "Bearer $token")))93 }94 }95 private fun disconnectListeningSocket() {96 Log.i(logTag, "Disconnecting listening socket")97 listeningSocket?.disconnect()98 }99 fun listenForTasks(token: String, uuid: String, callback: (TaskDTO, String, String) -> (Unit)) {100 connectListeningSocket(token)101 Log.i(logTag, "Listening for tasks")102 listenForTasksTopic =103 listeningSocket?.topic(context.getString(R.string.listen_for_tasks).format(uuid))?.subscribe { data ->104 Log.i(logTag, "Received task")105 callback(TaskDTO.Deserializer().deserialize(data.payload), uuid, token)106 }107 }108 fun stopListeningForTasks() {109 Log.i(logTag, "Stopping listening for tasks")110 listenForTasksTopic?.dispose()111 }112 suspend fun uploadTaskResult(113 token: String,114 uuid: String,115 task: GetTasksResponseDTO116 ): Result<GetTasksResponseDTO, FuelError> {117 Log.i(logTag, "Uploading task result to server")118 val uploadTaskResultURL = context.getString(R.string.upload_task_result).format(task.id)119 val fileStream = GetTasksResponseDTO.Serializer().serialize(task).byteInputStream()120 return uploadTaskResultURL121 .httpUpload()122 .add(BlobDataPart(fileStream, name = "file", filename = "task_${task.id}_result.json"))123 .addAuthorizationHeader(token)124 .addUUIDHeader(uuid)125 .awaitObjectResult(GetTasksResponseDTO.Deserializer())126 }127 suspend fun sendKeepAlive(token: String, uuid: String): Result<KeepAliveResponseDTO, FuelError> {128 val keepAliveURL = context.getString(R.string.active)129 return keepAliveURL130 .httpPost()131 .addAuthorizationHeader(token)132 .addUUIDHeader(uuid)133 .awaitObjectResult(KeepAliveResponseDTO.Deserializer())134 }135}...
CurrencyViewModel.kt
Source:CurrencyViewModel.kt
...4import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper5import com.fasterxml.jackson.module.kotlin.readValue6import com.github.kittinunf.fuel.Fuel7import com.github.kittinunf.fuel.core.ResponseDeserializable8import com.github.kittinunf.fuel.coroutines.awaitObjectResult9import com.kotlinbyte.scoped_state.MutableScopedStateFlow10import com.kotlinbyte.scoped_state.ScopedStateFlow11import kotlinx.coroutines.Dispatchers12import kotlinx.coroutines.delay13import kotlinx.coroutines.launch14import kotlinx.coroutines.withContext15class CurrencyViewModel : ViewModel() {16 var counter = 017 var counter2 = 018 private val _scopedState: MutableScopedStateFlow<CurrencyScope> =19 MutableScopedStateFlow.create<CurrencyScope, CurrencyScope.Initial>()20 val state: ScopedStateFlow<CurrencyScope> = _scopedState21 fun fetchDateAndTime() = _scopedState.withScope<CurrencyScope.FetchTime, FetchTimeState> {22 viewModelScope.launch {23 withContext(Dispatchers.IO) {24 while (true) {25 delay(3000)26 emit(FetchTimeState.Loading)27 Fuel.get("http://worldtimeapi.org/api/timezone/Asia/Tehran")28 .awaitObjectResult(DateTimeResponseDeserializer)29 .fold(30 { data -> emit(FetchTimeState.Data(data.datetime, data.timezone)) },31 { error -> emit(FetchTimeState.Error("An error of type ${error.exception} happened: ${error.message}")) }32 )33 }34 }35 }36 }37 fun updateCurrencyAutomatically() =38 _scopedState.withScope<CurrencyScope.FetchCurrency, FetchCurrencyState> {39 viewModelScope.launch {40 withContext(Dispatchers.IO) {41 while (true) {42 delay(3000)43 emit(FetchCurrencyState.Loading)44 Fuel.get("https://api.binance.com/api/v3/ticker/price")45 .awaitObjectResult(CurrencyResponseDeserializer)46 .fold(47 { data -> emit(FetchCurrencyState.Data(data)) },48 { error -> emit(FetchCurrencyState.Error("An error of type ${error.exception} happened: ${error.message}")) }49 )50 }51 }52 }53 }54 fun increment() = _scopedState.withScope<CurrencyScope.CounterScope, CounterState> {55 viewModelScope.launch {56 counter++57 emit(CounterState.Changed(counter))58 }59 }...
ApiWrapper.kt
Source:ApiWrapper.kt
...5import com.github.kittinunf.fuel.core.FuelError6import com.github.kittinunf.fuel.core.FuelManager7import com.github.kittinunf.fuel.core.ResponseDeserializable8import com.github.kittinunf.fuel.core.awaitResult9import com.github.kittinunf.fuel.coroutines.awaitObjectResult10import com.github.kittinunf.fuel.httpDownload11import com.github.kittinunf.fuel.httpGet12import com.github.kittinunf.result.Result13import com.google.gson.Gson14import timber.log.Timber15import java.io.File16class ApiWrapper(private val appContext: Context) {17 init {18 //TODO: check if internet is available19 //yande.re does not talk to android user agents...20 FuelManager.instance.baseHeaders = mapOf("User-Agent" to "Java/1.8.0_112")21 }22 suspend fun requestPost(board: String,23 page: Int,24 tags: String = "",25 limit: Int = 20): Result<List<Post>, FuelError> =26 //TODO: add board dependent request limits, so that we can stop before the board will stop us27 buildPostRequest(board, page, tags, limit).also { Timber.d("request '$it'") }.httpGet().awaitObjectResult(PostDeserializer)28 suspend fun requestTag(board: String, tagName: String): Result<List<Tag>, FuelError> =29 //add protocol if it is missing30 "${board.prepentHttp()}/tag.json?name=$tagName&limit=0".also {31 Timber.i("Request tag info from board '$board' with name '$tagName'. Request '$it'")32 }.httpGet().awaitObjectResult(TagDeserializer).also { Timber.d("Requested Tags $board, $tagName") }33 private fun String.prepentHttp(): String = if (this.startsWith("http")) this else "https://$this"34 private fun buildPostRequest(board: String, page: Int, tags: String, limit: Int): String =35 "${board.prepentHttp()}/post.json?limit=$limit" +36 (if (page > 1) "&page=$page" else "") +37 (if (tags != "") "&tags=$tags" else "")38 suspend fun downloadPost(post: Post, destination: File) =39 post.file_url.httpDownload().fileDestination { _, _ ->40 destination41 }.awaitResult(NoopDeserializer)42 object PostDeserializer : ResponseDeserializable<List<Post>> {43 override fun deserialize(content: String): List<Post> = Gson().fromJson(content, Array<Post>::class.java).toList()44 }45 object TagDeserializer : ResponseDeserializable<List<Tag>> {46 override fun deserialize(content: String): List<Tag> = Gson().fromJson(content, Array<Tag>::class.java).toList()...
ApiClient.kt
Source:ApiClient.kt
2import android.util.Log3import com.github.kittinunf.fuel.Fuel4import com.github.kittinunf.fuel.core.FuelError5import com.github.kittinunf.fuel.core.ResponseDeserializable6import com.github.kittinunf.fuel.coroutines.awaitObjectResult7import com.github.kittinunf.result.Result8import com.google.gson.Gson9import com.google.gson.JsonObject10import java.nio.charset.Charset11/**12 * Simplified interface to make HTTP calls with JSON responses.13 */14class ApiClient(val gson: Gson) {15 /**16 * Make an unauthenticated POST call.17 */18 suspend fun <T : Any> post(path: String, deserializer: ResponseDeserializable<T>, body: Any? = null): Result<T, Exception> {19 val request = Fuel.post(path)20 request.body(gson.toJson(body))21 return convertResult(request.awaitObjectResult(deserializer))22 }23 /**24 * Make an authenticated POST call.25 */26 suspend fun <T : Any> postWithAuth(path: String, authToken: String, deserializer: ResponseDeserializable<T>, body: Any? = null): Result<T, Exception> {27 val request = Fuel.post(path)28 request.header(Pair("Authorization", "Bearer $authToken"))29 request.body(gson.toJson(body))30 return convertResult(request.awaitObjectResult(deserializer))31 }32 /**33 * Make an unauthenticated GET call.34 */35 suspend fun <T : Any> get(path: String, deserializer: ResponseDeserializable<T>): Result<T, Exception> {36 val request = Fuel.get(path)37 return convertResult(request.awaitObjectResult(deserializer))38 }39 /**40 * Make an authenticated GET call.41 */42 suspend fun <T : Any> getWithAuth(path: String, authToken: String, deserializer: ResponseDeserializable<T>): Result<T, Exception> {43 val request = Fuel.get(path)44 request.header(Pair("Authorization", "Bearer $authToken"))45 return convertResult(request.awaitObjectResult(deserializer))46 }47 /**48 * Convert error responses to JsonObject, and logs the error.49 */50 private fun <T : Any> convertResult(result: Result<T, FuelError>): Result<T, Exception> {51 lateinit var res: Result<T, Exception>52 result.fold({ response ->53 res = Result.of(response)54 }, { error ->55 val json = gson.fromJson(error.response.data.toString(Charset.defaultCharset()), JsonObject::class.java)56 Log.e("ApiClient", "Exception in API call", error)57 res = if (json == null) {58 Result.error(error)59 } else {...
CoinRepository.kt
Source:CoinRepository.kt
1package fr.ippon.androidaacsample.coinsentinel.repository2import androidx.lifecycle.LiveData3import androidx.lifecycle.MediatorLiveData4import com.github.kittinunf.fuel.Fuel5import com.github.kittinunf.fuel.coroutines.awaitObjectResult6import fr.ippon.androidaacsample.coinsentinel.api.CoinResultDeserializer7import fr.ippon.androidaacsample.coinsentinel.api.CoinRouting8import fr.ippon.androidaacsample.coinsentinel.db.Coin9import fr.ippon.androidaacsample.coinsentinel.db.CoinDao10import kotlinx.coroutines.CoroutineScope11import kotlinx.coroutines.GlobalScope12import kotlinx.coroutines.channels.produce13import kotlinx.coroutines.launch14class CoinRepository constructor(15 private val coinDao: CoinDao,16 private val coinResultDeserializer: CoinResultDeserializer17) {18 private val _coins = MediatorLiveData<Resource<Array<Coin>>>()19 val coins: LiveData<Resource<Array<Coin>>>20 get() {21 return _coins22 }23 init {24 subscribeToDatabase()25 }26 private fun subscribeToDatabase() {27 val sourceDb = coinDao.getAll()28 _coins.postValue(Resource.loading(emptyArray()))29 _coins.addSource(sourceDb) {30 _coins.postValue(Resource.success(it))31 }32 }33 private fun CoroutineScope.getCoins() = produce {34 val lastData: Array<Coin> = coins.value?.data ?: emptyArray()35 send(Resource.loading(lastData))36 Fuel.request(CoinRouting.GetCoins())37 .awaitObjectResult(coinResultDeserializer)38 .fold(success = { response ->39 coinDao.insertAll(response.data)40 }, failure = { error ->41 send(Resource.error(error, lastData))42 })43 }44 fun fetchCoins() = GlobalScope.launch {45 for (coin in getCoins()) {46 _coins.postValue(coin)47 }48 }49}...
NewsRepositoryImpl.kt
Source:NewsRepositoryImpl.kt
1package com.hellodiffa.jetpackcomposeexample.data.repository2import com.github.kittinunf.fuel.Fuel3import com.github.kittinunf.fuel.core.FuelError4import com.github.kittinunf.fuel.coroutines.awaitObjectResult5import com.github.kittinunf.result.Result6import com.hellodiffa.jetpackcomposeexample.domain.executor.Dispatchers7import com.hellodiffa.jetpackcomposeexample.domain.repository.NewsRepository8import com.hellodiffa.jetpackcomposeexample.data.response.NewsResponse9class NewsRepositoryImpl(private val dispatchers: Dispatchers) :10 NewsRepository {11 override suspend fun getAllArticle(): Result<NewsResponse, FuelError> {12 return Fuel.get("https://newsapi.org/v2/top-headlines?country=id&category=technology&apiKey=efd67bbc1d024b32a17469d00124ec15")13 .awaitObjectResult(NewsResponse.Deserializer(), dispatchers.ioDispatchers())14 }15}...
Api.kt
Source:Api.kt
1package com.hoc.viewpager22import com.github.kittinunf.fuel.core.FuelError3import com.github.kittinunf.fuel.coroutines.awaitObjectResult4import com.github.kittinunf.fuel.httpGet5import com.github.kittinunf.fuel.serialization.kotlinxDeserializerOf6import com.github.kittinunf.result.Result7import kotlinx.coroutines.delay8import kotlinx.serialization.ImplicitReflectionSerializer9import kotlinx.serialization.internal.ArrayListSerializer10private const val URL = "https://hoc081098.github.io/hoc081098.github.io/data.json"11@ImplicitReflectionSerializer12suspend fun getViewPagerItems(): Result<List<ViewPagerItem>, FuelError> {13 delay(2_000)14 return URL15 .httpGet()16 .awaitObjectResult(kotlinxDeserializerOf(ArrayListSerializer(ViewPagerItem.serializer())))17}...
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!