AttributeError: 'unicode' object has no attribute 'success' - python

I have a simple script using requests to validate a list of emails. Relevant code:
def ___process_email(email, output_file=None):
profile = request(email)
if profile and profile.success != 'nothing_useful':
logger.info('Found match for {0}'.format(email))
print(profile)
if output_file:
output_file.write(str(profile) + '\n')
else:
print("No information found\n")
This ran through 5 loops successfully then threw:
Traceback (most recent call last):
File "app.py", line 147, in <module> main()
File "app.py", line 141, in main ___process_email(arg, output)
File "app.py", line 107, in ___process_email if profile and profile.success != 'nothing_useful':
AttributeError: 'unicode' object has no attribute 'success'
Here's the model:
class Profile(object):
def __init__(self, person):
if person:
self.name = person.get('name')
self.jobinfo = [
(occupation.get('job_title'), occupation.get('company'))
for occupation in person.get('occupations', [])
]
self.memberships = [
(membership.get('site_name'), membership.get('profile_url'))
for membership in person.get('memberships', [])
]
self.success = person.get('success')
def __str__(self):
return dedent("""
Name: {0}
{1}
{2}
""").format(
self.name,
"\n".join(
"{0} {1}".format(title, company)
for title, company in self.jobinfo),
"\n".join(
"\t{0} {1}".format(site_name, url)
for site_name, url in self.memberships)
)
Request:
import requests
def request(email):
status_url = STATUS_URL.format(email)
response = requests.get(status_url).json()
session_token = response.get('session_token')
# fail gracefully if there is an error
if 'error' in response:
return response['error']
elif response['status'] == 200 and session_token:
logger.debug('Session token: {0}'.format(session_token))
url = URL.format(email)
headers = {'X-Session-Token': session_token}
response = requests.get(url, headers=headers).json()
if response.get('success') != 'nothing_useful':
return Profile(response.get('contact'))
return {}
Anyone see why my strings are unicode? thanks

If there is an error in the response, you return the error string:
if 'error' in response:
return response['error']
That's your unicode value there. Note that the same function returns either the 'error' value, a new Profile() instance, or an empty dictionary. You may want to make this more consistent, return only Profile() istances and None instead.
Instead of the error string, raise an exception and handle the exception in your ___process_email method:
class EmailValidationError(Exception):
pass
and in your request() function:
if 'error' in response:
raise EmailValidationError(response['error'])
then handle this in __process_email() with something like:
try:
profile = request(email)
if profile and profile.success != 'nothing_useful':
logger.info('Found match for {0}'.format(email))
print(profile)
if output_file:
output_file.write(str(profile) + '\n')
else:
print("No information found\n")
except EmailValidationError:
# Do something here

Related

Check if person's id exists in a function's dictionary

