Need to access self.request.GET from main.py in lib.py - python

I need to do calculations among other things within lib.py and I need to access the user input data within main.py for it, because it needs to be that way. How do I do this?
doing from main import MainHandler in lib.py and then calling it "works" in the sense that it doesn't give any code errors, but displays a blank page when done that way and I get a log error saying that I cannot import it.
main.py
import webapp2
from lib import FormData
from pages import FormPage
from pages import ResultsPage
class MainHandler(webapp2.RequestHandler):
def get(self):
f = FormPage()
s = ResultsPage()
fd1 = FormData()
if self.request.GET:
fd1.name = self.request.GET['name']
fd1.email = self.request.GET['email']
fd1.weight = self.request.GET['weight']
fd1.height = self.request.GET['height']
self.response.write(s.second_page(fd1.name, fd1.email, fd1.weight, fd1.height))
else:
self.response.write(f.form_page)
app = webapp2.WSGIApplication([
('/', MainHandler)
], debug=True)
lib.py
class FormData(object):
def __init__(self):
pass
I need to be able to access:
fd1.name = self.request.GET['name']
fd1.email = self.request.GET['email']
fd1.weight = self.request.GET['weight']
fd1.height = self.request.GET['height']
In lib.py

Your if/else statement is outside the get method, so it shouldn't even work properly.
I think the most clean way would be to pass the request data to the FormData class already in the initialiser. So the code would look like this:
main.py
import webapp2
from lib import FormData
from pages import FormPage
from pages import ResultsPage
class MainHandler(webapp2.RequestHandler):
def get(self):
f = FormPage()
s = ResultsPage()
fd1 = FormData(data=self.request.GET)
if fd1.name: # This is None, if form has not been submitted
self.response.write(s.second_page(fd1.name, fd1.email, fd1.weight, fd1.height))
else:
self.response.write(f.form_page)
app = webapp2.WSGIApplication([
('/', MainHandler)
], debug=True)
lib.py
class FormData(object):
def __init__(self, data):
self.name = data.get('name')
self.email = data.get('email')
self.weight = data.get('weight')
self.height = data.get('height')
As a side note, I don't really know this webapp2 framework, so there might be a better way to do this.

Related

Flask redirect from a different class

I'm trying to call a function that has a flask redirect which exists in a certain class.
My files are like so:
--- Lib/config.py
--- Lib/lib.py
--- auth.py
My code inside lib.py
import os
import json
import time
import requests
from Lib.config import APP_UID, REDIRECT_URI
from flask import redirect
class PyLi:
def __init__(self):
self.app_uid = APP_UID
self.redirect_uri = REDIRECT_URI
def code_redirect(self):
d = {'client_id=' + self.app_uid, 'redirect_uri=' + self.redirect_uri,
'response_type=' + 'code'}
return redirect("https://website.com/oauth/authorize?%s" %
("&".join(d)))
My config.py is just used to define the env variables I'm calling.
from decouple import config
APP_UID = config('APP_UID', cast=str, default=None)
...
And in auth.py I am calling it like so:
from Lib import lib
#token.route("/authorize", methods=['GET'])
def redirect():
auth = lib.PyLi()
auth.code_redirect()
But I'm getting TypeError: The view function did not return a valid response. The function either returned None or ended without a return statement.
What am I doing wrong?
You're missing a return on the last line of redirect() view function. Add it as follows:
#token.route("/authorize", methods=['GET'])
def redirect():
auth = lib.PyLi()
return auth.code_redirect()

Render Multiple Jinja Templates with One Handler

