salespyforce 1.4.0.dev0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- salespyforce/__init__.py +53 -0
- salespyforce/api.py +129 -0
- salespyforce/chatter.py +167 -0
- salespyforce/core.py +872 -0
- salespyforce/errors/__init__.py +12 -0
- salespyforce/errors/exceptions.py +389 -0
- salespyforce/errors/handlers.py +15 -0
- salespyforce/knowledge.py +531 -0
- salespyforce/utils/__init__.py +10 -0
- salespyforce/utils/core_utils.py +152 -0
- salespyforce/utils/helper.py +140 -0
- salespyforce/utils/log_utils.py +264 -0
- salespyforce/utils/tests/__init__.py +8 -0
- salespyforce/utils/tests/resources.py +157 -0
- salespyforce/utils/tests/test_instantiate_object.py +49 -0
- salespyforce/utils/tests/test_sobjects.py +58 -0
- salespyforce/utils/tests/test_soql.py +23 -0
- salespyforce/utils/tests/test_sosl.py +29 -0
- salespyforce/utils/version.py +52 -0
- salespyforce-1.4.0.dev0.dist-info/LICENSE +21 -0
- salespyforce-1.4.0.dev0.dist-info/METADATA +253 -0
- salespyforce-1.4.0.dev0.dist-info/RECORD +23 -0
- salespyforce-1.4.0.dev0.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
:Module: salespyforce.utils.tests.resources
|
|
4
|
+
:Synopsis: Frequently used resources for performing unit testing
|
|
5
|
+
:Usage: ``from salespyforce.utils.tests import resources``
|
|
6
|
+
:Example: ``exceptions = resources.import_exceptions_module()``
|
|
7
|
+
:Created By: Jeff Shurtliff
|
|
8
|
+
:Last Modified: Jeff Shurtliff
|
|
9
|
+
:Modified Date: 14 Nov 2025
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
import os
|
|
13
|
+
import sys
|
|
14
|
+
import importlib
|
|
15
|
+
|
|
16
|
+
import pytest
|
|
17
|
+
|
|
18
|
+
# Define constants
|
|
19
|
+
SKIP_LOCAL_TEST_MSG = 'skipping local-only tests'
|
|
20
|
+
HELPER_FILE_NAME = 'helper_dm_conn.yml'
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class MockResponse:
|
|
24
|
+
"""This class simulates an API response for testing purposes.
|
|
25
|
+
|
|
26
|
+
.. versionadded:: 1.1.0
|
|
27
|
+
"""
|
|
28
|
+
def __init__(self, json_body, status_code=200):
|
|
29
|
+
self.json_body = json_body
|
|
30
|
+
self.status_code = status_code
|
|
31
|
+
|
|
32
|
+
def json(self):
|
|
33
|
+
return self.json_body
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def mock_success_post(*args, **kwargs):
|
|
37
|
+
"""This function works with the `MockedResponse` class to simulate a successful API response.
|
|
38
|
+
|
|
39
|
+
.. versionadded:: 1.1.0
|
|
40
|
+
"""
|
|
41
|
+
return MockResponse({
|
|
42
|
+
"id": "001D000000IqhSLIAZ",
|
|
43
|
+
"errors": [],
|
|
44
|
+
"success": True
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def mock_error_post(*args, **kwargs):
|
|
49
|
+
"""This function works with the `MockedResponse` class to simulate a failed API response.
|
|
50
|
+
|
|
51
|
+
.. versionadded:: 1.1.0
|
|
52
|
+
"""
|
|
53
|
+
return MockResponse({
|
|
54
|
+
"errors": [],
|
|
55
|
+
"success": False
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def mock_sosl_get(*args, **kwargs):
|
|
60
|
+
"""This function works with the `MockedResponse` class to simulate an SOSL response."""
|
|
61
|
+
return MockResponse({
|
|
62
|
+
"searchRecords": [
|
|
63
|
+
{
|
|
64
|
+
'attributes': {
|
|
65
|
+
'type': 'Account',
|
|
66
|
+
'url': '/services/data/v57.0/sobjects/Account/0018V00002NeqAxQAJ'
|
|
67
|
+
},
|
|
68
|
+
'Id': '0018V00002NeqAxQAJ'
|
|
69
|
+
}
|
|
70
|
+
]
|
|
71
|
+
})
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def set_package_path():
|
|
75
|
+
"""This function adds the high-level salespyforce directory to the sys.path list.
|
|
76
|
+
|
|
77
|
+
.. versionadded:: 1.1.0
|
|
78
|
+
"""
|
|
79
|
+
sys.path.insert(0, os.path.abspath('../..'))
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def import_modules(*modules):
|
|
83
|
+
"""This function imports and returns one or more modules to utilize in a unit test.
|
|
84
|
+
|
|
85
|
+
.. versionadded:: 1.1.0
|
|
86
|
+
|
|
87
|
+
:param modules: One or more module paths (absolute) in string format
|
|
88
|
+
:returns: The imported module(s) as an individual object or a tuple of objects
|
|
89
|
+
"""
|
|
90
|
+
imported_modules = []
|
|
91
|
+
for module in modules:
|
|
92
|
+
imported_modules.append(importlib.import_module(module))
|
|
93
|
+
tuple(imported_modules)
|
|
94
|
+
return imported_modules if len(imported_modules) > 1 else imported_modules[0]
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def secrets_helper_exists():
|
|
98
|
+
"""This function checks to see if the unencrypted helper file exists for GitHub Actions.
|
|
99
|
+
|
|
100
|
+
.. versionadded:: 1.1.0
|
|
101
|
+
"""
|
|
102
|
+
helper_path = f'{os.environ.get("HOME")}/secrets/{HELPER_FILE_NAME}'
|
|
103
|
+
return os.path.isfile(helper_path)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def local_helper_exists():
|
|
107
|
+
"""This function checks to see if a helper file is present in the ``local/`` directory.
|
|
108
|
+
|
|
109
|
+
.. versionadded:: 1.1.0
|
|
110
|
+
"""
|
|
111
|
+
return os.path.exists(f'local/{HELPER_FILE_NAME}')
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def get_core_object():
|
|
115
|
+
"""This function instantiates and returns the core object using a local helper file.
|
|
116
|
+
|
|
117
|
+
.. versionadded:: 1.1.0
|
|
118
|
+
"""
|
|
119
|
+
set_package_path()
|
|
120
|
+
if secrets_helper_exists():
|
|
121
|
+
sfdc_object = instantiate_with_secrets_helper()
|
|
122
|
+
else:
|
|
123
|
+
if not local_helper_exists():
|
|
124
|
+
pytest.skip('skipping tests where a valid helper file is needed')
|
|
125
|
+
sfdc_object = instantiate_with_local_helper()
|
|
126
|
+
return sfdc_object
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def instantiate_with_secrets_helper():
|
|
130
|
+
"""This function instantiates the Salesforce object using the unencrypted helper file intended for GitHub Actions.
|
|
131
|
+
|
|
132
|
+
.. versionadded:: 1.1.0
|
|
133
|
+
|
|
134
|
+
:returns: The instantiated :py:class:`salespyforce.core.Salesforce` object
|
|
135
|
+
:raises: :py:exc:`FileNotFoundError`
|
|
136
|
+
"""
|
|
137
|
+
if not secrets_helper_exists():
|
|
138
|
+
raise FileNotFoundError('The unencrypted GitHub Actions helper file cannot be found.')
|
|
139
|
+
file_name = f'{os.environ.get("HOME")}/secrets/{HELPER_FILE_NAME}'
|
|
140
|
+
set_package_path()
|
|
141
|
+
core_module = importlib.import_module('salespyforce.core')
|
|
142
|
+
return core_module.Salesforce(helper=file_name)
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def instantiate_with_local_helper():
|
|
146
|
+
"""This function instantiates the Salesforce object using a local helper file for unit testing.
|
|
147
|
+
|
|
148
|
+
.. versionadded:: 1.1.0
|
|
149
|
+
|
|
150
|
+
:returns: The instantiated :py:class:`salespyforce.core.Salesforce` object
|
|
151
|
+
:raises: :py:exc:`FileNotFoundError`
|
|
152
|
+
"""
|
|
153
|
+
if not local_helper_exists():
|
|
154
|
+
raise FileNotFoundError('The local helper file cannot be found.')
|
|
155
|
+
set_package_path()
|
|
156
|
+
core_module = importlib.import_module('salespyforce.core')
|
|
157
|
+
return core_module.Salesforce(helper=f"local/{HELPER_FILE_NAME}")
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
:Module: salespyforce.utils.tests.test_instantiate_object
|
|
4
|
+
:Synopsis: This module is used by pytest to test instantiating the core object
|
|
5
|
+
:Created By: Jeff Shurtliff
|
|
6
|
+
:Last Modified: Jeff Shurtliff
|
|
7
|
+
:Modified Date: 29 May 2023
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from . import resources
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def test_instantiate_core_object():
|
|
14
|
+
"""This function tests the ability to instantiate the core object.
|
|
15
|
+
|
|
16
|
+
.. versionadded:: 1.1.0
|
|
17
|
+
"""
|
|
18
|
+
sfdc_object = resources.get_core_object()
|
|
19
|
+
assert 'force.com' in sfdc_object.base_url
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def test_get_api_versions():
|
|
23
|
+
"""This function tests the get_api_versions() method in the core object.
|
|
24
|
+
|
|
25
|
+
.. versionadded:: 1.1.0
|
|
26
|
+
"""
|
|
27
|
+
sfdc_object = resources.get_core_object()
|
|
28
|
+
api_versions = sfdc_object.get_api_versions()
|
|
29
|
+
assert isinstance(api_versions, list) and 'version' in api_versions[0]
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def test_get_rest_resources():
|
|
33
|
+
"""This function tests the get_rest_resources() method in the core object.
|
|
34
|
+
|
|
35
|
+
.. versionadded:: 1.1.0
|
|
36
|
+
"""
|
|
37
|
+
sfdc_object = resources.get_core_object()
|
|
38
|
+
rest_resources = sfdc_object.get_rest_resources()
|
|
39
|
+
assert 'metadata' in rest_resources
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def test_get_org_limits():
|
|
43
|
+
"""This function tests the get_org_limits() method in the core object.
|
|
44
|
+
|
|
45
|
+
.. versionadded:: 1.1.0
|
|
46
|
+
"""
|
|
47
|
+
sfdc_object = resources.get_core_object()
|
|
48
|
+
org_limits = sfdc_object.get_org_limits()
|
|
49
|
+
assert 'DailyApiRequests' in org_limits
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
:Module: salespyforce.utils.tests.test_sobjects
|
|
4
|
+
:Synopsis: This module is used by pytest to test basic sObject-related methods
|
|
5
|
+
:Created By: Jeff Shurtliff
|
|
6
|
+
:Last Modified: Jeff Shurtliff
|
|
7
|
+
:Modified Date: 29 May 2023
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import requests
|
|
11
|
+
|
|
12
|
+
from . import resources
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def test_get_all_sobjects():
|
|
16
|
+
"""This function tests the get_all_sobjects() method in the core object.
|
|
17
|
+
|
|
18
|
+
.. versionadded:: 1.1.0
|
|
19
|
+
"""
|
|
20
|
+
sfdc_object = resources.get_core_object()
|
|
21
|
+
all_sobjects = sfdc_object.get_all_sobjects()
|
|
22
|
+
assert 'sobjects' in all_sobjects
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def test_get_and_describe_sobject():
|
|
26
|
+
"""This function tests the get_sobject() and describe_object() methods in the core object.
|
|
27
|
+
|
|
28
|
+
.. versionadded:: 1.1.0
|
|
29
|
+
"""
|
|
30
|
+
# Instantiate the core object
|
|
31
|
+
sfdc_object = resources.get_core_object()
|
|
32
|
+
|
|
33
|
+
# Test the default query (non-describe)
|
|
34
|
+
account_sobject = sfdc_object.get_sobject('Account')
|
|
35
|
+
assert 'objectDescribe' in account_sobject
|
|
36
|
+
|
|
37
|
+
# Test with describe enabled
|
|
38
|
+
account_sobject_describe = sfdc_object.get_sobject('Account', describe=True)
|
|
39
|
+
assert 'activateable' in account_sobject_describe
|
|
40
|
+
|
|
41
|
+
# Test the describe_object() method
|
|
42
|
+
account_describe = sfdc_object.describe_object('Account')
|
|
43
|
+
assert 'activateable' in account_describe
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def test_create_record(monkeypatch):
|
|
47
|
+
# Instantiate the core object
|
|
48
|
+
sfdc_object = resources.get_core_object()
|
|
49
|
+
|
|
50
|
+
# Overwrite the requests.post functionality with the mock_success_post() function
|
|
51
|
+
monkeypatch.setattr(requests, 'post', resources.mock_success_post)
|
|
52
|
+
|
|
53
|
+
# Perform the mock API call
|
|
54
|
+
payload = {
|
|
55
|
+
"Name": "Express Logistics and Transport"
|
|
56
|
+
}
|
|
57
|
+
response = sfdc_object.create_sobject_record('Account', payload)
|
|
58
|
+
assert 'success' in response and response.get('success') is True and 'id' in response
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
:Module: salespyforce.utils.tests.test_sobjects
|
|
4
|
+
:Synopsis: This module is used by pytest to test performing SOQL queries
|
|
5
|
+
:Created By: Jeff Shurtliff
|
|
6
|
+
:Last Modified: Jeff Shurtliff
|
|
7
|
+
:Modified Date: 29 May 2023
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from . import resources
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def test_soql_query():
|
|
14
|
+
"""This function tests the ability to perform a SOQL query.
|
|
15
|
+
|
|
16
|
+
.. versionadded:: 1.1.0
|
|
17
|
+
"""
|
|
18
|
+
sfdc_object = resources.get_core_object()
|
|
19
|
+
soql_statement = 'SELECT Id FROM Account LIMIT 1'
|
|
20
|
+
soql_response = sfdc_object.soql_query(soql_statement)
|
|
21
|
+
assert 'done' in soql_response and soql_response.get('done') is True
|
|
22
|
+
assert 'totalSize' in soql_response and 'records' in soql_response
|
|
23
|
+
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
:Module: salespyforce.utils.tests.test_sobjects
|
|
4
|
+
:Synopsis: This module is used by pytest to test performing SOQL queries
|
|
5
|
+
:Created By: Jeff Shurtliff
|
|
6
|
+
:Last Modified: Jeff Shurtliff
|
|
7
|
+
:Modified Date: 29 May 2023
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import requests
|
|
11
|
+
|
|
12
|
+
from . import resources
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def test_search_string(monkeypatch):
|
|
16
|
+
"""This function tests the ability to search for a string using an SOSL query.
|
|
17
|
+
|
|
18
|
+
.. versionadded:: 1.1.0
|
|
19
|
+
"""
|
|
20
|
+
# Instantiate the core object
|
|
21
|
+
sfdc_object = resources.get_core_object()
|
|
22
|
+
|
|
23
|
+
# Overwrite the requests.post functionality with the mock_success_post() function
|
|
24
|
+
monkeypatch.setattr(requests, 'get', resources.mock_sosl_get)
|
|
25
|
+
|
|
26
|
+
# Perform the mock API call
|
|
27
|
+
result = sfdc_object.search_string('Account')
|
|
28
|
+
assert 'searchRecords' in result
|
|
29
|
+
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
:Module: salespyforce.utils.version
|
|
4
|
+
:Synopsis: Utilities for working with the package version.
|
|
5
|
+
:Created By: Jeff Shurtliff
|
|
6
|
+
:Last Modified: Jeff Shurtliff
|
|
7
|
+
:Modified Date: 17 Nov 2025
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from importlib.metadata import version, PackageNotFoundError
|
|
11
|
+
|
|
12
|
+
from . import log_utils
|
|
13
|
+
|
|
14
|
+
# Initialize logging
|
|
15
|
+
logger = log_utils.initialize_logging(__name__)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def get_full_version() -> str:
|
|
19
|
+
"""This function returns the current full version of the ``salespyforce`` package.
|
|
20
|
+
|
|
21
|
+
.. version-changed:: 1.4.0
|
|
22
|
+
The function now retrieves the version from the package metadata,
|
|
23
|
+
rather than from the ``__version__`` special variable.
|
|
24
|
+
|
|
25
|
+
Retrieves the package version from the installed package metadata, which is
|
|
26
|
+
populated from the ``version`` field in ``pyproject.toml``.
|
|
27
|
+
"""
|
|
28
|
+
try:
|
|
29
|
+
return version('salespyforce')
|
|
30
|
+
except PackageNotFoundError:
|
|
31
|
+
# This can happen if the package is not installed in the environment.
|
|
32
|
+
# (e.g. running from a source checkout without an editable install)
|
|
33
|
+
logger.warning("salespyforce is not installed; falling back to '0.0.0' as version")
|
|
34
|
+
return '0.0.0'
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def get_major_minor_version() -> str:
|
|
38
|
+
"""Return the current major.minor (i.e., X.Y) version of the package.
|
|
39
|
+
|
|
40
|
+
.. version-changed:: 1.4.0
|
|
41
|
+
The function utilizes the :py:func:`salespyforce.utils.version.get_full_version`
|
|
42
|
+
function to get the package version rather than using ``__version__``.
|
|
43
|
+
"""
|
|
44
|
+
full_version = get_full_version()
|
|
45
|
+
parts = full_version.split(".")
|
|
46
|
+
if len(parts) >= 2:
|
|
47
|
+
return ".".join(parts[:2])
|
|
48
|
+
return full_version
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
# Define __version__ for backward compatibility and to utilize as needed
|
|
52
|
+
__version__ = get_full_version()
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2023 Jeff Shurtliff
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: salespyforce
|
|
3
|
+
Version: 1.4.0.dev0
|
|
4
|
+
Summary: A Python toolset for performing Salesforce API calls
|
|
5
|
+
License: MIT License
|
|
6
|
+
|
|
7
|
+
Copyright (c) 2023 Jeff Shurtliff
|
|
8
|
+
|
|
9
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
10
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
11
|
+
in the Software without restriction, including without limitation the rights
|
|
12
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
13
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
14
|
+
furnished to do so, subject to the following conditions:
|
|
15
|
+
|
|
16
|
+
The above copyright notice and this permission notice shall be included in all
|
|
17
|
+
copies or substantial portions of the Software.
|
|
18
|
+
|
|
19
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
20
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
21
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
22
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
23
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
24
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
25
|
+
SOFTWARE.
|
|
26
|
+
Keywords: salesforce,sfdc,api,rest,tooling,python
|
|
27
|
+
Author: Jeff Shurtliff
|
|
28
|
+
Author-email: jeffshurtliff@gmail.com
|
|
29
|
+
Requires-Python: >=3.9,<4.0
|
|
30
|
+
Classifier: Development Status :: 4 - Beta
|
|
31
|
+
Classifier: Intended Audience :: Developers
|
|
32
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
33
|
+
Classifier: Programming Language :: Python :: 3
|
|
34
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
35
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
36
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
37
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
38
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
39
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
40
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
41
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
42
|
+
Requires-Dist: PyYAML (>=6.0.3,<7)
|
|
43
|
+
Requires-Dist: requests (>=2.32.5)
|
|
44
|
+
Project-URL: Documentation, https://salespyforce.readthedocs.io/en/latest/
|
|
45
|
+
Project-URL: Homepage, https://github.com/jeffshurtliff/salespyforce
|
|
46
|
+
Project-URL: Issue Tracker, https://github.com/jeffshurtliff/salespyforce/issues
|
|
47
|
+
Project-URL: Repository, https://github.com/jeffshurtliff/salespyforce
|
|
48
|
+
Description-Content-Type: text/markdown
|
|
49
|
+
|
|
50
|
+
# salespyforce
|
|
51
|
+
A Python toolset for performing Salesforce API calls
|
|
52
|
+
|
|
53
|
+
<table>
|
|
54
|
+
<tr>
|
|
55
|
+
<td>Latest Stable Release</td>
|
|
56
|
+
<td>
|
|
57
|
+
<a href='https://pypi.org/project/salespyforce/'>
|
|
58
|
+
<img alt="PyPI" src="https://img.shields.io/pypi/v/salespyforce">
|
|
59
|
+
</a>
|
|
60
|
+
</td>
|
|
61
|
+
</tr>
|
|
62
|
+
<tr>
|
|
63
|
+
<td>Latest Beta/RC Release</td>
|
|
64
|
+
<td>
|
|
65
|
+
<a href='https://pypi.org/project/salespyforce/#history'>
|
|
66
|
+
<img alt="PyPI" src="https://img.shields.io/badge/pypi-1.3.0rc3-blue">
|
|
67
|
+
</a>
|
|
68
|
+
</td>
|
|
69
|
+
</tr>
|
|
70
|
+
<tr>
|
|
71
|
+
<td>Build Status</td>
|
|
72
|
+
<td>
|
|
73
|
+
<a href="https://github.com/jeffshurtliff/salespyforce/blob/master/.github/workflows/pythonpackage.yml">
|
|
74
|
+
<img alt="GitHub Workflow Status"
|
|
75
|
+
src="https://img.shields.io/github/actions/workflow/status/jeffshurtliff/salespyforce/pythonpackage.yml?branch=master">
|
|
76
|
+
</a>
|
|
77
|
+
</td>
|
|
78
|
+
</tr>
|
|
79
|
+
<tr>
|
|
80
|
+
<td>Supported Versions</td>
|
|
81
|
+
<td>
|
|
82
|
+
<a href='https://pypi.org/project/salespyforce/'>
|
|
83
|
+
<img alt="PyPI - Python Version" src="https://img.shields.io/pypi/pyversions/salespyforce">
|
|
84
|
+
</a>
|
|
85
|
+
</td>
|
|
86
|
+
</tr>
|
|
87
|
+
<tr>
|
|
88
|
+
<td>Code Coverage</td>
|
|
89
|
+
<td>
|
|
90
|
+
<a href="https://codecov.io/gh/jeffshurtliff/salespyforce">
|
|
91
|
+
<img src="https://codecov.io/gh/jeffshurtliff/salespyforce/branch/master/graph/badge.svg" />
|
|
92
|
+
</a>
|
|
93
|
+
</td>
|
|
94
|
+
</tr>
|
|
95
|
+
<tr>
|
|
96
|
+
<td>Documentation</td>
|
|
97
|
+
<td>
|
|
98
|
+
<a href='https://salespyforce.readthedocs.io/en/latest/?badge=latest'>
|
|
99
|
+
<img src='https://readthedocs.org/projects/salespyforce/badge/?version=latest' alt='Documentation Status' />
|
|
100
|
+
</a>
|
|
101
|
+
</td>
|
|
102
|
+
</tr>
|
|
103
|
+
<tr>
|
|
104
|
+
<td>Security Audits</td>
|
|
105
|
+
<td>
|
|
106
|
+
<a href="https://github.com/marketplace/actions/python-security-check-using-bandit">
|
|
107
|
+
<img alt="Bandit" src="https://img.shields.io/badge/security-bandit-yellow.svg">
|
|
108
|
+
</a>
|
|
109
|
+
</td>
|
|
110
|
+
</tr>
|
|
111
|
+
<tr>
|
|
112
|
+
<td>License</td>
|
|
113
|
+
<td>
|
|
114
|
+
<a href="https://github.com/jeffshurtliff/salespyforce/blob/master/LICENSE">
|
|
115
|
+
<img alt="License (GitHub)" src="https://img.shields.io/github/license/jeffshurtliff/salespyforce">
|
|
116
|
+
</a>
|
|
117
|
+
</td>
|
|
118
|
+
</tr>
|
|
119
|
+
<tr>
|
|
120
|
+
<td style="vertical-align: top;">Issues</td>
|
|
121
|
+
<td>
|
|
122
|
+
<a href="https://github.com/jeffshurtliff/salespyforce/issues">
|
|
123
|
+
<img style="margin-bottom:5px;" alt="GitHub open issues" src="https://img.shields.io/github/issues-raw/jeffshurtliff/salespyforce"><br />
|
|
124
|
+
</a>
|
|
125
|
+
<a href="https://github.com/jeffshurtliff/salespyforce/issues">
|
|
126
|
+
<img alt="GitHub closed issues" src="https://img.shields.io/github/issues-closed-raw/jeffshurtliff/salespyforce">
|
|
127
|
+
</a>
|
|
128
|
+
</td>
|
|
129
|
+
</tr>
|
|
130
|
+
<tr>
|
|
131
|
+
<td style="vertical-align: top;">Pull Requests</td>
|
|
132
|
+
<td>
|
|
133
|
+
<a href="https://github.com/jeffshurtliff/salespyforce/pulls">
|
|
134
|
+
<img style="margin-bottom:5px;" alt="GitHub pull open requests" src="https://img.shields.io/github/issues-pr-raw/jeffshurtliff/salespyforce"><br />
|
|
135
|
+
</a>
|
|
136
|
+
<a href="https://github.com/jeffshurtliff/salespyforce/pulls">
|
|
137
|
+
<img alt="GitHub closed pull requests" src="https://img.shields.io/github/issues-pr-closed-raw/jeffshurtliff/salespyforce">
|
|
138
|
+
</a>
|
|
139
|
+
</td>
|
|
140
|
+
</tr>
|
|
141
|
+
</table>
|
|
142
|
+
|
|
143
|
+
## Installation
|
|
144
|
+
The package can be installed via pip using the syntax below.
|
|
145
|
+
|
|
146
|
+
```sh
|
|
147
|
+
pip install salespyforce --upgrade
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
You may also clone the repository and install from source using below.
|
|
151
|
+
|
|
152
|
+
```sh
|
|
153
|
+
git clone git://github.com/jeffshurtliff/salespyforce.git
|
|
154
|
+
cd salespyforce/
|
|
155
|
+
python setup.py install
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Change Log
|
|
159
|
+
The change log can be found in the [documentation](https://salespyforce.readthedocs.io/en/latest/changelog.html).
|
|
160
|
+
|
|
161
|
+
## Usage
|
|
162
|
+
This section provides basic usage instructions for the package.
|
|
163
|
+
|
|
164
|
+
### Importing the package
|
|
165
|
+
Rather than importing the base package, it is recommended that you import the primary `Salesforce` class using the
|
|
166
|
+
syntax below.
|
|
167
|
+
|
|
168
|
+
```python
|
|
169
|
+
from salespyforce import Salesforce
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Initializing a Salesforce object instance
|
|
173
|
+
The primary `Salesforce` object serves many purposes, the most important being to establish a connection to the
|
|
174
|
+
Salesforce environment with which you intend to interact. As such, when initializing an instance of the `Salesforce`
|
|
175
|
+
object, you will need to pass it the following information:
|
|
176
|
+
* The username and password of the API user
|
|
177
|
+
* The Organization ID of the Salesforce environment
|
|
178
|
+
* The Base URL and Endpoint URL
|
|
179
|
+
* The client ID, client secret, and security token
|
|
180
|
+
|
|
181
|
+
The `Salesforce` object can be initiated in two different ways:
|
|
182
|
+
* Passing the information directly into the object
|
|
183
|
+
* Leveraging a "helper" configuration file
|
|
184
|
+
|
|
185
|
+
#### Passing the information directly into the object
|
|
186
|
+
The environment and connection information can be passed directly into the `Salesforce` object when initializing it,
|
|
187
|
+
as demonstrated in the example below.
|
|
188
|
+
|
|
189
|
+
```python
|
|
190
|
+
sfdc = Salesforce(
|
|
191
|
+
username='admin.user@example.com',
|
|
192
|
+
password='example123',
|
|
193
|
+
org_id='4DJ000000CeMFYA0',
|
|
194
|
+
base_url='https://example-dev-ed.lightning.force.com/',
|
|
195
|
+
endpoint_url='https://example-dev-ed.my.salesforce.com/services/oauth2/token',
|
|
196
|
+
client_id='3MVG9gTv.DiE8cKRIpEtSN_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX_TAoy1Zk_AKGukbqa4KbhM6nVYVUu6md',
|
|
197
|
+
client_secret='7536F4A7865559XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX53797BEA88174713CC3C',
|
|
198
|
+
security_token='2muXaXXXXXXXXXXXXXXXoVKxz'
|
|
199
|
+
)
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
#### Leveraging a "helper" configuration file
|
|
203
|
+
As an alternative to passing the connection information to the `Salesforce` class in the way demonstrated above, a
|
|
204
|
+
"helper" configuration file in `yaml` or `json` format can be leveraged instead and passed to the `Salesforce` class
|
|
205
|
+
when initializing the object.
|
|
206
|
+
|
|
207
|
+
This is an example of how the configuration file would be written in YAML format:
|
|
208
|
+
|
|
209
|
+
```yaml
|
|
210
|
+
# Helper configuration file for the SalesPyForce package
|
|
211
|
+
|
|
212
|
+
# Define how to obtain the connection information
|
|
213
|
+
connection:
|
|
214
|
+
# Define the credentials
|
|
215
|
+
username: admin.user@example.com
|
|
216
|
+
password: example123
|
|
217
|
+
|
|
218
|
+
# Define the org information
|
|
219
|
+
org_id: 4DJ000000CeMFYA0
|
|
220
|
+
base_url: https://example-dev-ed.lightning.force.com/
|
|
221
|
+
endpoint_url: https://example-dev-ed.my.salesforce.com/services/oauth2/token
|
|
222
|
+
|
|
223
|
+
# Define the API connection info
|
|
224
|
+
client_key: 3MVG9gTv.DiE8cKRIpEtSN_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX_TAoy1Zk_AKGukbqa4KbhM6nVYVUu6md
|
|
225
|
+
client_secret: 7536F4A7865559XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX53797BEA88174713CC3C
|
|
226
|
+
security_token: 2muXaXXXXXXXXXXXXXXXoVKxz
|
|
227
|
+
|
|
228
|
+
# Define if SSL certificates should be verified when making API calls
|
|
229
|
+
ssl_verify: yes
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
The file can then be referenced using the `helper` argument when initializing the object instance, as shown below.
|
|
233
|
+
|
|
234
|
+
```python
|
|
235
|
+
HELPER_FILE = '/path/to/helper.yml'
|
|
236
|
+
sfdc = Salesforce(helper=HELPER_FILE)
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## Documentation
|
|
240
|
+
The documentation is located here: [https://salespyforce.readthedocs.io/en/latest/](https://salespyforce.readthedocs.io/en/latest/)
|
|
241
|
+
|
|
242
|
+
## License
|
|
243
|
+
[MIT License](https://github.com/jeffshurtliff/salespyforce/blob/master/LICENSE)
|
|
244
|
+
|
|
245
|
+
## Reporting Issues
|
|
246
|
+
Issues can be reported within the [GitHub repository](https://github.com/jeffshurtliff/salespyforce/issues).
|
|
247
|
+
|
|
248
|
+
## Donations
|
|
249
|
+
If you would like to donate to this project then you can do so using [this PayPal link](https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=XDZ8M6UV6EFK6&item_name=SalesPyForce+Python+API¤cy_code=USD).
|
|
250
|
+
|
|
251
|
+
## Disclaimer
|
|
252
|
+
This package is considered unofficial and is in no way endorsed or supported by [Salesforce Inc](https://www.salesforce.com).
|
|
253
|
+
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
salespyforce/__init__.py,sha256=W2RY2_kojLcXtTHJrto5FtU6q1umVPaU1RZe_QkFgNY,2031
|
|
2
|
+
salespyforce/api.py,sha256=JoqYyOo7Psx-l-bEC7iFdFfQVziIkqINcOKOnlpa_jM,5763
|
|
3
|
+
salespyforce/chatter.py,sha256=GI9iXmq2mrbrH7daW8Kc3gt2O04dRthSVocJq4BVwCU,7494
|
|
4
|
+
salespyforce/core.py,sha256=OPn5TsY9oCjg_jtEFWCq3yQz4-B7pTeYKsSGOtfo8yI,49148
|
|
5
|
+
salespyforce/errors/__init__.py,sha256=Tnl4lB2ycpK2UmwmoBoSYuWDtovDNA4CxC5Cku2hDYs,320
|
|
6
|
+
salespyforce/errors/exceptions.py,sha256=6ATDNCPNXnjOzXcaaLZVUy39lsFt2Se5cCvqkd_8faM,17057
|
|
7
|
+
salespyforce/errors/handlers.py,sha256=8Hp-WrpYooMlC7cuuowTkOFyBH8OQFfHKmB8XxDPlyk,479
|
|
8
|
+
salespyforce/knowledge.py,sha256=YCUbVDr8n23mdUzeuqlNToHIaaD9mzcSZ5Rvr_J8kAw,24770
|
|
9
|
+
salespyforce/utils/__init__.py,sha256=ATE6BsWd2qDxsy1fQpvaoSJimZgfCmNPYpcFEucES6Q,292
|
|
10
|
+
salespyforce/utils/core_utils.py,sha256=ESuQVb8L00KoP56_nAKTj3i09u_6BqK0MxJtYV5QbwI,5674
|
|
11
|
+
salespyforce/utils/helper.py,sha256=zwbysqwddWwhp3mfzKJf0aeTTkVqoR35L9dLu6ZVJtU,5661
|
|
12
|
+
salespyforce/utils/log_utils.py,sha256=085OBfJNxwJSjE3lQzmixjsK1s9akGvYG_kJpUPvDJ4,11799
|
|
13
|
+
salespyforce/utils/tests/__init__.py,sha256=Iv7M9gPyKv5f5tR-pxc089cd2nrWn5M0ZZpWqiB2htc,242
|
|
14
|
+
salespyforce/utils/tests/resources.py,sha256=-PEqzLMsEQSVj3dz_8VTHXINbSeMvmjX3gZRMTJgoac,4774
|
|
15
|
+
salespyforce/utils/tests/test_instantiate_object.py,sha256=vxeXuzJ3OJrGlNFM4gOUfsifefRkr4tDUoElC90a0uo,1422
|
|
16
|
+
salespyforce/utils/tests/test_sobjects.py,sha256=H_drUPsopu6y0nAxHZkZD1PAP5pd5jE15hqwC0qdDso,1846
|
|
17
|
+
salespyforce/utils/tests/test_soql.py,sha256=xSVNuJo7U4vNqWXGbw2ue66p7-RQ-PuBlql1vkddl3M,715
|
|
18
|
+
salespyforce/utils/tests/test_sosl.py,sha256=tKKirOtDFmROMGvMsPuG1cM603zQIeXXJHVgWYXOqYw,815
|
|
19
|
+
salespyforce/utils/version.py,sha256=uEWnq3DHmN9wZVohiRCRE1KzNF1XVhP4oVY4vBBgoVU,1781
|
|
20
|
+
salespyforce-1.4.0.dev0.dist-info/LICENSE,sha256=b_Ch0pvcZN6Mr4dQ9Bo3It-J3MihQYcj_-EIdaZHuWw,1071
|
|
21
|
+
salespyforce-1.4.0.dev0.dist-info/METADATA,sha256=H5ENENMftGOHZAvC2BQUEJ02SEqTwU1WgErPbSdKvGg,10346
|
|
22
|
+
salespyforce-1.4.0.dev0.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
23
|
+
salespyforce-1.4.0.dev0.dist-info/RECORD,,
|