Skip to content

Commit fd1a0ca

Browse files
authored
build(BaseClient): Bumped httpx + updates related to secure requests (#407)
Co-authored-by: Alexander Sytsevich <[email protected]>
1 parent ec4c6e9 commit fd1a0ca

File tree

6 files changed

+1208
-1024
lines changed

6 files changed

+1208
-1024
lines changed

poetry.lock

Lines changed: 1181 additions & 1008 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,13 @@ classifiers = [
2323
python = "^3.8"
2424
fastavro = "^1.7.3"
2525
jsonschema = "^4.17.3"
26-
httpx = ">=0.26,<0.28"
26+
httpx = ">=0.28,<0.29"
2727
aiofiles = ">=23.1,<25.0"
2828
faust-streaming = {version = ">=0.10.11,<0.12.0", optional = true}
2929

3030
[tool.poetry.group.dev.dependencies]
3131
mypy = "^1"
32-
ruff = ">=0.2,<0.5"
32+
ruff = "^0.8"
3333
pytest = ">=7,<9"
3434
pytest-cov = ">=4,<6"
3535
pytest-mock = "^3.10.0"

schema_registry/client/client.py

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@
22

33
import json
44
import logging
5+
import os
6+
import ssl
57
import typing
68
from abc import abstractmethod
79
from collections import defaultdict
810
from urllib.parse import urlparse
911

12+
import certifi
1013
import httpx
1114
from httpx import USE_CLIENT_DEFAULT, Auth, BasicAuth
1215
from httpx._client import UseClientDefault
@@ -135,16 +138,18 @@ def _configure_auth(self) -> Auth:
135138
@staticmethod
136139
def _configure_client_tls(
137140
conf: dict,
138-
) -> typing.Optional[typing.Union[str, typing.Tuple[str, str], typing.Tuple[str, str, str]]]:
139-
certificate = conf.get(utils.SSL_CERTIFICATE_LOCATION)
141+
) -> typing.Optional[typing.Union[typing.Tuple[str, str], typing.Tuple[str, str, str]]]:
142+
cert = conf.get(utils.SSL_CERTIFICATE_LOCATION)
143+
certificate = cert
140144

141-
if certificate is not None:
145+
if cert is not None:
142146
key_path = conf.get(utils.SSL_KEY_LOCATION)
143147
key_password = conf.get(utils.SSL_KEY_PASSWORD)
148+
certificate = (cert,)
144149

145150
if key_path is not None:
146151
certificate = (
147-
certificate,
152+
cert,
148153
key_path,
149154
)
150155

@@ -154,16 +159,24 @@ def _configure_client_tls(
154159
return certificate
155160

156161
def _get_client_kwargs(self) -> typing.Dict:
157-
verify = self.conf.get(utils.SSL_CA_LOCATION, False)
158-
certificate = self._configure_client_tls(self.conf)
159162
auth = self._configure_auth()
160163

161164
client_kwargs: typing.Dict = {
162-
"cert": certificate,
163-
"verify": verify,
164165
"auth": auth,
165166
}
166167

168+
certificate = self._configure_client_tls(self.conf)
169+
170+
if certificate:
171+
global_ca_location = self.conf.get(utils.SSL_CA_LOCATION, certifi.where())
172+
ctx = ssl.create_default_context(
173+
cafile=os.environ.get("SSL_CERT_FILE", global_ca_location),
174+
capath=os.environ.get("SSL_CERT_DIR"),
175+
)
176+
177+
ctx.load_cert_chain(*certificate)
178+
client_kwargs["verify"] = ctx
179+
167180
# If these values haven't been explicitly defined let httpx sort out
168181
# the default values.
169182
if self.extra_headers is not None:

tests/client/async_client/test_http_client.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,8 @@
1010

1111
@pytest.mark.asyncio
1212
async def test_invalid_cert():
13-
client = AsyncSchemaRegistryClient(url="https://127.0.0.1:65534", cert_location="/path/to/cert")
1413
with pytest.raises(FileNotFoundError):
15-
await client.request("https://example.com")
14+
AsyncSchemaRegistryClient(url="https://127.0.0.1:65534", cert_location="/path/to/cert")
1615

1716

1817
def test_cert_with_key(certificates):

tests/client/sync_client/test_http_client.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,8 @@
1010

1111

1212
def test_invalid_cert():
13-
client = SchemaRegistryClient(url="https://127.0.0.1:65534", cert_location="/path/to/cert")
1413
with pytest.raises(FileNotFoundError):
15-
client.request("https://example.com")
14+
SchemaRegistryClient(url="https://127.0.0.1:65534", cert_location="/path/to/cert")
1615

1716

1817
def test_cert_with_key(certificates):

tests/serializer/test_faust_serializer.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ def test_create_avro_faust_serializer(client, avro_country_schema):
1414
schema_subject = "test-avro-country"
1515
faust_serializer = serializer.FaustSerializer(client, schema_subject, avro_country_schema)
1616

17-
assert type(faust_serializer.message_serializer) == AvroMessageSerializer
17+
assert isinstance(faust_serializer.message_serializer, AvroMessageSerializer)
1818
assert faust_serializer.schema_subject == schema_subject
1919
assert faust_serializer.schema == avro_country_schema
2020
assert faust_serializer.message_serializer.schemaregistry_client == client
@@ -155,7 +155,7 @@ def test_create_json_faust_serializer(client, json_country_schema):
155155
schema_subject = "test-json-country"
156156
faust_serializer = serializer.FaustJsonSerializer(client, schema_subject, json_country_schema)
157157

158-
assert type(faust_serializer.message_serializer) == JsonMessageSerializer
158+
assert isinstance(faust_serializer.message_serializer, JsonMessageSerializer)
159159
assert faust_serializer.schema_subject == schema_subject
160160
assert faust_serializer.schema == json_country_schema
161161
assert faust_serializer.message_serializer.schemaregistry_client == client

0 commit comments

Comments
 (0)