Skip to content

Commit 215d73f

Browse files
author
Matt Sokoloff
committed
removed queries that aren't ready
1 parent 39e29d6 commit 215d73f

File tree

11 files changed

+526
-616
lines changed

11 files changed

+526
-616
lines changed

examples/basics/user_management.ipynb

Lines changed: 410 additions & 445 deletions
Large diffs are not rendered by default.

labelbox/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,4 @@
1717
from labelbox.schema.prediction import Prediction, PredictionModel
1818
from labelbox.schema.ontology import Ontology
1919
from labelbox.schema.role import Role, ProjectRole
20-
from labelbox.schema.invite import Invite, InviteLimit, UserLimit
20+
from labelbox.schema.invite import Invite, InviteLimit

labelbox/client.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class Client:
3737
def __init__(self,
3838
api_key=None,
3939
endpoint='https://api.labelbox.com/graphql',
40-
enable_beta = False):
40+
enable_beta=False):
4141
""" Creates and initializes a Labelbox Client.
4242
4343
Logging is defaulted to level WARNING. To receive more verbose
@@ -62,11 +62,10 @@ def __init__(self,
6262
"Labelbox API key not provided")
6363
api_key = os.environ[_LABELBOX_API_KEY]
6464
self.api_key = api_key
65-
65+
6666
self.enable_beta = True
6767
if enable_beta:
6868
logger.info("Beta features have been enabled")
69-
7069

7170
logger.info("Initializing Labelbox client at '%s'", endpoint)
7271
self.endpoint = endpoint
@@ -76,11 +75,10 @@ def __init__(self,
7675
'Authorization': 'Bearer %s' % api_key,
7776
'X-User-Agent': f'python-sdk {SDK_VERSION}'
7877
}
79-
8078

8179
@retry.Retry(predicate=retry.if_exception_type(
8280
labelbox.exceptions.InternalServerError))
83-
def execute(self, query, params=None, timeout=30.0, beta = False):
81+
def execute(self, query, params=None, timeout=30.0, beta=False):
8482
""" Sends a request to the server for the execution of the
8583
given query.
8684

labelbox/orm/db_object.py

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,11 @@ def __init__(self, client, field_values):
4747
self._set_field_values(field_values)
4848

4949
for relationship in self.relationships():
50-
value = field_values.get(relationship.name)
50+
value = field_values.get(relationship.name)
5151
if relationship.precompute and value is None:
52-
raise KeyError(f"Expected field values for {relationship.name}")
53-
52+
raise KeyError(
53+
f"Expected field values for {relationship.name}")
54+
5455
setattr(self, relationship.name,
5556
RelationshipManager(self, relationship, value))
5657

@@ -258,22 +259,25 @@ def delete(self):
258259

259260

260261
def beta(fn):
262+
261263
def wrapper(self, *args, **kwargs):
262264
if not isinstance(self, DbObject):
263-
raise TypeError("Cannot decorate functions that are not functions of `DbOjects` with `beta` decorator")
265+
raise TypeError(
266+
"Cannot decorate functions that are not functions of `DbOjects` with `beta` decorator"
267+
)
264268
if not self.client.enable_beta:
265269
raise Exception(
266270
f"This function {fn.__name__} relies on a beta feature in the api. This means that the interface could change."
267-
" Set `enable_beta=True` in the client to enable use of these functions.")
268-
execute_fn = self.client.execute
271+
" Set `enable_beta=True` in the client to enable use of these functions."
272+
)
273+
execute_fn = self.client.execute
269274
try:
270-
self.client.execute = partial(execute_fn, beta = True)
275+
self.client.execute = partial(execute_fn, beta=True)
271276
result = fn(self, *args, **kwargs)
272277
if isinstance(result, PaginatedCollection):
273278
result.beta = True
274279
return result
275280
finally:
276281
self.client.execute = execute_fn
277-
return wrapper
278-
279282

283+
return wrapper

