Skip to content

Commit 40ecaae

Browse files
committed
Clean up the common module a bit.
1 parent 1a3d628 commit 40ecaae

File tree

3 files changed

+100
-89
lines changed

3 files changed

+100
-89
lines changed

src/akismet/_async_client.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ async def _request(
253253
raise _exceptions.RequestError("Error making request to Akismet.") from exc
254254
except Exception as exc:
255255
raise _exceptions.RequestError("Error making request to Akismet.") from exc
256-
return _common._akismet_response(endpoint, response)
256+
return _common._handle_akismet_response(endpoint, response)
257257

258258
async def _get_request(
259259
self, version: str, endpoint: str, params: dict
@@ -310,7 +310,7 @@ async def _post_request(
310310
"api_key": self._config.key,
311311
"blog": self._config.url,
312312
"user_ip": user_ip,
313-
**_common._check_post_kwargs(kwargs, endpoint),
313+
**_common._prepare_post_kwargs(kwargs, endpoint),
314314
},
315315
)
316316

@@ -329,7 +329,7 @@ async def _submit(
329329
received from the Akismet API.
330330
331331
"""
332-
return _common._submit_response(
332+
return _common._handle_submit_response(
333333
endpoint,
334334
await self._post_request(
335335
_common._API_V11, endpoint, user_ip=user_ip, **kwargs
@@ -567,7 +567,7 @@ async def verify_key(
567567
"""
568568
if not all([key, url]):
569569
key, url = self._config
570-
return _common._verify_key_response(
570+
return _common._handle_verify_key_response(
571571
await self._request(
572572
"POST",
573573
_common._API_V11,

src/akismet/_common.py

Lines changed: 92 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import sys
1111
import textwrap
1212
from importlib.metadata import version
13-
from typing import Literal, NamedTuple, NoReturn, TypedDict
13+
from typing import Literal, NamedTuple, NoReturn, TypedDict, cast
1414

1515
import httpx
1616

@@ -69,6 +69,32 @@
6969
# -------------------------------------------------------------------------------
7070

7171

72+
class AkismetArguments(TypedDict, total=False):
73+
"""
74+
A :class:`~typing.TypedDict` representing the optional keyword arguments accepted by
75+
most Akismet API operations.
76+
77+
"""
78+
79+
blog_charset: str
80+
blog_lang: str
81+
comment_author: str
82+
comment_author_email: str
83+
comment_author_url: str
84+
comment_content: str
85+
comment_context: str
86+
comment_date_gmt: str
87+
comment_post_modified_gmt: str
88+
comment_type: str
89+
honeypot_field_name: str
90+
is_test: bool
91+
permalink: str
92+
recheck_reason: str
93+
referrer: str
94+
user_agent: str
95+
user_role: str
96+
97+
7298
class CheckResponse(enum.IntEnum):
7399
"""
74100
Possible response values from an Akismet content check, including the
@@ -96,33 +122,11 @@ class Config(NamedTuple):
96122
url: str
97123

98124

99-
class AkismetArguments(TypedDict, total=False):
100-
"""
101-
A :class:`~typing.TypedDict` representing the optional keyword arguments accepted by
102-
most Akismet API operations.
103-
104-
"""
105-
106-
blog_charset: str
107-
blog_lang: str
108-
comment_author: str
109-
comment_author_email: str
110-
comment_author_url: str
111-
comment_content: str
112-
comment_context: str
113-
comment_date_gmt: str
114-
comment_post_modified_gmt: str
115-
comment_type: str
116-
honeypot_field_name: str
117-
is_test: bool
118-
permalink: str
119-
recheck_reason: str
120-
referrer: str
121-
user_agent: str
122-
user_role: str
125+
# Private helper functions.
126+
# -------------------------------------------------------------------------------
123127

124128

125-
# Private helper functions.
129+
# Functions which throw errors for various situations.
126130
# -------------------------------------------------------------------------------
127131

128132

@@ -143,22 +147,6 @@ def _configuration_error(config: Config) -> NoReturn:
143147
)
144148

145149

146-
def _get_async_http_client() -> httpx.AsyncClient:
147-
"""
148-
Return an asynchronous HTTP client for interacting with the Akismet API.
149-
150-
"""
151-
return httpx.AsyncClient(headers={"User-Agent": USER_AGENT}, timeout=_TIMEOUT)
152-
153-
154-
def _get_sync_http_client() -> httpx.Client:
155-
"""
156-
Return a synchronous HTTP client for interacting with the Akismet API.
157-
158-
"""
159-
return httpx.Client(headers={"User-Agent": USER_AGENT}, timeout=_TIMEOUT)
160-
161-
162150
def _protocol_error(operation: str, response: httpx.Response) -> NoReturn:
163151
"""
164152
Raise an appropriate exception for unexpected API responses.
@@ -177,6 +165,26 @@ def _protocol_error(operation: str, response: httpx.Response) -> NoReturn:
177165
)
178166

179167

168+
# Functions which help autodiscover/autofill configuration.
169+
# -------------------------------------------------------------------------------
170+
171+
172+
def _get_async_http_client() -> httpx.AsyncClient:
173+
"""
174+
Return an asynchronous HTTP client for interacting with the Akismet API.
175+
176+
"""
177+
return httpx.AsyncClient(headers={"User-Agent": USER_AGENT}, timeout=_TIMEOUT)
178+
179+
180+
def _get_sync_http_client() -> httpx.Client:
181+
"""
182+
Return a synchronous HTTP client for interacting with the Akismet API.
183+
184+
"""
185+
return httpx.Client(headers={"User-Agent": USER_AGENT}, timeout=_TIMEOUT)
186+
187+
180188
def _try_discover_config() -> Config:
181189
"""
182190
Attempt to discover and return an Akismet configuration from the environment.
@@ -207,14 +215,30 @@ def _try_discover_config() -> Config:
207215
f"""
208216
Invalid Akismet site URL specified: {url}
209217
210-
Akismet requires the full URL including the leading
211-
'http://' or 'https://'.
218+
Akismet requires the full URL including the leading 'http://' or 'https://'.
212219
"""
213220
)
214221
)
215222
return Config(key=key, url=url)
216223

217224

225+
# Functions which help process Akismet requests and responses.
226+
# -------------------------------------------------------------------------------
227+
228+
229+
def _handle_akismet_response(endpoint: str, response: httpx.Response) -> httpx.Response:
230+
"""
231+
Check the response to see if it indicates an invalid key.
232+
233+
"""
234+
# It's possible to construct a client without performing up-front API key
235+
# validation, in which case the responses will all have text "invalid". So we check
236+
# for that and raise an exception when it's detected.
237+
if endpoint != _VERIFY_KEY and response.text == "invalid":
238+
raise _exceptions.APIKeyError("Akismet API key and/or site URL are invalid.")
239+
return response
240+
241+
218242
def _handle_check_response(response: httpx.Response) -> CheckResponse:
219243
"""
220244
Return the correct result for a response from the comment-check endpoint.
@@ -229,7 +253,29 @@ def _handle_check_response(response: httpx.Response) -> CheckResponse:
229253
_protocol_error(_COMMENT_CHECK, response)
230254

231255

232-
def _check_post_kwargs(kwargs: dict, endpoint: str) -> AkismetArguments:
256+
def _handle_submit_response(endpoint: str, response: httpx.Response) -> bool:
257+
"""
258+
Proces the response from a submit (ham/spam) request.
259+
260+
"""
261+
if response.text == _SUBMISSION_RESPONSE:
262+
return True
263+
_protocol_error(endpoint, response)
264+
265+
266+
def _handle_verify_key_response(response: httpx.Response) -> bool:
267+
"""
268+
Handle the response from a verify_key() request.
269+
270+
"""
271+
if response.text == "valid":
272+
return True
273+
if response.text == "invalid":
274+
return False
275+
_protocol_error(_VERIFY_KEY, response)
276+
277+
278+
def _prepare_post_kwargs(kwargs: dict, endpoint: str) -> AkismetArguments:
233279
"""
234280
Verify that the provided set of keyword arguments is valid for an Akismet POST
235281
request, returning them if they are or raising UnknownArgumentError if they aren't.
@@ -240,7 +286,7 @@ def _check_post_kwargs(kwargs: dict, endpoint: str) -> AkismetArguments:
240286
f"Received unknown argument(s) for Akismet operation {endpoint}: "
241287
f"{', '.join(unknown_args)}"
242288
)
243-
return kwargs
289+
return cast(AkismetArguments, kwargs)
244290

245291

246292
def _prepare_request(
@@ -257,38 +303,3 @@ def _prepare_request(
257303
)
258304
request_kwarg = "data" if method == "POST" else "params"
259305
return f"{_API_URL}/{api_version}/{endpoint}", {request_kwarg: data}
260-
261-
262-
def _akismet_response(endpoint: str, response: httpx.Response) -> httpx.Response:
263-
"""
264-
Check the response to see if it indicates an invalid key.
265-
266-
"""
267-
# It's possible to construct a client without performing up-front API key
268-
# validation, in which case the responses will all have text "invalid". So we check
269-
# for that and raise an exception when it's detected.
270-
if endpoint != _VERIFY_KEY and response.text == "invalid":
271-
raise _exceptions.APIKeyError("Akismet API key and/or site URL are invalid.")
272-
return response
273-
274-
275-
def _submit_response(endpoint: str, response: httpx.Response) -> bool:
276-
"""
277-
Proces the response from a submit (ham/spam) request.
278-
279-
"""
280-
if response.text == _SUBMISSION_RESPONSE:
281-
return True
282-
_protocol_error(endpoint, response)
283-
284-
285-
def _verify_key_response(response: httpx.Response) -> bool:
286-
"""
287-
Handle the response from a verify_key() request.
288-
289-
"""
290-
if response.text == "valid":
291-
return True
292-
if response.text == "invalid":
293-
return False
294-
_protocol_error(_VERIFY_KEY, response)

src/akismet/_sync_client.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ def _request(
254254
raise _exceptions.RequestError("Error making request to Akismet.") from exc
255255
except Exception as exc:
256256
raise _exceptions.RequestError("Error making request to Akismet.") from exc
257-
return _common._akismet_response(endpoint, response)
257+
return _common._handle_akismet_response(endpoint, response)
258258

259259
def _get_request(self, version: str, endpoint: str, params: dict) -> httpx.Response:
260260
"""
@@ -309,7 +309,7 @@ def _post_request(
309309
"api_key": self._config.key,
310310
"blog": self._config.url,
311311
"user_ip": user_ip,
312-
**_common._check_post_kwargs(kwargs, endpoint),
312+
**_common._prepare_post_kwargs(kwargs, endpoint),
313313
},
314314
)
315315

@@ -328,7 +328,7 @@ def _submit(
328328
received from the Akismet API.
329329
330330
"""
331-
return _common._submit_response(
331+
return _common._handle_submit_response(
332332
endpoint,
333333
self._post_request(_common._API_V11, endpoint, user_ip=user_ip, **kwargs),
334334
)
@@ -561,7 +561,7 @@ def verify_key(self, key: Optional[str] = None, url: Optional[str] = None) -> bo
561561
"""
562562
if not all([key, url]):
563563
key, url = self._config
564-
return _common._verify_key_response(
564+
return _common._handle_verify_key_response(
565565
self._request(
566566
"POST", _common._API_V11, _common._VERIFY_KEY, {"key": key, "blog": url}
567567
)

0 commit comments

Comments
 (0)