Accessing variable outside class using inheritance - python

I am trying to inherit a variable from base class but the interpreter throws an error.
Here is my code:
class LibAccess(object):
def __init__(self,url):
self.url = url
def url_lib(self):
self.urllib_data = urllib.request.urlopen(self.url).read()
return self.urllib_data
class Spidering(LibAccess):
def category1(self):
print (self.urllib_data)
scrap = Spidering("http://jabong.com")
scrap.category1()
This is the output:
Traceback (most recent call last):
File "variable_concat.py", line 16, in <module>
scrap.category1()
File "variable_concat.py", line 12, in category1
print (self.urllib_data)
AttributeError: 'Spidering' object has no attribute 'urllib_data'
What is the problem with the code?

You will need to define self.urllib_data prior to accessing it. The simples way would be to create it during initialization, e.g.
class LibAccess(object):
def __init__(self,url):
self.url = url
self.urllib_data = None
That way you can make sure it exists everytime you try to access it. From your code I take it that you do not want to obtain the actual data during initialization. Alternatively, you could call self.url_lib() from __init__(..) to read the data for the first time. Updating it later on would be done in the same way as before.

Related

list() method in API causing TypeError: 'list' object is not callable in unit test

I'm working on code that retrieves information from Twilio's Flow system through their API. That part of the code functions fine, but when I try to mock it for unit testing, it's throwing an error from the mocked api response.
Here is the code being tested:
from twilio.rest import Client
class FlowChecker:
def __init__(self, twilio_sid, twilio_auth_token):
self.twilio_SID = twilio_sid
self.twilio_auth_token = twilio_auth_token
self.client = Client(self.twilio_SID, self.twilio_auth_token)
self.calls = self.client.calls.list()
self.flows = self.client.studio.v2.flows
def get_active_executions(self):
active_executions = []
for flow in self.flows.list():
executions = self.client.studio.v2.flows(flow.sid).executions.list()
for execution in executions:
if execution._properties['status'] != 'ended':
active_executions.append({'flow_sid': flow.sid, 'execution': execution})
And here is my unit test code that's throwing the error:
import unittest
from unittest.mock import Mock, patch
from flows.twilio_flows import FlowChecker
class FlowCheckerTest(unittest.TestCase):
#patch('flows.twilio_flows.Client')
def test_get_active_flows(self, mock_client):
flow_checker = FlowChecker('fake_sid', 'fake_auth_token')
mock_call = Mock()
mock_flow = Mock()
mock_flow.sid = 0
mock_execution = Mock()
mock_execution._properties = {'status': 'ended'}
mock_client.calls.list().return_value = [mock_call]
mock_client.studio.v2.flows = [mock_flow]
mock_client.studio.v2.flows(mock_flow.sid).executions.list().return_value = [mock_execution]
self.assertEqual(flow_checker.get_active_executions(), [])
And here is the error traceback:
Ran 2 tests in 0.045s
FAILED (errors=1)
Error
Traceback (most recent call last):
File "C:\Users\Devon\AppData\Local\Programs\Python\Python310\lib\unittest\mock.py", line 1369, in patched
return func(*newargs, **newkeywargs)
File "C:\Users\Devon\PycharmProjects\Day_35\tests\twilio_flows_test'.py", line 19, in test_get_active_flows_when_empty
mock_client.studio.v2.flows(mock_flow.sid).executions.list().return_value = [mock_execution]
TypeError: 'list' object is not callable
Process finished with exit code 1
As you can see, "mock_client.calls.list().return_value = [mock_call]" doesn't throw any errors during init, and the first code block runs fine. It's only the mocked executions.list() that's throwing the error in the test.
Can anyone clear this up?
Thank you!
I've tried researching this specific issue and was unable to find information addressing it. It's a very specific deeply nested function in a vendor supplied client that I need to test, so I don't know what to try.
The problem isn't with .list(), it's with .flows().
mock_client.studio.v2.flows = [mock_flow]
mock_client.studio.v2.flows(mock_flow.sid).executions.list().return_value = [mock_execution]
You assign .flows to be a list, and then you try to call it like a function, which causes the error.
I think maybe you intended to say .flows[mock_flow.sid] instead of .flows(mock_flow.sid)?
Although even that doesn't make sense. .flows is a one-element list, so you would use .flows[0] to access the first (and only) item.

