Send PATCH request to Django Rest Framework - django

I am sending a PATCH request to my DRF server in Postman and it works perfect
However when I do the same in Python I get:
<Response [405]> http://127.0.0.1:8000/api/title/8174/
b'{"detail":"Method \\"PATCH\\" not allowed."}'
Method Not Allowed
My function that sends data:
ss_token = os.getenv('SS_TOKEN')
headers = {
'Authorization': 'Token ' + ss_token,
}
source = Source.objects.all().first()
url = source.url + str(self.ss_id) + '/'
response = requests.patch(source.url, headers=headers, data={'key':'value'})
print(response, url)
print(response.content)
print(response.reason)
return True
Do I have to send other headers to the API to make the PATCH work?

Ah looks like I made a mistake. Forgot to replace source.url with the new url variable called 'url' variable. Because that add the 'ss_id' at the url' so it becomes 'api/title/ID/' instead of just 'api/title'
url = source.url + str(self.ss_id) + '/'
response = requests.patch(url, headers=headers, data={'key':'value'})

Related

How to fix "Process exited before completing request" in Python Requests?

I am trying to replicate the successful POST operation performed using Postman in Python. My code is something like this:
import requests
url = "https://api.appx.com/v1/gen_ticket"
headers = {
'authorizationtoken': "Bearer " + access_token,
'x-api-key': "ddQk4mlTAl5cUj0N7omg4457jXuYlH25kOdvJoeJN3",
'catalogitem': "eb29189cd00576b00dd3cf5951d96197d",
'Content-Type': "application/json",
}
response = requests.request("POST", url, headers=headers)
print(response.text)
but when i run this, i keep getting the following error (This is working properly when using Postman but not in Python code).
{"errorMessage":"RequestId: af75334a-f955-11e8-b2e7-17baf7f53f31 Process exited before completing request"}
Can someone please suggest how to fix this?
One more thing to above is, i am passing a JSON file in Postman body section (how can i use the same in python code as well?)
try change authorizationtoken to Authorization
import requests
url = "https://api.appx.com/v1/gen_ticket"
headers = {
'Authorization': "Bearer " + access_token,
'x-api-key': "ddQk4mlTAl5cUj0N7omg4457jXuYlH25kOdvJoeJN3",
'catalogitem': "eb29189cd00576b00dd3cf5951d96197d",
'Content-Type': "application/json",
}
response = requests.post(url, headers=headers)
print(response.text)

Using requests to POST to pastebin API

I simply cannot get this to work.
header = {"Content-Type": "application/json; charset=utf8"}
params = {"api_dev_key": dev_key, "api_user_name": username, "api_user_password": password}
req = requests.post("http://pastebin.com/api/api_login.php", params = json.dumps(params), headers = header)
print(req.status_code, req.reason, req.text)
The variables (my credentials) are just strings.
The response I get:
(200, 'OK', u'Bad API request, invalid api_dev_key')
There's nothing wrong with the key, this POST works fine when I use https://www.hurl.it
You need to just use data=params:
req = requests.post("http://pastebin.com/api/api_login.php", data=params)

Browsermob proxy - is there a way to add custom cookies via REST API?

