newsdataapi 0.3.1__tar.gz → 0.3.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {newsdataapi-0.3.1 → newsdataapi-0.3.2}/PKG-INFO +1 -1
- {newsdataapi-0.3.1 → newsdataapi-0.3.2}/src/newsdataapi/__init__.py +1 -1
- {newsdataapi-0.3.1 → newsdataapi-0.3.2}/src/newsdataapi/client.py +18 -2
- {newsdataapi-0.3.1 → newsdataapi-0.3.2}/src/newsdataapi/websocket.py +2 -0
- {newsdataapi-0.3.1 → newsdataapi-0.3.2}/tests/test_unit.py +73 -1
- {newsdataapi-0.3.1 → newsdataapi-0.3.2}/.github/workflows/ci.yml +0 -0
- {newsdataapi-0.3.1 → newsdataapi-0.3.2}/.github/workflows/publish.yml +0 -0
- {newsdataapi-0.3.1 → newsdataapi-0.3.2}/.gitignore +0 -0
- {newsdataapi-0.3.1 → newsdataapi-0.3.2}/.python-version +0 -0
- {newsdataapi-0.3.1 → newsdataapi-0.3.2}/LICENSE +0 -0
- {newsdataapi-0.3.1 → newsdataapi-0.3.2}/README.md +0 -0
- {newsdataapi-0.3.1 → newsdataapi-0.3.2}/examples/basic_usage.py +0 -0
- {newsdataapi-0.3.1 → newsdataapi-0.3.2}/examples/websocket_usage.py +0 -0
- {newsdataapi-0.3.1 → newsdataapi-0.3.2}/newsdata-logo.png +0 -0
- {newsdataapi-0.3.1 → newsdataapi-0.3.2}/pyproject.toml +0 -0
- {newsdataapi-0.3.1 → newsdataapi-0.3.2}/src/newsdataapi/constants.py +0 -0
- {newsdataapi-0.3.1 → newsdataapi-0.3.2}/src/newsdataapi/csv_export.py +0 -0
- {newsdataapi-0.3.1 → newsdataapi-0.3.2}/src/newsdataapi/exceptions.py +0 -0
- {newsdataapi-0.3.1 → newsdataapi-0.3.2}/src/newsdataapi/py.typed +0 -0
- {newsdataapi-0.3.1 → newsdataapi-0.3.2}/tests/__init__.py +0 -0
- {newsdataapi-0.3.1 → newsdataapi-0.3.2}/tests/conftest.py +0 -0
- {newsdataapi-0.3.1 → newsdataapi-0.3.2}/tests/test_integration.py +0 -0
- {newsdataapi-0.3.1 → newsdataapi-0.3.2}/tests/test_websocket.py +0 -0
- {newsdataapi-0.3.1 → newsdataapi-0.3.2}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: newsdataapi
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.2
|
|
4
4
|
Summary: Official Python client (SDK) for the Newsdata.io News API — fetch real-time, historical, crypto, and stock-market news via REST, with validation, retries, pagination, and typed exceptions.
|
|
5
5
|
Project-URL: Homepage, https://newsdata.io
|
|
6
6
|
Project-URL: Documentation, https://newsdata.io/documentation
|
|
@@ -47,6 +47,7 @@ _STRING_PARAMS = frozenset(
|
|
|
47
47
|
"domain",
|
|
48
48
|
"domainurl",
|
|
49
49
|
"excludedomain",
|
|
50
|
+
"excludedomainurl",
|
|
50
51
|
"timezone",
|
|
51
52
|
"from_date",
|
|
52
53
|
"to_date",
|
|
@@ -81,7 +82,7 @@ _MUTEX_GROUPS: tuple[tuple[str, ...], ...] = (
|
|
|
81
82
|
("country", "excludecountry"),
|
|
82
83
|
("category", "excludecategory"),
|
|
83
84
|
("language", "excludelanguage"),
|
|
84
|
-
("domain", "domainurl", "excludedomain"),
|
|
85
|
+
("domain", "domainurl", "excludedomain", "excludedomainurl"),
|
|
85
86
|
)
|
|
86
87
|
|
|
87
88
|
_QUOTA_EXHAUSTED_CODES = frozenset({"ApiKeyLimitExceeded", "ApiLimitExceeded"})
|
|
@@ -103,7 +104,8 @@ def _validate_params(user_params: Mapping[str, Any]) -> dict[str, Any]:
|
|
|
103
104
|
* Server-side mutex groups (``q``/``qInTitle``/``qInMeta``,
|
|
104
105
|
``country``/``excludecountry``, ``category``/``excludecategory``,
|
|
105
106
|
``language``/``excludelanguage``, and
|
|
106
|
-
``domain``/``domainurl``/``excludedomain``) are
|
|
107
|
+
``domain``/``domainurl``/``excludedomain``/``excludedomainurl``) are
|
|
108
|
+
enforced client-side;
|
|
107
109
|
setting more than one from any group raises
|
|
108
110
|
``NewsdataValidationError`` before the request leaves.
|
|
109
111
|
* ``sentiment_score`` requires ``sentiment`` to be set; passing
|
|
@@ -480,6 +482,7 @@ class NewsDataApiClient:
|
|
|
480
482
|
domain: str | list[str] | None = None,
|
|
481
483
|
domainurl: str | list[str] | None = None,
|
|
482
484
|
excludedomain: str | list[str] | None = None,
|
|
485
|
+
excludedomainurl: str | list[str] | None = None,
|
|
483
486
|
prioritydomain: str | None = None,
|
|
484
487
|
timeframe: int | str | None = None,
|
|
485
488
|
timezone: str | None = None,
|
|
@@ -528,6 +531,7 @@ class NewsDataApiClient:
|
|
|
528
531
|
"domain": domain,
|
|
529
532
|
"domainurl": domainurl,
|
|
530
533
|
"excludedomain": excludedomain,
|
|
534
|
+
"excludedomainurl": excludedomainurl,
|
|
531
535
|
"prioritydomain": prioritydomain,
|
|
532
536
|
"timeframe": str(timeframe) if timeframe is not None else None,
|
|
533
537
|
"timezone": timezone,
|
|
@@ -571,6 +575,7 @@ class NewsDataApiClient:
|
|
|
571
575
|
domain: str | list[str] | None = None,
|
|
572
576
|
domainurl: str | list[str] | None = None,
|
|
573
577
|
excludedomain: str | list[str] | None = None,
|
|
578
|
+
excludedomainurl: str | list[str] | None = None,
|
|
574
579
|
prioritydomain: str | None = None,
|
|
575
580
|
timezone: str | None = None,
|
|
576
581
|
size: int | None = None,
|
|
@@ -617,6 +622,7 @@ class NewsDataApiClient:
|
|
|
617
622
|
"domain": domain,
|
|
618
623
|
"domainurl": domainurl,
|
|
619
624
|
"excludedomain": excludedomain,
|
|
625
|
+
"excludedomainurl": excludedomainurl,
|
|
620
626
|
"prioritydomain": prioritydomain,
|
|
621
627
|
"timezone": timezone,
|
|
622
628
|
"size": size,
|
|
@@ -684,6 +690,7 @@ class NewsDataApiClient:
|
|
|
684
690
|
domain: str | list[str] | None = None,
|
|
685
691
|
domainurl: str | list[str] | None = None,
|
|
686
692
|
excludedomain: str | list[str] | None = None,
|
|
693
|
+
excludedomainurl: str | list[str] | None = None,
|
|
687
694
|
prioritydomain: str | None = None,
|
|
688
695
|
timeframe: int | str | None = None,
|
|
689
696
|
timezone: str | None = None,
|
|
@@ -723,6 +730,7 @@ class NewsDataApiClient:
|
|
|
723
730
|
"domain": domain,
|
|
724
731
|
"domainurl": domainurl,
|
|
725
732
|
"excludedomain": excludedomain,
|
|
733
|
+
"excludedomainurl": excludedomainurl,
|
|
726
734
|
"prioritydomain": prioritydomain,
|
|
727
735
|
"timeframe": str(timeframe) if timeframe is not None else None,
|
|
728
736
|
"timezone": timezone,
|
|
@@ -762,6 +770,7 @@ class NewsDataApiClient:
|
|
|
762
770
|
domain: str | list[str] | None = None,
|
|
763
771
|
domainurl: str | list[str] | None = None,
|
|
764
772
|
excludedomain: str | list[str] | None = None,
|
|
773
|
+
excludedomainurl: str | list[str] | None = None,
|
|
765
774
|
language: str | list[str] | None = None,
|
|
766
775
|
excludelanguage: str | list[str] | None = None,
|
|
767
776
|
prioritydomain: str | None = None,
|
|
@@ -807,6 +816,7 @@ class NewsDataApiClient:
|
|
|
807
816
|
"domain": domain,
|
|
808
817
|
"domainurl": domainurl,
|
|
809
818
|
"excludedomain": excludedomain,
|
|
819
|
+
"excludedomainurl": excludedomainurl,
|
|
810
820
|
"language": language,
|
|
811
821
|
"excludelanguage": excludelanguage,
|
|
812
822
|
"prioritydomain": prioritydomain,
|
|
@@ -854,6 +864,7 @@ class NewsDataApiClient:
|
|
|
854
864
|
domain: str | list[str] | None = None,
|
|
855
865
|
domainurl: str | list[str] | None = None,
|
|
856
866
|
excludedomain: str | list[str] | None = None,
|
|
867
|
+
excludedomainurl: str | list[str] | None = None,
|
|
857
868
|
full_content: bool | None = None,
|
|
858
869
|
image: bool | None = None,
|
|
859
870
|
video: bool | None = None,
|
|
@@ -901,6 +912,7 @@ class NewsDataApiClient:
|
|
|
901
912
|
"domain": domain,
|
|
902
913
|
"domainurl": domainurl,
|
|
903
914
|
"excludedomain": excludedomain,
|
|
915
|
+
"excludedomainurl": excludedomainurl,
|
|
904
916
|
"full_content": full_content,
|
|
905
917
|
"image": image,
|
|
906
918
|
"video": video,
|
|
@@ -940,6 +952,7 @@ class NewsDataApiClient:
|
|
|
940
952
|
domain: str | list[str] | None = None,
|
|
941
953
|
domainurl: str | list[str] | None = None,
|
|
942
954
|
excludedomain: str | list[str] | None = None,
|
|
955
|
+
excludedomainurl: str | list[str] | None = None,
|
|
943
956
|
full_content: bool | None = None,
|
|
944
957
|
image: bool | None = None,
|
|
945
958
|
video: bool | None = None,
|
|
@@ -978,6 +991,7 @@ class NewsDataApiClient:
|
|
|
978
991
|
"domain": domain,
|
|
979
992
|
"domainurl": domainurl,
|
|
980
993
|
"excludedomain": excludedomain,
|
|
994
|
+
"excludedomainurl": excludedomainurl,
|
|
981
995
|
"full_content": full_content,
|
|
982
996
|
"image": image,
|
|
983
997
|
"video": video,
|
|
@@ -1011,6 +1025,7 @@ class NewsDataApiClient:
|
|
|
1011
1025
|
domain: str | list[str] | None = None,
|
|
1012
1026
|
domainurl: str | list[str] | None = None,
|
|
1013
1027
|
excludedomain: str | list[str] | None = None,
|
|
1028
|
+
excludedomainurl: str | list[str] | None = None,
|
|
1014
1029
|
language: str | list[str] | None = None,
|
|
1015
1030
|
excludelanguage: str | list[str] | None = None,
|
|
1016
1031
|
full_content: bool | None = None,
|
|
@@ -1055,6 +1070,7 @@ class NewsDataApiClient:
|
|
|
1055
1070
|
"domain": domain,
|
|
1056
1071
|
"domainurl": domainurl,
|
|
1057
1072
|
"excludedomain": excludedomain,
|
|
1073
|
+
"excludedomainurl": excludedomainurl,
|
|
1058
1074
|
"language": language,
|
|
1059
1075
|
"excludelanguage": excludelanguage,
|
|
1060
1076
|
"full_content": full_content,
|
|
@@ -177,6 +177,7 @@ class NewsDataApiWebSocket:
|
|
|
177
177
|
domain: str | list[str] | None = None,
|
|
178
178
|
domainurl: str | list[str] | None = None,
|
|
179
179
|
excludedomain: str | list[str] | None = None,
|
|
180
|
+
excludedomainurl: str | list[str] | None = None,
|
|
180
181
|
prioritydomain: str | None = None,
|
|
181
182
|
timezone: str | None = None,
|
|
182
183
|
full_content: bool | None = None,
|
|
@@ -212,6 +213,7 @@ class NewsDataApiWebSocket:
|
|
|
212
213
|
"domain": domain,
|
|
213
214
|
"domainurl": domainurl,
|
|
214
215
|
"excludedomain": excludedomain,
|
|
216
|
+
"excludedomainurl": excludedomainurl,
|
|
215
217
|
"prioritydomain": prioritydomain,
|
|
216
218
|
"timezone": timezone,
|
|
217
219
|
"full_content": full_content,
|
|
@@ -148,13 +148,23 @@ def test_validate_size_negative_rejected() -> None:
|
|
|
148
148
|
({"country": "us", "excludecountry": "gb"}, "country"),
|
|
149
149
|
({"category": "business", "excludecategory": "sports"}, "category"),
|
|
150
150
|
({"language": "en", "excludelanguage": "fr"}, "language"),
|
|
151
|
-
# Domain
|
|
151
|
+
# Domain 4-way mutex (any two of
|
|
152
|
+
# domain/domainurl/excludedomain/excludedomainurl)
|
|
152
153
|
({"domain": "cnn.com", "domainurl": "https://bbc.com"}, "domain"),
|
|
153
154
|
({"domain": "cnn.com", "excludedomain": "fox.com"}, "domain"),
|
|
154
155
|
(
|
|
155
156
|
{"domainurl": "https://bbc.com", "excludedomain": "fox.com"},
|
|
156
157
|
"domainurl",
|
|
157
158
|
),
|
|
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
|
+
),
|
|
158
168
|
(
|
|
159
169
|
{
|
|
160
170
|
"domain": "cnn.com",
|
|
@@ -1285,6 +1295,51 @@ def test_count_endpoint_url_resolves(
|
|
|
1285
1295
|
assert len(mocked_responses.calls) == 1
|
|
1286
1296
|
|
|
1287
1297
|
|
|
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
|
+
|
|
1288
1343
|
# ===========================================================================
|
|
1289
1344
|
# WebSocket query management (register / fetch / delete)
|
|
1290
1345
|
# ===========================================================================
|
|
@@ -1367,6 +1422,23 @@ def test_websocket_register_raw_query_rejects_unknown_param(
|
|
|
1367
1422
|
NewsDataApiWebSocket(client).websocket_register(raw_query="q=pizza&size=10")
|
|
1368
1423
|
|
|
1369
1424
|
|
|
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
|
+
|
|
1370
1442
|
def test_websocket_register_duplicate_409(
|
|
1371
1443
|
client: NewsDataApiClient,
|
|
1372
1444
|
mocked_responses: responses.RequestsMock,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|