How do I catch "split" exceptions in python? - python

I am trying to parse a list of email addresses to remove the username and '#' symbol only leaving the domain name.
Example: blahblah#gmail.com
Desired output: gmail.com
I have accomplished this with the following code:
for row in cr:
emailaddy = row[0]
(emailuser, domain) = row[0].split('#')
print domain
but my issue is when I encounter a improperly formatted email address. For example if the row contains "aaaaaaaaa" (instead of a valid email address) the program crashes with the error
(emailuser, domain) = row[0].split('#')
ValueError: need more than 1 value to unpack.
(as you would expect) Rather than check all the email addresses for their validity, I would rather just not update grab the domain and move on to the next record. How can I properly handle this error and just move on?
So for the list of:
blahblah#gmail.com
mmymymy#hotmail.com
youououou
nonononon#yahoo.com
I would like the output to be:
gmail.com
hotmail.com
yahoo.com
Thanks!

You want something like this?
try:
(emailuser, domain) = row[0].split('#')
except ValueError:
continue

You can just filter out the address which does not contain #.
>>> [mail.split('#')[1] for mail in mylist if '#' in mail]
['gmail.com', 'hotmail.com', 'yahoo.com']
>>>

What about
splitaddr = row[0].split('#')
if len(splitaddr) == 2:
domain = splitaddr[1]
else:
domain = ''
This even handles cases like aaa#bbb#ccc and makes it invalid ('').

Try this
In [28]: b = ['blahblah#gmail.com',
'mmymymy#hotmail.com',
'youououou',
'nonononon#yahoo.com']
In [29]: [x.split('#')[1] for x in b if '#' in x]
Out[29]: ['gmail.com', 'hotmail.com', 'yahoo.com']

This does what you want:
import re
l=["blahblah#gmail.com","mmymymy#hotmail.com",
"youououou","nonononon#yahoo.com","amy#bong#youso.com"]
for e in l:
if '#' in e:
l2=e.split('#')
print l2[-1]
else:
print
Output:
gmail.com
hotmail.com
yahoo.com
youso.com
It handles the case where an email might have more than one '#' and just takes the RH of that.

if '#' in row[0]:
user, domain = row[0].split('#')
print domain

Maybe the best solution is to avoid exception handling all together.
You can do this by using the builtin function partition(). It is similar to split() but does not raise ValueError when the seperator is not found. Read more: https://docs.python.org/3/library/stdtypes.html#str.partition

We can consider the string not having '#' symbol, as a simple username:
try:
(emailuser, domain) = row[0].split('#')
print "Email User" + emailuser
print "Email Domain" + domain
except ValueError:
emailuser = row[0]
print "Email User Only" + emailuser
O/P:
Email User : abc
Email Domain : gmail.com
Email User : xyz
Email Domain : gmail.com
Email User Only : usernameonly

Related

Undesirable line break mysteriously appearing in a print() invocation

I'm printing some variables, like this:
print("First name:", first_name)
print("Last name:", last_name)
print("Password:", password)
The first two are displayed just fine but the last one is like this:
Password:
<the password>
Which is undesirable and inconsistent with the other ones, which is why I want it to look like this:
Password:<the password>
Using end="" did not help.
Try to convert the password into string inside the print func
print("password:",str(password))
Your password variable contains a linebreak (or its string representation does).
Either of these formatting methods will print a string variable inline with no linebreak:
>>> password = "blarf"
>>> print("password:", password)
password: blarf
>>> print(f"password: {password}")
password: blarf
If the variable contains a linebreak, though, you'll get a linebreak in the output:
>>> password = "\nblarf"
>>> print("password:", password)
password:
blarf
Try:
print("password:",password.strip())
Your password variable content likely has a linebreak before it. strip gets rid of that. Note that it also removes all whitespaces before and after the string characters in password, including before and after spaces. If you wish to only remove linebreaks from before and after, use:
print("password:",password.strip("\n"))
Try and remove any newline char that exist in the password string.
You can do so using the following:
first_name = "david"
last_name = "s"
password = "\n1234"
print("firstname:",first_name)
print("lastname:",last_name)
print("password:",password)
# firstname: david
# lastname: s
# password:
# 1234
# removing the new line
password = password.replace("\n","")
print("firstname:",first_name)
print("lastname:",last_name)
print("password:",password)
# firstname: david
# lastname: s
# password: 1234
import re
re.sub("\n", "", password)
print("firstname:",first_name)
print("lastname:",last_name)
print("password:",password)
# firstname: david
# lastname: s
# password: 1234
The first option is using replace method of string object which you can read about in the following link:
https://www.tutorialspoint.com/python/string_replace.htm
The second option is using sub of the re module which you can read about in the following link:
https://note.nkmk.me/en/python-str-replace-translate-re-sub/
Managed to resolve the problem thanks to Samwise I used :
password.splitlines()
password = password[1]
print("password:",password)
David S method works fine too
password = password.replace("\n","")
print("password:",password)