labelbox/pagination.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ def __init__(self,
1717
params,
1818
dereferencing,
1919
obj_class,
20-
cursor_path=None
21-
):
20+
cursor_path=None):
2221
""" Creates a PaginatedCollection.
2322
2423
Args:

labelbox/schema/invite.py

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,9 @@ class InviteLimit:
2020
limit: int
2121

2222

23-
@dataclass
24-
class UserLimit(InviteLimit):
25-
"""
26-
remaining(int): Remaining number of users that an org is allowed to have
27-
used (int): Total number of users in the org
28-
limit (int): Maximum number of users available to the org
29-
date_limit_was_reached (date): Date that `limit` was equal to `used`
30-
"""
31-
date_limit_was_reached: Optional[datetime]
32-
33-
3423
class Invite(DbObject):
3524
"""
3625
An object representing a user invite
37-
3826
"""
3927
created_at = Field.DateTime("created_at")
4028
organization_role_name = Field.String("organization_role_name")
@@ -49,13 +37,3 @@ def __init__(self, client, invite_response):
4937
role=client.get_roles()[r['projectRoleName']])
5038
for r in project_roles
5139
]
52-
53-
@beta
54-
def revoke(self):
55-
""" Makes the invitation invalid.
56-
"""
57-
query_str = """mutation CancelInvitePyApi($where: WhereUniqueIdInput!) {
58-
cancelInvite(where: $where) {id}}"""
59-
self.client.execute(query_str, {'where': {
60-
'id': self.uid
61-
}})

labelbox/schema/organization.py

Lines changed: 36 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@
55
from labelbox.pagination import PaginatedCollection
66
from labelbox.orm.db_object import DbObject, beta
77
from labelbox.orm.model import Field, Relationship
8-
from labelbox.schema.invite import Invite, InviteLimit, UserLimit, ProjectRole
8+
from labelbox.schema.invite import Invite, InviteLimit, ProjectRole
99
from labelbox.schema.user import User
1010
from labelbox.schema.role import Role
1111
import logging
1212

1313
logger = logging.getLogger(__name__)
1414

15+
1516
class Organization(DbObject):
1617
""" An Organization is a group of Users.
1718
@@ -45,61 +46,6 @@ def __init__(self, *args, **kwargs):
4546
projects = Relationship.ToMany("Project", True)
4647
webhooks = Relationship.ToMany("Webhook", False)
4748

