You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 59d5431
Browse filesBrowse the repository at this point in the historyBrowse files
Copy file name to clipboardExpand all lines: README.md
+84-5Lines changed: 84 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -13,7 +13,7 @@
13
13
14
14
</div>
15
15
16
-
`newsdataapi` is the official Python SDK for the [NewsData.io](https://newsdata.io) REST API. It wraps every endpoint (`latest`, `archive`, `sources`, `crypto`, `market`, `count`, `crypto/count`, `market/count`) with consistent retry, pagination, and error handling.
16
+
`newsdataapi` is the official Python SDK for the [NewsData.io](https://newsdata.io) REST API. It wraps every endpoint (`latest`, `archive`, `sources`, `crypto`, `market`, `count`, `crypto/count`, `market/count`) with consistent retry, pagination, and error handling. It also covers the real-time WebSocket service end to end with `NewsDataApiWebSocket`: register, list, and delete queries, and stream the matching news as it is published (sync or asyncio).
17
17
18
18
## Installation
19
19
@@ -27,7 +27,7 @@ If you use [uv](https://github.com/astral-sh/uv):
27
27
uv add newsdataapi
28
28
```
29
29
30
-
Supports Python 3.8 through 3.14. The only runtime dependency is`requests`.
30
+
Supports Python 3.10 through 3.14. The runtime dependencies are`requests` (REST) and `websockets` (real-time streaming).
All endpoint parameters are keyword-only (except the required `from_date` / `to_date` on the count endpoints). Most accept either a single string or a `list[str]`; lists are comma-joined for the API.
70
+
All endpoint parameters are keyword-only (except the required `from_date` / `to_date` on the count endpoints). Most accept either a single string or a `list[str]`; lists are comma-joined for the API. The real-time WebSocket endpoints are covered by `NewsDataApiWebSocket` (see below).
71
71
72
72
See the [NewsData.io documentation](https://newsdata.io/documentation) — or the [OpenAPI 3.1 spec](https://newsdata.io/openapi.json) — for the full parameter reference.
73
73
@@ -87,6 +87,83 @@ for page in client.latest_api(q="news", paginate=True, max_pages=5):
87
87
88
88
`scroll` and `paginate` are mutually exclusive. `scroll=True` truncates strictly to `max_result`; `paginate=True` stops at `max_pages` or when the API returns no `nextPage`.
89
89
90
+
## Real-time news (WebSocket)
91
+
92
+
Register a query first — the returned `registration_id` identifies it from then on:
93
+
94
+
```python
95
+
from newsdataapi import NewsDataApiClient, NewsDataApiWebSocket
`websocket_register` accepts the familiar filter parameters (`q`, `country`, `language`, `domain`, …). Registering an identical query twice raises `NewsdataAPIError` with `status_code=409` — the existing id is in `e.response_body["results"]["registration_id"]`. `websocket_fetch()` lists every registered query, and `websocket_delete(registration_id)` removes one.
104
+
105
+
Then stream — each yielded response has the familiar `status` / `totalResults` / `results` shape:
106
+
107
+
```python
108
+
for response in ws.stream(registration_id):
109
+
for article in response["results"]:
110
+
print(article["title"], "-", article["link"])
111
+
```
112
+
113
+
Use it as a context manager to close the connection promptly when you stop early (otherwise it closes when iteration ends):
114
+
115
+
```python
116
+
with NewsDataApiWebSocket(client) as ws:
117
+
for response in ws.stream(registration_id):
118
+
print(response["totalResults"])
119
+
break
120
+
```
121
+
122
+
Inside asyncio applications use `stream_async()` — the same class, same behavior, awaited iteration:
123
+
124
+
```python
125
+
import asyncio
126
+
127
+
asyncdefmain():
128
+
asyncwith NewsDataApiWebSocket(client) as ws:
129
+
asyncfor response in ws.stream_async(registration_id):
130
+
for article in response["results"]:
131
+
print(article["title"], "-", article["link"])
132
+
133
+
asyncio.run(main())
134
+
```
135
+
136
+
Transient drops (network errors, server restarts, abnormal closes) are reconnected automatically with a capped exponential backoff. Pass `reconnect=False` to stop on the first disconnect instead. A permanent rejection — bad API key, missing WebSocket entitlement, unknown `registration_id`, device limit reached, or exhausted quota — raises `NewsdataWebSocketAuthError` and is **not** retried:
137
+
138
+
```python
139
+
from newsdataapi import NewsdataWebSocketAuthError, NewsdataWebSocketError
140
+
141
+
try:
142
+
for response in NewsDataApiWebSocket(client).stream(registration_id):
143
+
...
144
+
except NewsdataWebSocketAuthError as e:
145
+
print(f"rejected: {e}")
146
+
except NewsdataWebSocketError as e:
147
+
print(f"stream error: {e}")
148
+
```
149
+
150
+
All connection options are keyword-only:
151
+
152
+
```python
153
+
ws = NewsDataApiWebSocket(
154
+
client,
155
+
base_url="wss://ws.newsdata.io/ws/event", # override for staging / self-hosted / proxied
156
+
reconnect=True, # auto-reconnect on transient drops; default True
157
+
reconnect_delay=1.0, # seconds before first reconnect (doubles each retry)
158
+
reconnect_delay_max=30.0, # cap on the reconnect delay
0 commit comments