Skip to content

Commit 06fdbd4

Browse files
authored
Merge pull request #29 from newsdataapi/new_updates
New updates
2 parents ed70045 + b8ad6dd commit 06fdbd4

4 files changed

Lines changed: 94 additions & 4 deletions

File tree

‎src/newsdataapi/__init__.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
)
1616
from .websocket import NewsDataApiWebSocket
1717

18-
__version__ = "0.3.1"
18+
__version__ = "0.3.2"
1919

2020
__all__ = [
2121
"NewsDataApiClient",

‎src/newsdataapi/client.py‎

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
"domain",
4848
"domainurl",
4949
"excludedomain",
50+
"excludedomainurl",
5051
"timezone",
5152
"from_date",
5253
"to_date",
@@ -81,7 +82,7 @@
8182
("country", "excludecountry"),
8283
("category", "excludecategory"),
8384
("language", "excludelanguage"),
84-
("domain", "domainurl", "excludedomain"),
85+
("domain", "domainurl", "excludedomain", "excludedomainurl"),
8586
)
8687

8788
_QUOTA_EXHAUSTED_CODES = frozenset({"ApiKeyLimitExceeded", "ApiLimitExceeded"})
@@ -103,7 +104,8 @@ def _validate_params(user_params: Mapping[str, Any]) -> dict[str, Any]:
103104
* Server-side mutex groups (``q``/``qInTitle``/``qInMeta``,
104105
``country``/``excludecountry``, ``category``/``excludecategory``,
105106
``language``/``excludelanguage``, and
106-
``domain``/``domainurl``/``excludedomain``) are enforced client-side;
107+
``domain``/``domainurl``/``excludedomain``/``excludedomainurl``) are
108+
enforced client-side;
107109
setting more than one from any group raises
108110
``NewsdataValidationError`` before the request leaves.
109111
* ``sentiment_score`` requires ``sentiment`` to be set; passing
@@ -480,6 +482,7 @@ def latest_api(
480482
domain: str | list[str] | None = None,
481483
domainurl: str | list[str] | None = None,
482484
excludedomain: str | list[str] | None = None,
485+
excludedomainurl: str | list[str] | None = None,
483486
prioritydomain: str | None = None,
484487
timeframe: int | str | None = None,
485488
timezone: str | None = None,
@@ -528,6 +531,7 @@ def latest_api(
528531
"domain": domain,
529532
"domainurl": domainurl,
530533
"excludedomain": excludedomain,
534+
"excludedomainurl": excludedomainurl,
531535
"prioritydomain": prioritydomain,
532536
"timeframe": str(timeframe) if timeframe is not None else None,
533537
"timezone": timezone,
@@ -571,6 +575,7 @@ def archive_api(
571575
domain: str | list[str] | None = None,
572576
domainurl: str | list[str] | None = None,
573577
excludedomain: str | list[str] | None = None,
578+
excludedomainurl: str | list[str] | None = None,
574579
prioritydomain: str | None = None,
575580
timezone: str | None = None,
576581
size: int | None = None,
@@ -617,6 +622,7 @@ def archive_api(
617622
"domain": domain,
618623
"domainurl": domainurl,
619624
"excludedomain": excludedomain,
625+
"excludedomainurl": excludedomainurl,
620626
"prioritydomain": prioritydomain,
621627
"timezone": timezone,
622628
"size": size,
@@ -684,6 +690,7 @@ def crypto_api(
684690
domain: str | list[str] | None = None,
685691
domainurl: str | list[str] | None = None,
686692
excludedomain: str | list[str] | None = None,
693+
excludedomainurl: str | list[str] | None = None,
687694
prioritydomain: str | None = None,
688695
timeframe: int | str | None = None,
689696
timezone: str | None = None,
@@ -723,6 +730,7 @@ def crypto_api(
723730
"domain": domain,
724731
"domainurl": domainurl,
725732
"excludedomain": excludedomain,
733+
"excludedomainurl": excludedomainurl,
726734
"prioritydomain": prioritydomain,
727735
"timeframe": str(timeframe) if timeframe is not None else None,
728736
"timezone": timezone,
@@ -762,6 +770,7 @@ def market_api(
762770
domain: str | list[str] | None = None,
763771
domainurl: str | list[str] | None = None,
764772
excludedomain: str | list[str] | None = None,
773+
excludedomainurl: str | list[str] | None = None,
765774
language: str | list[str] | None = None,
766775
excludelanguage: str | list[str] | None = None,
767776
prioritydomain: str | None = None,
@@ -807,6 +816,7 @@ def market_api(
807816
"domain": domain,
808817
"domainurl": domainurl,
809818
"excludedomain": excludedomain,
819+
"excludedomainurl": excludedomainurl,
810820
"language": language,
811821
"excludelanguage": excludelanguage,
812822
"prioritydomain": prioritydomain,
@@ -854,6 +864,7 @@ def count_api(
854864
domain: str | list[str] | None = None,
855865
domainurl: str | list[str] | None = None,
856866
excludedomain: str | list[str] | None = None,
867+
excludedomainurl: str | list[str] | None = None,
857868
full_content: bool | None = None,
858869
image: bool | None = None,
859870
video: bool | None = None,
@@ -901,6 +912,7 @@ def count_api(
901912
"domain": domain,
902913
"domainurl": domainurl,
903914
"excludedomain": excludedomain,
915+
"excludedomainurl": excludedomainurl,
904916
"full_content": full_content,
905917
"image": image,
906918
"video": video,
@@ -940,6 +952,7 @@ def crypto_count_api(
940952
domain: str | list[str] | None = None,
941953
domainurl: str | list[str] | None = None,
942954
excludedomain: str | list[str] | None = None,
955+
excludedomainurl: str | list[str] | None = None,
943956
full_content: bool | None = None,
944957
image: bool | None = None,
945958
video: bool | None = None,
@@ -978,6 +991,7 @@ def crypto_count_api(
978991
"domain": domain,
979992
"domainurl": domainurl,
980993
"excludedomain": excludedomain,
994+
"excludedomainurl": excludedomainurl,
981995
"full_content": full_content,
982996
"image": image,
983997
"video": video,
@@ -1011,6 +1025,7 @@ def market_count_api(
10111025
domain: str | list[str] | None = None,
10121026
domainurl: str | list[str] | None = None,
10131027
excludedomain: str | list[str] | None = None,
1028+
excludedomainurl: str | list[str] | None = None,
10141029
language: str | list[str] | None = None,
10151030
excludelanguage: str | list[str] | None = None,
10161031
full_content: bool | None = None,
@@ -1055,6 +1070,7 @@ def market_count_api(
10551070
"domain": domain,
10561071
"domainurl": domainurl,
10571072
"excludedomain": excludedomain,
1073+
"excludedomainurl": excludedomainurl,
10581074
"language": language,
10591075
"excludelanguage": excludelanguage,
10601076
"full_content": full_content,

‎src/newsdataapi/websocket.py‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,7 @@ def websocket_register(
177177
domain: str | list[str] | None = None,
178178
domainurl: str | list[str] | None = None,
179179
excludedomain: str | list[str] | None = None,
180+
excludedomainurl: str | list[str] | None = None,
180181
prioritydomain: str | None = None,
181182
timezone: str | None = None,
182183
full_content: bool | None = None,
@@ -212,6 +213,7 @@ def websocket_register(
212213
"domain": domain,
213214
"domainurl": domainurl,
214215
"excludedomain": excludedomain,
216+
"excludedomainurl": excludedomainurl,
215217
"prioritydomain": prioritydomain,
216218
"timezone": timezone,
217219
"full_content": full_content,

‎tests/test_unit.py‎

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,13 +148,23 @@ def test_validate_size_negative_rejected() -> None:
148148
({"country": "us", "excludecountry": "gb"}, "country"),
149149
({"category": "business", "excludecategory": "sports"}, "category"),
150150
({"language": "en", "excludelanguage": "fr"}, "language"),
151-
# Domain 3-way mutex (any two of domain/domainurl/excludedomain)
151+
# Domain 4-way mutex (any two of
152+
# domain/domainurl/excludedomain/excludedomainurl)
152153
({"domain": "cnn.com", "domainurl": "https://bbc.com"}, "domain"),
153154
({"domain": "cnn.com", "excludedomain": "fox.com"}, "domain"),
154155
(
155156
{"domainurl": "https://bbc.com", "excludedomain": "fox.com"},
156157
"domainurl",
157158
),
159+
({"domain": "cnn.com", "excludedomainurl": "fox.com"}, "domain"),
160+
(
161+
{"domainurl": "https://bbc.com", "excludedomainurl": "fox.com"},
162+
"domainurl",
163+
),
164+
(
165+
{"excludedomain": "cnn.com", "excludedomainurl": "fox.com"},
166+
"excludedomain",
167+
),
158168
(
159169
{
160170
"domain": "cnn.com",
@@ -1285,6 +1295,51 @@ def test_count_endpoint_url_resolves(
12851295
assert len(mocked_responses.calls) == 1
12861296

12871297

1298+
@pytest.mark.parametrize(
1299+
("method_name", "endpoint_path", "args"),
1300+
[
1301+
("latest_api", "latest", ()),
1302+
("archive_api", "archive", ()),
1303+
("crypto_api", "crypto", ()),
1304+
("market_api", "market", ()),
1305+
("count_api", "count", ("2024-01-01", "2024-01-31")),
1306+
("crypto_count_api", "crypto/count", ("2024-01-01", "2024-01-31")),
1307+
("market_count_api", "market/count", ("2024-01-01", "2024-01-31")),
1308+
],
1309+
)
1310+
def test_excludedomainurl_sent_as_csv(
1311+
client: NewsDataApiClient,
1312+
mocked_responses: responses.RequestsMock,
1313+
method_name: str,
1314+
endpoint_path: str,
1315+
args: tuple[str, ...],
1316+
) -> None:
1317+
mocked_responses.get(
1318+
f"https://newsdata.io/api/1/{endpoint_path}",
1319+
json={"status": "success", "results": []},
1320+
status=200,
1321+
)
1322+
getattr(client, method_name)(*args, excludedomainurl=["bbc.com", "cnn.com"])
1323+
sent_url = mocked_responses.calls[0].request.url
1324+
assert sent_url is not None
1325+
assert "excludedomainurl=bbc.com%2Ccnn.com" in sent_url
1326+
1327+
1328+
def test_raw_query_accepts_excludedomainurl(
1329+
client: NewsDataApiClient,
1330+
mocked_responses: responses.RequestsMock,
1331+
) -> None:
1332+
mocked_responses.get(
1333+
LATEST_URL,
1334+
json={"status": "success", "results": []},
1335+
status=200,
1336+
)
1337+
client.latest_api(raw_query="excludedomainurl=bbc.com")
1338+
sent_url = mocked_responses.calls[0].request.url
1339+
assert sent_url is not None
1340+
assert "excludedomainurl=bbc.com" in sent_url
1341+
1342+
12881343
# ===========================================================================
12891344
# WebSocket query management (register / fetch / delete)
12901345
# ===========================================================================
@@ -1367,6 +1422,23 @@ def test_websocket_register_raw_query_rejects_unknown_param(
13671422
NewsDataApiWebSocket(client).websocket_register(raw_query="q=pizza&size=10")
13681423

13691424

1425+
def test_websocket_register_sends_excludedomainurl(
1426+
client: NewsDataApiClient,
1427+
mocked_responses: responses.RequestsMock,
1428+
) -> None:
1429+
mocked_responses.post(
1430+
WS_REGISTER_URL,
1431+
json={"status": "success", "results": {"registration_id": "abc"}},
1432+
status=200,
1433+
)
1434+
NewsDataApiWebSocket(client).websocket_register(
1435+
q="pizza", excludedomainurl=["bbc.com", "cnn.com"]
1436+
)
1437+
sent_url = mocked_responses.calls[0].request.url
1438+
assert sent_url is not None
1439+
assert "excludedomainurl=bbc.com%2Ccnn.com" in sent_url
1440+
1441+
13701442
def test_websocket_register_duplicate_409(
13711443
client: NewsDataApiClient,
13721444
mocked_responses: responses.RequestsMock,

0 commit comments

Comments
 (0)