Skip to content

Commit e5b33d6

Browse files
Werdedferhatelmas
authored andcommitted
feat: added async support
1 parent 87ea6b2 commit e5b33d6

36 files changed

+3553
-933
lines changed

.coveragerc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[run]
2+
omit = stream/tests/*

.github/workflows/ci.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@ jobs:
1414
name: 🧪 Test & lint
1515
runs-on: ubuntu-latest
1616
strategy:
17+
max-parallel: 1
1718
matrix:
18-
python: ["3.7", "3.8", "3.9", "3.10"]
19+
python: ['3.7', '3.8', '3.9', '3.10']
1920
steps:
2021
- uses: actions/checkout@v3
2122
with:
@@ -30,7 +31,7 @@ jobs:
3031
python-version: ${{ matrix.python }}
3132

3233
- name: Install deps with ${{ matrix.python }}
33-
run: pip install ".[test, ci]"
34+
run: pip install -q ".[test, ci]"
3435

3536
- name: Lint with ${{ matrix.python }}
3637
if: ${{ matrix.python == '3.7' }}

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ docs/_build/
5858
secrets.*sh
5959
.idea
6060
.vscode/
61+
.python-version
6162

6263
.venv
6364
.envrc

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ lint-fix:
1919
test: ## Run tests
2020
STREAM_KEY=$(STREAM_KEY) STREAM_SECRET=$(STREAM_SECRET) pytest stream/tests
2121

22+
2223
check: lint test ## Run linters + tests
2324

2425
reviewdog:

README.md

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,9 +163,135 @@ events = [impression, engagement]
163163
redirect_url = client.create_redirect_url('http://google.com/', 'user_id', events)
164164
```
165165

166+
### Async code usage
167+
```python
168+
import datetime
169+
import stream
170+
client = stream.connect('YOUR_API_KEY', 'API_KEY_SECRET', use_async=True)
171+
172+
173+
# Create a new client specifying data center location
174+
client = stream.connect('YOUR_API_KEY', 'API_KEY_SECRET', location='us-east', use_async=True)
175+
# Find your API keys here https://getstream.io/dashboard/
176+
177+
# Create a feed object
178+
user_feed_1 = client.feed('user', '1')
179+
180+
# Get activities from 5 to 10 (slow pagination)
181+
result = await user_feed_1.get(limit=5, offset=5)
182+
# (Recommended & faster) Filter on an id less than the given UUID
183+
result = await user_feed_1.get(limit=5, id_lt="e561de8f-00f1-11e4-b400-0cc47a024be0")
184+
185+
# Create a new activity
186+
activity_data = {'actor': 1, 'verb': 'tweet', 'object': 1, 'foreign_id': 'tweet:1'}
187+
activity_response = await user_feed_1.add_activity(activity_data)
188+
# Create a bit more complex activity
189+
activity_data = {'actor': 1, 'verb': 'run', 'object': 1, 'foreign_id': 'run:1',
190+
'course': {'name': 'Golden Gate park', 'distance': 10},
191+
'participants': ['Thierry', 'Tommaso'],
192+
'started_at': datetime.datetime.now()
193+
}
194+
await user_feed_1.add_activity(activity_data)
195+
196+
# Remove an activity by its id
197+
await user_feed_1.remove_activity("e561de8f-00f1-11e4-b400-0cc47a024be0")
198+
# or by foreign id
199+
await user_feed_1.remove_activity(foreign_id='tweet:1')
200+
201+
# Follow another feed
202+
await user_feed_1.follow('flat', '42')
203+
204+
# Stop following another feed
205+
await user_feed_1.unfollow('flat', '42')
206+
207+
# List followers/following
208+
following = await user_feed_1.following(offset=0, limit=2)
209+
followers = await user_feed_1.followers(offset=0, limit=10)
210+
211+
# Creates many follow relationships in one request
212+
follows = [
213+
{'source': 'flat:1', 'target': 'user:1'},
214+
{'source': 'flat:1', 'target': 'user:2'},
215+
{'source': 'flat:1', 'target': 'user:3'}
216+
]
217+
await client.follow_many(follows)
218+
219+
# Batch adding activities
220+
activities = [
221+
{'actor': 1, 'verb': 'tweet', 'object': 1},
222+
{'actor': 2, 'verb': 'watch', 'object': 3}
223+
]
224+
await user_feed_1.add_activities(activities)
225+
226+
# Add an activity and push it to other feeds too using the `to` field
227+
activity = {
228+
"actor":"1",
229+
"verb":"like",
230+
"object":"3",
231+
"to":["user:44", "user:45"]
232+
}
233+
await user_feed_1.add_activity(activity)
234+
235+
# Retrieve an activity by its ID
236+
await client.get_activities(ids=[activity_id])
237+
238+
# Retrieve an activity by the combination of foreign_id and time
239+
await client.get_activities(foreign_id_times=[
240+
(foreign_id, activity_time),
241+
])
242+
243+
# Enrich while getting activities
244+
await client.get_activities(ids=[activity_id], enrich=True, reactions={"counts": True})
245+
246+
# Update some parts of an activity with activity_partial_update
247+
set = {
248+
'product.name': 'boots',
249+
'colors': {
250+
'red': '0xFF0000',
251+
'green': '0x00FF00'
252+
}
253+
}
254+
unset = [ 'popularity', 'details.info' ]
255+
# ...by ID
256+
await client.activity_partial_update(id=activity_id, set=set, unset=unset)
257+
# ...or by combination of foreign_id and time
258+
await client.activity_partial_update(foreign_id=foreign_id, time=activity_time, set=set, unset=unset)
259+
260+
# Generating user token for client side usage (JS client)
261+
user_token = client.create_user_token("user-42")
262+
263+
# Javascript client side feed initialization
264+
# client = stream.connect(apiKey, userToken, appId);
265+
266+
# Generate a redirect url for the Stream Analytics platform to track
267+
# events/impressions on url clicks
268+
impression = {
269+
'content_list': ['tweet:1', 'tweet:2', 'tweet:3'],
270+
'user_data': 'tommaso',
271+
'location': 'email',
272+
'feed_id': 'user:global'
273+
}
274+
275+
engagement = {
276+
'content': 'tweet:2',
277+
'label': 'click',
278+
'position': 1,
279+
'user_data': 'tommaso',
280+
'location': 'email',
281+
'feed_id':
282+
'user:global'
283+
}
284+
285+
events = [impression, engagement]
286+
287+
redirect_url = client.create_redirect_url('http://google.com/', 'user_id', events)
288+
289+
```
290+
166291
[JS client](http://github.com/getstream/stream-js).
167292

168293
## ✍️ Contributing
294+
=======
169295

170296
We welcome code changes that improve this library or fix a problem, please make sure to follow all best practices and add tests if applicable before submitting a Pull Request on Github. We are very happy to merge your code in the official repository. Make sure to sign our [Contributor License Agreement (CLA)](https://docs.google.com/forms/d/e/1FAIpQLScFKsKkAJI7mhCr7K9rEIOpqIDThrWxuvxnwUq2XkHyG154vQ/viewform) first. See our [license file](./LICENSE) for more details.
171297

setup.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@
88
"requests>=2.3.0,<3",
99
"pyjwt>=2.0.0,<3",
1010
"pytz>=2019.3",
11+
"aiohttp>=3.6.0",
1112
]
12-
tests_require = ["pytest", "pytest-cov", "python-dateutil"]
13+
tests_require = ["pytest", "pytest-cov", "python-dateutil", "pytest-asyncio"]
1314
ci_require = ["black", "flake8", "pytest-cov"]
1415

1516
long_description = open("README.md", "r").read()

stream/__init__.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,17 @@ def connect(
1919
timeout=3.0,
2020
location=None,
2121
base_url=None,
22+
use_async=False,
2223
):
2324
"""
2425
Returns a Client object
2526
2627
:param api_key: your api key or heroku url
2728
:param api_secret: the api secret
2829
:param app_id: the app id (used for listening to feed changes)
30+
:param use_async: flag to set AsyncClient
2931
"""
30-
from stream.client import StreamClient
32+
from stream.client import AsyncStreamClient, StreamClient
3133

3234
stream_url = os.environ.get("STREAM_URL")
3335
# support for the heroku STREAM_URL syntax
@@ -42,6 +44,17 @@ def connect(
4244
else:
4345
raise ValueError("Invalid api key or heroku url")
4446

47+
if use_async:
48+
return AsyncStreamClient(
49+
api_key,
50+
api_secret,
51+
app_id,
52+
version,
53+
timeout,
54+
location=location,
55+
base_url=base_url,
56+
)
57+
4558
return StreamClient(
4659
api_key,
4760
api_secret,

stream/client/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from .async_client import AsyncStreamClient
2+
from .client import StreamClient

0 commit comments

Comments
 (0)