I need to convert a string type, from and get call on web.py, into an integer, but I'm getting this error:
invalid literal for int() with base 10
Here is my code:
import web
render = web.template.render('templates/')
urls = ('/webservices/test', 'Test')
app = web.application(urls, globals())
class Test:
def __init__(self):
pass
def GET(self):
user_data = web.input(id="")
id = int(user_data.id)
return id
application = app.wsgifunc()
if __name__ == "__main__":
app.run()
I've seen this documentation:
http://webpy.readthedocs.org/en/latest/input.html
You give a default constructor of user_data.id as "". If this is not specified by the browser, you will be calling
int("")
which is what is throwing your error. Try
user_data = web.input(id="0")
Related
I am learning Python 2.7 and trying to write a function in a module named new5.py like this:
def compare(a,b,c):
if a - 3 == 8:
return "I like a!"
elif b == c:
return "I like c!"
else:
return "I like b!"
When I try to call the function in the moudle named app02.py which is presented with detail code at the end of the qustion, I am told like this as presented as the following on the screen shot:
I guess the problem is on a, but what should I do to use the function? Thank you!
------ the following is the module app02.py rooted from web.py 0.3------
import web
import new5
urls = (
'/dyear', 'Index'
)
app = web.application(urls, globals())
render = web.template.render('/Users/Administrator/projects/gothonweb/templates/', base="layout01")
class Index(object):
def GET(self):
return render.hello_form01()
def POST(self):
form01 = web.input(a_year=1980)
form02 = web.input(a_month=01)
form03 = web.input(a_day=01)
greeting = "Your result from app02 is %s" % (new5.compare(form01, form02, form03))
return render.index(greeting = greeting)
if __name__ == "__main__":
app.run()
Instead of passing the whole Storage object to compare(), you should access a_year in form01, a_month in form02 and a_day in form03 objects like form01.a_year, form2.a_month or form3.a_day
So your function call should look something like
greeting = "Your result from app02 is %s" % (new5.compare(form01.a_year, form02.a_month, form03.a_day))
Also, note this from the docs
Note that the web.input() values will be strings even if there are
numbers passed to it.
so you'll need to typecast your web.input from string to the required type(here int) like so
if int(a) - 3 == 8:
Is there any way to call a webpy (GET) view (from another view) with params?
Thanks in advance.
import web
urls = (
'/(\d+)', 'index',
'/number', 'novo'
)
class index:
def GET(self, number):
return "Number: %i " % number
class number:
def GET(self):
get_index = index()
return get_index.GET(3)
app = web.application(urls, globals())
if __name__ == "__main__":
app.run()
In the following way I bind "hello.py" and "goodbye.py" with the corresponding classes (functions) and it works. If I go to "0.0.0.0:8080/hello.py" or "0.0.0.0:8080/goodbye.py", I see what I expect to see.
import web
urls = ('/(hello.py)', 'hello', '/(goodbye.py)', 'goodbye')
app = web.application(urls, globals())
class hello:
def GET(self, name):
if not name:
name = 'World'
return 'Hello, ' + name + '!'
class goodbye:
def GET(self, name):
if not name:
name = 'World'
return 'Goodbye, ' + name + '!'
if __name__ == "__main__":
app.run()
However, I do not understand why I need to use brackets. If I replace '/(hello.py)' by '/hello.py', it does not work. However, in the example here no brackets are used.
From the examples that I see (I don't know web.py too well) the get parameters should not be passed in as method parameters, but rather acquired via the web.input method, like so:
import web
urls = (
'/SomePageHello','SomePageHello',
'/SomePageGoodbye','SomePageGoodbye',
)
app = web.application(urls, globals())
class SomePageHello:
def GET(self):
user_data = web.input(name="no data")
return "<h1> Hello " + user_data.name + "</h1>"
class SomePageGoodbye:
def GET(self):
user_data = web.input(name="no data")
return "<h1> Goodbye " + user_data.name + "</h1>"
if __name__ == "__main__":
app.run()
The url should be something like:
http://127.0.0.1:8081/SomePageHello?name=dasfasd
I need to write a unit test using Mock module for a Python code with different functions:
_read_file(): opens a URL and then parse the xml using Element tree and return element tree instance.
validate_field: this filed takes arguments as field_value and order.
tree.findall function is used to get all fields_values in a list and then using the order exact value of that field is stored in a field. this file is then compared with the received argument and based on comparison either true of false is returned.
I have written unit test for above function. I have mocked urllib.urlopen and the return value of the called function, but it's giving error as:
IndexError: list index out of range
Please guide me on this.
Code below:
class test:
def __init__(self, host, service_path='/policy/test.xml'):
self.base_url = 'https://' +host + service_path
self.service_path = service_path
self.host = host
def _read_policy(self, url):
policy_xml = urllib.urlopen(url)
self.tree = ElementTree.parse(policy_xml)
return self.tree
def compare(self, arg1, arg2):
if arg1 == arg2:
return 'true'
else:
return 'false'
def validate_email(self, email, order):
index = int(order) - 1
email_list = self.tree.findall("testList/test/email")
xml_email = email_list[index].text
_resp = self.compare(xml_email, email)
return(_resp)
Test class:
class test_validate_email(unittest.TestCase):
def test_validate_email(self):
myMock = Mock( return_value = StringIO.StringIO("""<?xml version="1.0" encoding="utf-8"?><email>*#test.com</email>"""))
urllib.urlopen = myMock
print 'urllib.urlopen', urllib.urlopen()
cp = test(DEFAULT_HOST)
tree = cp._read_policy("some data")
ElementTree.dump(tree)
myMock2 = Mock(return_value = 'true')
_resp = myMock2
print 'test_resp', _resp()
resp = cp.validate_email('*#ashishtest.com','1')
print 'resp', resp
self.assertEqual(resp, 'true')
if __name__ == '__main__':
unittest.main()
I have a class that doesn't extend webapp.RequestHandler, and I can't use self.response.out.write(), I get:
AttributeError: Fetcher instance has no attribute 'response'
If I extend webapp.RequestHandler (I thought it would work), I get:
AttributeError: 'Fetcher' object has no attribute 'response'
How can I use that method properly? Sometimes print doesn't work either; I just get a blank screen.
EDIT:
app.yaml:
application: fbapp-lotsofquotes
version: 1
runtime: python
api_version: 1
handlers:
- url: .*
script: main.py
source (the problematic line is marked with #<- HERE):
import random
import os
from google.appengine.api import users, memcache
from google.appengine.ext import webapp, db
from google.appengine.ext.webapp import util, template
from google.appengine.ext.webapp.util import run_wsgi_app
import facebook
class Quote(db.Model):
author = db.StringProperty()
string = db.StringProperty()
categories = db.StringListProperty()
#rating = db.RatingProperty()
class Fetcher(webapp.RequestHandler):
'''
Memcache keys: all_quotes
'''
def is_cached(self, key):
self.fetched = memcache.get(key)
if self.fetched:
print 'ok'#return True
else:
print 'not ok'#return False
#TODO: Use filters!
def fetch_quotes(self):
quotes = memcache.get('all_quotes')
if not quotes:
#Fetch and cache it, since it's not in the memcache.
quotes = Quote.all()
memcache.set('all_quotes',quotes,3600)
return quotes
def fetch_quote_by_id(self, id):
self.response.out.write(id) #<---------- HERE
class MainHandler(webapp.RequestHandler):
def get(self):
quotes = Fetcher().fetch_quotes()
template_data = {'quotes':quotes}
template_path = 'many.html'
self.response.out.write(template.render(template_path, template_data))
class ViewQuoteHandler(webapp.RequestHandler):
def get(self, obj):
self.response.out.write('viewing quote<br/>\n')
if obj == 'all':
quotes = Fetcher().fetch_quotes()
self.render('view_many.html',quotes=quotes)
else:
quotes = Fetcher().fetch_quote_by_id(obj)
'''for quote in quotes:
print quote.author
print quote.'''
def render(self, type, **kwargs):
if type == 'single':
template_values = {'quote':kwargs['quote']}
template_path = 'single_quote.html'
elif type == 'many':
print 'many'
self.response.out.write(template.render(template_path, template_values))
'''
CREATORS
'''
class NewQuoteHandler(webapp.RequestHandler):
def get(self, action):
if action == 'compose':
self.composer()
elif action == 'do':
print 'hi'
def composer(self):
template_path = 'quote_composer.html'
template_values = ''
self.response.out.write(template.render(template_path,template_values))
def post(self, action):
author = self.request.get('quote_author')
string = self.request.get('quote_string')
print author, string
if not author or not string:
print 'REDIRECT'
quote = Quote()
quote.author = author
quote.string = string
quote.categories = []
quote.put()
def main():
application = webapp.WSGIApplication([('/', MainHandler),
(r'/view/quote/(.*)',ViewQuoteHandler),
(r'/new/quote/(.*)',NewQuoteHandler) ],
debug=True)
util.run_wsgi_app(application)
if __name__ == '__main__':
main()
You're not routing to Fetcher when you initialize a WSGIApplication. Rather, you create an instance manually in other handlers. Thus, App Engine will not initialize your request and response properties. You can manually do so in from the handlers you route to, such as MainHandler and ViewQuoteHandler. E.g.:
fetcher = Fetcher()
fetcher.initialize(self.request, self.response)
quotes = fetcher.fetch_quotes()
Note that fetcher really doesn't have to be a RequestHandler. It could be a separate class or function. Once you have request and response objects, you can pass them around as you choose.