Skip to content

Labelbox Client usage of requests Library doesn't support the verify argument so it ignores REQUESTS_CA_BUNDLE Environment Variable #1809

Closed
@tommypkeane-gehc

Description

@tommypkeane-gehc

Describe the bug

In the execute() method of the Client class, the low-level requests.Request class is instantiated to create a requests.PreparedRequest, but this bypasses the requests.merge_environment_settings() method.

This means that Client.execute() will not collect and use the REQUESTS_CA_BUNDLE environment variable if present, and will result in SSL errors.

To reproduce

  1. Use method client_obj = labelbox.Client(api_key="...")
  2. Pass parameters client_obj.execute(...)
  3. See error: labelbox.exceptions.NetworkError: HTTPSConnectionPool(host='api.labelbox.com', port=443): Max retries exceeded with url: /_gql (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self-signed certificate in certificate chain (_ssl.c:1006)')))

Expected behavior

The REQUESTS_CA_BUNDLE if set properly should allow the SSL certificate chain to be verified through a proxy or other deferred networking path where a custom certificate chain is needed.

Screenshots / Videos

N/A

Environment (please complete the following information

  • OS: macOS
  • Python Version: 3.11.x
  • SDK + SDK Version: labelbox@4.0.0
  • Python Environment: poetry.lock

Additional context

N/A

Proposed Fix

In the Client.execute(...) method at the lines:

prepped: requests.PreparedRequest = request.prepare()
response = self._connection.send(prepped, timeout=timeout)

the update could be:

            prepped: requests.PreparedRequest = request.prepare()

            response = self._connection.send(
                prepped,
                timeout=timeout,
                verify=os.getenv("REQUESTS_CA_BUNDLE", None),
            )

However, a more robust fix could be like this, though this wouldn't allow direct pass-through setting of the values, it would only rely on the Environment Variables:

            prepped: requests.PreparedRequest = request.prepare()

            req_settings: dict = self._connection.merge_environment_settings(
                url=None,
                proxies=None,
                stream=None,
                verify=None,
                cert=None,
            )

            response = self._connection.send(
                prepped,
                timeout=timeout,
                **req_settings,
            )

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions