def delete_atlas(dataset: str, x: int, y: int, z: int, user: User = Depends(get_user)): if not user.can_write_own(dataset): raise HTTPException( status_code=401, detail=f"no permission to delete annotations in dataset {dataset}") try: # delete only supported from interface # (delete by dataset + user name + xyz) collection = firestore.get_collection( [CLIO_ANNOTATIONS, "ATLAS", "annotations"]) match_list = collection.where("user", "==", user.email).where( "locationkey", "==", f"{x}_{y}_{z}").where("dataset", "==", dataset).get() for match in match_list: match.reference.delete() except Exception as e: print(e) raise HTTPException( status_code=400, detail= f"error in deleting annotation ({x},{y},{z}) for dataset {dataset}" )
def delete_annotation(dataset: str, key: str, user_email: str = "", user: User = Depends(get_user)): """ Delete an annotation based on the key supplied in the URL. If the client has proper authorization, annotations for another user can be deleted by supplying the query string '[email protected]'. """ if user_email == "": user_email = user.email authorized = (user_email == user.email and user.can_write_own(dataset)) or \ (user_email != user.email and user.can_write_others(dataset)) if not authorized: raise HTTPException( status_code=401, detail= f"no permission to delete annotation for user {user_email} on dataset {dataset}" ) try: collection = firestore.get_collection( [CLIO_ANNOTATIONS_V2, dataset, user_email]) collection.document(key).delete() except Exception as e: print(e) raise HTTPException( status_code=400, detail= f"error in deleting annotation with key {key} for dataset {dataset}" )
def write_annotation(dataset: str, annotation: Annotation, user: User, move_key: str = "") -> str: if annotation.user is None: annotation.user = user.email authorized = (annotation.user == user.email and user.can_write_own(dataset)) or \ (annotation.user != user.email and user.can_write_others(dataset)) if not authorized: raise HTTPException( status_code=401, detail= f"no permission to add annotation for user {annotation.user} on dataset {dataset}" ) try: collection = firestore.get_collection( [CLIO_ANNOTATIONS_V2, dataset, annotation.user]) annotation_json = jsonable_encoder(annotation, exclude_unset=True) key = annotation.key() collection.document(key).set(annotation_json) if move_key != "" and move_key != key: collection.document(move_key).delete() return key except Exception as e: print(e) raise HTTPException( status_code=400, detail=f"error in put annotation for dataset {dataset}")
def submit_subvol(dataset: str, payload: dict, user: User = Depends(get_user)): """ Stores reference to an edited neuroglancer subvolume. """ if not user.can_write_own(dataset): raise HTTPException( status_code=401, detail=f"no permission to submit subvolume in dataset {dataset}") try: payload["_timestamp"] = time.time() collection = firestore.get_collection( [CLIO_SUBVOL, user.email, "submissions"]) collection.document().set(payload) except Exception as e: print(e) raise HTTPException( status_code=400, detail=f"error submitting subvolume for dataset {dataset}: {e}")
def edit_subvol(dataset: str, subvol: SubVolume, user: User = Depends(get_user)): """ Creates a neuroglancer precomputed subvolume cutout given bounding box. Returns python script that can be downloaded and used to open and then submit change to Clio store. """ if not user.can_read(dataset) or not user.can_write_own(dataset): raise HTTPException( status_code=401, detail=f"no permission to edit subvolume in dataset {dataset}") try: dataset_obj = get_dataset(dataset) # cv = CloudVolume(dataset_obj.location) # vol_dest = subvol.destination(user.email) # vol_bounds = subvol.bbox() # cv.transfer_to(vol_dest, vol_bounds) except Exception as e: print(e) raise HTTPException( status_code=400, detail=f"error editing subvolume for dataset {dataset}: {e}")
def post_atlas(dataset: str, x: int, y: int, z: int, payload: dict, user: User = Depends(get_user)) -> dict: if "title" not in payload or "user" not in payload: raise HTTPException( status_code=400, detail=f"POSTed object must include 'title' and 'user' properties") if not user.can_write_own(dataset): raise HTTPException( status_code=401, detail=f"no permission to write annotations in dataset {dataset}") if payload["user"] != user.email and not user.can_write_others(dataset): raise HTTPException( status_code=401, detail= f"no permission to write others' annotations in dataset {dataset}") if "verified" in payload and payload["verified"] and not user.has_role( "clio_write", dataset): raise HTTPException( status_code=401, detail=f"no permission to set verified status in dataset {dataset}" ) try: location_key = f"{x}_{y}_{z}" collection = firestore.get_collection( [CLIO_ANNOTATIONS, "ATLAS", "annotations"]) annotations = collection.where("user", "==", payload["user"]) \ .where("dataset", "==", dataset) \ .where("locationkey", "==", f"{x}_{y}_{z}").get() payload["timestamp"] = time.time() payload["dataset"] = dataset payload["location"] = [x, y, z] payload["locationkey"] = location_key if len(annotations) == 0: new_ref = collection.document() payload["id"] = new_ref.id if "verified" in payload: if payload["verified"] and not user.has_role( "clio_write", dataset): raise HTTPException( status_code=401, detail=f"no permission to set verified atlas pt") else: payload["verified"] = False new_ref.set(payload) else: first = True for annotation in annotations: if first: current = annotation.to_dict() if "verified" in current and current[ "verified"] and not user.has_role( "clio_write", dataset): raise HTTPException( status_code=401, detail=f"no permission to modify verified atlas pt" ) payload["id"] = annotation.id annotation.reference.set(payload) first = False else: # shouldn't happen unless legacy bad points. print( f"deleted duplicate atlas annotation point: {annotation}" ) annotation.reference.delete() return payload except HTTPException as e: raise e except Exception as e: print(e) raise HTTPException( status_code=400, detail= f"error in put annotation ({x},{y},{z}) for dataset {dataset}: {e}" )