Using django for non http requests - python

Can I use django to handle non http-requests and responses? I have a django web application serving up webpages, and I would like to use it to also communicate with other devices (hand-held gps sending in status reports and receiving ack) over tcp, but django reports that the requests are "
code 400, message Bad HTTP/0.9 request type".
[28/Sep/2015 15:14:26] code 400, message Bad HTTP/0.9 request type ('[V1.0.0,244565434376396,1,abcd,2015-09-28')
[28/Sep/2015 15:14:26] "[V1.0.0,244565434376396,1,abcd,2015-09-28 14:14:12,1-2,865456543459367,2,T1]" 400 -
The message from the device is sent as text over tcp with no http parameters at all.
I haven't found any information on how to do this with django, but it would make my life easier if it was possible.
Thanks!

Not that I know of.
Django is a web framework, so it's designed around a certain paradigm if not a certain protocol.
The design is heavily informed - if not by HTTP - by the notions of URL, request, a stateless protocol, et cetera.
If the template system and the routing system were taken away you would be left with a glorified ORM and some useless bits of code.
However, unless you are dealing with existing devices with their own protocol, you can use Django to build a RESTful service to successfully exchange information with something other than bipeds in front of a web browser.
This article on Dr. Dobb's is very informative.
Django REST, although by no means necessary, can help you.
If you are really stuck with legacy devices and protocols, you could write an adapter/proxy that would receive your devices' requests and translate them to RESTful calls, if you protocol looks enough like HTTP semantically rather than syntactically (as in, if you just have to translate QUUX aaa:bbb:ccc: to GET xx/yy/zz).
If it does not share the slightest bit of HTTP's semantics, I'd say Django can't help you much.

I second the suggestion that you can better handle non-http with other methods, but I do have a suggestion as to how to structure a Django app that could do it. HTTP processing takes place in middleware and you could just make your app be on the top of that stack and either pre-empt other middlewares by returning the response instead of passing it down the stack or preparing a mock request to pass down to other handlers, grabbing the response on the way back to post-process it for your receiver.
This feels hacky and might require a bunch of un-orthodox tricks but that's how I would approach the problem as stated.

Related

How to interpose RabbitMQ between REST client and (Python) REST server?

If I develop a REST service hosted in Apache and a Python plugin which services GET, PUT, DELETE, PATCH; and this service is consumed by an Angular client (or other REST interacting browser technology). Then how do I make it scale-able with RabbitMQ (AMQP)?
Potential Solution #1
Multiple Apache's still faces off against the browser's HTTP calls.
Each Apache instance uses an AMQP plugin and then posts message to a queue
Python microservices monitor a queue and pull a message, service it and return response
Response passed back to Apache plugin, in turn Apache generates the HTTP response
Does this mean the Python microservice no longer has any HTTP server code at all. This will change that component a lot. Perhaps best to decide upfront if you want to use this pattern as it seems it would be a task to rip out any HTTP server code.
Other potential solutions? I am genuinely puzzled as to how we're supposed to take a classic REST server component and upgrade it to be scale-able with RabbitMQ/AMQP with minimal disruption.
I would recommend switching wsgi to asgi(nginx can help here), Im not sure why you think rabbitmq is the solution to your problem, as nothing you described seems like that would be solved by using this method.
asgi is not supported by apache as far as I know, but it allows the server to go do work, and while its working it can continue to service new requests that come in. (gross over simplification)
If for whatever reason you really want to use job workers (rabbitmq, etc) then I would suggest returning to the user a "token" (really just the job_id) and then they can call with that token, and it will report back either the current job status or the result

Client-Server framework for python

I'm currently working on a University project that needs to be implemented with a Client - Server model.
I had experiences in the past where I was managing the communication at socket level and that really sucked.
I was wondering if someone could suggest an easy to use python framework that I can use for that purpose.
I don't know what kind of details you may need to answer so I'm just going to describe the project briefly.
Communication should happen over HTTP, possibly HTTPS.
The server does not need to send data back or invoke methods on the clients, it just collects data
Many clients send data concurrently to server, who needs to distinguish the sender, process the data accordingly and put the result in a database.
You can use something like Flask or Django. Both frameworks are fairly easy to implement, Flask is much easier than Django IMO, although Django has a built in authentication layer that you can use, albeit more difficult to implement in a client/server scenario like you need.
I would personally use Flask and JWT (JSON Web Tokens), which will allow you to give a token to each client for authentication with the server, which will also let you differentiate between clients, and you can use HTTPS for your SSL/TLS requirement. It is tons easier to implement this, and although I like django better for what it brings to the table, it is probably overkill to have you learn it for a single assignment.
For Flask with SSL, here is a quick rundown of that.
For JWT with Flask, here is that.
You can use any database system you would like.
If I understood you correctly you can use any web framework in python. For instance, you can use Flask (I use it and I like it). Django is also a popular choice among the python web frameworks. However, you shouldn't be limited to only these two. There are plenty of them out there. Just google for them.
The implementation of the client depends on what kind of communication there will be between the clients and the server - I don't have enough details here. I only know it's unidirectional.
The client can be a browser accessing you web application written in Flask where users send only POST requests to the server. However, even here the communication will bidirectional (the clients need to open the page which means the server sends requests back to the client) and it violates your initial requirement.
Then it can be a specific client written in python sending some particular requests to your server over http/https. For instance, your client can use a requests package to send HTTP requests.

