I am trying to access the Open Apparel Registry api using httr.
NB: It's free to sign up (need to login + get authentication code on profile page).
But you can see the swagger api docs here: https://openapparel.org/api/docs/#!/facilities/facilities_list
Here is how you authorize on web version:
oar_root_api <- "https://openapparel.org/api/facilities/"
oar_token <- XXX
oar_api_facilities_GET <- httr::GET(url = oar_root_api,
add_headers(
`Authorization` = oar_token),
verbose()
)
The code I receive back is 401 so something is wrong with my authorization, but I've tried so many ways. I can't figure out how to specify this correctly.
Sorry to hear you've been having difficulties. This additional documentation may help: https://docs.google.com/document/d/1ZKCN84Eu9WDAXUokojOw7Dcg5TAJw0vKnVk7RPrTPZ0/edit?usp=sharing
We tend to find that users need to add the "Token" prefix (see page 3), which I appreciate isn't standard practice - this is something we intend to change!
Let us know how you get on.
OAR
The Open Apparel Registry (OAR) uses Django REST Framework to provide API enpoints. The TokenAuthentication class requires that the Authorization header value have a "Token " prefix. From the documentation
For clients to authenticate, the token key should be included in the Authorization HTTP header. The key should be prefixed by the string literal "Token", with whitespace separating the two strings. For example:
Authorization: Token 9944b09.....
I am not familiar with R, but I searched for string concatenation and it looks like the paste function will build the header value that you need.
oar_root_api <- "https://openapparel.org/api/facilities/"
oar_token <- XXX
oar_api_facilities_GET <- httr::GET(url = oar_root_api,
add_headers(
`Authorization` = paste("Token ", oar_token)),
verbose()
)
Related
I have added Bearer token authorization to my Swagger (created with Plumber), using the solution here.
Now I would like to add arbitrary headers that are a part of the request. My plumber deployment is used by a React dashboard, where parsing req$HTTP_TENANT gives me the desired value. And it is this I would like to recreate in Swagger.
Consider this example:
library(plumber)
r <- plumber::pr("plumber.R") %>%
plumber::pr_set_docs("swagger") %>%
plumber::pr_set_api_spec(function(spec) {
spec$components$securitySchemes$bearerAuth$type <- "http"
spec$components$securitySchemes$bearerAuth$scheme <- "bearer"
spec$components$securitySchemes$bearerAuth$bearerFormat <- "JWT"
spec$security[[1]]$bearerAuth <- ""
spec$components$parameters$HTTP_TENANT <- "HTTP_TENANT"
spec$parameters[[1]]$HTTP_TENANT <- "Customer name"
spec
})
r %>% plumber::pr_run(port = 8000, host = '0.0.0.0')
This gives the following result:
How can arbitrary headers be requested, for example HTTP_TENANT, maybe typed below the Bearer token input? It could also be somewhere else at the top of Swagger.
How can default values be provided for the headers, e.g. Customer name, but also the Bearer token (i.e. it could be programmatically entered from R)?
In Swagger, you can add a parameter to the API endpoint and change the "in" property to "header" to request any header, such as HTTP_TENANT. For instance:
spec$paths$"/endpoint"$get$parameters[[1]]$name <- "HTTP_TENANT"
spec$paths$"/endpoint"$get$parameters[[1]]$in <- "header"
spec$paths$"/endpoint"$get$parameters[[1]]$description <- "Customer name"
Under the "parameters" section of the Swagger UI, an input field for the "HTTP_TENANT" header will be added as a result of this.
A "default" property on the parameter object can be added to headers to provide default values. For instance:
spec$paths$"/endpoint"$get$parameters[[1]]$default <- "customer1"
The default values could also be set programmatically by reading them from an external source (like a configuration file) or by using an R package that handles authentication (like httr) to handle the bearer token automatically.
Docs about using the Azure's Form Recognizer seem unclear. What is the correct ENDPOINT to send my request?
I'm using python and have followed the docs to use the prebuilt receipt model of Form Recognizer but don't get the expected output. I'm unsure if I'm using the correct endpoint. I tried two things:
Reading this tutorial, it is stated that I need to look up the <ENDPOINT> in my resource's overview page. In my case it is: formextractor.cognitiveservices.azure.com. So I tried this:
import http.client, urllib.request, urllib.parse, urllib.error, base64
params = urllib.parse.urlencode({
})
# key = '...'
headers = {
# Request headers
'Content-Type': 'application/json',
'Ocp-Apim-Subscription-Key': key,
}
source = r"https://www.w3.org/WAI/WCAG20/Techniques/working-examples/PDF20/table.pdf"
body = {"url":source}
body = json.dumps(body)
try:
conn = http.client.HTTPSConnection('formextractor.cognitiveservices.azure.com')
conn.request("POST", "/formrecognizer/v1.0-preview/prebuilt/receipt/asyncBatchAnalyze?s" % params, f"{body}", headers)
response = conn.getresponse()
data = response.read()
operationURL = "" + response.getheader("Operation-Location")
print ("Operation-Location header: " + operationURL)
conn.close()
except Exception as e:
print(e)
This returns:
[Errno 8] nodename nor servname provided, or not known
But in the API Docs the ENDPOINT is already fixed to westeurope.api.cognitive.microsoft.com, which is where my resource is located. So I tried this:
# ... same headers, body and params as before
try:
conn = http.client.HTTPSConnection('westeurope.api.cognitive.microsoft.com')
conn.request("POST", "/formrecognizer/v1.0-preview/prebuilt/receipt/asyncBatchAnalyze?%s" % params, f"{body}", headers)
response = conn.getresponse()
data = response.read()
operationURL = "" + response.getheader("Operation-Location")
print ("Operation-Location header: " + operationURL)
conn.close()
except Exception as e:
print("[Errno {0}] {1}".format(e.errno, e.strerror))
Outputs an URL where I see:
{"error":{"code":"401","message": "Access denied due to invalid subscription key or wrong API endpoint. Make sure to provide a valid key for an active subscription and use a correct regional API endpoint for your resource."}}
I am certain I'm using the correct key. But in any case neither of the two seems to work. Could you help me? Thank you.
It looks like the initial documentation you are mentioning is misleading. You can find the endpoint of your resource in Azure portal, in the resource overview. Sample for mine:
Form Recognizer API is (at the time of writing this answer) hosted in the following Azure regions:
West US 2 - westus2.api.cognitive.microsoft.com
West Europe - westeurope.api.cognitive.microsoft.com
So in my case it's WestEurope, and as you mentioned it is the same on your resource. Once you got it, you then got a 401 Unauthorized
Several possibilities:
You made an error in the way you are passing the header (wrong key name, wrong key value), but it looks okay based on your code above (but I'm not used to Python)
Your resource is not from the same region as the endpoint you are querying (please double check)
You are using the right root, but something is wrong in how you are calling it
Once you have checked your region / key values, can you remove your ?%s"%params from your query? The Analyze Receipt method don't have params in query string (given documentation)
I'm trying to connect to the StackExchange API in R.
When I try:
library(httr)
end <- oauth_endpoint(authorize = "https://stackoverflow.com/oauth",
access = "https://stackoverflow.com/oauth")
myapp <- oauth_app("myapp",
key = "KEY", # tried swapping these
secret = "CLIENT SECRET",
redirect_uri = "https://stackoverflow.com/oauth/login_success")
token <- oauth2.0_token(end,
myapp)
The browser opens but leads to the following message (in the browser):
Couldn't parse `client_id`
This also happens if I try it with opposite (reversed) values of key and secret, or event with key set to either value and secret=NULL (just to test without privileged access).
The StackExchange API docs say that the key value they give you is not really a secret but the client_secret value is. In the oauth_app help it says that the secret "is not equivalent to a password, and is not really a secret". Interesting.
For now I'm just trying to establish an initial test connection.
Update:
I was curious if it was actually a matter of not being able to parse special character. I tried escaping the 2 parentheses ((() in my key and client_secret. That didn't change anything. I then tried setting both to an empty string (i.e. key = "", etc) and yet that somehow led to the same result. I feel it's a clue but I still don't know what's wrong.
You're using implicit ("Client side") OAuth(SE API Doc).
That means that the auth sequence should look like this example:
Your app HTTP GETS:
https://stackexchange.com/oauth/dialog?client_id=4709&scope=private_info&redirect_uri=https://stackexchange.com/oauth/login_success
Where client_idand scope are set to your circumstances.
Your app is then redirected to:
https://stackexchange.com/oauth/login_success#access_token=wdR8Lm7m4ibD48lfrCcFxQ))&expires=86399
For example.
Where access_token is what you need for subsequent calls that require authentication.
I'm no r coder, but guess that the syntax should be something like:
myapp <- oauth_app("myapp",
client_id = "{Your App's ID}",
scope = "private_info", # Or whatever is desired. See the doc page linked above
redirect_uri = "https://stackoverflow.com/oauth/login_success")
client_secret is only used for server-side (explicit) OAuth.
pass key in all subsequent calls, OAuth needed or not, for quota purposes.
I was getting the same error, my issue was that I was using the client secret as a value for my client_id parameter
I want to consume a REST API and have to perform the following steps for it.
I have to get a Token using my UserName and Password
(What I have accomplished successfully and the token is stored in a variable)
I have to use this Token to get data from the API and here I stuck.
I have tried
req_token <- THE TOKEN I HAVE RECIEVED ALREADY
url <- 'https://myService.com/web/api/datasources/{identifier}/data'
mydata <- GET(url, config = add_headers(paste0("Basic ", req_token)))
The identifier is there to specify a datasource within many, so in my case I had to replace it with EdQVFcgRGF0 (sort like). So I end up with the url
https://myService.com/web/api/datasources/{EdQVFcgRGF0}/data
All specification I got from the provider was
/datasources/{identifier]/data (GET)
● get data for one datasource (full data)
I tried consume the api with vb.net first and sending the token in the header works
request.AddHeader("Authorization", "Basic " + _token)
Now I get an 401 Unauthorized using R and do not know, what is wrong, anyone who can help me out?
Depending on the API configuration, I think you'll add it in where there's the curly brackets for {identifier} in the URL.
req_token <- THE TOKEN I HAVE RECIEVED ALREADY
url <- paste('https://myService.com/web/api/datasources/', req_token, '/data', sep='')
That's how some API's do it. Which means your headers might not look like this any more.
mydata <- GET(url, config = add_headers(paste0("Basic ", req_token)))
They probably just won't be there any more. So like :
mydata <- GET(url)
If the token is required in the headers it might look more like this:
mydata <- GET(url, config = add_headers("Basic " = req_token))
But I doubt the token will be both in the URL and in the header. You'll have to find out which is required from the docs.
Edit
I believe your headers should look like this:
mydata <- GET(url, config = add_headers("Authorization " = paste( "Basic", req_token, sep = ' ' ))
I am trying to access a Wikipedia page so to get a list of pages, and get the following error:
library(RCurl)
u <- "http://en.wikipedia.org/w/index.php?title=Special%3APrefixIndex&prefix=tal&namespace=4"
getURL(u)
[1] "Scripts should use an informative User-Agent string with contact information, or they may be IP-blocked without notice.\n"
I hope to get to that page through the Wikipedia api, but I am not sure it would work.
And the thing is that other pages are read without problem, for example:
u <- "http://en.wikipedia.org/wiki/Wikipedia:Talk"
getURL(u)
Any suggestions?
Side note: In general I would rather to not scrape wiki pages and go through the api, but I fear that this specific pages are not yet available through the api...
According to the documentation of RCurl, you can specify additional header by adding a httpheader parameter:
getURL(u, httpheader = c('User-Agent' = "Informative string with your contact info"))