{"id":9276,"library":"repoze.who","title":"repoze.who (Identification & Authentication for WSGI)","description":"repoze.who is an identification and authentication framework for WSGI applications. It provides middleware to manage user identification, authentication, and authorization. The current stable version is 3.1.0, and it is actively maintained by the Pylons Project, though releases are infrequent.","status":"maintenance","version":"3.1.0","language":"en","source_language":"en","source_url":"https://github.com/repoze/repoze.who","tags":["wsgi","authentication","authorization","security","middleware","pylons"],"install":[{"cmd":"pip install repoze.who","lang":"bash","label":"Install stable version"}],"dependencies":[],"imports":[{"note":"The primary function for configuring and instantiating the WhoMiddleware in repoze.who 3.x and newer.","symbol":"make_who_with_config","correct":"from repoze.who.config import make_who_with_config"},{"note":"In repoze.who 3.x+, WhoMiddleware is typically instantiated via `make_who_with_config`. Direct import from `repoze.who.middleware` was common in 2.x and is discouraged/may not work as expected in 3.x.","wrong":"from repoze.who.middleware import WhoMiddleware","symbol":"WhoMiddleware","correct":"from repoze.who.config import make_who_with_config # Indirectly used"},{"note":"Utility to ensure the 'repoze.who' object is properly added to the WSGI environment for request processing.","symbol":"add_new_r_w_to_environ","correct":"from repoze.who.config import add_new_r_w_to_environ"}],"quickstart":{"code":"import os\nfrom webob.dec import wsgify\nfrom webob import Response\nfrom repoze.who.config import make_who_with_config, add_new_r_w_to_environ\nfrom repoze.who.plugins.basicauth import BasicAuthPlugin # Example plugin\n\n# Dummy WSGI application\n@wsgify\ndef my_app(request):\n    identity = request.environ.get('repoze.who.identity')\n    if identity:\n        username = identity.get('repoze.who.userid')\n        return Response(f'Hello, {username}! You are authenticated.')\n    else:\n        return Response('Please authenticate.', status=401)\n\n# Configure repoze.who\n# For real applications, use proper credential storage\nusers_db = {'admin': 'secret', 'user': 'password'}\n\ndef my_authenticator(environ, identity):\n    if 'login' in identity and 'password' in identity:\n        login = identity['login']\n        password = identity['password']\n        if users_db.get(login) == password:\n            identity['repoze.who.userid'] = login # Store userid\n            return login\n    return None\n\n# Example challenge (basic auth)\nbasic_auth_plugin = BasicAuthPlugin('My Realm')\n\n# Who config dictionary (simplified)\nwho_config = {\n    'identifiers': [('basic_auth_identifier', basic_auth_plugin)],\n    'authenticators': [('my_auth', my_authenticator)],\n    'challengers': [('basic_auth_challenger', basic_auth_plugin)],\n    'log_stream': None,\n    'log_level': 10 # DEBUG\n}\n\n# Create WhoMiddleware\nwho_middleware_app = make_who_with_config(my_app, who_config)\n\n# Wrap the app to ensure 'repoze.who' object is in environ\n@wsgify\ndef wrapped_app(request):\n    add_new_r_w_to_environ(request.environ, who_config)\n    return who_middleware_app(request)\n\n# To run this with a WSGI server (e.g., waitress):\n# pip install webob waitress\n# from waitress import serve\n# serve(wrapped_app, host='0.0.0.0', port=8000)\n# (Uncomment above lines to run)\n","lang":"python","description":"This quickstart demonstrates setting up `repoze.who` with a basic authenticator and `BasicAuthPlugin` for identification and challenging. It shows how to use `make_who_with_config` to create the middleware and `add_new_r_w_to_environ` to populate the WSGI environment, then access the identity from `request.environ`. To run this example, you will also need to install `webob` and a WSGI server like `waitress`."},"warnings":[{"fix":"Upgrade your environment to Python 3.9+ and ensure all dependencies are Python 3 compatible. Review the 3.x documentation for configuration changes, especially the use of `make_who_with_config`.","message":"repoze.who 3.x (and higher) is Python 3.9+ only. Earlier versions (2.x) supported Python 2.x. Porting from 2.x requires adapting to Python 3 syntax and potentially updated configuration approaches.","severity":"breaking","affected_versions":"<3.0"},{"fix":"Replace direct `WhoMiddleware` imports and instantiation with `from repoze.who.config import make_who_with_config` and use the configuration dictionary.","message":"The primary method for instantiating the WhoMiddleware has changed. Direct import of `WhoMiddleware` from `repoze.who.middleware` (common in 2.x) is not the recommended approach in 3.x; instead, use `make_who_with_config`.","severity":"breaking","affected_versions":"2.x -> 3.x"},{"fix":"Ensure `from repoze.who.config import add_new_r_w_to_environ` is imported and called, typically within your WSGI application's request processing or wrapped around the main `WhoMiddleware`.","message":"Forgetting to call `add_new_r_w_to_environ` after creating the `repoze.who` middleware means that the `repoze.who` object (containing identifiers, authenticators, etc.) will not be available in the WSGI environment for subsequent requests, leading to unexpected behavior or errors.","severity":"gotcha","affected_versions":"3.x"},{"fix":"Carefully review the `who_config` dictionary structure. Ensure all identifiers, authenticators, and challengers are correctly instantiated and provided as `(name, plugin_instance)` tuples in their respective lists. Use `log_level=10` (DEBUG) for more verbose error messages during development.","message":"Configuration of `repoze.who` relies on a dictionary structure passed to `make_who_with_config`. Incorrectly formatted dictionaries (e.g., missing required keys, invalid plugin instances) will lead to runtime errors that can be hard to diagnose.","severity":"gotcha","affected_versions":"3.x"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Use `from repoze.who.config import make_who_with_config` to configure and instantiate the `repoze.who` middleware. The `WhoMiddleware` class itself is an internal detail when using `make_who_with_config`.","cause":"Attempting to import `WhoMiddleware` directly from `repoze.who.middleware`, which was common in `repoze.who` 2.x but is not the standard or working method in 3.x.","error":"ImportError: cannot import name 'WhoMiddleware' from 'repoze.who.middleware'"},{"fix":"Double-check your `who_config` dictionary to ensure all plugins (identifiers, authenticators, challengers) are correctly instantiated and passed. Verify that your custom authenticators return `None` on failure or the correct identifier on success.","cause":"Often occurs when an authenticator, identifier, or challenger is not correctly configured or fails to return the expected type/value. For example, if a plugin instance is `None` instead of a callable object.","error":"TypeError: 'NoneType' object is not callable (or similar error when authenticating)"},{"fix":"Ensure that your WSGI application is correctly wrapped by the `repoze.who` middleware created via `make_who_with_config`. Also, verify that `add_new_r_w_to_environ` is invoked early in your request processing chain.","cause":"The `repoze.who` middleware has not processed the request, or the `add_new_r_w_to_environ` function was not called, preventing the `repoze.who` object from being properly set up in the WSGI environment.","error":"KeyError: 'repoze.who.identity' (or other repoze.who keys not found in environ)"}]}