whats the Kotlin Equivalent request.post() from python? - android

So I'm trying to use an API from a website but inorder to use it i'll have to send my login informaton. The documentation shows me a python example on how to login.
R = requests.post('http://nova.astrometry.net/api/login', data={'request-json':
json.dumps({"apikey": "XXXXXXXX"})})
print(R.text)
So what is the Kotlin equivalent of the above code ? In the websites documentation it states
"Note the request-json=VALUE: we’re not sending raw JSON, we’re sending the JSON-encoded string as though it were a text field called request-json."
I have attempted to use Android Volley but im not entirely sure how to use it.
private fun plateSolve(){
val json=JSONObject(map).toString()
Log.d(TAG,"URL:$url")
Log.d(TAG,"Hashmap:$json")
JSONObject(map).toString()
val jsonObjectRequest = JsonObjectRequest(
Request.Method.POST, url, null,
{ response ->
try {
Log.d(TAG,"POST Response: %s".format(response.toString()))
}catch (e:Exception){
Log.d(TAG,"Exception: $e")
}
},
{ error ->
// TODO: Handle error
Log.d(TAG,"There Was an Error")
error.stackTraceToString()
}
)
// Access the RequestQueue through your singleton class.
VolleySingleton.instance?.addToRequestQueue(jsonObjectRequest)
}
Thanks in advance

it's not recommended to use volley anymore for android please use retrofit as its google's recommended library,the answer for your question is too big so i will write some checkpoints to do and also i have shared a simple working example with retrofit one of my own projects on github , hopefully this helps you
retrofit link - https://square.github.io/retrofit/
Insert library files in gradle
create response classes
create retrofit api class
4.create interface class with api calls
Github project with app using retrofit for api calls
https://github.com/zaidzak9/NewsApp

Related

Connection between Android and AWS SageMaker with AWS Lambda

I set up a connection between Android and AWS Lambda which has the endpoint set to SageMaker. I am using the REST API during the connection, the AWS Cognito plug is set to be accessed without authorization.
I make a connection as described here:
https://aws.amazon.com/blogs/machine-learning/call-an-amazon-sagemaker-model-endpoint-using-amazon-api-gateway-and-aws-lambda/
My question is how to send this data:
{"data":"13.49,22.3,86.91,561.0,0.08752,0.07697999999999999,0.047510000000000004,0.033839999999999995,0.1809,0.057179999999999995,0.2338,1.3530000000000002,1.735,20.2,0.004455,0.013819999999999999,0.02095,0.01184,0.01641,0.001956,15.15,31.82,99.0,698.8,0.1162,0.1711,0.2282,0.1282,0.2871,0.06917000000000001"}
And how to view the received response later. Anyone know how to do it or where I can find tips on how to do it?
If I understand correctly, this is your system flow:
POST some data from your Android device
It gets received by API Gateway
And continues through to AWS Lambda
In AWS Lambda the data is extracted, and passed to Sage Maker
Creating a POST using AWS Amplify
To POST data form the Android device, follow the Amplify API (REST) category documentation.
Specifically, you can do something like:
val options = RestOptions.builder()
.addPath("/prod/predictbreastcancer")
.addBody("{\"data\":\"13.49,22.3,86.91,561.0,0.08752,0.07697999999999999,0.047510000000000004,0.033839999999999995,0.1809,0.057179999999999995,0.2338,1.3530000000000002,1.735,20.2,0.004455,0.013819999999999999,0.02095,0.01184,0.01641,0.001956,15.15,31.82,99.0,698.8,0.1162,0.1711,0.2282,0.1282,0.2871,0.06917000000000001\"}".toByteArray())
.build()
Amplify.API.post(options,
{ Log.i("Demo", "POST response = $it") },
{ Log.e("Demo", "POST failed", it) }
)
Creating POST body from EditText content
You mentioned you're using an EditText widget to gather the input data. I assume a user can enter a comma-separated list of values like 0.44, 6.11, etc.
To extract it's content and build the POST body, you can do:
val input = findViewById(R.id.input) as EditText
val body = JSONObject()
.put("data", input.text)
.toString()
.replaceAll("\"", "\\\"")
Displaying response in another Activity
Skimming the blog you referenced, I can't see an example of the response body content. But, here's how you can retrieve response JSON and pass it to a new activity.
Amplify.API.post(options,
{ response ->
val intent = Intent(this, YourOtherActivity::class.java)
intent.putExtra("json", response.data.asString())
runOnUiThread { startActivity(intent) }
},
{ /* handle error ... */ }
)
In YourOtherActivity, access the extra data in onCreate() like so:
val json = intent.getStringExtra("json")

OkHttp 4.x giving error when trying to access url via Call request

I recently started update to okhttp3 to 4.x
In doing so I am getting following build time error:
Using 'url(): HttpUrl' is an error. moved to val
The issue is happening when I am trying to get url from request object obtained via call:
e.g
call.enque(callback : Callback){
override fun onFailure(call : Call, t:Throwable) {
val url = call.request().url().toString
}
}
I looked up further and the Url object within Request is val aka final now.
Also, no directions on their upgrade guide https://square.github.io/okhttp/upgrading_to_okhttp_4/
I would appreciate for any suggestions on another way to obtain Url.
Using 'url(): HttpUrl' is an error. moved to val
This means you should change the function call url() to a property access url.
okhttp 4 comes with replaceWith param in the deprecation annotation that makes e.g. Android Studio to offer that fix automatically with right-click/alt-enter on the error:
#Deprecated(
message = "moved to val",
replaceWith = ReplaceWith(expression = "url"),
level = DeprecationLevel.ERROR)
From comments:
Upon further investigation I found out that the request() or Request object is from Retrofit 2. And Retrofit 2 returns call object from okhttp3
That's an issue with Android Studio. You can work around it with explicit cast to okhttp 4 types, e.g. (call.request() as Request).url.
In my case, I just had to remove the brackets:
call.request().url() -> call.request().url

