Beispiel #1
0
    def get(self):
        """Refreshes an existing JWT by creating a new one that is a copy of the old
        except that it has a refreshed access expiration.
        
        .. :quickref: Authentication; Refresh a token.

        .. code-block:: bash

            $ curl http://localhost:5000/api/v1/auth/token/ -X GET \\
              -H "Authorization: Bearer <your_token>"
        """
        # old_token = praetorian.read_token_from_header()
        # new_token = praetorian.refresh_jwt_token(old_token)
        # response = {"access_token": new_token}

        user = current_user()
        response = {
            "access_token": praetorian.encode_jwt_token(user),
            "valid_for": praetorian.access_lifespan.total_seconds(),
            "user": {
                "id": user.id,
                "login": user.login,
                "full_name": user.full_name,
                "email": user.email,
            },
        }

        return NestedResponse().dump(response)
Beispiel #2
0
    def post(self) -> dict:
        """Creates a new project.

        .. :quickref: Projects; Create a new project.

        :param name: a name/title for the project
        :param description: a description of the project and it's purpose
        :param workspace_id: id of the workspace that contains this project
        :returns: a newly created project
        """
        parser = reqparse.RequestParser()
        parser.add_argument("name",
                            type=str,
                            required=True,
                            help="No name provided")
        parser.add_argument("description", type=str)
        parser.add_argument("workspace_id", type=int, required=True)
        args = parser.parse_args()

        workspace = Workspace.query.filter_by(id=args["workspace_id"]).first()
        if workspace:
            project = Project(
                name=args["name"],
                description=args["description"],
                workspace_id=args["workspace_id"],
            )
            db.session.add(project)
            db.session.commit()

            return NestedResponse(schema=ProjectSchema).dump(project)
        return {
            "error": f"Workspace {args['workspace_id']} does not exist."
        }, 400
Beispiel #3
0
    def post(self):
        """Logs the user in by parsing a POST request containing user credentials and
        issuing a JWT token.

        .. :quickref: Authentication; Log user in.

        .. code-block:: bash
        
            $ curl http://localhost:5000/api/v1/auth/login/ -X POST \\
              -d '{"login":"******", "password":"******"}'
        """
        parser = reqparse.RequestParser()
        parser.add_argument("login", type=str, required=True)
        parser.add_argument("password", type=str, required=True)
        args = parser.parse_args()

        user = praetorian.authenticate(args["login"], args["password"])
        current_app.logger.info("user " + str(user.id) +
                                " logged in successfully")
        response = {
            "access_token": praetorian.encode_jwt_token(user),
            "valid_for": praetorian.access_lifespan.total_seconds(),
            "user": {
                "id": user.id,
                "login": user.login,
                "full_name": user.full_name,
                "email": user.email,
            },
        }

        return NestedResponse().dump(response)
Beispiel #4
0
    def get(self, id: int) -> dict:
        workspace = Workspace.query.filter_by(id=id).first()

        if not workspace:
            abort(404)

        return NestedResponse(schema=WorkspaceSchema).dump(workspace)
    def get(self, id: int) -> dict:
        project = Project.query.filter_by(id=id).first()

        if not project:
            abort(404)

        return NestedResponse(schema=ProjectSchema).dump(project)
Beispiel #6
0
    def post(self) -> dict:
        """Creates a new user.

        .. :quickref: Users; Create a new user.

        :param login: login for the new user
        :param password: password for the new user
        :param full_name: full name for the new user (optional)
        :param email: an email address for the new user (optional)
        :returns: a newly created user
        """
        parser = reqparse.RequestParser()
        parser.add_argument("login", type=str, required=True)
        parser.add_argument("password", type=str, required=True)
        parser.add_argument("full_name", type=str)
        parser.add_argument("email", type=str)
        args = parser.parse_args()

        new_user = User(
            login=args["login"],
            password=args["password"],
            full_name=args["full_name"],
            email=args["email"],
        )

        db.session.add(new_user)
        db.session.commit()

        return NestedResponse(schema=UserSchema).dump(new_user)