Django - checking if instance exists results in internal server error 500

I am trying to check if I have an entry in my database using this code:
def device_update(request):
json_data = json.loads(request.body)
email = json_data['email']
imei = json_data['imei']
sdk_version = json_data['sdk_version']
date = json_data['updateDate']
rule = json_data['ruleName']
group_name = json_data['group']
if Group.objects.filter(group=group_name).exists():
print("group does exists")
else:
print("group doesn't exists")
return HttpResponse("Successful")
However, when the code reaches the if statement to check if the group exists, it returns error 500.
I tried to check with two groups one that exists and another one that doesn't, in both cases I got error 500.
How can I fix this and why is this happening?
The logic for checking if a Group exists, i.e. the line:
if Group.objects.filter(group=group_name).exists()
is not throwing the error here. It is likely that json_data is missing one of the keys you expect it to have, for example, 'group'.
I'd recommend using the get method that dictionaries have. This provides default values when the specified key is not present in the dictionary. You should also have error handling for when the request body is not in valid JSON format.
Here's an example:
def device_update(request):
try:
json_data = json.loads(request.body)
except json.JSONDecodeError:
return HttpResponse('Request body must be in valid JSON format')
email = json_data.get('email', '')
imei = json_data.get('imei', '')
sdk_version = json_data.get('sdk_version', '')
date = json_data.get('updateDate', '')
rule = json_data.get('ruleName', '')
group_name = json_data.get('group', '')
if Group.objects.filter(group=group_name).exists():
print("group does exists")
else:
print("group doesn't exists")
return HttpResponse("Successful")
I set the defaults to the empty string '', but you may want to change that.
Your view doesn't have any error handling. Looking at it quickly, at least two things could go wrong. The request body might not be valid json, and if it is valid json, it might not contain the required keys.
def device_update(request):
try:
json_data = json.loads(request.body)
except ValueError:
return HttpResponse("Invalid json")
try:
email = json_data['email']
imei = json_data['imei']
sdk_version = json_data['sdk_version']
date = json_data['updateDate']
rule = json_data['ruleName']
group_name = json_data['group']
except KeyError as e:
return HttpResponse("Missing Key %s" % e[0])
...
Writing your own validation for a single view like this is ok. As it gets more complicated, you might want to look at django rest framework. It has serializers which will help you manage validation.
Alasdair/Keselme, looks that your view is correct.
Try to put the ipdb into your code in order to debug your code, and than you can print the request.data and see what is comming in the request.

Bad search filter

Im trying to filter few attributes from the ldap server but get errors,
ldap.FILTER_ERROR: {'desc': 'Bad search filter'}
Code:-
import ldap
ldap.OPT_REFERRALS = 0
ldap_server="ldapps.test.com"
username = "testuser"
password= "" #your password
connect = ldap.open(ldap_server)
dn='uid='+username;
print 'dn =', dn
try:
result = connect.simple_bind_s(username,password)
print 'connected == ', result
filter1 = "(|(uid=" + username + "\*))"
result = connect.search("DC=cable,DC=com,DC=com",ldap.SCOPE_SUBTREE,filter1)
print result
except ldap.INVALID_CREDENTIALS as e:
connect.unbind_s()
print "authentication error == ", e
Your search filter is, in fact, bad.
The | character is for joining several conditions together in an OR statement. For example, if you wanted to find people with a last name of "smith", "jones", or "baker", you would use this filter:
(|(lastname=smith)(lastname=jones)(lastname=baker))
However, your filter only has one condition, so there's nothing for the | character to join together. Change your filter to this and it should work:
"(uid=" + username + "\*)"
By the way, what are you trying to do with the backslash and asterisk? Are you looking for people whose usernames actually end with an asterisk?

Simple beginner stuff, multiple conditional test

