Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updates SSL context options to find default system certificates #123

Merged
merged 1 commit into from
Jun 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
202 changes: 101 additions & 101 deletions Pipfile.lock

Large diffs are not rendered by default.

8 changes: 7 additions & 1 deletion mygeotab/altitude/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
from .wrapper import AltitudeAPI

from .daas_definition import DaasResult, DaasGetJobStatusResult, DaasGetQueryResult, DaasError, NOT_FULL_API_CALL_EXCEPTION
from .daas_definition import (
DaasResult,
DaasGetJobStatusResult,
DaasGetQueryResult,
DaasError,
NOT_FULL_API_CALL_EXCEPTION,
)

__all__ = [
"AltitudeAPI",
Expand Down
75 changes: 30 additions & 45 deletions mygeotab/altitude/daas_definition.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@

class DaasError:
def __init__(self, error: dict):
self.error = error
self.code = self.error['code']
self.domain = self.error['domain']
self.message = self.error['message']
self.code = self.error["code"]
self.domain = self.error["domain"]
self.message = self.error["message"]


NOT_FULL_API_CALL_EXCEPTION = Exception("api return did not have all expected attributes, please retry again.")


class DaasResult:
"""DaasResult class, the base class for all results returned from calling our application from the gateway

Expand All @@ -19,10 +21,9 @@ class DaasResult:
api_result_errors (list): possible errors list that happened on the altitude application.
api_result_error_message (str): possible single error message that happened on the altitude application.
api_result_error (DaasError): possible single error object that happened on the altitude application.
errors (list): list of all the errors (gateway and altitude application) combined together.
errors (list): list of all the errors (gateway and altitude application) combined together.
"""


def __init__(self, call_result: dict):

if not call_result:
Expand All @@ -32,10 +33,7 @@ def __init__(self, call_result: dict):
self.call_result = call_result

self.daas_errors = [DaasError(error) for error in self.call_result.get("errors", [])]
self.errors = [
Exception(error.message) for error in self.daas_errors
]

self.errors = [Exception(error.message) for error in self.daas_errors]

if "apiResult" not in call_result:
self.errors += [Exception("apiResult not present"), NOT_FULL_API_CALL_EXCEPTION]
Expand All @@ -45,33 +43,24 @@ def __init__(self, call_result: dict):
self.jobs = self.api_result["results"]
self.job = self.jobs[0]


self.api_result_errors = [DaasError(error) for error in self.api_result.get("errors", [])]
self.api_result_error_message = self.api_result.get("errorMessage", None)
self.api_result_error = None

self.errors += [Exception(error.message) for error in self.api_result_errors]



self.errors += [
Exception(error.message) for error in self.api_result_errors
]


if "error" in self.api_result and self.api_result["error"]:
if "error" in self.api_result and self.api_result["error"]:
self.api_result_error = DaasError(self.api_result["error"])
self.errors += [
Exception(self.api_result_error.message)
]
self.errors += [Exception(self.api_result_error.message)]

if self.api_result_error_message and isinstance(self.api_result_error_message, str) and len(self.api_result_error_message):
self.errors += [
Exception(self.api_result_error_message)
]
elif self.api_result_error_message and isinstance(self.api_result_error_message, dict):
self.errors += [
Exception(self.api_result_error_message["message"])
]
if (
self.api_result_error_message
and isinstance(self.api_result_error_message, str)
and len(self.api_result_error_message)
):
self.errors += [Exception(self.api_result_error_message)]
elif self.api_result_error_message and isinstance(self.api_result_error_message, dict):
self.errors += [Exception(self.api_result_error_message["message"])]


class DaasGetJobStatusResult(DaasResult):
Expand All @@ -82,23 +71,22 @@ class DaasGetJobStatusResult(DaasResult):
status (dict): the status of the job
state (str): the state of the job (from the status object)
"""



def __init__(self, call_result: dict):
super().__init__(call_result)
self.id = self.job['id']
self.status = self.job.get("status", {'state': 'FAILED'})
self.id = self.job["id"]
self.status = self.job.get("status", {"state": "FAILED"})
self.state = self.status.get("state", "FAILED")

def has_finished(self):
if self.state == 'DONE':
if self.state == "DONE":
return True
elif self.state != 'FAILED':
elif self.state != "FAILED":
return False
elif self.state == 'FAILED' and self.errors and len(self.errors) > 0:
elif self.state == "FAILED" and self.errors and len(self.errors) > 0:
return False
else:
raise Exception("got to failed state with no error, please reach out.")



class DaasGetQueryResult(DaasResult):
Expand All @@ -109,12 +97,9 @@ class DaasGetQueryResult(DaasResult):
rows (list): the rows including the data
pageToken (str): the token of the page
"""



def __init__(self, call_result: dict):
super().__init__(call_result)
self.total_rows = self.job.get('totalRows', None)
self.rows = self.job.get('rows', None)
self.page_token = self.job.get('pageToken', None)


self.total_rows = self.job.get("totalRows", None)
self.rows = self.job.get("rows", None)
self.page_token = self.job.get("pageToken", None)
37 changes: 12 additions & 25 deletions mygeotab/altitude/wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,14 @@ def __init__(
proxies=proxies,
cert=cert,
)
_ = logging.basicConfig(stream=sys.stdout, level=logging.INFO, format='%(asctime)s.%(msecs)03d %(levelname)-8s %(message)s', datefmt='%Y-%m-%d %H:%M:%S')


_ = logging.basicConfig(
stream=sys.stdout,
level=logging.INFO,
format="%(asctime)s.%(msecs)03d %(levelname)-8s %(message)s",
datefmt="%Y-%m-%d %H:%M:%S",
)

def _call_api(
self, service_name: str, function_name: str, function_parameters: dict
) -> dict:
def _call_api(self, service_name: str, function_name: str, function_parameters: dict) -> dict:
results = self.call(
method="GetBigDataResults",
serviceName=service_name,
Expand All @@ -64,12 +65,10 @@ def _call_api(
)
return results



def call_api(self, function_name: str, params: dict) -> dict :
'''
def call_api(self, function_name: str, params: dict) -> dict:
"""
Supports getJobStatus calls, and getQueryResults calls. Retries in case of errors like connection rest.
'''
"""
assert function_name in ["getJobStatus", "getQueryResults", "createQueryJob"]
max_tries = 5
for try_index in range(max_tries):
Expand All @@ -87,7 +86,7 @@ def call_api(self, function_name: str, params: dict) -> dict :
raise e
else:
print(f"encountered error trying to parse to api response {str(call_result)}, retrying....")
time.sleep((try_index + 1)*10)
time.sleep((try_index + 1) * 10)
else:
raise e

Expand Down Expand Up @@ -139,8 +138,6 @@ def wait_for_job_to_complete(self, params: dict) -> dict:
raise e
return daas_status.job



def fetch_data(self, params: dict) -> dict:
"""
fetch data for the given params. jobId needs to be included in params.
Expand Down Expand Up @@ -194,7 +191,7 @@ def get_data(self, params: dict) -> list:
logging.error(f"error: error while combining data:: {e}")
raise e
return data

def do(self, params: dict) -> list:
"""
given the parameters, will call the request, wait on it to finish and return the combined data.
Expand All @@ -210,13 +207,3 @@ def do(self, params: dict) -> list:
data = self.get_data(params)
logging.info(f"data gathered")
return data










2 changes: 2 additions & 0 deletions mygeotab/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -351,10 +351,12 @@ class GeotabHTTPAdapter(HTTPAdapter):

def init_poolmanager(self, connections, maxsize, block=False, **pool_kwargs):
ssl_context = create_urllib3_context(ssl_version=ssl.PROTOCOL_TLS)
ssl_context.load_default_certs()
ssl_context.options |= ssl.OP_NO_SSLv2
ssl_context.options |= ssl.OP_NO_SSLv3
ssl_context.options |= ssl.OP_NO_TLSv1
ssl_context.options |= ssl.OP_NO_TLSv1_1
ssl_context.options |= ssl.OP_ENABLE_MIDDLEBOX_COMPAT
self.poolmanager = urllib3.poolmanager.PoolManager(
num_pools=connections, maxsize=maxsize, block=block, ssl_context=ssl_context, **pool_kwargs
)
Expand Down
2 changes: 2 additions & 0 deletions mygeotab/api_async.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,10 +203,12 @@ async def _query(server, method, parameters, timeout=DEFAULT_TIMEOUT, verify_ssl
ssl_context = False
if verify_ssl or cert:
ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS)
ssl_context.load_default_certs()
ssl_context.options |= ssl.OP_NO_SSLv2
ssl_context.options |= ssl.OP_NO_SSLv3
ssl_context.options |= ssl.OP_NO_TLSv1
ssl_context.options |= ssl.OP_NO_TLSv1_1
ssl_context.options |= ssl.OP_ENABLE_MIDDLEBOX_COMPAT
if cert:
if isinstance(cert, str):
ssl_context.load_cert_chain(cert)
Expand Down
10 changes: 9 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,15 @@
packages=packages,
package_data={"": ["LICENSE"]},
license="Apache 2.0",
install_requires=["requests", "urllib3", "click", "pytz", "arrow", "aiohttp>=3.8.1,<4", "python-rapidjson"],
install_requires=[
"requests",
"urllib3",
"click",
"pytz",
"arrow",
"aiohttp>=3.8.1,<4",
"python-rapidjson",
],
setup_requires=["wheel"],
entry_points="""
[console_scripts]
Expand Down