Beispiel #7
0
    def get(self) -> list:
        """Lists all models that satisfy certain conditions.
        
        Every parameter can be appeneded multiple times.
        :param workspace: search for models only in this workspace
        :param project: search for models only in this project
        :param hyperparam: search for models that have this hyperparameter
        :param param: search for models that have this parameter

        :returns: a list of objects
        """
        parser = paginated_parser.copy()
        parser.add_argument("projects", type=str)

        args = parser.parse_args()

        # Initialize query builder
        query = Model.query

        paginated_query = query.paginate(args["page"], args["per_page"], False)

        return NestedResponse(schema=ModelLesserSchema,
                              many=True,
                              pagination=paginated_query).dump(
                                  paginated_query.items)
    def get(self) -> list:
        parser = paginated_parser.copy()
        args = parser.parse_args()
        paginated_query = Project.query.paginate(args["page"], args["per_page"], False)

        return NestedResponse(
            schema=ProjectSchema, many=True, pagination=paginated_query
        ).dump(paginated_query.items)
Beispiel #9
0
    def post(self) -> dict:
        parser = reqparse.RequestParser()
        parser.add_argument("name", type=str, required=True, help="No name provided")
        parser.add_argument("description", type=str, default="")
        args = parser.parse_args()
        workspace = Workspace(name=args["name"], description=args["description"])
        db.session.add(workspace)
        db.session.commit()

        return NestedResponse(schema=WorkspaceSchema).dump(workspace)
Beispiel #10
0
    def get(self, id: int) -> dict:
        """Returns data about a requested user.

        .. :quickref: Users; Get a single user.

        :param id: id of a requested user
        :returns: a single object
        """
        user = User.query.filter_by(id=id).one_or_none()

        return NestedResponse(schema=UserSchema).dump(user)
Beispiel #11
0
 def get(self) -> list:
     parser = paginated_parser.copy()
     args = parser.parse_args()
     # paginated_query = Tag.query.options(db.noload('models')).paginate(args["page"], args["per_page"], False)
     paginated_query = Tag.query.paginate(args["page"], args["per_page"],
                                          False)
     return NestedResponse(schema=TagSchema,
                           exclude=("models", ),
                           many=True,
                           pagination=paginated_query).dump(
                               paginated_query.items)
Beispiel #12
0
 def delete(self, model_id: int, tag_id: int) -> dict:
     model = Model.query.filter_by(id=model_id).first()
     tag = Tag.query.filter_by(id=tag_id).first()
     if not (model and tag):
         abort(404)
     tag.models.remove(model)
     current_app.logger.info("tag " + str(tag_id) + " dropped from model " +
                             str(model_id))
     db.session.add(tag)
     db.session.commit()
     return NestedResponse(schema=ModelSchema).dump(model)
    def get(self, id: int) -> dict:
        """Returns data about a requested tag.
        
        :param id: id of a requested tag
        :returns: a single object
        """
        tag = Tag.query.filter_by(id=id).one_or_none()

        if not tag:
            abort(404)

        return NestedResponse(schema=TagSchema).dump(tag)
    def get(self, id: int) -> dict:
        """Returns data about a requested model.
        
        :param id: id of a requested model
        :returns: a single object
        """
        model = Model.query.filter_by(id=id).one_or_none()

        if not model:
            abort(404)

        return NestedResponse(schema=ModelSchema).dump(model)
    def post(self) -> dict:
        parser = reqparse.RequestParser()
        parser.add_argument("name",
                            type=str,
                            required=True,
                            help="No name provided")
        parser.add_argument("description", type=str)
        args = parser.parse_args()

        tag = Tag(name=args["name"], description=args["description"])
        db.session.add(tag)
        db.session.commit()

        return NestedResponse(schema=TagSchema).dump(tag)
Beispiel #16
0
    def get(self) -> list:
        """Lists all users.
        
        .. :quickref: Users; Get a collection of users.

        :return: a list of users
        """
        parser = paginated_parser.copy()
        args = parser.parse_args()

        paginated_query = User.query.paginate(args["page"], args["per_page"],
                                              False)
        return NestedResponse(schema=UserSchema,
                              many=True,
                              pagination=paginated_query).dump(
                                  paginated_query.items)
