Skip to content

Commit a141e16

Browse files
authored
Merge pull request #35 from getoriginal/feature/ori-2209-userasset-add-external-ids-to-python-sdk
fix(ORI-2209): add external ids for user and asset
2 parents 04f9a7b + 6b69d92 commit a141e16

File tree

7 files changed

+175
-28
lines changed

7 files changed

+175
-28
lines changed

README.md

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
- [Create a new user](#create-a-new-user)
1010
- [Get a user by UID](#get-a-user-by-uid)
1111
- [Get a user by email](#get-a-user-by-email)
12-
- [Get a user by client ID](#get-a-user-by-client-id)
12+
- [Get a user by user external ID](#get-a-user-by-client-id)
1313
- [Asset](#asset)
1414
- [Create a new asset](#create-a-new-asset)
1515
- [Get an asset by UID](#get-an-asset-by-asset-uid)
@@ -105,9 +105,9 @@ new_user_uid = create_response['data']['uid']
105105
}
106106
}
107107

108-
# You can also pass in a client_id and/or email for your external reference.
109-
# The client ID and/or email supplied must be unique per app
110-
create_response = client.create_user(email='YOUR_EMAIL', client_id='YOUR_CLIENT_ID')
108+
# You can also pass in a user_external_id and/or email for your external reference.
109+
# The user_external_id and/or email supplied must be unique per app
110+
create_response = client.create_user(email='YOUR_EMAIL', user_external_id='YOUR_USER_EXTERNAL_ID')
111111
new_user_uid = create_response['data']['uid']
112112
# ...
113113
```
@@ -123,7 +123,7 @@ user_details = user_response['data'] # Contains user details such as UID, email
123123
"success": True,
124124
"data": {
125125
"uid": "754566475542",
126-
"client_id": "user_client_id",
126+
"user_external_id": "user_external_id_1",
127127
"created_at": "2024-02-26T13:12:31.798296Z",
128128
"email": "[email protected]",
129129
"wallet_address": "0xa22f2dfe189ed3d16bb5bda5e5763b2919058e40"
@@ -142,7 +142,7 @@ user_by_email_details = user_by_email_response['data']
142142
"success": True,
143143
"data": {
144144
"uid": "754566475542",
145-
"client_id": "user_client_id",
145+
"user_external_id": "user_external_id_1",
146146
"created_at": "2024-02-26T13:12:31.798296Z",
147147
"email": "[email protected]",
148148
"wallet_address": "0xa22f2dfe189ed3d16bb5bda5e5763b2919058e40"
@@ -156,24 +156,24 @@ user_by_email_details = user_by_email_response['data']
156156
}
157157
```
158158

159-
### Get a user by client ID
159+
### Get a user by user external ID
160160
```python
161-
# Get a user by client ID
162-
# Retrieves a user by their client ID. If the user does not exist, `data` will be None.
163-
user_by_client_id_response = client.get_user_by_client_id('YOUR_CLIENT_ID')
164-
user_by_client_id_details = user_by_client_id_response['data']
165-
# Sample user_by_client_id_response on success:
161+
# Get a user by user external ID
162+
# Retrieves a user by their user external ID. If the user does not exist, `data` will be None.
163+
user_by_user_external_id_response = client.get_user_by_user_external_id('YOUR_USER_EXTERNAL_ID')
164+
user_by_user_external_details = user_by_user_external_id_response['data']
165+
# Sample user_by_user_external_id_response on success:
166166
{
167167
"success": True,
168168
"data": {
169169
"uid": "754566475542",
170-
"client_id": "user_client_id",
170+
"user_external_id": "user_external_id",
171171
"created_at": "2024-02-26T13:12:31.798296Z",
172172
"email": "[email protected]",
173173
"wallet_address": "0xa22f2dfe189ed3d16bb5bda5e5763b2919058e40"
174174
}
175175
}
176-
# Sample user_by_client_id_response on failure:
176+
# Sample user_by_user_external_id_response on failure:
177177
{
178178
"success": False,
179179
"data": None
@@ -190,7 +190,7 @@ The asset methods exposed by the sdk are used to create (mint) assets and retrie
190190
# prepare the new asset params
191191
new_asset_params = {
192192
"user_uid": "324167489835",
193-
"client_id": "client_id_1",
193+
"asset_external_id": "asset_external_id_1",
194194
"collection_uid": "221137489875",
195195
"data": {
196196
"name": "Dave Starbelly",
@@ -237,7 +237,7 @@ asset_details = asset_response['data']
237237
"data": {
238238
"uid": "151854912345",
239239
"name": "random name #2",
240-
"client_id": "asset_client_id_1",
240+
"asset_external_id": "asset_external_id_1",
241241
"collection_uid": "471616646163",
242242
"collection_name": "Test SDK Collection 1",
243243
"token_id": 2,
@@ -285,7 +285,7 @@ assets_list = assets_response['data']
285285
{
286286
"uid": "151854912345",
287287
"name": "random name #2",
288-
"client_id": "asset_client_id_1",
288+
"asset_external_id": "asset_external_id_1",
289289
"collection_uid": "471616646163",
290290
"collection_name": "Test SDK Collection 1",
291291
"token_id": 2,
@@ -539,7 +539,7 @@ collection_details = collection_response['data']
539539
```
540540

541541

542-
### Handling Errors
542+
## Handling Errors
543543

544544
If something goes wrong, you will receive well typed error messages.
545545

@@ -573,7 +573,7 @@ So when an error occurs, you can either catch all using the OriginalError class:
573573
from original_sdk import OriginalError
574574

575575
try:
576-
result = client.create_user('invalid_email', 'client_id');
576+
result = client.create_user(email='invalid_email', user_external_id='user_external_id');
577577
except OriginalError as e:
578578
# handle all errors
579579
```
@@ -584,7 +584,7 @@ or specific errors:
584584
from original_sdk import ClientError, ServerError, ValidationError
585585

586586
try:
587-
result = client.create_user('invalid_email', 'client_id');
587+
result = client.create_user(email='invalid_email', user_external_id='user_external_id');
588588
except ClientError as e:
589589
# handle client errors
590590
except ServerError as e:
@@ -619,7 +619,7 @@ Please note, if you plan to parse the error detail, it can also be an array if t
619619
# {
620620
# "code": "null",
621621
# "message": "This field may not be null.",
622-
# "field_name": "client_id"
622+
# "field_name": "user_external_id"
623623
# },
624624
# {
625625
# "code": "invalid",

original_sdk/async_client.py

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import json
2+
import warnings
23
from types import TracebackType
34
from typing import (
45
Any,
@@ -126,9 +127,25 @@ async def patch(
126127
return await self._make_request(self.session.patch, relative_url, params, data)
127128

128129
async def create_user(
129-
self, email: Union[None, str] = None, client_id: Union[None, str] = None
130+
self,
131+
email: Union[None, str] = None,
132+
client_id: Union[None, str] = None,
133+
user_external_id: Union[None, str] = None,
130134
) -> OriginalResponse:
131-
return await self.post("user", data={"email": email, "client_id": client_id})
135+
if client_id:
136+
warnings.warn(
137+
"client_id is deprecated, please use user_external_id instead",
138+
DeprecationWarning,
139+
stacklevel=2,
140+
)
141+
return await self.post(
142+
"user",
143+
data={
144+
"email": email,
145+
"client_id": client_id,
146+
"user_external_id": user_external_id,
147+
},
148+
)
132149

133150
async def get_user(self, uid: str) -> OriginalResponse:
134151
return await self.get(f"user/{uid}")
@@ -137,8 +154,18 @@ async def get_user_by_email(self, email: str) -> OriginalResponse:
137154
return await self.get("user", params={"email": email})
138155

139156
async def get_user_by_client_id(self, client_id: str) -> OriginalResponse:
157+
warnings.warn(
158+
"get_user_by_client_id is deprecated, please use get_user_by_user_external_id instead",
159+
DeprecationWarning,
160+
stacklevel=2,
161+
)
140162
return await self.get("user", params={"client_id": client_id})
141163

164+
async def get_user_by_user_external_id(
165+
self, user_external_id: str
166+
) -> OriginalResponse:
167+
return await self.get("user", params={"user_external_id": user_external_id})
168+
142169
async def get_collection(self, uid: str) -> OriginalResponse:
143170
return await self.get(f"collection/{uid}")
144171

original_sdk/base/client.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,10 @@ def handle_parsed_response(
9090

9191
@abc.abstractmethod
9292
def create_user(
93-
self, email: Union[None, str] = None, client_id: Union[None, str] = None
93+
self,
94+
email: Union[None, str] = None,
95+
client_id: Union[None, str] = None,
96+
user_external_id: Union[None, str] = None,
9497
) -> Union[OriginalResponse, Awaitable[OriginalResponse]]:
9598
"""
9699
Create an Original user.
@@ -116,7 +119,7 @@ def get_user_by_email(
116119
"""
117120
Gets a user by email
118121
119-
:param email: the users email
122+
:param email: the user's email
120123
:return:
121124
"""
122125
pass
@@ -126,9 +129,23 @@ def get_user_by_client_id(
126129
self, client_id: str
127130
) -> Union[OriginalResponse, Awaitable[OriginalResponse]]:
128131
"""
132+
Deprecated: use get_user_by_user_external_id instead.
133+
129134
Gets a user by client_id
130135
131-
:param client_id: the users email
136+
:param client_id: the user's client_id
137+
:return:
138+
"""
139+
pass
140+
141+
@abc.abstractmethod
142+
def get_user_by_user_external_id(
143+
self, user_external_id: str
144+
) -> Union[OriginalResponse, Awaitable[OriginalResponse]]:
145+
"""
146+
Gets a user by user_external_id
147+
148+
:param user_external_id: the user's user_external_id
132149
:return:
133150
"""
134151
pass

original_sdk/client.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import json
2+
import warnings
23
from typing import Any, Callable, Dict, Tuple, Union
34

45
import requests
@@ -112,9 +113,25 @@ def patch(
112113
return self._make_request(self.session.patch, relative_url, params, data)
113114

114115
def create_user(
115-
self, email: Union[None, str] = None, client_id: Union[None, str] = None
116+
self,
117+
email: Union[None, str] = None,
118+
client_id: Union[None, str] = None,
119+
user_external_id: Union[None, str] = None,
116120
) -> OriginalResponse:
117-
return self.post("user", data={"email": email, "client_id": client_id})
121+
if client_id:
122+
warnings.warn(
123+
"client_id is deprecated, please use user_external_id instead",
124+
DeprecationWarning,
125+
stacklevel=2,
126+
)
127+
return self.post(
128+
"user",
129+
data={
130+
"email": email,
131+
"client_id": client_id,
132+
"user_external_id": user_external_id,
133+
},
134+
)
118135

119136
def get_user(self, uid: str) -> OriginalResponse:
120137
return self.get(f"user/{uid}")
@@ -123,8 +140,16 @@ def get_user_by_email(self, email: str) -> OriginalResponse:
123140
return self.get("user", params={"email": email})
124141

125142
def get_user_by_client_id(self, client_id: str) -> OriginalResponse:
143+
warnings.warn(
144+
"get_user_by_client_id is deprecated, please use get_user_by_user_external_id instead",
145+
DeprecationWarning,
146+
stacklevel=2,
147+
)
126148
return self.get("user", params={"client_id": client_id})
127149

150+
def get_user_by_user_external_id(self, user_external_id: str) -> OriginalResponse:
151+
return self.get("user", params={"user_external_id": user_external_id})
152+
128153
def get_collection(self, uid: str) -> OriginalResponse:
129154
return self.get(f"collection/{uid}")
130155

original_sdk/tests/e2e/test_async_client_e2e.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,17 @@
2323

2424

2525
class TestAsyncClientE2E:
26+
2627
async def test_create_user_with_params(self, async_client: OriginalAsyncClient):
28+
user_external_id = get_random_string(8)
29+
response = await async_client.create_user(
30+
email=f"{user_external_id}@test.com", user_external_id=user_external_id
31+
)
32+
assert response["data"]["uid"] is not None
33+
34+
async def test_create_user_with_deprecated_client_id(
35+
self, async_client: OriginalAsyncClient
36+
):
2737
client_id = get_random_string(8)
2838
response = await async_client.create_user(
2939
email=f"{client_id}@test.com", client_id=client_id
@@ -52,6 +62,15 @@ async def test_get_user_by_email(self, async_client: OriginalAsyncClient):
5262
assert response["data"]["uid"] == TEST_APP_USER_UID
5363
assert response["data"]["email"] == TEST_APP_USER_EMAIL
5464

65+
async def test_get_user_by_user_external_id(
66+
self, async_client: OriginalAsyncClient
67+
):
68+
response = await async_client.get_user_by_user_external_id(
69+
TEST_APP_USER_CLIENT_ID
70+
)
71+
assert response["data"]["uid"] == TEST_APP_USER_UID
72+
assert response["data"]["email"] == TEST_APP_USER_EMAIL
73+
5574
async def test_get_user_by_client_id(self, async_client: OriginalAsyncClient):
5675
response = await async_client.get_user_by_client_id(TEST_APP_USER_CLIENT_ID)
5776
assert response["data"]["uid"] == TEST_APP_USER_UID
@@ -84,6 +103,29 @@ async def test_get_collection_not_found_throws_404(
84103
assert e.status == 404
85104

86105
async def test_create_asset(self, async_client: OriginalAsyncClient):
106+
asset_name = get_random_string(8)
107+
asset_data = {
108+
"name": asset_name,
109+
"unique_name": True,
110+
"image_url": "https://example.com/image.png",
111+
"store_image_on_ipfs": False,
112+
"attributes": [
113+
{"trait_type": "Eyes", "value": "Green"},
114+
{"trait_type": "Hair", "value": "Black"},
115+
],
116+
}
117+
request_data = {
118+
"data": asset_data,
119+
"user_uid": TEST_APP_USER_UID,
120+
"asset_external_id": asset_name,
121+
"collection_uid": TEST_APP_COLLECTION_UID,
122+
}
123+
response = await async_client.create_asset(**request_data)
124+
assert response["data"]["uid"] is not None
125+
126+
async def test_create_asset_with_deprecated_client_id(
127+
self, async_client: OriginalAsyncClient
128+
):
87129
asset_name = get_random_string(8)
88130
asset_data = {
89131
"name": asset_name,

0 commit comments

Comments
 (0)