How do you mock an object in a list? - python

I have the following function:
signature_request = client.send_signature_request_embedded_with_template(
client_id = self.CLIENT_ID,
template_id = self.template_id,
title = self.title,
subject = self.email_subject,
message = self.message,
signers = self.signers,
custom_fields = self.custom_fields
)
signature_id = signature_request.signatures[0].signature_id
I cannot for the life of me mock the signature_id value in my test. I know that I am properly mocking the correct target because I am successfully mocking another return value from this signature_request object. Any help would be highly appreciated!
I have tried the following:
send_request_mocked.return_value.signatures.return_value =
[PropertyMock(signature_id = 'signature_id')]
send_request_mocked.return_value.signatures.return_value =
[Mock(signature_id = 'signature_id')]
etc.

Related

Django manytomany field holding Users autofilling

I am pulling data from a json file on the web, and updating it in my django database. I want to keep track of users that are associated with each team, but as soon as a user loads the page once they are added to the model. How do I avoid this?
class Team(models.Model):
name = models.CharField(max_length=120)
abbreviation = models.CharField(max_length=3)
id = models.IntegerField(primary_key=True)
link = models.CharField(max_length=120)
wins = models.IntegerField(default=0)
losses = models.IntegerField(default=0)
ties = models.IntegerField(default=0)
points = models.IntegerField(default=0)
users = models.ManyToManyField(User)
def getTeams():
import requests
baseUrl = "https://statsapi.web.nhl.com/"
# INITALIZING THE DATA IN THE DATA DICTIONARY
r = requests.get(baseUrl + '/api/v1/teams')
originalData = r.json()
# i dont need the copyright, only care about the teams
originalData = originalData["teams"]
for team in originalData:
id = team["id"]
try:
databaseTeam = Team.objects.get(id = id)
except Exception:
Team.objects.create(id = id)
databaseTeam = Team.objects.get(id = id)
databaseTeam.name = team["name"]
databaseTeam.abbreviation = team["abbreviation"]
databaseTeam.link = team["link"]
databaseTeam.save()
print("done")
#login_required
def myTeamView(request):
t1 = Thread(target=getTeams)
t1.start()
return(render(request, "teams/myTeams.html", {}))
The user is stored on user variable inside the request, so first we need to pass it to getTeams method. Then we use the method add of Manytomany fields to append an record to it, in this case the user.
def getTeams(request):
import requests
baseUrl = "https://statsapi.web.nhl.com/"
# INITALIZING THE DATA IN THE DATA DICTIONARY
r = requests.get(baseUrl + '/api/v1/teams')
originalData = r.json()
# i dont need the copyright, only care about the teams
originalData = originalData["teams"]
for team in originalData:
id = team["id"]
try:
databaseTeam = Team.objects.get(id = id)
except Exception:
Team.objects.create(id = id)
databaseTeam = Team.objects.get(id = id)
databaseTeam.name = team["name"]
databaseTeam.abbreviation = team["abbreviation"]
databaseTeam.link = team["link"]
databaseTeam.save()
databaseTeam.users.add(request.user) # after save!!
print("done")
#login_required
def myTeamView(request):
t1 = Thread(target=getTeams, args=(request, ))
t1.start()
return(render(request, "teams/myTeams.html", {}))

Python how to return a list to other functions?

I have been trying to return the list so other functions can access it. But in all the other functions the variables become undefined. The command should be "return twitchClipLinks" right?
def api():
#API via twitch to get the top clips of Just Chatting
API_ENDPOINT = 'https://api.twitch.tv/kraken/clips/top?game=Just%20Chatting&period=day&trending=false&limit=6'
ID = 'REMOVED'
auth = 'application/vnd.twitchtv.v5+json'
head = {
'Client-ID' : ID,
'Accept' : auth
}
r = requests.get(url = API_ENDPOINT, headers = head)
twitchClipLinks = []
data = r.json()
for link in data['clips']:
store = str(link['url'])
twitchClipLinks.append(store)
return twitchClipLinks
Inside every function, you have to add something like this: twitchClipLinks = api() Or you can define twitchClipLinks as a global variable and remove the return statement from ur api() function.

