如何使用Python连接到Microsoft Dataverse API端点
我面临着通过Python连接到Microsoft Dataverse API端点的问题。
该代码分为三个部分:
a)代币生成
b)端点API调用选项1
c)端点API调用选项2 Appi call选项2
################ Token generation code begins ################
import adal
# Tenant ID for your Azure Subscription
TENANT_ID = 'abc'
# Your Service Principal App ID
CLIENT = '52'
# Your Service Principal Password
KEY = '43'
# subscription_id = 'xxxxxxx'
authority_url = 'https://login.microsoftonline.com/'+TENANT_ID
context = adal.AuthenticationContext(authority_url)
token = context.acquire_token_with_client_credentials(
resource='https://orgabc.api.crm8.dynamics.com/',
client_id=CLIENT,
client_secret=KEY
)
print('Fresh token is: ', token["accessToken"])
print('Full response is: ', token)
################ Token generation code ends ################
################ Method/Option 1: Token generation code begins ################
import requests
import json
import msal
config = {
"authority": "https://login.microsoftonline.com/abc",
"client_id": "52",
"client_secret": "43",
"scope": ["https://orgabc.crm8.dynamics.com/.default"],
}
app = msal.ConfidentialClientApplication(
config["client_id"],
authority=config["authority"],
client_credential=config["client_secret"])
result = app.acquire_token_silent(config["scope"], account=None)
if not result:
result = app.acquire_token_for_client(scopes=config["scope"])
# bearerToken = result['access_token']
bearerToken = token["accessToken"]
url = "https://orgabc.api.crm8.dynamics.com/api/data/v9.2"
headers = {
"Accept": "application/json",
"Content-type": "application/json",
"Authorization": "Bearer "+bearerToken,
}
response = requests.request("GET", url, headers = headers)
print(response)
################ Method/Option 1: Token generation code ends ################
# ################ Method/Option 2: Token generation code begins ################
# import requests
# import json
#
# # set these values to retrieve the oauth token
# crmorg = 'https://orgabc.crm8.dynamics.com' # base url for crm org
# clientid = '52' # application client id
# username = '[email protected]' # username
# userpassword = 'HgN@6013' # password
# tokenendpoint = 'https://login.microsoftonline.com/abc/oauth2/v2.0/token' # oauth token endpoint
#
# # set these values to query your crm data
# crmwebapi = 'https://orgabc.crm8.dynamics.com/api/data/v9.2' # full path to web api endpoint
# # crmwebapiquery = '/contacts?$select=fullname,contactid' # web api query (include leading /)
# crmwebapiquery = '/accounts' # web api query (include leading /)
#
#
# # build the authorization token request
# tokenpost = {
# 'client_id': clientid,
# 'resource': crmorg,
# 'username': username,
# 'password': userpassword,
# 'grant_type': 'password'
# }
#
# # make the token request
# tokenres = requests.post(tokenendpoint, data=tokenpost)
#
# # set accesstoken variable to empty string
# accesstoken = ''
#
# # extract the access token
# try:
# accesstoken = token["accessToken"]
# except(KeyError):
# # handle any missing key errors
# print('Could not get access token')
#
# # if we have an accesstoken
# if (accesstoken != ''):
# # prepare the crm request headers
# crmrequestheaders = {
# 'Authorization': 'Bearer ' + token["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'])
# except KeyError:
# # handle any missing key errors
# print('Could not parse CRM results')
# ################ Method/Option 2: Token generation code ends ################
该代码的块1正常工作,我们正在生成令牌,但是当我们尝试块时2或3,在这两种情况下,代码都失败了以下错误(完整的追溯):
Traceback (most recent call last):
File "C:\Users\aakashbasu1\PycharmProjects\Personal_RnD\venv\lib\site-packages\urllib3\connectionpool.py", line 597, in urlopen
httplib_response = self._make_request(conn, method, url,
File "C:\Users\aakashbasu1\PycharmProjects\Personal_RnD\venv\lib\site-packages\urllib3\connectionpool.py", line 343, in _make_request
self._validate_conn(conn)
File "C:\Users\aakashbasu1\PycharmProjects\Personal_RnD\venv\lib\site-packages\urllib3\connectionpool.py", line 849, in _validate_conn
conn.connect()
File "C:\Users\aakashbasu1\PycharmProjects\Personal_RnD\venv\lib\site-packages\urllib3\connection.py", line 349, in connect
self.sock = ssl_wrap_socket(
File "C:\Users\aakashbasu1\PycharmProjects\Personal_RnD\venv\lib\site-packages\urllib3\util\ssl_.py", line 359, in ssl_wrap_socket
return context.wrap_socket(sock, server_hostname=server_hostname)
File "C:\Users\aakashbasu1\AppData\Local\Programs\Python\Python39\lib\ssl.py", line 500, in wrap_socket
return self.sslsocket_class._create(
File "C:\Users\aakashbasu1\AppData\Local\Programs\Python\Python39\lib\ssl.py", line 1040, in _create
self.do_handshake()
File "C:\Users\aakashbasu1\AppData\Local\Programs\Python\Python39\lib\ssl.py", line 1309, in do_handshake
self._sslobj.do_handshake()
ssl.SSLError: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1129)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\aakashbasu1\PycharmProjects\Personal_RnD\venv\lib\site-packages\requests\adapters.py", line 440, in send
resp = conn.urlopen(
File "C:\Users\aakashbasu1\PycharmProjects\Personal_RnD\venv\lib\site-packages\urllib3\connectionpool.py", line 637, in urlopen
retries = retries.increment(method, url, error=e, _pool=self,
File "C:\Users\aakashbasu1\PycharmProjects\Personal_RnD\venv\lib\site-packages\urllib3\util\retry.py", line 398, in increment
raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='orgabc.api.crm8.dynamics.com', port=443): Max retries exceeded with url: /api/data/v9.2 (Caused by SSLError(SSLError(1, '[SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1129)')))
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\aakashbasu1\PycharmProjects\Personal_RnD\internal_experiments\azure_ad_token_generator.py", line 60, in <module>
response = requests.request("GET", url, headers = headers)
File "C:\Users\aakashbasu1\PycharmProjects\Personal_RnD\venv\lib\site-packages\requests\api.py", line 61, in request
return session.request(method=method, url=url, **kwargs)
File "C:\Users\aakashbasu1\PycharmProjects\Personal_RnD\venv\lib\site-packages\requests\sessions.py", line 529, in request
resp = self.send(prep, **send_kwargs)
File "C:\Users\aakashbasu1\PycharmProjects\Personal_RnD\venv\lib\site-packages\requests\sessions.py", line 645, in send
r = adapter.send(request, **kwargs)
File "C:\Users\aakashbasu1\PycharmProjects\Personal_RnD\venv\lib\site-packages\requests\adapters.py", line 517, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host='orgabc.api.crm8.dynamics.com', port=443): Max retries exceeded with url: /api/data/v9.2 (Caused by SSLError(SSLError(1, '[SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1129)')))
在开放论坛上,对于Dataverse而言,没有太多帮助。有一个可用的C#代码,但是我们需要使用Python进行相同的操作。 C#代码是:
using Microsoft.AspNetCore.Http;
using Microsoft.Graph;
using Microsoft.WindowsAzure.ActiveDirectory.Authentication;
using MySql.Data.MySqlClient.Memcached;
using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
namespace AccessToken
{
class Program
{
static void Main(string[] args)
{
string serviceUrl = "https://orgabc.crm8.dynamics.com";
string clientId = "52";//"<your app id>";
string secret = "41";//"<your app secret>";
AuthenticationContext authContext = new AuthenticationContext("https://login.microsoftonline.com/53");//tenant ID
ClientCredential credential = new ClientCredential(clientId, secret);
AuthenticationResult result = authContext.AcquireToken(serviceUrl,credential);
string accessToken = result.AccessToken;
Console.WriteLine("Hello World!");
Console.WriteLine("Acces Token for given :"+accessToken);
//Retrieving data here
using (var client = new HttpClient())
{
var tokenType = "Bearer"; //Other APIs use Bearer or other auth types.
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(tokenType, accessToken);//token type=Bearer, accesstoken refers to token which we generated.
//https://orgabc.crm8.dynamics.com refers to org URL
var content = client.GetStringAsync("https://orgabc.crm8.dynamics.com/api/data/v9.2/accounts");//accounts refers to the User Table Logical Name.
Console.WriteLine("Acces Token for given :" + content.Result);
}
//end of retrieve data.
}
}
}
我们尝试了什么?
- 根据Microsoft文档,将API版本从实际的9.2更改为9.2,
- 根据多个so so so s so s so q/ake this
- 与Postman工具一起在相同的连接详细信息上工作的效果非常好,
因此,缩小了它的范围,似乎问题是代码键入端点。有帮助吗?
I'm facing an issue in connecting to Microsoft Dataverse API endpoint through Python.
The code is broken down into three parts:
A) Token Generation
B) Endpoint API call Option 1
C) Endpoint API call Option 2
################ Token generation code begins ################
import adal
# Tenant ID for your Azure Subscription
TENANT_ID = 'abc'
# Your Service Principal App ID
CLIENT = '52'
# Your Service Principal Password
KEY = '43'
# subscription_id = 'xxxxxxx'
authority_url = 'https://login.microsoftonline.com/'+TENANT_ID
context = adal.AuthenticationContext(authority_url)
token = context.acquire_token_with_client_credentials(
resource='https://orgabc.api.crm8.dynamics.com/',
client_id=CLIENT,
client_secret=KEY
)
print('Fresh token is: ', token["accessToken"])
print('Full response is: ', token)
################ Token generation code ends ################
################ Method/Option 1: Token generation code begins ################
import requests
import json
import msal
config = {
"authority": "https://login.microsoftonline.com/abc",
"client_id": "52",
"client_secret": "43",
"scope": ["https://orgabc.crm8.dynamics.com/.default"],
}
app = msal.ConfidentialClientApplication(
config["client_id"],
authority=config["authority"],
client_credential=config["client_secret"])
result = app.acquire_token_silent(config["scope"], account=None)
if not result:
result = app.acquire_token_for_client(scopes=config["scope"])
# bearerToken = result['access_token']
bearerToken = token["accessToken"]
url = "https://orgabc.api.crm8.dynamics.com/api/data/v9.2"
headers = {
"Accept": "application/json",
"Content-type": "application/json",
"Authorization": "Bearer "+bearerToken,
}
response = requests.request("GET", url, headers = headers)
print(response)
################ Method/Option 1: Token generation code ends ################
# ################ Method/Option 2: Token generation code begins ################
# import requests
# import json
#
# # set these values to retrieve the oauth token
# crmorg = 'https://orgabc.crm8.dynamics.com' # base url for crm org
# clientid = '52' # application client id
# username = '[email protected]' # username
# userpassword = 'HgN@6013' # password
# tokenendpoint = 'https://login.microsoftonline.com/abc/oauth2/v2.0/token' # oauth token endpoint
#
# # set these values to query your crm data
# crmwebapi = 'https://orgabc.crm8.dynamics.com/api/data/v9.2' # full path to web api endpoint
# # crmwebapiquery = '/contacts?$select=fullname,contactid' # web api query (include leading /)
# crmwebapiquery = '/accounts' # web api query (include leading /)
#
#
# # build the authorization token request
# tokenpost = {
# 'client_id': clientid,
# 'resource': crmorg,
# 'username': username,
# 'password': userpassword,
# 'grant_type': 'password'
# }
#
# # make the token request
# tokenres = requests.post(tokenendpoint, data=tokenpost)
#
# # set accesstoken variable to empty string
# accesstoken = ''
#
# # extract the access token
# try:
# accesstoken = token["accessToken"]
# except(KeyError):
# # handle any missing key errors
# print('Could not get access token')
#
# # if we have an accesstoken
# if (accesstoken != ''):
# # prepare the crm request headers
# crmrequestheaders = {
# 'Authorization': 'Bearer ' + token["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'])
# except KeyError:
# # handle any missing key errors
# print('Could not parse CRM results')
# ################ Method/Option 2: Token generation code ends ################
The block 1 of the code is working fine, where we're generating the token, but while we try block 2 or 3, in both the cases the code fails with the below error (full traceback):
Traceback (most recent call last):
File "C:\Users\aakashbasu1\PycharmProjects\Personal_RnD\venv\lib\site-packages\urllib3\connectionpool.py", line 597, in urlopen
httplib_response = self._make_request(conn, method, url,
File "C:\Users\aakashbasu1\PycharmProjects\Personal_RnD\venv\lib\site-packages\urllib3\connectionpool.py", line 343, in _make_request
self._validate_conn(conn)
File "C:\Users\aakashbasu1\PycharmProjects\Personal_RnD\venv\lib\site-packages\urllib3\connectionpool.py", line 849, in _validate_conn
conn.connect()
File "C:\Users\aakashbasu1\PycharmProjects\Personal_RnD\venv\lib\site-packages\urllib3\connection.py", line 349, in connect
self.sock = ssl_wrap_socket(
File "C:\Users\aakashbasu1\PycharmProjects\Personal_RnD\venv\lib\site-packages\urllib3\util\ssl_.py", line 359, in ssl_wrap_socket
return context.wrap_socket(sock, server_hostname=server_hostname)
File "C:\Users\aakashbasu1\AppData\Local\Programs\Python\Python39\lib\ssl.py", line 500, in wrap_socket
return self.sslsocket_class._create(
File "C:\Users\aakashbasu1\AppData\Local\Programs\Python\Python39\lib\ssl.py", line 1040, in _create
self.do_handshake()
File "C:\Users\aakashbasu1\AppData\Local\Programs\Python\Python39\lib\ssl.py", line 1309, in do_handshake
self._sslobj.do_handshake()
ssl.SSLError: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1129)
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\aakashbasu1\PycharmProjects\Personal_RnD\venv\lib\site-packages\requests\adapters.py", line 440, in send
resp = conn.urlopen(
File "C:\Users\aakashbasu1\PycharmProjects\Personal_RnD\venv\lib\site-packages\urllib3\connectionpool.py", line 637, in urlopen
retries = retries.increment(method, url, error=e, _pool=self,
File "C:\Users\aakashbasu1\PycharmProjects\Personal_RnD\venv\lib\site-packages\urllib3\util\retry.py", line 398, in increment
raise MaxRetryError(_pool, url, error or ResponseError(cause))
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='orgabc.api.crm8.dynamics.com', port=443): Max retries exceeded with url: /api/data/v9.2 (Caused by SSLError(SSLError(1, '[SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1129)')))
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\aakashbasu1\PycharmProjects\Personal_RnD\internal_experiments\azure_ad_token_generator.py", line 60, in <module>
response = requests.request("GET", url, headers = headers)
File "C:\Users\aakashbasu1\PycharmProjects\Personal_RnD\venv\lib\site-packages\requests\api.py", line 61, in request
return session.request(method=method, url=url, **kwargs)
File "C:\Users\aakashbasu1\PycharmProjects\Personal_RnD\venv\lib\site-packages\requests\sessions.py", line 529, in request
resp = self.send(prep, **send_kwargs)
File "C:\Users\aakashbasu1\PycharmProjects\Personal_RnD\venv\lib\site-packages\requests\sessions.py", line 645, in send
r = adapter.send(request, **kwargs)
File "C:\Users\aakashbasu1\PycharmProjects\Personal_RnD\venv\lib\site-packages\requests\adapters.py", line 517, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host='orgabc.api.crm8.dynamics.com', port=443): Max retries exceeded with url: /api/data/v9.2 (Caused by SSLError(SSLError(1, '[SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1129)')))
There's not much help available on the open forum for this problem for Dataverse. There is a C# code available which works fine, but we need to use Python for the same. C# code for the same is:
using Microsoft.AspNetCore.Http;
using Microsoft.Graph;
using Microsoft.WindowsAzure.ActiveDirectory.Authentication;
using MySql.Data.MySqlClient.Memcached;
using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
namespace AccessToken
{
class Program
{
static void Main(string[] args)
{
string serviceUrl = "https://orgabc.crm8.dynamics.com";
string clientId = "52";//"<your app id>";
string secret = "41";//"<your app secret>";
AuthenticationContext authContext = new AuthenticationContext("https://login.microsoftonline.com/53");//tenant ID
ClientCredential credential = new ClientCredential(clientId, secret);
AuthenticationResult result = authContext.AcquireToken(serviceUrl,credential);
string accessToken = result.AccessToken;
Console.WriteLine("Hello World!");
Console.WriteLine("Acces Token for given :"+accessToken);
//Retrieving data here
using (var client = new HttpClient())
{
var tokenType = "Bearer"; //Other APIs use Bearer or other auth types.
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(tokenType, accessToken);//token type=Bearer, accesstoken refers to token which we generated.
//https://orgabc.crm8.dynamics.com refers to org URL
var content = client.GetStringAsync("https://orgabc.crm8.dynamics.com/api/data/v9.2/accounts");//accounts refers to the User Table Logical Name.
Console.WriteLine("Acces Token for given :" + content.Result);
}
//end of retrieve data.
}
}
}
What we tried?
- Changing the API version to 9.1 and 9.0 from the actual 9.2 as per microsoft documentation
- Lowering urllib version as per suggestions from multiple SO Q/A like this
- Working on the same connection details with Postman Tool works perfectly fine
So, narrowing down on it seems the issue is with the code hitting the endpoint. Any help?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
该代码没有错误,它是正确编写的。问题在于当地机器的防火墙/代理/VPN设置问题,该问题阻止了实际的API调用。在打开系统上运行时,它可以正常工作。
The code has no bug, it is correctly written. The issue was with the local machine's firewall/proxy/VPN setting issues which was blocking the actual API call. It works fine when run on an open system.