Skip to content

Commit

Permalink
Fix doc errors
Browse files Browse the repository at this point in the history
  • Loading branch information
rayluo committed May 19, 2024
1 parent ee5717e commit 0c07b6a
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 27 deletions.
4 changes: 2 additions & 2 deletions docs/flask.rst
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ Web app that logs in users and calls a web API on their behalf

#. Decorate your token-consuming views using the same
:py:func:`identity.flask.Auth.login_required` decorator,
this time with a parameter ``scopes=["your_scope_1", "your_scope_2"]``.
this time with a parameter ``scopes=["your_scope_1", "your_scope_2"]``.

Then, inside your view, the token will be readily available via
``context['access_token']``. For example::
Expand All @@ -85,7 +85,7 @@ Web app that logs in users and calls a web API on their behalf
"https://your_api.example.com",
headers={'Authorization': 'Bearer ' + context['access_token']},
timeout=30,
).json() # Here we assume the response format is json
)
...

All of the content above are demonstrated in
Expand Down
30 changes: 27 additions & 3 deletions docs/quart.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,20 @@ Configuration


#. Setup session management with the `Quart-session <https://github.com/kroketio/quart-session>`_ package, which currently supports either Redis or MongoDB backing stores. To use Redis as the session store, you should first install the package with the extra dependency::

pip install quart-session[redis]

#. Then add configuration to ``app.py`` pointing to your Redis instance::

app.config['SESSION_TYPE'] = 'redis'
app.config['SESSION_URI'] = 'redis://localhost:6379'


Sign In and Sign Out
----------------------------------

#. In your web project's ``app.py``, decorate some views with the
:py:func:`identity.flask.Auth.login_required` decorator.
:py:func:`identity.quart.Auth.login_required` decorator.
It will automatically trigger sign-in. ::

@app.route("/")
Expand All @@ -63,6 +63,30 @@ Sign In and Sign Out
<a href="{{ url_for('identity.logout') }}">Logout</a>


Web app that logs in users and calls a web API on their behalf
--------------------------------------------------------------

#. Decorate your token-consuming views using the same
:py:func:`identity.quart.Auth.login_required` decorator,
this time with a parameter ``scopes=["your_scope_1", "your_scope_2"]``.

Then, inside your view, the token will be readily available via
``context['access_token']``. For example::

@app.route("/call_api")
@auth.login_required(scopes=os.getenv("SCOPE", "").split())
def call_api(*, context):
api_result = requests.get( # Use access token to call a web api
"https://your_api.example.com",
headers={'Authorization': 'Bearer ' + context['access_token']},
timeout=30,
)
...

All of the content above are demonstrated in
`this Quart web app sample <https://github.com/rayluo/python-webapp-quart>`_.


API reference
--------------------------

Expand Down
2 changes: 1 addition & 1 deletion identity/django.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ def my_view2(request, *, context):
"https://example.com/endpoint",
headers={'Authorization': 'Bearer ' + context['access_token']},
timeout=30,
).json() # Here we assume the response format is json
)
...
"""
# With or without brackets. Inspired by https://stackoverflow.com/a/39335652/728675
Expand Down
18 changes: 10 additions & 8 deletions identity/flask.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ def __init__(self, app: Flask, *args, **kwargs):
# Manually register the routes, since we cannot use @app or @bp on methods
if self._redirect_uri:
redirect_path = urlparse(self._redirect_uri).path
#bp.route(redirect_path or "/auth_response")(self.auth_response)
bp.route(redirect_path)(self.auth_response)
bp.route(
f"{os.path.dirname(redirect_path)}/logout" # Use it in template by url_for("identity.logout")
Expand Down Expand Up @@ -107,12 +106,14 @@ def login_required( # Named after Django's login_required
Usage::
@settings.AUTH.login_required
def my_view(request, *, context):
return render(request, 'index.html', dict(
@app.route("/")
@auth.login_required
def index(*, context):
return render_template(
'index.html',
user=context["user"], # User is guaranteed to be present
# because we decorated this view with @login_required
))
)
:param list[str] scopes:
A list of scopes that your app will need to use.
Expand All @@ -121,13 +122,14 @@ def my_view(request, *, context):
Usage::
@settings.AUTH.login_required(scopes=["scope1", "scope2"])
def my_view2(request, *, context):
@app.route("/call_api")
@auth.login_required(scopes=["scope1", "scope2"])
def call_an_api(*, context):
api_result = requests.get( # Use access token to call an api
"https://example.com/endpoint",
headers={'Authorization': 'Bearer ' + context['access_token']},
timeout=30,
).json() # Here we assume the response format is json
)
...
"""
# With or without brackets. Inspired by https://stackoverflow.com/a/39335652/728675
Expand Down
29 changes: 16 additions & 13 deletions identity/quart.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ def __init__(self, app: Quart, *args, **kwargs):
# Manually register the routes, since we cannot use @app or @bp on methods
if self._redirect_uri:
redirect_path = urlparse(self._redirect_uri).path
#bp.route(redirect_path or "/auth_response")(self.auth_response)
bp.route(redirect_path)(self.auth_response)
bp.route(
f"{os.path.dirname(redirect_path)}/logout" # Use it in template by url_for("identity.logout")
Expand Down Expand Up @@ -107,12 +106,14 @@ def login_required( # Named after Django's login_required
Usage::
@settings.AUTH.login_required
def my_view(request, *, context):
return render(request, 'index.html', dict(
@app.route("/")
@auth.login_required
async def index(*, context):
return await render_template(
'index.html',
user=context["user"], # User is guaranteed to be present
# because we decorated this view with @login_required
))
)
:param list[str] scopes:
A list of scopes that your app will need to use.
Expand All @@ -121,14 +122,16 @@ def my_view(request, *, context):
Usage::
@settings.AUTH.login_required(scopes=["scope1", "scope2"])
def my_view2(request, *, context):
api_result = requests.get( # Use access token to call an api
"https://example.com/endpoint",
headers={'Authorization': 'Bearer ' + context['access_token']},
timeout=30,
).json() # Here we assume the response format is json
...
@app.route("/call_api")
@auth.login_required(scopes=["scope1", "scope2"])
async def call_api(*, context):
async with httpx.AsyncClient() as client:
api_result = await client.get( # Use access token to call a web api
os.getenv("ENDPOINT"),
headers={'Authorization': 'Bearer ' + context['access_token']},
)
return await render_template('display.html', result=api_result)
"""
# With or without brackets. Inspired by https://stackoverflow.com/a/39335652/728675

Expand Down

0 comments on commit 0c07b6a

Please sign in to comment.