I have this code to check if a person exists given their id. If they do exist, it has to print the name and last name. If they don't exists, it has to print some error. The thing is, my code only prints the error even though I tried the code with a number I know corresponds to an existing person. How do I fix that?
This is my view:
from django.shortcuts import render, HttpResponse
import requests
from django.views.generic import FormView
from .forms import MonotributoForm
from app.ws_sr_padron import get_persona
class ConstanciaInscripcion(FormView):
def get(self, request):
return render(request, 'app/constancia-inscripcion.html')
def post(self,request):
form = MonotributoForm(request.POST)
try:
cuit_r = int(request.POST.get('cuit', '-1')) # Get 'cuit' with default of -1
except ValueError:
pass
response= get_persona(cuit_r)
if response is True:
print(response["persona"]['name'])
print(response['persona']['lastname'])
else:
print("cuit doesn't exist")
if form.is_valid():
cuit = form.cleaned_data.get('cuit')
email = form.cleaned_data.get('email')
cuit.save()
email.save()
return HttpResponseRedirect('app/constancia-inscripcion.html')
return render(request, 'app/constancia-inscripcion.html')
The code for get_persona (I cannot modify this as I did not write it and it was given to me this way):
def get_persona(cuit_requested, ta_sign=None, ta_token=None):
try:
if ta_sign is None and ta_token is None:
ta_sign, ta_token = wsaa.get_ta_sign_token('ws_sr_padron_a13')
client = Client(padron13_wsdl)
response = client.service.getPersona(
sign=ta_sign,
token=ta_token,
cuitRepresentada=cuit_consultante,
idPersona=cuit_requested,
)
return serialize_object(response, target_cls=dict)
except Fault as e:
if e.message == 'No person with Id':
return None
elif e.message == 'inactive':
return 'inactive'
print('Error: ', e)
return None
except Exception as e:
print('Error: ', e)
return None
Result of get_persona with an existing id (tried on terminal):
{'metadata': {'fechaHora': datetime.datetime(2021, 3, 4, 15, 13, 54, 738000, tzinfo=<FixedOffset '-03:00'>), 'servidor': 'linux11b'}, 'persona': {'apellido': 'POLAR', 'estadoClave': 'ACTIVO', 'idPersona': 2231230211, 'mesCierre': 12, 'nombre': 'MAURICIO', 'tipoClave': 'CUIT'}}
The output of response on it's own seems to be None for some reason.
The issue is due to the conditional in your code: if response is True.
If you look at the value that get_persona returns, it can be the result of the function serialize_object(...), None, or "inactive".
If the serialize_object(...) function returns a None or the string "inactive", the statement response is True will be false.
>>> type(True)
bool
>>> type({"a": 1})
dict
>>> type("inactive")
str
# To test this, I created this function
>>> def test_response(response):
return response is True
>>> test_response(None)
False
>>> test_response({"persona": True})
False
>>> test_response("inactive")
False
# The only value of response that `is True` is the value `True` itself!
>>> test_response(True)
True
What you want to do is change your conditional to check for a useful response value. In this case, you could test if the response value is a dict, but what if it doesn't have the persona value -- or what if the persona exists, but it doesn't have a nombre?
>>> response = {"a": 1}
>>> response["persona"]["nombre"]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'persona'
>>> response = {"persona": None}
>>> response["persona"]["nombre"]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object is not subscriptable
A better solution than an if statement would be a try/except, which can handle both types of errors gracefully and default to the invalid/error case.
response = get_persona(cuit_r)
try:
nombre = response["persona"]["nombre"]
apellido = response["persona"]["apellido"]
except KeyError:
nombre, apellido = None, None
print("get_persona response is missing keys!")
except TypeError:
nombre, apellido = None, None
print("get_persona response had wrong type!")
else:
print("get_persona returned a valid response!")
print("nombre:", nombre)
print("apellido:", apellido)
Update #1
Based on your comments, it also sounds like you're having trouble with the cuit_r value as well. You should change your code to properly handle the possible exceptions as separate statements:
try:
cuit_r = int(request.POST["cuit"])
except KeyError:
print("The key 'cuit' was missing from the POST data.")
print("Defaulting to cuit_r = -1")
cuit_r = -1
except TypeError:
print(
"The 'cuit' value is the wrong type:",
type(request.POST["cuit"]),
)
print("Defaulting to cuit_r = -1")
cuit_r = -1
print(f"Resolved value of cuit_r: {type(cuit_r).__name__}({cuit_r!r})")

Value error: view didn't return an HttpResponse object. It returned None instead Django

