I'm working with Python to create a Google App Engine application.To test my app, i am using html forms to enter data.
In my form i have a line:
<tr><td>Age</td><td><input type="number" size="10" name="age"/></td></tr>
and in my model class, a property defined like this:
class Person(ndb.Model):
...
age = ndb.IntegerProperty()
when i test my app locally it displays the form but on entering a value for age, i get a BadValueError: Expected integer, got u '23' message.Posting image because i do not know how to copy command prompt text.I hope it's clear enough.
Edit: This is how the data is been passed from html form.
# Data taken from the registration form (above) is used to
# create a new member.
class PersonHandler(webapp2.RequestHandler):
def post(self):
# need to check this member-name does not exist
name = self.request.get('name')
callback = self.request.get('callback')
member = Member.get_by_id(name)
if member: # This member name already exists.
self.error(409) # This is the HTTP status code for 'unable to process due to conflict'
else:
...
a = self.request.get("age")
member = Member(age=a,...)
member.put()
if callback:
self.response.write(callback + '(' + member.toJSON + ')')
else:
self.response.write(member.toJSON())
Can someone tell me what am doing wrong?
You simply need to convert the retrieved value to an integer:
...
else:
...
a = int(self.request.get("age"))
Related
My Django project is currently deployed in a test remote server using nginx/gunicorn/supervisor.
I try to update minor change 'on the fly' remotly.
I have a field with expected format: XXX-YY-000
I have added Jquery field mask on a field (AAA-AA-999) and want the user be able to enter lowercase but want to store result in database in uppercase
Moreover, I have form validation:
on length (10)
YY that should correspond to specific XXX (patient_code_is_valid function)
So I modify by code entries using upper() method
Locally, it works but on remote server it doesn't work !
I don't know how to 'debug' to see what is pass to my patient_code_is_valid function...
forms.py
def clean_ran_num(self):
data = self.cleaned_data['ran_num'].upper()
if len(data) != 10:
raise forms.ValidationError(_("Error on Patient code number format (example: XXX-YY-000)"))
if not patient_code_is_valid(data):
raise forms.ValidationError(_("Error on Patient code number: country code does not correspond to site code"))
return data
models.py
def patient_code_is_valid(code):
site = code[4:6].upper()
pays = code[:3].upper()
site_list = [s.sit_abr for s in Site.objects.all()]
pays_list = [p.pay_abr for p in Pays.objects.all()]
if site in site_list and pays in pays_list:
a = Site.objects.get(sit_abr = site).reg.pay.pay_ide
b = Pays.objects.get(pay_abr = pays).pay_ide
if a == b:
return True
return False
only had to restart server to have modfication kaken into account
sudo supervisorctl restart myproject
I'm working on a script to programmatically create a bunch of intents. I want to set the input context for these intents to a specific value. I have working code that creates the full intent - but I can't get the parameter for input context to work.
This works (in python), but does not create an input context:
intents_client = dialogflow_v2beta1.IntentsClient.from_service_account_json(PROJECT_JSON)
parent = intents_client.project_agent_path(PROJECT_ID)
training_phrases = []
part1 = dialogflow_v2beta1.types.Intent.TrainingPhrase.Part(text="hello ")
parts = []
parts.append(part1)
training_phrase = dialogflow_v2beta1.types.Intent.TrainingPhrase(parts=parts)
training_phrases.append(training_phrase)
text = dialogflow_v2beta1.types.Intent.Message.Text(text=["say hello"])
message = dialogflow_v2beta1.types.Intent.Message(text=text)
messages = []
messages.append(message)
intent = dialogflow_v2beta1.types.Intent(
display_name='Mike_Hello',
training_phrases=training_phrases,
messages=messages)
response = intents_client.create_intent(parent, intent, language_code=LANGUAGE)
But, when I add the following to my Intent definition:
intent = dialogflow_v2beta1.types.Intent(
display_name='Mike_Hello',
input_context_names=['5000'],
training_phrases=training_phrases,
messages=messages)
(ie - adding the input_context_names parameter)
The intent creation fails with an error:
Resource name does not match format 'projects/{project_id}/agent/sessions/{session_id}/contexts/{context_id}'
I tried creating a context with a context client and create_context, but it fails with the same error. The create_context API seems to me to be more related to creating a context for inputting into detect_intent, as it wants a live SESSION_ID as input.
I can replace ["5000"] in the input_context above with 'projects/PROJECT_ID/agent/sessions/-/contexts/5000', and I get the same error.
Bug? Or am I missing something?
Found the problem.
The entity string:
'projects/' + PROJECT_ID + '/agent/sessions/-/contexts/my_ctx_name'
works great.
The entity string:
'/projects/' + PROJECT_ID + '/agent/sessions/-/contexts/my_ctx_name'
does not work. My problem was the leading '/' before 'projects'.
I'm developing an Android application with backend developed using Tastypie and Django. I have a get request for which I want to optionally be able to retrieve the entire object (with complete related fields, rather than URIs). Below is part of the python code for the resource I'm talking about:
class RideResource(ModelResource):
user = fields.ForeignKey(UserResource, 'driver')
origin = fields.ForeignKey(NodeResource, 'origin', full=True)
destination = fields.ForeignKey(NodeResource, 'destination', full=True)
path = fields.ForeignKey(PathResource, 'path')
# if the request has full_path=1 then we perform a deep query, returning the entire path object, not just the URI
def dehydrate(self, bundle):
if bundle.request.GET.get('full_path') == "1":
self.path.full = True
else:
ride_path = bundle.obj.path
try:
bundle.data['path'] = _Helpers.serialise_path(ride_path)
except ObjectDoesNotExist:
bundle.data['path'] = []
return bundle
As you can see the RideResource has a foreign key pointing to PathResource. I'm using the dehydrate function to be able to inspect if the GET request has a parameter "full_path" set to 1. In that case I set programmatically the path variable to full=True. Otherwise I simply return the path URI.
The thing is that the code seems to work only the second time the GET is performed. I've tested it hundreds of times and, when I perform my GET with full_path=1, even tho it enters the if and sets self.path.full = True, the first time it only returns the URI of the PathResource object. While, if I relaunch the exact same request a second time it works perfectly...
Any idea what's the problem?
EDIT AFTER SOLUTION FOUND THANKS TO #Tomasz Jakub Rup
I finally managed to get it working using the following code:
def full_dehydrate(self, bundle, for_list=False):
self.path.full = bundle.request.GET.get('full_path') == "1"
return super(RideResource, self).full_dehydrate(bundle, for_list)
def dehydrate(self, bundle):
if not bundle.request.GET.get('full_path') == "1":
try:
bundle.data['path'] = _Helpers.serialise_path(bundle.obj.path)
except ObjectDoesNotExist:
bundle.data['path'] = []
return bundle
dehydrate is called after full_dehydrate. Overwrite full_dehydrate function.
def full_dehydrate(self, bundle, for_list=False):
self.path.full = bundle.request.GET.get('full_path') == "1"
return super(RideResource, self).full_dehydrate(bundle, for_list)
I am currently trying out python's web.py module by making a small form. I wrote one, and received input from the user and wrote them to a (mysql) database table. Every thing is fine, except for one issue. When I run the program and write something in one of the form's fields, it persists to the next time I want to write in that field. How can I reset the field after receiving the data?
this is my code:
import web
import MySQLdb
url=('/search', 'search_by_name')
db=web.database(dbn='mysql' ,db='std',user='root', pw='123456')
tmpl=web.template.render('templates/')
class search_by_name:
form=web.form.Form(
web.form.Textbox('username',vpass,web.form.notnull),
web.form.Button('search')
)
def GET(self):
return tmpl.page( self.form)
def POST(self):
form=self.form
if not form.validates():
return tmpl.page(form)
else:
name=form['username'].value
a=db.select('student', where="name=$name", vars=locals())
row=list(a)
if row:
col=row[0]
return tmpl.table(row,col)
else:
return tmpl.message("There isn't student with this name in list")
app=web.application (url,globals())
if __name__=='__main__':
app.run()
I am trying to use endpoints to update some JSON values in my datastore. I have the following Datastore in GAE...
class UsersList(ndb.Model):
UserID = ndb.StringProperty(required=True)
ArticlesRead = ndb.JsonProperty()
ArticlesPush = ndb.JsonProperty()
In general what I am trying to do with the API is have the method take in a UserID and a list of articles read (with an article being represented by a dictionary holding an ID and a boolean field saying whether or not the user liked the article). My messages (centered on this logic) are the following...
class UserID(messages.Message):
id = messages.StringField(1, required=True)
class Articles(messages.Message):
id = messages.StringField(1, required=True)
userLiked = messages.BooleanField(2, required=True)
class UserIDAndArticles(messages.Message):
id = messages.StringField(1, required=True)
items = messages.MessageField(Articles, 2, repeated=True)
class ArticleList(messages.Message):
items = messages.MessageField(Articles, 1, repeated=True)
And my API/Endpoint method that is trying to do this update is the following...
#endpoints.method(UserIDAndArticles, ArticleList,
name='user.update',
path='update',
http_method='GET')
def get_update(self, request):
userID = request.id
articleList = request.items
queryResult = UsersList.query(UsersList.UserID == userID)
currentList = []
#This query always returns only one result back, and this for loop is the only way
# I could figure out how to access the query results.
for thing in queryResult:
currentList = json.loads(thing.ArticlesRead)
for item in articleList:
currentList.append(item)
for blah in queryResult:
blah.ArticlesRead = json.dumps(currentList)
blah.put()
for thisThing in queryResult:
pushList = json.loads(thisThing.ArticlesPush)
return ArticleList(items = pushList)
I am having two problems with this code. The first is that I can't seem to figure out (using the localhost Google APIs Explorer) how to send a list of articles to the endpoints method using my UserIDAndArticles class. Is it possible to have a messages.MessageField() as an input to an endpoint method?
The other problem is that I am getting an error on the 'blah.ArticlesRead = json.dumps(currentList)' line. When I try to run this method with some random inputs, I get the following error...
TypeError: <Articles
id: u'hi'
userLiked: False> is not JSON serializable
I know that I have to make my own JSON encoder to get around this, but I'm not sure what the format of the incoming request.items is like and how I should encode it.
I am new to GAE and endpoints (as well as this kind of server side programming in general), so please bear with me. And thanks so much in advance for the help.
A couple things:
http_method should definitely be POST, or better yet PATCH because you're not overwriting all existing values but only modifying a list, i.e. patching.
you don't need json.loads and json.dumps, NDB does it automatically for you.
you're mixing Endpoints messages and NDB model properties.
Here's the method body I came up with:
# get UsersList entity and raise an exception if none found.
uid = request.id
userlist = UsersList.query(UsersList.UserID == uid).get()
if userlist is None:
raise endpoints.NotFoundException('List for user ID %s not found' % uid)
# update user's read articles list, which is actually a dict.
for item in request.items:
userslist.ArticlesRead[item.id] = item.userLiked
userslist.put()
# assuming userlist.ArticlesPush is actually a list of article IDs.
pushItems = [Article(id=id) for id in userlist.ArticlesPush]
return ArticleList(items=pushItems)
Also, you should probably wrap this method in a transaction.