Webpy, calling a view from another method - python

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()

Related

Python | check if dict{} item is in list[]

Attempting to check an in-memory list, plant_list[] against a JSON payload from an api.
If the incoming payload's dict name matches inside of plant_list the if should fire off.
Instead my script only returns null
Please point out my mistakes.
The JSON sent over the api call is:
{ "name":"swizz", "days": "7", "price": 2.00 }
Source Code
from flask import Flask, request
from flask_restful import Api, Resource
app = Flask(__name__)
api = Api(app)
#app.route('/', methods=['GET', 'POST'])
def home():
return 'Tiny'
plant_list = []
class Plant(Resource):
def get(self, name):
return {'Name':name}, 200
def post(self, name):
payload = request.get_json()
for x in range(0, len(plant_list)):
if payload['name'] == plant_list[x]['name']:
return {'message': f'''Item {payload['name']} already stored in database.'''}
else:
plant_list.append(payload)
return plant_list, 201
api.add_resource(Plant, '/plant/<string:name>')
if __name__ == '__main__':
app.run(port=9004, debug=True)
You can test for key in dict simply by: if key_name in my_dict:... So, if "price" in plant_list[x]:
You are setting plant_list as a global. If you want to use that inside a Class, you should define it inside the function in your class:
plant_list = []
class Plant(Resource):
....
def post(self, name):
global plant_list
....
Not sure why you need it as a global variable. Perhaps you want:
class Plant(Resource):
plant_list = []
....
def post(self, name):
....

Flask render_template context not showing in URL

I am trying to pass params to the URL in flask, but I can not get them to show up for anything.
#logout.route('/logout')
def logout_page():
current_provider = current_oauth_user.get_provider()
return render_template('index.html', provider=current_provider)
I expect to see /logout?provider=facebook but I just get /logout
Right now I am doing this:
#logout.route('/logout')
def logout_page():
provider = request.args.get('provider')
current_provider = current_oauth_user.get_provider()
if not provider and current_provider:
return redirect(url_for('logout.logout_page',
provider=current_provider))
return render_template('index.html')
but that just seems so terrible.
You should return some value using '/logout' path.
So at first, you use render_template(index.html) under def main(). Then you create def logout_page() and return some value ( in your case is current_provider).
#app.route('/')
def main():
return render_template('index.html')
#app.route('/logout')
def logout_page():
current_provider = current_oauth_user.get_provider()
return current_provider
if __name__=="__main__":
app.run(port=8000)

web.py invalid literal for int() with base 10

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")

How does URL handling work in web.py?

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

self.response.out.write() - how to use it properly?

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.

Categories