Call torando Request Handler function without running tornado loop start? - python

I need to store the output of a get function of a request handler before running the tornado server from outside the application.
Example:-
class Test(RequestHandler):
def get:
print "safds"'
....
...
I need to call get function without tornado loop server from outside. Is it possible ? Is there any turnaround. Please help.
Thanks

If you happen to end up reading this question, I knew that I had to somehow create an instance of my handler to be able to call the post or get function inside. After looking at the RequestHandler's implementation, I came up with the following snippet:
from tornado.web import Application
from tornado.httpserver import HTTPRequest
mock_app = Mock(spec=Application)
request = HTTPRequest(
method='GET', uri='/', headers=None, body=None
)
response = Handler(mock_app, request).get()

Related

When using Python/Tornado, is it possible to call another API thru http request within a handler?

I have written a set of python REST APIs that are served by the Tornado web framework. The issue I am facing is like this: When handling endpoint1 or API1, I need to get at some data that endpoint2 or API2 can provide. So, inside the handler for endpoint1, I call something like this:
class endpoint1(tornado.web.RequestHandler):
.........
def get(self):
..........
http_client = AsyncHTTPClient()
url = "http://127.0.0.1:8686/v1/endpoint2"
response = yield http_client.fetch(url)
But, the code just hangs at this point. My guess is it doesn't work since the framework is currently in the middle of servicing endpoint1 and I am trying to sneak in another request within. I am looking for suggestions on how to get this to work without using MQ or databases.
I tried using nest_asyncio also - no dice. Any help appreciated
Turns out that nest_asyncio actually does the trick. Here is a link to another thread that explains it well: RuntimeError: This event loop is already running in python
import nest_asyncio
nest_asyncio.apply()
class endpoint1(tornado.web.RequestHandler):
.........
def get(self):
..........
http_client = AsyncHTTPClient()
url = "http://127.0.0.1:8686/v1/endpoint2"
response = await http_client.fetch(url)

Writing an HTTP serrver with context in python

I'm trying to write an HTTP server in python 2.7. I'm trying to use ready-made classes to simplify the job (such as SimpleHTTPServer, BaseHTTPRequestHandler, etc.).
The server should listen for GET requests, and once it gets one - parse the request (the path and the arguments), and interact with an already initialized object (which accesses a DB, counts number of requests, etc.) - let's call it the 'handler', and return a response.
I understand that the RequestHandler class (e.g. BaseHTTPRequestHandler) will be constructed for each request. How can I pass the 'handler' to the handling routines, so that they could call its methods?
Thanks!
Use a framework to further simplify your job. Here is an example in flask:
from flask import Flask
from flask import request
app = Flask(__name__)
your_handler = SomeHandlerClass()
#app.route("/")
def index():
return your_handler.do_something_with(request)
if __name__ == "__main__":
app.run()
request is a proxy object that holds all the incoming request data.

Call Tornado WebSocketHandler from Requesthandler

I am using Tornado Webserver and want to internally call a WebSocketHandler from a RequestHandler.
It is not possible to use the redirect /redirectHandler functionality, because the WebSocketHandler class to call ("IndexHandlerDynamic1" in the example below) will be created with a classFactory.
Using the definition of Requesthandler (here) my example looks like:
class IndexHandlerDynamic1(tornado.web.WebSocketHandler):
def initialize(self):
print "Forwarded to Websocket"
def open(self):
print "WebSocket opened"
class IndexHandlerDistributor(tornado.web.RequestHandler):
def get(self, channelId):
IndexHandlerDynamic1(self.application, self.request)
If I request the related url he jumps into IndexHandlerDistributor and IndexHandlerDynamic1.initialize() is called.
But on Clientside the Browser console outputs the following error:
Error during WebSocket handshake: Unexpected response code: 200
Obviously the socket connection is not opened correctly, what's my mistake ?
EDIT:
Thanks to Ben for his help!
Sadly I still have trouble to route the user to a dynamically created class named like a url parameter. I hope you can understand my problem by having a look on my example:
app = tornado.web.Application(
[(r"/", IndexHandler)] +
[(r"/channel/(?P<channelId>[^\/]+)?", ClassFactory(channelId))]
)
How to use channelId as a parameter for my call of ClassFactory as Requesthandler?
Or is there maybe another way to dynamically change the routing of my application while the application is running? If so, i could use this way to solve my initial task.
The problem is that you're attaching two RequestHandlers to the same request. I'm not sure that dynamically creating handler classes is a great idea, but if you want to do it just pass your factory function (which is not itself a RequestHandler) to the url routing table. The routing table doesn't necessarily need a RequestHandler subclass, it just needs an object which can be called with (app, request) and return a RequestHandler instance.

