gpt4 book ai didi

python - 在 PostgreSQL 和 Dynamics 365 Web API 之间构建 Python3 授权代理服务器

转载 作者:太空宇宙 更新时间:2023-11-03 11:44:23 25 4
gpt4 key购买 nike

经过几天的进步,我开始接受这样一个事实,即我缺乏知识或技能水平,无法将所有这些部分组合在一起并完成这个项目。因此,我呼吁并感谢任何能帮助我解决这个问题的人。

技术

问题

  • CRM 拥有最新的客户数据,并希望将其导入 PostgreSQL 以用于多种用途
  • 想使用 www_fdw 因为它是我见过的唯一可以使用 Web API 的 PostgreSQL 外国数据包装器:https://github.com/cyga/www_fdw/wiki
  • Dynamics Web API 使用 OAuth2,www_fdw 本身不支持任何类型的身份验证
  • www_fdw 的开发人员交谈,后者建议制作一个代理服务器来处理 Microsoft 的 OAuth2 身份验证
  • 带有 www_fdw 的 PostgreSQL 会与代理对话,后者又会向 Microsoft 发送身份验证,最终能够将 Web API 视为外部表,以便像对待任何其他表一样对待它

三部分以及目前尝试过的内容

三部分 = www_fdw + 代理服务器 + OAuth2

  1. www_fdw:我已基于此使用以下参数进行设置:https://github.com/cyga/www_fdw/wiki/Examples

    DROP EXTENSION IF EXISTS www_fdw CASCADE;
    CREATE EXTENSION www_fdw;
    CREATE SERVER crm FOREIGN DATA WRAPPER www_fdw OPTIONS
    (uri 'http://localhost:12345'); -- proxy server
    CREATE USER MAPPING FOR current_user SERVER crm;

    -- for testing trying to get 'name' out of the CRM 'accounts' table and
    naming the foreign table the same as the table in CRM
    CREATE FOREIGN TABLE accounts (
    name varchar(255)
    ) SERVER crm;
  2. crmproxytest.py 用于代理服务器,我一直在尝试使用此链接制作一个简单的骨架:http://effbot.org/librarybook/simplehttpserver.htm

    import socketserver
    import http.server
    import urllib

    PORT = 12345

    class Proxy(http.server.SimpleHTTPRequestHandler):
    def do_GET(self):
    self.copyfile(urllib.urlopen(self.path), self.wfile)

    httpd = socketserver.ForkingTCPServer(('', PORT), Proxy)
    print ("serving at port", PORT)
    httpd.serve_forever()

    这似乎有效,因为它在控制台上说 serving at port 12345,显示正在运行 nmap -sT -O localhost,控制台上有一些事件正在运行nmap 运行时的服务器。否则无法从中获取任何事件。

    从 PostgreSQL 运行 SELECT * FROM accounts 导致 无法从服务器获得响应:无法连接到::1:权限被拒绝

  3. OAuth2。我将 crm.py 放在一起,并在与 Microsoft 交谈后让它工作,整理了他们的文档,并找到了这个链接:http://alexanderdevelopment.net/post/2016/11/27/dynamics-365-and-python-integration-using-the-web-api/

    简而言之,您必须在 Azure Active Directory 中注册您的应用,这样您才能获得 client_idclient_secret,此外还能够获得 OAuth 2.0 token URIOAuth 2.0 授权 URI。然后,您可以向 authorizationendpoint 发送请求,如果凭据匹配,它会返回一个 token ,然后将 token 发送到 tokenendpoint,最终访问 Web API授予。

    这是我最终使用的有效代码,它从 Dynamics Web API 检索数据,并将其填充到控制台中:

    import requests  
    import json

    #set these values to retrieve the oauth token
    crmorg = 'https://ORG.crm.dynamics.com' #base url for crm org
    clientid = '00000000-0000-0000-0000-000000000000' #application client id
    client_secret = 'SUPERSECRET'
    username = 'asd@asd.com' #username
    userpassword = 'qwerty' #password
    authorizationendpoint = 'https://login.windows.net/ZZZZZZZZ-ZZZZ-ZZZZ-ZZZZ-ZZZZZZZZZZZZ/oauth2/authorize'
    tokenendpoint = 'https://login.windows.net/ZZZZZZZZ-ZZZZ-ZZZZ-ZZZZ-ZZZZZZZZZZZZ/oauth2/token' #oauth token endpoint

    #set these values to query your crm data
    crmwebapi = 'https://ORG.api.crm.dynamics.com/api/data/v8.2' #full path to web api endpoint
    crmwebapiquery = '/accounts?$select=name&$orderby=name' #web api query (include leading /)

    #build the authorization token request
    tokenpost = {
    'client_id':clientid,
    'client_secret': client_secret,
    'resource':crmorg,
    'oauthUrl': authorizationendpoint,
    'username':username,
    'password':userpassword,
    'grant_type':'password'
    }

    #make the token request
    tokenres = requests.post(tokenendpoint, data=tokenpost)

    #check the value of tokenres
    print(tokenres)

    #set accesstoken variable to empty string
    accesstoken = ''

    #extract the access token
    try:
    accesstoken = tokenres.json()['access_token']
    except(KeyError):
    #handle any missing key errors
    print('Could not get access token')

    # check point for debugging
    # print(accesstoken)

    #if we have an accesstoken
    if(accesstoken!=''):
    #prepare the crm request headers
    crmrequestheaders = {
    'Authorization': 'Bearer ' + accesstoken,
    'OData-MaxVersion': '4.0',
    'OData-Version': '4.0',
    'Accept': 'application/json',
    'Content-Type': 'application/json; charset=utf-8',
    'Prefer': 'odata.maxpagesize=500',
    'Prefer': 'odata.include-annotations=OData.Community.Display.V1.FormattedValue'
    }

    #make the crm request
    crmres = requests.get(crmwebapi+crmwebapiquery, headers=crmrequestheaders)

    try:
    #get the response json
    crmresults = crmres.json()

    #loop through it
    for x in crmresults['value']:
    # print (x['fullname'] + ' - ' + x['contactid'])
    print (x['name'])
    except KeyError:
    #handle any missing key errors
    print('Could not parse CRM results')

    这就像一个魅力,但实际上是为了测试 OAuth2。变量 crmwebapicrmwebapiquery 组合的查询实际上并不需要在那里,因为 PostgreSQL,如果 FDW 正常工作,应该允许针对网络 API。

无论如何,我希望我解释得足够好。似乎我得到了三个独立的拼图 block ,或者说有点工作,但将它们放在一起是我遇到的困难。 crm.pycrmtest.py 可能需要合并,但不确定如何合并。

在此先感谢您的帮助!

编辑:显然到处都是 www_ftw 而不是 www_fdw

最佳答案

在我看来,第 1 步中设置 FDW 没问题。

步骤 2 中的 Python 脚本需要在顶部有一个 shebang。否则它被视为 bash,所以前 3 行运行 import(1)并将屏幕截图保存到名为 http.serversocketserverurllib 的新文件中。这会让脚本在 PORT 行结束之前忙碌一段时间。同时(甚至在它死掉之后),只运行 curl http://localhost:12345 会给出与 Postgres 相同的错误:

curl: (7) Failed to connect to localhost port 12345: Connection refused

添加 #!/usr/bin/env python3 后,您的脚本将响应请求。例如,我可以说 curl http://localhost:12345/etc/passwd 并得到结果。

我不确定您打算如何连接第 3 步(OAuth),但希望这个答案能让您克服目前的障碍。

关于python - 在 PostgreSQL 和 Dynamics 365 Web API 之间构建 Python3 授权代理服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42988955/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com