Skip to content

Commit cb1433a

Browse files
Merge pull request #9 from Geocodio/refactor/auth-header-authentication
refactor: use Authorization header for API authentication
2 parents 57c4ae5 + 4a1ca43 commit cb1433a

File tree

4 files changed

+33
-25
lines changed

4 files changed

+33
-25
lines changed

src/geocodio/client.py

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ def geocode(
7777
limit: Optional[int] = None,
7878
country: Optional[str] = None,
7979
) -> GeocodingResponse:
80-
params: Dict[str, Union[str, int]] = {"api_key": self.api_key}
80+
params: Dict[str, Union[str, int]] = {}
8181
if fields:
8282
params["fields"] = ",".join(fields)
8383
if limit:
@@ -131,7 +131,7 @@ def reverse(
131131
fields: Optional[List[str]] = None,
132132
limit: Optional[int] = None,
133133
) -> GeocodingResponse:
134-
params: Dict[str, Union[str, int]] = {"api_key": self.api_key}
134+
params: Dict[str, Union[str, int]] = {}
135135
if fields:
136136
params["fields"] = ",".join(fields)
137137
if limit:
@@ -170,7 +170,7 @@ def _request(
170170
self,
171171
method: str,
172172
endpoint: str,
173-
params: dict,
173+
params: Optional[dict] = None,
174174
json: Optional[dict] = None,
175175
files: Optional[dict] = None,
176176
timeout: Optional[float] = None,
@@ -183,8 +183,11 @@ def _request(
183183
if timeout is None:
184184
timeout = self.single_timeout
185185

186+
# Set up authorization header
187+
headers = {"Authorization": f"Bearer {self.api_key}"}
188+
186189
logger.debug(f"Using timeout: {timeout}s")
187-
resp = self._http.request(method, endpoint, params=params, json=json, files=files, timeout=timeout)
190+
resp = self._http.request(method, endpoint, params=params, json=json, files=files, headers=headers, timeout=timeout)
188191

189192
logger.debug(f"Response status code: {resp.status_code}")
190193
logger.debug(f"Response headers: {resp.headers}")
@@ -289,9 +292,7 @@ def create_list(
289292
AuthenticationError: If the API key is invalid.
290293
GeocodioServerError: If the server encounters an error.
291294
"""
292-
# @TODO we repeat building the params here; prob should move the API key
293-
# to the self._request() method.
294-
params: Dict[str, Union[str, int]] = {"api_key": self.api_key}
295+
params: Dict[str, Union[str, int]] = {}
295296
endpoint = f"{self.BASE_PATH}/lists"
296297

297298
if not file:
@@ -321,7 +322,7 @@ def get_lists(self) -> PaginatedResponse:
321322
Returns:
322323
A ListResponse object containing all lists.
323324
"""
324-
params: Dict[str, Union[str, int]] = {"api_key": self.api_key}
325+
params: Dict[str, Union[str, int]] = {}
325326
endpoint = f"{self.BASE_PATH}/lists"
326327

327328
response = self._request("GET", endpoint, params, timeout=self.list_timeout)
@@ -356,7 +357,7 @@ def get_list(self, list_id: str) -> ListResponse:
356357
Returns:
357358
A ListResponse object containing the retrieved list.
358359
"""
359-
params: Dict[str, Union[str, int]] = {"api_key": self.api_key}
360+
params: Dict[str, Union[str, int]] = {}
360361
endpoint = f"{self.BASE_PATH}/lists/{list_id}"
361362

362363
response = self._request("GET", endpoint, params, timeout=self.list_timeout)
@@ -369,7 +370,7 @@ def delete_list(self, list_id: str) -> None:
369370
Args:
370371
list_id: The ID of the list to delete.
371372
"""
372-
params: Dict[str, Union[str, int]] = {"api_key": self.api_key}
373+
params: Dict[str, Union[str, int]] = {}
373374
endpoint = f"{self.BASE_PATH}/lists/{list_id}"
374375

375376
self._request("DELETE", endpoint, params, timeout=self.list_timeout)
@@ -538,7 +539,7 @@ def download(self, list_id: str, filename: Optional[str] = None) -> str | bytes:
538539
Raises:
539540
GeocodioServerError if the list is still processing or another error occurs.
540541
"""
541-
params = {"api_key": self.api_key}
542+
params = {}
542543
endpoint = f"{self.BASE_PATH}/lists/{list_id}/download"
543544

544545
response: httpx.Response = self._request("GET", endpoint, params, timeout=self.list_timeout)

tests/unit/test_errors.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ def _add_err(httpx_mock, status_code):
99
# this should actually make the request and see and error response
1010
# but we are mocking it here for testing purposes
1111
httpx_mock.add_response(
12-
url=httpx.URL("https://api.test/v1.9/geocode", params={"api_key": "TEST_KEY", "q": "bad input"}),
12+
url=httpx.URL("https://api.test/v1.9/geocode", params={"q": "bad input"}),
13+
match_headers={"Authorization": "Bearer TEST_KEY"},
1314
json={"error": "boom"},
1415
status_code=status_code,
1516
)

tests/unit/test_geocode.py

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ def response_callback(request):
5757

5858
httpx_mock.add_callback(
5959
callback=response_callback,
60-
url=httpx.URL("https://api.test/v1.9/geocode", params={"api_key": "TEST_KEY", "q": "1109 N Highland St, Arlington, VA"}),
60+
url=httpx.URL("https://api.test/v1.9/geocode", params={"q": "1109 N Highland St, Arlington, VA"}),
61+
match_headers={"Authorization": "Bearer TEST_KEY"},
6162
)
6263

6364
# Act
@@ -139,7 +140,8 @@ def batch_response_callback(request):
139140

140141
httpx_mock.add_callback(
141142
callback=batch_response_callback,
142-
url=httpx.URL("https://api.test/v1.9/geocode", params={"api_key": "TEST_KEY"}),
143+
url=httpx.URL("https://api.test/v1.9/geocode"),
144+
match_headers={"Authorization": "Bearer TEST_KEY"},
143145
)
144146

145147
# Act
@@ -171,11 +173,11 @@ def response_callback(request):
171173
httpx_mock.add_callback(
172174
callback=response_callback,
173175
url=httpx.URL("https://api.test/v1.9/geocode", params={
174-
"api_key": "TEST_KEY",
175176
"street": "1109 N Highland St",
176177
"city": "Arlington",
177178
"state": "VA"
178179
}),
180+
match_headers={"Authorization": "Bearer TEST_KEY"},
179181
)
180182

181183
# Act
@@ -228,10 +230,10 @@ def response_callback(request):
228230
httpx_mock.add_callback(
229231
callback=response_callback,
230232
url=httpx.URL("https://api.test/v1.9/geocode", params={
231-
"api_key": "TEST_KEY",
232233
"q": "1109 Highland St, Arlington, VA",
233234
"fields": "timezone,cd"
234235
}),
236+
match_headers={"Authorization": "Bearer TEST_KEY"},
235237
)
236238

237239
# Act
@@ -291,10 +293,10 @@ def response_callback(request):
291293
httpx_mock.add_callback(
292294
callback=response_callback,
293295
url=httpx.URL("https://api.test/v1.9/geocode", params={
294-
"api_key": "TEST_KEY",
295296
"q": "1109 Highland St, Arlington, VA",
296297
"limit": "2"
297298
}),
299+
match_headers={"Authorization": "Bearer TEST_KEY"},
298300
)
299301

300302
# Act
@@ -369,7 +371,8 @@ def batch_response_callback(request):
369371

370372
httpx_mock.add_callback(
371373
callback=batch_response_callback,
372-
url=httpx.URL("https://api.test/v1.9/geocode", params={"api_key": "TEST_KEY"}),
374+
url=httpx.URL("https://api.test/v1.9/geocode"),
375+
match_headers={"Authorization": "Bearer TEST_KEY"},
373376
)
374377

375378
# Act
@@ -475,7 +478,8 @@ def batch_response_callback(request):
475478

476479
httpx_mock.add_callback(
477480
callback=batch_response_callback,
478-
url=httpx.URL("https://api.test/v1.9/geocode", params={"api_key": "TEST_KEY", "fields": "timezone,cd"}),
481+
url=httpx.URL("https://api.test/v1.9/geocode", params={"fields": "timezone,cd"}),
482+
match_headers={"Authorization": "Bearer TEST_KEY"},
479483
)
480484

481485
# Act

tests/unit/test_reverse.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ def response_callback(request):
3232

3333
httpx_mock.add_callback(
3434
callback=response_callback,
35-
url=httpx.URL("https://api.test/v1.9/reverse", params={"api_key": "TEST_KEY", "q": "38.886672,-77.094735"}),
35+
url=httpx.URL("https://api.test/v1.9/reverse", params={"q": "38.886672,-77.094735"}),
36+
match_headers={"Authorization": "Bearer TEST_KEY"},
3637
)
3738

3839
# Act
@@ -54,7 +55,7 @@ def test_reverse_batch_coordinates(client, httpx_mock):
5455

5556
def batch_response_callback(request):
5657
assert request.method == "POST"
57-
assert request.url.params["api_key"] == "TEST_KEY"
58+
assert request.headers["Authorization"] == "Bearer TEST_KEY"
5859
return httpx.Response(200, json={
5960
"results": [
6061
{
@@ -109,7 +110,8 @@ def batch_response_callback(request):
109110

110111
httpx_mock.add_callback(
111112
callback=batch_response_callback,
112-
url=httpx.URL("https://api.test/v1.9/reverse", params={"api_key": "TEST_KEY"}),
113+
url=httpx.URL("https://api.test/v1.9/reverse"),
114+
match_headers={"Authorization": "Bearer TEST_KEY"},
113115
)
114116

115117
# Act
@@ -161,10 +163,10 @@ def response_callback(request):
161163
httpx_mock.add_callback(
162164
callback=response_callback,
163165
url=httpx.URL("https://api.test/v1.9/reverse", params={
164-
"api_key": "TEST_KEY",
165166
"q": "38.886672,-77.094735",
166167
"fields": "timezone,cd"
167168
}),
169+
match_headers={"Authorization": "Bearer TEST_KEY"},
168170
)
169171

170172
# Act
@@ -224,10 +226,10 @@ def response_callback(request):
224226
httpx_mock.add_callback(
225227
callback=response_callback,
226228
url=httpx.URL("https://api.test/v1.9/reverse", params={
227-
"api_key": "TEST_KEY",
228229
"q": "38.886672,-77.094735",
229230
"limit": "2"
230231
}),
232+
match_headers={"Authorization": "Bearer TEST_KEY"},
231233
)
232234

233235
# Act
@@ -243,9 +245,9 @@ def test_reverse_invalid_coordinate(client, httpx_mock):
243245
# Arrange: stub the API call with error response
244246
httpx_mock.add_response(
245247
url=httpx.URL("https://api.test/v1.9/reverse", params={
246-
"api_key": "TEST_KEY",
247248
"q": "invalid,coordinate"
248249
}),
250+
match_headers={"Authorization": "Bearer TEST_KEY"},
249251
json={"error": "Invalid coordinate format"},
250252
status_code=422
251253
)

0 commit comments

Comments
 (0)