def drop_audit_trail(): """ Remove PGMemento audit trail """ db = get_database() db.exec_sql(relative_path(__file__, "drop-audit.sql")) drop_audit_columns(db)
async def users(request): db = get_database() with db.session_scope(commit=False): if request.method == "POST": data = await request.json() return create_user(db, data) res = db.session.query(User).all() return UserResponse(res)
def create_user(db, data): db = get_database() try: username = data["username"] password = data["password"] except IndexError: raise SparrowAPIError("Must provide both username and password") if db.session.query(User).get(username) is not None: raise SparrowAPIError(f"User {username} already exists", 409) res = _create_user(db, username, validate_password(password)) return UserResponse(res)
async def get(self, request): db = get_database() sample = db.model.sample sampleSchema = db.interface.sample(many=True) data = (db.session.query( sample.id, sample.name, sample.location).filter(sample.location != None).all()) json_data = sampleSchema.dump(data) return JSONResponse({"data": json_data, "total_count": len(json_data)})
async def get(self, request): """Handler for all GET requests""" model_names = await parser.parse(self.args_schema, request, location="querystring") db = get_database() n_models = sum(len(v) for v in model_names.values()) if n_models == 0: raise SparrowAPIError("No IDs were passed to filter by") # Wrap entire query infrastructure in error-handling block. # We should probably make this a "with" statement or something # to use throughout our API code. with db.session_scope(commit=False): DataFile = db.model.data_file DataFileLink = db.model.data_file_link data = [] for model_name, model_ids in model_names.items(): q = db.session.query( DataFile.file_hash, DataFile.file_mtime, DataFile.basename, DataFile.type_id, getattr(DataFileLink, model_name), ).order_by(DataFile.file_mtime) q = q.join(DataFile.data_file_link_collection).filter( getattr(DataFileLink, model_name).in_(model_ids)) res = q.all() # SUPER messy way to create a custom json serialization for row in res: row_obj = {} file_hash, file_mtime, basename, type_id, model_id = row row_obj["file_hash"] = file_hash row_obj["file_mtime"] = file_mtime.isoformat() row_obj["basename"] = basename row_obj["type"] = type_id row_obj["model"] = model_name[:-3] row_obj["model_id"] = model_id data.append(row_obj) return JSONResponse(dict(data=data, total_count=len(data)))
async def get(self, request): """Handler for all GET requests""" args = await parser.parse(self.args_schema, request, location="querystring") db = get_database() if not len(request.query_params.keys()): return JSONResponse({}) # Wrap entire query infrastructure in error-handling block. # We should probably make this a "with" statement or something # to use throughout our API code. with db.session_scope(commit=False): try: DataFile = self.model q = db.session.query( DataFile.file_hash, DataFile.file_mtime, DataFile.basename, DataFile.type_id, ).order_by(DataFile.file_mtime) if args["all"]: res = q.all() return APIResponse(res, schema=self.schema(many=True), total_count=len(res)) for _filter in self._filters: q = _filter(q, args) try: res = get_page(q, per_page=args["per_page"], page=args["page"]) except ValueError: raise ValidationError("Invalid page token.") # Note: we don't need to use a schema to serialize here. but it is nice if we have it return APIResponse(res, schema=self.schema(many=True)) except Exception as err: raise ApplicationError(str(err))
async def login(request, username: str, password: str): db = get_database() backend = get_backend() current_user = db.session.query(User).get(username) log.debug(current_user) if current_user is not None and current_user.is_correct_password(password): day = 24 * 60 * 60 token = backend.set_cookie(None, "access", max_age=day, identity=username) resp = JSONResponse(dict(login=True, username=username, token=token)) return backend.set_login_cookies(resp, identity=username) return backend.logout(UnauthorizedResponse(status_code=401))
def validate_data(model_name): """Try to import data into the database to see if errors are raised. Pipe JSON into this command's stdin to see if the import will be successful. """ setup_stderr_logs() setup_stderr_logs("sqlalchemy.engine") db = get_database() data = load(stdin) # In some cases, we might have data in the "data" key # NOTE: this is likely a bad assumption in many cases, probably schema = getattr(db.interface, model_name)() t0 = time() with on_conflict("do-nothing"): res = schema.load(data, session=db.session) db.session.add(res) t_delta = time() - t0 print(f"Elapsed time: {t_delta:.2f} seconds")
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) db = get_database() self.schema = db.interface.data_file self.model = db.model.data_file self._filters = [] self.register_filter(OpenSearchFilter) self.register_filter(AuthorityFilter) self.register_filter(FieldExistsFilter) self.register_filter(FieldNotExistsFilter) self.register_filter(EmbargoFilter) self.register_filter(DateFilter) self.register_filter(TextSearchFilter) self.register_filter(AgeRangeFilter) self.register_filter(IdListFilter) self.register_filter(TagsFilter)
async def user(request): auth = get_backend() db = get_database() username = request.path_params["username"] user = db.session.query(User).get(username) if user is None: raise SparrowAPIError(f"User {username} does not exist", 404) if request.method == "GET": return UserResponse(user) elif request.method == "PUT": data = await request.json() return update_user(db, user, data) elif request.method == "DELETE": # Make sure we aren't trying to delete ourselves if user.username == auth.get_identity(request): raise SparrowAPIError("Cannot delete yourself", 403) with db.session_scope(): db.session.delete(user) return JSONResponse({"success": "True", "deleted": [username]}) raise SparrowAPIError("Method not allowed", 405)
async def put(self, request): db = get_database() sample = db.model.sample id_ = request.path_params["id"] sample_ = db.session.query(sample).get(id_) data = await request.json() if "member_of" in data: member_id = data["member_of"] sample_.member_of = member_id try: db.session.commit() return JSONResponse({"id": id_, "member_of": member_id}) except Exception as err: db.session.rollback() raise ApplicationError(str(err))
async def get(self, request): db = get_database() sample = db.model.sample sampleSchema = db.interface.sample(many=True) if "id" not in request.path_params: return JSONResponse({}) id_ = request.path_params["id"] sample_ = db.session.query(sample).get(id_) if len(sample_.sample_collection) == 0: return JSONResponse({"id": id_, "sample_collection": []}) sample_collection = sampleSchema.dump(sample_.sample_collection) return JSONResponse({ "id": id_, "sample_collection": sample_collection })
def __init__(self, user_): db = get_database() _many = isinstance(user_, Iterable) _schema = db.interface.user(many=_many, exclude=("password", )) super().__init__(user_, schema=_schema)