Trouble executing my class crawler

I'm completely newbie to python when it comes to scrape any web data using class. So, apology in advance for any serious mistake. I've written a script to parse the text using a tag from wikipedia web site. I tried to write the code accurately from my level best but for some reason when i execute the code it throws error. The code and the error I'm having are given below for your kind consideration.
The script:
import requests
from lxml.html import fromstring
class TextParser(object):
def __init__(self):
self.link = 'https://en.wikipedia.org/wiki/Main_Page'
self.storage = None
def fetch_url(self):
self.storage = requests.get(self.link).text
def get_text(self):
root = fromstring(self.storage)
for post in root.cssselect('a'):
print(post.text)
item = TextParser()
item.get_text()
The error:
Traceback (most recent call last):
File "C:\Users\mth\AppData\Local\Programs\Python\Python35-32\testmatch.py", line 38, in <module>
item.get_text()
File "C:\Users\mth\AppData\Local\Programs\Python\Python35-32\testmatch.py", line 33, in get_text
root = fromstring(self.storage)
File "C:\Users\mth\AppData\Local\Programs\Python\Python35-32\lib\site-packages\lxml\html\__init__.py", line 875, in fromstring
is_full_html = _looks_like_full_html_unicode(html)
TypeError: expected string or bytes-like object
You're executing the following two lines
item = TextParser()
item.get_text()
When you initialize TextParser, self.storage is equal to None. When you execute the function get_text() it's still equal to None. So that's why you get that error.
However, if you change it to the following. self.storage should get populated with a string rather than being none.
item = TextParser()
item.fetch_url()
item.get_text()
If you want to call the function get_text without calling fetch_url you can do it this way.
def get_text(self):
self.fetch_url()
root = fromstring(self.storage)
for post in root.cssselect('a'):
print(post.text)

Django database sqlite display of value of attribute