Beispiel #17
0
    def get(self, id: int) -> dict:
        """Returns data about a requested project.

        .. :quickref: Projects; Get a single project.
        
        :param id: id of a requested project
        :reqheader Authorization: Bearer JWT
        :status 200: when project exists
        :status 404: when requested project does not exist
        :returns: a single object
        """
        project = Project.query.filter_by(id=id).first()

        if not project:
            abort(404)

        return NestedResponse(schema=ProjectSchema).dump(project)
Beispiel #18
0
    def get(self) -> list:
        """Lists all projects.
        
        .. :quickref: Projects; Get a collection of projects.

        :param search: lists only projects that contain the name like `search`
        :return: a list of projects
        """
        parser = paginated_parser.copy()
        args = parser.parse_args()
        paginated_query = Project.query.paginate(args["page"],
                                                 args["per_page"], False)

        return NestedResponse(schema=ProjectSchema,
                              many=True,
                              pagination=paginated_query).dump(
                                  paginated_query.items)
Beispiel #19
0
    def post(self) -> dict:
        parser = reqparse.RequestParser()
        parser.add_argument("login", type=str, required=True)
        parser.add_argument("password", type=str, required=True)
        parser.add_argument("full_name", type=str)
        parser.add_argument("email", type=str)
        args = parser.parse_args()

        new_user = User(
            login=args["login"],
            password=args["password"],
            full_name=args["full_name"],
            email=args["email"],
        )

        db.session.add(new_user)
        db.session.commit()

        return NestedResponse(schema=UserSchema).dump(new_user)
    def post(self) -> dict:
        parser = reqparse.RequestParser()
        parser.add_argument("name", type=str, required=True, help="No name provided")
        parser.add_argument("description", type=str)
        parser.add_argument("workspace_id", type=int, required=True)
        args = parser.parse_args()

        workspace = Workspace.query.filter_by(id=args["workspace_id"]).first()
        if workspace:
            project = Project(
                name=args["name"],
                description=args["description"],
                workspace_id=args["workspace_id"],
            )
            db.session.add(project)
            db.session.commit()

            return NestedResponse(schema=ProjectSchema).dump(project)
        return {"error": f"Workspace {args['workspace_id']} does not exist."}, 400
    def post(self) -> dict:
        parser = reqparse.RequestParser()
        parser.add_argument("name", type=str)
        parser.add_argument("dataset_name", type=str)
        parser.add_argument("dataset_description", type=str)
        parser.add_argument("project_id", type=int, required=True)
        parser.add_argument("user_id", type=int, required=True)
        parser.add_argument("hyperparameters", type=str, default="{}")
        parser.add_argument("parameters", type=str, default="{}")
        parser.add_argument("metrics", type=str, default="{}")
        parser.add_argument("git_active_branch", type=str, default=None)
        parser.add_argument("git_commit_hash", type=str, default=None)
        parser.add_argument("file", type=FileStorage, location="files", required=True)
        parser.add_argument("private", type=bool, default=False)
        args = parser.parse_args()

        if "file" in args:
            print("FILE:", args["file"])
            filename = models_uploadset.save(args["file"], name=str(uuid.uuid4()) + ".")

            for arg_name in ["hyperparameters", "parameters", "metrics"]:
                args[arg_name] = json.loads(args[arg_name])

            new_model = Model(
                user_id=args["user_id"],
                project_id=args["project_id"],
                hyperparameters=args["hyperparameters"],
                parameters=args["parameters"],
                metrics=args["metrics"],
                name=args["name"],
                path=filename,
                dataset_name=args["dataset_name"],
                dataset_description=args["dataset_description"],
                git_active_branch=args["git_active_branch"],
                git_commit_hash=args["git_commit_hash"],
                private=args["private"],
            )

        db.session.add(new_model)
        db.session.commit()

        return NestedResponse(schema=ModelSchema).dump(new_model)