I'm looking for a way to add 2 custom cookies to every http request.
The browsermob proxy (https://github.com/lightbody/browsermob-proxy) has removeHeaders() and addHeader() methods, but what can I do to keep existing cookies in request, but add 2 more cookies?
Thanks!
You can use this method to invoke your custom js code in each request/response
https://github.com/lightbody/browsermob-proxy#http-request-manipulation
Some example in Python
def response_interceptor(self, js):
"""
Executes the javascript against each response
:param js: the javascript to execute
"""
r = requests.post(url='%s/proxy/%s/interceptor/response' % (self.host, self.port),
data=js,
headers={'content-type': 'x-www-form-urlencoded'})
return r.status_code
def request_interceptor(self, js):
"""
Executes the javascript against each request
:param js: the javascript to execute
"""
r = requests.post(url='%s/proxy/%s/interceptor/request' % (self.host, self.port),
data=js,
headers={'content-type': 'x-www-form-urlencoded'})
return r.status_code
and test:
def test_request_interceptor_with_parsing_js(self):
"""
/proxy/:port/interceptor/request
"""
js = 'alert("foo")'
status_code = self.client.request_interceptor(js)
assert(status_code == 200)
As I answered above, you could use proxy's REST API to set custom js handler on every request, made through the proxy.
For example you could add any custom cookies to every request:
curl -X POST -H 'Content-Type: text/plain' -d 'js code' http://10.100.100.20:8080/proxy/8081/interceptor/request
In php it would look like:
/**
* #param Proxy $proxyObject
* #param array $cookiesArray
*/
protected function _setRequestCookies(Proxy $proxyObject, array $cookiesArray)
{
foreach ($cookiesArray as $nameString => $valueString) {
$cookiesArray[$nameString] = $nameString . '=' . $valueString;
}
$jsHandlerString = sprintf(
'var c = request.getMethod().getFirstHeader("Cookie") ? request.getMethod().getFirstHeader("Cookie").getValue() : ""; request.getMethod().setHeader("Cookie", c + "; %s");',
implode('; ', $cookiesArray)
);
$urlString = sprintf('%sproxy/%u/interceptor/request', $this->_hubUrlString, $proxyObject->getPort());
$this->_requesterObject->makeRequest($urlString, Requester::REQUEST_METHOD_POST, $jsHandlerString);
}

Access-Control-Allow-Origin error with XMLHttpRequest

I'm developing a Django server. I need to get some data from an external service here.
Here is the JavaScript code that I'm using:
function getDeclination(latitude, longitude) {
var url = 'http://www.ngdc.noaa.gov/geomag-web/calculators/calculateDeclination';
url += '?';
url += 'lat1=' + latitude;
url += '&'
url += 'lon1=' + longitude;
url += '&';
url += 'resultFormat=xml';
var xmlHttp = null;
xmlHttp = new XMLHttpRequest();
xmlHttp.open( "GET", url, false );
xmlHttp.send();
xml = xmlHttp.responseXML;
var temp_d = xml.getElementsByTagName('declination');
var string = temp_d[0].childNodes[0].nodeValue;
string = string.substring(1, string.length - 2);
return parseFloat(string);
}
Using this code for a call like this getDeclination(46.0815605783, 13.2158580422) rise this error:
XMLHttpRequest cannot load
http://www.ngdc.noaa.gov/geomag-web/calculators/calculateDeclination?lat1=46.0815605783&lon1=13.2158580422&resultFormat=xml.
Origin http://127.0.0.1:8000 is not allowed by Access-Control-Allow-Origin
How can I get rid of this problem and return to testing?
EDIT:
So I installed the middleware and the JS, but I can't get results.
Perhaps I have done some error during the installation of the middleware, it's the first time for me.
I know that Django found it, and that it's udsing it, but I don't know if I have done the setup correctly.
XS_SHARING_ALLOWED_ORIGINS = "http://127.0.0.1:8000"
XS_SHARING_ALLOWED_METHODS = ['POST','GET','OPTIONS', 'PUT', 'DELETE']
I have put this code in settings.py, is this correct? Because I still get the same error.
Use this middleware while you're developing, and disable it when you put everything into production.
Edit:
As for the Javascript side of things, I've just tested this and it works ok. It does require jQuery and the middleware to be installed though.
function getDeclination(latitude, longitude){
var url = "http://www.ngdc.noaa.gov/geomag-web/calculators/calculateDeclination";
url += "?";
url += "lat1=" + latitude;
url += "&"
url += "lon1=" + longitude;
url += "&";
url += "resultFormat=xml";
$.ajax({
url: url,
success: function(data){
var declination = parseFloat($(data).find("declination").text());
alert(declination);
}
});
}
In the end I implemented the code to get the declination from a server call.
For sake of completeness here is the code:
import urllib2
from xml.dom.minidom import parseString
# build the url
def buildUrl(latitude, longitude):
return settings.MAGNETIC_URL + '?' + 'lat1=' + str(latitude) + '&' + 'lon1=' + str(longitude) + '&' + 'resultFormat=xml'
# load the page from the address
def retrieveWeb(address):
try:
web_handle = urllib2.urlopen(address)
except urllib2.HTTPError, e:
error_desc = BaseHTTPServer.BaseHTTPRequestHandler.responses[e.code][0]
print "Cannot retrieve URL: HTTP Error Code", e.code, "Error: ", error_desc
sys.exit(1)
except urllib2.URLError, e:
print "Cannot retrieve URL: " + e.reason[1]
sys.exit(1)
except:
print "Cannot retrieve URL: unknown error"
sys.exit(1)
return web_handle
# main function to get declination
def retrieveDeclination(lat, lng):
# build url
address = buildUrl(lat, lng)
# get the page
page = retrieveWeb(address)
# get xml
xml = page.read()
page.close()
# inizio il parsin
dom = parseString(xml)
#retrieve the first xml tag (<tag>data</tag>) that the parser finds with name tagName:
xmlTag = dom.getElementsByTagName('declination')[0].toxml()
#strip off the tag (<tag>data</tag> ---> data):
xmlData=xmlTag.replace('<declination>','').replace('</declination>','')
# parse the output as float
return float(xmlData)

POST SOAP request in python getting error Response: 403 Forbidden

Please can anyone help out? i am trying to POST a SOAP request in python but i am getting the error Response 403: Forbidden. my code looks like below:
i am using the python imports:
import httplib
import base64
import string
#the message
message = """<soap:Envelope ...rest message </soap:Envelope>"""
host = "host.test.com"
url = 'https://server.etc.com' #End point url
i need to use the Basic Authentication too so i need the username and password in the http header
username = 'username'
password = 'password'
webSoapAction = 'urn:etc-com:document...'
#the Authentication in base64 encoding form for Basic Authentication
auth = 'Basic' + string.strip(base64.encodestring(username +'.'+ password))
webservice = httplib.HTTP(host) #connect to the server(host)
here i try to build the header:
webservice.putrequest("POST", url)
webservice.putheader("Host", host)
webservice.putheader("User-Agent", "Python http auth")
webservice.putheader("Content-Type:", "text/xml; charset=\"UTF-8\"")
webservice.putheader("Content-length", "%d" % len(message))
webservice.putheader("SOAPAction",webSoapAction)
webservice.putheader('Authorization', auth)
webservice.endheaders()
webservice.send(message)
i should get the response here
#get the response
statuscode, statusmessage, header = webservice.getreply()
print "Response: ", statuscode, statusmessage
print "Headers: ",header
res = webservice.getfile().read()
print 'Content: ', res
Two things regard to your basic auth header construction:
Put a single space between "Basic" and your secret
Use ':' instead of '.' in between username and password
So it should looks like:
#the Authentication in base64 encoding form for Basic Authentication
auth = 'Basic ' + string.strip(base64.encodestring(username +':'+ password))