Specifying custom URL schema in appengine using app.yaml? - python

I am trying to have a custom URL which looks like this:
example.com/site/yahoo.com
which would hit this script like this=
example.com/details?domain=yahoo.com
can this be done using app.yaml?
the basic idea is to call "details" with the input "yahoo.com"

You can't really rewrite the URLs per se, but you can use regular expression groups to perform a similar kind of thing.
In your app.yaml file, try something like:
handlers:
- url: /site/(.+)
script: site.py
And in your site.py:
SiteHandler(webapp.RequestHandler):
def get(self, site):
# the site parameter will be what was passed in the URL!
pass
def main():
application = webapp.WSGIApplication([('/site/(.+)', SiteHandler)], debug=True)
util.run_wsgi_app(application)
What happens is, whatever you have after /site/ in the request URL will be passed to SiteHandler's get() method in the site parameter. From there you can do whatever it is you wanted to do at /details?domain=yahoo.com, or simply redirect to that URL.

Related

how to send data to html worksheet using flask framework

I have a function calculate_full_eva_web(input:dict) it receives input dictionary several function applied on this input to create calculations dict, after calculations i want to send this data to html dashboard and after send data to html file i can play there with jinja stuff. i am unable to do so, i tried several ways but flask throws error. and also i don't know much about ajax ,may be ajax will do my work, let me know. that is why i am tagging ajax people on this post. Traceback is also attached..Thank you
In simple words, i want to send data to html in flask ! Please check my code. Let me know if i am doing anything wrong.
imports ...
from other file import other_functions
from other file import other_functions_2
from other file import other_functions_3
app = Flask(__name__, template_folder='templates/')
#app.route("/dashboard")
def calculate_full_eva_web(input:dict):
calculate_gap = other_functions(input)
calculate_matrix = other_functions_2(input)
average = other_functions_3(input)
data = dict{'calculate_gap':calculate_gap, 'calculate_matrix':calculate_matrix,'average':average}
return render_template('pages/dashboard.html', data = data)
if __name__ == "__main__":
app.run(debug=True)
The route receive a dict as input so you must change #app.route("/dashboard") to #app.route("/dashboard/<input>") and pass input to the route in the link of the route.
For example, I have a route as below.
#app.route('/user/<name>')
def user(name):
return render_template('home.html', name=name)
To pass name to the route, I access the link http://localhost:5000/user/myname.

How can I modify the url of the Superset welcome page?

I would like to know how I can modify the URL to the welcome page.
Currently it is /superset/welcome.
It is run into superset/views/core.py in a #expose('/welcome').
I know I can modify the code inside this #expose, but I want to redirect to another url.
So I want to find the line where there is:
welcome_page = /superset/welcome
As of Superset 1.3, you can change the default landing page by adding this code to your Superset config:
from flask import Flask, redirect
from flask_appbuilder import expose, IndexView
from superset.typing import FlaskResponse
class SupersetDashboardIndexView(IndexView):
#expose("/")
def index(self) -> FlaskResponse:
return redirect("/dashboard/list/")
FAB_INDEX_VIEW = f"{SupersetDashboardIndexView.__module__}.{SupersetDashboardIndexView.__name__}"
In the above example, I am using /dashboard/list/ instead of the default /superset/welcome/.
The code above is Unlicensed and thus is free and unencumbered software released into the public domain.
In superset's file structure, navigate to:
superset/app.py
There you will find
class SupersetIndexView(IndexView):
#expose("/")
def index(self) -> FlaskResponse:
return redirect("/superset/welcome")
Modify this to path where you want to redirect.

Best way to make subapps with Traversal