I'm yet to understand why I'm getting 'HttpResponse' error.
Traceback (most recent call last):
File "C:\Python27\Scripts\covaenv\lib\site-packages\django\core\handlers\exception.py", line 42, in inner
response = get_response(request)
File "C:\Python27\Scripts\covaenv\lib\site-packages\django\core\handlers\base.py", line 198, in _get_response
"returned None instead." % (callback.__module__, view_name)
ValueError: The view exampleapp.views.get_recieve_update didn't return an HttpResponse object. It returned None instead.
This view is responsible for getting a POST request from an API and load the data and do things with it.
Views:
#csrf_exempt
def get_recieve_update(request):
if request.method=="POST":
man= json.loads(request.body)
txId = man['hash']
uri = bgo_main_base_url + '/wallet/{}/tx/{}'.format(WALLETID, txId)
rexa = requests.get(uri, headers=headers)
vd = rexa.json()
isMine = vd['outputs'][0]['isMine']
confirmations = vd['confirmations']
if isMine == True and confirmations > 1:
address = vd['outputs'][0]['account']
value = vd['outputs'][0]['value']
try:
get_adr = CPro.objects.get(address = address)
except CPro.DoesNotExist:
get_adr = None
if not get_adr.is_used==True and get_adr.is_active==False:
update_cw = CW.objects.filter(user =
get_adr.user).update(current_btc_balance=F('current_btc_balance') + value , modified_date=datetime.datetime.now())
return HttpResponse('done')
elif get_adr.is_used==True and get_adr.is_active==False:
address = vd['outputs'][0]['account']
value = vd['outputs'][0]['value']
send_mail('Recieved on Used Address','failed to credit for {} with {} and id {}'.format(address, value, txId), DEFAULT_FROM_EMAIL,[DE_MAIL,])
else:
address = vd['outputs'][0]['account']
value = vd['outputs'][0]['value']
send_mail('Recieved Callback Error','failed to credit for {} with {}'.format(address, value), DEFAULT_FROM_EMAIL,[DE_MAIL,])
What am I missing here?
You need to return an HttpResponse on every condition.In last if else statement you can see you are not returning anything from the view so you have to return an appropriate http response for every case in your view. See updated code below.
#csrf_exempt
def get_recieve_update(request):
if request.method=="POST":
man= json.loads(request.body)
txId = man['hash']
uri = bgo_main_base_url + '/wallet/{}/tx/{}'.format(WALLETID, txId)
rexa = requests.get(uri, headers=headers)
vd = rexa.json()
isMine = vd['outputs'][0]['isMine']
confirmations = vd['confirmations']
if isMine == True and confirmations > 1:
address = vd['outputs'][0]['account']
value = vd['outputs'][0]['value']
try:
get_adr = CPro.objects.get(address = address)
except CPro.DoesNotExist:
get_adr = None
if not get_adr.is_used==True and get_adr.is_active==False:
update_cw = CW.objects.filter(user =
get_adr.user).update(current_btc_balance=F('current_btc_balance') + value , modified_date=datetime.datetime.now())
return HttpResponse('done')
elif get_adr.is_used==True and get_adr.is_active==False:
address = vd['outputs'][0]['account']
value = vd['outputs'][0]['value']
send_mail('Recieved on Used Address','failed to credit for {} with {} and id {}'.format(address, value, txId), DEFAULT_FROM_EMAIL,[DE_MAIL,])
return HttpResponse("Some appropriate response")
else:
# return something. If both condition from does not get true then there will be no return from view
else:
address = vd['outputs'][0]['account']
value = vd['outputs'][0]['value']
send_mail('Recieved Callback Error','failed to credit for {} with {}'.format(address, value), DEFAULT_FROM_EMAIL,[DE_MAIL,])
return HttpResponse("Some appropriate response") # <-- here you were not returning a response
Another Helpful answer

Django & Python AttributeError: 'Retailer' object has no attribute

