Python requests for Google Book API. How to create url? - python-requests

I'm using this API to search through books. I need to create a request with given parameters. When I use requests library and params argument it creates bad URL which gives me wrong response. Let's look at the examples:
import requests
params = {'q': "", 'inauthor': 'keyes', 'intitle': 'algernon'}
r = requests.get('https://www.googleapis.com/books/v1/volumes?', params=params)
print('URL', r.url)
The URL is https://www.googleapis.com/books/v1/volumes?q=&inauthor=keyes&intitle=algernon
Which works but gives a different response than when the link is as Working Wolumes tells.
Should be: https://www.googleapis.com/books/v1/volumes?q=inauthor:keyes+intitle:algernon
Documentation of requests tells only about params and separates them with &.
I'm looking for a library or any solution. Hopefully, I don't have to create them using e.g. f-strings

You need to create a parameter to send the url, the way you are doing it now is not what you wanted.
In this code you are saying that you need to send 3 query parameters, but that is not what you wanted. You actually want to send 1 parameter with a value.
import requests
params = {'q': "", 'inauthor': 'keyes', 'intitle': 'algernon'}
r = requests.get('https://www.googleapis.com/books/v1/volumes?', params=params)
print('URL', r.url)
try below code instead which is doing what you require:
import requests
params = {'inauthor': 'keyes', 'intitle': 'algernon'}
new_params = 'q='
new_params += '+'.join('{}:{}'.format(key, value) for key, value in params.items())
print(new_params)
r = requests.get('https://www.googleapis.com/books/v1/volumes?', params=new_params)
print('URL', r.url)

Related

Calling a REST API using Azure function App and store data in Azure container

I have a requirement to call a rest api and store the resulting json in azure storage container. I have tried standalone python coding to extract the data from rest api and able to successfully receive the data from api that has pagination. Now I need to integrate/modify this python coding inside Azure Function and will ultimately store the resulting json data in a azure storage container. I am fairly new to Azure and hence need your guidance on how to tweak this code to suit in Azure function that will in turn push the json to azure container finally.
response = requests.post(base_url,
auth=(client_id, client_secret), data={'grant_type':grant_type,'client_id':client_id,'client_secret':client_secret,'resource':resource})
acc_token_json = response.json()
access_token = json.loads(response.text)
token = access_token['access_token']
#call API to know total pages
API_Key = 'xxxxx'
api_url='https://api.example.com?pageSize=10&page=1&sortBy=orderid&sortDirection=asc'
headers = {
'Authorization': token,
'API-Key': API_Key,
}
r = requests.get(url=api_url, headers=headers).json()
total_record=int(r['pagination']['total'])
total_page=round(total_record/500)+1
#loop through all pages
all_items = []
for page in range(0, total_page):
url = "https://api.example.com?pageSize=500&sortBy=orderid&sortDirection=asc&page="+str(page)
response = requests.get(url=url, headers=headers).json()
response_data=response['data']
all_items.append(response_data)
Your inputs/guidances are very much appreciated.
You can put the logic in the body of the function.(Function is just set the condition of trigger.)
For example, if you are based on HttpTrigger:
import logging
import azure.functions as func
def main(req: func.HttpRequest) -> func.HttpResponse:
logging.info('Python HTTP trigger function processed a request.')
'''
#Put the your logic code here.
'''
return func.HttpResponse(
"This is a test.",
status_code=200
)
And you can also use blob output to achieve your requirement, it is easier, have a look of this offcial doc:
https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-storage-blob-output?tabs=python#example
Let me know if have any problem.

Python Request Session JIRA REST post http 405