ok, this seems like it should be really simple but Im a bit confused:
i have two values - domain and ip
its best described with code:
whois_result = Popen(['whois', str(domain)], stdout=PIPE,stderr=STDOUT).communicate()[0]
debug_output(whois_result)
if 'Not found' or 'No entries' in whois_result:
print "Processing whois failure on '%s'" % str(domain)
print "Trying the IP (%s) instead..." % ip
whois_result = Popen(['whois', ip], stdout=PIPE,stderr=STDOUT).communicate()[0]
debug_output(whois_result)
if 'Not found' or 'No entries' in whois_result:
print "complete and utter whois failure, its you isnt it, not me."
return False
else:
test = re.search("country.+([A-Z].)",whois_result)
countryid = test.group(1)
so this function checks the domain whois, if it doesnt find it, its tries a whois with the ip address, but what I want to know is what is the best way to check if the domain is equal to None dont bother with the domain check and go onto the ip check, yet also if the domain is NOT equal to None, do the domain check and then the ip check in that order. Sorry if this is basic, this has me a bit confused. I guess i could set a variable and test for that but is there a more elegant way of doing it ?
if i put at the top a
if domain != None:
the only way it seems i can do it is by repeating the code or setting a variable, I guess there must be other conditional tests I could use that I dont know about.
EDIT: update 2 based on answers below: - ive also put in the country checking code with my database.
def do_whois(data):
if data is not None: return Popen(['whois', str(data)], stdout=PIPE,stderr=STDOUT).communicate()[0]
return 'No entries'
def check_whois(data):
conn = sqlite3.connect(db_name)
cursor = conn.cursor()
if 'No entries' in data or 'Not found' in data or 'No match for' in data:return False
id = re.search("country.+([A-Z].)",data)
if id is None:
print "we didnt get nuttin from whois"
return False
countryid = id.group(1)
# fetch country from countrycode db
cursor.execute("SELECT country,countrycode FROM countries WHERE countrycode = ?",(countryid,))
country = cursor.fetchone()
country = country[0]
print "Server is from: " + country
return (country,countryid)
def find_country(domain, ip):
return check_whois(do_whois(domain)) or check_whois(do_whois(ip))
part of the problem with making this robust is the varying values returned by the whois server eg for this IP: 67.222.137.216
the whois server returns :
# : whois 67.222.137.216
#
# Query terms are ambiguous. The query is assumed to be:
# "n 67.222.137.216"
#
# Use "?" to get help.
#
#
# The following results may also be obtained via:
# http://whois.arin.net/rest/nets;q=67.222.137.216?showDetails=true&showARIN=false&ext=netref2
#
BLUESQUAREDATAVPSLLC BLUESQUAREDATAVPSLLCNET (NET-67-222-137-213-1) 67.222.137.213 - 67.222.137.244
DFW Datacenter DFW-DATACENTER (NET-67-222-128-0-1) 67.222.128.0 - 67.222.159.255
#
# ARIN WHOIS data and services are subject to the Terms of Use
# available at: https://www.arin.net/whois_tou.html
#
thanks for any help.
Try this
def do_whois(data):
if data: return Popen(['whois', str(data)], stdout=PIPE,stderr=STDOUT).communicate()[0]
return 'No entries'
def check_whois(data):
if 'No entries' in data or 'Not found' in data:return False
test = re.search("country.+([A-Z].)",whois_result)
return test.group(1)
def find_whois(domain, ip):
return check_whois(do_whois(domain)) or check_whois(do_whois(ip))
This isn't going to work :
if 'Not found' or 'No entries' in whois_result:
This is interpreted as if ('Not found') or ('No entries' in whois_result) which always returns True.
To answer your question:
if domain != None && domain != 1:
-edit-
If you meant None instead of "one", you should simply put your IP checking code (which is to be executed after the domain check) on the same indenting level as the domain check.
This condition is wrong:
if 'Not found' or 'No entries' in whois_result:
It will always evaluate as "true", because the expression 'Not found' or 'No entries' in whois_result will always return 'Not found'.
You need to changed the if-statement to:
if 'Not found' in whois_result or 'No entries' in whois_result:

Cant seem to find how to check for valid emails in App Engine

any one know where any docs might be about this?
So far I've only found this
http://code.google.com/appengine/articles/djangoforms.html
EmailProperty() only validates for empty strings... sigh
The following validates the email address on the server:
from google.appengine.api import mail
if not mail.is_email_valid(to_addr):
# Return an error message...
Hope that helps?
If you check the source for Google's mail function you'll see that mail.is_email_valid() only checks that the string is not None/empty.
From this site I found an RFC822 compliant Python email address validator.
import re
qtext = '[^\\x0d\\x22\\x5c\\x80-\\xff]'
dtext = '[^\\x0d\\x5b-\\x5d\\x80-\\xff]'
atom = '[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+'
quoted_pair = '\\x5c[\\x00-\\x7f]'
domain_literal = "\\x5b(?:%s|%s)*\\x5d" % (dtext, quoted_pair)
quoted_string = "\\x22(?:%s|%s)*\\x22" % (qtext, quoted_pair)
domain_ref = atom
sub_domain = "(?:%s|%s)" % (domain_ref, domain_literal)
word = "(?:%s|%s)" % (atom, quoted_string)
domain = "%s(?:\\x2e%s)*" % (sub_domain, sub_domain)
local_part = "%s(?:\\x2e%s)*" % (word, word)
addr_spec = "%s\\x40%s" % (local_part, domain)
email_address = re.compile('\A%s\Z' % addr_spec)
# How this is used:
def isValidEmailAddress(email):
if email_address.match(email):
return True
else:
return False
* If you use this please use this version as it contains the name and so on of the person whom created it.

Categories