Hello Stackoverflow Guru's!
I'm a complete newb, and I've got a question that I can't seem to find the answer to (hopefully because it's so simple nobody has bothered to ask).
I'm designing a website that has a bunch of recipes using google app engine. I'd like to be able to render a bunch of the recipe pages using one handler, because I plan of having lots of recipes later and I don't want to have to make a new handler for each one. My code is below:
import urllib2
import webapp2
import jinja2
import os
JINJA_ENVIRONMENT = jinja2.Environment(
loader=jinja2.FileSystemLoader(os.path.dirname(__file__)),
extensions=['jinja2.ext.autoescape'],
autoescape=True)
class Handler(webapp2.RequestHandler):
def write(self, *a, **kw):
self.response.out.write(*a, **kw)
def render_str(self,template,**params):
t = JINJA_ENVIRONMENT.get_template(template)
return t.render(params)
def render(self,template,**kw):
self.write(self.render_str(template,**kw))
class MainHandler(Handler):
def get(self):
template = JINJA_ENVIRONMENT.get_template('main.html')
self.response.write(template.render())
class RecipeHandler(Handler, recipe):
def get(self, recipe):
recipe_pages = {
'carbonara' : 'carbonara.html'
'burger' : 'burger.html'
}
if recipe in recipe_pages:
template = JINJA_ENVIRONMENT.get_template(recipe_pages[recipe])
self.response.write(template.render())
else:
self.abort(404)
app = webapp2.WSGIApplication([
('/', MainHandler),
('/carbonara', RecipeHandler(carbonara)),
('/burger',RecipeHandler(burger)),
], debug=True)
I basically want to avoid writing out a "CarbonaraHander" and "BurgerHandler", and just use "RecipeHandler" to render both pages. I know this should be possible, but I have no idea how to do it.
Any help is appreciated!
Edit: I think I should be using something called regular expressions? But I don't really understand how they need to be used in this case.
AFAIK you can't pass args to the handler, you need to extract them from the request. This is what I'd do (pushed it a bit further to directly use the template name in the URl routing):
class RecipeHandler(Handler):
def extract_template_name_from_request(self):
return self.request.path_info[9:] # strip leading '/recipes/' (or whatever else you need)
def get(self):
template_name = self.extract_template_name_from_request()
try:
template = JINJA_ENVIRONMENT.get_template(template_name)
except Exception:
# can't locate a template matching the requested path
self.abort(404)
return
# prepare the template values as needed
values = {'recipe': {'name': template_name[:-5]}} # just an example
try:
self.response.write(template.render(values))
except Exception:
# failure rendering the template
self.abort(500)
app = webapp2.WSGIApplication([
('/recipes/.*.html', RecipeHandler), # see extract_template_name_from_request()
('/.*', MainHandler),
], debug=True)

Stuck retrieving parameters in sessions - GAE webapp2

I'm trying to get sessions to work with Webapp2 with GAE, but I'm stuck retrieving the stored parameters. Maybe I'm overlooking the obvious.
A dressed down version of with main.py where I store a value in the webapp2 session:
import webapp2
from webapp2_extras import sessions
other imports...
class BaseHandler(webapp2.RequestHandler): # Copied from Google's doc
def dispatch(self):
# Get a session store for this request.
self.session_store = sessions.get_store(request=self.request)
try:
# Dispatch the request.
webapp2.RequestHandler.dispatch(self)
finally:
# Save all sessions.
self.session_store.save_sessions(self.response)
#webapp2.cached_property
def session(self):
# Returns a session using the default cookie key.
return self.session_store.get_session()
class MainPage(webapp2.RequestHandler): # My main page proper
def get(self):
self.session['foo'] = 'bar' # Store somehing in the session
template_values = {
}
template = JINJA_ENVIRONMENT.get_template('index.html')
self.response.write(template.render(template_values))
application = webapp2.WSGIApplication([
('/', MainPage, ),], debug = True)
My problem is how to access the value stored in the session from another module. In test.py I do the following:
from webapp2_extras import sessions
import main
other imports ...
class Test(main.BaseHandler):
def post(self):
foo1 = self.session.get('foo')
return foo1
class ProductsPage(webapp2.RequestHandler):
def get(self):
foo2 = Test.post()
...
But I get the following error:
TypeError: unbound method post() must be called with Test instance as first argument (got nothing instead)
I just can't find the proper way to use the Test class and retrieve the value stored in the session. I must be overlooking something when using the class, but I'm stuck and can't find the way out.
Maybe somebody looking from outside will spot it easily?
Looking further I found a post that helped me
GAE webapp2 session handling not working when putting basehandler to a different file
After some tinkering here's the recipe that worked for me to setup a session in webapp2 and share the session among different .py files. Hope it saves others some time.
1) Create basehandler.py, this will need to be imported by all .py files using the session. This is straight from Google's documentation:
import webapp2
from webapp2_extras import sessions
class BaseHandler(webapp2.RequestHandler):
def dispatch(self):
# Get a session store for this request
self.session_store = sessions.get_store(request = self.request)
try:
webapp2.RequestHandler.dispatch(self)
finally:
self.session_store.save_sessions(self.response)
#webapp2.cached_property
def session(self):
# Returns a session using the default cookie key
return self.session_store.get_session()
2) Create main.py importing BaseHandler. In my case I store a value in the session:
import os
import urllib
import webapp2
import jinja2
from basehandler import BaseHandler
JINJA_ENVIRONMENT = jinja2.Environment(
loader=jinja2.FileSystemLoader(os.path.dirname(__file__)),
extensions=['jinja2.ext.autoescape'])
class MainPage(BaseHandler):
def get(self):
self.session['foo'] = 'bar' # Store a value in the session
# you can store more than one :-)
# Define values that will be passed onto the template
template_values = {
'title': 'TITLE'
}
# search for an appropriate template and render it.
template = JINJA_ENVIRONMENT.get_template('./templates/index.html')
self.response.write(template.render(template_values))
config = {}
config['webapp2_extras.sessions'] = {
'secret_key': 'my-super-secret-key'
}
application = webapp2.WSGIApplication([
('/', MainPage)
], config = config, debug = True)
3) Create another.py taking care to also import BaseHandler and use the same secret key. Here you can retrieve the value stored by main.py or any other .py file sharing the same session:
import os
import urllib
import webapp2
import jinja2
from basehandler import BaseHandler
JINJA_ENVIRONMENT = jinja2.Environment(
loader=jinja2.FileSystemLoader(os.path.dirname(__file__)),
extensions=['jinja2.ext.autoescape'])
class AnotherPage(BaseHandler):
def get(self):
foo1 = self.session.get('foo')
# Now go and do something with foo1, even store a new value as in main.py
# ...
# ...
# Define values that will be passed onto the template
template_values = {
'title': 'TITLE'
}
# search for an appropriate template and render it.
template = JINJA_ENVIRONMENT.get_template('./templates/additional.html')
self.response.write(template.render(template_values))
config = {}
config['webapp2_extras.sessions'] = {
'secret_key': 'my-super-secret-key'
}
application = webapp2.WSGIApplication([
('/', AdditionalPage)
], config = config, debug = True)