Using python requests session I can connect to JIRA and retrieve issue information ...
session = requests.Session()
headers = {"Authorization": "Basic %s" % bas64_val}
session.post(jira_rest_url, headers=headers)
jira = session.get(jira_srch_issue_url + select_fields)
# select_fields = the fields I want from the issue
Now I'm trying to post a payload via the JIRA API, using a fixed issue url e.g. "https://my_jira_server.com:1234/rest/api/latest/issue/KEY-9876"
Which should be a case of the following, given: https://developer.atlassian.com/jiradev/jira-apis/about-the-jira-rest-apis/jira-rest-api-tutorials/jira-rest-api-example-edit-issues
payload = { "update": {
"fixVersions": [ {"set": "release-2.139.0"} ]
}}
posted = session.post(jira_task_url, data=payload)
# returns <Response [405]>
# jira_task_url = https://my_jira_server.com:1234/rest/api/latest/issue/KEY-9876
But this doesn't appear to work! Looking into the http 405 response, suggests that my payload is not properly formatted! Which notably, is the not easiest thing to diagnose.
What am I doing wrong here? Any help on this would be much appreciated.
Please note, I am not looking to use the python jira module, I am using requests.session to manage several sessions for different systems i.e. JIRA, TeamCity, etc..
Found the solution! I had two problems:
1) The actual syntax structure should have been:
fix_version = { "update": { "fixVersions": [ {"set" : [{ "name" : "release-2.139.0" }]}]
2) To ensure the payload is actually presented as JSON, use json.dumps() which takes an object and produces a string (see here) AND set 'content-type' to 'application/json':
payload = json.dumps(fix_version)
app_json = { 'content-type': 'application/json' }
session.put(https://.../rest/api/latest/issue/KEY-9876, headers=app_json, data=payload)
Rather than trying to define the JSON manually!

API authentication in R - unable to pass auth token as header

I am looking to do a simple GET request (from the Aplos API) in R using the httr package. I'm able to obtain a temporary token by authenticating with an API key, but then I get a 401 "Token could not be located" once trying to use the token to make an actual GET request. Would appreciate any help! Thank you in advance.
AplosURL <- "https://www.aplos.com/hermes/api/v1/auth/"
AplosAPIkey <- "XYZ"
AplosAuth <- GET(paste0(AplosURL,AplosAPIkey))
AplosAuthContent <- content(AplosAuth, "parsed")
AplosAuthToken <- AplosAuthContent$data$token
#This is where the error occurs
GET("https://www.aplos.com/hermes/api/v1/accounts",
add_headers(Authorization = paste("Bearer:", AplosAuthToken)))
This is a Python snippet provided by the API documentation:
def api_accounts_get(api_base_url, api_id, api_access_token):
# This should print a contact from Aplos.
# Lets show what we're doing.
headers = {'Authorization': 'Bearer: {}'.format(api_access_token)}
print 'geting URL: {}accounts'.format(api_base_url)
print 'With headers: {}'.format(headers)
# Actual request goes here.
r = requests.get('{}accounts'.format(api_base_url), headers=headers)
api_error_handling(r.status_code)
response = r.json()
print 'JSON response: {}'.format(response)
return (response)
In the python example, the return of the auth code block is the api_bearer_token which is base64 decoded and rsa decrypted (using your key) before it can be used.
...
api_token_encrypted = data['data']['token']
api_bearer_token = rsa.decrypt(base64.decodestring(api_token_encrypted), api_user_key)
return(api_bearer_token)
That decoded token is then used in the api call to get the accounts.
The second issue I see is that your Authorization header does not match the example's header. Specifically, you are missing the space after "Bearer:"
headers = {'Authorization': 'Bearer: {}'.format(api_access_token)}
vs
add_headers(Authorization = paste("Bearer:", AplosAuthToken)))
Likely after addressing both of these you should be able to proceed.

Microsoft Cognitive Service Internal Server Error for /vision/v1.0/analyze

I made a small program to test Microsoft Cognitive Service, but it always return
{
"code":"InternalServerError",
"requestId":"6d6dd4ec-9840-4db3-9849-a6497094fa4c",
"message":"Internal server error."
}
The code I'm using is:
#!/usr/bin/env python
import httplib, urllib, base64
headers = {
# Request headers
'Content-Type': 'application/json',
'Ocp-Apim-Subscription-Key': '53403359628e420ab85a516a79ba1bd0',
}
params = urllib.urlencode({
# Request parameters
'visualFeatures': 'Categories,Tags,Adult,Description,Faces',
'details': '{string}',
})
try:
conn = httplib.HTTPSConnection('api.projectoxford.ai')
conn.request("POST", "/vision/v1.0/analyze?%s" % params,
'{"url":"http://static5.netshoes.net/Produtos/bola-umbro-neo-liga-futsal/28/D21-0232-028/D21-0232-028_zoom1.jpg?resize=54g:*"}', headers)
response = conn.getresponse()
data = response.read()
print(data)
conn.close()
except Exception as e:
print("[Errno {0}] {1}".format(e.errno, e.strerror))
Am I doing something wrong or it's a generalized server problem?
The problem is in the params variable. When defining which visual features you would like to extract you can specify specific details from the image, as described in the documentation. The details field, if used, must be initialized with one of the valid string options available (currently, only supporting the "Celebrities" option, that would identify which celebrity is in the image). In this case, you initialized the details field with literally the placeholder noted in the documentation ('{string'}). That caused the system to give an internal error.
To correct that, you should try:
params = urllib.urlencode({
# Request parameters
'visualFeatures': 'Categories,Tags,Adult,Description,Faces',
'details': 'Celebrities',
})
(PS: Have already reported this behavior to Microsoft Cognitive Services.)

Send request with body with openresty lua-resty-http module

I am trying to send request via http module lua-resty-http. How I can send request with body data.
I have tried this
hc:connect("127.0.0.1", 82)
dates = ngx.req.get_post_args()
local hc = http:new()
result, errors = hc:request{
path = requrl,
method = "POST",
body = dates,
headers = {
["Host"] = "localhost",
},
}
Basically I am trying to send a lua table to another server location. And how to capture on that lua table location.
I'd appreciate a detailed explanation.
ngx.req.get_post_args() returns a table of key, value pairs. The body argument for the http client's request function must be in a format supported by OpenResty's cosocket send API. This means either a string, or array like table holding strings.
If you want to send a lua table with an HTTP request then you'll need a way to encode it to a string. A common approach is using JSON, and you can do this with the bundled cjson library:
local json = require "cjson"
local dates = ngx.req.get_post_args()
hc:request {
body = json.encode(dates),
...
}

Resources