def refresh(self) -> None: """Synchronizes values of all fields with the database. """ query_str, params = query.get_single(BulkImportRequest, self.uid) res = self.client.execute(query_str, params) res = res[utils.camel_case(BulkImportRequest.type_name())] self._set_field_values(res)
def _to_many(self, where=None, order_by=None): """ Returns an iterable over the destination relationship objects. Args: where (None, Comparison or LogicalExpression): Filtering clause. order_by (None or (Field, Field.Order)): Ordering clause. Return: iterable over destination DbObject instances. """ rel = self.relationship if where is not None and not self.supports_filtering: raise InvalidQueryError( "Relationship %s.%s doesn't support filtering" % (self.source.type_name(), rel.name)) if order_by is not None and not self.supports_sorting: raise InvalidQueryError( "Relationship %s.%s doesn't support sorting" % (self.source.type_name(), rel.name)) if rel.filter_deleted: not_deleted = rel.destination_type.deleted == False where = not_deleted if where is None else where & not_deleted query_string, params = query.relationship( self.source if self.filter_on_id else type(self.source), rel, where, order_by) return PaginatedCollection( self.source.client, query_string, params, [utils.camel_case(self.source.type_name()), rel.graphql_name], rel.destination_type)
def _to_one(self): """ Returns the relationship destination object. """ rel = self.relationship query_string, params = query.relationship(self.source, rel, None, None) result = self.source.client.execute(query_string, params) result = result[utils.camel_case(type(self.source).type_name())] result = result[rel.graphql_name] if result is None: return None return rel.destination_type(self.source.client, result)
def get_single(entity, uid): """ Constructs the query and params dict for obtaining a single object. Either on ID, or without params. Args: entity (type): An Entity subtype being obtained. uid (str): The ID of the sought object. It can be None, which is legal for DB types that have a default object being returned (User and Organization). """ type_name = entity.type_name() where = entity.uid == uid if uid else None return Query(utils.camel_case(type_name), entity, where).format_top("Get" + type_name)
def update_relationship(a, b, relationship, update): """ Updates the relationship in DB object `a` to connect or disconnect DB object `b`. Args: a (DbObject): The object being updated. b (DbObject): Object on the other side of the relationship. relationship (Relationship): The relationship from `a` to `b`. update (str): The type of update. Must be either `connect` or `disconnect`. Return: (query_string, query_parameters) """ to_one_disconnect = update == "disconnect" and \ relationship.relationship_type == Relationship.Type.ToOne a_uid_param = utils.camel_case(type(a).type_name()) + "Id" if not to_one_disconnect: b_uid_param = utils.camel_case(type(b).type_name()) + "Id" param_declr = "($%s: ID!, $%s: ID!)" % (a_uid_param, b_uid_param) b_query = "{id: $%s}" % b_uid_param else: param_declr = "($%s: ID!)" % a_uid_param b_query = "true" query_str = """mutation %s%sAnd%sPyApi%s{update%s( where: {id: $%s} data: {%s: {%s: %s}}) {id}} """ % ( utils.title_case(update), type(a).type_name(), type(b).type_name(), param_declr, utils.title_case(type(a).type_name()), a_uid_param, relationship.graphql_name, update, b_query) if to_one_disconnect: params = {a_uid_param: a.uid} else: params = {a_uid_param: a.uid, b_uid_param: b.uid} return query_str, params
def __init__(self, field_type, name, graphql_name=None): """ Field init. Args: field_type (Field.Type): The type of the field. name (str): client-side Python attribute name of a database object. graphql_name (str): query and server-side name of a database object. If None, it is constructed from the client-side name by converting snake_case (Python convention) into camelCase (GraphQL convention). """ self.field_type = field_type self.name = name if graphql_name is None: graphql_name = utils.camel_case(name) self.graphql_name = graphql_name
def _get_all(self, db_object_type, where): """ Fetches all the objects of the given type the user has access to. Args: db_object_type (type): DbObject subclass. where (Comparison, LogicalOperation or None): The `where` clause for filtering. Return: An iterable of `db_object_type` instances. """ not_deleted = db_object_type.deleted == False where = not_deleted if where is None else where & not_deleted query_str, params = query.get_all(db_object_type, where) return PaginatedCollection( self, query_str, params, [utils.camel_case(db_object_type.type_name()) + "s"], db_object_type)
def get_all(entity, where): """ Constructs a query that fetches all items of the given type. The resulting query is intended to be used for pagination, it contains two python-string int-placeholders (%d) for 'skip' and 'first' pagination parameters. Args: entity (type): The object type being queried. where (Comparison, LogicalExpression or None): The `where` clause for filtering. Return: (str, dict) tuple that is the query string and parameters. """ check_where_clause(entity, where) type_name = entity.type_name() query = Query(utils.camel_case(type_name) + "s", entity, where, True) return query.format_top("Get" + type_name + "s")
def __init__(self, relationship_type, destination_type_name, filter_deleted=True, name=None, graphql_name=None): self.relationship_type = relationship_type self.destination_type_name = destination_type_name self.filter_deleted = filter_deleted if name is None: name = utils.snake_case(destination_type_name) + ( "s" if relationship_type == Relationship.Type.ToMany else "") self.name = name if graphql_name is None: graphql_name = utils.camel_case(name) self.graphql_name = graphql_name
def bulk_delete(db_objects, use_where_clause): """ Generates a query that bulk-deletes the given `db_objects` from the DB. Args: db_objects (list): A list of DB objects of the same type. use_where_clause (bool): If the object IDs should be passed to the mutation in a `where` clause or directly as a mutation value. """ type_name = db_objects[0].type_name() if use_where_clause: query_str = "mutation delete%ssPyApi{delete%ss(where: {%sIds: [%s]}){id}}" else: query_str = "mutation delete%ssPyApi{delete%ss(%sIds: [%s]){id}}" query_str = query_str % ( utils.title_case(type_name), utils.title_case(type_name), utils.camel_case(type_name), ", ".join('"%s"' % db_object.uid for db_object in db_objects)) return query_str, {}
def _get_single(self, db_object_type, uid): """ Fetches a single object of the given type, for the given ID. Args: db_object_type (type): DbObject subclass. uid (str): Unique ID of the row. Return: Object of `db_object_type`. Raises: labelbox.exceptions.ResourceNotFoundError: If there is no object of the given type for the given ID. """ query_str, params = query.get_single(db_object_type, uid) res = self.execute(query_str, params) res = res[utils.camel_case(db_object_type.type_name())] if res is None: raise labelbox.exceptions.ResourceNotFoundError( db_object_type, params) else: return db_object_type(self, res)
def relationship(source, relationship, where, order_by): """ Constructs a query that fetches all items from a -to-many relationship. To be used like: >>> project = ... >>> query_str, params = relationship(Project, "datasets", Dataset) >>> datasets = PaginatedCollection( client, query_str, params, ["project", "datasets"], Dataset) The resulting query is intended to be used for pagination, it contains two python-string int-placeholders (%d) for 'skip' and 'first' pagination parameters. Args: source (DbObject or type): If a `DbObject` then the source of the relationship (the query originates from that particular object). If `type`, then the source of the relationship is implicit, even without the ID. Used for expanding from Organization. relationship (Relationship): The relationship. where (Comparison, LogicalExpression or None): The `where` clause for filtering. order_by (None or (Field, Field.Order): The `order_by` clause for sorting results. Return: (str, dict) tuple that is the query string and parameters. """ check_where_clause(relationship.destination_type, where) check_order_by_clause(relationship.destination_type, order_by) to_many = relationship.relationship_type == Relationship.Type.ToMany subquery = Query(relationship.graphql_name, relationship.destination_type, where, to_many, order_by) query_where = type(source).uid == source.uid if isinstance(source, Entity) \ else None query = Query(utils.camel_case(source.type_name()), subquery, query_where) return query.format_top("Get" + source.type_name() + utils.title_case(relationship.graphql_name))
def format_param_value(attribute, param): if isinstance(attribute, Field): return "%s: $%s" % (attribute.graphql_name, param) else: return "%s: {connect: {id: $%s}}" % (utils.camel_case( attribute.graphql_name), param)
def test_camel(): assert utils.camel_case(SNAKE) == CAMEL assert utils.camel_case(TITLE) == CAMEL assert utils.camel_case(CAMEL) == CAMEL assert utils.camel_case(MIXED) == CAMEL