From e533d86943b17abd045199c1109a733f44877330 Mon Sep 17 00:00:00 2001 From: JPy Date: Thu, 12 Jul 2018 20:50:50 +0200 Subject: [PATCH] factorizing models parts + more on projects models --- solidata_api/_models/models_generic.py | 90 +++++++++++++++++ solidata_api/_models/models_projects.py | 79 ++++++++++----- solidata_api/_models/models_user.py | 86 ++++++++--------- .../_serializers/schema_datamodels.py | 16 ++++ solidata_api/_serializers/schema_generic.py | 34 +++++-- solidata_api/_serializers/schema_logs.py | 39 ++++++-- solidata_api/_serializers/schema_projects.py | 53 +++++----- solidata_api/_serializers/schema_users.py | 96 +++++++++++-------- solidata_api/api/__init__.py | 2 +- .../api/api_projects/endpoint_proj_create.py | 2 +- .../api/api_projects/endpoint_proj_edit.py | 2 +- .../api/api_projects/endpoint_projects.py | 2 +- solidata_api/api/api_users/endpoint_users.py | 1 + 13 files changed, 353 insertions(+), 149 deletions(-) create mode 100644 solidata_api/_models/models_generic.py diff --git a/solidata_api/_models/models_generic.py b/solidata_api/_models/models_generic.py new file mode 100644 index 0000000..626716a --- /dev/null +++ b/solidata_api/_models/models_generic.py @@ -0,0 +1,90 @@ +# -*- encoding: utf-8 -*- + +""" +_models/models_generic.py +- provides the models for all api routes +""" + +from log_config import log, pformat + +log.debug("... loading models_generic.py ...") + + +from flask_restplus import fields + +### import data serializers +from solidata_api._serializers.schema_logs import * +from solidata_api._serializers.schema_generic import * +from solidata_api._serializers.schema_projects import * + + + +### MODEL / BASIC INFOS +def create_model_basic_infos(ns_, model_name, + schema=doc_basics, + ) : + + basic_infos = fields.Nested( + ns_.model( model_name , doc_basics ) + ) + return basic_infos + + + +### MODEL TEAM +def create_model_team(ns_, model_name="Collaborator"): + + collaborator = fields.Nested( + ns_.model( model_name, { + 'user_oid' : oid, + 'auth_edit' : edit_auth + }) + ) + + collaborators = fields.List( + collaborator, + description = "List of collaborators on this document", + default = [] + ) + + return collaborators + + +### MODIFICATIONS LOG +def create_model_modif_log(ns_, model_name, + schema = modification_full, + include_counts = False, + counts_name = "counts", + include_created_by = True, + include_is_running = False, + ) : + + ### create the list of modifications + modifications = fields.List( + fields.Nested( + ns_.model('Modifications', schema ) + ), + description = "List of the modifications on this document", + default = [] + ) + + log_base = { + 'created_at' : created_at, + 'modified_log' : modifications + } + + if include_created_by == True : + log_base['created_by'] = oid + + if include_counts == True : + log_base[ counts_name ] = count + + if include_is_running == True : + log_base[ "is_running" ] = is_running + + ### compile the document's log + doc_log = fields.Nested( + ns_.model( model_name, log_base ) + ) + + return doc_log \ No newline at end of file diff --git a/solidata_api/_models/models_projects.py b/solidata_api/_models/models_projects.py index 15e882b..4ca1241 100644 --- a/solidata_api/_models/models_projects.py +++ b/solidata_api/_models/models_projects.py @@ -17,6 +17,8 @@ from solidata_api._serializers.schema_generic import * from solidata_api._serializers.schema_projects import * +### import generic models functions +from solidata_api._models.models_generic import * ### create models from serializers # nested models : https://github.com/noirbizarre/flask-restplus/issues/8 @@ -32,24 +34,34 @@ class Project_infos : def __init__(self, ns_) : - ### SELF MODULES - self.basic_infos = fields.Nested( - ns_.model('Project_public_data', project_basics ) - ) - - self.modifications = fields.List( - fields.Nested( - ns_.model('Modifications', modification ) - ), - default = [] - ) - self.project_log = fields.Nested( - ns_.model('Project_log', { - 'created_at' : created_at, - # 'login_count' : count, - 'modified_log' : self.modifications - }) - ) + ### SELF MODULES + # self.basic_infos = fields.Nested( + # ns_.model('Project_infos', doc_basics ) + # ) + self.basic_infos = create_model_basic_infos(ns_, "Project_infos") + + # self.modifications = fields.List( + # fields.Nested( + # ns_.model('Modifications_by', modification_full ) + # ), + # default = [] + # ) + # self.project_log = fields.Nested( + # ns_.model('Project_log', { + # 'created_at' : created_at, + # 'modified_log' : self.modifications + # }) + # ) + + self.project_log = create_model_modif_log(ns_, "Project_log", include_is_running=True) + + # self.collaborator = fields.Nested( + # ns_.model('Collaborator', { + # 'user_oid' : oid, + # 'auth_edit' : edit_auth + # }) + # ) + self.collaborators = create_model_team(ns_) ### IN / complete data to enter in DB @@ -58,17 +70,34 @@ def __init__(self, ns_) : 'infos' : self.basic_infos, 'log' : self.project_log , + ### team and edition levels + # 'proj_team' : fields.List(self.collaborator) , + 'proj_team' : self.collaborators , + ### datasets + 'dm_t' : oid, + 'ds_i' : fields.List(oid), + 'dc_' : fields.List(oid), + 'rec_' : fields.List(oid), }) ### OUT / complete data to enter in DB - self.mod_complete_out = ns_.model('Project_out', { - - 'infos' : self.basic_infos, - 'log' : self.project_log , - - - }) + # self.mod_complete_out = ns_.model('Project_out', { + + # 'infos' : self.basic_infos, + # 'log' : self.project_log , + + # ### team and edition levels + # # 'project_team' : fields.List(self.collaborator) , + # 'proj_team' : self.collaborators , + + # ### datasets + # 'datamodel' : oid, + # 'dataset_inputs' : fields.List(oid), + # 'correspondance_dicts' : fields.List(oid), + # 'recipes' : fields.List(oid), + + # }) @property diff --git a/solidata_api/_models/models_user.py b/solidata_api/_models/models_user.py index 24718b8..e3b017d 100644 --- a/solidata_api/_models/models_user.py +++ b/solidata_api/_models/models_user.py @@ -17,6 +17,8 @@ from solidata_api._serializers.schema_generic import * from solidata_api._serializers.schema_users import * +### import generic models functions +from solidata_api._models.models_generic import * ### create models from serializers # nested models : https://github.com/noirbizarre/flask-restplus/issues/8 @@ -33,7 +35,7 @@ def __init__(self, ns_): @property def model(self): return self.mod - + class AnonymousUser : """ @@ -145,27 +147,45 @@ def __init__(self, ns_) : ns_.model('User_profiles', user_profiles) ) - self.modifications = fields.List( - fields.Nested( - ns_.model('Modifications', modification ) - ), - default = [] - ) - self.user_log = fields.Nested( - ns_.model("User_log", { - 'created_at' : created_at, - 'login_count' : count, - 'modified_log' : self.modifications + # self.modifications = fields.List( + # fields.Nested( + # ns_.model('Modifications', modification ) + # ), + # default = [] + # ) + # self.user_log = fields.Nested( + # ns_.model("User_log", { + # 'created_at' : created_at, + # 'login_count' : count, + # 'modified_log' : self.modifications + # }) + # ) + + self.user_log = create_model_modif_log(ns_, "User_log", schema=modification, include_counts=True, counts_name='login_count', include_created_by=False) + + ### favorites + self.fav_ = fields.Nested( + ns_.model("User_fav", { + 'oid' : oid, + 'doc_categ' : doc_categ, + 'added_at' : created_at, }) ) + self.favorites = fields.List( + self.fav_ , + description = "list of user's favorite documents", + attribute = "favorites", + default = [] + ) ### IN / complete data to enter in DB self.mod_complete_in = ns_.model('User_in', { - 'infos' : self.basic_infos, - 'profile' : self.profiles, - 'log' : self.user_log , + 'infos' : self.basic_infos, + 'profile' : self.profiles, + 'log' : self.user_log , + 'favorites' : self.favorites, 'auth': fields.Nested( ns_.model('User_authorizations', user_auth_in ) @@ -184,9 +204,10 @@ def __init__(self, ns_) : ### OUT / complete data to enter in DB self.mod_complete_out = ns_.model('User_out', { - 'infos' : self.basic_infos, - 'profile' : self.profiles, - 'log' : self.user_log , + 'infos' : self.basic_infos, + 'profile' : self.profiles, + 'log' : self.user_log , + 'favorites' : self.favorites, 'auth' : fields.Nested( ns_.model('User_authorizations', user_auth_out ) @@ -207,9 +228,10 @@ def __init__(self, ns_) : ### OUT / for access tokens self.mod_access = ns_.model('User_access', { - 'infos' : self.basic_infos, - # 'log' : self.user_log, - # 'profile' : self.profiles, + 'infos' : self.basic_infos, + # 'log' : self.user_log, + # 'profile' : self.profiles, + # 'favorites' : self.favorites, 'auth' : fields.Nested( ns_.model('User_authorizations', user_auth_out ) @@ -236,25 +258,3 @@ def model_complete_out(self): def model_access(self): return self.mod_access -# class User_in : - -# def __init__(self, ns_) : - -# self.mod = ns_.model('User', { -# 'infos': fields.Nested( -# ns_.model('User_public_data', user_basics ) -# ), -# 'auth': fields.Nested( -# ns_.model('User_authorizations', user_auth ) -# ), -# 'preferences': fields.Nested( -# ns_.model('User_preferences', user_preferences_in ) -# ), -# 'datasets': fields.Nested( -# ns_.model('User_datasets', user_datasets_in ) -# ), -# }) - -# @property -# def model(self): -# return self.mod \ No newline at end of file diff --git a/solidata_api/_serializers/schema_datamodels.py b/solidata_api/_serializers/schema_datamodels.py index e69de29..5ac7671 100644 --- a/solidata_api/_serializers/schema_datamodels.py +++ b/solidata_api/_serializers/schema_datamodels.py @@ -0,0 +1,16 @@ +# -*- encoding: utf-8 -*- + +""" +schema_datamodels.py +- provides the model for DATAMODEL definition in DB and Flask-Restplus +""" + +from log_config import log, pformat + +log.debug("... loading schema_datamodels.py ...") + +from flask_restplus import fields + +from .schema_generic import * +from .schema_logs import * +from .schema_users import * \ No newline at end of file diff --git a/solidata_api/_serializers/schema_generic.py b/solidata_api/_serializers/schema_generic.py index a4d6451..63c538e 100644 --- a/solidata_api/_serializers/schema_generic.py +++ b/solidata_api/_serializers/schema_generic.py @@ -13,6 +13,7 @@ log.debug("... loading schema_generic.py ...") + ### generic info for updates generic_data = fields.String( description = "data about a document", @@ -22,7 +23,7 @@ required = True, ) -### basic informations about a document : project / dataset / ... +### basic informations about a document : project / licence / oid ... title = fields.String( description = "title of the document", attribute = "title", @@ -30,18 +31,37 @@ default = 'title', required = True, ) +descript = fields.String( + description = "description of the document", + attribute = "description", + example = "my-description", + default = 'description', + required = False, + ) +licence = fields.String( + description = "licence of the document", + attribute = "licence", + example = "my-licence", + default = 'licence', + required = True, + ) oid = fields.String( description = "oid of a document", attribute = "oid", example = "5b461ed90a82867e7b114f44", required = True, ) -edit_auth = fields.String( - description = "authorization level for edition", - attribute = "owner_oid", - example = "can_edit", +doc_categ = fields.String( + description = "category of a document : usr, dm_t, dm_p, dsi, cd, rec ...", + attribute = "doc_categ", + example = "usr", + default = 'usr', required = True, - default = 'title', ) - +### preformat some generic fields +doc_basics = { + "title" : title, + "licence" : licence, + "description" : descript, +} \ No newline at end of file diff --git a/solidata_api/_serializers/schema_logs.py b/solidata_api/_serializers/schema_logs.py index 095e0ad..7da4b73 100644 --- a/solidata_api/_serializers/schema_logs.py +++ b/solidata_api/_serializers/schema_logs.py @@ -9,38 +9,61 @@ from flask_restplus import fields #, marshal - log.debug("... loading schema_logs.py ...") +from .schema_generic import * ### counts infos count = fields.Integer( description = "count", - attribute = "count" , + # attribute = "count" , required = False, default = 0, ) ### datetime infos created_at = fields.DateTime( - description = "creation date", + description = "date of creation", attribute = "created_at" , - required = False, + required = True, ) modified_at = fields.DateTime( - description = "modification date", + description = "date of a modification", attribute = "modif_at" , - required = False, + required = True, ) modified_for = fields.String( - description = "modification action", + description = "action corresponding to a modification", attribute = "modif_for" , + required = True, + ) +# modified_by = fields.String( +# description = "user doing the modification", +# attribute = "modif_by" , +# required = False, +# ) +modified_val = fields.String( + description = "value of the modification", + attribute = "modif_val" , required = False, ) - ### FOR GENERIC MODELS modification = { "modif_at" : modified_at, "modif_for" : modified_for } + +modification_by = { + "modif_at" : modified_at, + "modif_for" : modified_for, + # "modif_by" : modified_by + "modif_by" : oid +} + +modification_full = { + "modif_at" : modified_at, + "modif_for" : modified_for, + "modif_by" : oid, + "modif_val" : modified_val, +} \ No newline at end of file diff --git a/solidata_api/_serializers/schema_projects.py b/solidata_api/_serializers/schema_projects.py index 6ef33f9..591de67 100644 --- a/solidata_api/_serializers/schema_projects.py +++ b/solidata_api/_serializers/schema_projects.py @@ -1,10 +1,14 @@ # -*- encoding: utf-8 -*- """ -model_projects.py +schema_projects.py - provides the model for PROJECT definition in DB and Flask-Restplus """ +from log_config import log, pformat + +log.debug("... loading schema_projects.py ...") + from flask_restplus import fields from .schema_generic import * @@ -13,35 +17,38 @@ - ### FOR GENERIC MODELS -project_data = { - "data" : generic_data, -} +# project_data = { +# "data" : generic_data, +# } + +is_running = fields.Boolean( + description = "is the project currently running ?", + attribute = "is_running", + example = False, + required = True, + default = False, + ) -project_basics = { - "title" : title, - "owner" : oid, - "dso" : oid -} -project_team = { - -} +# project_collaborator = { +# "user_oid" : oid, +# "auth_level" : None, +# } -project_datasets = { - "dm_" : None, -} +# project_datasets = { +# "dm_" : None, +# } -project_recipes = { - "on_datamodel" : None, - "on_datasets" : None, - "on_corr_dict" : None, -} +# project_recipes = { +# "on_datamodel" : None, +# "on_datasets" : None, +# "on_corr_dict" : None, +# } -project_outputs = { +# project_outputs = { -} +# } diff --git a/solidata_api/_serializers/schema_users.py b/solidata_api/_serializers/schema_users.py index e8a0723..d2b5aa7 100644 --- a/solidata_api/_serializers/schema_users.py +++ b/solidata_api/_serializers/schema_users.py @@ -9,9 +9,7 @@ log.debug("... loading schema_users.py ...") - -from flask_restplus import fields #, marshal -# import json +from flask_restplus import fields from ._choices_user import * from .schema_generic import * @@ -96,6 +94,13 @@ default = "no_old_refresh_token", required = False, ) +edit_auth = fields.List( + fields.String( + description = "edit auth of an user" + ), + attribute = "edit_auth", + default = [] + ) ### preferences language = fields.String( @@ -106,7 +111,8 @@ ) fav_list = fields.List( fields.String( - description = "ids of the favorites projects created by the user"), + description = "ids of the favorites projects created by the user" + ), attribute = "fav_list", default = [] ) @@ -114,23 +120,27 @@ ### profesional infos structures = fields.List( fields.String( - description = "structures / organisations the user"), + description = "structures / organisations the user" + ), example = ["my structure A", "my structure B"], attribute = "struct", default = [] ) struct_profiles = fields.List( fields.String( - description = "structures / organisations profile"), - enum = user_structure, - example = ["public_state"], + description = "structures / organisations profile", + example = "public_state", + enum = user_structure, + ), attribute = "struct_profiles", default = [] ) profiles = fields.List( fields.String( - description = "profiles of the user"), - enum = user_profiles, + description = "profiles of the user", + enum = user_structure, + ), + # enum = user_profiles, example = ["organizer"], attribute = "profiles", default = [] @@ -138,38 +148,44 @@ ### datasets infos proj_list = fields.List( - fields.String( - description = "ids of the projects created by the user"), + oid, + description = "ids of the projects created by the user", attribute = "proj_list", default = [] ) -dm_list = fields.List( - fields.String( - description = "ids of the datamodels created by the user"), - attribute = "dm_list", +dm_t_list = fields.List( + oid, + description = "ids of the datamodels templates created by the user", + attribute = "dm_t_list", default = [] ) -dsi_list = fields.List( - fields.String( - description = "ids of the datasets_in imported by the user"), - attribute = "dsi_list", +dm_p_list = fields.List( + oid, + description = "ids of the datamodels parts created by the user", + attribute = "dm_p_list", default = [] ) -dso_list = fields.List( - fields.String( - description = "ids of the datasets_out exported by the user"), - attribute = "dso_list", +ds_i_list = fields.List( + oid, + description = "ids of the datasets_in imported by the user", + attribute = "ds_i_list", default = [] ) +# dso_list = fields.List( +# oid, +# description = "ids of the datasets_out exported by the user", +# attribute = "dso_list", +# default = [] +# ) dc_list = fields.List( - fields.String( - description = "ids of the correspondance_dicts created by the user"), + oid, attribute = "dc_list", + description = "ids of the correspondance_dicts created by the user", default = [] ) rec_list = fields.List( - fields.String( - description = "ids of the recipes created by the user"), + oid, + description = "ids of the recipes created by the user", attribute = "rec_list", default = [] ) @@ -248,16 +264,17 @@ } user_datasets_in = { - "proj_" : proj_list, - "dm_" : dm_list, - "dsi_" : dsi_list, - "dso_" : dso_list, - "dc_" : dc_list, - "rec_" : rec_list, + "proj_list" : proj_list, + "dm_t_list" : dm_t_list, + "dm_p_list" : dm_p_list, + "ds_i_list" : ds_i_list, + # "ds_o_list" : dso_list, + "dc_list" : dc_list, + "rec_list" : rec_list, } user_preferences_in = { "lang" : language, - "fav_list" : fav_list + # "fav_list" : fav_list } user_professional_in = { @@ -279,16 +296,17 @@ user_datasets_out = { "projects" : proj_list, - "datamodels" : dm_list, - "datasets_inputs" : dsi_list, - "datasets_outputs" : dso_list, + "datamodels_templates" : dm_t_list, + "datamodels_parts" : dm_p_list, + "datasets_inputs" : ds_i_list, + # "datasets_outputs" : dso_list, "correspondance_dicts" : dc_list, "recipes" : rec_list, } user_preferences_out = { "language" : language, - "favorites" : fav_list + # "favorites" : fav_list } user_professional_out = { diff --git a/solidata_api/api/__init__.py b/solidata_api/api/__init__.py index 7cf94b3..0b614cc 100644 --- a/solidata_api/api/__init__.py +++ b/solidata_api/api/__init__.py @@ -10,7 +10,7 @@ from bson.objectid import ObjectId from bson.json_util import dumps -from flask import Blueprint, current_app as app, url_for, request +from flask import Blueprint, current_app as app, url_for, request, render_template from werkzeug.security import generate_password_hash, check_password_hash diff --git a/solidata_api/api/api_projects/endpoint_proj_create.py b/solidata_api/api/api_projects/endpoint_proj_create.py index a1100ef..537b1c9 100644 --- a/solidata_api/api/api_projects/endpoint_proj_create.py +++ b/solidata_api/api/api_projects/endpoint_proj_create.py @@ -16,7 +16,7 @@ ### import models from solidata_api._models.models_projects import * model_project_in = Project_infos(ns).mod_complete_in -model_project_out = Project_infos(ns).mod_complete_out +# model_project_out = Project_infos(ns).mod_complete_out ### + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ### diff --git a/solidata_api/api/api_projects/endpoint_proj_edit.py b/solidata_api/api/api_projects/endpoint_proj_edit.py index 5e8a8ee..92fe3b0 100644 --- a/solidata_api/api/api_projects/endpoint_proj_edit.py +++ b/solidata_api/api/api_projects/endpoint_proj_edit.py @@ -16,7 +16,7 @@ ### import models from solidata_api._models.models_projects import * model_project_in = Project_infos(ns).mod_complete_in -model_project_out = Project_infos(ns).mod_complete_out +# model_project_out = Project_infos(ns).mod_complete_out ### + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ### diff --git a/solidata_api/api/api_projects/endpoint_projects.py b/solidata_api/api/api_projects/endpoint_projects.py index d45544d..858693f 100644 --- a/solidata_api/api/api_projects/endpoint_projects.py +++ b/solidata_api/api/api_projects/endpoint_projects.py @@ -16,7 +16,7 @@ ### import models from solidata_api._models.models_projects import * model_project_in = Project_infos(ns).mod_complete_in -model_project_out = Project_infos(ns).mod_complete_out +# model_project_out = Project_infos(ns).mod_complete_out ### + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ### diff --git a/solidata_api/api/api_users/endpoint_users.py b/solidata_api/api/api_users/endpoint_users.py index 4ce2ade..526cebb 100644 --- a/solidata_api/api/api_users/endpoint_users.py +++ b/solidata_api/api/api_users/endpoint_users.py @@ -29,6 +29,7 @@ @ns.route('/') class UsersList(Resource): + ### TO DO : pagination arguments @ns.doc('users_list') @admin_required @ns.expect(pagination_arguments)