'AttributeError: 'NoneType' object has no attribute 'to_dict'

I am developing an API using Google App Engine in Python. I am having trouble sending a GET request to a particular url. I get the 'NoneType' object has no attribute to_dict error. The trouble comes in at out = client.to_dict() in the apiClient.py, which is routed to in main.py by
app.router.add(webapp2.Route(r'/api/client/<clientid:[0-9]+><:/?>', 'apiClient.Client'))
I do not understand why ndb.Key(db_defs.Client, int(kwargs['clientid'])).get() is returning None
apiClient.py:
import webapp2
from google.appengine.ext import ndb
import db_defs
import json
class Client(webapp2.RequestHandler):
#returns all or a specified client(s)
def get(self, **kwargs):
if 'application/json' not in self.request.accept:
self.response.status = 406
self.response.status_message = "Not acceptable: json required"
return
if 'clientid' in kwargs:
client = ndb.Key(db_defs.Client, int(kwargs['clientid'])).get()
out = client.to_dict()
self.response.write(json.dumps(out))
else:
q = db_defs.Client.query()
keys = q.fetch(keys_only=True)
results = { 'keys' : [x.id() for x in keys]}
self.response.write(json.dumps(results))
db_defs.py:
from google.appengine.ext import ndb
#http://stackoverflow.com/questions/10077300/one-to-many-example-in-ndb
class Model(ndb.Model):
def to_dict(self):
d = super(Model, self).to_dict()
d['key'] = self.key.id()
return d
class Pet(Model):
name = ndb.StringProperty(required=True)
type = ndb.StringProperty(choices=set(["cat", "dog"]))
breed = ndb.StringProperty(required=False)
weight = ndb.IntegerProperty(required=False)
spayed_or_neutered = ndb.BooleanProperty()
photo = ndb.BlobProperty()
owner = ndb.KeyProperty(kind='Client')
class Client(Model):
lname = ndb.StringProperty(required=True)
fname = ndb.StringProperty(required=False)
phone = ndb.StringProperty(required=False)
email = ndb.StringProperty(required=False)
staddr = ndb.StringProperty(required=False)
pets = ndb.KeyProperty(kind='Pet', repeated=True, required=False)
def to_dict(self):
d = super(Client, self).to_dict()
d['pets'] = [p.id() for m in d['pets']]
return d
EDIT:
When I do a GET request to http://localhost:8080/api/client/ I get a list of client ids:
{"keys": [4679521487814656, 4855443348258816, 5136918324969472,
5242471441235968, 5277655813324800, 5559130790035456,
5699868278390784, 5805421394657280, 6051711999279104,
6368371348078592, 6544293208522752, 6614661952700416,
6685030696878080]}
which I have verified are the same as those present in the GAE Datastore Viewer.
But when I do a GET request to http://localhost:8080/api/client/4679521487814656
I get the NoneType Error.
client is set to None, which is not an object with a to_dict() method.
client is None because the following expression returned None:
client = ndb.Key(db_defs.Client, int(kwargs['clientid'])).get()
e.g. there is no Client object with that key.

need help creating permalinks in google app engine

