|
2 | 2 | # License, v. 2.0. If a copy of the MPL was not distributed with this |
3 | 3 | # file, You can obtain one at http://mozilla.org/MPL/2.0/. |
4 | 4 | # |
5 | | -# Copyright (c) 2015-2018 Digi International Inc. |
| 5 | +# Copyright (c) 2015-2025 Digi International Inc. |
6 | 6 |
|
7 | 7 | import logging |
8 | 8 | import time |
9 | 9 | import json |
10 | 10 |
|
11 | 11 | from devicecloud.util import validate_type |
12 | | -from requests.auth import HTTPBasicAuth |
| 12 | +from requests.auth import HTTPBasicAuth, AuthBase |
13 | 13 | import requests |
14 | 14 | from devicecloud.version import __version__ |
15 | 15 | import six |
@@ -344,21 +344,35 @@ class DeviceCloud(object): |
344 | 344 | if dc.has_valid_credentials(): |
345 | 345 | print list(dc.devicecore.get_devices()) |
346 | 346 |
|
| 347 | + It's also possible to authenticate using API keys:: |
| 348 | +
|
| 349 | + dc = DeviceCloud(api_key_id='my-id', api_key_secret='my-secret') |
| 350 | +
|
347 | 351 | From there, access to all of Device Clouds features are possible. In some cases, methods |
348 | 352 | for quickly performing selected actions may be provided directly via the ``DeviceCloud`` object |
349 | 353 | while advanced usage requires using functionality exposed through other interfaces. |
350 | 354 |
|
351 | 355 | """ |
352 | 356 |
|
353 | | - def __init__(self, username, password, base_url=None, |
| 357 | + def __init__(self, username=None, password=None, |
| 358 | + api_key_id=None, api_key_secret=None, |
| 359 | + base_url=None, |
354 | 360 | throttle_retries=DEFAULT_THROTTLE_RETRIES, |
355 | 361 | throttle_delay_init=DEFAULT_THROTTLE_DELAY_INIT, |
356 | 362 | throttle_delay_max=DEFAULT_THROTTLE_DELAY_MAX, |
357 | 363 | throttle_delay_backoff_coefficient=DEFAULT_THROTTLE_DELAY_BACKOFF_COEFFICIENT): |
358 | 364 | if base_url is None: |
359 | 365 | base_url = "https://devicecloud.digi.com" |
| 366 | + |
| 367 | + if username and password: |
| 368 | + auth = HTTPBasicAuth(username, password) |
| 369 | + elif api_key_id and api_key_secret: |
| 370 | + auth = ApiKeyAuth(api_key_id, api_key_secret) |
| 371 | + else: |
| 372 | + raise ValueError("Must provide either username/password or api_key_id/api_key_secret") |
| 373 | + |
360 | 374 | self._conn = DeviceCloudConnection( |
361 | | - auth=HTTPBasicAuth(username, password), |
| 375 | + auth=auth, |
362 | 376 | base_url=base_url, |
363 | 377 | throttle_retries=throttle_retries, |
364 | 378 | throttle_delay_init=throttle_delay_init, |
@@ -543,3 +557,16 @@ def get_web_service_stub(self): |
543 | 557 | from devicecloud.ws import WebServiceStub |
544 | 558 |
|
545 | 559 | return WebServiceStub(self._conn, "/ws") |
| 560 | + |
| 561 | + |
| 562 | +class ApiKeyAuth(AuthBase): |
| 563 | + """Custom Auth class for API key authentication.""" |
| 564 | + |
| 565 | + def __init__(self, api_key_id: str, api_key_secret: str): |
| 566 | + self.api_key_id = api_key_id |
| 567 | + self.api_key_secret = api_key_secret |
| 568 | + |
| 569 | + def __call__(self, r): |
| 570 | + r.headers["X-API-KEY-ID"] = self.api_key_id |
| 571 | + r.headers["X-API-KEY-SECRET"] = self.api_key_secret |
| 572 | + return r |
0 commit comments