I'm developing an application but this application run on two subdomain. This is classicaly.
admin.domain.com and www.domain.com
Tornado is loading routes on initialize time.
def __init__(self):
client_routing = client.routing.Routing.get()
admin_routing = admin.routing.Routing.get()
setting = TornadoSettings.get()
tornado.web.Application.__init__(self, client_routing , **setting)
But I want to load subdomain based routing. May be override rouing function and sperate routing handlers.
I don't know, how to do this.
Patterns passed to the Application constructor will apply to all domains. To use separate routes per domain, pass an empty list to the constructor and use Application.add_handlers instead. This is not very well documented but there is a simple example in the Application class docs
Related
I have a flask route this like:
#app.route('/product/<string:slug>')
def product(slug):
# some codes...
return render_template('product.html', product=product)
Different clients use the project (different websites, same infrastructure). And every customer wants the product URL to be different. Like;
asite.com/product-nike-shoe-323
bsite.com/nike-shoe
csite.com/product/nike-shoue
vs. vs
How do I set the URL structure to come from the database?
like:
url_config = "product-{product_name}-{product_id}"
or
url_config = "product-{product_id}"
Note: please without redirect.
I’m not 100% clear on what you refer to when you say “database” here. From context I infer you may be talking about the Flask Config object. If that’s the case, you can simply register your view function right after setting up the app configuration. Just call app.add_url_rule() to register the URL pattern from the configuration to point to your view function of choice.
If, however, you are talking about a SQL or NoSQL database and you have built a web UI to register routes, then don’t dispair. Flask routes can be registered with the app object at any point. There is no point in the Flask app lifecycle after which you can no longer register a route!
All that registering a route does, is create a mapping between a URL template and endpoint name, an opaque string. Most of the time, you also register a function to be called to handle the specific endpoint, and most of the time, Flask infers the endpoint name from the function. Once registered in the mapping any next incoming request can be routed to the function for the given endpoint.
So, Flask keeps two maps:
from url route -> endpoint name: Flask.url_map
from endpoint name -> function: Flask.view_functions
That said, there is API for removing or changing url registrations (other than restarting your server, of course). You can’t change the url route, the endpoint name for a given route or what endpoint maps to what function. The intention of the framework is that you register your routes early on when first starting your server, via code that runs directly when imported or when bound to the app (Blueprints and Flask extensions do the latter). The majority of Flask apps will create their Flask instance, register all their routes and extensions, then pass the instance to the WSGI server for request dispatch, and that’s it. But there is nothing in the implementation stopping you from registering more routes after this point.
If you want to register URL routes from database information, you have to take care of at least the following two things:
Register existing routes at start-up. Once you have a connection to your database established, retrieve the existing routes and register them.
If a new entry is added to the database, register a new route.
First of all: if I were to implement something like this I’d use one view function. You can always figure out what url rule was matched and what endpoint name this mapped to by looking at request.url_rule and request.endpoint, respectively.
Next, I’d explicitly generate endpoint names for each url rule from the database. Use the primary key in the name; you want to be able to find the database row from the endpoint name and vice versa. How you do this is up to you; let’s assume you know how to do this, and you have two functions for this named pk_from_endpoint() and endpoint_from_pk().
Your view function can then look like this:
from flask import request
def product_request(**kwargs):
key = pk_from_endpoint(request.endpoint)
row = database_query(key)
# … process request
You register a route for a given database row with:
app.add_url_route(row.url_config, endpoint_from_pk(row.id), product_request)
As mentioned, you can’t change URL registrations. But, as long as changes to these URLs are infrequent you could always add new registrations and for any old entries use abort(404) to return a 404 Not Found response.
That's not possible with Flask's routing system. The URL map is supposed to be defined at startup and not change after that.
However, if you have some specific path where you need the dynamic parts (e.g. /product/WHATEVER), then you can register a route for /product/<slug> and query the database within your view function.
That said, if you REALLY want URL rules in a DB, and do not mind connecting to your database during startup (usually that's ugly), then nothing stop you from querying the database at startup time and define the URL rules based on data from the DB. Quite ugly, but doable.
Example:
with app.app_context():
url_map = {u.endpoint: u.rule for u in URLRules.query}
#app.route(url_map['foo'])
def foo():
...
Of course doing so makes it harder to nicely structure your app unless you use app.add_url_rule() for all the endpoints in a single place instead of the #app.route() decorators.
Likewise with blueprints of course.
Gurus, Wizards, Geeks
I am tasked with providing Python Flask apps (more generally, webapps written in python) a way to reload properties on the fly.
Specifically, my team and I currently deploy python apps with a {env}.properties file that contains various environment specific configurations in a key value format (yaml for instance). Ideally, these properties are reloaded by the app when changed. Suppose a secondary application existed that updates the previously mentioned {env}.properties file, the application should ALSO be able to read and use new values.
Currently, we read the {env}.properties at startup and the values are accessed via functions stored in a context.py. I could write a function that could periodically update the variables. Before starting an endeavor like this, I thought I would consult the collective to see if someone else has solved this for Django or Flask projects (as it seems like a reasonable request for feature flags, etc).
One such pattern is the WSGI application factory pattern.
In short, you define a function that instantiates the application object. This pattern works with all WSGI-based frameworks.
The Flask docs explain application factories pretty well.
This allows you to define the application dynamically on-the-fly, without the need to redeploy or deploy many configurations of an application. You can change just about anything about the app this way, including configuration, routes, middlewares, and more.
A simple example of this would be something like:
def get_settings(env):
"""get the (current, updated) application settings"""
...
return settings
def create_app(env: str):
if env not in ('dev', 'staging', 'production'):
raise ValueError(f'{env} is not a valid environment')
app = Flask(__name__)
app.config.update(get_settings(env))
return app
Then, you could set FLASK_APP environment variable to something like "myapp:create_app('dev')" and that would do it. This is also the same way you could specify this for servers like gunicorn.
The get_settings function should be written to return the newest settings. It could even do something like retrieve settings from an external source like S3, a config service, or anything.
So, I want to write this Python code that wants to assess data in requests I am getting and act accordingly. I have many different endpoints and I'd like a way to access the request data for all requests without creating manually every possible endpoint.
Is there a way to do it with Flask/Bottle? A proxy of sorts
You can register a function to be called before every request with the #app.before_request decorator:
#app.before_request
def handle_every_request():
# ...
If this function returns anything other than None, it'll be used as the response and no views will be called. This would let you create any number of routing options.
Another option is to use the request_started signal, see the Signals documentation:
from flask import request_started
#request_started.connect_via(app)
def handle_every_request(sender, **kwargs):
# ...
The above listens to requests for the specific Flask app instance. Use #request_started.connect if you want to listen to all requests for all apps. Signals just listen, they don't route, however.
In general, both Flask and Bottle are WSGI applications. WSGI supports wrapping such applications in WSGI middleware, letting you inspect every ingoing and outgoing byte of a request-response pair. This gives you access to the data at a lower level. You could use this to rewrite paths being requested however.
I've created a Django-rest-framework app. It exposes some API which does some get/set operations in the MySQL DB.
I have a requirement of making an HTTP request to another server and piggyback this response along with the usual response. I'm trying to use a self-made HTTP connection pool to make HTTP requests instead of making new connections on each request.
What is the most appropriate place to keep this app level HTTP connection pool object?
I've looked around for it & there are multiple solutions each with some cons. Here are some:
To make a singleton class of the pool in a diff file, but this is not a good pythonic way to do things. There are various discussions over why not to use singleton design pattern.
Also, I don't know how intelligent it would be to pool a pooler? (:P)
To keep it in init.py of the app dir. The issue with that are as follows:
It should only contain imports & things related to that.
It will be difficult to unit test the code because the import would happen before mocking and it would actually try to hit the API.
To use sessions, but I guess that makes more sense if it was something user session specific, like a user specific number, etc
Also, the object needs to be serializable. I don't know how HTTP Connection pool can be serialized.
To keep it global in views.py but that also is discouraged.
What is the best place to store such app/global level variables?
This thread is a bit old but still could be googled. generally, if you want a component to be accessible among several apps in your Django project you can put it in a general or core app as a Util or whatever.
in terms of reusability and app-specific you can use a Factory with a cache mechanism something like:
class ConnectionPool:
pass
#dataclass
class ConnectionPoolFactory:
connection_pool_cache: dict[str: ConnectionPool] = field(default_factory=dict)
def get_connection(self, app_name: str) -> ConnectionPool:
if self.connection_pool_cache.get(app_name, None) is None:
self.connection_pool_cache[app_name] = ConnectionPool()
return self.connection_pool_cache[app_name]
A possible solution is to implement a custom Django middleware, as described in https://docs.djangoproject.com/ja/1.9/topics/http/middleware/.
You could initialize the HTTP connection pool in the middleware's __init__ method, which is only called once at the first request. Then, start the HTTP request during process_request and on process_response check it has finished (or wait for it) and append that response to the internal one.
I am trying to have one service which will fulfill two related functions. I would like to have something like this for my REST api:
/route1/get/as_text
/route2/get/as_json
In nodejs, you can pass off a collection of routes from some base URL by saying:
app.use('/route1/', route1.js)
app.use('/route2/', route2.js)
and then the route1.js will have routes defined like this:
app.router('/as_text', function(){//some stuff})
When I do this, can define a set of routes, that all have /route1/ as the basis of the URL. I would like to do something similar in flask, where I just define the first section of the url, and add all logic of that section of the API into a file which is separate to another section of the api.
Is this possible in flask? Or should I look for a new approach?
You'll want to take a look at Blueprints.
When defining your application, you can register Blueprints with a path prefix:
app = Flask(__name__, template_folder='views')
app.register_blueprint(controllers.route1, url_prefix="/route1")
app.register_blueprint(controllers.route2, url_prefix="/route2")
Then define the controllers for these routes in separate files.
route1 = Blueprint('route1', __name__, template_folder='views')
#route1.route('/get/as_text',methods=['GET'])
def get_as_text_route():
return json.jsonify(data="my data")
You could also checkout Flask Restful for creating REST APIs in with Flask.