From 1120db0567d49fe4d24234583d29a78f77be162d Mon Sep 17 00:00:00 2001 From: Joaquin Vanschoren Date: Sun, 29 Sep 2019 10:32:43 +0200 Subject: [PATCH 1/2] Develop (#999) * fixed link * ES bugfix * setup api docs * apidocs fix * Return the reason why the XML was not valid according to the XSD * force download of RDF files * add uploader to evaluation_list * add user_id to name * add to initial check * list of user names * add username tpl to views and remove from_id function * remove extra brace * add uploader to evaluations * change uploader to user * change uploader to user * doc update * doc update * Delete swagger.json * Delete swagger.yaml * review comments * add space * extended error messages * better error handling * increase stat circles on cover page * indentation changes * two spaces * fix code style --- css/expdb.css | 12 ++-- downloads/swagger.json | 72 +++++++++++++++++-- downloads/swagger.yaml | 68 ++++++++++++++++-- openml_OS/helpers/api_helper.php | 4 +- openml_OS/models/api/v1/Api_evaluation.php | 2 +- openml_OS/models/api/v1/Api_study.php | 10 ++- openml_OS/models/api/v1/Api_user.php | 27 +++++++ .../pages/api_new/v1/xml/evaluations.tpl.php | 1 + .../pages/api_new/v1/xml/user-name.tpl.php | 8 +++ openml_OS/views/rdf_main.php | 4 ++ 10 files changed, 184 insertions(+), 24 deletions(-) create mode 100644 openml_OS/views/pages/api_new/v1/xml/user-name.tpl.php diff --git a/css/expdb.css b/css/expdb.css index d1bafb19a..f644322d7 100644 --- a/css/expdb.css +++ b/css/expdb.css @@ -2762,11 +2762,10 @@ a.bold:hover{ font-weight: 100; - width: 76px; - height: 76px; + width: 100px; + height: 100px; padding: 0px; - background: #fff; color: #fff; display:block; position: relative; @@ -2793,10 +2792,9 @@ a.bold:hover{ } .arc { - height: 84px; - width: 84px; - left: -3px; - top: -5px; + height: 100px; + width: 100px; + top: -15px; position: absolute; box-shadow: 0 0 4px rgba(0,0,0,.14),0 4px 8px rgba(0,0,0,.28); diff --git a/downloads/swagger.json b/downloads/swagger.json index c9ab66470..f671f448c 100755 --- a/downloads/swagger.json +++ b/downloads/swagger.json @@ -1979,6 +1979,7 @@ "evaluation" : [ { "run_id" : "1", "task_id" : "68", + "uploader" : "1", "flow_id" : "61", "function" : "area_under_roc_curve", "upload_time" : "2014-04-06 23:30:40", @@ -1987,6 +1988,7 @@ }, { "run_id" : "1", "task_id" : "68", + "uploader" : "1", "flow_id" : "61", "function" : "f_measure", "upload_time" : "2014-04-06 23:30:40", @@ -1995,6 +1997,7 @@ }, { "run_id" : "1", "task_id" : "68", + "uploader" : "1", "flow_id" : "61", "function" : "predictive_accuracy", "upload_time" : "2014-04-06 23:30:40", @@ -2237,16 +2240,16 @@ "parameters" : [ { "name" : "id", "in" : "path", - "description" : "Id of the study.", + "description" : "Id of the study. Supplied in the URL path.", "required" : true, "type" : "number", "format" : "integer" }, { - "name" : "description", + "name" : "ids", "in" : "formData", - "description" : "An XML file describing the entities to be attached. Also see the [XSD schema](https://www.openml.org/api/v1/xsd/openml.study.attach) and an [XML example](https://www.openml.org/api/v1/xml_example/attach).", + "description" : "Comma-separated list of entity IDs to be attached to the study. For instance, if this is a run study, the list of run IDs that need to be added (attached) to the study. Must be supplied as a POST variable.", "required" : true, - "type" : "file" + "type" : "string" }, { "name" : "api_key", "in" : "query", @@ -2292,11 +2295,11 @@ "type" : "number", "format" : "integer" }, { - "name" : "description", + "name" : "ids", "in" : "formData", - "description" : "An XML file describing the entities to be detached. Also see the [XSD schema](https://www.openml.org/api/v1/xsd/openml.study.detach) and an [XML example](https://www.openml.org/api/v1/xml_example/detach).", + "description" : "Comma-separated list of entity IDs to be detached from the study. For instance, if this is a run study, the list of run IDs that need to be removed (detached) from the study. Must be supplied as a POST variable.", "required" : true, - "type" : "file" + "type" : "string" }, { "name" : "api_key", "in" : "query", @@ -2359,6 +2362,31 @@ } } }, + "/user/list" : { + "get" : { + "tags" : [ "user" ], + "summary" : "List all users by user id", + "description" : "Returns an array with all user ids and names.\n", + "parameters" : [ { + "name" : "api_key", + "in" : "query", + "description" : "API key to authenticate the user", + "required" : false, + "type" : "string" + } ], + "responses" : { + "200" : { + "description" : "A list of users", + "examples" : { + "application/json" : "{\n \"users\":{\n \"user\":[\n {\n \"id\":\"1\",\n \"username\":\"janvanrijn@gmail.com\"},\n {\n \"id\":\"2\",\n \"username\":\"joaquin.vanschoren@gmail.com\"}\n ]\n }\n}" + }, + "schema" : { + "$ref" : "#/definitions/UserList" + } + } + } + } + }, "/evaluationmeasure/list" : { "get" : { "tags" : [ "evaluationmeasure" ], @@ -2402,6 +2430,14 @@ } } }, + "UserList" : { + "type" : "object", + "properties" : { + "users" : { + "$ref" : "#/definitions/UserList_users" + } + } + }, "Task" : { "type" : "object", "properties" : { @@ -3146,6 +3182,28 @@ } } }, + "UserList_users_user" : { + "properties" : { + "id" : { + "type" : "string", + "description" : "The user ID" + }, + "username" : { + "type" : "string", + "description" : "The full user name" + } + } + }, + "UserList_users" : { + "properties" : { + "user" : { + "type" : "array", + "items" : { + "$ref" : "#/definitions/UserList_users_user" + } + } + } + }, "Task_task_description_data_set" : { "properties" : { "data_set_id" : { diff --git a/downloads/swagger.yaml b/downloads/swagger.yaml index a8f469f9a..5854f0bcb 100755 --- a/downloads/swagger.yaml +++ b/downloads/swagger.yaml @@ -2635,6 +2635,7 @@ paths: evaluation: - run_id: "1" task_id: "68" + uploader: "1" flow_id: "61" function: area_under_roc_curve upload_time: 2014-04-06 23:30:40 @@ -2642,6 +2643,7 @@ paths: array_data: '[0,0.99113,0.898048,0.874862,0.791282,0.807343,0.820674]' - run_id: "1" task_id: "68" + uploader: "1" flow_id: "61" function: f_measure upload_time: 2014-04-06 23:30:40 @@ -2649,6 +2651,7 @@ paths: array_data: '[0,0,0.711934,0.735714,0.601363,0.435678,0.430913]' - run_id: "1" task_id: "68" + uploader: "1" flow_id: "61" function: predictive_accuracy upload_time: 2014-04-06 23:30:40 @@ -2914,15 +2917,15 @@ paths: parameters: - name: id in: path - description: Id of the study. + description: Id of the study. Supplied in the URL path. required: true type: number format: integer - - name: description + - name: ids in: formData - description: An XML file describing the entities to be attached. Also see the [XSD schema](https://www.openml.org/api/v1/xsd/openml.study.attach) and an [XML example](https://www.openml.org/api/v1/xml_example/attach). + description: Comma-separated list of entity IDs to be attached to the study. For instance, if this is a run study, the list of run IDs that need to be added (attached) to the study. Must be supplied as a POST variable. required: true - type: file + type: string - name: api_key in: query description: Api key to authenticate the user @@ -2971,11 +2974,11 @@ paths: required: true type: number format: integer - - name: description + - name: ids in: formData - description: An XML file describing the entities to be detached. Also see the [XSD schema](https://www.openml.org/api/v1/xsd/openml.study.detach) and an [XML example](https://www.openml.org/api/v1/xml_example/detach). + description: Comma-separated list of entity IDs to be detached from the study. For instance, if this is a run study, the list of run IDs that need to be removed (detached) from the study. Must be supplied as a POST variable. required: true - type: file + type: string - name: api_key in: query description: Api key to authenticate the user @@ -3052,6 +3055,38 @@ paths: 500 - No model performance estimation procedures available. schema: $ref: '#/definitions/Error' + /user/list: + get: + tags: + - user + summary: List all users by user id + description: | + Returns an array with all user ids and names. + parameters: + - name: api_key + in: query + description: API key to authenticate the user + required: false + type: string + responses: + 200: + description: A list of users + examples: + application/json: |- + { + "users":{ + "user":[ + { + "id":"1", + "username":"janvanrijn@gmail.com"}, + { + "id":"2", + "username":"joaquin.vanschoren@gmail.com"} + ] + } + } + schema: + $ref: '#/definitions/UserList' /evaluationmeasure/list: get: tags: @@ -3095,6 +3130,11 @@ definitions: properties: flows: $ref: '#/definitions/FlowList_flows' + UserList: + type: object + properties: + users: + $ref: '#/definitions/UserList_users' Task: type: object properties: @@ -3563,6 +3603,20 @@ definitions: type: array items: $ref: '#/definitions/FlowList_flows_flow' + UserList_users_user: + properties: + id: + type: string + description: The user ID + username: + type: string + description: The full user name + UserList_users: + properties: + user: + type: array + items: + $ref: '#/definitions/UserList_users_user' Task_task_description_data_set: properties: data_set_id: diff --git a/openml_OS/helpers/api_helper.php b/openml_OS/helpers/api_helper.php index 4c9774d0b..f3e194580 100644 --- a/openml_OS/helpers/api_helper.php +++ b/openml_OS/helpers/api_helper.php @@ -10,7 +10,6 @@ function validateXml( $xmlDocument, $xsdDocument, &$xmlErrors, $from_file = true else $xml->loadXML( $xmlDocument ); - $cxmlErrors = ''; foreach (libxml_get_errors() as $error) { $xmlErrors .= $error->message . '. '; } @@ -19,6 +18,9 @@ function validateXml( $xmlDocument, $xsdDocument, &$xmlErrors, $from_file = true return true; } else { $xmlErrors .= 'XML does not correspond to XSD schema. '; + foreach (libxml_get_errors() as $error) { + $xmlErrors .= 'Error ' . $error->message . ' on line ' . $error->line . ' column ' . $error->column . '. '; + } return false; } } diff --git a/openml_OS/models/api/v1/Api_evaluation.php b/openml_OS/models/api/v1/Api_evaluation.php index 736b3079a..26733307d 100644 --- a/openml_OS/models/api/v1/Api_evaluation.php +++ b/openml_OS/models/api/v1/Api_evaluation.php @@ -207,7 +207,7 @@ private function evaluation_list($segs, $user_id) { // TODO: remove dependency on task_inputs and dataset table // TODO (2): transform into subquery where all columns except evaluation_fold are obtained in subquery (along with limit requirements, as MYSQL query optimizer does not seem to understand this query has an upper limit to the number of obtained runs that need to be inspected) $sql = - 'SELECT r.rid, r.task_id, r.start_time, s.implementation_id, s.sid, f.name AS `function`, i.fullName, d.did, d.name, e.evaluation_engine_id, ' . $columns . ' ' . + 'SELECT r.rid, r.task_id, r.start_time, r.uploader, s.implementation_id, s.sid, f.name AS `function`, i.fullName, d.did, d.name, e.evaluation_engine_id, ' . $columns . ' ' . 'FROM run r, ' . $eval_table . ' e, algorithm_setup s, implementation i, dataset d, task t, task_inputs ti, math_function f ' . 'WHERE r.setup = s.sid ' . 'AND e.source = r.rid ' . diff --git a/openml_OS/models/api/v1/Api_study.php b/openml_OS/models/api/v1/Api_study.php index 40d6b49d1..8bb45dfb6 100644 --- a/openml_OS/models/api/v1/Api_study.php +++ b/openml_OS/models/api/v1/Api_study.php @@ -143,6 +143,11 @@ private function study_create() { ); $study_id = $this->Study->insert($schedule_data); + if (!$study_id) { + $this->db->trans_rollback(); + $this->returnError(1039, $this->version, $this->openmlGeneralErrorCode, 'Problem creating study record. Please check whether the alias is unique. '); + return; + } $res = $this->_link_entities($study_id, $this->user_id, $link_entities); @@ -519,7 +524,10 @@ private function _link_entities($study_id, $uploader_id, $link_entities) { 'uploader' => $uploader_id, 'date' => now(), ); - $this->{$model}->insert($data); + $result = $this->{$model}->insert($data); + if (!$result) { + return false; + } } return true; } diff --git a/openml_OS/models/api/v1/Api_user.php b/openml_OS/models/api/v1/Api_user.php index 076963688..14a988483 100644 --- a/openml_OS/models/api/v1/Api_user.php +++ b/openml_OS/models/api/v1/Api_user.php @@ -15,6 +15,13 @@ function __construct() { function bootstrap($format, $segments, $request_type, $user_id) { $this->outputFormat = $format; + + # http://test.openml.org/api/v1/user/list/uploader/1,2 + if (count($segments) >= 1 && $segments[0] == 'list') { + array_shift($segments); + $this->username_list($segments); + return; + } /*$getpost = array('get','post'); @@ -74,5 +81,25 @@ function bootstrap($format, $segments, $request_type, $user_id) { $this->_xmlContents( 'user-delete', array( 'user' => $user ) ); } */ + + private function username_list($segs) { + # pass uploader list to get username list + $legal_filters = array('user_id'); + $query_string = array(); + for ($i = 0; $i < count($segs); $i += 2) { + $query_string[$segs[$i]] = urldecode($segs[$i+1]); + if (in_array($segs[$i], $legal_filters) == false) { + $this->returnError(370, $this->version, $this->openmlGeneralErrorCode, 'Legal filter operators: ' . implode(',', $legal_filters) .'. Found illegal filter: ' . $segs[$i]); + return; + } + } + $user_id = element('user_id', $query_string); + $users = $this->Author->getWhere('`id` IN (' . $user_id . ')'); + $this->xmlContents('user-name', $this->version, array('users' => $users)); + } + } + + + ?> diff --git a/openml_OS/views/pages/api_new/v1/xml/evaluations.tpl.php b/openml_OS/views/pages/api_new/v1/xml/evaluations.tpl.php index dcc5bf231..d11116b28 100644 --- a/openml_OS/views/pages/api_new/v1/xml/evaluations.tpl.php +++ b/openml_OS/views/pages/api_new/v1/xml/evaluations.tpl.php @@ -2,6 +2,7 @@ rid; ?> + uploader; ?> task_id; ?> sid; ?> implementation_id; ?> diff --git a/openml_OS/views/pages/api_new/v1/xml/user-name.tpl.php b/openml_OS/views/pages/api_new/v1/xml/user-name.tpl.php new file mode 100644 index 000000000..e4abfd777 --- /dev/null +++ b/openml_OS/views/pages/api_new/v1/xml/user-name.tpl.php @@ -0,0 +1,8 @@ + + + + id ?> + username ?> + + + diff --git a/openml_OS/views/rdf_main.php b/openml_OS/views/rdf_main.php index a5b86cede..26ca72f3a 100644 --- a/openml_OS/views/rdf_main.php +++ b/openml_OS/views/rdf_main.php @@ -20,5 +20,9 @@ $getParams['id'] = $info[array_search('t',$info)+1]; } $command = 'cd ' . $rdfize_path . '&& ./rdfize.sh ' . $getParams['type'] . ' ' . $getParams['id']; + + $filename = 'OpenML_' . $getParams['type'] . '_' . $getParams['id'] . '.rdf'; + header('Content-Disposition: attachment; filename="'.$filename.'"'); + echo shell_exec($command); ?> From d34725761f25e625035a8ac4527910bf0d3ade60 Mon Sep 17 00:00:00 2001 From: Joaquin Vanschoren Date: Wed, 4 Dec 2019 23:49:24 +0100 Subject: [PATCH 2/2] added checksum --- openml_OS/views/pages/api_new/v1/json/data.tpl.php | 1 + 1 file changed, 1 insertion(+) diff --git a/openml_OS/views/pages/api_new/v1/json/data.tpl.php b/openml_OS/views/pages/api_new/v1/json/data.tpl.php index 762eb41cd..b7ba61317 100644 --- a/openml_OS/views/pages/api_new/v1/json/data.tpl.php +++ b/openml_OS/views/pages/api_new/v1/json/data.tpl.php @@ -8,6 +8,7 @@ "version":version; ?>, "status":"status; ?>", "format":"format; ?>", + "md5_checksum":"md5_checksum; ?>", file_id != null): /* optional field! */?> "file_id": file_id; ?>,