User management in Single Page App + REST backend

What is the best way to do user management in a single page JS (Mithril) app? I want users to login to load preferences and take on a role so they gain certain permissions. I have a REST API backend written in Python (Falcon web framework). Having read a bit into it, it seems to boil down to sending credentials to the backend and get a token back. But the question is how that should be done. It seems that tokens are a better method than cookies, but that has effects on the exchange of secrets/tokens. the 'xhr.withCredentials' method seems to be cookie based for instance. JWT (json web tokens) seems like a modern, interesting option, but it's hard to find a clear explanation how it could be used with a SPA.. And once the Mithril app has a token, where should I store it and how should I use it with subsequent requests?
This isn't so much about Mithril, actually the only Mithril-related area is the server communication. That is done with the m.request method (docs here), but you need to create an object for all server communication that requires authentication.
That object should have knowledge about the auth system and detect if a token expired, then request a new one, take proper action if things fail, etc. It's a bit of work, but the process is different for most auth systems, so there's not much to do about it, except using something that already exists.
Being a small and lean MVC framework, Mithril doesn't have any security-related features built-in, but the m.request method is very powerful and you should use that inside the auth communication object.
The client-side storage will be in cookies or HTML5 storage. Here's an StackExchange answer that goes into more depth: https://security.stackexchange.com/a/80767 but the point is that this isn't Mithril-related either.
Thanks for linking to the tokens vs. cookies article, it was very nice!

how to unit test a REST client for an unreliable server?

I'm making a Python-based REST client for a 3rd party service that's still under development. The issue is to test/verify that the client will work under ALL kinds of scenarios. Including incorrect responses.
The client uses the Requests library to make the remote REST calls (mostly GET and POST). And for unit testing, I'm thinking of employing the HTTPretty module to simulate/mock the server responses.
The problem is how to deal with the sheer number of possible test cases. Consider the following made-up API;
REQUEST (GET) = http://example.com/new_api?param1=34&param2=hello
RESPONSE = {"value1":34,"value2":"a string"}
I find myself needing to write unit test cases for the following scenarios -
client sending correct number of parameters
client sending incorrect parameter values
client missing a parameter
server's correct responses for above scenarios
server not sending back all the required values
server mixing up value parameters (returning a string instead of a number)
server sending back HTML instead of JSON
... etc
The intent behind all this extensive testing is to help identify where an error could originate from. i.e. is it my client that's having an issue, or the 3rd party server?
Does anyone know of a good way to organize a Python test suite to accommodate these scenarios? Writing unit test functions feels like it will become a never-ending task... :(
That's the goal of unit testing is to test all the cases where you think, you might have to handle errors. On the other hand you do not need to test things which are already handled naturally by the system.
Note that HTTP is an application level protocol where the client always initiates the request and the server just responds. So what I mean by this, is that because you are developing the client you are not responsible of the server response. Your goal is just to sent the appropriate requests.
On the other hand, there are HTTP responses which might trigger behaviors on the client side. These you want to test. For example, the server answers a 301, and you want to test if your client does the right thing by initiating the next request, grabbing the Location: HTTP header value.
In the case of a REST API (aka hypertext driven), your client will parse the content of the HTTP responses and specifically the set of links and/or rel associated value. Based on these values, the client may make decisions or expose possible choices to the users. These you have to test.
If the server doesn't give the information inside the HTTP response for continuing your exploration on the client side, then it's not a REST API, but a perfectly valid HTTP API. Simple as that. It becomes even easier to test. Nothing much to do.

Flask User Management : How to make Stateless Server using better authentication ways?

I have been reading at multiple places and it is suggested that the Web Servers should be Stateles with share nothing architecture. This helps them scale better.
That means each request has all the information needed to process the request.
This becomes tricky when you have REST endpoints that needs authentication.
I have been looking at ways Flask extensions do this and Flask Login extension is defined as
Flask-Login provides user session management for Flask. It handles the
common tasks of logging in, logging out, and remembering your users’
sessions over extended periods of time.
This seems like against the philosophy of building a Stateless server, isn't it?
What are better ways to build a Stateless server with authentication provided via HTTP headers with Python or related python libraries?
P.S: Apologies for not posting a programming question here, this is a design issue and I do not know how to solve it and SO seems to have right people to answer such questions. Thanks.
Flask-Login uses flask's built in session management, which by default uses secure/signed cookies, and so is purely client side.
It can support server side sessions if needed though of course, here's an example redis backed session store.
I've the same problem as you have said.
While I have built a simple solution for this but looking for a better one.
What I currently did is to ask the caller (Who send the http request) provide a 'X-User-Info' in the http header, the value is a token. When I received the request, I use this token to get user identity (From redis for instance) and all of the following authorization & permission control are based on this identity.
The authentication does nothing but generate a random token, save it with user info to redis and return the token itself to the caller.

Categories