I want to send POST request to VNF to save Services .
Here is my code .
class APIClient:
def __init__(self, api_type, auth=None):
if api_type == 'EXTERNAL':
self.auth_client = auth
def api_call(self, http_verb, base_url, api_endpoint, headers=None, request_body=None, params=None):
if headers is not None:
headers = merge_dicts(headers, auth_header)
else:
headers = auth_header
url_endpoint = base_url + api_endpoint
request_body = json.dumps(request_body)
if http_verb == 'POST':
api_resp = requests.post(url_endpoint, data=request_body, headers=headers)
return api_resp
else:
return False
def add_service():
for service in service_list:
dict = service.view_service()
auth_dict = {
'server_url': 'https://authserver.nisha.com/auth/',
'client_id': 'vnf_api',
'realm_name': 'nisha,
'client_secret_key': 'abcd12345',
'grant_type': 'client_credentials'
}
api_client = APIClient(api_type='EXTERNAL', auth=auth_dict)
response = api_client.api_call(http_verb='POST',
base_url='http://0.0.0.0:5054',
api_endpoint='/vnf/service-management/v1/services',
request_body=f'{dict}')
print(response)
if response.ok:
print("success")
else:
print("no")
When I run this code it prints
<Response [415]>
no
All the functions in VNF side are working without issues and I have no issue with GET services api call.
How to fix this ?
If you need to post application/json data to an endpoint, you need to use the json kwarg in requests.post rather than the data kwarg.
To show the difference between the json and data kwargs in requests.post:
import requests
from requests import Request
# This is form-encoded
r = Request('POST', 'https://myurl.com', headers={'hello': 'world'}, data={'some': 'data'})
x = r.prepare()
x.headers
# note the content-type here
{'hello': 'world', 'Content-Length': '9', 'Content-Type': 'application/x-www-form-urlencoded'}
# This is json content
r = Request('POST', 'https://myurl.com', headers={'hello': 'world'}, json={'some': 'data'})
x = r.prepare()
x.headers
{'hello': 'world', 'Content-Length': '16', 'Content-Type': 'application/json'}
So you don't need the json.dumps step here at all:
url_endpoint = base_url + api_endpoint
if http_verb == 'POST':
api_resp = requests.post(url_endpoint, json=request_body, headers=headers)
Related
Basically, I am trying to pass a list of ids in payloads of 100 from a spreadsheet to delete organizations using the destroy many endpoint.
import json
import xlrd
import requests
session = requests.Session()
session.headers = {'Content-Type': 'application/json'}
session.auth = 'my email', 'password'
url = 'https://domain.zendesk.com/api/v2/organizations/destroy_many.json'
payloads = []
organizations_dict = {}
book = xlrd.open_workbook('orgs_list_destroy.xls')
sheet = book.sheet_by_name('Sheet1')
for row in range(1, sheet.nrows):
if sheet.row_values(row)[2]:
organizations_dict = {'ids': int(sheet.row_values(row)[2])}
if len(organizations_dict) == 100:
payloads.append(json.dumps(organizations_dict))
organizations_dict = {}
if organizations_dict:
payloads.append(json.dumps(organizations_dict))
for payload in payloads:
response = session.delete(url, data=payload)
if response.status_code != 200:
print('Import failed with status {}'.format(response.status_code))
exit()
print('Successfully imported a batch of organizations')
Try placing it outside the for loop, where you're defining your request headers:
url = 'https://{{YOURDOMAIN}}.zendesk.com/api/v2/organizations/destroy_many.json'
user = 'YOUR_EMAIL#DOMAIN.com' + '/token'
pwd = '{{YOUR_TOKEN}}'
headers = {'Content-Type': 'application/json'}
response = requests.delete(url, auth=(user, pwd), headers=headers)
i want to use the login session in another function but it does not work. i use python 2.7 and the requests module. the server is a commercial web api.
def add_device(s, argv):
headers = {'Content-Type': 'application/json; charset=UTF-8', 'Accept': 'application/json'}
url = 'https://lvgwatchit01t.***.**/watchit/ui/index.php/wapi/inventory/object?Type=Device'
s.verify = False
p = req.Request('PUT', url, json = argv, headers = headers, cookies = sessioncookie).prepare()
r = s.send(p)
rc = r.status_code
print r.text
return rc
# login routine
s = req.Session()
headers = {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
data = {'username':'***', 'password':'***'}
url = 'https://lvgwatchit01t.***.**/watchit/ui/index.php/user/login'
s.verify = False
p = req.Request('POST', url, data = data, headers = headers).prepare()
r = s.send(p)
parsed_json = json.loads(r.text)
rc = parsed_json['RC']
msg = parsed_json['MSG']
sessioncookie = r.cookies
if rc == "0":
print msg
add_device(s, data_add_device)
else:
print msg
sys.exit(1)
output:
DEBUG:urllib3.connectionpool:Starting new HTTPS connection (1): lvgwatchit01t.***.**:443
DEBUG:urllib3.connectionpool:https://lvgwatchit01t.***.**:443 "POST /watchit/ui/index.php/user/login HTTP/1.1" 200 106
You were successfully logged in!
/usr/lib/python2.7/site-packages/urllib3/connectionpool.py:857:
DEBUG:urllib3.connectionpool:https://lvgwatchit01t.***.**:443 "PUT /watchit/ui/index.php/wapi/inventory/object?Type=Device HTTP/1.1" 200 1131
{"DATA":...}],"META":{"RC":0,"MSG":"OK"}}
how to get the login session in the second function?
You pass an argument s but you set the variable again. So you lost the content of the var s and you have to make the request again with the credentials. I think you only need remove the first line of add_device(s, argv)
after adding the session cookie everything works fine. code updated in initial post.
I have a couple of web services calls using the request package in python one is purely form and WORKS:
r = requests.post('http://localhost:5000/coordinator/finished-crawl', \
data = {'competitorId':value})
And the other uses JSON and does not work:
service_url = 'http://localhost:5000/coordinator/save-page'
data = {'Url': url, 'CompetitorId': competitorID, \
'Fetched': self.generateTimestamp(), 'Html': html}
headers = {'Content-type': 'application/json'}
r = requests.post(service_url, data=json.dumps(data), headers=headers)
Now if do not include headers I use the headers as above, I get a 404, but if I do not include as
r = requests.post(service_url, data=json.dumps(data))
I get a 415. I have tried looking at other post on stackoverflow and from what I can tell the call is correct. I have tested the web service via the application postman and it works. Can some tell me what is wrong or point me in the right direction?
THE FULL METHOD
def saveContent(self, url, competitorID, html):
temp = self.cleanseHtml(html)
service_url = 'http://localhost:5000/coordinator/save-page'
data = {'Url': url, 'CompetitorId': competitorID, \
'Fetched': self.generateTimestamp(), \
'Html': temp}
headers = {'Content-type': 'application/json'}
r = requests.post(service_url, json=json.dumps(data), headers=headers)
r = requests.post(service_url, json=json.dumps(data))
And cleanseHTML:
def cleanseHtml(self, html):
return html.replace("\\", "\\\\")\
.replace("\"", "\\\"")\
.replace("\n", "")\
.replace("\r", "")
I'm trying to extract the cookies from a HTTPResponse using cookielib.CookieJar.extract_cookies(), but I keep getting an error saying that the response object doesn't have an .info attribute. I know it's more designed for pseudo-file objects like those returned by urllib2.urlopen, but what's the canonical way to extract cookies from a HTTPResponse? Here's what I've got:
def _make_request(self, loc, headers, data=None, retry=True):
retries = 0
max_retries = self._retry_max if retry else 1
self._request = urllib2.Request('http://example.com/')
self._connection = httplib.HTTPSConnection(host)
try:
while retries < max_retries:
try:
self._request.add_data(data)
self._connection.request(self._request.get_method(), self._request.get_selector() + loc,
self._request.get_data(), headers)
resp = self._connection.getresponse()
self._cookies.extract_cookies(resp, self._request) # problems!
if len(self._cookies) > 0:
# do something
...
Thanks
Try to use key set-cookie to get cookies. Here is example for you.
#!/usr/bin/env python
import urllib
import httplib2
http = httplib2.Http()
url = 'http://www.example.com/login'
body = {'USERNAME': 'foo', 'PASSWORD': 'bar'}
headers = {'Content-type': 'application/x-www-form-urlencoded'}
response, content = http.request(url, 'POST', headers=headers, body=urllib.urlencode(body))
headers = {'Cookie': response['set-cookie']}
url = 'http://www.example.com/home'
response, content = http.request(url, 'GET', headers=headers)
I can't seem to Google it, but I want a function that does this:
Accept 3 arguments (or more, whatever):
URL
a dictionary of params
POST or GET
Return me the results, and the response code.
Is there a snippet that does this?
requests
https://github.com/kennethreitz/requests/
Here's a few common ways to use it:
import requests
url = 'https://...'
payload = {'key1': 'value1', 'key2': 'value2'}
# GET
r = requests.get(url)
# GET with params in URL
r = requests.get(url, params=payload)
# POST with form-encoded data
r = requests.post(url, data=payload)
# POST with JSON
import json
r = requests.post(url, data=json.dumps(payload))
# Response, status etc
r.text
r.status_code
httplib2
https://github.com/jcgregorio/httplib2
>>> from httplib2 import Http
>>> from urllib import urlencode
>>> h = Http()
>>> data = dict(name="Joe", comment="A test comment")
>>> resp, content = h.request("http://bitworking.org/news/223/Meet-Ares", "POST", urlencode(data))
>>> resp
{'status': '200', 'transfer-encoding': 'chunked', 'vary': 'Accept-Encoding,User-Agent',
'server': 'Apache', 'connection': 'close', 'date': 'Tue, 31 Jul 2007 15:29:52 GMT',
'content-type': 'text/html'}
Even easier: via the requests module.
import requests
get_response = requests.get(url='http://google.com')
post_data = {'username':'joeb', 'password':'foobar'}
# POST some form-encoded data:
post_response = requests.post(url='http://httpbin.org/post', data=post_data)
To send data that is not form-encoded, send it serialised as a string (example taken from the documentation):
import json
post_response = requests.post(url='http://httpbin.org/post', data=json.dumps(post_data))
# If using requests v2.4.2 or later, pass the dict via the json parameter and it will be encoded directly:
post_response = requests.post(url='http://httpbin.org/post', json=post_data)
You could use this to wrap urllib2:
def URLRequest(url, params, method="GET"):
if method == "POST":
return urllib2.Request(url, data=urllib.urlencode(params))
else:
return urllib2.Request(url + "?" + urllib.urlencode(params))
That will return a Request object that has result data and response codes.
import urllib
def fetch_thing(url, params, method):
params = urllib.urlencode(params)
if method=='POST':
f = urllib.urlopen(url, params)
else:
f = urllib.urlopen(url+'?'+params)
return (f.read(), f.code)
content, response_code = fetch_thing(
'http://google.com/',
{'spam': 1, 'eggs': 2, 'bacon': 0},
'GET'
)
[Update]
Some of these answers are old. Today I would use the requests module like the answer by robaple.
I know you asked for GET and POST but I will provide CRUD since others may need this just in case: (this was tested in Python 3.7)
#!/usr/bin/env python3
import http.client
import json
print("\n GET example")
conn = http.client.HTTPSConnection("httpbin.org")
conn.request("GET", "/get")
response = conn.getresponse()
data = response.read().decode('utf-8')
print(response.status, response.reason)
print(data)
print("\n POST example")
conn = http.client.HTTPSConnection('httpbin.org')
headers = {'Content-type': 'application/json'}
post_body = {'text': 'testing post'}
json_data = json.dumps(post_body)
conn.request('POST', '/post', json_data, headers)
response = conn.getresponse()
print(response.read().decode())
print(response.status, response.reason)
print("\n PUT example ")
conn = http.client.HTTPSConnection('httpbin.org')
headers = {'Content-type': 'application/json'}
post_body ={'text': 'testing put'}
json_data = json.dumps(post_body)
conn.request('PUT', '/put', json_data, headers)
response = conn.getresponse()
print(response.read().decode(), response.reason)
print(response.status, response.reason)
print("\n delete example")
conn = http.client.HTTPSConnection('httpbin.org')
headers = {'Content-type': 'application/json'}
post_body ={'text': 'testing delete'}
json_data = json.dumps(post_body)
conn.request('DELETE', '/delete', json_data, headers)
response = conn.getresponse()
print(response.read().decode(), response.reason)
print(response.status, response.reason)