{"id":26919,"library":"dynamics365crm-python","title":"Dynamics 365 CRM Python Client","description":"An API wrapper for Microsoft Dynamics 365 CRM that provides Python bindings for CRM operations. Current version 1.0.2 supports Python 3.7-3.11. The library is stable with no recent updates; it wraps OData REST endpoints for entity CRUD and batch operations.","status":"active","version":"1.0.2","language":"python","source_language":"en","source_url":"https://github.com/michalstolarczyk/dynamics365crm-python","tags":["dynamics365","crm","microsoft","api-wrapper","odata"],"install":[{"cmd":"pip install dynamics365crm-python","lang":"bash","label":"Install via pip"}],"dependencies":[{"reason":"HTTP client for API calls","package":"requests","optional":false},{"reason":"Azure AD authentication","package":"msal","optional":true}],"imports":[{"note":"Old docs incorrectly showed submodule path","wrong":"from dynamics365crm.client import Dynamics365Client","symbol":"Dynamics365Client","correct":"from dynamics365crm import Dynamics365Client"},{"note":"","wrong":null,"symbol":"Entity","correct":"from dynamics365crm import Entity"}],"quickstart":{"code":"from dynamics365crm import Dynamics365Client\nimport os\n\nclient = Dynamics365Client(\n    client_id=os.environ.get('CLIENT_ID', ''),\n    client_secret=os.environ.get('CLIENT_SECRET', ''),\n    tenant_id=os.environ.get('TENANT_ID', ''),\n    resource_url=os.environ.get('CRM_URL', '')\n)\n# Create a contact\ncontact = client.create('contacts', {'fullname': 'John Doe', 'emailaddress1': 'john@example.com'})\nprint('Created contact:', contact.id)","lang":"python","description":"Initialize client with Azure AD auth and create a new contact entity."},"warnings":[{"fix":"Update calls to use keyword arguments: Dynamics365Client(client_id='...', client_secret='...')","message":"In version 1.0.0, the constructor changed from positional arguments to keyword-only arguments for client_id, client_secret, etc. Older code using positional args will break.","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"Use single entity methods for single operations: client.create(entity_name, data)","message":"The 'create', 'update', 'delete' methods still expect entity data as a list of dictionaries for batch operations, but the non-batch methods are preferred. Batch methods may be removed in a future release.","severity":"deprecated","affected_versions":"all"},{"fix":"Ensure resource_url ends without a slash, e.g., 'https://org.crm.dynamics.com/api/data/v9.1'","message":"The resource_url must not include a trailing slash. Many users include '/api/data/v9.1/' which is default, but mistakenly add a slash at the end, causing 404 errors.","severity":"gotcha","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-05-01T00:00:00.000Z","next_check":"2026-07-30T00:00:00.000Z","problems":[{"fix":"Use 'from dynamics365crm import Dynamics365Client'","cause":"Incorrect import path; the library uses a flat structure, not submodules.","error":"ImportError: cannot import name 'Dynamics365Client' from 'dynamics365crm'"},{"fix":"If using batch, access the ID directly (the return value is the ID string). For single entity creation, use the non-batch method which returns an Entity object with .id.","cause":"The create method in batch mode returns a string ID, not an object. Using .id on a string fails.","error":"AttributeError: 'str' object has no attribute 'id'"},{"fix":"Double-check CLIENT_ID, CLIENT_SECRET, TENANT_ID. Ensure the app registration has CRM permissions (Dynamics CRM user_impersonation) and grant admin consent.","cause":"Authentication failure due to wrong tenant, client id, or secret. Often environment variables are missing or expired.","error":"requests.exceptions.HTTPError: 401 Client Error: Unauthorized"}],"ecosystem":"pypi","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}