The GAE team made AEoid's interface very similar to the App Engine Users API so users could leverage a familiar environment:
from aeoid import users
user = users.UserProperty()
user = users.get_current_user()
if not user:
logging.warn("Logged in as %s (%s)", user.nickname(), user.user_id())
data = TestData(user=user)
There are just a few differences. First, you have to specify an OpenID URL in order to construct a User Object. Users are identified by their OpenID endpoint. Since nicknames and email addresses are user-generated, they're not validated or guaranteed to be unique. is_current_user_admin() hasn't been implemented and login: clauses in app.yaml are not affected by AEoid, but they still use the regular Users API to authenticate.
AEoid uses a single piece of WSGI middleware, which you include in your app upon installation. With App Engine's built in webapp framework, or any other framework that calls the run_wsgi_app function, App Engine's configuration framework can be used to install AEoid.
from aeoid import middleware
app = middleware.AeoidMiddleware(app)
Frameworks that don't use run_wsgi_app, will need to insert the middleware into the processing chain.
application = webapp.WSGIApplication([
application = middleware.AeoidMiddleware(application)
The AEoid code uses the python-openid library for authenticating with OpenID. The beaker sessions library is used for user session tracking. The components of the AEoid code include request handlers, the public interface, and the middleware code. The request handlers (login/log out pages and requests) contain most of the OpenID machinery. Users submit their OpenID URL then the login handler redirects them back to their provider after creating an OpenID request. After login is finished, the provider sends the user back to AEoid's completion handler, which then creates the user session and redirects them back to the application. The public interface is just like the App Engine Users module. User objects are wrappers around a datastore entity with the user's information. A UserProperty stores the key to the internal User object while providing a UI identical to the UserProperty's interface.
Although AEoid should be compatible with most frameworks, it has only been tested with the webapp framework so far. The code may have problems integrating with frameworks that include their own copy of beaker or python-openid. The GAE team says there's a lot of room for improvement on AEoid. If you are using AEoid with a framework other than webapp, the team wants to know about it so they can add the frameworks to the list of compatible integrations. GAE is also looking for feature requests and bug reports. They say the UI is subject to change depending on user feedback. Users can't configure the OpenID library right now, but the GAE team says this will likely change in the near future.