{ "info": { "author": "Felix Lindstrom", "author_email": "felix.lindstrom@gmail.com", "bugtrack_url": null, "classifiers": [ "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "Python Salesforce API\n=====================\n\n[![Build Status](https://travis-ci.org/felixlindstrom/python-salesforce-api.svg?branch=master)](https://travis-ci.org/felixlindstrom/python-salesforce-api)\n\nThis project aims to provide an easy to use, highly flexible and testable solution for communicating with Salesforce\nthrough its REST and SOAP api.\n\nContent\n-------\n\n- [Simple Usage](#simple-usage)\n- [Authentication](#authentication)\n- [Record management](#record-management)\n - [Insert](#insert)\n - [Upsert](#upsert)\n - [Update](#update)\n - [Get](#get)\n - [Delete](#delete)\n- [Quering SObjects](#querying-sobjects)\n- [Bulk](#bulk)\n- [Tooling](#tooling)\n- [Deploying](#deploying)\n- [Retrieving](#retrieving)\n- [Additional features](#additional-features)\n\n\nSimple usage\n------------\n\nCreating a new connection / client is as simple as this:\n```python\nfrom salesforce_api import Salesforce\nclient = Salesforce(\n username='test@example.com',\n password='my-password',\n security_token='password-token'\n)\n```\n\nAuthentication\n--------------\nTo get started in the simples of ways, you would do the following\n\n```python\nfrom salesforce_api import Salesforce\nclient = Salesforce(username='test@example.com',\n password='my-password',\n security_token='password-token')\n```\n\nIf you are trying to connect to a sandbox, you have to specify this using the `is_sandbox` argument.\n```python\nfrom salesforce_api import Salesforce\nclient = Salesforce(username='test@example.com',\n password='my-password',\n security_token='password-token',\n is_sandbox=True)\n```\n\nIf for some reason the login-url differs from the standard prod/test login urls, you can specify the login url. This can be useful if you are using a mock-server, for example. This will override the `is_sandbox` argument.\n```python\nfrom salesforce_api import Salesforce\nclient = Salesforce(username='test@example.com',\n password='my-password',\n security_token='password-token',\n domain='login.example.com')\n```\n\nThe examples so far would use the SOAP API for authenticating. If you want to authenticate using an app, that's easy engough. The login-url and sandbox-arguments applies here as well.\n```python\nfrom salesforce_api import Salesforce\nclient = Salesforce(username='test@example.com',\n password='my-password',\n client_id='123',\n client_secret='my-secret')\n```\n\nIf you already have a token, obtain elsewhere, you can just as easily create a new client.\n```python\nfrom salesforce_api import Salesforce\nclient = Salesforce(access_token='access-token-here')\n```\n\nIf you want to explicitly use one or the other methods of authenticating, you can do that as well\n```python\nfrom salesforce_api import Salesforce, login\nclient = Salesforce(login.oauth2(username='test@example.com',\n password='my-password',\n client_id='123',\n client_secret='my-secret'))\n```\n\nRecord management\n-----------------\n\nWokring with records is easy. All SObject-related methods are exposed through the `sobjects`-property on the client.\n\nThe data returned from the different calls is the decoded data from the raw response.\n\n##### Insert\nExample\n```python\nclient.sobjects.Contact.insert({'LastName': 'Example', 'Email': 'test@example.com'})\n```\nReturns\n```\n{\"id\":\"0031l000007rU3vAAE\",\"success\":true,\"errors\":[]}\n```\n\n##### Get\nExample\n```python\nclient.sobjects.Contact.get('0031l000007rU3vAAE')\n```\nReturns\n```\n{\n \"attributes\": {\n \"type\": \"Contact\",\n \"url\": \"/services/data/v44.0/sobjects/Contact/0031l000007rU3vAAE\"\n },\n \"Id\": \"0031l000007rU3vAAE\",\n \"LastName\": \"Example\",\n \"FirstName\": \"Test\",\n ...\n}\n```\n\n##### Update\nExample\n```python\nclient.sobjects.Contact.update('0031l000007rU3vAAE', {'FirstName': 'Felix', 'LastName': 'Lindstrom'})\n```\nReturns\n```python\nTrue\n```\n\n##### Upsert\nExample\n```python\nclient.sobjects.Contact.upsert('customExtIdField__c', '11999', {'FirstName': 'Felix', 'LastName': 'Lindstrom'})\n```\nReturns\n```python\nTrue\n```\n\n##### Delete\nExample\n```python\nclient.sobjects.Contact.delete('0031l000007rU3vAAE')\n```\nReturns\n```python\nTrue\n```\n\n##### Metadata\nExample\n```python\nclient.sobjects.Contact.metadata()\n```\nReturns\n```\n{\n 'objectDescribe': {\n 'activateable': False,\n 'createable': True,\n 'custom': False,\n ...\n 'urls': {\n 'compactLayouts': '/services/data/v44.0/sobjects/Contact/describe/compactLayouts',\n 'rowTemplate': '/services/data/v44.0/sobjects/Contact/{ID}',\n 'approvalLayouts': '/services/data/v44.0/sobjects/Contact/describe/approvalLayouts',\n ...\n }\n },\n 'recentItems': []\n}\n```\n\n##### Describe\nExample\n```python\nclient.sobjects.Contact.describe()\n```\nReturns\n```\n{\n ...\n}\n```\n\nQuerying SObjects\n-------------\n\nThe Salesforce API is great at returning large amounts of data, so the pagination that Salesforce implements for the result of your queries is taken cared of automagically when querying for data.\n\nExample\n```python\nclient.sobjects.query(\"SELECT Id, FirstName, LastName FROM Contact WHERE FirstName='Felix'\")\n```\nReturn\n```\n[{\n 'attributes': {\n 'type': 'Contact',\n 'url': '/services/data/v44.0/sobjects/Contact/0031l000007Jia4AAC'\n },\n 'Id': '0031l000007Jia4AAC',\n 'FirstName': 'Felix',\n 'LastName': 'Lindstrom'\n}, ...]\n``` \n\nBulk\n----\n\nThis module implements the Bulk V2 API. Basically, it allows you to think less and do more.\n\nNote that the correct permission-set might be needed on the user, see https://success.salesforce.com/issues_view?id=a1p3A000000BMPFQA4\n\n##### Bulk Insert\nExample\n```python\nclient.bulk.insert('Contact', [\n {'LastName': 'Lindstrom', 'Email': 'test@example.com'},\n {'LastName': 'Something else', 'Email': 'test@example.com'}\n])\n```\nReturns\n```python\n[,\n ]\n```\n\n##### Bulk Insert\nExample\n```python\nclient.bulk.insert('Contact', [\n {'LastName': 'Lindstrom', 'Email': 'test@example.com'},\n {'LastName': 'Something else', 'Email': 'test@example.com'}\n])\n```\nReturns\n```python\n[,\n ]\n```\n\n##### Bulk Upsert\nExample\n```python\nclient.bulk.upsert('Contact', [\n {'LastName': 'Lindstrom', 'Email': 'test@example.com', 'MyId__c': 1},\n {'LastName': 'Something else', 'Email': 'test@example.com', 'MyId__c': 2}\n], external_id_field='MyId__c')\n```\nReturns\n```python\n[,\n ]\n```\n\n##### Bulk Update\nExample\n```python\nclient.bulk.update('Contact', [\n {'LastName': 'Lindstrom', 'Email': 'test@example.com'},\n {'LastName': 'Something else', 'Email': 'test@example.com'}\n])\n```\nReturns\n```python\n[,\n ]\n```\n\n##### Bulk Delete\nExample\n```python\nclient.bulk.delete('Contact', ['0031l000007rU5rAAE', '0031l000007rU5sAAE'])\n```\nReturns\n```python\n[,\n ]\n```\n\n##### Failed requests\nExample (_Given that the records no longer exists_)\n```python\nclient.bulk.update('Contact', ['0031l000007rU5rAAE', '0031l000007rU5sAAE'])\n```\nReturns\n```python\n[,\n ]\n```\n\nTooling\n-------\n\n##### Execute Apex\nExample\n```python\nclient.tooling.execute_apex(\"System.debug('Test');\")\n```\nReturn on success\n```python\n\n```\nReturn on failure\n```\n\n```\n\nDeploying\n---------\nDeploying an existing package\n```python\nfrom salesforce_api.models.deploy import Options\n\n\ndeployment = client.deploy.deploy('/path/to/file.zip')\ndeployment.wait()\nresult = deployment.get_status()\n\n```\n\nOnly validating\n```python\nfrom salesforce_api.models.deploy import Options\n\n\ndeployment = client.deploy.deploy('/path/to/file.zip', Options(checkOnly=True))\ndeployment.wait()\nresult = deployment.get_status()\n\n```\n\nValidating running specific tests\n```python\nfrom salesforce_api.models.deploy import Options\n\n\ndeployment = client.deploy.deploy('/path/to/file.zip', Options(\n checkOnly=True,\n testLevel='RunSpecifiedTests',\n runTests=[\n 'TesterIntegrationApplicationTest',\n 'TesterIntegrationProcessTest'\n ]\n))\ndeployment.wait()\nresult = deployment.get_status()\n```\n\nCanceling a deployment as soon as it fails\n```python\nfrom salesforce_api.models.deploy import Options\n\n\ndeployment = client.deploy.deploy('/path/to/file.zip', Options(checkOnly=True))\n\nwhile not deployment.is_done():\n if deployment.has_failed():\n deployment.cancel()\n break\n\n```\n\nRetrieving\n----------\nExample\n```python\nfrom salesforce_api.models.retrieve import Type\n\n\n# Decide what you want to retrieve\ntypes = [\n Type('ApexTrigger'),\n Type('ApexClass', ['MyMainClass', 'AnotherClass'])\n]\n\n# Create retrievement-job\nretrievement = client.retrieve.retrieve(types)\n\n# Wait for the job to finish\nretrievement.wait()\n\n# Write the resulting zip-archive to a file\nopen('retrieve.zip', 'wb').write(retrievement.get_zip_file().read())\n```\n\nAdditional features\n-------------------\n\nIf for some reason you need to specify how the client communicates with Salesforce, you can create the requests-session yourself and pass it to the client upon creation. This would, for example, allow you proxy your requests:\n```python\nimport requests\nfrom salesforce_api import Salesforce\n\n\nsession = requests.Session()\nsession.proxies.update({'https': 'https://my-proxy.com/'})\nsession.headers.update({'User-Agent': 'My-User-Agent'})\n\nclient = Salesforce(username='test@example.com',\n password='my-password',\n security_token='password-token',\n session=session)\n```", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/felixlindstrom/python-salesforce-api", "keywords": "salesforce,salesforce api,salesforce bulk api", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "salesforce-api", "package_url": "https://pypi.org/project/salesforce-api/", "platform": "", "project_url": "https://pypi.org/project/salesforce-api/", "project_urls": { "Homepage": "https://github.com/felixlindstrom/python-salesforce-api" }, "release_url": "https://pypi.org/project/salesforce-api/0.1.35/", "requires_dist": null, "requires_python": "", "summary": "Salesforce API wrapper", "version": "0.1.35" }, "last_serial": 5792107, "releases": { "0.1.26": [ { "comment_text": "", "digests": { "md5": "fd7b343972e8ec11318b17a2cafa9a4e", "sha256": "911a28a578ce850635016af0c0edbd9b73114212908681cc130f821d5b1a790f" }, "downloads": -1, "filename": "salesforce-api-0.1.26.tar.gz", "has_sig": false, "md5_digest": "fd7b343972e8ec11318b17a2cafa9a4e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22112, "upload_time": "2019-02-20T11:33:35", "url": "https://files.pythonhosted.org/packages/46/c5/3033b1e4845976f71483859f6c4652c0e2391e45cba50b14f56c589b52af/salesforce-api-0.1.26.tar.gz" } ], "0.1.27": [ { "comment_text": "", "digests": { "md5": "9c1d297a0042382df24b3d4500a7a195", "sha256": "bec24631d94d62bc20f4933dc0b9e347d5ce96f0c065d871c7ab697705c1a707" }, "downloads": -1, "filename": "salesforce-api-0.1.27.tar.gz", "has_sig": false, "md5_digest": "9c1d297a0042382df24b3d4500a7a195", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22292, "upload_time": "2019-02-22T08:40:52", "url": "https://files.pythonhosted.org/packages/ee/20/3adf6214219dc0e8e7111fb35522527c64e0addd28b4de3a08e6768a4586/salesforce-api-0.1.27.tar.gz" } ], "0.1.28": [ { "comment_text": "", "digests": { "md5": "52eb26e17bdab2a441fdd9557222e240", "sha256": "473b9d307e37e00719e82f668434e0d9d442bb80c1fd1a58995c7a4cfffb75f1" }, "downloads": -1, "filename": "salesforce-api-0.1.28.tar.gz", "has_sig": false, "md5_digest": "52eb26e17bdab2a441fdd9557222e240", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 22294, "upload_time": "2019-02-28T09:51:53", "url": "https://files.pythonhosted.org/packages/68/90/31c415a0794bf6a25e6e1a4491e1275de707bd5cb9fcf9844721d5675ba2/salesforce-api-0.1.28.tar.gz" } ], "0.1.29": [ { "comment_text": "", "digests": { "md5": "76793afed74551f8ef0e06e3dbea22df", "sha256": "36fda62914f6be4d546de45cf6d19ee20808a13659ea8e4cd2145a9b66dccd7f" }, "downloads": -1, "filename": "salesforce-api-0.1.29.tar.gz", "has_sig": false, "md5_digest": "76793afed74551f8ef0e06e3dbea22df", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 26581, "upload_time": "2019-03-12T15:11:34", "url": "https://files.pythonhosted.org/packages/ae/bd/2688d764993e932cc0ec8fe3415ec635a320ee5f2a1e3ddaa7a26b19a07f/salesforce-api-0.1.29.tar.gz" } ], "0.1.30": [ { "comment_text": "", "digests": { "md5": "9a57732ddeb1ec08625b896b988ce254", "sha256": "059cf4627e68621d94bb4543c090c1022a565b03e48c477700ea4715e9e6d578" }, "downloads": -1, "filename": "salesforce-api-0.1.30.tar.gz", "has_sig": false, "md5_digest": "9a57732ddeb1ec08625b896b988ce254", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 26645, "upload_time": "2019-05-27T10:31:34", "url": "https://files.pythonhosted.org/packages/44/35/5835e4e1f95b5dccd34778c9c454eea631cd5aeccf49efb0ea5aa1160145/salesforce-api-0.1.30.tar.gz" } ], "0.1.31": [ { "comment_text": "", "digests": { "md5": "83810442f14415bcb9bac82c1cb704a7", "sha256": "68c665519b175c9e40dcbb03b1162167c63f229c6985ec1324e3674e2c861c1d" }, "downloads": -1, "filename": "salesforce-api-0.1.31.tar.gz", "has_sig": false, "md5_digest": "83810442f14415bcb9bac82c1cb704a7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 26783, "upload_time": "2019-05-27T11:04:22", "url": "https://files.pythonhosted.org/packages/38/e4/89e9b84233afe4ed66ba7ee657372af1a839bee27f0180d314863ddd238b/salesforce-api-0.1.31.tar.gz" } ], "0.1.32": [ { "comment_text": "", "digests": { "md5": "9997fb9f06c9eab1049e017aa0f7ed3f", "sha256": "683bc8afecc464a499386b05a945756cd2e854612335ff3e1727ebc6954c1004" }, "downloads": -1, "filename": "salesforce-api-0.1.32.tar.gz", "has_sig": false, "md5_digest": "9997fb9f06c9eab1049e017aa0f7ed3f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 26945, "upload_time": "2019-07-01T13:41:41", "url": "https://files.pythonhosted.org/packages/17/44/f50a6b1386c05941c90fa0d1ee56f30c9fc3da7f06f9a60576bfbae7e416/salesforce-api-0.1.32.tar.gz" } ], "0.1.34": [ { "comment_text": "", "digests": { "md5": "3895e99a560aa9aea29544fffac6cae7", "sha256": "d344d78b411d54643d245c7c4fe8c0cc4c6407f4ad2719e4edefd4c6711eae9b" }, "downloads": -1, "filename": "salesforce-api-0.1.34.tar.gz", "has_sig": false, "md5_digest": "3895e99a560aa9aea29544fffac6cae7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 27080, "upload_time": "2019-09-06T12:15:20", "url": "https://files.pythonhosted.org/packages/72/f2/374c8e8a7f009e96b41cd7a8f1fd5f603550e659de1f7eb3145f1af4b2fe/salesforce-api-0.1.34.tar.gz" } ], "0.1.35": [ { "comment_text": "", "digests": { "md5": "ab979a222f0a88f1eeb7ecea9d0066f2", "sha256": "93a633dcc31b773bd76ac178bc4d6b5e0fd09805f7a8064fe74290afd84a88b5" }, "downloads": -1, "filename": "salesforce-api-0.1.35.tar.gz", "has_sig": false, "md5_digest": "ab979a222f0a88f1eeb7ecea9d0066f2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 27075, "upload_time": "2019-09-06T12:53:41", "url": "https://files.pythonhosted.org/packages/6b/37/49581b65850a5a639aa6441d53638f4a1fd769d51d8ace5b31a0fbfade02/salesforce-api-0.1.35.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "ab979a222f0a88f1eeb7ecea9d0066f2", "sha256": "93a633dcc31b773bd76ac178bc4d6b5e0fd09805f7a8064fe74290afd84a88b5" }, "downloads": -1, "filename": "salesforce-api-0.1.35.tar.gz", "has_sig": false, "md5_digest": "ab979a222f0a88f1eeb7ecea9d0066f2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 27075, "upload_time": "2019-09-06T12:53:41", "url": "https://files.pythonhosted.org/packages/6b/37/49581b65850a5a639aa6441d53638f4a1fd769d51d8ace5b31a0fbfade02/salesforce-api-0.1.35.tar.gz" } ] }