I'm using pylons, and want to use clever css.
I created a controller SassController to handle .sass requests, but in the config/routing.py, I don't know how to write the mapping.
What I want is:
client request: http://localhost:5000/stylesheets/questions/index.sass
all such requests will be handled by SassController#index
I tried:
map.connect('/{path:.*}.sass', controller='sass', action='index')
But found only: http://localhost:5000/xxx.sass will be handled, but http://localhost:5000/xxx/yyy.sass won't.
What should I do now?
The routing code using regular expressions so you can make it eat everything in the url regardless of slashes.
The docs are here
It'll look something like:
map.connect(R'/{path:.*?}.sass', controller='SassController', action='index')
#in the SassController
def index(self, path):
return path
http://localhost:5000/blah/blah/something.sass will call SassController.index with path = blah/blah/something
Related
Alt: How to use a variable and loop it in Flask app route such that it handles multiple webpages which have similar permalinks (i'm not sure what that is though).
This is a snippet of a simple example to demostrate what I mean:
#app.route('/say-hii-1')
def say_hii_1():
return """<h1>Hello 1!</h1>"""
#app.route('/say-hii-2')
def say_hii_2():
return """<h1>Hello 2!</h1>"""
#app.route('/say-hii-3')
def say_hii_3():
return """<h1>Hello 3!</h1>"""
You see, only the number changes in all routes, and the return values also have a pattern. My project is much more complex and has 10-20 such routes.Is there a way, in which I can reduce all of them to just one route?
Some information that you might need:
OS: Ubuntu 19.10
Python version: 3.7.5
What you're looking for is flask route parameters/dynamic routes/variable rules
Route parameters allow you to match your application's route to a pattern, by inserting variables with carats <>. If the url matches the pattern, it'll pass the variable into the function your route is linked to.
From there, you can do whatever sort of dyanmic behaviour you want, as per usual python.
As an example, you could implement what you're asking for in your example as follows:
#app.route('/say-hii-<int:hi_number>')
def say_hii(hi_number):
return "<h1>Hello " + str(hi_number) + "</h1>"
For more information, you can have a look at the flask quickstart:
https://flask.palletsprojects.com/en/1.1.x/quickstart/#routing
This is a fairly common use case, so be sure to look through the flask quickstart and guides next time!
I am trying to create a folder traversing api with fastapi.
Say I have an end point like this:
#root_router.get("/path/{path}")
def take_path(path):
logger.info("test %s", path)
return path
If I do to the browser and call "URL:PORT/path/path"
it returns "path", easy. But if I try "URL:PORT/path/path/path" the code doesnt even get to the logger. I guess that makes sense as the API doesnt have that end point in existence. But it DOES exist on my server. I have figured out other ways to do this, i.e. pass the path as an array of params and rebuld in code with / separator, but passing params in url feels a bit clunky, if I can move through the paths in the url the same as my server, that would be ideal. Is this doable?
Thanks.
Add :path to your parameter:
#root_router.get("/path/{path:path}")
async def take_path(path: str):
logger.info("test %s", path)
return path
Notice that this is a Starlette feature.
I feel like I'm running into a brick wall, as I'm not getting anywhere with this, and I believe, simple task.
I'm trying to generate a URL by the likes of '/path/to/url', but upon gazing at multiple StackOverflow Q&A's, the official documentation for cherrypy, I still cannot seem to wrap my head around the issue.
Here's my code so far:
import details
import input_checker as input
import time
import cherrypy
class Index(object):
#cherrypy.expose
def input(self):
return input.check_input()
#cherrypy.expose
def stream(self):
while True:
return 'Hey'
#return input.check_input()
time.sleep(3)
if __name__ == '__main__':
index = Index()
cherrypy.tree.mount(index.stream(), '/input/stream', {})
cherrypy.config.update(
{'server.socket_host': '0.0.0.0'})
cherrypy.quickstart(index)
So essentially, I want to be able to visit http://127.0.0.1:8080/input/stream, and I will be returned with the given result.
After executing this code, and multiple variants of it, I'm still being returned with a 404 not found error, and I'm not sure what I need to do, in order to get it working.
Any tips and/or supporting documentation that I may have skimmed over?
Thanks guys.
So there are couple problems here, why do you use MethodDispatcher do you actually need it?
To serve you stream function on /input/stream you have to mount it as such:
cherrypy.tree.mount(index.stream(), '/input/stream', your_config)
note /input/stream instead of /stream.
But because you're using MethodDispatcher this will likely make your endpoint return 405 as GET is not allowed on this endpoint - to fix that just remove the MethodDispatcher bit.
But if you do require MethodDispatcher you will have to refactor a bit to something like that:
class Stream:
exposed = True # to let cherrypy know that we're exposing all methods in this one
def GET(self):
return something
stream = Stream()
cherrypy.tree.mount(stream , '/index/stream',
{'/':
{'request.dispatch': cherrypy.dispatch.MethodDispatcher()}
}
)
Also make sure to not actually call your methods when mounting them into cherrypy tree, just pass in the name of the function/class
I want to routes all paths that start with something like “/api” to same handler function.
Such as:
/api/foo
/api/bar
/api/foo/bar
/api/bar/baz/this/that
All should be handled with one function and I should be able to get the full path after /api.
This feature is very handy and I used it often at Node.js Express framework. Now I am looking for ways to accomplish the same thing with Python Falcon framework.
More info can be found here; It defines the feature as "white-listed “global” functionality."
http://expressjs.com/api.html#app.all
Perhaps you are looking for Falcon's sink facility, e.g.:
class Sink(object):
def on_get(self, req, resp):
resp.body = ('\nTwo things awe me most, the starry sky '
'above me and the moral law within me.\n'
'\n'
' ~ Immanuel Kant\n\n')
app = falcon.API()
handler = Sink().on_get
app.add_sink(handler, prefix='/')
This will route all URLs to the sink handler.
If you're looking for a way to handle all requests before they get routed to appropriate resources, I suggest you to look into middleware components.
I'm using cherrypy with Mako as a template engine.
I want Mako to lookup different directories based on what app is being requested.
I.e.
I have three 'apps': Site, Admin and Install.
They all have their own template folder, structure looking something like:
/template
/template/site
/template/admin
/template/install
/template/system
/system contains some system wide templates, like 404 pages, etc.
I'm using Twiseless as a reference whilst trying to get to grips with cherrypy / mako, but I'm stuck with how to do this.
Read on for a brief overview of how I've tried to do this, but a warning: I think I'm going about this completely the wrong way! :) So, if you have any ideas/pointers, it might be a good idea to save yourself the trouble of reading any further than this.
In my main file, server.py, I do something like:
from libs.plugins.template import MakoTemplatePlugin
engine = cherrypy.engine
makoTemplate = MakoTemplatePlugin(engine, self.base_dir)
setTemplateDirs(makoTemplate, self.template_path)
MakoTemplatePlugin is a slightly modified version of the plugin by the same name found in Twiseless, linked above.
What this code does is set the TemplateLookup to use the default template directories from my global config file. i.e.
/template
/template/system
Then, each time an app is loaded, I call a function (setTemplateDirs) to update the directories where Mako searches.
I thought this would work, but it doesn't. Initially I made the error of creating a new instance of MakoTemplatePlugin for each app. This just resulted in them all being called on each page load, starting with the first one instantiated, containing just the basic, non-app specific directories.
As this was called first, it was triggering a 404 error, as it was searching in the wrong folders.
I instead made sure to pass a reference to the MakeTemplatePlugin to all of my apps. I thought if I ran setTemplateDirs each time each app is called, this would solve the problem... but it doesn't.
I don't know where to put the function so it will run every time a page is requested...
e.g.
# /apps/site/app.py
import somemodule.setTemplateDirs
class Site(object, params):
def __init__(self):
self.params = params
self.makoTemplate = params['makoTemplate']
self.base_path = params['base_path']
setTemplateDirs(self.makoTemplate, self.base_path, '', '/')
#cherrypy.expose
#cherrypy.tools.render(template='index.html')
def index(self):
pass
This obviously just works when the application is first loaded... I tried moving the update function call into a seperate method update and tried calling that for each page, e.g:
#cherrypy.exposed
#cherrypy.tools.render(template='index.html')
#update
def index(self):
pass
But this just gives me config related errors.
Rather than to continue to mess about with this, there must be an easier way.
How would you do it?
Thanks a lot,
Tom
I got this working. Thanks to stephan for providing the link to the mako tool example: http://tools.cherrypy.org/wiki/Mako.
I just modified that slightly to get it working.
If anyone's wondering, the basis of it is that you define tools.mako.directories in your global config, you can then override that in individual app config files.
e.g.
server.conf
...
tools.mako.directories: ['', 'system']
...
site.conf
...
tools.mako.directories: ['site', 'system']
...
I did some extra work to translate the relative URIs to absolute paths, but the crux of it is explained above.