Routes in bottle which proxy to another server - python

I have a bottle.py application which has a number of routes already built. I would like to create a new get route which, when accessed, passes the request along to another HTTP server and relays the result back.
What is the simplest way to get that done?

In principle, all you need is to install the wsgiproxy module and do this:
import bottle
from wsgiproxy.app import WSGIProxyApp
root = bottle.Bottle()
proxy_app = WSGIProxyApp("http://localhost/")
root.mount(proxy_app,"/proxytest")
Running this app will then proxy all requests under /proxytest to the server running on localhost:80. In practice, I found this didn't work without taking extra steps to remove hop-by-hop headers. I took the code in this gist and stripped it down to make a simple app that successfully proxies the request.

Related

How to use underscore headers with waitress?

I've been working in a Flask project using waitress for production environement (Targeting Linux ARM and Windows), and I need to recieve a request from a service which has a headers like "dev_id" and "request_code" (doc).
Waitress got a pull request in 2015 (link) basically skipping headers containing _, which explains why the headers are not present in the request object.
I've considered switching to Gunicorn, but Windows support is a must-have.
Using flask as a self-WSGI works, but do not seems to be the perfect approach for a production environement.
Using raw socket for HTTP instead of Flask sounds acceptable, but demands some work for refactoring.
Changing the header name is not an option as I do not have access.
I want to read the header dev_id sent by my client in a Flask application, but waitress doesn't let me do that. Is there any way to ignore this rule? Any workarounds?

FLASK: Does the code outside the routers get executed every time a new request comes in?

The following is a basic flask app:
from flask import Flask, render_template, request
import pickle
import os
cur_dir = os.path.dirname(__file__)
clf = pickle.load(open(os.path.join(cur_dir, 'pkl_objects/classifier.pkl'), 'rb'))
#app.route('/')
def index():
return "RESPONSE"
Now my question is whether the model is loaded every time a new request is made to this server or is it loaded just once and only the routes get executed for every incoming request? This is hard to figure out using a simple Flask development server since it contains only one thread. So if a deployment server spawns a thread for each request, will the loading of model happen each time?
Your code is a regular python code. What happens when you start the application is that your Python WSGI HTTP Server (there are plenty of WSGI servers like gunicorn) loads this script and verifies the minimal requirements for a WSGI Servers (which flask takes care of). See here for details. This server might start several instances of this script for performance purposes, then your model will be loaded several times.
Then what happens when a request is made is that the server balances this request in one of the previously started process and access the flask object in it directly (so it doesn't reload the code). However, some servers might adapt the number of process depending on the number of request, and your model will be reloaded.

Using twisted to selectively reverse proxy to different servers

I'm using Twisted (well twistd actually) to serve content like this currently :
twistd -n -o web --path=./foo/
That's fine but I want to send some requests to another server - like this.
When the client requests
localhost/something.html
I want the request to be handled by the twistd server .
But when the client requests
localhost/api/somedata
I want the request to be reverse proxied to another server .
So in summary if the URL contains the string "api" then I want the request reverse proxied elsewhere.
I can see that Twisted has a built in Reverse Proxy but I don't know how to use that so that I can filter requests made in such a way that some requests would get sent off to the alternative server and some wouldn't.
ReverseProxyResource is a resource. You can place it into a resource hierarchy.
root = Resource()
root.putChild("something.html", SomethingHTML())
root.putChild("api", ReverseProxyResource(...))
This is just one example of an arrangement of the resource hierarchy. You can combine ReverseProxyResource with other resources in any of the ways supported by IResource.

Accessing request data of all requests that is being received with Flask

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.

Pylons 0.9.6 Get Current Server Name

In my Pylons config file, I have:
[server:main1]
port = 9090
...config here...
[server:main2]
port = 9091
...config here...
Which are ran using:
paster serve --server-name=main1 ...(more stuff)...
paster serve --server-name=main2 ...(more stuff)...
Now, using Haproxy and Stunnel, I have all http requests going to main1 and all https requests going to main2. I would like some of my controllers to react a little differently based on if they are being requested under http or https but pylons.request.scheme always thinks that it is under http even when it is not.
Seeing as I always know that main2 is always the one handling all https requests, is there a way for the controller to determine what sever name it was ran under or what id it is?
I got around this by just changing the workflow to not have to react differently based on what protocol it's under. It doesn't look like there's a way to pass a unique arbitrary identifier to each separate process that it can read.

Categories

Resources