In my test file:
class TestMakeSoup(TestCase):
fixtures = ['deals_test_data.json']
def test_string_is_valid(self):
s = Retailer.objects.get(pk=1)
with open('/home/danny/PycharmProjects/askarby/deals/tests/BestBuyTest.html', 'r') as myfile:
text = myfile.read().replace('\n', '')
self.assertTrue(s.make_soup(text))
In the file it's testing:
class retailer():
'''
Retail site, drawn from database queryset object
'''
def __init__(self,r_object):
'''
Initializes retailer variables
obj -> nonetype
Precondition: r_object.currency == 3
Precondition: r_object.name != None
'''
assert len(r_object.currency) == 3, "{} must be a three-letter string (eg 'USD').".format(r_object.currency)
assert r_object.name != None, "Name must exist."
assert r_object.deal_container_css != None, "Title css must exist."
assert r_object.title_css != None, "Title css must exist."
assert r_object.price_css != None, "Price css must exist."
self.name = r_object.name
self.base_url = r_object.base_url
self.currency = r_object.currency
#dict containing css lookup values for various fields
self.css = {}
self.css['container'] = self.extract_css(r_object.deal_container_css)
self.css['title'] = self.extract_css(r_object.title_css)
self.css['product_model'] = self.extract_css(r_object.product_model_css)
self.css['price'] = self.extract_css(r_object.price_css)
self.css['old_price'] = self.extract_css(r_object.old_price_css)
self.css['brand'] = self.extract_css(r_object.brand_css)
self.css['image'] = self.extract_css(r_object.image_css)
self.css['description'] = self.extract_css(r_object.description_css)
self.css['exclude'] = self.extract_css(r_object.exclude_css)
self.css['shipping'] = self.extract_css(r_object.shipping_css)
#dict containing associated clearance urls for retailer
self.clearance_urls = self.get_clearance_urls()
#dict to house final list of deals
self.deals = {}
def __str__(self):
return self.name
def make_soup(self, text):
assert isinstance(text,str), "text must be string."
soup = bs4.BeautifulSoup(text, "html.parser")
if soup:
return soup
return False
The Retailer call refers to the Retailer model in my deals app.
I get this error:
Error
Traceback (most recent call last):
File "/home/danny/PycharmProjects/askarby/deals/tests/test_deals.py", line 101, in test_string_is_valid
self.assertTrue(s.make_soup(text))
AttributeError: 'Retailer' object has no attribute 'make_soup'
Why isn't make_soup running as a method?
The retailer class takes an object retrieved from the database. I retrieved the object from the database but didn't create a class with it.
def test_makesoup(self):
z = Retailer.objects.get(pk=1)
s = dealscan.retailer(z)
with open('/home/danny/PycharmProjects/askarby/deals/tests/BestBuyTest.html', 'r') as myfile:
text = myfile.read().replace('\n', '')
self.assertTrue(s.make_soup(text))
solves it.

Python Request Libary Error 404 Handling Soundcloud API

So I'm attempting to create a program that takes the genre and location of recently uploaded Soundcloud tracks and displays them on a map. I'm trying to gather the data using the Soundcloud API however at random points while the program is executing an HTTPError gets thrown. Here's my code:
import soundcloud
import urllib2
client = soundcloud.Client(client_id="xxxxx",
client_secret="xxxxx",
username="xxxx",
password="xxxx")
def main():
for trackId in getAllTrackId('tracks/'):
try:
trackId = str(trackId)
userId = str(client.get('tracks/' + trackId).user_id)
genre = client.get('tracks/' + trackId).genre
country = client.get('users/' + userId).country
city = client.get('users/' + userId).city
user = client.get('tracks/' + trackId).user
except urllib2.HTTPError, e:
print e.geturl()
if (type(city) != None) & (type(country) != None) & (type(genre) != None):
try:
print 'User: ' + userId + '\t\tLocation: ' + city + ', ' + country + '\t\tGenre: ' + genre
except:
print trackId
def getAllTrackId(path):
items=[]
page_size=200
offset=0
page = client.get(path, limit=page_size, offset=offset)
#while (len(page) != 0):
while (offset<=1000):
for item in page:
items.append(item.id)
offset += page_size
page = client.get(path, limit=page_size, offset=offset)
return items
main()
I'm trying to figure out how to catch the error but also why it is thrown in the first place. I'm new to programming so I'm sure there are many errors in my code but if anyone could help me through this it would be awesome :)
(env)xxxxxxx-MacBook-Pro-2:soundcloudmap xxxxxxxxxx$ python soundcloudmap.py
User: 1278531 Location: Detroit, United States Genre: HSB
User: 1139662 Location: Brasilia, Brazil Genre: Beat
159333532
User: 23129248 Location: Cadiz, Spain Genre: Breaks
159333523
User: 10761166 Location: Wadsworth, United States Genre: Say
Traceback (most recent call last):
File "soundcloudmap.py", line 43, in <module>
main()
File "soundcloudmap.py", line 28, in main
userId = str(client.get('tracks/' + trackId).user_id)
File "/Users/michaelspearman/code/soundcloudmap/env/lib/python2.7/site-packages/soundcloud/client.py", line 130, in _request
return wrapped_resource(make_request(method, url, kwargs))
File "/Users/michaelspearman/code/soundcloudmap/env/lib/python2.7/site-packages/soundcloud/request.py", line 134, in make_request
result.raise_for_status()
File "/Users/michaelspearman/code/soundcloudmap/env/lib/python2.7/site-packages/requests/models.py", line 795, in raise_for_status
raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 404 Client Error: Not Found
EDIT:
To catch the error I just need to follow the path of the error correctly.. duhh
except urllib2.HTTPError, e:
should be
except requests.exceptions.HTTPError as e:
However I'm still not sure why it's being thrown..
From the Soundclould Python documentation:
tracks = client.get('/tracks', limit=10)
compare this to yours:
client.get('tracks/' + trackId).user_id
More specifically, you are missing the leading /. Adding this should work.

