Registry / web-framework / identity

identity

JSON →
library0.11.0pypypi✓ verified 85d ago

Identity is an authentication and authorization library optimized for web applications, building upon Microsoft's MSAL Python. It provides high-level APIs for popular frameworks like Flask, Quart, and Django, simplifying integration with Microsoft Identity Platform. The library is actively maintained with frequent updates addressing bug fixes and introducing new features.

pip install identity[flask]
INSTALL
IMPORT
SIG · IDENTITY
I
identity
web-frameworkpythonv0.11.0
Install
4.6s avg
Import
984ms
Disk
87MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.93.13
musl
3.93.13
Install & Compatibility
Where this runs
tested against v0.11.0 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.103.940 runs
installs and imports cleanly · install 0.0s · import 1.026s · 87.1MB
glibc
py 3.103.940 runs
installs and imports cleanly · install 4.6s · import 0.943s · 88MB
87MB installed
● package 87MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

Auth
from identity.flask import Auth
from identity.web import Auth
For high-level framework integration (Flask, Django, Quart), use the framework-specific import. `identity.web.Auth` is for lower-level or custom scenarios.
login_required
from identity.flask import login_required
from identity.web import login_required
Similar to `Auth`, prefer the framework-specific `login_required` decorator for seamless integration.

This Flask example demonstrates how to set up `identity` for authentication. It initializes `Auth` with credentials typically pulled from environment variables, protects the root route with `@login_required`, handles the redirect after login, and provides a logout mechanism. Ensure you replace the placeholder environment variables with your actual Azure AD (or Entra ID) application registration details for client ID, client secret, and authority.

import os from flask import Flask, render_template_string, session, redirect, url_for, request from identity.flask import Auth, login_required app = Flask(__name__) app.secret_key = os.urandom(32) # Use a strong, rotated key in production # Configure Identity using environment variables auth = Auth( app, authority=os.environ.get('IDENTITY_AUTHORITY', 'https://login.microsoftonline.com/common'), client_id=os.environ.get('IDENTITY_CLIENT_ID', 'YOUR_CLIENT_ID'), client_secret=os.environ.get('IDENTITY_CLIENT_SECRET', 'YOUR_CLIENT_SECRET'), redirect_uri=os.environ.get('IDENTITY_REDIRECT_URI', 'http://localhost:5000/redirect'), endpoint=os.environ.get('IDENTITY_ENDPOINT', 'https://graph.microsoft.com/v1.0/users'), scope=os.environ.get('IDENTITY_SCOPE', 'User.ReadBasic.All').split() ) @app.route("/") @login_required def index(): user_data = session.get('user', {}) return render_template_string( """ <h1>Welcome, {{ user.get('name', 'Guest') }}!</h1> <p>Logged in user details: {{ user }}</p> <p><a href="{{ url_for('logout') }}">Logout</a></p> """, user=user_data ) @app.route(auth.redirect_uri_path) def auth_redirect(): auth.complete_login(request.args) return redirect(url_for("index")) @app.route("/logout") def logout(): return auth.logout(url_for("index", _external=True)) if __name__ == "__main__": # Set dummy values for quick local test if env vars are not set os.environ.setdefault('IDENTITY_CLIENT_ID', 'YOUR_CLIENT_ID_FROM_AZURE') os.environ.setdefault('IDENTITY_CLIENT_SECRET', 'YOUR_CLIENT_SECRET_FROM_AZURE') # Make sure to replace YOUR_TENANT_ID with your actual tenant ID or 'common' for multi-tenant os.environ.setdefault('IDENTITY_AUTHORITY', 'https://login.microsoftonline.com/YOUR_TENANT_ID') os.environ.setdefault('IDENTITY_REDIRECT_URI', 'http://localhost:5000/redirect') os.environ.setdefault('IDENTITY_ENDPOINT', 'https://graph.microsoft.com/v1.0/me') os.environ.setdefault('IDENTITY_SCOPE', 'User.ReadBasic.All') print("\n--- To run this app, make sure to replace placeholders YOUR_CLIENT_ID_FROM_AZURE and YOUR_CLIENT_SECRET_FROM_AZURE with actual values from your Azure App Registration. ---\n") app.run(debug=True, port=5000)
Debug
Known issues
breakingThe default behavior of the `prompt` parameter in `Auth` has changed. Previously, it effectively always prompted for login; now, it defaults to `None` which allows automatic sign-in if an active session with the identity provider already exists.
fix
If you require the old behavior (always show a login page), explicitly set `prompt="select_account"` in the `Auth` constructor: `Auth(..., prompt="select_account")`.
affects: 0.11.0+
breakingDjango views decorated by `@login_required` must now accept a keyword-only parameter named `context`.
fix
Update your Django view functions to include the `context` parameter: `def your_view(request, *, context):`.
affects: 0.6.0+
breakingThe Django API's logout URL was normalized, potentially breaking existing logout links in templates.
fix
Update your Django templates to use the new logout URL pattern: `<a href="{% url 'identity.logout' %}">Logout</a>`.
affects: 0.7.0+
gotchaWhen using Flask/Quart factory patterns, `Auth` must be initialized using `init_app(app)` after the application object is created.
fix
Instead of `auth = Auth(app, ...)`, initialize with `auth = Auth(...)` and then `auth.init_app(app)`.
affects: 0.9.0+
Errors
Common errors & fixes
TypeError: your_view_func() missing 1 required keyword-only argument: 'context'
After upgrading to `identity` 0.6.0 or later, Django views decorated with `login_required` now expect a `context` keyword argument.
fix
Modify your Django view function signature to accept `context`: `def your_view_func(request, *, context):`
RuntimeError: redirect_uri is not configured. Please provide it in Auth(redirect_uri=...)
The `redirect_uri` parameter was either omitted or incorrectly configured in the `Auth` constructor, which is crucial for the OAuth flow.
fix
Ensure that the `Auth` constructor includes a valid `redirect_uri` that matches what's configured in your Identity Provider (e.g., Azure AD App Registration): `auth = Auth(..., redirect_uri="http://localhost:5000/redirect")`
Users are always prompted to log in, even if they have an active session with the Identity Provider.
As of `identity` 0.11.0, the default for the `prompt` parameter in the `Auth` constructor changed, allowing automatic sign-in. If you upgrade from an older version, the behavior might seem like it's always prompting.
fix
If you explicitly want to force a login prompt every time (the old behavior), set `prompt="select_account"` in your `Auth` configuration: `auth = Auth(..., prompt="select_account")`.
Upgrade
Version history
0.11.0latest on PyPI · released Jul 7, 2025
Audit
Dependencies
msalrequiredCore authentication logic is built on MSAL Python.
flaskoptionalRequired for Flask integration features.
djangooptionalRequired for Django integration features.
quartoptionalRequired for Quart integration features.
Agent activity
26 hits · last 30 days
node
24
OpenAI (training)
1
Resources
identity — pip install identity · libregistry