In __init__ method when i try to access get_movie_detail it displays an error that the object has no attribute.This happens when i try to get data from a list. When i tried returning a single variable in get_movie_detail eg. return title, it successfully returned the title but the same if i am trying to do with a list the below error appears:
Stack trace:
674
Harry Potter and the Goblet of Fire
7.6
Traceback (most recent call last):
File "C:\Users\HOME\Desktop\movie trailer\entertainment.py", line 4, in <module>
movie_name_1=media.Data('Harry potter and goblet of fire')
File "C:\Users\HOME\Desktop\movie trailer\media.py", line 73, in __init__
self.title = detail_new.detail_list[0]
AttributeError: 'list' object has no attribute 'detail_list'
Below is my code:
""" stores requested movie data"""
import webbrowser
import urllib.request
import json
import tmdbsimple as tmdb
tmdb.API_KEY = ''
class Data():
"""takes argument movie_name,searches the data from tmdb database
tmdbSimple is wrapper&classes of tmdb
movie name keyword should be precise so that api can fetch data
accurately.Incomplete keyword could lead to unwanted results.
Attributes:
Search():search method in tmdbsimple.
movie:movie method takes query and return results
search_result:getd the result of searched movies includes
data regarding movies in list format.
movie_id:stores the unique movie ID for a particular movie
title:stores title of movie.
imdb_rating:rating of movie.
movie_overview:short description of movie.
release_date:date on which movie released.
data_yt:searches the movie keyword on youtube api for trailer.
youtube_key:gets key from the search result in json format
trailer.youtube_url:complete youtube link to the trailer
poster_image_url:link to the poster of movie."""
def get_movie_detail(self,movie_name):
print("in am in get_movie_detail")
#search movie id related to query from tmdb api
search = tmdb.Search()
response_old = search.movie(query=movie_name)
search_result = search.results
s_find = search_result[0]#gets the first id of the search result
movie_id = s_find['id']
print(movie_id)
#uses movie id to get the details of movie
movie = tmdb.Movies(movie_id)
response = movie.info()#stores the movie information in dict format
title = response['title']#if you try to print title in the definition it will print correctly
print(title)
vote = response['vote_average']
print(vote)
discript = response['overview']
date = response['release_date']
poster_id = response['poster_path']
detail_list = [title,vote,discript,date,poster_id]
return detail_list
"""" issue is that if i try calling from __init__ its not returning any attributes of get_movie_detail,Is there scope issue?"""
def get_trailer_link(self,movie_name):
print("I am in get_trailer")
query_new = urllib.parse.quote_plus(movie_name+'trailer')
data_yt = urllib.request.urlopen("https://www.googleapis.com/youtube/v3/search?part=snippet&maxResults=5&q="+query_new+"&type=video&key=")
trailer_data = data_yt.read()
youtube_json = json.loads(trailer_data)
youtube_key = str(youtube_json['items'][0]['id']['videoId'])
def __init__(self,movie_name):
"""stores the atrributes of instances"""
detail_new = self.get_movie_detail(movie_name)
self.title = detail_new.detail_list[0] #***while trying to get data from method it shows error:'NoneType' object has no attribute 'title'***
print(self.title)
self.imdb_rating = detail_new.vote.detail_list[1]
print(self.imdb_rating)
self.movie_overview = detail_new.detail_list[2]
print(self.movie_overview)
self.release_date = detail_new.detail_list[3]
print(self.release_date)
#uses youtube api to get the url from the search result
#gets movie image from the database tmdbsimple api
self.trailer_youtube_url = "https://www.youtube.com/watch?v="+str(self.get_trailer_link.youtube_key)
self.poster_image_url = "http://image.tmdb.org/t/p/w185"+str(poster_id)
def trailer(self):
"""opens youtube url"""
webbrowser.open(self.trailer_youtube_url)
You don't need to try to access detail_list, your detail_new is that list.
You can get the title by accessing detail_new[0].
So that portion of your __init__() function becomes:
self.title = detail_new[0]
self.imdb_rating = detail_new[1]
self.movie_overview = detail_new[2]
self.release_date = detail_new[3]
Related
from pymed import PubMed
pubmed = PubMed(tool="PubMedSearcher", email="daspranab239#gmail.com")
search_term = "Your search term"
results = pubmed.query(search_term, max_results=500)
articleList = []
articleInfo = []
for article in results:
Print the type of object we've found (can be either PubMedBookArticle or PubMedArticle).
We need to convert it to dictionary with available function
articleDict = article.toDict()
articleList.append(articleDict)
Generate list of dict records which will hold all article details that could be fetch from PUBMED API
for article in articleList:
#Sometimes article['pubmed_id'] contains list separated with comma - take first pubmedId in that list - thats article pubmedId
pubmedId = article['pubmed_id'].partition('\n')[0]
Append article info to dictionary
articleInfo.append({u'pubmed_id':pubmedId,
u'title':article['title'],
u'keywords':article['keywords'],
u'journal':article['journal'],
u'abstract':article['abstract'],
u'conclusions':article['conclusions'],
u'methods':article['methods'],
u'results': article['results'],
u'copyrights':article['copyrights'],
u'doi':article['doi'],
u'publication_date':article['publication_date'],
u'authors':article['authors']})
Generate Pandas DataFrame from list of dictionaries
articlesPD = pd.DataFrame.from_dict(articleInfo)
articlesPD
when I try to execute above code I got KeyError: 'keywords', 'journal', 'conclusions', .. etc.
Based on the following code, article is an instance other than dict, so the fields should be access by . other than get or bracket []
Reference https://github.com/gijswobben/pymed/blob/master/pymed/article.py#L124
class PubMedArticle(object):
def _initializeFromXML(self: object, xml_element: TypeVar("Element")) -> None:
""" Helper method that parses an XML element into an article object.
"""
# Parse the different fields of the article
self.pubmed_id = self._extractPubMedId(xml_element)
self.title = self._extractTitle(xml_element)
self.keywords = self._extractKeywords(xml_element)
self.journal = self._extractJournal(xml_element)
self.abstract = self._extractAbstract(xml_element)
self.conclusions = self._extractConclusions(xml_element)
self.methods = self._extractMethods(xml_element)
self.results = self._extractResults(xml_element)
self.copyrights = self._extractCopyrights(xml_element)
self.doi = self._extractDoi(xml_element)
self.publication_date = self._extractPublicationDate(xml_element)
self.authors = self._extractAuthors(xml_element)
self.xml = xml_element
The following could be helpful.
from pymed import PubMed
import json
pubmed = PubMed(tool="PubMedSearcher", email="daspranab239#gmail.com")
search_term = "Your search term"
results = pubmed.query(search_term, max_results=500)
articleList = []
articleInfo = []
def get_data(article, name):
return getattr(article, 'name', 'N/A')
for article in results:
pubmedId = article.pubmed_id.partition('\n')[0]
articleInfo.append({
u'pubmed_id': pubmedId,
u'title': article.title,
u'keywords': get_data(article, 'keywords'),
u'journal': get_data(article, 'journal'),
u'abstract': article.abstract,
u'conclusions': get_data(article, 'conclusions'),
u'methods': get_data(article, 'methods'),
u'results': get_data(article, 'results'),
u'copyrights': article.copyrights,
u'doi': article.doi,
u'publication_date': article.publication_date,
u'authors': article.authors})
print(json.dumps(articleInfo, indent=4, default=str))
I am trying to test my own update_or_create method written in Python, but I run into a error, I Googled it and find no answer.
Here is the source code:
class ListingManager(models.Manager):#manage the creating/editting/deleting of listings
def update_or_create_listing(self, listing_attributes, scraped = False, **extra_attributes):
from sitebot.tasks import scrape_listing_url
keys = listing_attributes.keys()
print keys
site = Site.objects.get(id = listing_attributes['site_id'])
if 'sku' in keys and 'site_id' in keys and 'url' in keys:
#create a listing if no such listing exists
#SiteUrl.objects.get_or_create(href )
listing, created = self.get_or_create(sku = listing_attributes['sku'], site = site, defaults = {'url': listing_attributes['url']})
dynamo_db_listing_attributes = []
if len(keys)> 3:
dynamo_db_listing_attributes = listing.create_or_update_attributes(listing_attributes = listing_attributes, **extra_attributes)
if scraped == True and listing.scraped == False: #if the listing is already scraped, update the scraped status
listing.scraped = scraped
listing.save()
if created == True and listing.scraped == False: #if the listing is just created and not scraped yet
scrape_listing_url.delay(listing_id = str(listing.id), sku = listing.sku, listing_url = listing.url, scraper_name = listing.site.scraper.name) # what does delay do?
return listing, listing_attributes
else:
raise KeyError
and this is the test code:
class ListingManagerClassTests(TestCase):
def setUp(self):
#Generate Site for listing
site = models.Site()
#Generating Site requires ForeignKey Country
country_for_site = models.Country()
country_for_site.save()
#Generating Site requires ForeignKey Scraper
scraper_for_site = models.Scraper()
scraper_for_site.scrapes_per_day = 1
scraper_for_site.max_results = 10
scraper_for_site.save()
site.country = country_for_site
site.scraper = scraper_for_site
site.name = "siteforListingMangerTest"
site.save()
def test_create_listing(self):
"""update_or_create_listing should return the created listing"""
lm = models.ListingManager()
site = models.Site.objects.get(name="siteforListingMangerTest")
listing_attributes = {'sku':'123456','site_id':site.id,
'url':'www.aaa.com'}
#Create the new listing
created_listing, created_listing_attributes = lm.update_or_create_listing(listing_attributes,False)
#check if the retreived listing is the right one
assertEqual(created_listing.sku, '123456')
assertEqual(created_listing.site, site)
assertEqual(created_listing.url,'www.aaa.com')
and the error is:
ERROR: test_create_listing (sitebot.tests.ListingManagerClassTests)
update_or_create_listing should return the created listing
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/wx2228/Desktop/BestBot/bestbot/sitebot/tests.py", line 35, in test_create_listing
created_listing, created_listing_attributes = lm.update_or_create_listing(listing_attributes,False)
File "/home/wx2228/Desktop/BestBot/bestbot/sitebot/models.py", line 90, in update_or_create_listing
listing, created = self.get_or_create(sku = listing_attributes['sku'], site = site, defaults = {'url': listing_attributes['url']})
File "/usr/local/lib/python2.7/dist-packages/django/db/models/manager.py", line 127, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py", line 402, in get_or_create
lookup, params = self._extract_model_params(defaults, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py", line 457, in _extract_model_params
for f in self.model._meta.fields:
AttributeError: 'NoneType' object has no attribute '_meta'
source code for Listing:
class Listing(models.Model):#representing the listing of an product
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
dynamoDB_connection = DynamoDBConnection(region=RegionInfo(name='us-west-2', endpoint='dynamodb.us-west-2.amazonaws.com'))
listings_dynamo_table = Table(table_name = 'sitebot_listings', connection= dynamoDB_connection)
sku = models.CharField(max_length=50)
site = models.ForeignKey(Site)
url = models.CharField(max_length=200, null = True)
scraped = models.BooleanField(default = False)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
objects = ListingManager()
Instantiating the ListingManager directly prevents the query engine to find the underlying object.
You can fix this by replacing the line:
lm = models.ListingManager()
With the line:
lm = Listing.objects
(or maybe)
lm = Listing.objects.all()
Anyway, you need to refer to the Manager through the Model itself, otherwise the query manager will get lost.
It should work (I just spent half a day on a similar problem. Gotta love Django magic error messages ;) )
Python is trying to find the field _meta in self.model. When it says that NoneType does not have that attribute, it means that self.model is None at the point you hit that line. You will have to trace back through your code and see why its value would be None at that point.
This happened to me when I rename a table and set a Foreign key of another table to it.
Make it on 2 migrations, and it should work ;)
Question: I am trying to debug a function in a class to make sure a list is implemented and if not, I want an error to be thrown up. I am new to programming and am trying to figure how to effectively add an assert for the debugging purposes mentioned above.
In the method body of class BaseAPI() I have to iterate over the list and call retrieve_category for each item in ConvenienceAPI(BaseAPI), passing the new list on your super(). I think that I am doing something wrong because I get the error: TypeError: create_assessment() got an unexpected keyword argument 'category'
Question 2
I also want category to have a list to hold multiple categories (strings). This is not happening right now. The list in the method is not being iterated or created. I am unsure... see the traceback error below.
CODE
instantiating a list of categories:
api = BaseAPI()
api.create_assessment('Situation Awareness', 'Developing better skills', 'baseball', 'this is a video','selecting and communicating options', category=['Leadership', 'Decision-Making', 'Situation Awareness', 'Teamwork and Communication'])
BaseAPI() method where assert and create lives
class BaseAPI(object):
def create_assessment(self, name, text, user, video, element, category):
category = [] # Trying to check if category isn't a list
assert category, 'Category is not a list'
new_assessment = Assessment(name, text, user, video, element, category)
self.session.add(new_assessment)
self.session.commit()
NEW ADD TO iterate through list but still gives Error!
class ConvenienceAPI(BaseAPI):
def create_assessment(self, name, text, username, videoname, element_text, category_name):
user = self.retrieve_user(username)
video = self.retrieve_video(videoname)
element = self.retrieve_element(element_text)
categories = self.retrieve_category(category_name)
for items in categories: # < ==== added
return categories # < ==== added
return super(ConvenienceAPI, self).create_assessment(name, text, user, video, element, categories)
Table
class Assessment(Base):
__tablename__ = 'assessments'
#some code
category_id = Column(Integer, ForeignKey('categories.category_id'))
category = relationship('AssessmentCategoryLink', backref='assessments')
def __init__(self, name, text, user, video, element, category): # OBJECTS !!
#some code
self.category = []
TracebackError
ERROR: db.test.test.test1
----------------------------------------------------------------------
Traceback (most recent call last):
File "/usr/local/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
self.test(*self.arg)
File "/Users/ack/code/venv/NotssDB/notssdb/test/test.py", line 69, in test1
api.create_assessment('Situation Awareness', 'Developing better skills', 'baseball', 'this is a video','selecting and communicating options', category=['Leadership', 'Decision-Making', 'Situation Awareness', 'Teamwork and Communication'])
TypeError: create_assessment() got an unexpected keyword argument 'category'
Your assert statement should be:
assert isinstance(category, list)
Remove the category = [] line as well.
You pass category as kwarg, but method signature expects it as positional arg.
Try to change method signature to
class BaseAPI(object):
def create_assessment(self, name, text, user, video, element, category=[]):
or call it with positional arg
return super(ConvenienceAPI, self).create_assessment(
name, text, user, video, element, category=category
)
In short, how do i
var="TableName"
models.var.query.all()
explanation
My goal is to allow the user to change the order of list of items.
I set up an ajax call that sends an array of id's to the api below.
It works if i hard code the query, and make a api view per table.
my problem is that i want "table" to fill in this line
models.table.query.filter_by(id=item).first()
to complete the query.
here is the view api which gives me an error "no attribute 'table'"
#app.route('/order/<table>')
def order(table):
# import pdb;pdb.set_trace()
sortedItems = request.args.listvalues()[0]
o=1
import pdb;pdb.set_trace()
for item in sortedItems:
grab = models.table.query.filter_by(id=item).first()
grab.order=o
o=o+1
db.session.commit()
return jsonify(result=sortedItems)
You can use getattr():
>>> var = 'table_name'
>>> table = getattr(models, var)
>>> table.query.filter_by(id=item).first()
getattr() will raise an AttributeError if the attribute your trying to get does not exist.
Example for your order()-function:
#app.route('/order/<table>')
def order(table):
sortedItems = request.args.listvalues()[0]
o=1
table = getattr(models, table)
for item in sortedItems:
grab = table.query.filter_by(id=item).first()
grab.order=o
o=o+1
db.session.commit()
return jsonify(result=sortedItems)
I am using GAE Python. I have two root entities:
class X(ndb.Model):
subject = ndb.StringProperty()
grade = ndb.StringProperty()
class Y(ndb.Model):
identifier = ndb.StringProperty()
name = ndb.StringProperty()
school = ndb.StringProperty()
year = ndb.StringProperty()
result = ndb.StructuredProperty(X, repeated=True)
Since google stores our data across several data centers, we might not get the most recent data when we do a query as shown below(in case some changes have been "put"):
def post(self):
identifier = self.request.get('identifier')
name = self.request.get('name')
school = self.request.get('school')
year = self.request.get('year')
qry = Y.query(ndb.AND(Y.name==name, Y.school==school, Y.year==year))
record_list = qry.fetch()
My question: How should I modify the above fetch operation to always get the latest data
I have gone through the related google help doc but could not understand how to apply that here
Based on hints from Isaac answer, Would the following be the solution(would "latest_record_data" contain the latest data of the entity):
def post(self):
identifier = self.request.get('identifier')
name = self.request.get('name')
school = self.request.get('school')
year = self.request.get('year')
qry = Y.query(ndb.AND(Y.name==name, Y.school==school, Y.year==year))
record_list = qry.fetch()
record = record_list[0]
latest_record_data = record.key.get()
There's a couple ways on app engine to get strong consistency, most commonly using gets instead of queries and using ancestor queries.
To use a get in your example, you could encode the name into the entity key:
class Y(ndb.Model):
result = ndb.StructuredProperty(X, repeated=True)
def put(name, result):
Y(key=ndb.Key(Y, name), result).put()
def get_records(name):
record_list = ndb.Key(Y, name).get()
return record_list
An ancestor query uses similar concepts to do something more powerful. For example, fetching the latest record with a specific name:
import time
class Y(ndb.Model):
result = ndb.StructuredProperty(X, repeated=True)
#classmethod
def put_result(cls, name, result):
# Don't use integers for last field in key. (one weird trick)
key = ndb.Key('name', name, cls, str(int(time.time())))
cls(key=key, result=result).put()
#classmethod
def get_latest_result(cls, name):
qry = cls.query(ancestor=ndb.Key('name', name)).order(-cls.key)
latest = qry.fetch(1)
if latest:
return latest[0]
The "ancestor" is the first pair of the entity's key. As long as you can put a key with at least the first pair into the query, you'll get strong consistency.