Multiple Term search by following multiple users using Streaming API

I am trying to Retrieve multiple keyword term tweets by following specific group of users. Using the code below:
I have posted one more code before that regarding issues for value error:
I figure it out somehow but again I am stuck because of this traceback
import tweepy
from tweepy.error import TweepError
consumer_key=('ABC'),
consumer_secret=('ABC'),
access_key=('ABC'),
access_secret=('ABC')
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
auth.set_access_token(access_key, access_secret)
api=tweepy.API(auth)
class CustomStreamListener(tweepy.StreamListener):
def on_status(self, status):
try:
print "%s\t%s\t%s\t%s" % (status.text,
status.author.screen_name,
status.created_at,
status.source,)
except Exception, e:
print error
#def filter(self, follow=None, track=None, async=False, locations=None):
#self.parameters = {}
#self.headers['Content-type'] = "application/x-www-form-urlencoded"
#if self.running:
#raise TweepError('Stream object already connected!')
#self.url = '/%i/statuses/filter.json?delimited=length' % STREAM_VERSION
def filter(self, follow=None, track=None, async=False, locations=None):
self.parameters = {}
self.headers['Content-type'] = "application/x-www-form-urlencoded"
if self.running:
raise TweepError('Stream object already connected!')
self.url = '/%i/statuses/filter.json?delimited=length' % STREAM_VERSION
if obey:
self.parameters['follow'] = ' '.join(map(str, obey))
if track:
self.parameters['track'] = ' '.join(map(str, track))
if locations and len(locations) > 0:
assert len(locations) % 4 == 0
self.parameters['locations'] = ' '.join('%.2f' % l for l in locations)
self.body = urllib.urlencode(self.parameters)
self.parameters['delimited'] = 'length'
self._start(async)
def on_error(self, status_code):
return True
streaming_api = tweepy.streaming.Stream(auth, CustomStreamListener(), timeout=60)
list_users = ['17006157','59145948','157009365','16686144','68044757','33338729']#Some ids
list_terms = ['narendra modi','robotics']#Some terms
streaming_api.filter(follow=[list_users])
streaming_api.filter(track=[list_terms])
I am getting a traceback:
Traceback (most recent call last):
File "C:\Python27\nytimes\26052014\Multiple term search with multiple addreses.py", line 49, in <module>
streaming_api.filter(follow=[list_users])
File "build\bdist.win32\egg\tweepy\streaming.py", line 296, in filter
encoded_follow = [s.encode(encoding) for s in follow]
AttributeError: 'list' object has no attribute 'encode'
Please help me resolving the issue.
You define list_users here
list_users = ['17006157','59145948','157009365','16686144','68044757','33338729']
and then you pass it to streaming_api.filter like this
streaming_api.filter(follow=[list_users])
When the streaming_api.filter function is iterating over the value you pass as follow, it gives the error
AttributeError: 'list' object has no attribute 'encode'
The reason for this is as follows
You call streaming_api.filter like this
streaming_api.filter(follow=[list_users])
Here
streaming_api.filter(follow=[list_users])
you are trying to pass your list as value for follow, however because you put list_users in enclosing [] you are creating a list in a list. Then streaming_api.filter iterates over follow, calling .encode on each entry as we see here
[s.encode(encoding) for s in follow]
But the entry s is a list while it should be a string.
That is because you accidentally created a list in a list like you can see above.
The solution is simple. Change
streaming_api.filter(follow=[list_users])
to
streaming_api.filter(follow=list_users)
To pass a list to a function, you can just specify the name. No need to enclose it in []
Same applies to the last line. Change
streaming_api.filter(track=[list_terms])
to
streaming_api.filter(track=list_terms)

Categories

Resources