File: upgrading.rst

package info (click to toggle)
python-globus-sdk 3.54.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 5,032 kB
  • sloc: python: 34,226; sh: 44; makefile: 31
file content (352 lines) | stat: -rw-r--r-- 9,886 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
.. _upgrading:

Upgrading
=========

This guide covers upgrading and migration between Globus SDK versions.
It is meant to help explain and resolve incompatibilities and breaking
changes, and does not cover all new features.

When upgrading, you should also read the relevant section of the
:ref:`changelog`.
The changelog can also be a source of information about new features
between major releases.

Many explanations are written in terms of ``TransferClient`` for consistency,
but apply to all client classes, including ``AuthClient``,
``NativeAppAuthClient``, ``ConfidentialAppAuthClient``, ``SearchClient``, and
``GroupsClient``.

Version Parsing
---------------

In the event that a codebase must support multiple versions of
the globus-sdk at the same time, consider adding this snippet:

.. code-block:: python

    import globus_sdk

    GLOBUS_SDK_VERSION = tuple(globus_sdk.__version__.split("."))
    GLOBUS_SDK_MAJOR_VERSION = int(GLOBUS_SDK_VERSION[0])

This will parse the Globus SDK version information into a tuple and grab the
first element (the major version number) as an integer.

Then, code can dispatch with

.. code-block:: python

    if GLOBUS_SDK_MAJOR_VERSION < 3:
        pass  # do one thing
    else:
        pass  # do another

From 1.x or 2.x to 3.0
-----------------------

The :ref:`v3 changelog <changelog_version3>` covers the full list of changes
made in version 3 of the Globus SDK.

Because version 2 did not introduce any changes to the SDK code other than
supported python versions, you may also want to view this section when
upgrading from version 1.

Type Annotations
~~~~~~~~~~~~~~~~

The Globus SDK now provides PEP 561 type annotation data.

This means that codebases which use ``mypy`` or similar tools to check type
annotations may see new warnings or errors when using version 3 of the SDK.

.. note::

    If you believe an annotation in the SDK is incorrect, please visit our
    `issue tracker <https://github.com/globus/globus-sdk-python/issues>`_ to
    file a bug report!

Automatic Retries
~~~~~~~~~~~~~~~~~

Globus SDK client methods now automatically retry failing requests when
encountering network errors and certain classes of server errors (e.g. rate
limiting).

For most users, retry logic can be removed.
Change:

.. code-block:: python

    import globus_sdk

    # globus-sdk v1 or v2
    tc = globus_sdk.TransferClient(...)

    response = None
    count, max_retries = 0, 10
    while response is None and count < max_retries:
        count += 1
        try:  # any operation, just an example
            response = tc.get_endpoint(foo)
        except globus_sdk.NetworkError:
            pass

    # globus-sdk v3
    tc = globus_sdk.TransferClient(...)
    response = tc.get_endpoint(foo)  # again, just an example operation

Updates to BaseClient Usage
~~~~~~~~~~~~~~~~~~~~~~~~~~~

You may be using the globus-sdk ``BaseClient`` object to implement a custom
client or for type annotations. Firstly, ``BaseClient`` is available from the
base ``globus_sdk`` namespace.

Change:

.. code-block:: python

    # globus-sdk v1 or v2
    from globus_sdk.base import BaseClient

    # globus-sdk v3
    from globus_sdk import BaseClient

Secondly, creating a ``BaseClient`` is different. Previously, initializing a
``BaseClient`` had one required positional argument ``service``. Now, this
exists as a class attribute, which subclasses can overwrite.

Change:

.. code-block:: python

    # globus-sdk v1 or v2
    class MyClient(BaseClient):
        pass


    MyClient("my-service", **kwargs)


    # globus-sdk v3
    class MyClient(BaseClient):
        service_name = "my-service"


    MyClient(**kwargs)

Import exceptions from globus_sdk
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Several exceptions which were available in v2 under ``globus_sdk.exc`` are now
only available from the ``globus_sdk`` namespace.

Change:

.. code-block:: python

    # globus-sdk v1 or v2
    from globus_sdk.exc import SearchAPIError, TransferAPIError, AuthAPIError

    # globus-sdk v3
    from globus_sdk import SearchAPIError, TransferAPIError, AuthAPIError

Note that this also may appear in your exception handling, as in:

.. code-block:: python

    # globus-sdk v1 or v2
    from globus_sdk import exc

    try:
        ...
    except exc.TransferAPIError:  # by way of example, any error here
        ...

    # globus-sdk v3
    import globus_sdk

    try:
        ...
    except globus_sdk.TransferAPIError:
        ...

Low Level API for Passing Data is Improved
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In version 2 of the SDK, passing data to client ``post()``, ``put()``, and
``patch()`` methods required the use of either ``json_body`` or ``text_body``.
Furthermore, ``text_body`` would (confusingly!) send a FORM body if it were
passed a dictionary.