Detect if URL contains parameters in GAE

I would like to parse the URL upon load to see if it has any parameters. I'm just trying to set up a basic test to see if that's possible. What is the correct regex to send a url like http://example.com/?hiyall to ParamHandler?
class ParamHandler(webapp2.RequestHandler):
def get(self):
self.response.out.write('parameters detected')
class MainHandler(webapp2.RequestHandler):
def get(self):
self.response.out.write('Hello World')
application = webapp2.WSGIApplication ([('/', MainHandler), ('/\?.*', ParamHandler)], debug=True)
Do something like this in get(self):
class ParamHandler(webapp2.RequestHandler):
def get(self):
hyl = self.request.get("hiyall")
self.response.out.write("hiyall was: " + hyl)
Customary official docs link: https://developers.google.com/appengine/docs/python/tools/webapp/requestclass#Request_get
If you're using webapp2, you cannot route requests based on parameters.
But you can create a condition based on query_string which can check if parameters exist. Like the following:
class MainHandler(webapp2.RequestHandler):
def get(self):
if self.request.query_string:
self.response.out.write('Has parameters')
else:
self.response.out.write('No parameters')
application = webapp2.WSGIApplication ([('/', MainHandler)], debug=True)

Simple scenario using middleware class for mobile detection with app engine

I'm a newbie to app engine and python and am just trying to get a basic idea for how things work.
I have a simple app, with one mapped url (/). All the classes I'm trying to use are in the base directory of the app.
This is my main.py - all i want to do is use the middleware class to pass a variable to the template so I can render different parts of the page depending on device type.
import webapp2
import jinja2
import os
from useragents import search_strings
jinja_environment = jinja2.Environment(
loader=jinja2.FileSystemLoader(os.path.dirname(__file__)))
class MainPage(webapp2.RequestHandler):
def get(self):
template = jinja_environment.get_template('templates/index.html')
self.response.out.write(template.render())
app = webapp2.WSGIApplication([('/', MainPage)],
debug=True)
class Middleware(object):
#staticmethod
def process_request(request):
"""Adds a "mobile" attribute to the request which is True or False
depending on whether the request should be considered to come from a
small-screen device such as a phone or a PDA
//rest of class is [here][1]
"""
import webapp2
import jinja2
import os
from useragents import search_strings
jinja_environment = jinja2.Environment(
loader=jinja2.FileSystemLoader(os.path.dirname(__file__)))
class MainPage(webapp2.RequestHandler):
def get(self):
#i don't know if you want to overwrite self.request but here it is
self.request = Middleware.process_request(self.request)
template = jinja_environment.get_template('templates/index.html')
self.response.out.write(template.render())
app = webapp2.WSGIApplication([('/', MainPage)],
debug=True)
class Middleware(object):
#staticmethod
def process_request(request):
"""Adds a "mobile" attribute to the request which is True or False
depending on whether the request should be considered to come from a
small-screen device such as a phone or a PDA
//rest of class is [here][1]
"""

Categories

Resources