OAuth for Python made easy
github.com
github.com
Doing OAuth signing logic correctly is pretty finicky. Requests is great, and we provide a shim layer for it, but it's silly to reimplement the underlying request signing logic for requests, urllib3 or what-have-you. And what happens when you need a server-side implementation for verifying signatures? It makes more sense to do the tricky logic in a separate, testable library than tying it to one representation of an HTTP request.
Having said all this, anybody willing to wade into this mess and write something is my kind of crazy. Respect.
After doing Django for 5 years, the nail in the coffin was when I wanted to simply access a users me object from their facebook graph timeline. Riddle me that. In ruby-pragmatism land it's a gem and a line or two of code away, thanks to the awesome Koala library.
Kenneth Reitz's recent requests library is the first refreshing and pragmatic python tool I have seen in a long time. This oauth library shares the same friendly and straightforward interface too. The docs and examples are directly clear and directly in front of you. It's simple and pragmatic.
The stars on the repo's speak for themselves ... rauth has over 700 stars, whereas oauthlib has considerably less than half of that. I'm not trying to tell you that you suck, because I admire your work quite a lot, but I think these days developers want simple and pragmatic.
It's not about stars. It's about the right architectural choice. Believe me when I say that we thought long and hard about the structure of OAuthLib, and it looks nothing at all like Java. When we started out, we were reacting to the mess that is/was python-oauth[2] and its class-based ridiculous. Like all real-world projects, after spending time with the spec and refactoring the parts which were common to the various signing flows, you end up with some real-world ugly.
Second, you're trying to solve a different problem than rauth solves: we needed a library that provided for the practical, de facto implementation of OAuth 1.0/a and 2.0 as well as Ofly which allowed us to consume provider APIs. This is exactly what rauth does. It loosely wraps Requests, which means you get to basically use Requests that also happens to handle real-world OAuth providers as a consumer. I don't think it's really fair to call this "silly": it's clearly filled a hole in the ecosystem for some people.
If you want to consume an OAuth provider, rauth tries to give you a simple interface to do so with. It's almost as easy as using Requests. You might even say, it's OAuth for Humans. (Sorry, Kenneth. :)
Edit: to be clear, rauth is about pragmatic simplicity, about a clean API that's pleasant to work with. It's a client for OAuth modeled around the fact and philosophy of Requests. Vis-à-vis everything else I've seen, this is in pretty stark contrast to existing libraries.
Why not a layered API, with lower levels supporting a higher-level wrapper library using requests?
All the same: OAuthLib and its libraries cover the exact use-case you've laid out, just in a fashion that has some architectural benefits on top of the usability goals. The simple "OAuth for Humans" thing you're reaching for exists—it's https://github.com/requests/requests-oauthlib. Kenneth and I hashed this interface out before we started out on OAuthLib, and thus far it's the only shim library for OAuthLib I know of (though it's pretty simple to write something equivalent which bridges OAuthLib's domain knowledge and any given HTTP request implementation). I even rewrote Requests' underlying auth implementation to make this sort of thing possible. And now you have:
oauth = OAuth1(client_key=key, client_secret=secret) r = requests.post(url=request_token_url, auth=oauth)
I don't see OAuth1 getting simpler than that, and the underlying signing logic is there for anybody to use in any context—as a provider, consumer, in a stubbing library—whatever!
Nope. They very much do not: your expectation is that your users will roll their own clients or use Requests' shim, which seems a little rough around the edges and doesn't provide for the necessary use cases, e.g. OAuth 2.0 and Ofly. I'm sorry, but this is not providing for the use cases I've laid out by any stretch of the imagination.
Rauth is batteries included, ready to get you up and running in minutes, not hours or days. You won't need to write your own client or patch an existing client to make it work with an unsupported protocol like OAuth 2.0.
> I don't see OAuth1 getting simpler than that
Then you haven't used rauth. The whole auth dance is taken into consideration and various helpers make it a breeze, literally a two or three step process. Further, once you have tokens, it becomes as simple as:
session.get('me')
Now, that's what I call simple.I think in your attempts to compare your lib to rauth you're missing the broader thrust of rauth: rauth is a client library. It makes using OAuth (1.0/a, 2.0, even the OAuth-ish Ofly) as easy as we can make it. This is far removed from the goal of some generalized, spec-centric, even idealized, implementation of OAuth as a spec. Rauth isn't trying to do that, it's trying to make it easier for you to connect to Facebook or Twitter or whatever provider you happen to need. I wouldn't really know, but I've been told, it seems to shine in this regard. :)
I guess I just feel like tying to one specific service is too specialized. Libraries like requests should be providing you with enough primitives to be flexible and enough abstraction to be "simple," though we clearly disagree on what constitutes the appropriate balance.
EDIT: Although their README only shows an OAuth1 example, check out https://github.com/litl/rauth/blob/master/examples/github-cl... for an example of using it with an OAuth2 provider.
It's not complicated to break down the UI as you need it.
[0] https://dev.twitter.com/docs/auth/3-legged-authorization
For django, I struggled, and struggled. Found a couple of libraries and a number of forks of these spread across github and bitbucket. Got one, but it didn't work. Debugged the code, fixed some stuff in my own fork, and got it working 5 hours later.
The world of python seems to have lots of half-baked libraries that are dead or dying. Makes you miss Ruby / Rails.
Rauth is a good start, but without a library that couples it to a full web stack, I'm spending a lot of time hooking it into my flask app and trying to make sure I don't make mistakes managing my session variables, etc.
Perhaps I'll start up a rauth-providers repo to catalog this stuff.
My company (dailycred) wraps ten OAuth 1 & 2 providers, as well as email & password and Mozilla Persona in a single OAuth 2 call.
(We started this project because even just within OAuth 2, providers break spec left and right and OAuth can be a huge headache, so we manage all of those headaches for our customers.)