sfdctrust 0.1.0__tar.gz
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.
- sfdctrust-0.1.0/LICENSE +21 -0
- sfdctrust-0.1.0/PKG-INFO +208 -0
- sfdctrust-0.1.0/README.md +173 -0
- sfdctrust-0.1.0/docs/API_CONTRACT.md +402 -0
- sfdctrust-0.1.0/docs/CHANGELOG.md +63 -0
- sfdctrust-0.1.0/poetry.lock +2033 -0
- sfdctrust-0.1.0/pyproject.toml +119 -0
- sfdctrust-0.1.0/src/sfdctrust/__init__.py +54 -0
- sfdctrust-0.1.0/src/sfdctrust/_async_client.py +132 -0
- sfdctrust-0.1.0/src/sfdctrust/_async_pat_refresh.py +151 -0
- sfdctrust-0.1.0/src/sfdctrust/_async_transport.py +129 -0
- sfdctrust-0.1.0/src/sfdctrust/_auth.py +96 -0
- sfdctrust-0.1.0/src/sfdctrust/_client.py +126 -0
- sfdctrust-0.1.0/src/sfdctrust/_constants.py +14 -0
- sfdctrust-0.1.0/src/sfdctrust/_exceptions.py +131 -0
- sfdctrust-0.1.0/src/sfdctrust/_pat_refresh.py +239 -0
- sfdctrust-0.1.0/src/sfdctrust/_pat_store.py +99 -0
- sfdctrust-0.1.0/src/sfdctrust/_transport.py +326 -0
- sfdctrust-0.1.0/src/sfdctrust/_version.py +84 -0
- sfdctrust-0.1.0/src/sfdctrust/integrations/__init__.py +8 -0
- sfdctrust-0.1.0/src/sfdctrust/models/__init__.py +8 -0
- sfdctrust-0.1.0/src/sfdctrust/models/_wire.py +39 -0
- sfdctrust-0.1.0/src/sfdctrust/models/events.py +228 -0
- sfdctrust-0.1.0/src/sfdctrust/models/status.py +33 -0
- sfdctrust-0.1.0/src/sfdctrust/models/tenants.py +74 -0
- sfdctrust-0.1.0/src/sfdctrust/py.typed +0 -0
- sfdctrust-0.1.0/src/sfdctrust/resources/__init__.py +8 -0
- sfdctrust-0.1.0/src/sfdctrust/resources/_async_events.py +154 -0
- sfdctrust-0.1.0/src/sfdctrust/resources/_async_status.py +29 -0
- sfdctrust-0.1.0/src/sfdctrust/resources/_async_tenants.py +94 -0
- sfdctrust-0.1.0/src/sfdctrust/resources/_requests.py +134 -0
- sfdctrust-0.1.0/src/sfdctrust/resources/events.py +228 -0
- sfdctrust-0.1.0/src/sfdctrust/resources/status.py +39 -0
- sfdctrust-0.1.0/src/sfdctrust/resources/tenants.py +115 -0
- sfdctrust-0.1.0/tests/fixtures/.gitkeep +0 -0
- sfdctrust-0.1.0/tests/unit/test_async_client.py +428 -0
- sfdctrust-0.1.0/tests/unit/test_async_pat_refresh.py +440 -0
- sfdctrust-0.1.0/tests/unit/test_auth.py +194 -0
- sfdctrust-0.1.0/tests/unit/test_client_retries.py +146 -0
- sfdctrust-0.1.0/tests/unit/test_exceptions.py +102 -0
- sfdctrust-0.1.0/tests/unit/test_pat_refresh.py +492 -0
- sfdctrust-0.1.0/tests/unit/test_read_resources.py +563 -0
- sfdctrust-0.1.0/tests/unit/test_tenants.py +241 -0
- sfdctrust-0.1.0/tests/unit/test_transport.py +336 -0
- sfdctrust-0.1.0/tests/unit/test_version.py +62 -0
sfdctrust-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 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.
|
sfdctrust-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sfdctrust
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Unofficial Python SDK for the Salesforce My Trust Center API
|
|
5
|
+
License-Expression: MIT
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Keywords: salesforce,sfdc,trust,uptime,api,rest,tooling,python
|
|
8
|
+
Author: Jeff Shurtliff
|
|
9
|
+
Author-email: jeff@shurt.us
|
|
10
|
+
Maintainer: Jeff Shurtliff
|
|
11
|
+
Maintainer-email: jeff@shurt.us
|
|
12
|
+
Requires-Python: >=3.12
|
|
13
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
14
|
+
Classifier: Intended Audience :: Information Technology
|
|
15
|
+
Classifier: Intended Audience :: System Administrators
|
|
16
|
+
Classifier: Intended Audience :: Developers
|
|
17
|
+
Classifier: Environment :: Web Environment
|
|
18
|
+
Classifier: Operating System :: OS Independent
|
|
19
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
20
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: Site Management
|
|
21
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
22
|
+
Classifier: Topic :: System :: Systems Administration
|
|
23
|
+
Classifier: Programming Language :: Python :: 3
|
|
24
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
26
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
27
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
28
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
29
|
+
Requires-Dist: httpx (>=0.28.1,<1.0.0)
|
|
30
|
+
Requires-Dist: pydantic (>=2.14.2,<3.0.0)
|
|
31
|
+
Project-URL: Issues, https://github.com/jeffshurtliff/sfdctrust/issues
|
|
32
|
+
Project-URL: Repository, https://github.com/jeffshurtliff/sfdctrust
|
|
33
|
+
Description-Content-Type: text/markdown
|
|
34
|
+
|
|
35
|
+
<p align="center">
|
|
36
|
+
<picture>
|
|
37
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/jeffshurtliff/sfdctrust/main/docs/_static/logos-dark/sfdctrust-logo-dark-320.png">
|
|
38
|
+
<img src="https://raw.githubusercontent.com/jeffshurtliff/sfdctrust/main/docs/_static/logos/sfdctrust-logo-320.png" alt="sfdctrust logo" width="200">
|
|
39
|
+
</picture>
|
|
40
|
+
</p>
|
|
41
|
+
|
|
42
|
+
# sfdctrust
|
|
43
|
+
|
|
44
|
+
An unofficial, community-maintained Python SDK project for the **Salesforce My Trust Center
|
|
45
|
+
API**. It is not affiliated with or supported by Salesforce.
|
|
46
|
+
|
|
47
|
+
The synchronous and asynchronous clients list authorized tenants, retrieve
|
|
48
|
+
status snapshots, search events, and return event timelines and tenant history
|
|
49
|
+
through their detail operations.
|
|
50
|
+
|
|
51
|
+
The API exposes only tenants authorized by the caller's personal access token (PAT);
|
|
52
|
+
empty results do not establish Salesforce-wide health.
|
|
53
|
+
|
|
54
|
+
See the [API contract and implementation decisions](https://sfdctrust.readthedocs.io/en/latest/API_CONTRACT.html) for the verified
|
|
55
|
+
operation inventory, schema notes, and authentication rules.
|
|
56
|
+
|
|
57
|
+
## Quickstart
|
|
58
|
+
|
|
59
|
+
Install from PyPI with `python -m pip install sfdctrust` on Python 3.12 or later.
|
|
60
|
+
Set `SFDCTRUST_PAT` in the process environment using a PAT from My Trust Center.
|
|
61
|
+
For installation in a virtual environment, see [Installation](https://sfdctrust.readthedocs.io/en/latest/getting-started/installation.html).
|
|
62
|
+
For creating a PAT and entering it at a hidden prompt, see
|
|
63
|
+
[Prepare to use sfdctrust](https://sfdctrust.readthedocs.io/en/latest/getting-started/setup.html).
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
from sfdctrust import TrustCenterClient
|
|
67
|
+
|
|
68
|
+
with TrustCenterClient.from_env() as client:
|
|
69
|
+
for tenant in client.tenants.iter_all(page_size=50):
|
|
70
|
+
print(tenant.id, tenant.name)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
If you use `client.tenants.list()` to fetch a single page and `page.next_page_token`
|
|
74
|
+
is set, request the next page with
|
|
75
|
+
`client.tenants.list(page_token=page.next_page_token)` inside the same context.
|
|
76
|
+
If you supplied `page_size` or `locale` on the first call, repeat those values.
|
|
77
|
+
See the [quickstart](https://sfdctrust.readthedocs.io/en/latest/getting-started/quickstart.html) and
|
|
78
|
+
[tenant reference](https://sfdctrust.readthedocs.io/en/latest/reference/tenants.html) for details.
|
|
79
|
+
|
|
80
|
+
## Use the asynchronous client
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
import asyncio
|
|
84
|
+
|
|
85
|
+
from sfdctrust import AsyncTrustCenterClient
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
async def main():
|
|
89
|
+
async with AsyncTrustCenterClient.from_env() as client:
|
|
90
|
+
snapshot = await client.status.snapshot()
|
|
91
|
+
print('Ongoing incidents', len(snapshot.ongoing.incident))
|
|
92
|
+
async for tenant in client.tenants.iter_all(page_size=50):
|
|
93
|
+
print(tenant.id, tenant.name)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
if __name__ == '__main__':
|
|
97
|
+
asyncio.run(main())
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Await single-page methods and the `list_all()` and `search_all()` collectors.
|
|
101
|
+
Consume `iter_all()` and `iter_search()` directly with `async for`.
|
|
102
|
+
Both clients use the same arguments, response models, and retry rules.
|
|
103
|
+
[Package reference](https://sfdctrust.readthedocs.io/en/latest/reference/package.html)
|
|
104
|
+
|
|
105
|
+
## Read status, search events, and inspect details
|
|
106
|
+
|
|
107
|
+
Use IDs from the tenant list, snapshot, or search results. Tenant detail
|
|
108
|
+
includes Salesforce's event history window. Event detail includes the
|
|
109
|
+
timeline when entries are available.
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
from datetime import UTC, datetime, timedelta
|
|
113
|
+
|
|
114
|
+
from sfdctrust import TrustCenterClient
|
|
115
|
+
from sfdctrust.models.events import EventSearchScope
|
|
116
|
+
|
|
117
|
+
with TrustCenterClient.from_env() as client:
|
|
118
|
+
snapshot = client.status.snapshot(locale='en-US')
|
|
119
|
+
for incident in snapshot.ongoing.incident:
|
|
120
|
+
print(incident.event_id, incident.title, list(incident.scope.tenants))
|
|
121
|
+
|
|
122
|
+
tenants = client.tenants.list()
|
|
123
|
+
if tenants.tenants:
|
|
124
|
+
tenant_id = tenants.tenants[0].id
|
|
125
|
+
end = datetime.now(UTC)
|
|
126
|
+
results = client.events.search_all(
|
|
127
|
+
scopes=[EventSearchScope(id=tenant_id)],
|
|
128
|
+
start_time=end - timedelta(days=30),
|
|
129
|
+
end_time=end,
|
|
130
|
+
event_types=['incident'],
|
|
131
|
+
page_size=50,
|
|
132
|
+
locale='en-US',
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
if results:
|
|
136
|
+
event = client.events.get(results[0].event_id, locale='en-US')
|
|
137
|
+
for entry in event.timeline or []:
|
|
138
|
+
print(entry.created_at, entry.sub_event_type, entry.message)
|
|
139
|
+
|
|
140
|
+
tenant = client.tenants.get(tenant_id, locale='en-US')
|
|
141
|
+
for event in tenant.events:
|
|
142
|
+
print(event.event_id, event.status)
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Use `client.tenants.list_all(page_size=50)` to collect tenants, or use
|
|
146
|
+
`client.events.iter_search(...)` with the same search arguments to consume
|
|
147
|
+
events lazily. Both traversals preserve order and duplicates. An empty page
|
|
148
|
+
continues when a cursor is present, including an empty string. A repeated cursor
|
|
149
|
+
or a required page beyond `max_pages` (default 1000) raises `PaginationError`
|
|
150
|
+
from `sfdctrust`. Iterators can yield items before a failure. Stale cursors raise
|
|
151
|
+
HTTP 400 `APIStatusError` without a restart.
|
|
152
|
+
|
|
153
|
+
All credential entry points default to two additional attempts per eligible read.
|
|
154
|
+
Set `max_retries=0` to disable SDK retries or choose an integer up to 5.
|
|
155
|
+
|
|
156
|
+
The search includes the start instant and excludes the end instant. Each
|
|
157
|
+
continuation repeats the original parameters and uses the token from the
|
|
158
|
+
preceding page. Salesforce's tenant history covers lifecycle overlap
|
|
159
|
+
within 365 days before or after the request time. Informational messages
|
|
160
|
+
cover the preceding 365 days. The PAT determines which tenants and events
|
|
161
|
+
are visible. An empty snapshot bucket, search page, or history establishes
|
|
162
|
+
no Salesforce-wide health claim.
|
|
163
|
+
|
|
164
|
+
See the [status and event reference](https://sfdctrust.readthedocs.io/en/latest/reference/events-and-status.html) for signatures and models.
|
|
165
|
+
|
|
166
|
+
## Rotate a PAT explicitly
|
|
167
|
+
|
|
168
|
+
For rotation, use `TrustCenterClient.from_store(store)` with a seeded,
|
|
169
|
+
caller-supplied adapter that provides durable atomic updates shared by all
|
|
170
|
+
rotators of the PAT. Call `client.refresh_pat(expires_in_days=7)` to save and
|
|
171
|
+
activate a replacement. It sends one POST and returns a secret-free
|
|
172
|
+
`PATRefreshResult`. The constructor and `from_env()` remain static credential
|
|
173
|
+
modes. See the [authentication reference](https://sfdctrust.readthedocs.io/en/latest/reference/authentication.html)
|
|
174
|
+
for the adapter contract and recovery runbook. To create and seed a working
|
|
175
|
+
local test store, follow [Prepare to use sfdctrust](https://sfdctrust.readthedocs.io/en/latest/getting-started/setup.html).
|
|
176
|
+
|
|
177
|
+
For asyncio, use `await AsyncTrustCenterClient.from_store(store)` with an
|
|
178
|
+
`AsyncPATStore`, then await rotation and any persistence recovery.
|
|
179
|
+
[Async adapter contract and cancellation recovery](https://sfdctrust.readthedocs.io/en/latest/reference/authentication.html#async-store-backed-clients)
|
|
180
|
+
|
|
181
|
+
## Development
|
|
182
|
+
|
|
183
|
+
Requires Python **3.12 or later** and Poetry **2.2 or later, below 3**.
|
|
184
|
+
From this checkout:
|
|
185
|
+
|
|
186
|
+
```sh
|
|
187
|
+
poetry install
|
|
188
|
+
poetry run pytest -q
|
|
189
|
+
poetry run ruff check .
|
|
190
|
+
poetry run ruff format --check .
|
|
191
|
+
poetry build
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
The SDK uses HTTPX and Pydantic v2. Tests run offline with synthetic PATs.
|
|
195
|
+
|
|
196
|
+
The [exception hierarchy](https://sfdctrust.readthedocs.io/en/latest/reference/exceptions.html) is available from `sfdctrust`, including
|
|
197
|
+
`ConfigurationError`, `AuthenticationError`, and the shared `TrustCenterError` base.
|
|
198
|
+
See [authentication](https://sfdctrust.readthedocs.io/en/latest/reference/authentication.html) for the implemented boundaries.
|
|
199
|
+
|
|
200
|
+
The documentation uses Sphinx with the optional `docs` dependency group:
|
|
201
|
+
|
|
202
|
+
```sh
|
|
203
|
+
poetry install --with docs
|
|
204
|
+
poetry run sphinx-build -W --keep-going -E -a -b html docs docs/_build/html
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
See [Maintain the documentation](https://sfdctrust.readthedocs.io/en/latest/maintainers/documentation.html) for details.
|
|
208
|
+
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<picture>
|
|
3
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/jeffshurtliff/sfdctrust/main/docs/_static/logos-dark/sfdctrust-logo-dark-320.png">
|
|
4
|
+
<img src="https://raw.githubusercontent.com/jeffshurtliff/sfdctrust/main/docs/_static/logos/sfdctrust-logo-320.png" alt="sfdctrust logo" width="200">
|
|
5
|
+
</picture>
|
|
6
|
+
</p>
|
|
7
|
+
|
|
8
|
+
# sfdctrust
|
|
9
|
+
|
|
10
|
+
An unofficial, community-maintained Python SDK project for the **Salesforce My Trust Center
|
|
11
|
+
API**. It is not affiliated with or supported by Salesforce.
|
|
12
|
+
|
|
13
|
+
The synchronous and asynchronous clients list authorized tenants, retrieve
|
|
14
|
+
status snapshots, search events, and return event timelines and tenant history
|
|
15
|
+
through their detail operations.
|
|
16
|
+
|
|
17
|
+
The API exposes only tenants authorized by the caller's personal access token (PAT);
|
|
18
|
+
empty results do not establish Salesforce-wide health.
|
|
19
|
+
|
|
20
|
+
See the [API contract and implementation decisions](https://sfdctrust.readthedocs.io/en/latest/API_CONTRACT.html) for the verified
|
|
21
|
+
operation inventory, schema notes, and authentication rules.
|
|
22
|
+
|
|
23
|
+
## Quickstart
|
|
24
|
+
|
|
25
|
+
Install from PyPI with `python -m pip install sfdctrust` on Python 3.12 or later.
|
|
26
|
+
Set `SFDCTRUST_PAT` in the process environment using a PAT from My Trust Center.
|
|
27
|
+
For installation in a virtual environment, see [Installation](https://sfdctrust.readthedocs.io/en/latest/getting-started/installation.html).
|
|
28
|
+
For creating a PAT and entering it at a hidden prompt, see
|
|
29
|
+
[Prepare to use sfdctrust](https://sfdctrust.readthedocs.io/en/latest/getting-started/setup.html).
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
from sfdctrust import TrustCenterClient
|
|
33
|
+
|
|
34
|
+
with TrustCenterClient.from_env() as client:
|
|
35
|
+
for tenant in client.tenants.iter_all(page_size=50):
|
|
36
|
+
print(tenant.id, tenant.name)
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
If you use `client.tenants.list()` to fetch a single page and `page.next_page_token`
|
|
40
|
+
is set, request the next page with
|
|
41
|
+
`client.tenants.list(page_token=page.next_page_token)` inside the same context.
|
|
42
|
+
If you supplied `page_size` or `locale` on the first call, repeat those values.
|
|
43
|
+
See the [quickstart](https://sfdctrust.readthedocs.io/en/latest/getting-started/quickstart.html) and
|
|
44
|
+
[tenant reference](https://sfdctrust.readthedocs.io/en/latest/reference/tenants.html) for details.
|
|
45
|
+
|
|
46
|
+
## Use the asynchronous client
|
|
47
|
+
|
|
48
|
+
```python
|
|
49
|
+
import asyncio
|
|
50
|
+
|
|
51
|
+
from sfdctrust import AsyncTrustCenterClient
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
async def main():
|
|
55
|
+
async with AsyncTrustCenterClient.from_env() as client:
|
|
56
|
+
snapshot = await client.status.snapshot()
|
|
57
|
+
print('Ongoing incidents', len(snapshot.ongoing.incident))
|
|
58
|
+
async for tenant in client.tenants.iter_all(page_size=50):
|
|
59
|
+
print(tenant.id, tenant.name)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
if __name__ == '__main__':
|
|
63
|
+
asyncio.run(main())
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Await single-page methods and the `list_all()` and `search_all()` collectors.
|
|
67
|
+
Consume `iter_all()` and `iter_search()` directly with `async for`.
|
|
68
|
+
Both clients use the same arguments, response models, and retry rules.
|
|
69
|
+
[Package reference](https://sfdctrust.readthedocs.io/en/latest/reference/package.html)
|
|
70
|
+
|
|
71
|
+
## Read status, search events, and inspect details
|
|
72
|
+
|
|
73
|
+
Use IDs from the tenant list, snapshot, or search results. Tenant detail
|
|
74
|
+
includes Salesforce's event history window. Event detail includes the
|
|
75
|
+
timeline when entries are available.
|
|
76
|
+
|
|
77
|
+
```python
|
|
78
|
+
from datetime import UTC, datetime, timedelta
|
|
79
|
+
|
|
80
|
+
from sfdctrust import TrustCenterClient
|
|
81
|
+
from sfdctrust.models.events import EventSearchScope
|
|
82
|
+
|
|
83
|
+
with TrustCenterClient.from_env() as client:
|
|
84
|
+
snapshot = client.status.snapshot(locale='en-US')
|
|
85
|
+
for incident in snapshot.ongoing.incident:
|
|
86
|
+
print(incident.event_id, incident.title, list(incident.scope.tenants))
|
|
87
|
+
|
|
88
|
+
tenants = client.tenants.list()
|
|
89
|
+
if tenants.tenants:
|
|
90
|
+
tenant_id = tenants.tenants[0].id
|
|
91
|
+
end = datetime.now(UTC)
|
|
92
|
+
results = client.events.search_all(
|
|
93
|
+
scopes=[EventSearchScope(id=tenant_id)],
|
|
94
|
+
start_time=end - timedelta(days=30),
|
|
95
|
+
end_time=end,
|
|
96
|
+
event_types=['incident'],
|
|
97
|
+
page_size=50,
|
|
98
|
+
locale='en-US',
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
if results:
|
|
102
|
+
event = client.events.get(results[0].event_id, locale='en-US')
|
|
103
|
+
for entry in event.timeline or []:
|
|
104
|
+
print(entry.created_at, entry.sub_event_type, entry.message)
|
|
105
|
+
|
|
106
|
+
tenant = client.tenants.get(tenant_id, locale='en-US')
|
|
107
|
+
for event in tenant.events:
|
|
108
|
+
print(event.event_id, event.status)
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Use `client.tenants.list_all(page_size=50)` to collect tenants, or use
|
|
112
|
+
`client.events.iter_search(...)` with the same search arguments to consume
|
|
113
|
+
events lazily. Both traversals preserve order and duplicates. An empty page
|
|
114
|
+
continues when a cursor is present, including an empty string. A repeated cursor
|
|
115
|
+
or a required page beyond `max_pages` (default 1000) raises `PaginationError`
|
|
116
|
+
from `sfdctrust`. Iterators can yield items before a failure. Stale cursors raise
|
|
117
|
+
HTTP 400 `APIStatusError` without a restart.
|
|
118
|
+
|
|
119
|
+
All credential entry points default to two additional attempts per eligible read.
|
|
120
|
+
Set `max_retries=0` to disable SDK retries or choose an integer up to 5.
|
|
121
|
+
|
|
122
|
+
The search includes the start instant and excludes the end instant. Each
|
|
123
|
+
continuation repeats the original parameters and uses the token from the
|
|
124
|
+
preceding page. Salesforce's tenant history covers lifecycle overlap
|
|
125
|
+
within 365 days before or after the request time. Informational messages
|
|
126
|
+
cover the preceding 365 days. The PAT determines which tenants and events
|
|
127
|
+
are visible. An empty snapshot bucket, search page, or history establishes
|
|
128
|
+
no Salesforce-wide health claim.
|
|
129
|
+
|
|
130
|
+
See the [status and event reference](https://sfdctrust.readthedocs.io/en/latest/reference/events-and-status.html) for signatures and models.
|
|
131
|
+
|
|
132
|
+
## Rotate a PAT explicitly
|
|
133
|
+
|
|
134
|
+
For rotation, use `TrustCenterClient.from_store(store)` with a seeded,
|
|
135
|
+
caller-supplied adapter that provides durable atomic updates shared by all
|
|
136
|
+
rotators of the PAT. Call `client.refresh_pat(expires_in_days=7)` to save and
|
|
137
|
+
activate a replacement. It sends one POST and returns a secret-free
|
|
138
|
+
`PATRefreshResult`. The constructor and `from_env()` remain static credential
|
|
139
|
+
modes. See the [authentication reference](https://sfdctrust.readthedocs.io/en/latest/reference/authentication.html)
|
|
140
|
+
for the adapter contract and recovery runbook. To create and seed a working
|
|
141
|
+
local test store, follow [Prepare to use sfdctrust](https://sfdctrust.readthedocs.io/en/latest/getting-started/setup.html).
|
|
142
|
+
|
|
143
|
+
For asyncio, use `await AsyncTrustCenterClient.from_store(store)` with an
|
|
144
|
+
`AsyncPATStore`, then await rotation and any persistence recovery.
|
|
145
|
+
[Async adapter contract and cancellation recovery](https://sfdctrust.readthedocs.io/en/latest/reference/authentication.html#async-store-backed-clients)
|
|
146
|
+
|
|
147
|
+
## Development
|
|
148
|
+
|
|
149
|
+
Requires Python **3.12 or later** and Poetry **2.2 or later, below 3**.
|
|
150
|
+
From this checkout:
|
|
151
|
+
|
|
152
|
+
```sh
|
|
153
|
+
poetry install
|
|
154
|
+
poetry run pytest -q
|
|
155
|
+
poetry run ruff check .
|
|
156
|
+
poetry run ruff format --check .
|
|
157
|
+
poetry build
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
The SDK uses HTTPX and Pydantic v2. Tests run offline with synthetic PATs.
|
|
161
|
+
|
|
162
|
+
The [exception hierarchy](https://sfdctrust.readthedocs.io/en/latest/reference/exceptions.html) is available from `sfdctrust`, including
|
|
163
|
+
`ConfigurationError`, `AuthenticationError`, and the shared `TrustCenterError` base.
|
|
164
|
+
See [authentication](https://sfdctrust.readthedocs.io/en/latest/reference/authentication.html) for the implemented boundaries.
|
|
165
|
+
|
|
166
|
+
The documentation uses Sphinx with the optional `docs` dependency group:
|
|
167
|
+
|
|
168
|
+
```sh
|
|
169
|
+
poetry install --with docs
|
|
170
|
+
poetry run sphinx-build -W --keep-going -E -a -b html docs docs/_build/html
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
See [Maintain the documentation](https://sfdctrust.readthedocs.io/en/latest/maintainers/documentation.html) for details.
|