48-
@beta
49-
def invites(self) -> PaginatedCollection:
50-
""" List all current invitees
51-
52-
Returns:
53-
A PaginatedCollection of Invite objects
54-
55-
"""
56-
query_str = """query GetOrgInvitationsPyApi($from: ID, $first: PageSize) {
57-
organization { id invites(from: $from, first: $first) {
58-
nodes { id createdAt organizationRoleName inviteeEmail } nextCursor }}}"""
59-
return PaginatedCollection(
60-
self.client,
61-
query_str, {}, ['organization', 'invites', 'nodes'],
62-
Invite,
63-
cursor_path=['organization', 'invites', 'nextCursor'])
64-
65-
def _assign_user_role(self, email: str, role: Role,
66-
project_roles: List[ProjectRole]) -> Dict[str, Any]:
67-
"""
68-
Creates or updates users. This function shouldn't directly be called.
69-
Use `Organization.invite_user`
70-
71-
Note: that there is a really unclear foreign key error if you use an unsupported role.
72-
- This means that the `Roles` object is not getting the right ids
73-
"""
74-
if self.client.get_user().email == email:
75-
raise ValueError("Cannot update your own role")
76-
77-
data_param = "data"
78-
query_str = """mutation createInvitesPyApi($%s: [CreateInviteInput!]){
79-
createInvites(data: $%s){ invite { id createdAt organizationRoleName inviteeEmail}}}""" % (
80-
data_param, data_param)
81-
82-
projects = [{
83-
"projectId": project_role.project.uid,
84-
"projectRoleId": project_role.role.uid
85-
} for project_role in project_roles]
86-
87-
res = self.client.execute(
88-
query_str, {
89-
data_param: [{
90-
"inviterId": self.client.get_user().uid,
91-
"inviteeEmail": email,
92-
"organizationId": self.uid,
93-
"organizationRoleId": role.uid,
94-
"projects": projects
95-
}]
96-
},
97-
)
98-
# We prob want to return an invite
99-
# Could support bulk ops in the future
100-
invite_info = res['createInvites'][0]['invite']
101-
return invite_info
102-
10349
@beta
10450
def invite_user(
10551
self,
@@ -117,18 +63,18 @@ def invite_user(
11763
Returns:
11864
Invite for the user
11965
66+
Creates or updates users. This function shouldn't directly be called.
67+
Use `Organization.invite_user`
68+
69+
Note: that there is a really unclear foreign key error if you use an unsupported role.
70+
- This means that the `Roles` object is not getting the right ids
12071
"""
12172
remaining_invites = self.invite_limit().remaining
12273
if remaining_invites == 0:
12374
raise LabelboxError(
12475
"Invite(s) cannot be sent because you do not have enough available seats in your organization. "
12576
"Please upgrade your account, revoke pending invitations or remove other users."
12677
)
127-
for invite in self.invites():
128-
if invite.email == email:
129-
raise ValueError(
130-
f"Invite already exists for {email}. Please revoke the invite if you want to update the role or resend."
131-
)
13278

13379
if not isinstance(role, Role):
13480
raise TypeError(f"role must be Role type. Found {role}")
@@ -145,26 +91,35 @@ def invite_user(
14591
f"project_roles must be a list of `ProjectRole`s. Found {project_role}"
14692
)
14793

148-
invite_response = self._assign_user_role(email, role, _project_roles)
149-
return Invite(self.client, invite_response)
94+
if self.client.get_user().email == email:
95+
raise ValueError("Cannot update your own role")
15096

151-
@beta
152-
def user_limit(self) -> UserLimit:
153-
""" Retrieve user limits for the org
97+
data_param = "data"
98+
query_str = """mutation createInvitesPyApi($%s: [CreateInviteInput!]){
99+
createInvites(data: $%s){ invite { id createdAt organizationRoleName inviteeEmail}}}""" % (
100+
data_param, data_param)
154101

155-
Returns:
156-
UserLimit
157-
158-
"""
159-
query_str = """query UsersLimitPyApi {
160-
organization {id account { id usersLimit { dateLimitWasReached remaining used limit }}}}
161-
"""
162-
res = self.client.execute(query_str)
163-
return UserLimit(
164-
**{
165-
utils.snake_case(k): v for k, v in res['organization']
166-
['account']['usersLimit'].items()
167-
})
102+
projects = [{
103+
"projectId": project_role.project.uid,
104+
"projectRoleId": project_role.role.uid
105+
} for project_role in _project_roles]
106+
107+
res = self.client.execute(
108+
query_str,
109+
{
110+
data_param: [{
111+
"inviterId": self.client.get_user().uid,
112+
"inviteeEmail": email,
113+
"organizationId": self.uid,
114+
"organizationRoleId": role.uid,
115+
"projects": projects
116+
}]
117+
},
118+
)
119+
# We prob want to return an invite
120+
# Could support bulk ops in the future
121+
invite_response = res['createInvites'][0]['invite']
122+
return Invite(self.client, invite_response)
168123

169124
@beta
170125
def invite_limit(self) -> InviteLimit:
@@ -177,13 +132,13 @@ def invite_limit(self) -> InviteLimit:
177132
178133
"""
179134
org_id_param = "organizationId"
180-
res = self.client.execute("""query InvitesLimitPyApi($%s: ID!) {
135+
res = self.client.execute(
136+
"""query InvitesLimitPyApi($%s: ID!) {
181137
invitesLimit(where: {id: $%s}) { used limit remaining }
182138
}""" % (org_id_param, org_id_param), {org_id_param: self.uid})
183139
return InviteLimit(
184140
**{utils.snake_case(k): v for k, v in res['invitesLimit'].items()})
185141

186-
@beta
187142
def remove_user(self, user: User):
188143
"""
189144
Deletes a user from the organization. This cannot be undone without sending another invite.

labelbox/schema/project.py

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -79,27 +79,6 @@ class Project(DbObject, Updateable, Deletable):
7979
predictions = Relationship.ToMany("Prediction", False)
8080
ontology = Relationship.ToOne("Ontology", True)
8181

82-
@beta
83-
def invites(self):
84-
""" Fetch all current invites for this project
85-
86-
Returns:
87-
A `PaginatedCollection` of `ProjectInvite`s.
88-
89-
"""
90-
id_param = "projectId"
91-
query_str = """query GetProjectInvitationsPyApi($from: ID, $first: PageSize, $%s: ID!) {
92-
project(where: {id: $%s}) {id
93-
invites(from: $from, first: $first) { nodes { %s
94-
projectInvites { projectId projectRoleName } } nextCursor}}}
95-
""" % (id_param, id_param, query.results_query_part(Entity.Invite))
96-
97-
return PaginatedCollection(
98-
self.client,
99-
query_str, {id_param: self.uid}, ['project', 'invites', 'nodes'],
100-
Invite,
101-
cursor_path=['project', 'invites', 'nextCursor'])
102-
10382
def members(self):
10483
""" Fetch all current members for this project
10584

labelbox/utils.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,3 @@ def title_case(s):
2424
def snake_case(s):
2525
""" Converts a string in [snake|camel|title]case to snake_case. """
2626
return _convert(s, "_", lambda i: False)
27-
28-
29-
30-

0 commit comments

Comments
 (0)