Skip to content

Commit 9d6775e

Browse files
committed
Client certificate support and example
1 parent 860ea1c commit 9d6775e

File tree

3 files changed

+67
-3
lines changed

3 files changed

+67
-3
lines changed

examples/basic/sample.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# -*- coding: utf-8 -*-
2+
3+
import os
4+
import getpass
5+
from mygeotab import api
6+
7+
8+
def main():
9+
# Get credentials
10+
username = input("Username: ") # [email protected]
11+
password = getpass.getpass("Password: ") # password
12+
database = input("Database: ") # demo
13+
server = input("Server: ") # my.geotab.com
14+
port = input("Port: ")
15+
16+
# Get path to private key/certificate from environment variables
17+
key_path = os.environ["MYGEOTAB_CERTIFICATE_KEY"]
18+
cert_path = os.environ["MYGEOTAB_CERTIFICATE_CER"]
19+
20+
if not key_path or not cert_path:
21+
print("MyGeotab key or certificate not provided")
22+
exit(1)
23+
24+
cert = (cert_path, key_path)
25+
session = api.API(username=username, password=password, database=database, server=server, cert=cert)
26+
27+
try:
28+
session.authenticate()
29+
except api.MyGeotabException as exception:
30+
print(f"AUTH ERROR: {exception}")
31+
exit(1)
32+
33+
# Create new session using authenticated session to the target server and port
34+
if ':' not in session.credentials.server:
35+
credentials = session.credentials
36+
credentials.server = f"{credentials.server}:{port}"
37+
session = api.API.from_credentials(credentials)
38+
39+
# Send requests
40+
# ...
41+
42+
43+
if __name__ == "__main__":
44+
main()

mygeotab/api.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ def __init__(
3939
server="my.geotab.com",
4040
timeout=DEFAULT_TIMEOUT,
4141
proxies=None,
42+
cert=None
4243
):
4344
"""Initialize the MyGeotab API object with credentials.
4445
@@ -56,6 +57,8 @@ def __init__(
5657
:type timeout: float or None
5758
:param proxies: The proxies dictionary to apply to the request.
5859
:type proxies: dict or None
60+
:param cert: The path to client certificate. A single path to .pem file or a Tuple (.cer file, .key file).
61+
:type cert: str or Tuple or None
5962
:raise Exception: Raises an Exception if a username, or one of the session_id or password is not provided.
6063
"""
6164
if username is None:
@@ -68,6 +71,7 @@ def __init__(
6871
self.timeout = timeout
6972
self._proxies = proxies
7073
self.__reauthorize_count = 0
74+
self._cert = cert
7175

7276
@property
7377
def _server(self):
@@ -105,7 +109,12 @@ def call(self, method, **parameters):
105109

106110
try:
107111
result = _query(
108-
self._server, method, params, self.timeout, verify_ssl=self._is_verify_ssl, proxies=self._proxies
112+
self._server,
113+
method, params,
114+
self.timeout,
115+
verify_ssl=self._is_verify_ssl,
116+
proxies=self._proxies,
117+
cert=self._cert
109118
)
110119
if result is not None:
111120
self.__reauthorize_count = 0
@@ -219,6 +228,7 @@ def authenticate(self):
219228
self.timeout,
220229
verify_ssl=self._is_verify_ssl,
221230
proxies=self._proxies,
231+
cert=self._cert
222232
)
223233
if result:
224234
if "path" not in result and self.credentials.session_id:
@@ -307,7 +317,7 @@ def init_poolmanager(self, connections, maxsize, block=False, **pool_kwargs):
307317
)
308318

309319

310-
def _query(server, method, parameters, timeout=DEFAULT_TIMEOUT, verify_ssl=True, proxies=None):
320+
def _query(server, method, parameters, timeout=DEFAULT_TIMEOUT, verify_ssl=True, proxies=None, cert=None):
311321
"""Formats and performs the query against the API.
312322
313323
:param server: The MyGeotab server.
@@ -332,6 +342,8 @@ def _query(server, method, parameters, timeout=DEFAULT_TIMEOUT, verify_ssl=True,
332342
headers = get_headers()
333343
with requests.Session() as session:
334344
session.mount("https://", GeotabHTTPAdapter())
345+
if cert:
346+
session.cert = cert
335347
try:
336348
response = session.post(
337349
api_endpoint,

tests/test_api_call.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
PASSWORD = os.environ.get("MYGEOTAB_PASSWORD")
1212
DATABASE = os.environ.get("MYGEOTAB_DATABASE")
1313
SERVER = os.environ.get("MYGEOTAB_SERVER")
14+
CER_FILE = os.environ.get("MYGEOTAB_CERTIFICATE_CER")
15+
KEY_FILE = os.environ.get("MYGEOTAB_CERTIFICATE_KEY")
16+
PEM_FILE = os.environ.get("MYGEOTAB_CERTIFICATE_PEM")
1417
TRAILER_NAME = "mygeotab-python test trailer"
1518

1619
FAKE_USERNAME = "fakeusername"
@@ -21,8 +24,13 @@
2124

2225
@pytest.fixture(scope="session")
2326
def populated_api():
27+
cert = None
28+
if CER_FILE and KEY_FILE:
29+
cert = (CER_FILE, KEY_FILE)
30+
elif PEM_FILE:
31+
cert = PEM_FILE
2432
if USERNAME and PASSWORD:
25-
session = api.API(USERNAME, password=PASSWORD, database=DATABASE, server=SERVER)
33+
session = api.API(USERNAME, password=PASSWORD, database=DATABASE, server=SERVER, cert=cert)
2634
try:
2735
session.authenticate()
2836
except api.MyGeotabException as exception:

0 commit comments

Comments
 (0)