Skip to content

Commit 44d1a6a

Browse files
authored
feat(import): add import endpoints (#121)
1 parent aee58da commit 44d1a6a

File tree

8 files changed

+184
-4
lines changed

8 files changed

+184
-4
lines changed

stream_chat/async_chat/client.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import datetime
22
import json
3+
import sys
34
import warnings
45
from types import TracebackType
56
from typing import (
@@ -15,6 +16,11 @@
1516
)
1617
from urllib.parse import urlparse
1718

19+
if sys.version_info >= (3, 8):
20+
from typing import Literal
21+
else:
22+
from typing_extensions import Literal
23+
1824
import aiohttp
1925
from aiofile import AIOFile
2026
from aiohttp import FormData
@@ -633,6 +639,20 @@ async def delete_push_provider(
633639
async def list_push_providers(self) -> StreamResponse:
634640
return await self.get("push_providers")
635641

642+
async def create_import_url(self, filename: str) -> StreamResponse:
643+
return await self.post("import_urls", data={"filename": filename})
644+
645+
async def create_import(
646+
self, path: str, mode: Literal["insert", "upsert"] = "upsert"
647+
) -> StreamResponse:
648+
return await self.post("imports", data={"path": path, "mode": mode})
649+
650+
async def get_import(self, id: str) -> StreamResponse:
651+
return await self.get(f"imports/{id}")
652+
653+
async def list_imports(self, options: Dict = None) -> StreamResponse:
654+
return await self.get("imports", params=options)
655+
636656
async def close(self) -> None:
637657
await self.session.close()
638658

stream_chat/base/client.py

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,14 @@
44
import hashlib
55
import hmac
66
import os
7+
import sys
78
from typing import Any, Awaitable, Dict, Iterable, List, TypeVar, Union
89

10+
if sys.version_info >= (3, 8):
11+
from typing import Literal
12+
else:
13+
from typing_extensions import Literal
14+
915
import jwt
1016

1117
from stream_chat.types.stream_response import StreamResponse
@@ -1122,6 +1128,89 @@ def list_push_providers(self) -> Union[StreamResponse, Awaitable[StreamResponse]
11221128
"""
11231129
pass
11241130

1131+
@abc.abstractmethod
1132+
def create_import_url(
1133+
self, filename: str
1134+
) -> Union[StreamResponse, Awaitable[StreamResponse]]:
1135+
"""
1136+
Create a URL to import a file.
1137+
Full flow:
1138+
::
1139+
1140+
url_resp = client.create_import_url("myfile.json")
1141+
1142+
upload_resp = requests.put(
1143+
url_resp["upload_url"],
1144+
data=open("myfile.json", "rb"),
1145+
headers={"Content-Type": "application/json"},
1146+
)
1147+
1148+
create_resp = client.create_import(url_resp["path"], "upsert")
1149+
import_resp = client.get_import(create_resp["import_task"]["id"])
1150+
"""
1151+
pass
1152+
1153+
def create_import(
1154+
self, path: str, mode: Literal["insert", "upsert"] = "upsert"
1155+
) -> Union[StreamResponse, Awaitable[StreamResponse]]:
1156+
"""
1157+
Create an import task.
1158+
Full flow:
1159+
::
1160+
1161+
url_resp = client.create_import_url("myfile.json")
1162+
1163+
upload_resp = requests.put(
1164+
url_resp["upload_url"],
1165+
data=open("myfile.json", "rb"),
1166+
headers={"Content-Type": "application/json"},
1167+
)
1168+
1169+
create_resp = client.create_import(url_resp["path"], "upsert")
1170+
import_resp = client.get_import(create_resp["import_task"]["id"])
1171+
"""
1172+
pass
1173+
1174+
def get_import(self, id: str) -> Union[StreamResponse, Awaitable[StreamResponse]]:
1175+
"""
1176+
Get the status of an import task.
1177+
Full flow:
1178+
::
1179+
1180+
url_resp = client.create_import_url("myfile.json")
1181+
1182+
upload_resp = requests.put(
1183+
url_resp["upload_url"],
1184+
data=open("myfile.json", "rb"),
1185+
headers={"Content-Type": "application/json"},
1186+
)
1187+
1188+
create_resp = client.create_import(url_resp["path"], "upsert")
1189+
import_resp = client.get_import(create_resp["import_task"]["id"])
1190+
"""
1191+
pass
1192+
1193+
def list_imports(
1194+
self, options: Dict = None
1195+
) -> Union[StreamResponse, Awaitable[StreamResponse]]:
1196+
"""
1197+
List all import tasks. Options can contain a "limit" and "offset" parameter.
1198+
Full flow:
1199+
::
1200+
1201+
url_resp = client.create_import_url("myfile.json")
1202+
1203+
upload_resp = requests.put(
1204+
url_resp["upload_url"],
1205+
data=open("myfile.json", "rb"),
1206+
headers={"Content-Type": "application/json"},
1207+
)
1208+
1209+
create_resp = client.create_import(url_resp["path"], "upsert")
1210+
import_resp = client.get_import(create_resp["import_task"]["id"])
1211+
"""
1212+
pass
1213+
11251214
#####################
11261215
# Private methods #
11271216
#####################

stream_chat/client.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
11
import datetime
22
import json
3+
import sys
34
import warnings
45
from typing import Any, Callable, Dict, Iterable, List, Union
56
from urllib.parse import urlparse
67
from urllib.request import Request, urlopen
78

9+
if sys.version_info >= (3, 8):
10+
from typing import Literal
11+
else:
12+
from typing_extensions import Literal
13+
14+
815
import requests
916

1017
from stream_chat.__pkg__ import __version__
@@ -598,3 +605,17 @@ def delete_push_provider(self, provider_type: str, name: str) -> StreamResponse:
598605

599606
def list_push_providers(self) -> StreamResponse:
600607
return self.get("push_providers")
608+
609+
def create_import_url(self, filename: str) -> StreamResponse:
610+
return self.post("import_urls", data={"filename": filename})
611+
612+
def create_import(
613+
self, path: str, mode: Literal["insert", "upsert"] = "upsert"
614+
) -> StreamResponse:
615+
return self.post("imports", data={"path": path, "mode": mode})
616+
617+
def get_import(self, id: str) -> StreamResponse:
618+
return self.get(f"imports/{id}")
619+
620+
def list_imports(self, options: Dict = None) -> StreamResponse:
621+
return self.get("imports", params=options)

stream_chat/tests/async_chat/test_channel.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import time
22
import uuid
3+
from pathlib import Path
34
from typing import Dict, List
45

56
import pytest
@@ -202,13 +203,17 @@ async def test_get_reactions(self, channel: Channel, random_user: Dict):
202203
assert response["reactions"][0]["count"] == 42
203204

204205
async def test_send_and_delete_file(self, channel: Channel, random_user: Dict):
205-
url = "helloworld.jpg"
206+
url = str(
207+
Path.joinpath(Path(__file__).parent.parent, "assets", "helloworld.jpg")
208+
)
206209
resp = await channel.send_file(url, "helloworld.jpg", random_user)
207210
assert "helloworld.jpg" in resp["file"]
208211
await channel.delete_file(resp["file"])
209212

210213
async def test_send_and_delete_image(self, channel: Channel, random_user: Dict):
211-
url = "helloworld.jpg"
214+
url = str(
215+
Path.joinpath(Path(__file__).parent.parent, "assets", "helloworld.jpg")
216+
)
212217
resp = await channel.send_image(
213218
url, "helloworld.jpg", random_user, content_type="image/jpeg"
214219
)

stream_chat/tests/async_chat/test_client.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -740,3 +740,26 @@ async def test_swap_http_client(self):
740740
)
741741
resp = await client.get_app_settings()
742742
assert resp.status_code() == 200
743+
744+
async def test_imports_end2end(self, client: StreamChatAsync):
745+
url_resp = await client.create_import_url(str(uuid.uuid4()) + ".json")
746+
assert url_resp["upload_url"]
747+
assert url_resp["path"]
748+
749+
sess = aiohttp.ClientSession()
750+
async with sess.put(
751+
url_resp["upload_url"],
752+
data=b"{}",
753+
headers={"Content-Type": "application/json"},
754+
) as resp:
755+
assert resp.status == 200
756+
sess.close()
757+
758+
create_resp = await client.create_import(url_resp["path"], "upsert")
759+
assert create_resp["import_task"]["id"]
760+
761+
get_resp = await client.get_import(create_resp["import_task"]["id"])
762+
assert get_resp["import_task"]["id"] == create_resp["import_task"]["id"]
763+
764+
list_resp = await client.list_imports({"limit": 1})
765+
assert len(list_resp["import_tasks"]) == 1

stream_chat/tests/test_channel.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import time
22
import uuid
3+
from pathlib import Path
34
from typing import Dict, List
45

56
import pytest
@@ -192,13 +193,13 @@ def test_get_reactions(self, channel: Channel, random_user: Dict):
192193
assert response["reactions"][0]["count"] == 42
193194

194195
def test_send_and_delete_file(self, channel: Channel, random_user: Dict):
195-
url = "helloworld.jpg"
196+
url = str(Path.joinpath(Path(__file__).parent, "assets", "helloworld.jpg"))
196197
resp = channel.send_file(url, "helloworld.jpg", random_user)
197198
assert "helloworld.jpg" in resp["file"]
198199
channel.delete_file(resp["file"])
199200

200201
def test_send_and_delete_image(self, channel: Channel, random_user: Dict):
201-
url = "helloworld.jpg"
202+
url = str(Path.joinpath(Path(__file__).parent, "assets", "helloworld.jpg"))
202203
resp = channel.send_image(
203204
url, "helloworld.jpg", random_user, content_type="image/jpeg"
204205
)

stream_chat/tests/test_client.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -711,3 +711,24 @@ def test_swap_http_client(self):
711711
client.set_http_session(requests.Session())
712712
resp = client.get_app_settings()
713713
assert resp.status_code() == 200
714+
715+
def test_imports_end2end(self, client: StreamChat):
716+
url_resp = client.create_import_url(str(uuid.uuid4()) + ".json")
717+
assert url_resp["upload_url"]
718+
assert url_resp["path"]
719+
720+
upload_resp = requests.put(
721+
url_resp["upload_url"],
722+
data=b"{}",
723+
headers={"Content-Type": "application/json"},
724+
)
725+
assert upload_resp.status_code == 200
726+
727+
create_resp = client.create_import(url_resp["path"], "upsert")
728+
assert create_resp["import_task"]["id"]
729+
730+
get_resp = client.get_import(create_resp["import_task"]["id"])
731+
assert get_resp["import_task"]["id"] == create_resp["import_task"]["id"]
732+
733+
list_resp = client.list_imports({"limit": 1})
734+
assert len(list_resp["import_tasks"]) == 1

0 commit comments

Comments
 (0)