Python urllib3 Error Handling - python-2.7

I'm fairly new to Python and would like some guidance on how to deal with authentication errors with urrlib3 on Python 2.7. My current use case is using SNAPI to auto create ServiceNow tickets. To do this I have the following snippet of code to use my username/password and get a token to log in.
r = session.post(auth_url, json=login_data, verify=False)
web_token = r.text
This is working fine but I want a cleaner way of notifying myself if there is an error within the code. If the username/password is incorrect, I get this back from the SN web server.
{
"error": "Authentication failure"
}
Originally I was going to use a try/exception but it seems like that wouldn't work very well in this case since the code is working correctly, it's just not the input I was expecting. So my second thought was doing something along the lines of:
if r.text does not contain "error"
then continue on my doe
else send an email telling me the error code
Before writing the code for that, I wanted to see if this is the best method for this type of error handling or if I should be going down another route.
Thanks,
Eric

I spoke with a friend and he recommended the following method which seems to work very well and is a lot cleaner than doing an if/match statement.
try:
r = session.post(auth_url, json=login_data, verify=False)
web_token = r.text
r.raise_for_status()
except Exception as e:
print(e)

Related

How do you return a POST message exactly the way it was received in Flask (meaning no encoding changes)

I have been fighting with Paypals API, and more specifically I've been trying to implement IPN (instant payment notifications) into my flask app. I have gotten it to the point where it works as long as I don't include any special characters. Unfortunately my last name is Engström...
The way it works is that paypal sends a bunch of parameters to you, which you are then supposed to send back exactly the way they came to you, with the addition of a parameter specifying cmd=_notify-validate
My current code is essentially:
#app.route("/paypal_ipn", methods=['POST', 'GET'])
def paypal_ipn_listener():
# Returning message as-is with the notify-validate request
raw_data = "cmd=_notify-validate&" + request.get_data()
response = requests.post(VERIFY_URL, params=raw_data, verify=True)
response.raise_for_status()
# See if PayPal confirms the validity of the IPN received
if response.text == 'VERIFIED':
print(OKGREEN + "Verified IPN response received." + ENDC)
elif response.text == 'INVALID':
# Don't trust
print(FAIL + "Invalid IPN response." + ENDC)
else:
print("Some other response.")
print(response.text)
return ""
And this code in fact works fine so long as my last name is Engstrom rather than Engström when paying for something.
My troubleshooting so far:
Apparently Paypal uses the windows-1252 encoding per default. I however changed for it to use the utf-8 encoding using this SO answer: https://stackoverflow.com/a/46303635/5331467, however that didn't do anything when I made a payment, and I'm sticking with the IPN simulator tool for now, which is stuck with windows-1252
If I print request.form I get among other things ImmutableMultiDict([('last_name', u'Engstr\ufffdm'') which notably looks the same for ä and ö, which at least tells me it sees no distinction between them
The stuff that's in request.get_data() is
payment_type=instant&payment_date=15%3A08%3A30%20Jan%2028%2C%202022%20PST&payment_status=Completed&address_status=confirmed&payer_status=verified&first_name=John&last_name=Engstr%F6m&payer_email=buyer#paypalsandbox.com&payer_id=TESTBUYERID01&address_name=John%20Smith&address_country=United%20States&address_country_code=US&address_zip=95131&address_state=CA&address_city=San%20Jose&address_street=123%20any%20street&business=seller#paypalsandbox.com&receiver_email=seller#paypalsandbox.com&receiver_id=seller#paypalsandbox.com&residence_country=US&item_name1=something&item_number1=AK-1234&tax=2.02&mc_currency=USD&mc_fee=0.44&mc_gross=12.34&mc_gross_1=12.34&mc_handling=2.06&mc_handling1=1.67&mc_shipping=3.02&mc_shipping1=1.02&txn_type=cart&txn_id=474083376&notify_version=2.1&custom=xyz123&invoice=abc1234&test_ipn=1&verify_sign=A8Vpc0Ws5acpR3s0gcM6u4Qtk1utA8eY7wJKy6n.AkPJ6RHIQeSSmBzL
where it says &last_name=Engstr%F6m
Now I don't know if what I want is for it to actually have the right encoding when being sent, or if theres some way for me to ensure it never touches the encoding anyways.
**TL;DR
Taking an incoming POST message and sending it straight back in Flask still screws up the formatting somehow.**
Your first mistake is using IPN for anything at all, it's 20 years old and quite clunky. Don't use IPN, and if you are going to complain that a 20-year-old piece of technology is difficult to integrate from scratch with current web stacks, well, yes it is.
Today's PayPal integrations use REST APIs and the JS SDK. For one-time payments the capture response should be all you need -- however in the rare event that you need asynchronous notifications of later events such as refunds, use Webhooks.

TypeError: can only concatenate str (not "DeferredAttribute") to str

I am wondering anyone can help me in one of the thing I cannot get my around it and really bothering as I spent last two on it but couldnt make it.
Basically, I am building an App (Django Python) to restore the information regarding all the network device e.g hostname, IP Address, S/N, Rack info etc. but I also to enable few options like Add, Edit, Delete and Connect next to device entery. I was able to create all the options except Connect option where I am completely stuck, I am trying to query database to get the IP address information and then using Popen module to open a putty window with the ssh to that IP Address device related, I tried everything I could but nothing worked, thereofrore, asking your help if you have any idea about this ? or any other alternative method for a user when he click on connect the putty or similar app will open and he just put the login credentials and get into the device.
I am sharing my code here, let me know if I am doing something wrong.
on the show all device page, i have this code, show.html
<td>Connect</td>
<!--<td>Connect</td>-->
I tried both ways, with id and ip address entry in the database
on view.py
def connect(request, ip_address):
hostlist_ip = HostList.ip_address
print(hostlist_ip)
Popen("putty.exe" + hostlist_ip)
return redirect('/show')
and in the url.py
path('connect/<str:ip_address>', views.connect),
or
path('connect/<str:ip_address>', views.connect),
Since I am also printing the the output on the terminal I notice that it is not returning the actually IP address but return this;
<django.db.models.query_utils.DeferredAttribute object at 0x04B77C50>
and on the web I receiving this error
TypeError at /connect/10.10.32.10
can only concatenate str (not "DeferredAttribute") to str
Request Method: GET
Request URL: http://localhost:8000/connect/10.10.32.10
Django Version: 2.2.3
Exception Type: TypeError
Exception Value:
can only concatenate str (not "DeferredAttribute") to str
let me know if you can help.
Just a F.Y.I I already tested the Popen via python but since we not getting the actual IP address from the database I am seeing this and I am a complete newbie with html/css and Djano, however I have some basic knowledge of python, so please ignore my any stupid comments in the post.
Many thanks
ahh I cannot believe I spend two day to troubleshoot this and just changed the name from ip_address to ip_add and it is working now :) i think as I mentioned above in the comment, it probably confusing with the built in module
here is simple solution:
views.py
def connect(request, ip_add):
import os
from subprocess import Popen
Popen("powershell putty.exe " + ip_add)
return redirect('/show')
url.py
path('connect/<str:ip_add>', views.connect),
I may have to find out a way if user is using the mac or linux, how I am going to change this powershell to something else. but anyhow it is working for windows
thanks all for the responses.

Problems with MSF4J and #MatrixParam

Folks, I have found what seems to be a problem with / (bug in ?) MSF4J as including an #MatrixParam annotated variable in a URI causes the affected (micro)service to either 'hang' indefinitely, or if accessed via a browser, to give a "404 Not Found" message for the path/endpoint, even when correct.
Here is a code fragment that illustrates the problem - it compiles ok (eclipse/maven) and deploys without errors using microservicesrunner() in the usual way.
package org.test.service;
import javax.ws.rs.GET;
import javax.ws.rs.MatrixParam;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;
#Path("books")
public class MPTest { // MatrixParam Test
#GET
#Produces(MediaType.TEXT_PLAIN)
#Path("/query")
// method to respond to 'GET' requests
public Response getListOfBooks(#MatrixParam("Author") String author) {
// do something in here to get book data from DB and sort by titles
List<String> titles = .......;
return Response.status(200) .entity("List of Books by " +author+ "ordered by title " + titles).build();
}
}
With this code fragment, accessing the URL "(host:8080)/books/query;Author=MickeyMouse" should cause a list of books by that author to be retrieved from the DB (I have omitted the actual code that does so for clarity, as it is not relevant to this post).
However, it does not get there, so that code isnt executed. As far as I can tell with a debugger, no #MatricParam value is retrieved - it remains null until the process times out. Things like curl and wget just hang until they time out, and from a browser, the best I can get is a 404 not found error for the URI, even though it is valid.
However, if I replace the #MatrixParam with a #PathParam it works perfectly, and can I get the URL string retrieved in its entirity. The URI that I get is as expected - no odd hex characters, no typos, and so forth. The URI entered is what you get back. So, no problem there.
Behaviour is also consistent across platforms (couple of flavours of Linux, and three versions of Windoze), so it is not anything to do with the OS itself. Similarly, I get the same behavior with multiple clients and tools, so it isnt a problem there either.
So, it appears to be a problem within the MSF4J framework / domain, and I could use some support / help / suggestions here as I've reached the point of tearing my hair out..... Any ideas, folks?
The only reference I can find to a similar problem was closed as 'off topic' without a reply (see Rest API Matrix param annotation) so I think that this needs re-opening as it seems to be a genuine problem....
Regards, and thanks in advance for any help,
Rick
#MatrixParam is not supported with MSF4J at the moment. You can create a GitHub issue. So we can implement that support in future releases.

Getting an 500 internal error when uploading file using cgi and python

Hi I have a project that involves uploading documents. I am using html for the front end and python for the backend. I've managed to link my html and python file but I'm having a problem with the server. At first I though it was a random thing but I'm pretty sure it's because of what I added to the python code. I have:
import cgi
import sys
import os
htmlform = cgi.FieldStorage()
file_data = htmlform['myfile']
if not fileitem.file:
return
(name,ext) = os.path.splitext( fileitem.filename)
#if ext == “.jpg” or ext == “.png” or ext == “.gif”:
#ioFlag = “wb”
#else:
#ioFlag = “w”
I was able to log into my page go to the html form submit the form and got to a basic success html page I had below the above input. Now Im pretty new to python and didnt realise that the if statements should be indented. And I get a 500 internal error when I uncommented the if statement. I did it once and then went through commenting out my code being completely confused as to why I was getting error but after a while it just started working again. My guess is the incorrect if statement somehow got it stuck. I expect after about an hour it'll be working again but ideally I'd like to know if I could stop the process on the server if possible. I was following this guide http://www.alwaysgetbetter.com/blog/2009/01/02/python-file-upload/
Fixed it! The problem seems to be the indentation. If you're ever unsure about this stuff look at the error logs. I'm using an apache server and I dont have access to the error logs so I used
sudo cat /etc/log/apache2/error.log
It gave me the answer and this should hopefully help you even if your question is unrelated.
EDIT: An for completeness sake file_data should be fileitem

Error with Flex HTTPService and Django, even though POST is successful

(This is the first time I've done this actually.)
<mx:HTTPService id="post_update" method="POST" result="{Dumper.info('bye')}"/>
The result handler above is just for debugging purposes, but its never hit, even though what I'm uploading via POST...
post_update.url = getPath(parentDocument.url)+"update";
post_update.send(new_sel);
...is received and handled successfully by my Django view:
def wc_post(request) :
request.session['wc'] = request.POST
return http.HttpResponse("<ok/>", mimetype="text/xml")
As far as what I'm sending back from Django, I'm following the guidelines here:
Sending Images From Flex to a Server
I just don't want it to generate an error on the Flex side considering Django is actually receiving and processing the data. Any help appreciated. Can't remember the text of the error in Flex at the moment.
UPDATE: new_sel (what I'm posting from Flex) is just a Flex Object, with various text fields.
UPDATE: various error messages from event.message (in fault handler):
faultCode = "Server.Error.Request"
faultString = "HTTP request error"; DSStatusCode = 500; errorID = 2032; type = "ioError"
This is more grasping at straws than answers, but do I have to send a particular type of header back from Django- the default sent by Django includes a 200 success status code, and the response I was sending of "<ok/>" with mime type of "text/xml" was following the example exactly that I provided from that other source.
And also the url I'm sending the POST to is localhost:8000/wr_view1/wr_webcube/update, and I previously successfully did a GET to localhost:8000/wr_view1/wr_webcube/webcube.xml, and despite the .xml extension in the case of GET, it was still being handled by Django (and without errors in Flex). In the case of this POST, once again, the data is actually succesfully sent and handled by Django, but Flex is returning Error 2032, which I found out can mean numerous different things including cross domain issues, but don't see how that's the case here.
Just had to return HttpResponse("ok") Didn't like it being sent as xml for some reason. So much ado about nothing I guess.