diff options
author | CoprDistGit <infra@openeuler.org> | 2023-04-11 23:33:14 +0000 |
---|---|---|
committer | CoprDistGit <infra@openeuler.org> | 2023-04-11 23:33:14 +0000 |
commit | 5240f76bbd97de831349c907eaa628230a97ab26 (patch) | |
tree | b669bf5a3913b22502e2583ba25891a18248ec73 | |
parent | 0d9e267ad100512d5e07d4f410dc8fb0f2be5dc4 (diff) |
automatic import of python-dynamics365crm-python
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | python-dynamics365crm-python.spec | 724 | ||||
-rw-r--r-- | sources | 1 |
3 files changed, 726 insertions, 0 deletions
@@ -0,0 +1 @@ +/dynamics365crm_python-1.0.1.tar.gz diff --git a/python-dynamics365crm-python.spec b/python-dynamics365crm-python.spec new file mode 100644 index 0000000..059fbc1 --- /dev/null +++ b/python-dynamics365crm-python.spec @@ -0,0 +1,724 @@ +%global _empty_manifest_terminate_build 0 +Name: python-dynamics365crm-python +Version: 1.0.1 +Release: 1 +Summary: API wrapper for Dynamics365CRM written in Python +License: MIT +URL: https://pypi.org/project/dynamics365crm-python/ +Source0: https://mirrors.nju.edu.cn/pypi/web/packages/cd/c4/7c2ad1c2bcf41e35d12523c6429723e250ba16a3cfb2880d736baceefcca/dynamics365crm_python-1.0.1.tar.gz +BuildArch: noarch + +Requires: python3-requests + +%description +# dynamics365crm-python +Dynamics365CRM API wrapper for Dynamics 365 written in Python. +This library works for API version: v9.0 + +## Installing +``` +pip install dynamics365crm-python +``` + +## Usage + +This library provides a client that is initialized with the following arguments + +- domain: the dynamics 365 tenant domain (yours or someone else's) +- access_token: the retrieved token after authentication + +Arguments for OAuth2 flow +- client_id: your Azure AD application client id +- client_secret: your Azure AD application client secret + +```python +from dynamics365crm.client import Client + +## Normal use to make calls to the api +client = Client("https://tenant_name.crmX.dynamics.com", access_token="access_token") + +## OAuth2 configuration required arguments +client = Client( + "https://tenant_name.crmX.dynamics.com", + client_id=CLIENT_ID, + client_secret=CLIENT_SECRET, +) +``` + +### OAuth2 Protocol +#### Get authorization url + +This will return a [MSAL](https://github.com/AzureAD/microsoft-authentication-library-for-python) valid authorization url, the following are required: + +- tenant_id: someone else's Azure AD tenant_id + - Ask the dynamics tenant owner to go to the [Azure Portal](portal.azure.com) and retrieve the Tenant ID from the Azure Active Directory/Overview + - If your app is configured as multi-tenant (for any enterprise or personal account to use) you could pass "common" instead od the Tenant ID + - However microsoft azure app configuration is a mess so the Tenant ID is preferable +- redirect_uri: your service callback url +- state: your unique generated state to identify the requester + - you could also initiate an oauth flow with msal manually with initiate_auth_code_flow method, check the [official example](https://github.com/Azure-Samples/ms-identity-python-webapp) + +```python +authorization_url = client.build_authorization_url("tenant_id", "redirect_uri", "state") + +>>> "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=XXXX&response_type=code&redirect_uri=https%3A%2F%your_domain/%2Fcallback%2F&scope=https%3A%2F%2tenant_name.crmX.dynamics.com%2Fuser_impersonation+offline_access+openid+profile&state=XXXX&prompt=consent" +``` + +#### Exchange the callback code for an access token + +To finish the oauth protocol microsoft will redirect to your callback endpoint with a temporal code in the url query params to be exchanged for the full-fledged token (a json with the access_token, refresh_token, expires_in, etc.) + +Again the (**tenant_id** or "common") and **redirect_uri** are required, the third argument is the code sent by microsoft + +```python +token = client.exchange_code("tenant_id", "redirect_uri", "code") +``` + +#### Refresh token + +If the access token expires you could get a new **access_token** exchanging the long-lived **refresh_token** + +Again the **tenant_id** or "common" is required + +```python +token = client.refresh_access_token("tenant_id", "refresh_token") +``` + +#### Set access token + +You could pass the access_token in the constructor or set it with + +```python +client.set_access_token("access_token") +``` + +## Dynamics Web API + +### Contacts +- See the documentation https://docs.microsoft.com/es-es/dynamics365/customer-engagement/web-api/contact?view=dynamics-ce-odata-9 + +#### Get Contacts +can receive orderby, filter, select, top, expand +``` +list_contacts = client.get_contacts() +``` + +#### Create Contact +``` +create_contact = client.create_contact(firstname="FIRSTNAME", lastname="LASTNAME", middlename="MIDDLENAME", emailaddress1="EMAILADDRESS") +``` + +#### Delete Contact +``` +delete_contact = client.delete_contact('ID') +``` + +#### Update Contact +``` +update_contact = client.update_contact('ID', firstname="FIRSTNAME", lastname="LASTNAME", middlename="MIDDLENAME", emailaddress1="EMAILADDRESS") +``` + +### Accounts +- See the documentation https://docs.microsoft.com/es-es/dynamics365/customer-engagement/web-api/account?view=dynamics-ce-odata-9 + +#### Get Accounts +can receive orderby, filter, select, top, expand +``` +get_accounts = client.get_accounts() +``` + +#### Create Account +``` +create_account = client.create_account(name="NAME", websiteurl="WWW.WEBSITE.COM") +``` + +#### Delete Account +``` +create_account = client.delete_account('ID') +``` + +#### Update Account +``` +update_account = client.update_account(id="ID", name="NAME") +``` + +### Opportunities +- See the documentation https://docs.microsoft.com/es-es/dynamics365/customer-engagement/web-api/opportunity?view=dynamics-ce-odata-9 + +#### Get Opportunities +can receive orderby, filter, select, top, expand +``` +list_opportunities = client.get_opportunities() +``` + +#### Create Opportunities +``` +create_opportunities = client.create_opportunity(name="OPPORTUNITY NAME") +``` + +#### Delete Opportunities +``` +delete_opportunities = client.delete_opportunity(id="OPPORTUNITY ID") +``` + +#### Update Opportunities +``` +update_opportunities = client.update_opportunity(id="OPPORTUNITY ID", name="OPPORTUNITY NAME", description="SOME DESCRIPTION") +``` + +### Leads +- See the documentation https://docs.microsoft.com/es-es/dynamics365/customer-engagement/web-api/lead?view=dynamics-ce-odata-9 + +#### Get Leads +can receive orderby, filter, select, top, expand +``` +list_leads = client.get_leads() +``` + +#### Create Lead +``` +create_leads = client.create_lead(fullname="LEAD NAME", subject="LEAD SUBJECT", mobilephone="123456", websiteurl="WWW.WEBSITE.COM", middlename="MIDDLE LEAD NAME") +``` + +#### Delete Lead +``` +delete_leads = client.delete_lead("ID") +``` + +#### Update Lead +``` +update_leads = client.update_lead(fullname="LEAD NAME", subject="LEAD SUBJECT", mobilephone="123456", websiteurl="WWW.WEBSITE.COM", middlename="MIDDLE LEAD NAME") +``` + +### Campaigns +- See the documentation https://docs.microsoft.com/es-es/dynamics365/customer-engagement/web-api/campaign?view=dynamics-ce-odata-9 + +#### Get Campaigns +can receive orderby, filter, select, top, expand +``` +list_campaigns = client.get_campaigns() +``` + +#### Create Campaign +``` +create_campaign = client.create_campaign(name="CAMPAIGN NAME", description="SOME DESCRIPTION") +``` + +#### Delete Campaign +``` +delete_campaign = client.delete_campaign(id="ID") +``` + +#### Update Campaign +``` +update_campaign = client.update_campaign(id="ID", name="CAMPAIGN NAME", description="SOME DESCRIPTION") +``` + +## Requirements +- requests +- msal + +## Contributing +We are always grateful for any kind of contribution including but not limited to bug reports, code enhancements, bug fixes, and even functionality suggestions. +#### You can report any bug you find or suggest new functionality with a new [issue](https://github.com/GearPlug/dynamics365crm-python/issues). +#### If you want to add yourself some functionality to the wrapper: +1. Fork it ( https://github.com/GearPlug/dynamics365crm-python ) +2. Create your feature branch (git checkout -b my-new-feature) +3. Commit your changes (git commit -am 'Adds my new feature') +4. Push to the branch (git push origin my-new-feature) +5. Create a new Pull Request + + + +%package -n python3-dynamics365crm-python +Summary: API wrapper for Dynamics365CRM written in Python +Provides: python-dynamics365crm-python +BuildRequires: python3-devel +BuildRequires: python3-setuptools +BuildRequires: python3-pip +%description -n python3-dynamics365crm-python +# dynamics365crm-python +Dynamics365CRM API wrapper for Dynamics 365 written in Python. +This library works for API version: v9.0 + +## Installing +``` +pip install dynamics365crm-python +``` + +## Usage + +This library provides a client that is initialized with the following arguments + +- domain: the dynamics 365 tenant domain (yours or someone else's) +- access_token: the retrieved token after authentication + +Arguments for OAuth2 flow +- client_id: your Azure AD application client id +- client_secret: your Azure AD application client secret + +```python +from dynamics365crm.client import Client + +## Normal use to make calls to the api +client = Client("https://tenant_name.crmX.dynamics.com", access_token="access_token") + +## OAuth2 configuration required arguments +client = Client( + "https://tenant_name.crmX.dynamics.com", + client_id=CLIENT_ID, + client_secret=CLIENT_SECRET, +) +``` + +### OAuth2 Protocol +#### Get authorization url + +This will return a [MSAL](https://github.com/AzureAD/microsoft-authentication-library-for-python) valid authorization url, the following are required: + +- tenant_id: someone else's Azure AD tenant_id + - Ask the dynamics tenant owner to go to the [Azure Portal](portal.azure.com) and retrieve the Tenant ID from the Azure Active Directory/Overview + - If your app is configured as multi-tenant (for any enterprise or personal account to use) you could pass "common" instead od the Tenant ID + - However microsoft azure app configuration is a mess so the Tenant ID is preferable +- redirect_uri: your service callback url +- state: your unique generated state to identify the requester + - you could also initiate an oauth flow with msal manually with initiate_auth_code_flow method, check the [official example](https://github.com/Azure-Samples/ms-identity-python-webapp) + +```python +authorization_url = client.build_authorization_url("tenant_id", "redirect_uri", "state") + +>>> "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=XXXX&response_type=code&redirect_uri=https%3A%2F%your_domain/%2Fcallback%2F&scope=https%3A%2F%2tenant_name.crmX.dynamics.com%2Fuser_impersonation+offline_access+openid+profile&state=XXXX&prompt=consent" +``` + +#### Exchange the callback code for an access token + +To finish the oauth protocol microsoft will redirect to your callback endpoint with a temporal code in the url query params to be exchanged for the full-fledged token (a json with the access_token, refresh_token, expires_in, etc.) + +Again the (**tenant_id** or "common") and **redirect_uri** are required, the third argument is the code sent by microsoft + +```python +token = client.exchange_code("tenant_id", "redirect_uri", "code") +``` + +#### Refresh token + +If the access token expires you could get a new **access_token** exchanging the long-lived **refresh_token** + +Again the **tenant_id** or "common" is required + +```python +token = client.refresh_access_token("tenant_id", "refresh_token") +``` + +#### Set access token + +You could pass the access_token in the constructor or set it with + +```python +client.set_access_token("access_token") +``` + +## Dynamics Web API + +### Contacts +- See the documentation https://docs.microsoft.com/es-es/dynamics365/customer-engagement/web-api/contact?view=dynamics-ce-odata-9 + +#### Get Contacts +can receive orderby, filter, select, top, expand +``` +list_contacts = client.get_contacts() +``` + +#### Create Contact +``` +create_contact = client.create_contact(firstname="FIRSTNAME", lastname="LASTNAME", middlename="MIDDLENAME", emailaddress1="EMAILADDRESS") +``` + +#### Delete Contact +``` +delete_contact = client.delete_contact('ID') +``` + +#### Update Contact +``` +update_contact = client.update_contact('ID', firstname="FIRSTNAME", lastname="LASTNAME", middlename="MIDDLENAME", emailaddress1="EMAILADDRESS") +``` + +### Accounts +- See the documentation https://docs.microsoft.com/es-es/dynamics365/customer-engagement/web-api/account?view=dynamics-ce-odata-9 + +#### Get Accounts +can receive orderby, filter, select, top, expand +``` +get_accounts = client.get_accounts() +``` + +#### Create Account +``` +create_account = client.create_account(name="NAME", websiteurl="WWW.WEBSITE.COM") +``` + +#### Delete Account +``` +create_account = client.delete_account('ID') +``` + +#### Update Account +``` +update_account = client.update_account(id="ID", name="NAME") +``` + +### Opportunities +- See the documentation https://docs.microsoft.com/es-es/dynamics365/customer-engagement/web-api/opportunity?view=dynamics-ce-odata-9 + +#### Get Opportunities +can receive orderby, filter, select, top, expand +``` +list_opportunities = client.get_opportunities() +``` + +#### Create Opportunities +``` +create_opportunities = client.create_opportunity(name="OPPORTUNITY NAME") +``` + +#### Delete Opportunities +``` +delete_opportunities = client.delete_opportunity(id="OPPORTUNITY ID") +``` + +#### Update Opportunities +``` +update_opportunities = client.update_opportunity(id="OPPORTUNITY ID", name="OPPORTUNITY NAME", description="SOME DESCRIPTION") +``` + +### Leads +- See the documentation https://docs.microsoft.com/es-es/dynamics365/customer-engagement/web-api/lead?view=dynamics-ce-odata-9 + +#### Get Leads +can receive orderby, filter, select, top, expand +``` +list_leads = client.get_leads() +``` + +#### Create Lead +``` +create_leads = client.create_lead(fullname="LEAD NAME", subject="LEAD SUBJECT", mobilephone="123456", websiteurl="WWW.WEBSITE.COM", middlename="MIDDLE LEAD NAME") +``` + +#### Delete Lead +``` +delete_leads = client.delete_lead("ID") +``` + +#### Update Lead +``` +update_leads = client.update_lead(fullname="LEAD NAME", subject="LEAD SUBJECT", mobilephone="123456", websiteurl="WWW.WEBSITE.COM", middlename="MIDDLE LEAD NAME") +``` + +### Campaigns +- See the documentation https://docs.microsoft.com/es-es/dynamics365/customer-engagement/web-api/campaign?view=dynamics-ce-odata-9 + +#### Get Campaigns +can receive orderby, filter, select, top, expand +``` +list_campaigns = client.get_campaigns() +``` + +#### Create Campaign +``` +create_campaign = client.create_campaign(name="CAMPAIGN NAME", description="SOME DESCRIPTION") +``` + +#### Delete Campaign +``` +delete_campaign = client.delete_campaign(id="ID") +``` + +#### Update Campaign +``` +update_campaign = client.update_campaign(id="ID", name="CAMPAIGN NAME", description="SOME DESCRIPTION") +``` + +## Requirements +- requests +- msal + +## Contributing +We are always grateful for any kind of contribution including but not limited to bug reports, code enhancements, bug fixes, and even functionality suggestions. +#### You can report any bug you find or suggest new functionality with a new [issue](https://github.com/GearPlug/dynamics365crm-python/issues). +#### If you want to add yourself some functionality to the wrapper: +1. Fork it ( https://github.com/GearPlug/dynamics365crm-python ) +2. Create your feature branch (git checkout -b my-new-feature) +3. Commit your changes (git commit -am 'Adds my new feature') +4. Push to the branch (git push origin my-new-feature) +5. Create a new Pull Request + + + +%package help +Summary: Development documents and examples for dynamics365crm-python +Provides: python3-dynamics365crm-python-doc +%description help +# dynamics365crm-python +Dynamics365CRM API wrapper for Dynamics 365 written in Python. +This library works for API version: v9.0 + +## Installing +``` +pip install dynamics365crm-python +``` + +## Usage + +This library provides a client that is initialized with the following arguments + +- domain: the dynamics 365 tenant domain (yours or someone else's) +- access_token: the retrieved token after authentication + +Arguments for OAuth2 flow +- client_id: your Azure AD application client id +- client_secret: your Azure AD application client secret + +```python +from dynamics365crm.client import Client + +## Normal use to make calls to the api +client = Client("https://tenant_name.crmX.dynamics.com", access_token="access_token") + +## OAuth2 configuration required arguments +client = Client( + "https://tenant_name.crmX.dynamics.com", + client_id=CLIENT_ID, + client_secret=CLIENT_SECRET, +) +``` + +### OAuth2 Protocol +#### Get authorization url + +This will return a [MSAL](https://github.com/AzureAD/microsoft-authentication-library-for-python) valid authorization url, the following are required: + +- tenant_id: someone else's Azure AD tenant_id + - Ask the dynamics tenant owner to go to the [Azure Portal](portal.azure.com) and retrieve the Tenant ID from the Azure Active Directory/Overview + - If your app is configured as multi-tenant (for any enterprise or personal account to use) you could pass "common" instead od the Tenant ID + - However microsoft azure app configuration is a mess so the Tenant ID is preferable +- redirect_uri: your service callback url +- state: your unique generated state to identify the requester + - you could also initiate an oauth flow with msal manually with initiate_auth_code_flow method, check the [official example](https://github.com/Azure-Samples/ms-identity-python-webapp) + +```python +authorization_url = client.build_authorization_url("tenant_id", "redirect_uri", "state") + +>>> "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=XXXX&response_type=code&redirect_uri=https%3A%2F%your_domain/%2Fcallback%2F&scope=https%3A%2F%2tenant_name.crmX.dynamics.com%2Fuser_impersonation+offline_access+openid+profile&state=XXXX&prompt=consent" +``` + +#### Exchange the callback code for an access token + +To finish the oauth protocol microsoft will redirect to your callback endpoint with a temporal code in the url query params to be exchanged for the full-fledged token (a json with the access_token, refresh_token, expires_in, etc.) + +Again the (**tenant_id** or "common") and **redirect_uri** are required, the third argument is the code sent by microsoft + +```python +token = client.exchange_code("tenant_id", "redirect_uri", "code") +``` + +#### Refresh token + +If the access token expires you could get a new **access_token** exchanging the long-lived **refresh_token** + +Again the **tenant_id** or "common" is required + +```python +token = client.refresh_access_token("tenant_id", "refresh_token") +``` + +#### Set access token + +You could pass the access_token in the constructor or set it with + +```python +client.set_access_token("access_token") +``` + +## Dynamics Web API + +### Contacts +- See the documentation https://docs.microsoft.com/es-es/dynamics365/customer-engagement/web-api/contact?view=dynamics-ce-odata-9 + +#### Get Contacts +can receive orderby, filter, select, top, expand +``` +list_contacts = client.get_contacts() +``` + +#### Create Contact +``` +create_contact = client.create_contact(firstname="FIRSTNAME", lastname="LASTNAME", middlename="MIDDLENAME", emailaddress1="EMAILADDRESS") +``` + +#### Delete Contact +``` +delete_contact = client.delete_contact('ID') +``` + +#### Update Contact +``` +update_contact = client.update_contact('ID', firstname="FIRSTNAME", lastname="LASTNAME", middlename="MIDDLENAME", emailaddress1="EMAILADDRESS") +``` + +### Accounts +- See the documentation https://docs.microsoft.com/es-es/dynamics365/customer-engagement/web-api/account?view=dynamics-ce-odata-9 + +#### Get Accounts +can receive orderby, filter, select, top, expand +``` +get_accounts = client.get_accounts() +``` + +#### Create Account +``` +create_account = client.create_account(name="NAME", websiteurl="WWW.WEBSITE.COM") +``` + +#### Delete Account +``` +create_account = client.delete_account('ID') +``` + +#### Update Account +``` +update_account = client.update_account(id="ID", name="NAME") +``` + +### Opportunities +- See the documentation https://docs.microsoft.com/es-es/dynamics365/customer-engagement/web-api/opportunity?view=dynamics-ce-odata-9 + +#### Get Opportunities +can receive orderby, filter, select, top, expand +``` +list_opportunities = client.get_opportunities() +``` + +#### Create Opportunities +``` +create_opportunities = client.create_opportunity(name="OPPORTUNITY NAME") +``` + +#### Delete Opportunities +``` +delete_opportunities = client.delete_opportunity(id="OPPORTUNITY ID") +``` + +#### Update Opportunities +``` +update_opportunities = client.update_opportunity(id="OPPORTUNITY ID", name="OPPORTUNITY NAME", description="SOME DESCRIPTION") +``` + +### Leads +- See the documentation https://docs.microsoft.com/es-es/dynamics365/customer-engagement/web-api/lead?view=dynamics-ce-odata-9 + +#### Get Leads +can receive orderby, filter, select, top, expand +``` +list_leads = client.get_leads() +``` + +#### Create Lead +``` +create_leads = client.create_lead(fullname="LEAD NAME", subject="LEAD SUBJECT", mobilephone="123456", websiteurl="WWW.WEBSITE.COM", middlename="MIDDLE LEAD NAME") +``` + +#### Delete Lead +``` +delete_leads = client.delete_lead("ID") +``` + +#### Update Lead +``` +update_leads = client.update_lead(fullname="LEAD NAME", subject="LEAD SUBJECT", mobilephone="123456", websiteurl="WWW.WEBSITE.COM", middlename="MIDDLE LEAD NAME") +``` + +### Campaigns +- See the documentation https://docs.microsoft.com/es-es/dynamics365/customer-engagement/web-api/campaign?view=dynamics-ce-odata-9 + +#### Get Campaigns +can receive orderby, filter, select, top, expand +``` +list_campaigns = client.get_campaigns() +``` + +#### Create Campaign +``` +create_campaign = client.create_campaign(name="CAMPAIGN NAME", description="SOME DESCRIPTION") +``` + +#### Delete Campaign +``` +delete_campaign = client.delete_campaign(id="ID") +``` + +#### Update Campaign +``` +update_campaign = client.update_campaign(id="ID", name="CAMPAIGN NAME", description="SOME DESCRIPTION") +``` + +## Requirements +- requests +- msal + +## Contributing +We are always grateful for any kind of contribution including but not limited to bug reports, code enhancements, bug fixes, and even functionality suggestions. +#### You can report any bug you find or suggest new functionality with a new [issue](https://github.com/GearPlug/dynamics365crm-python/issues). +#### If you want to add yourself some functionality to the wrapper: +1. Fork it ( https://github.com/GearPlug/dynamics365crm-python ) +2. Create your feature branch (git checkout -b my-new-feature) +3. Commit your changes (git commit -am 'Adds my new feature') +4. Push to the branch (git push origin my-new-feature) +5. Create a new Pull Request + + + +%prep +%autosetup -n dynamics365crm-python-1.0.1 + +%build +%py3_build + +%install +%py3_install +install -d -m755 %{buildroot}/%{_pkgdocdir} +if [ -d doc ]; then cp -arf doc %{buildroot}/%{_pkgdocdir}; fi +if [ -d docs ]; then cp -arf docs %{buildroot}/%{_pkgdocdir}; fi +if [ -d example ]; then cp -arf example %{buildroot}/%{_pkgdocdir}; fi +if [ -d examples ]; then cp -arf examples %{buildroot}/%{_pkgdocdir}; fi +pushd %{buildroot} +if [ -d usr/lib ]; then + find usr/lib -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/lib64 ]; then + find usr/lib64 -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/bin ]; then + find usr/bin -type f -printf "/%h/%f\n" >> filelist.lst +fi +if [ -d usr/sbin ]; then + find usr/sbin -type f -printf "/%h/%f\n" >> filelist.lst +fi +touch doclist.lst +if [ -d usr/share/man ]; then + find usr/share/man -type f -printf "/%h/%f.gz\n" >> doclist.lst +fi +popd +mv %{buildroot}/filelist.lst . +mv %{buildroot}/doclist.lst . + +%files -n python3-dynamics365crm-python -f filelist.lst +%dir %{python3_sitelib}/* + +%files help -f doclist.lst +%{_docdir}/* + +%changelog +* Tue Apr 11 2023 Python_Bot <Python_Bot@openeuler.org> - 1.0.1-1 +- Package Spec generated @@ -0,0 +1 @@ +8fca7547c34867dee3ac3e2d81257c6f dynamics365crm_python-1.0.1.tar.gz |