Beispiel #22
0
    def post(self) -> dict:
        """Uploads a model.

        .. :quickref: Models; Upload a new model.

        :param name: human-readable name of the model
        :param dataset_name: name used to identify the dataset
        :param dataset_description: description used to provide more context
        :param project_id: id of the project the model belongs to
        :param hyperparameters: a dictionary of hyperparameters
        :param parameters: a dictionary of parameters
        :param metrics: a dictionary of metrics
        :param tags: a list of tags in form of a single string separated by commas
        :param git_active_branch: an active branch of the uploaded model
        :param git_commit_hash: hash of the most recent commit
        :param file: contents of the file selected to upload
        :param private: whether to mark the model as private
        :returns: a newly uploaded model
        """
        parser = reqparse.RequestParser()
        parser.add_argument("name", type=str)
        parser.add_argument("dataset_name", type=str)
        parser.add_argument("dataset_description", type=str)
        parser.add_argument("project_id", type=int, required=True)
        # user_id : deprecated
        parser.add_argument("user_id", type=int, required=False)
        parser.add_argument("hyperparameters", type=str, default="{}")
        parser.add_argument("parameters", type=str, default="{}")
        parser.add_argument("metrics", type=str, default="{}")
        parser.add_argument("tags", type=str, default="")
        parser.add_argument("git_active_branch", type=str, default=None)
        parser.add_argument("git_commit_hash", type=str, default=None)
        parser.add_argument("file",
                            type=FileStorage,
                            location="files",
                            required=True)
        parser.add_argument("private", type=bool, default=False)
        args = parser.parse_args()

        if "file" in args:
            print("FILE:", args["file"])
            filename = models_uploadset.save(args["file"],
                                             name=str(uuid.uuid4()) + ".")

            for arg_name in ["hyperparameters", "parameters", "metrics"]:
                args[arg_name] = json.loads(args[arg_name])

            user = current_user()
            new_model = Model(
                user_id=user.id,
                project_id=args["project_id"],
                hyperparameters=args["hyperparameters"],
                parameters=args["parameters"],
                metrics=args["metrics"],
                name=args["name"],
                path=filename,
                dataset_name=args["dataset_name"],
                dataset_description=args["dataset_description"],
                git_active_branch=args["git_active_branch"],
                git_commit_hash=args["git_commit_hash"],
                private=args["private"],
            )

        db.session.add(new_model)
        db.session.commit()

        return NestedResponse(schema=ModelSchema).dump(new_model)
Beispiel #23
0
    def get(self, id: int) -> dict:
        user = User.query.filter_by(id=id).one_or_none()

        return NestedResponse(schema=UserSchema).dump(user)
Beispiel #24
0
    def get(self) -> list:
        """Lists all models that satisfy certain conditions.
        
        .. :quickref: Models; Get a collection of models.

        Every parameter can be appended multiple times.

        :param workspace: search for models only in this workspace
        :param project: search for models only in this project
        :param hyperparam: search for models that have this hyperparameter
        :param param: search for models that have this parameter
        :returns: a list of objects
        """
        parser = paginated_parser.copy()
        parser.add_argument("workspace", type=int)
        parser.add_argument("projects", type=str)
        parser.add_argument("hyperparameters", type=str)
        parser.add_argument("parameters", type=str)
        parser.add_argument("metrics", type=str)
        parser.add_argument("users", type=str)

        args = parser.parse_args()

        # Initialize query builder
        query = Model.query

        if args["workspace"]:
            # TODO: add fetching models from multiple workspaces
            # query = query.filter()
            pass
        if args["projects"]:
            query = query.filter(
                Model.project_id.in_(args["projects"].split(",")))
        if args["users"]:
            query = query.filter(Model.user_id.in_(args["users"].split(",")))
        # if args["hyperparameters"]:
        #     # Filtering through hyperparameters.
        #     # Every result has to contain ALL of the requested keys
        #     query = query.filter(
        #         Model.hyperparameters.has_all(
        #             postgres_array(args["hyperparameters"].split(","))
        #         )
        #     )
        # if args["parameters"]:
        #     # Filtering through parameters.
        #     # Every result has to contain ALL of the requested keys
        #     query = query.filter(
        #         Model.parameters.has_all(postgres_array(args["parameters"].split(",")))
        #     )
        if args["metrics"]:
            # Filtering through metrics.
            # Every result has to contain ALL of the requested keys
            query = query.filter(
                Model.metrics.has_all(
                    postgres_array(args["metrics"].split(","))))

        paginated_query = query.paginate(args["page"], args["per_page"], False)

        return NestedResponse(
            schema=ModelSchema,
            exclude=("parameters", "hyperparameters", "metrics"),
            many=True,
            pagination=paginated_query,
        ).dump(paginated_query.items)