Retrofit2 with Kotlin: URL changes unexpectedly

Working on an Android project with Kotlin using Retrofit. Problem is that the URL changes unexpectedly and 422 is thrown.
More specifically, the problem is in the way Retrofit handles my formatted date. The API uses this time format:
2019-08-21T05%3A12%3A53Z
which, in this example, represents August 21, 2019, at 05:12:53. As you can see, the separator for time values is %3A.
This is the interface I'm using:
interface CurrenciesApi {
#GET("currencies/sparkline?key=${apiKey}")
fun getCurrenciesSparkline(
#Query("start") start: String,
#Query("end") end: String): Call<List<CurrencySparkline>>
}
Minor remarks: apiKey is a top-level constant properly imported. CurrencySparkline is a data class corresponding to the JSON response.
From previous unit tests I know Retrofit should be built this way
let myBaseUrl: String = "https:// ..."
let retrofit: Retrofit = Retrofit.Builder()
.baseUrl(myBaseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build()
implementation of CurrenciesApi interface
val api = retrofit.create(CurrenciesApi::class.java)
and lastly the call
val start = "2019-08-08T02%3A17%3A59Z"
val end = "2019-09-01T00%3A00%3A00Z"
response: Response<List<CurrencySparkline>> = api
.getCurrenciesSparkline(start, end)
.execute()
When testing the API endpoint in browser, the response is valid and data comes back. However, if I look at the URL in debug mode, I see that I has changed values for start and end:
... &start=2019-08-08T02%253A17%253A59Z&end=2019-09-01T00%253A00%253A00Z ...
Why is this happening and how do I fix it? Any sort of help is much appreciated.

How to get response data on Android using Apollo client for GraphQL if http code is not 200?

I'm new to GraphQL using the Apollo client on Android. I'm trying to sign up a user on the server via graphQL mutation.
I call a mutation and if user's data is not valid I get http code 422: Unprocessible Entity, and in this case I cannot get any response details. I use standard way to make a call:
.enqueue(object : ApolloCall.Callback<CreateUserMutation.Data>() {
override fun onFailure(e: ApolloException) {
}
override fun onResponse(response:
Response<CreateUserMutation.Data>) {
}
And after this I'm in the onFailure block. ApolloException contains only http code description. But I want to see error details in a full response, that I can see via the Postman. I've already tried com.apollographql.apollo.ApolloCall.Callback#onHttpError callback, but the networkResponse body = null. I've described this problem here, but haven't fixed my problem:
https://github.com/apollographql/apollo-android/issues/1166
The way to do this is to check if ApolloException is an instanceof ApolloHttpException.
If it is, you can get the throwable.rawResponse().code() from it.
If it's not it means it isn't server error (maybe timeout or others)

Set headers using spring android resttemplate and android annotations

I am currently playing with Spring Android Resttemplate to interact with a java-backed REST API. Actually, I am using android annotations to send http calls to this back-end service and I must say it rocks. Basically, Android annotations allows you to define an interface for the service calls and the http methods to be used for each api call available : it will generate all the boiler-plate code related to low-level stuff like marshalling/unmarshalling, calling the right http method according to the interface definition.
Now, I would like to set some headers to http requests : How can I achieve this knowing that I only have a reference to the Service interface defining all the calls ?
I can also have reference to the RestTemplate object but it seems there is now way of setting the headers.
any help would really be appreciated
thanks
The way I approached it is by creating an instance of ApiClient in the application class and set a custom REST template.
In my case I was using Jackson for JSON message conversion:
RestTemplate restTemplate = new RestTemplate(fac);
MappingJacksonHttpMessageConverter converter =
new MappingJacksonHttpMessageConverter();
converter.getObjectMapper().configure(Feature.UNWRAP_ROOT_VALUE, true);
restTemplate
.getMessageConverters()
.add(converter);
mClient.setRestTemplate(restTemplate);
My request factory fac then looks like this:
ClientHttpRequestFactory fac = new HttpComponentsClientHttpRequestFactory() {
#Override
protected HttpUriRequest createHttpRequest(HttpMethod httpMethod, URI uri) {
HttpUriRequest uriRequest = super.createHttpRequest(httpMethod, uri);
// Add request headers
uriRequest.addHeader(
"Content-Type",
MediaType.APPLICATION_JSON_VALUE);
return uriRequest;
}
#Override
public ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod)
throws IOException {
if (Config.DEBUG_REQUESTS) {
Log.d(TAG, uri);
}
return super.createRequest(uri, httpMethod);
}
};
WARNING
Although this works on all Android devices in our office, I've recently discovered that headers don't appear to be added with all devices! I'm not sure why this is (or which devices specifically), but I'm looking in to it and will try to update this answer when I've found a resolution.

Categories

Resources