【问题标题】:Microsoft Graph API Paging interface with python and html带有 python 和 html 的 Microsoft Graph API 分页接口
【发布时间】:2019-01-13 20:59:02
【问题描述】:

目前我正在尝试使用 @odata.nextLink 对从图形 API 检索到的数据进行分页。我需要在 html 上使用某种箭头来回移动,所以我可能不得不在 python 代码上使用烧瓶创建一些函数,以使用 json 文件中的 @odata.nextLink 值,因此它加载下一组数据的。我一直在尝试做的是这样的事情,但是我的“下一个”函数只会检索第二组数据,它缺少返回的功能,而且我创建了第二个 html 文件来显示下一个数据块是没有意义的。我想让你们给我一个想法,让我知道如何做到这一点。

Python 代码:

import base64
import mimetypes
import os
import pprint
import uuid

import flask
from flask_oauthlib.client import OAuth
from flask import request

import config

APP = flask.Flask(__name__, template_folder='static/templates')
APP.debug = True
APP.secret_key = 'development'
OAUTH = OAuth(APP)
MSGRAPH = OAUTH.remote_app(
    'microsoft',
    consumer_key=config.CLIENT_ID,
    consumer_secret=config.CLIENT_SECRET,
    request_token_params={'scope': config.SCOPES},
    base_url=config.RESOURCE + config.API_VERSION + '/',
    request_token_url=None,
    access_token_method='POST',
    access_token_url=config.AUTHORITY_URL + config.TOKEN_ENDPOINT,
    authorize_url=config.AUTHORITY_URL + config.AUTH_ENDPOINT)

@APP.route('/')
def homepage():
    """Render the home page."""
    return flask.render_template('homepage.html')

@APP.route('/login')
def login():
    """Prompt user to authenticate."""
    flask.session['state'] = str(uuid.uuid4())
    print(config.REDIRECT_URI)
    return MSGRAPH.authorize(callback=config.REDIRECT_URI, state=flask.session['state'])

@APP.route('/login/authorized')
def authorized():
    """Handler for the application's Redirect Uri."""
    if str(flask.session['state']) != str(flask.request.args['state']):
        raise Exception('state returned to redirect URL does not match!')
    response = MSGRAPH.authorized_response()
    flask.session['access_token'] = response['access_token']
    print(flask.session['access_token'])
    return  flask.redirect('/query')



@MSGRAPH.tokengetter
def get_token():
    """Called by flask_oauthlib.client to retrieve current access token."""
    return (flask.session.get('access_token'), '')

def request_headers(headers=None):
    """Return dictionary of default HTTP headers for Graph API calls.
    Optional argument is other headers to merge/override defaults."""
    default_headers = {'SdkVersion': 'sample-python-flask',
                       'x-client-SKU': 'sample-python-flask',
                       'client-request-id': str(uuid.uuid4()),
                       'return-client-request-id': 'true'}
    if headers:
        default_headers.update(headers)
    return default_headers


@APP.route('/query')
def query():
    # query = "groups?$filter=startswith(displayName,'C')"
    query = "groups/?$expand=members"

    result = MSGRAPH.get(query, headers=request_headers()).data

    return flask.render_template('query.html',result=result, query=query)

@APP.route('/next')
def next():

    query = "groups/?$expand=members"
    result = MSGRAPH.get(query, headers=request_headers()).data
    nextResult = MSGRAPH.get(result['@odata.nextLink'], headers=request_headers()).data

    return flask.render_template('query_2.html', result=nextResult, query=query)
# Last Group Was: APP_EZSHARE_CO-O0004

if __name__ == '__main__':
    APP.run()

HTML 文件:

<!DOCTYPE html>
<!-- Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license.
See LICENSE in the source repository root for complete license information. -->
<html>
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>{{ sample }} sample</title>
        <link rel="stylesheet" type="text/css" href="/static/css/bootstrap.min.css" />
        <link rel="stylesheet" type="text/css" href="/static/css/site.css?version=1.28" />
    </head>
    <body>
        <div class="container homepage-container">
            <div>
                <h1 style="text-align: center">Active Directory Viewer</h1>




                <div>
                    <!--<h1>Result</h1>-->
                    <table border="1px solid black">
                    <tr>
                        <!--<th>ID</th>-->
                        <th>Group Name</th>
                        <th>Description</th>
                        <!--<th>Users</th>-->
                    </tr>

                    {% for gd in result.value %}
                    <tr style="background-color: green; color: white">
                        <!--<td>{{ gd.id }}</td>-->
                        <td>{{ gd.displayName }}</td><!-- TRYING TO ACCESS THE GROUP DISPLAYNAME-->
                        <td>{{ gd.description }}</td>
                    </tr>

                    {% for mem in gd.members %}
                    <tr>
                        <td>{{ mem.displayName }}</td>
                    </tr>
                    {% endfor %}

                    {% endfor %}
                    </table>

                    <a href="/next"><input type="button" value="Next"></a>
                    <!--{{ result }}-->
                </div>



            </div>
        </div>
    </body>
</html>

谢谢!

【问题讨论】:

    标签: python html flask pagination microsoft-graph-api


    【解决方案1】:

    正如您所提到的,由于 Microsoft Graph API 的分页机制不提供双向分页,因此我不会使用它为用户提供这样的功能。相反,我会使用 $skip 参数。确实,正如那篇文章所指出的:

    一些 Microsoft Graph API,例如 Outlook 邮件和日历(消息、事件和日历),使用 $skip 来实现分页。

    对于某些 Graph API 的 @odata.nextLink 值中使用的 $skipToken 参数的持久性,我也无法从 Microsoft 那里找到任何保证,因此我会谨慎地在面向用户的上下文中使用它它可能很快就会过期(在当前主要版本的 API 的这次或未来的迭代中)。

    如果您只是使用$skip 参数来提供分页,则生成的 JSON 格式将是相同的,因此您应该能够对第一页和所有后续页面使用相同的 HTML 模板。我有一个/query 路由(而不是/next 路由),它只接受一个名为skip 之类的可选参数。

    【讨论】:

    • 你说得对,使用@odata.nextLink 中的值来实现分页持久性是正确的,它持续了我大约 13 页,当我再次单击下一个时,它让我返回了一个错误。你认为跳过我可以实现后退按钮吗?如果你知道怎么做,请告诉我。感谢您的宝贵时间!
    • 是的,您可以使用$skip 实现后退按钮。例如,如果每页有 10 条记录,并且用户在第三页(即为$skip=20 返回的记录),那么当用户点击返回时,将为用户提供为$skip=10 返回的记录按钮。请注意,在用户分页时数据可能会发生变化,从而更改哪些记录显示在哪些页面中。您的用例可能会或可能不会接受一些需要考虑的事情。
    • 知道了,所以这就像根据用户想要移动的位置来增加或减少 $skip 的值。嗯,根据用例,我认为不会有问题,因为我还想在数据更改时实现推送通知器。幸运的是,这个 api 提供了这种可能性。
    • 确实如此。祝你好运!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-03
    • 1970-01-01
    • 1970-01-01
    • 2022-08-24
    相关资源
    最近更新 更多