Now, these behaviors are described by ``data`` (a body for these HTTP methods)
and ``encoding`` (an explicit data format parameter). If the ``encoding`` is
not set, the default behavior is that if ``data`` is a dictionary, it will be
sent as JSON. If ``data`` is a string, it will be sent as text.

``encoding`` can be set to ``"json"`` or ``"form"`` to explicitly format the
data.

Change code for a JSON PUT like so:

.. code-block:: python

    # globus-sdk v1 or v2
    from globus_sdk import TransferClient

    tc = TransferClient(...)
    tc.put("/some/custom/path", json_body={"a": "dict", "of": "data"})

    # globus-sdk v3
    from globus_sdk import TransferClient

    tc = TransferClient(...)
    tc.put("/some/custom/path", data={"a": "dict", "of": "data"})

Or a FORM POST like so:

.. code-block:: python

    # globus-sdk v1 or v2
    from globus_sdk import TransferClient

    tc = TransferClient(...)
    tc.post("/some/custom/path", text_body={"a": "dict", "of": "data"})

    # globus-sdk v3
    from globus_sdk import TransferClient

    tc = TransferClient(...)
    tc.put("/some/custom/path", data={"a": "dict", "of": "data"}, encoding="form")

Passthrough Parameters are Explicit
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Many methods in version 2 accepted arbitrary keyword arguments which were then
transformed into query or body parameters based on the context. This is no
longer allowed, but methods can still be passed additional query parameters in the
form of a ``query_params`` dict.

For example, if the Transfer API is known to support a query param ``foo=bar``
for ``GET Endpoint``, but the SDK does not include this parameter, the way that
it can be added to a request has changed as follows:

.. code-block:: python

    # globus-sdk v1 or v2
    from globus_sdk import TransferClient

    tc = TransferClient(...)
    tc.get_endpoint(epid, foo="bar")

    # globus-sdk v3
    from globus_sdk import TransferClient

    tc = TransferClient(...)
    tc.get_endpoint(epid, query_params={"foo": "bar"})

.. note::

    If a parameter which you need is not supported by the Globus SDK, use
    ``query_params`` to work around it! But also, feel free to visit our
    `issue tracker <https://github.com/globus/globus-sdk-python/issues>`_ to
    request an improvement.

Responses are always GlobusHTTPResponse
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In version 2, ``GlobusHTTPResponse`` inherited from a base class,
``GlobusResponse``. In version 3, the distinction has been eliminated and
responses are only ``GlobusHTTPResponse``.

This may appear in contexts where you type annotate or use ``isinstance`` checks
to check the type of an object.

Change:

.. code-block:: python

    # globus-sdk v1 or v2
    from globus_sdk.response import GlobusResponse

    data = some_complex_func()
    if isinstance(data, GlobusResponse):
        ...

    # globus-sdk v3
    from globus_sdk import GlobusHTTPResponse

    data = some_complex_func()
    if isinstance(data, GlobusHTTPResponse):
        ...

Pagination is now explicit
~~~~~~~~~~~~~~~~~~~~~~~~~~

In version 2, paginated methods of ``TransferClient`` returned a
``PaginatedResource`` iterable type.
In version 3, no methods return paginators by default, and pagination is always
opt-in. See also :ref:`doc on making paginated calls <making_paginated_calls>`.

Change:

.. code-block:: python

    # globus-sdk v1 or v2
    from globus_sdk import TransferClient

    tc = TransferClient(...)
    for endpoint_info in tc.endpoint_search("query"):
        ...

    # globus-sdk v3
    from globus_sdk import TransferClient

    tc = TransferClient(...)
    for endpoint_info in tc.paginated.endpoint_search("query").items():
        ...

Authorizer Methods
~~~~~~~~~~~~~~~~~~

``GlobusAuthorizer`` objects have had their methods modified.

In particular, in version 2, authorizers have a method
``set_authorization_header`` for modifying a dict.

This has been replaced in version 3 with a method ``get_authorization_header``
which returns an ``Authorization`` header value.

Configuration has Changed
~~~~~~~~~~~~~~~~~~~~~~~~~

The Globus SDK no longer reads configuration data from ``/etc/globus.cfg`` or
``~/.globus.cfg``.

If you are using these files to customize the behavior of the SDK, see
:ref:`the configuration documentation <config>`.

Internal Changes to components including Config
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Several modules and components which are considered mostly or entirely internal
have been reorganized.

In particular, if you are using undocumented methods from
``globus_sdk.config``, note that this has been largely rewritten.
(These are not considered public APIs.)


From 1.x to 2.0
---------------

Also see the :ref:`v2 changelog <changelog_version2>`.

When upgrading from version 1 to version 2 of the Globus SDK, no code changes
should be necessary.

Version 2 removed support for python2 but made no other changes.

Simply ensure that you are running python 3.6 or later and update version
specifications to ``globus_sdk>=2,<3``.