Redirect all ips in config file to static address

Currently using Tornado as a wrapper for several WSGI apps (mostly Flask apps). Recently been noticing a lot of hacking attempts, and been wondering if it's possible to automatically look at a list of the IPs defined in some file and then redirect all of those IPs to a page saying something like "Someone using this IP tried hacking our site, prove you're not a bot and we'll re-allow your ip".
The tornado code that runs the server is here:
from tornado.wsgi import WSGIContainer
from tornado.httpserver import HTTPServer
from tornado.ioloop import IOLoop
from Wrapper.app import application
http_server = HTTPServer(WSGIContainer(application))
http_server.listen(80)
IOLoop.instance().start()
And wrapper.app is below:
from werkzeug.wsgi import DispatcherMiddleware
from Splash import splash_app
from SentimentDemo import sentiment_app
from FERDemo import FER_app
application = DispatcherMiddleware(splash_app, {
'/api/sentiment': sentiment_app,
'/api/fer': FER_app
})
I haven't been able to find any documentation on this sort of thing, so I'm sorry in advance if this question seems uninformed, but even just a place to start looking would be spectacular.
You want to subclass WSGIContainer and override its __call__ method. Something like
class MyWSGIContainer(WSGIContainer):
def __call__(self, request):
if request.remote_ip in blacklist:
self.write_redirect()
else:
super(MyWSGIContainer, self)(request)
For some tips on writing self.write_redirect() look at the code for the WSGIContainer here; you can see how it formats the HTTP headers. You should use HTTP 302 Temporary Redirect.
Then pass your MyWSGIContainer instance into HTTPServer, instead of the default WSGIContainer.

What's the Google App Engine equivalent of ASP.NET's Server.Transfer?

Server.Transfer is sort of like a Redirect except instead of requesting the browser to do another page fetch, it triggers an internal request that makes the request handler "go to" another request handler.
Is there a Python equivalent to this in Google App Engine?
Edit: webapp2
With most Python frameworks the request handler is simply a function: I should imagine you can just import the actual handler function you want to use and pass it the parameters you received in the current handler function.
In Django (for example): you usually have a function that takes at least 1 parameter, the request object. You should be able to simply import the next handler and then return the result of executing it. Something like:
def actual_update_app_queue_settings(request):
return HttpResponse()
def update_app_queue_settings(request):
return actual_update_app_queue_settings(request):
For the framework you've mentioned, probably something like this:
class ProductHandler(webapp2.RequestHandler):
def get(self, product_id):
self.response.write('You requested product %r.' % product_id)
class ProductHandler2(webapp2.RequestHandler):
def get(self, product_id):
nph = ProductHandler()
nph.initialize(request, response)
nph.get(product_id)
I'm fudging that by looking at http://webapp-improved.appspot.com/guide/handlers.html: it looks reasonable. If you're using route annotations I'm honestly not sure what you do, but that might do it.
Usually, you just have to call the corresponding method.
For being more specific... Which flavour of AppEngine are you using? Java, Python, Go... Php?
If you are using java/servlet, then the "forward" is
protected void doGet(HttpServletRequest request, HttpServletResponse response){
request.getRequestDispatcher("/newurl").forward(request, response);
}

Categories

Resources