Socket Connection between django servers - python

I am newbie for django and python. The thing what I need is, connecting more than one django server with socket. One of these servers (main server) will get a request from mobile client with Django-REST API, and then, it should transmit it to the other django servers related to an ID of the server. (e.g. When main server gets data with an ID as 1, it should transmit the data to the server#1, if it gets the data with ID 2, it should transmit the data to server#2)
I am looking forward your advices..
p.s. Http requests cannot be sent to the django servers except main one. Each of them are intranet application and locations are different. The only way to send data to these servers via http is, sending the request to main server with the ID of the servers.

If you are not able to send an (internal) http request not even to localhost you can try to speak to the WSGI API of the different django apps. The main app might create a WSGI application object and fill it with pseudo request data.
# views.py of the main server
def myview(self, request):
# do some stuff
if server_id = 1:
from server_1_app.wsgi import application
response = application(environ, pseudo_request)
# ...

Related

How to store a message from the client in the server and send it further via some route in Flask

From a web application, this is making a request to the backend application (Python with Flask and flask-socketio). From this route on the backend, an emit should be done to a socketio client standalone application. This works fine, but when the client app sends back a message directly after, I want to retrieve this message and send it back in my route to the web application. The message I get back from the client via a callback will be asynchronous, so how in the simplest manner could this be achieved? Each time I fetch the message from the client, the route has already sent back a reply to the web app without the message.
I fully understand that this flow is usually not normal, but can this be achieved without saving this message into a database, but store it somewhere on the backend and send it back to the web app?
You can use an Event object from the Python standard library.
from threading import Event
my_event = Event()
In your Flask route:
my_event.wait() # block until the event is signaled
return socketio_response
In your Socket.IO callback function:
socketio_response = data
my_event.set() # alert the route that a result is now available

Bottle-WebSocket: How to ensure an HTTP request is from the same session as ws connection?

I built an web application using Python Bottle framework.
I used bottle-websocket plugin for WebSocket communication with clients.
Here is a part of my code.
from bottle import Bottle, request, run
from bottle.ext.websocket import GeventWebSocketServer, websocket
class MyHandler():
...
class MyServer(Bottle):
...
def _serve_websocket(self, ws):
handler = MyHandler()
some_data = request.cookies.get('some_key') # READ SOME DATA FROM HTTP REQUEST
while True:
msg = ws.receive()
handler.do_sth_on(msg, some_data) # USE THE DATA FROM HTTP REQUEST
ws.send(msg)
del(handler)
if __name__ == '__main__':
run(app=MyServer(), server=GeventWebSocketServer, host=HOST, port=PORT)
As the code shows, I need to read some data from the browser (cookies or anything in the HTTP request headers) and use it for WebSocket message processing.
How can I ensure the request is from the same browser session as the one where WebSocket connection comes?
NOTE
As I do not have much knowledge of HTTP and WebSocket, I'd love to here detailed answere as much as possible.
How can I ensure the request is from the same browser session as the one where WebSocket connection comes?
Browser session is a bit abstract since HTTP does not have a concept of sessions. HTTP and RESTful APIs is designed to be stateless, but there is options.
Usually, what you usually want to know is what user the request comes from. This is usually solved by authentication e.g. by using OpenID Connect and let the user send his JWT-token in the Authorization: header, this works for all HTTP requests, including when setting up a Websocket connection.
bottle-oauthlib seem to be a library for authenticating end-users using OAuth2 / OpenID Connect.
Another option is to identify the "browser session" using cookies but this depends on a state somewhere on the server side and is harder to implement on cloud native platforms like e.g. Kubernetes that prefer stateless workloads.

Flask: asynchronous response to client

I'm using Flask to develop a web server in a python app. I'm achieving this scenario: the client (it won't be a browser) sends a request, the server does some long task in background and on completion sends the response back to the client asynchronously. Is it possible to do that?
What you ask cannot be done with the HTTP protocol. Each request receives a response synchronously. The closest thing to achieve what you want would be this:
The client sends the request and the server responds with a job id immediately, while it also starts a background task for this long calculation.
The client can then poll the server for status by sending the job id in a new request. The response is again immediate and contains a job status, such as "in progress", "completed", "failed", etc. The server can also return a progress percentage, which the client can use to render a progress bar.
You could also implement web sockets, but that will require socket enabled server and client.

How do I get data from a url callback

I am using a web service that will send a url callback when a particular external event happens (that service is monitoring it 24-7)
I need to have a python script running (locally on my own computer) and waiting (possibly just looping) to receive that callback and then do something with the data.
How do I do this? Do I need to have a webserver running? Where do I look for the data? I am pretty experienced with python, but not much in the use of HTTP and other web related things.
I have looked at other stackoverflow posts but they all seem to presume some prior knowledge.... I need the basics!
Here is a simple server using Bottle Microframework .
from bottle import Bottle, run, route, request
app = Bottle()
#app.route('/listener')
def my_listener():
data = request.query.your_data
#do_something_with_data(data)
return data
run(app, host="0.0.0.0", port=8080)
You can send data to server requesting http://sever_ip:8080/listener?your_data=some_data
Look into setting up a Flask server that will run in the background and listen for the callback request

Empty reply from Django web service

I have created a web service in django and its hosted on a shared server.The django web service respond to request from a game made in unity. But whenever game tries to request a django Web service url the server send empty resonse.Response is always:
WWW Error: server return empty string
The Unity webplayer expects a http served policy file named "crossdomain.xml" to be available on the domain you want to access with the WWW class, (although this is not needed if it is the same domain that is hosting the unity3d file).So I placed a file "crossdomain.xml" at the root of my domain ,but still i am getting same empty reply.Help plz...
EDIT:
I tried it through browser my service works fine and reply with proper response.And you know what My game can communicate to django web service when both are running on local machine.But now the django project is hosted on actual server and when game tried accessing service it never get response :(
url.py
urlpatterns = patterns('',
url(r'^crossdomain.xml$',views.CrossDomain),
url(r'^ReadFile/$',views.ReadFile),
)
views.py
def CrossDomain(request):
f = open(settings.MEDIA_ROOT+'jsondata/crossdomain.xml', 'r')
data = f.read()
f.close()
return HttpResponse(data, mimetype="application/xml")
def ReadFile(request):
f = open(settings.MEDIA_ROOT+'jsondata/some_file.json', 'r')
data = f.read()
f.close()
return HttpResponse(data, mimetype="application/javascript")
def Test(request):
return HttpResponse("Hello", mimetype="text/plain")
As I said using django for this is slight overkill because you could just serve them. Point aside though. If your serving on a different server it could be
A) Connection problems mean that your response is lost
B) Firewall issues mean that the request mean something
C) The server isn't setup correctly and therefore it justs get an error.
You need to test the response on the server. so is you access the page on the server through your browser. If so then make the game make a request and check the server error and access logs. In the apache access log you should see something like
GET "/url" 200 each time a request is made.
If you don't see any request getting through then either the request isn't made or its been lost.
If you do then the problem is in the code somewhere.

Categories