So I am trying to create a unique permalink each time that a person posts on my webpage and I want it to be relatively search engine friendly so I have made a little code to change the title to a good search engine title and it is working but then my handler cannot accept it. At least that is what I think is happening because the webpage just gives me a 404 error. The HTML works fine because when I redirect to a static page it all goes through. Here is the applicable code:
def post(self):
subject = self.request.get('subject')
content = self.request.get('content')
if subject and content:
p = Post(parent = blog_key(), subject = subject, content = content)
p.put()
id=str(p.key().id())
subject = str(subject)
subject = subject.replace(' ', '25fdsa67ggggsd5')
subject = ''.join(e for e in subject if e.isalnum())
subject = subject.replace('25fdsa67ggggsd5', '-')
subject = subject.lower()
url = '/blog/%s/%s' % (id, subject)
self.redirect('/blog/%s/%s' % (id, subject))
class PostPage(BlogHandler):
def get(self, post_id):
key = db.Key.from_path('PersonalPost', int(post_id), parent=blog_key())
post = db.get(key)
if not post:
self.error(404)
return
self.render("permalink.html", post = post)
class PersonalPost(db.Model):
subject = db.StringProperty(required = True)
content = db.TextProperty(required = True)
created = db.DateTimeProperty(auto_now_add = True)
last_modified = db.DateTimeProperty(auto_now = True)
user_id = db.StringProperty(required = True)
def render(self):
self._render_text = self.content.replace('\n', '<br>')
return render_str("post.html", p = self)
def blog_key(name = 'default'):
return db.Key.from_path('blogs', name)
app = webapp2.WSGIApplication([('/blog/([0-9]+)/([.*]+)', PostPage)]
And again it works when I just have it redirect to the main page and list them but not when I try to direct to the new SEO page.
UPDATE:
The test url I am using is setting
subject = "test-url"
id = "1234"
The app then directs me to www.url.com/blog/1234/test-url but it gives me a 404 error.
You define two groups in ('/blog/([0-9]+)/([.*]+) but your PostPage.get() only takes one.
Change it to def get(self, post_id, subject) or remove the second group ('/blog/([0-9]+)/[.*]+
I think you should have a look at the quotes on ur handler mapping, it seems inconsistent.
yours: app = webapp2.WSGIApplication([('/blog/([0-9]+)/([.*]+)', PostPage)]
try : app = webapp2.WSGIApplication(['/blog/([0-9]+)/([.*]+)', PostPage)]

Using tastypie resource in view

my first question here :
So I'm using tastypie to have api's for my app.
I want to be able to use tastypie to render json and then include that in a django view so that I can bootstrap my app's data.
There is an example of this in django tastypie cookbook here : http://django-tastypie.readthedocs.org/en/latest/cookbook.html#using-your-resource-in-regular-views
The problem is that I CANNOT get this to work, I've tried variants from simpler to more complex and I just cant get it, here some code for my models :
class ChatMessage(models.Model):
content = models.TextField()
added = models.DateTimeField(auto_now_add=True)
author = models.ForeignKey(ChatUser, related_name="messages")
chat_session = models.ForeignKey(ChatSession, related_name="messages")
answer_to = models.ForeignKey('self', blank=True, null=True)
flagged = models.BooleanField(blank=True,default=False)
mododeleted = models.BooleanField(blank=True,default=False)
mododeleted_by = models.ForeignKey(ChatUser,blank=True,null=True,default=None)
mododeleted_at = models.DateTimeField(blank=True,null=True,default=None)
[...]
class ChatSession (models.Model):
title = models.CharField(max_length=200)
link_title = models.CharField(max_length=200)
description = tinymce_models.HTMLField()
date = models.DateTimeField()
online = models.BooleanField(default=False)
next_session = models.BooleanField(default=False)
meps = models.ManyToManyField(ChatMep)
uid_newsupdate = models.CharField(max_length=200,blank=True,null=True,default="")
[...]
and my resources :
class ChatMessageResource(MyModelResource):
chat_session = fields.ForeignKey(ChatSessionResource, 'chat_session')
def renderOne(self,request,pkval):
data = self.obj_get(None,pk=pkval)
dbundle = self.build_bundle(obj=data,request=request)
return self.serialize(None,self.full_dehydrate(dbundle),'application/json')
def dehydrate(self, bundle):
bundle.data['likes'] = bundle.obj.get_likes()
bundle.data['likes_count'] = len(bundle.data['likes'])
return bundle
class Meta:
authentication = Authentication()
authorization = Authorization()
queryset = ChatMessage.objects.all()
resource_name = 'message'
fields = ('content', 'added', 'flagged', 'mododeleted','author','answer_to','chat_session')
filtering = {
'chat_session': ALL_WITH_RELATIONS,
}
and my view index :
def index(request):
cur_sess = get_current_chat_session()
data1= ChatMessageResource().renderOne(request,723)
return render_to_response('test.html',
{
'all_data' : data1
},
context_instance=RequestContext(request))
What I want is my renderOne() function to give me the json of ONE ChatMessageResource
And also I'd like a renderAll() function to gice me ALL (or filtered) ChatMessageResources in json.
And I want to use tastypie internals, I KNOW i could serialize it by myself but that's not the point..
Right now the error is :
NoReverseMatch at /live/
Reverse for 'api_dispatch_detail' with arguments '()' and keyword arguments '{'pk': 14L, 'resource_name': 'session'}' not found.
I'm just getting crazy, I've been trying for hours.
So please, how to get ONE/ALL resource as JSON by code using tastypie in a django view !
If It's not clear or I need to clarify, please just ask, thanks
Really what I want to do is to be able to get the JSON returned by an API url I created, but from code, not by visiting the url .. So If I have /api/v1/messages/?chat_session=14 which return a list of messages, I want to be able to do the same by code (and not by fetching the url with curl or something please).
Note :
definition of ModelResource.obj_get from https://github.com/toastdriven/django-tastypie/blob/master/tastypie/resources.py
def obj_get(self, request=None, **kwargs):
"""
A ORM-specific implementation of ``obj_get``.
Takes optional ``kwargs``, which are used to narrow the query to find
the instance.
"""
try:
base_object_list = self.get_object_list(request).filter(**kwargs)
object_list = self.apply_authorization_limits(request, base_object_list)
stringified_kwargs = ', '.join(["%s=%s" % (k, v) for k, v in kwargs.items()])
if len(object_list) <= 0:
raise self._meta.object_class.DoesNotExist("Couldn't find an instance of '%s' which matched '%s'." % (self._meta.object_class.__name__, stringified_kwargs))
elif len(object_list) > 1:
raise MultipleObjectsReturned("More than '%s' matched '%s'." % (self._meta.object_class.__name__, stringified_kwargs))
return object_list[0]
except ValueError:
raise NotFound("Invalid resource lookup data provided (mismatched type).")
So here I found the solution, the problem was with url resolving ... I needed to add
def get_resource_uri(self, bundle_or_obj):
return '/api/v1/%s/%s/' % (self._meta.resource_name,bundle_or_obj.obj.id)
to the related object (session here) in order for it to work (don't ask why!)
So here is my working solution for renderDetail and renderList :
def renderDetail(self,pkval):
request = HttpRequest()
request.GET = {'format': 'json'}
resp = self.get_detail(request, pk=pkval)
return resp.content
def renderList(self,options={}):
request = HttpRequest()
request.GET = {'format': 'json'}
if len(options) > 0:
request.GET.update(options)
resp = self.get_list(request)
return resp.content
And here is an example usage :
cmr = ChatMessageResource()
dataOne= cmr.renderDetail("723")
dataAll = cmr.renderList({'limit':'0','chat_session':cur_sess.pk})
https://github.com/toastdriven/django-tastypie/issues/962
I've found that obj_get method needs a bundled request object. See the link.
def user_detail(request, username):
ur = UserResource()
# Add this request bundle to the obj_get() method as shown.
req_bundle = ur.build_bundle(request=request)
user = ur.obj_get(req_bundle, username=username)
....
Your problem seems to be here:
data = self.obj_get(None,pk=pkval)
The parameters to obj_get should be kwargs that can be passed directly to a standard get. None should not be in there.

Categories

Resources