sg-python-api 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.
- sg_python_api-0.1.0/.gitignore +52 -0
- sg_python_api-0.1.0/COMPATIBILITY.md +290 -0
- sg_python_api-0.1.0/LICENSE +21 -0
- sg_python_api-0.1.0/Makefile +89 -0
- sg_python_api-0.1.0/PKG-INFO +177 -0
- sg_python_api-0.1.0/README.md +153 -0
- sg_python_api-0.1.0/docs/benchmarks.md +115 -0
- sg_python_api-0.1.0/docs/development.md +204 -0
- sg_python_api-0.1.0/docs/migration-guide.md +93 -0
- sg_python_api-0.1.0/docs/testing.md +119 -0
- sg_python_api-0.1.0/examples/async_client.py +116 -0
- sg_python_api-0.1.0/examples/sync_client.py +118 -0
- sg_python_api-0.1.0/pyproject.toml +166 -0
- sg_python_api-0.1.0/scripts/_artifact_evidence.py +204 -0
- sg_python_api-0.1.0/scripts/_conformance_runtime.py +520 -0
- sg_python_api-0.1.0/scripts/_conformance_setup.py +540 -0
- sg_python_api-0.1.0/scripts/_sdist_contract.py +372 -0
- sg_python_api-0.1.0/scripts/benchmark.py +3302 -0
- sg_python_api-0.1.0/scripts/bootstrap_test_site.py +128 -0
- sg_python_api-0.1.0/scripts/probe_wire.py +2167 -0
- sg_python_api-0.1.0/scripts/run_conformance.sh +377 -0
- sg_python_api-0.1.0/scripts/run_installed_tests.py +524 -0
- sg_python_api-0.1.0/scripts/validate_artifacts.sh +344 -0
- sg_python_api-0.1.0/src/shotgun_api3/__init__.py +68 -0
- sg_python_api-0.1.0/src/shotgun_api3/_async_client.py +2906 -0
- sg_python_api-0.1.0/src/shotgun_api3/_async_driver.py +945 -0
- sg_python_api-0.1.0/src/shotgun_api3/_async_httpx2.py +662 -0
- sg_python_api-0.1.0/src/shotgun_api3/_async_transport.py +162 -0
- sg_python_api-0.1.0/src/shotgun_api3/_capabilities.py +165 -0
- sg_python_api-0.1.0/src/shotgun_api3/_client.py +2682 -0
- sg_python_api-0.1.0/src/shotgun_api3/_config.py +1463 -0
- sg_python_api-0.1.0/src/shotgun_api3/_crud.py +916 -0
- sg_python_api-0.1.0/src/shotgun_api3/_driver.py +879 -0
- sg_python_api-0.1.0/src/shotgun_api3/_errors.py +49 -0
- sg_python_api-0.1.0/src/shotgun_api3/_execution.py +273 -0
- sg_python_api-0.1.0/src/shotgun_api3/_files.py +1094 -0
- sg_python_api-0.1.0/src/shotgun_api3/_methods.py +1205 -0
- sg_python_api-0.1.0/src/shotgun_api3/_protocol.py +1347 -0
- sg_python_api-0.1.0/src/shotgun_api3/_sentinel.py +5 -0
- sg_python_api-0.1.0/src/shotgun_api3/_sg_timezone.py +5 -0
- sg_python_api-0.1.0/src/shotgun_api3/_signatures.py +53 -0
- sg_python_api-0.1.0/src/shotgun_api3/_transport.py +901 -0
- sg_python_api-0.1.0/src/shotgun_api3/_version.py +3 -0
- sg_python_api-0.1.0/src/shotgun_api3/lib/__init__.py +1 -0
- sg_python_api-0.1.0/src/shotgun_api3/lib/mockgun/__init__.py +16 -0
- sg_python_api-0.1.0/src/shotgun_api3/lib/mockgun/_async.py +315 -0
- sg_python_api-0.1.0/src/shotgun_api3/lib/mockgun/_mockgun.py +1666 -0
- sg_python_api-0.1.0/src/shotgun_api3/lib/sgtimezone.py +209 -0
- sg_python_api-0.1.0/src/shotgun_api3/py.typed +0 -0
- sg_python_api-0.1.0/src/shotgun_api3/shotgun.py +58 -0
- sg_python_api-0.1.0/tests/__init__.py +0 -0
- sg_python_api-0.1.0/tests/_git.py +6 -0
- sg_python_api-0.1.0/tests/_loopback.py +25 -0
- sg_python_api-0.1.0/tests/_pyright.py +23 -0
- sg_python_api-0.1.0/tests/_required_mode.py +68 -0
- sg_python_api-0.1.0/tests/_transports.py +131 -0
- sg_python_api-0.1.0/tests/client/__init__.py +0 -0
- sg_python_api-0.1.0/tests/client/test_activity.py +509 -0
- sg_python_api-0.1.0/tests/client/test_async.py +2534 -0
- sg_python_api-0.1.0/tests/client/test_auth_methods.py +431 -0
- sg_python_api-0.1.0/tests/client/test_crud.py +1318 -0
- sg_python_api-0.1.0/tests/client/test_filters.py +262 -0
- sg_python_api-0.1.0/tests/client/test_misc_methods.py +677 -0
- sg_python_api-0.1.0/tests/client/test_nav.py +276 -0
- sg_python_api-0.1.0/tests/client/test_schema.py +634 -0
- sg_python_api-0.1.0/tests/client/test_summarize_search.py +380 -0
- sg_python_api-0.1.0/tests/client/test_sync.py +1787 -0
- sg_python_api-0.1.0/tests/conftest.py +124 -0
- sg_python_api-0.1.0/tests/files/__init__.py +0 -0
- sg_python_api-0.1.0/tests/files/test_async.py +2138 -0
- sg_python_api-0.1.0/tests/files/test_cookie_handler.py +221 -0
- sg_python_api-0.1.0/tests/files/test_downloads.py +993 -0
- sg_python_api-0.1.0/tests/files/test_multipart.py +146 -0
- sg_python_api-0.1.0/tests/files/test_upload_routing.py +66 -0
- sg_python_api-0.1.0/tests/files/test_uploads.py +1648 -0
- sg_python_api-0.1.0/tests/fixtures/activity_stream_read.json +40 -0
- sg_python_api-0.1.0/tests/fixtures/batch.json +52 -0
- sg_python_api-0.1.0/tests/fixtures/create.json +49 -0
- sg_python_api-0.1.0/tests/fixtures/fault_bad_auth.json +46 -0
- sg_python_api-0.1.0/tests/fixtures/following.json +38 -0
- sg_python_api-0.1.0/tests/fixtures/get_session_token.json +32 -0
- sg_python_api-0.1.0/tests/fixtures/info.json +27 -0
- sg_python_api-0.1.0/tests/fixtures/nav_expand.json +35 -0
- sg_python_api-0.1.0/tests/fixtures/preferences_read.json +35 -0
- sg_python_api-0.1.0/tests/fixtures/read.json +46 -0
- sg_python_api-0.1.0/tests/fixtures/schema_entity_read.json +32 -0
- sg_python_api-0.1.0/tests/fixtures/schema_read.json +32 -0
- sg_python_api-0.1.0/tests/fixtures/summarize.json +45 -0
- sg_python_api-0.1.0/tests/fixtures/text_search.json +43 -0
- sg_python_api-0.1.0/tests/fixtures/update_project_last_accessed.json +36 -0
- sg_python_api-0.1.0/tests/fixtures/work_schedule_read.json +36 -0
- sg_python_api-0.1.0/tests/lib/__init__.py +0 -0
- sg_python_api-0.1.0/tests/lib/conftest.py +151 -0
- sg_python_api-0.1.0/tests/lib/test_mockgun_async.py +252 -0
- sg_python_api-0.1.0/tests/lib/test_mockgun_crud.py +733 -0
- sg_python_api-0.1.0/tests/lib/test_mockgun_find.py +1357 -0
- sg_python_api-0.1.0/tests/lib/test_mockgun_schema.py +394 -0
- sg_python_api-0.1.0/tests/lib/test_sgtimezone.py +311 -0
- sg_python_api-0.1.0/tests/live/__init__.py +0 -0
- sg_python_api-0.1.0/tests/live/conftest.py +197 -0
- sg_python_api-0.1.0/tests/live/test_async.py +360 -0
- sg_python_api-0.1.0/tests/live/test_roundtrip.py +129 -0
- sg_python_api-0.1.0/tests/test_config.py +1714 -0
- sg_python_api-0.1.0/tests/test_datetimes.py +303 -0
- sg_python_api-0.1.0/tests/test_errors.py +19 -0
- sg_python_api-0.1.0/tests/test_examples.py +362 -0
- sg_python_api-0.1.0/tests/test_init.py +311 -0
- sg_python_api-0.1.0/tests/test_parity.py +1415 -0
- sg_python_api-0.1.0/tests/test_project_metadata.py +34 -0
- sg_python_api-0.1.0/tests/test_signature_parity.py +232 -0
- sg_python_api-0.1.0/tests/tooling/__init__.py +0 -0
- sg_python_api-0.1.0/tests/tooling/_wire_replay.py +161 -0
- sg_python_api-0.1.0/tests/tooling/test_artifact_evidence.py +382 -0
- sg_python_api-0.1.0/tests/tooling/test_benchmark.py +4999 -0
- sg_python_api-0.1.0/tests/tooling/test_conformance_runtime.py +563 -0
- sg_python_api-0.1.0/tests/tooling/test_conformance_setup.py +370 -0
- sg_python_api-0.1.0/tests/tooling/test_required_mode.py +698 -0
- sg_python_api-0.1.0/tests/tooling/test_run_conformance.py +715 -0
- sg_python_api-0.1.0/tests/tooling/test_run_installed_tests.py +615 -0
- sg_python_api-0.1.0/tests/tooling/test_validate_artifacts.py +1171 -0
- sg_python_api-0.1.0/tests/tooling/test_wire_fixtures.py +1539 -0
- sg_python_api-0.1.0/tests/transport/__init__.py +0 -0
- sg_python_api-0.1.0/tests/transport/test_abort.py +406 -0
- sg_python_api-0.1.0/tests/transport/test_async.py +278 -0
- sg_python_api-0.1.0/tests/transport/test_async_driver.py +2383 -0
- sg_python_api-0.1.0/tests/transport/test_async_httpx2.py +1483 -0
- sg_python_api-0.1.0/tests/transport/test_async_prefetch.py +428 -0
- sg_python_api-0.1.0/tests/transport/test_driver.py +1770 -0
- sg_python_api-0.1.0/tests/transport/test_prefetch.py +1214 -0
- sg_python_api-0.1.0/tests/transport/test_protocol.py +640 -0
- sg_python_api-0.1.0/tests/transport/test_retry_policy.py +775 -0
- sg_python_api-0.1.0/tests/transport/test_streaming.py +604 -0
- sg_python_api-0.1.0/tests/transport/test_sync.py +301 -0
- sg_python_api-0.1.0/tests/transport/test_urllib3.py +336 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
dist/
|
|
13
|
+
.eggs/
|
|
14
|
+
*.egg-info/
|
|
15
|
+
*.egg
|
|
16
|
+
|
|
17
|
+
# Virtual environments
|
|
18
|
+
.venv/
|
|
19
|
+
venv/
|
|
20
|
+
ENV/
|
|
21
|
+
|
|
22
|
+
# PyInstaller
|
|
23
|
+
*.manifest
|
|
24
|
+
*.spec
|
|
25
|
+
|
|
26
|
+
# Unit test / coverage reports
|
|
27
|
+
htmlcov/
|
|
28
|
+
.tox/
|
|
29
|
+
.nox/
|
|
30
|
+
.coverage*
|
|
31
|
+
.pytest_cache/
|
|
32
|
+
.cache/
|
|
33
|
+
|
|
34
|
+
# Type checker / linter caches
|
|
35
|
+
.pyright/
|
|
36
|
+
.mypy_cache/
|
|
37
|
+
.ruff_cache/
|
|
38
|
+
pyrightconfig.json
|
|
39
|
+
|
|
40
|
+
# Root scratch files
|
|
41
|
+
/*.png
|
|
42
|
+
/*.txt
|
|
43
|
+
!/requirements-ci.txt
|
|
44
|
+
!/requirements-test.txt
|
|
45
|
+
|
|
46
|
+
# Editors
|
|
47
|
+
.vscode/
|
|
48
|
+
.idea/
|
|
49
|
+
|
|
50
|
+
# OS
|
|
51
|
+
.DS_Store
|
|
52
|
+
Thumbs.db
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
# Compatibility
|
|
2
|
+
|
|
3
|
+
Use this reference to decide whether sg-python-api fits an existing integration and to configure
|
|
4
|
+
the behavior that differs from Autodesk's client. For the installation and validation sequence,
|
|
5
|
+
start with the [migration guide](docs/migration-guide.md); for a first request, see the
|
|
6
|
+
[README quick start](README.md#quick-start).
|
|
7
|
+
|
|
8
|
+
| If you want to... | Start here |
|
|
9
|
+
| -------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
|
|
10
|
+
| Check whether your application is in scope | [Supported scope](#supported-scope) |
|
|
11
|
+
| Review the differences that affect applications | [What changes for your application](#what-changes-for-your-application) |
|
|
12
|
+
| Tune pooling or page prefetch, or observe requests | [Configuration and observer extensions](#configuration-and-observer-extensions) |
|
|
13
|
+
| Use the async client or async `mockgun` | [Async extension surfaces](#async-extension-surfaces) |
|
|
14
|
+
| Check which configuration names are supported | [Supported configuration and capability surfaces](#supported-configuration-and-capability-surfaces) |
|
|
15
|
+
| Check when plain HTTP is allowed | [Authenticated transport security](#authenticated-transport-security) |
|
|
16
|
+
| Point an existing client at a different site | [Server floor and readiness](#server-floor-and-readiness) |
|
|
17
|
+
|
|
18
|
+
Two terms recur on this page. A site's *origin* is its scheme, normalized hostname, and effective
|
|
19
|
+
port, where the effective port is the URL's explicit port or else 443 for HTTPS and 80 for HTTP.
|
|
20
|
+
The URL path is not part of the origin. Before the first operation against an origin, the client
|
|
21
|
+
reads that server's information and checks its version and page limit; this page calls that step
|
|
22
|
+
the *readiness check*.
|
|
23
|
+
|
|
24
|
+
## Supported scope
|
|
25
|
+
|
|
26
|
+
The package provides the `shotgun_api3` import name and targets the documented synchronous API of
|
|
27
|
+
Autodesk's Python client `3.10.2`, including its method signatures, return shapes, errors, filters,
|
|
28
|
+
paging, schema, file, activity, navigation, and scheduling operations. It also provides the
|
|
29
|
+
`shotgun_api3.lib.mockgun` and `shotgun_api3.lib.sgtimezone` modules and native async extensions.
|
|
30
|
+
|
|
31
|
+
The target is the documented API, so test the workflows your application uses before adopting the
|
|
32
|
+
package in production. Exception-message text is not guaranteed to match Autodesk's client; handle
|
|
33
|
+
documented exception types instead of parsing messages.
|
|
34
|
+
|
|
35
|
+
You need Python 3.11 or newer and a server version of at least 7.10.0. This package and the
|
|
36
|
+
official distribution both install `shotgun_api3`, so they cannot coexist in one Python
|
|
37
|
+
environment.
|
|
38
|
+
|
|
39
|
+
## What changes for your application
|
|
40
|
+
|
|
41
|
+
The most consequential differences concern timeouts, retries, trust, and shared-client use. Other
|
|
42
|
+
differences are grouped below so you can check only the areas your application uses.
|
|
43
|
+
|
|
44
|
+
### Timeouts and retries
|
|
45
|
+
|
|
46
|
+
Requests have a 15-second connect timeout and a 300-second read timeout by default. Finite waits
|
|
47
|
+
let an application recover when a dependency stops responding. To change both limits, assign
|
|
48
|
+
`sg.config.timeout_secs` a finite positive number of seconds no larger than the platform's
|
|
49
|
+
`threading.TIMEOUT_MAX`. Assigning a Boolean, zero, a negative or non-finite number, or a value
|
|
50
|
+
above that limit raises an error immediately. Set it to `None` only when the application
|
|
51
|
+
deliberately accepts an unlimited wait.
|
|
52
|
+
|
|
53
|
+
Retries use one policy for every operation, with backoff and jitter. Reads can retry. A write that
|
|
54
|
+
is unsafe to replay retries only when a failure occurs before the request is sent. Once sent, its
|
|
55
|
+
result may be ambiguous, so the client does not repeat it automatically. HTTP status retries,
|
|
56
|
+
including those directed by `Retry-After`, require an operation that is safe to replay. There is no
|
|
57
|
+
exact legacy retry mode.
|
|
58
|
+
|
|
59
|
+
Tune the number of attempts with `sg.config.max_rpc_attempts` (default `3`). Tune the base delay
|
|
60
|
+
with `sg.config.rpc_attempt_interval`, in milliseconds; its default is `3000`, or the value of the
|
|
61
|
+
`SHOTGUN_API_RETRY_INTERVAL` environment variable when the client is created.
|
|
62
|
+
|
|
63
|
+
When a retryable response carries a valid `Retry-After` header of 0 to 30 seconds, the client waits
|
|
64
|
+
that long before the next attempt. A larger valid value stops retrying and raises the current
|
|
65
|
+
response's error, so the client neither waits without a bound nor retries earlier than the server
|
|
66
|
+
asked. This 30-second bound is not configurable. A malformed `Retry-After` value is ignored, and
|
|
67
|
+
the client uses its computed backoff.
|
|
68
|
+
|
|
69
|
+
### Error handling
|
|
70
|
+
|
|
71
|
+
- RPC faults, including authentication faults, and terminal transport failures raise exceptions in
|
|
72
|
+
the `ShotgunError` family.
|
|
73
|
+
- An HTTP error response raises `shotgun_api3.ProtocolError`. This is the standard library's
|
|
74
|
+
`xmlrpc.client.ProtocolError`, which is outside the `ShotgunError` family.
|
|
75
|
+
- An invalid configuration value raises `ValueError`, or `TypeError` when the value has the wrong
|
|
76
|
+
type. An authenticated operation against a disallowed HTTP origin also raises `ValueError`.
|
|
77
|
+
|
|
78
|
+
Handle these families separately. The transport's concrete exception classes are implementation
|
|
79
|
+
details, so do not catch them directly.
|
|
80
|
+
|
|
81
|
+
### Trust and authentication
|
|
82
|
+
|
|
83
|
+
The client uses the system trust store by default. Passing `ca_certs=` or setting
|
|
84
|
+
`SHOTGUN_API_CACERTS` replaces that trust store with the selected bundle, so a custom bundle must
|
|
85
|
+
include every CA needed for the site and for any upload or download hosts. Remote authenticated
|
|
86
|
+
operations require HTTPS.
|
|
87
|
+
|
|
88
|
+
Attachment downloads send the site session cookie only to the client's configured origin.
|
|
89
|
+
Retargeting a client to a different origin clears any authentication and session values you do not
|
|
90
|
+
supply again. These rules prevent credentials from following an unrelated download or site change.
|
|
91
|
+
See [authenticated transport security](#authenticated-transport-security) and
|
|
92
|
+
[server floor and readiness](#server-floor-and-readiness) for the exact boundaries.
|
|
93
|
+
|
|
94
|
+
### Concurrency, pooling, and paging
|
|
95
|
+
|
|
96
|
+
A synchronous `Shotgun` can be shared across threads. An `AsyncShotgun` can be shared across tasks
|
|
97
|
+
on its owning event loop. Existing one-client-per-thread code remains valid.
|
|
98
|
+
|
|
99
|
+
Page fetching is serial by default, which preserves request order. A positive
|
|
100
|
+
`sg.config.page_prefetch` opts into bounded lookahead while still returning results in order.
|
|
101
|
+
[Configuration extensions](#configuration-and-observer-extensions) explains pooling and prefetch.
|
|
102
|
+
Measure your own workload before tuning them.
|
|
103
|
+
|
|
104
|
+
The client takes its page size from the server's `api_max_entities_per_page` value and leaves that
|
|
105
|
+
raw metadata available. When the value is missing, `None`, `0`, or empty, the page size is 500. Any
|
|
106
|
+
other malformed or non-positive value fails the readiness check with `ShotgunError`, and the next
|
|
107
|
+
operation repeats the check; the client never pages with an invalid size.
|
|
108
|
+
|
|
109
|
+
### Files, values, and diagnostics
|
|
110
|
+
|
|
111
|
+
| Behavior | Application impact |
|
|
112
|
+
| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
113
|
+
| Download setup errors | Setup RPC faults keep their specific types. Setup or transfer HTTP failures and invalid download URLs raise `ShotgunFileDownloadError` with a generic message and no underlying exception details. Configuration and security failures keep their existing types. |
|
|
114
|
+
| Multi-target thumbnail sharing | The client waits for source readiness before sharing and does not upload the source again. |
|
|
115
|
+
| Legacy form uploads | A successful response from the legacy form-upload route is unsupported. Hosted direct and multipart routes are supported. |
|
|
116
|
+
| Datetime-shaped strings | Invalid values remain unchanged strings. On platforms without pre-1970 time conversion, valid pre-epoch values use the process standard offset without historical daylight-saving accuracy. |
|
|
117
|
+
| Request diagnostics | Structured observers omit credentials and bodies. Application `httpx2` INFO logging can include signed URLs; set that logger to WARNING. |
|
|
118
|
+
| User agent | The default includes an `sg-python-api` marker. `add_user_agent()` preserves it, `reset_user_agent()` restores the default, and assigning `sg.config.user_agents` replaces every entry. |
|
|
119
|
+
| `shotgun_api3.__version__` | Reports the installed sg-python-api version, rather than Autodesk's compatibility-target version. |
|
|
120
|
+
|
|
121
|
+
### Unsupported legacy surfaces
|
|
122
|
+
|
|
123
|
+
The package omits `shotgun_api3.lib.httplib2` and the official client's `shotgun.Http`,
|
|
124
|
+
`shotgun.ProxyInfo`, and `shotgun.socks` internals. Applications that import them must use a
|
|
125
|
+
supported public API or manage their own transport integration.
|
|
126
|
+
|
|
127
|
+
Python versions below 3.11 cannot install the package, so setting `SHOTGUN_ALLOW_OLD_PYTHON` has no
|
|
128
|
+
effect. Servers below 7.10.0 are unsupported, and the official client's thumbnail URL synthesis for
|
|
129
|
+
servers older than 3.3.0 is not provided.
|
|
130
|
+
|
|
131
|
+
## Configuration and observer extensions
|
|
132
|
+
|
|
133
|
+
These settings have no counterpart in Autodesk's client. Set them on `sg.config` like any other
|
|
134
|
+
configuration attribute.
|
|
135
|
+
|
|
136
|
+
`page_prefetch` controls bounded lookahead for paged `find()` requests. Its default, `0`, keeps
|
|
137
|
+
page fetching serial. A positive value N permits N concurrent page requests, with at most N-1 later
|
|
138
|
+
pages fetched ahead while results remain ordered; a value of 1 therefore fetches nothing ahead.
|
|
139
|
+
|
|
140
|
+
`pool_maxsize` defaults to `10`. For the synchronous client, it sets how many connections the pool
|
|
141
|
+
keeps open per origin; concurrent demand can still open additional connections. For the
|
|
142
|
+
asynchronous client, it caps both simultaneous and retained keep-alive connections.
|
|
143
|
+
|
|
144
|
+
### Observers
|
|
145
|
+
|
|
146
|
+
The five observer fields accept a synchronous callback or `None`. Each callback receives one event
|
|
147
|
+
record:
|
|
148
|
+
|
|
149
|
+
| Configuration field | Event record |
|
|
150
|
+
| -------------------------- | ------------------------------------------------------------------------------------ |
|
|
151
|
+
| `on_compatibility_warning` | `CompatibilityWarningEvent(code, message)` |
|
|
152
|
+
| `on_progress` | `ProgressEvent(operation, route, attempt, bytes_transferred, total_bytes)` |
|
|
153
|
+
| `on_request` | `RequestEvent(operation, route, http_method, attempt)` |
|
|
154
|
+
| `on_response` | `ResponseEvent(operation, route, attempt, latency, status, outcome, correlation_id)` |
|
|
155
|
+
| `on_retry` | `RetryEvent(operation, route, attempt, delay, status)` |
|
|
156
|
+
|
|
157
|
+
These frozen records contain only allowlisted metadata. They exclude credentials, cookies, request
|
|
158
|
+
and response bodies, signed URLs, arbitrary headers, and backend exception text. The
|
|
159
|
+
`correlation_id` field contains only the `x-sg-correlation-id` response header, when the server
|
|
160
|
+
sends it.
|
|
161
|
+
|
|
162
|
+
Application logging of `httpx2` is separate from these observers. Its INFO request logs can include
|
|
163
|
+
signed upload or download URLs. Set the logger to WARNING or higher when handling signed URLs:
|
|
164
|
+
|
|
165
|
+
```python
|
|
166
|
+
import logging
|
|
167
|
+
|
|
168
|
+
logging.getLogger('httpx2').setLevel(logging.WARNING)
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Compatibility warnings use stable codes and fixed messages:
|
|
172
|
+
|
|
173
|
+
| Code | Emitted when |
|
|
174
|
+
| ------------------------------- | --------------------------------------------------------------------------------------- |
|
|
175
|
+
| `deprecated-entity-types-alias` | The application calls `entity_types()`, the deprecated alias of `schema_entity_read()`. |
|
|
176
|
+
| `deprecated-schema-alias` | The application calls `schema()`, the deprecated alias of `schema_field_read()`. |
|
|
177
|
+
| `legacy-infinite-timeout` | An operation runs with `sg.config.timeout_secs` set to `None`. |
|
|
178
|
+
|
|
179
|
+
### Callback threads and failures
|
|
180
|
+
|
|
181
|
+
Callbacks run synchronously and are never awaited, so keep them short. Serial synchronous
|
|
182
|
+
operations invoke callbacks on the caller's thread. With `page_prefetch` above 0 and a multi-page
|
|
183
|
+
`find()`, callbacks for every page request, including the first, run on the worker thread executing
|
|
184
|
+
that request. `AsyncShotgun` invokes callbacks on its owning event loop.
|
|
185
|
+
|
|
186
|
+
Each progress record is cumulative and ordered within one attempt: `bytes_transferred` is the total
|
|
187
|
+
reported so far, and `total_bytes` is `None` when the complete size is unknown. Chunking determines
|
|
188
|
+
when progress is reported, so there is no fixed byte interval between records.
|
|
189
|
+
|
|
190
|
+
If a callback raises an ordinary `Exception`, the client suppresses it and logs a sanitized warning
|
|
191
|
+
that names the event type without formatting the exception value. This boundary does not suppress
|
|
192
|
+
`BaseException` subclasses. A callback must not start an operation that would wait on the same
|
|
193
|
+
in-progress readiness check; the client raises `RuntimeError` instead of waiting on itself.
|
|
194
|
+
|
|
195
|
+
## Async extension surfaces
|
|
196
|
+
|
|
197
|
+
### `shotgun_api3.AsyncShotgun`
|
|
198
|
+
|
|
199
|
+
`AsyncShotgun` provides native asynchronous counterparts to the synchronous client operations.
|
|
200
|
+
Install the `async` extra to use it. Await I/O methods; configuration and properties remain
|
|
201
|
+
synchronous.
|
|
202
|
+
|
|
203
|
+
Import it explicitly with `from shotgun_api3 import AsyncShotgun`. Star imports exclude optional
|
|
204
|
+
dependency names, including `AsyncShotgun`.
|
|
205
|
+
|
|
206
|
+
An instance belongs to one event loop and may be shared by tasks on that loop. Prefer `async with`;
|
|
207
|
+
otherwise, call `await sg.close()`. Closing drains in-flight work and releases the current
|
|
208
|
+
transport, including page requests already reserved by an in-flight `find()`. Once closing begins,
|
|
209
|
+
the closing transport rejects unrelated new work, and a later operation reconnects lazily.
|
|
210
|
+
|
|
211
|
+
The async client has no `abort()` method; cancel an operation by cancelling its task. Cancellation
|
|
212
|
+
is not retried. A cancelled write may already have reached the server, so check its outcome before
|
|
213
|
+
repeating it.
|
|
214
|
+
|
|
215
|
+
`AsyncShotgun` validates constructor arguments synchronously but defers network work. The readiness
|
|
216
|
+
check and any one-use `auth_token` exchange run at the first of these points: entering an
|
|
217
|
+
`async with` block (only with the default `connect=True`), calling `await sg.connect()`, or
|
|
218
|
+
starting an operation that needs readiness. Until then, `server_caps` and `server_info` raise
|
|
219
|
+
`ShotgunError` and direct the caller to await `connect()` or an RPC.
|
|
220
|
+
|
|
221
|
+
### `shotgun_api3.lib.mockgun.AsyncShotgun`
|
|
222
|
+
|
|
223
|
+
`mockgun.AsyncShotgun` delegates awaitable methods to the in-memory `mockgun.Shotgun`
|
|
224
|
+
implementation and works without the `async` extra. Use it to exercise async application code
|
|
225
|
+
without making network requests. Configure schema files before construction with
|
|
226
|
+
`await mockgun.AsyncShotgun.set_schema_paths(field_path, entity_path)`; retrieving them with
|
|
227
|
+
`get_schema_paths()` also requires `await`.
|
|
228
|
+
|
|
229
|
+
Both async extension surfaces inherit the semantics of their synchronous counterparts.
|
|
230
|
+
Transport-specific differences apply to `AsyncShotgun`; `mockgun.AsyncShotgun` works in memory and
|
|
231
|
+
has no HTTP transport behavior.
|
|
232
|
+
|
|
233
|
+
## Supported configuration and capability surfaces
|
|
234
|
+
|
|
235
|
+
Applications may use these configuration and capability surfaces from Autodesk's client:
|
|
236
|
+
|
|
237
|
+
- Official `sg.config` attributes, with `records_per_page` read-only.
|
|
238
|
+
- `sg.config.set_server_params()`.
|
|
239
|
+
- `server_caps` and `ServerCapabilities`: `host`, `server_info`, `version`, `is_dev`, and the
|
|
240
|
+
`ensure_*` methods.
|
|
241
|
+
- `client_caps` and `ClientCapabilities`: `platform`, `local_path_field`, `py_version`, and
|
|
242
|
+
`ssl_version`.
|
|
243
|
+
- Module-level `LOG`, `SG_TIMEZONE`, `SgTimezone`, and `SHOTGUN_API_DISABLE_ENTITY_OPTIMIZATION`.
|
|
244
|
+
|
|
245
|
+
The following opt-in extensions have no official counterpart:
|
|
246
|
+
|
|
247
|
+
- `sg.config.page_prefetch`.
|
|
248
|
+
- `sg.config.pool_maxsize`.
|
|
249
|
+
- `sg.config.on_compatibility_warning`.
|
|
250
|
+
- `sg.config.on_progress`.
|
|
251
|
+
- `sg.config.on_request`.
|
|
252
|
+
- `sg.config.on_response`.
|
|
253
|
+
- `sg.config.on_retry`.
|
|
254
|
+
- `sg.config.update_fields()`.
|
|
255
|
+
- `shotgun_api3.AsyncShotgun`.
|
|
256
|
+
- `shotgun_api3.lib.mockgun.AsyncShotgun`.
|
|
257
|
+
|
|
258
|
+
## Authenticated transport security
|
|
259
|
+
|
|
260
|
+
Authenticated RPCs, uploads, thumbnail sharing, and same-origin attachment downloads require HTTPS,
|
|
261
|
+
because they carry credentials or the site session cookie. HTTP is allowed only for direct
|
|
262
|
+
connections to the exact hostname `localhost` (case-insensitive) or a literal loopback IP address:
|
|
263
|
+
IPv4 `127.0.0.0/8` or IPv6 `::1`. A configured proxy disallows this exception even when the proxy
|
|
264
|
+
itself is on loopback, because it can forward traffic elsewhere. Hostnames that resolve to
|
|
265
|
+
loopback, `localhost.`, and subdomains of `localhost` are not exceptions. There is no opt-out for
|
|
266
|
+
insecure remote origins.
|
|
267
|
+
|
|
268
|
+
The client checks this rule when each authenticated operation starts, not when you construct the
|
|
269
|
+
client. A client for a remote or proxied HTTP origin can therefore be created, but its first
|
|
270
|
+
authenticated operation raises `ValueError` before sending a request. Cached session tokens do not
|
|
271
|
+
bypass this check.
|
|
272
|
+
|
|
273
|
+
Credential-free downloads from external attachment URLs may still use HTTP. A URL with a different
|
|
274
|
+
port from the configured origin counts as external and receives no site session cookie.
|
|
275
|
+
|
|
276
|
+
## Server floor and readiness
|
|
277
|
+
|
|
278
|
+
The supported server floor is version 7.10.0. The readiness check belongs to one exact origin, not
|
|
279
|
+
to the client as a whole: the client rejects a server below the floor before the first operation
|
|
280
|
+
other than `info()` for each origin. A successful `info()` call completes the readiness check for
|
|
281
|
+
its origin without a duplicate request. After you point a client at a different origin, the next
|
|
282
|
+
operation runs a new readiness check for that origin.
|
|
283
|
+
|
|
284
|
+
Calling `sg.config.set_server_params()` with a new origin clears every authentication and session
|
|
285
|
+
value that belongs to the old origin. A change that affects only the API path keeps them. To switch
|
|
286
|
+
origins and credentials together, supply the new origin and its replacement credentials in one
|
|
287
|
+
atomic `sg.config.update_fields()` call.
|
|
288
|
+
|
|
289
|
+
For `AsyncShotgun`, the readiness check runs at the points described under
|
|
290
|
+
[async extension surfaces](#async-extension-surfaces).
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 the sg-python-api authors
|
|
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,89 @@
|
|
|
1
|
+
.DEFAULT_GOAL := all
|
|
2
|
+
|
|
3
|
+
PYTHON ?= python
|
|
4
|
+
VENV_BIN := .venv/bin
|
|
5
|
+
ifeq ($(OS),Windows_NT)
|
|
6
|
+
VENV_BIN := .venv/Scripts
|
|
7
|
+
endif
|
|
8
|
+
DEV_PYTHON := $(VENV_BIN)/python
|
|
9
|
+
export PATH := $(abspath $(VENV_BIN)):$(PATH)
|
|
10
|
+
export UV_SYSTEM_PYTHON := 0
|
|
11
|
+
UV_VERSION := 0.12.23
|
|
12
|
+
CI_PYTHON := 3.11
|
|
13
|
+
CI_EXTRAS := --extra async
|
|
14
|
+
CI_BUILD_REQUIREMENTS = $(DEV_PYTHON) -c 'import tomllib; print("\n".join(tomllib.load(open("pyproject.toml", "rb"))["build-system"]["requires"]))'
|
|
15
|
+
CI_COMPILE = uv pip compile pyproject.toml - $(CI_EXTRAS) --universal --python-version $(CI_PYTHON) --no-python-downloads --no-sources --no-build --generate-hashes --no-annotate --custom-compile-command 'make lock-update'
|
|
16
|
+
|
|
17
|
+
MARKDOWN_FILES := CHANGELOG.md COMPATIBILITY.md README.md docs/development.md docs/benchmarks.md docs/migration-guide.md docs/testing.md
|
|
18
|
+
PUBLIC_MARKDOWN_FILES := $(wildcard *.md docs/*.md)
|
|
19
|
+
SHELL_FILES := scripts/run_conformance.sh scripts/validate_artifacts.sh
|
|
20
|
+
|
|
21
|
+
.PHONY: all check env-check format format-check lock-check lock-update quality setup shell-check test type-check uv-check venv-check whitespace-check
|
|
22
|
+
|
|
23
|
+
uv-check:
|
|
24
|
+
@test "$$(uv --version | cut -d ' ' -f 2)" = "$(UV_VERSION)" || \
|
|
25
|
+
{ echo 'Use uv $(UV_VERSION), matching CI.' >&2; exit 1; }
|
|
26
|
+
|
|
27
|
+
setup: uv-check
|
|
28
|
+
@test -d .venv || uv venv --python "$(PYTHON)" --no-python-downloads .venv
|
|
29
|
+
rm -f .venv/.requirements-ci.txt .venv/.pyproject.toml
|
|
30
|
+
uv pip sync --python "$(DEV_PYTHON)" --no-python-downloads --require-hashes --build-constraints requirements-ci.txt requirements-ci.txt
|
|
31
|
+
uv pip install --python "$(DEV_PYTHON)" --no-python-downloads --no-deps --no-build-isolation -e .
|
|
32
|
+
cp requirements-ci.txt .venv/.requirements-ci.txt
|
|
33
|
+
cp pyproject.toml .venv/.pyproject.toml
|
|
34
|
+
|
|
35
|
+
venv-check:
|
|
36
|
+
@test -x "$(DEV_PYTHON)" || { echo 'Run make setup before project commands.' >&2; exit 1; }
|
|
37
|
+
|
|
38
|
+
env-check: venv-check
|
|
39
|
+
@cmp -s requirements-ci.txt .venv/.requirements-ci.txt && \
|
|
40
|
+
cmp -s pyproject.toml .venv/.pyproject.toml || \
|
|
41
|
+
{ echo 'Project setup is incomplete or outdated; run make setup.' >&2; exit 1; }
|
|
42
|
+
|
|
43
|
+
format: env-check
|
|
44
|
+
$(DEV_PYTHON) -m ruff format .
|
|
45
|
+
$(DEV_PYTHON) -m ruff check --fix .
|
|
46
|
+
biome format --write .
|
|
47
|
+
$(DEV_PYTHON) -m mdformat $(sort $(MARKDOWN_FILES) $(PUBLIC_MARKDOWN_FILES))
|
|
48
|
+
$(VENV_BIN)/pyproject-fmt pyproject.toml
|
|
49
|
+
shfmt -w $(SHELL_FILES)
|
|
50
|
+
|
|
51
|
+
format-check: env-check
|
|
52
|
+
$(DEV_PYTHON) -m ruff format --check .
|
|
53
|
+
$(DEV_PYTHON) -m ruff check .
|
|
54
|
+
biome format .
|
|
55
|
+
$(DEV_PYTHON) -m mdformat --check $(sort $(MARKDOWN_FILES) $(PUBLIC_MARKDOWN_FILES))
|
|
56
|
+
$(VENV_BIN)/pyproject-fmt --check pyproject.toml
|
|
57
|
+
shfmt -d $(SHELL_FILES)
|
|
58
|
+
|
|
59
|
+
type-check: env-check
|
|
60
|
+
$(DEV_PYTHON) -m pyright --project pyproject.toml --pythonpath "$(DEV_PYTHON)" --pythonplatform Linux
|
|
61
|
+
$(DEV_PYTHON) -m pyright --project pyproject.toml --pythonpath "$(DEV_PYTHON)" --pythonplatform Darwin
|
|
62
|
+
$(DEV_PYTHON) -m pyright --project pyproject.toml --pythonpath "$(DEV_PYTHON)" --pythonplatform Windows
|
|
63
|
+
|
|
64
|
+
lock-check: env-check uv-check
|
|
65
|
+
@tmp=$$(mktemp -d); trap 'rm -rf "$$tmp"' EXIT; \
|
|
66
|
+
cp requirements-ci.txt "$$tmp/requirements-ci.txt" && \
|
|
67
|
+
$(CI_BUILD_REQUIREMENTS) | $(CI_COMPILE) --group dev --quiet --output-file "$$tmp/requirements-ci.txt" && \
|
|
68
|
+
diff -u requirements-ci.txt "$$tmp/requirements-ci.txt" && \
|
|
69
|
+
$(CI_BUILD_REQUIREMENTS) | $(CI_COMPILE) --group test --constraint "$$tmp/requirements-ci.txt" --quiet --output-file "$$tmp/requirements-test.txt" && \
|
|
70
|
+
diff -u requirements-test.txt "$$tmp/requirements-test.txt"
|
|
71
|
+
|
|
72
|
+
lock-update: venv-check uv-check
|
|
73
|
+
$(CI_BUILD_REQUIREMENTS) | $(CI_COMPILE) --group dev --output-file requirements-ci.txt $(LOCK_FLAGS)
|
|
74
|
+
$(CI_BUILD_REQUIREMENTS) | $(CI_COMPILE) --group test --constraint requirements-ci.txt --output-file requirements-test.txt
|
|
75
|
+
|
|
76
|
+
test: env-check
|
|
77
|
+
$(DEV_PYTHON) -m pytest -q $(TEST_FLAGS)
|
|
78
|
+
|
|
79
|
+
shell-check:
|
|
80
|
+
bash -n $(SHELL_FILES)
|
|
81
|
+
|
|
82
|
+
whitespace-check:
|
|
83
|
+
git diff --check HEAD
|
|
84
|
+
|
|
85
|
+
quality: format-check lock-check type-check shell-check whitespace-check
|
|
86
|
+
|
|
87
|
+
check: quality test
|
|
88
|
+
|
|
89
|
+
all: check
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: sg-python-api
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python client for Autodesk Flow Production Tracking
|
|
5
|
+
Project-URL: Documentation, https://github.com/dactylo/sg-python-api/tree/main/docs
|
|
6
|
+
Project-URL: Homepage, https://github.com/dactylo/sg-python-api
|
|
7
|
+
Project-URL: Issues, https://github.com/dactylo/sg-python-api/issues
|
|
8
|
+
Project-URL: Repository, https://github.com/dactylo/sg-python-api
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: api,flow-production-tracking,shotgrid,shotgun,shotgun-api3
|
|
12
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
18
|
+
Classifier: Typing :: Typed
|
|
19
|
+
Requires-Python: >=3.11
|
|
20
|
+
Requires-Dist: urllib3<3,>=2
|
|
21
|
+
Provides-Extra: async
|
|
22
|
+
Requires-Dist: httpx2<3,>=2; extra == 'async'
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
|
|
25
|
+
# sg-python-api
|
|
26
|
+
|
|
27
|
+
sg-python-api is a Python client for Autodesk Flow Production Tracking, written for pipeline tools
|
|
28
|
+
and scripts built on Autodesk's `shotgun_api3` client. It keeps the same import name and documented
|
|
29
|
+
API, so an existing integration can switch without rewriting its calls and gain shared connections,
|
|
30
|
+
bounded network waits, and retries that do not repeat an ambiguous write. It also adds a native
|
|
31
|
+
asynchronous client.
|
|
32
|
+
|
|
33
|
+
This documentation uses SG for Flow Production Tracking, formerly named Shotgun and ShotGrid.
|
|
34
|
+
|
|
35
|
+
## Why use it?
|
|
36
|
+
|
|
37
|
+
- **Reuse connections:** share one synchronous client across threads, or one async client across
|
|
38
|
+
tasks on the same event loop.
|
|
39
|
+
- **Bound network waits:** default connect and read timeouts help applications recover from an
|
|
40
|
+
unavailable service.
|
|
41
|
+
- **Handle writes carefully:** retries account for whether an operation is safe to repeat. An
|
|
42
|
+
ambiguous write is left for the application to reconcile.
|
|
43
|
+
- **Test without a site:** synchronous and asynchronous `mockgun` clients provide an in-memory API
|
|
44
|
+
for application tests.
|
|
45
|
+
|
|
46
|
+
sg-python-api is an independent implementation of the documented API of Autodesk's Python client
|
|
47
|
+
`3.10.2`. Some behavior differs on purpose, so validate your application's workflows against a test
|
|
48
|
+
site before replacing its production client. The [migration guide](https://github.com/dactylo/sg-python-api/blob/v0.1.0/docs/migration-guide.md) walks
|
|
49
|
+
through the switch, and the [compatibility reference](https://github.com/dactylo/sg-python-api/blob/v0.1.0/COMPATIBILITY.md) lists the differences.
|
|
50
|
+
|
|
51
|
+
## Installation
|
|
52
|
+
|
|
53
|
+
You need Python 3.11 or newer and an SG site running server version 7.10.0 or newer. Authenticated
|
|
54
|
+
requests to a remote site require HTTPS.
|
|
55
|
+
|
|
56
|
+
`sg-python-api` and Autodesk's `shotgun-api3` both install the `shotgun_api3` package, so install
|
|
57
|
+
exactly one of them in a Python environment. If the official client is already installed, follow
|
|
58
|
+
the [migration steps](https://github.com/dactylo/sg-python-api/blob/v0.1.0/docs/migration-guide.md#install-the-replacement) to replace it.
|
|
59
|
+
|
|
60
|
+
When a release is available on your package index, install into the Python environment that runs
|
|
61
|
+
your application:
|
|
62
|
+
|
|
63
|
+
```sh
|
|
64
|
+
python -m pip install sg-python-api
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
To install from a checkout instead, run:
|
|
68
|
+
|
|
69
|
+
```sh
|
|
70
|
+
python -m pip install .
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
The base installation provides the synchronous `Shotgun` client and both `mockgun` test clients. To
|
|
74
|
+
use the native asynchronous client, `AsyncShotgun`, install the `async` extra, which adds the
|
|
75
|
+
`httpx2` HTTP library:
|
|
76
|
+
|
|
77
|
+
```sh
|
|
78
|
+
python -m pip install 'sg-python-api[async]'
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
From a checkout, use:
|
|
82
|
+
|
|
83
|
+
```sh
|
|
84
|
+
python -m pip install '.[async]'
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Quick start
|
|
88
|
+
|
|
89
|
+
These examples read one project from your site. They take the site URL and script credentials from
|
|
90
|
+
environment variables so the API key stays out of source code; the client does not read these
|
|
91
|
+
variables itself. Set `SHOTGUN_URL` to your site's HTTPS URL, and set `SHOTGUN_SCRIPT_NAME` and
|
|
92
|
+
`SHOTGUN_API_KEY` to a script account that can read projects.
|
|
93
|
+
|
|
94
|
+
### Synchronous client
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
import os
|
|
98
|
+
|
|
99
|
+
from shotgun_api3 import Shotgun
|
|
100
|
+
|
|
101
|
+
sg = Shotgun(
|
|
102
|
+
os.environ['SHOTGUN_URL'],
|
|
103
|
+
script_name=os.environ['SHOTGUN_SCRIPT_NAME'],
|
|
104
|
+
api_key=os.environ['SHOTGUN_API_KEY'],
|
|
105
|
+
)
|
|
106
|
+
try:
|
|
107
|
+
project = sg.find_one('Project', [], ['name'])
|
|
108
|
+
print(project)
|
|
109
|
+
finally:
|
|
110
|
+
sg.close()
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
The script prints a project dictionary containing `type`, `id`, and `name`, or `None` when no
|
|
114
|
+
project is visible to that account. You can share one `Shotgun` client across threads; `close()`
|
|
115
|
+
releases its pooled connections when you no longer need it.
|
|
116
|
+
|
|
117
|
+
### Asynchronous client
|
|
118
|
+
|
|
119
|
+
With the `async` extra installed and the same environment variables set, run:
|
|
120
|
+
|
|
121
|
+
```python
|
|
122
|
+
import asyncio
|
|
123
|
+
import os
|
|
124
|
+
|
|
125
|
+
from shotgun_api3 import AsyncShotgun
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
async def main() -> None:
|
|
129
|
+
async with AsyncShotgun(
|
|
130
|
+
os.environ['SHOTGUN_URL'],
|
|
131
|
+
script_name=os.environ['SHOTGUN_SCRIPT_NAME'],
|
|
132
|
+
api_key=os.environ['SHOTGUN_API_KEY'],
|
|
133
|
+
) as sg:
|
|
134
|
+
project = await sg.find_one('Project', [], ['name'])
|
|
135
|
+
print(project)
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
asyncio.run(main())
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
The output matches the synchronous example. The `async with` block closes the client even when an
|
|
142
|
+
operation fails. Without the `async` extra, importing `AsyncShotgun` raises `ImportError`.
|
|
143
|
+
|
|
144
|
+
Share an `AsyncShotgun` only among tasks on one event loop, and cancel its work by cancelling the
|
|
145
|
+
task. A cancelled write may already have reached the server, so check its outcome before repeating
|
|
146
|
+
it. The [async reference](https://github.com/dactylo/sg-python-api/blob/v0.1.0/COMPATIBILITY.md#async-extension-surfaces) covers shutdown and
|
|
147
|
+
cancellation in detail.
|
|
148
|
+
|
|
149
|
+
## Documentation
|
|
150
|
+
|
|
151
|
+
| If you want to... | Read |
|
|
152
|
+
| ----------------------------------------------------- | ---------------------------------------------------------------------------------- |
|
|
153
|
+
| Replace Autodesk's client in an existing application | [Migration guide](https://github.com/dactylo/sg-python-api/blob/v0.1.0/docs/migration-guide.md) |
|
|
154
|
+
| Check what behaves differently from Autodesk's client | [Compatibility](https://github.com/dactylo/sg-python-api/blob/v0.1.0/COMPATIBILITY.md) |
|
|
155
|
+
| Tune pooling and page prefetch, or observe requests | [Configuration extensions](https://github.com/dactylo/sg-python-api/blob/v0.1.0/COMPATIBILITY.md#configuration-and-observer-extensions) |
|
|
156
|
+
| Confirm which client loads and run a smoke test | [Testing an installation](https://github.com/dactylo/sg-python-api/blob/v0.1.0/docs/testing.md) |
|
|
157
|
+
| Compare measured latency and transfer memory | [Benchmarks](https://github.com/dactylo/sg-python-api/blob/v0.1.0/docs/benchmarks.md) |
|
|
158
|
+
| See changes by version | [Changelog](https://github.com/dactylo/sg-python-api/blob/v0.1.0/CHANGELOG.md) |
|
|
159
|
+
|
|
160
|
+
## Development
|
|
161
|
+
|
|
162
|
+
See the [development guide](https://github.com/dactylo/sg-python-api/blob/v0.1.0/docs/development.md) for the required tools, CI, and dependency locks.
|
|
163
|
+
With those tools installed, run:
|
|
164
|
+
|
|
165
|
+
```sh
|
|
166
|
+
make setup
|
|
167
|
+
make check
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
`make check` also runs the live-site tests, which create and delete records, whenever the
|
|
171
|
+
`SG_TEST_*` variables described in the development guide are set.
|
|
172
|
+
|
|
173
|
+
## License
|
|
174
|
+
|
|
175
|
+
sg-python-api is available under the [MIT License](https://github.com/dactylo/sg-python-api/blob/v0.1.0/LICENSE). It is an independent project and is
|
|
176
|
+
not affiliated with or endorsed by Autodesk. Flow Production Tracking is a product of Autodesk,
|
|
177
|
+
Inc.
|