I'm on a project using django and I wrote my models.py
I have two classes
class Adresse(models.Model):
numV=models.IntegerField(blank=False,null=False)
complementdest=models.TextField(blank=False,null=False)
complementadr=models.TextField(blank=False,null=False)
commune=models.TextField(blank=False,null=False)
codeP=models.IntegerField(blank=False,null=False)
pays=models.TextField(blank=False,null=False)
def __str__(self):
return self.numV
return self.complementdest
return self.complementadr
return self.commune
return self.codeP
return self.pays
def __Adr__(self):
return self.adr1.all()
and
class CompteCandidat(myUser):
sexe = models.TextField(max_length=10)
datecr = models.DateTimeField(auto_now_add = True)
adresse=models.OneToOneField('Adresse',related_name='adr1',null=True, default=None)
def __str__(self):
return self.first_name
return self.last_name
return self.email
return self.sexe
def __Adr__(self):
return self.adresse.all()
I try to do some tests like this:
adresse=Adresse(numV='254',complementdest='xxxxx',complementadr='Eugene napoleon',commune='Paris',codeP='75012',pays='France')
c1=CompteCandidat(username='Luna',first_name='celia',last_name='durand',password='CCC',email='hello2#gmail.com',type='candidat',adresse=adresse)
adresse.save()
c1.save()
and when I try to see what I have in my Adresse or in my CompteCandidat by using this command it didn't work
>>> Adresse.__getattribute__(numV)
Traceback (most recent call last):
File "<input>", line 1, in <module>
NameError: name 'numV' is not defined
i want to know what i'm suppose to do to display what I have in Adresse and CompteCandidat in order to be sure that the add works
i know i Can do :
>>> adresse.numV
'254'
but it works only in the console there is an another way to consult all the database without using the name of the temporery variables ????
You can use
Adresse.objects.all()
to see all records or Adresse.object.filter(numV='254)
to see records satisfying this condition.
For full reference please check:
https://docs.djangoproject.com/ja/1.9/topics/db/queries/
At first in the console try this:
>>>A = {numV='254',complementdest='xxxxx',complementadr='Eugene napoleon',commune='Paris',codeP='75012',pays='France'}
>>> adresse = Adresse(**A)
>>> adresse.save()
At first you will face an error beacuse your numV is Integer but you are assigning an String to it, so should edit numV = '254' to numV = 254 at first line.
Then try above steps again and post that in which step face error.
Two things :
__str__ must only return a single string - as it stands your code tries to return multiple non string values.
the __getattribute__ method (and it's counterpart getattr) should be passed the name of the attribute i.e. a string. Also you shouldn't be trying to call __getattribute__ directly except in exceptional circumstances: ie. you have some form of circular access confilct - which you don't here.
There is no reason that adresse.numV shouldn't work directly in your code - that is the normal way to retrieve attributes from an instance. You should only use getattr if you have the attribute name in a string from elsewhere.
At the risk of sounding rude - if you are struggling to write code that correctly accesses attributes then maybe trying to write a Django App is a case of trying to run before you walk.

Failing hard at OOP in python

This represents a simple class, that I have made to try and practice OOP.
import csv
import logging
class LoaderCSV:
def __init__(self, file):
self.file = file
if file is None:
logging.warning('Missing input file.')
def load(self):
with open(self.file) as f:
holder = csv.reader(f)
file_data = list(holder)
return file_data
What happens is when I call this class with:
data = LoaderCSV.load(input_file)
I get
line 14, in load
with open(self.file) as f:
AttributeError: 'str' object has no attribute 'file'
I must be messing something up, but can't understand what. My previous attempt worked just fine this way. I just don't understand why
self.file
does not pass the value, assigned to the argument, when it is defined under __init__
The problem is you're calling an instance method as a static method, so your filename is being passed in instead of self. The proper way to do this would be like:
loader = LoaderCSV(input_file)
data = loader.load()
This will pass in loader as the self parameter, allowing you to access the file name in the object's file field.
Check out the Python documentation on classes for more information.
You need to create the LoaderCSV object first, then call the load method on that object.
loader = LoaderCSV(input_file)
data = loader.load()
The way to use the instance method load is to make an instance of your class, and then call the method on that class. Like this:
myloader = LoaderCSV(input_file)
data = myloader.load()
or succinctly:
data = LoaderCSV(input_file).load()

Django queryset.first bug? May involve django-polymorphic and mixins

I have a model, and I have instantiated several instances and persisted them to the database. Through the python shell I can confirm that the objects exist, but I run into trouble as soon as I try to work with the queryset via the queryset.first() call, as well as indexing into the queryset.all() result. I'm using the django-polymorphic plugin.
>>> Thing.objects.all()
[<Thing: thing1>, <Thing: thing2>, <Thing: thing3>]
>>> Thing.objects.first()
>>> str(Thing.objects.first())
'None'
>>> Thing.objects.all()[0]
Traceback (most recent call last):
File "<console>", line 1, in <module>
File ".../python3.4/site-packages/django/db/models/query.py", line 201, in __getitem__
return list(qs)[0]
IndexError: list index out of range
>>> Thing.objects.all().__class__
<class 'polymorphic.query.PolymorphicQuerySet'>
>>>
I strongly suspect this involves the fact that I'm using a mixin for Thing on top of the polymorphic base class. Here's what my hierarchy looks like (boiled down to make it easier for y'all):
from django.db import models
from polymorphic.polymorphic_model import PolymorphicModel
class AwesomeMixin(object):
def reallyUsefulMethod(self):
print('show me your MOVES')
class BaseThing(PolymorphicModel, AwesomeMixin):
pass
class Thing(BaseThing):
pass
class Doohickey(BaseThing):
pass
class SomethingElse(models.Model, AwesomeMixin):
pass
Anyone know what's going on here? Am I using mixins correctly? Is the issue related to django-polymorphic? Thanks!

Categories