Ok so I have my apps, that takes requests from root / Almost everything is using traversal.
But i'd like to make on top of that site a rest api.
So I'm off with two choices. I either separate the that in two different apps and put that rest application to : rest.site.com, Or I can move it to site.com/rest/*traversal
If I'm doing "/rest/*traversal", I guess I'll have to add a route called rest_traversal where the traversal path will be *traversal with the route /rest/*traversal. I did that once for an admin page.
I was wondering if there was a cleanest way to do that. I tried to use virtual_root, but as I understand virtual_root is actually getting added to the path for traversal.
like having virtual_root = /cms and requesting /fun will create the following path /cms/fun
I on the other hand wish to have /cms/fun turned into /fun
I know this has been answered already, but in case someone arrives here looking for another possible way to make "subapps" and using them in pyramid, I wanted to point out that some interesting things can be done with pyramid.wsgi
"""
example of wsgiapp decorator usage
http://docs.pylonsproject.org/projects/pyramid/en/1.3-branch/api/wsgi.html
"""
from pyramid.wsgi import wsgiapp2, wsgiapp
from pyramid.config import Configurator
from webob import Request, Response
import pprint
# define some apps
def wsgi_echo(environ, start_response):
"""pretty print out the environ"""
response = Response(body=pprint.pformat({k: v for k, v in environ.items()
if k not in ["wsgi.errors",
"wsgi.input",
"SCRIPT_NAME"]}))
return response(environ, start_response)
print Request.blank("/someurl").send(wsgi_echo).body
# convert wsgi app to a pyramid view callable
pyramid_echo = wsgiapp(wsgi_echo)
pyramid_echo_2 = wsgiapp2(wsgi_echo)
# wire up a pyramid application
config = Configurator()
config.add_view(pyramid_echo, name="foo") # /foo
config.add_view(pyramid_echo, name="bar") # /bar
config.add_view(pyramid_echo_2, name="foo_2") # /foo
config.add_view(pyramid_echo_2, name="bar_2") # /bar
pyramid_app = config.make_wsgi_app()
#call some urls
foo_body = Request.blank("/foo").send(pyramid_app).body
bar_body = Request.blank("/bar").send(pyramid_app).body
foo_body_2 = Request.blank("/foo_2").send(pyramid_app).body
bar_body_2 = Request.blank("/bar_2").send(pyramid_app).body
# both should be different because we arrived at 2 different urls
assert foo_body != bar_body, "bodies should not be equal"
# should be equal because wsgiapp2 fixes stuff before calling
# application in fact there's an additional SCRIPT_NAME in the
# environment that we are filtering out
assert foo_body_2 == bar_body_2, "bodies should be equal"
# so how to pass the path along? like /foo/fuuuu should come back
# /fuuuu does it
foo_body = Request.blank("/foo_2/fuuuu").send(pyramid_app).body
assert "'/fuuuu'," in foo_body, "path didn't get passed along"
# tldr: a wsgi app that is decorated with wsgiapp2 will recieve data
# as if it was mounted at "/", any url generation it has to do should
# take into account the SCRIPT_NAME variable that may arrive in the
# environ when it is called
If you're using traversal already, why not just use it to return your "rest API root" object when Pyramid traverses to /rest/? From there, everything will work naturally.
class ApplicationRoot(object):
def __getitem__(self, name):
if name == "rest":
return RestAPIRoot(parent=self, name=name)
...
If your "application tree" and "API tree" have the same children and you want to have different views registered for them depending on which branch of the tree the child is located in, you can use containment view predicate to register your API views, so they will only match when the child is inside the "API branch":
containment
This value should be a reference to a Python class or interface that a
parent object in the context resource’s lineage must provide in order
for this view to be found and called. The resources in your resource
tree must be “location-aware” to use this feature.
If containment is not supplied, the interfaces and classes in the
lineage are not considered when deciding whether or not to invoke the
view callable.
Another approach would be not to build a separate "API tree" but to use your "main" application's "URI-space" as RESTful API. The only problem with this is that GET and possibly POST request methods are already "taken" on your resources and mapped to your "normal" views which return HTML or consume HTTP form POSTs. There are numerous ways to work around this:
register the API views with a separate name, so, say GET /users/123 would return HTML and GET /users/123/json would return a JSON object. Similarly, POST /users/123 would expect HTTP form to be posted and POST /users/123/json would expect JSON. A nice thing about this approach is that you can easily add, say, an XML serializer at GET /users/123/xml.
use custom view predicates so GET /users/123 and GET /users/123?format=json are routed to different views. Actually, there's a built-in request_param predicate for that since Pyramid 1.2
use xhr predicate to differentiate requests based on HTTP_X_REQUESTED_WITH header or accept predicate to differentiate on HTTP_ACCEPT header

How to reformat URLs to be more restful (from .../?id=123 to .../123)?

Currently I have pages accessed via:
www.foo.com/details.html?id=123
I'd like to make them more restful-like, such as by the following:
www.foo.com/details/123
I'm using Google App Engine. Currently the URL's are mapped in the html-mappings file:
('/details.html*', DetailsPage),
And then on the DetailsPage handler, it fetches the ID value via:
class DetailsPage(webapp.RequestHandler):
def get(self):
announcement_id = self.request.get("id")
How might I restructure this so that it can map the URL and a extract the ID via the other-formatted URL: www.foo.com/details/123
Thanks
Rewrite your URL mapping like this:
('/details/(\d+)', DetailsPage),
(this requires that there be a trailing part of the URL that contains one or more digits and nothing else).
Then modify your DetailsPage::get() method to accept that id parameter, like:
class DetailsPage(webapp.RequestHandler):
def get(self, announcement_id):
# next line no longer needed
# announcement_id = self.request.get("id")
...and carry on with your code.

how can i get value fron the URL in python appengine?

if i have this URL in from python code on appengine
http://localhost:8080/blog/view/2f1cab5844fb432b8426ae666c4ac493
how can i get the value of the key : 2f1cab5844fb432b8426ae666c4ac493
#Herms answer will work, but you may prefer this instead:
In the code that creates your webapp instance, capture the key part of the URL with a regex, like:
def main():
application = webapp.WSGIApplication( [
(r'/blog/view/(\w+)', MyBlogViewHandler),
## others listed here...
])
...then code your handler class like this - the key you captured will be passed to your get() method as an argument:
class MyBlogViewHandler(webapp.RequestHandler):
def get(self, key):
# do something useful with the 'key' argument
You can access the requested URL via self.request, assuming you're extending the standard webapp.RequestHandler class. That will give you access to the path and query, and you should be able to extract the values you want from the path.
Here's some documentation on the Request object:
http://code.google.com/appengine/docs/python/tools/webapp/requestclass.html

Categories