)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":23851,"name":"Riccardo Pittau","email":"elfosardo@gmail.com","username":"elfosardo"},"change_message_id":"71c5cef9074f758832e21176b998ace6cc4b0c43","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Add support for replacing WSME"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Story: 1651346"},{"line_number":10,"context_line":"Task: 10551"},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"This patch add string check function by json schema. So WSME string type"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"7faddb67_8920929d","line":9,"updated":"2019-08-12 09:15:28.000000000","message":"please put commit message first and Story/Task references after, thanks","commit_id":"d5600ad1199eb170a8366f3b631bde60c736ded5"},{"author":{"_account_id":29792,"name":"Jerry Wang","email":"jerry.a.wang@intel.com","username":"junyiwan-gtc"},"change_message_id":"1b0ed2b2a992ce1d9b3f2fffb7a7a165902df17d","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Add support for replacing WSME"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Story: 1651346"},{"line_number":10,"context_line":"Task: 10551"},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"This patch add string check function by json schema. So WSME string type"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"7faddb67_35bbdee5","line":9,"in_reply_to":"7faddb67_8920929d","updated":"2019-08-13 07:39:08.000000000","message":"Will do. Thanks for comment","commit_id":"d5600ad1199eb170a8366f3b631bde60c736ded5"},{"author":{"_account_id":11655,"name":"Julia Kreger","email":"juliaashleykreger@gmail.com","username":"jkreger","status":"Flying to the moon with a Jetpack!"},"change_message_id":"6d477da110b960b4036e7d86d5c9352e25f591da","unresolved":false,"context_lines":[{"line_number":4,"context_line":"Commit:     Wang, Jerry A \u003cjerry.a.wang@intel.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2019-09-06 10:15:47 +0800"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Add support for replacing WSME"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This patch add uuid type check funcation by json schema. So WSME"},{"line_number":10,"context_line":"wsexpose() of validate() could be replaced by this patch. The patch now"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":3,"id":"3fa7e38b_96ebb8da","line":7,"updated":"2019-10-07 22:37:38.000000000","message":"This seems like a first step. The description below provides some greater clarity though. For what it is worth, I suspect we may want to suggest that this is a first step. What I think we\u0027re missing is the \"map\" or \"plan\" to reach the end goal of replacing WSME.","commit_id":"245d9b2572eac55148265867937e165add4e514c"},{"author":{"_account_id":29792,"name":"Jerry Wang","email":"jerry.a.wang@intel.com","username":"junyiwan-gtc"},"change_message_id":"b630305a2d9a515529c7fbb32ec8bd54c3c4b8ff","unresolved":false,"context_lines":[{"line_number":4,"context_line":"Commit:     Wang, Jerry A \u003cjerry.a.wang@intel.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2019-09-06 10:15:47 +0800"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Add support for replacing WSME"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This patch add uuid type check funcation by json schema. So WSME"},{"line_number":10,"context_line":"wsexpose() of validate() could be replaced by this patch. The patch now"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":3,"id":"3fa7e38b_3f45e243","line":7,"in_reply_to":"3fa7e38b_8ae4ebad","updated":"2019-10-09 01:43:51.000000000","message":"Some more comments:\nFor above 2, after recheck those code, found it was also for parameters checking, ironic used some class derived from WSME\u0027s data types, for example, class derived from class \"APIbase\". I have no idea for replacing these code yet, need more investigating and efforts, not small effort as I mentioned above.\n\nOne more thing:\nI did not plan to write all these code by myself, I am open to welcom others to do these things together. After this patch was merged, I might go out of WSME things and to do other task. My thought might not be mature, hope somebody could raise better ideas to discuss.","commit_id":"245d9b2572eac55148265867937e165add4e514c"},{"author":{"_account_id":29792,"name":"Jerry Wang","email":"jerry.a.wang@intel.com","username":"junyiwan-gtc"},"change_message_id":"7f26579ec5fe0cd56d30db1cd1912286bb133e71","unresolved":false,"context_lines":[{"line_number":4,"context_line":"Commit:     Wang, Jerry A \u003cjerry.a.wang@intel.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2019-09-06 10:15:47 +0800"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Add support for replacing WSME"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"This patch add uuid type check funcation by json schema. So WSME"},{"line_number":10,"context_line":"wsexpose() of validate() could be replaced by this patch. The patch now"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":3,"id":"3fa7e38b_8ae4ebad","line":7,"in_reply_to":"3fa7e38b_96ebb8da","updated":"2019-10-08 09:39:34.000000000","message":"Hi, Julia:\nThanks for the comment! As I understood, ironic used WSME for three: the first and most cases were parameters checking, ironic used data types derived from WSME at API to reach the purpose. the second was function library, this is to do, but not too much effort, just replace some function of WSME with other way would be fine.  My patch already showed how to do parameters checking by json schema, we could use this way at all APIs. \n\nBut there was one big problem at the third one, function expose. Ironic still used WSME decorator to expose API, but this expose function depends on web framework used. it should be the responsibility of flask owner to replace pecan as I understand now.\n\nSo my plan was:\n1. Add json schema function at all places where WSME checked API parameters such as uuid or string.\n2. Replace all WSME library function  by other function or other library. For example, some code use WSME\u0027s date time library function to get date or time.\n3. After flask replaced pecan, remove all WSME parameter checking code and add the json schema decorator to the right place of API at new framework.","commit_id":"245d9b2572eac55148265867937e165add4e514c"}],"ironic/api/controllers/v1/node.py":[{"author":{"_account_id":10206,"name":"Madhuri Kumari","email":"madhuri.kumari@intel.com","username":"Madhuri"},"change_message_id":"cee33d7fd5dbea1b4536dfd1351613f7c507c9bb","unresolved":false,"context_lines":[{"line_number":83,"context_line":"    }"},{"line_number":84,"context_line":"}"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"_STRING_SCHEMA \u003d {"},{"line_number":87,"context_line":"    \"type\": \"string\","},{"line_number":88,"context_line":"    \"minLength\": 1,"},{"line_number":89,"context_line":"    \"maxLength\": 65536"},{"line_number":90,"context_line":"}"},{"line_number":91,"context_line":""},{"line_number":92,"context_line":""},{"line_number":93,"context_line":"METRICS \u003d metrics_utils.get_metrics_logger(__name__)"}],"source_content_type":"text/x-python","patch_set":1,"id":"7faddb67_a96eaefd","line":90,"range":{"start_line":86,"start_character":0,"end_line":90,"end_character":1},"updated":"2019-08-12 10:18:43.000000000","message":"This schema can be put in a common file so that can be used across the project.","commit_id":"d5600ad1199eb170a8366f3b631bde60c736ded5"},{"author":{"_account_id":29792,"name":"Jerry Wang","email":"jerry.a.wang@intel.com","username":"junyiwan-gtc"},"change_message_id":"1b0ed2b2a992ce1d9b3f2fffb7a7a165902df17d","unresolved":false,"context_lines":[{"line_number":83,"context_line":"    }"},{"line_number":84,"context_line":"}"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"_STRING_SCHEMA \u003d {"},{"line_number":87,"context_line":"    \"type\": \"string\","},{"line_number":88,"context_line":"    \"minLength\": 1,"},{"line_number":89,"context_line":"    \"maxLength\": 65536"},{"line_number":90,"context_line":"}"},{"line_number":91,"context_line":""},{"line_number":92,"context_line":""},{"line_number":93,"context_line":"METRICS \u003d metrics_utils.get_metrics_logger(__name__)"}],"source_content_type":"text/x-python","patch_set":1,"id":"7faddb67_b5ceee80","line":90,"range":{"start_line":86,"start_character":0,"end_line":90,"end_character":1},"in_reply_to":"7faddb67_a96eaefd","updated":"2019-08-13 07:39:08.000000000","message":"Will do. Thanks","commit_id":"d5600ad1199eb170a8366f3b631bde60c736ded5"},{"author":{"_account_id":23851,"name":"Riccardo Pittau","email":"elfosardo@gmail.com","username":"elfosardo"},"change_message_id":"71c5cef9074f758832e21176b998ace6cc4b0c43","unresolved":false,"context_lines":[{"line_number":1986,"context_line":"        rpc_node \u003d api_utils.get_rpc_node(node_uuid or node)"},{"line_number":1987,"context_line":""},{"line_number":1988,"context_line":"        topic \u003d api.request.rpcapi.get_topic_for(rpc_node)"},{"line_number":1989,"context_line":"        "},{"line_number":1990,"context_line":"        interfaces \u003d api.request.rpcapi.validate_driver_interfaces("},{"line_number":1991,"context_line":"                            api.request.context, rpc_node.uuid, topic)"},{"line_number":1992,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"7faddb67_4e07001f","line":1989,"updated":"2019-08-12 09:15:28.000000000","message":"remove blank spaces","commit_id":"d5600ad1199eb170a8366f3b631bde60c736ded5"},{"author":{"_account_id":29792,"name":"Jerry Wang","email":"jerry.a.wang@intel.com","username":"junyiwan-gtc"},"change_message_id":"1b0ed2b2a992ce1d9b3f2fffb7a7a165902df17d","unresolved":false,"context_lines":[{"line_number":1986,"context_line":"        rpc_node \u003d api_utils.get_rpc_node(node_uuid or node)"},{"line_number":1987,"context_line":""},{"line_number":1988,"context_line":"        topic \u003d api.request.rpcapi.get_topic_for(rpc_node)"},{"line_number":1989,"context_line":"        "},{"line_number":1990,"context_line":"        interfaces \u003d api.request.rpcapi.validate_driver_interfaces("},{"line_number":1991,"context_line":"                            api.request.context, rpc_node.uuid, topic)"},{"line_number":1992,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"7faddb67_75c87673","line":1989,"in_reply_to":"7faddb67_4e07001f","updated":"2019-08-13 07:39:08.000000000","message":"Will do. Thanks. \nBTW, would PEP8 or docs test check this also?","commit_id":"d5600ad1199eb170a8366f3b631bde60c736ded5"},{"author":{"_account_id":11655,"name":"Julia Kreger","email":"juliaashleykreger@gmail.com","username":"jkreger","status":"Flying to the moon with a Jetpack!"},"change_message_id":"6a14e0eb57ae6b1ff653c1bfac4088a5a3583324","unresolved":false,"context_lines":[{"line_number":1986,"context_line":"        rpc_node \u003d api_utils.get_rpc_node(node_uuid or node)"},{"line_number":1987,"context_line":""},{"line_number":1988,"context_line":"        topic \u003d api.request.rpcapi.get_topic_for(rpc_node)"},{"line_number":1989,"context_line":"        "},{"line_number":1990,"context_line":"        interfaces \u003d api.request.rpcapi.validate_driver_interfaces("},{"line_number":1991,"context_line":"                            api.request.context, rpc_node.uuid, topic)"},{"line_number":1992,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"7faddb67_99973991","line":1989,"in_reply_to":"7faddb67_75c87673","updated":"2019-08-15 17:22:30.000000000","message":"tox -epep8 locally should error on this.","commit_id":"d5600ad1199eb170a8366f3b631bde60c736ded5"},{"author":{"_account_id":23851,"name":"Riccardo Pittau","email":"elfosardo@gmail.com","username":"elfosardo"},"change_message_id":"71c5cef9074f758832e21176b998ace6cc4b0c43","unresolved":false,"context_lines":[{"line_number":1991,"context_line":"                            api.request.context, rpc_node.uuid, topic)"},{"line_number":1992,"context_line":""},{"line_number":1993,"context_line":"        _check_string(interfaces)"},{"line_number":1994,"context_line":"                 "},{"line_number":1995,"context_line":"        return interfaces"},{"line_number":1996,"context_line":""},{"line_number":1997,"context_line":"    @METRICS.timer(\u0027NodesController.get_one\u0027)"}],"source_content_type":"text/x-python","patch_set":1,"id":"7faddb67_0e010807","line":1994,"updated":"2019-08-12 09:15:28.000000000","message":"ditto","commit_id":"d5600ad1199eb170a8366f3b631bde60c736ded5"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"3ba1766b3170570e2edc425402551918e3077902","unresolved":false,"context_lines":[{"line_number":1977,"context_line":"        interfaces \u003d api.request.rpcapi.validate_driver_interfaces("},{"line_number":1978,"context_line":"            api.request.context, rpc_node.uuid, topic)"},{"line_number":1979,"context_line":""},{"line_number":1980,"context_line":"        schema._check_dict(interfaces)"},{"line_number":1981,"context_line":""},{"line_number":1982,"context_line":"        return interfaces"},{"line_number":1983,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"7faddb67_a9b11947","line":1980,"updated":"2019-08-22 10:01:49.000000000","message":"we don\u0027t really need validation for output data, we know it\u0027s valid..","commit_id":"91591db46e55d5b02d0f9072139c32db51fa5108"},{"author":{"_account_id":29792,"name":"Jerry Wang","email":"jerry.a.wang@intel.com","username":"junyiwan-gtc"},"change_message_id":"0d1ba02bf7254301c72b82d23d28c619f106d68b","unresolved":false,"context_lines":[{"line_number":1977,"context_line":"        interfaces \u003d api.request.rpcapi.validate_driver_interfaces("},{"line_number":1978,"context_line":"            api.request.context, rpc_node.uuid, topic)"},{"line_number":1979,"context_line":""},{"line_number":1980,"context_line":"        schema._check_dict(interfaces)"},{"line_number":1981,"context_line":""},{"line_number":1982,"context_line":"        return interfaces"},{"line_number":1983,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"7faddb67_e3dddadd","line":1980,"in_reply_to":"7faddb67_a9b11947","updated":"2019-08-23 06:37:42.000000000","message":"Thanks for comment! I agree with you. I added it here because wsme.wsexpose() verified return value by a decorator. At here, it was dict inside function and string/text outside the function. After I found suitable way, would move it outside the function like wsme did.\n\nBTW, one more thing, besides check data types by json schema, wsme still did a \"expose\" function, for example, when I remove wsme.wsexpose decorator, \"openstack baremetal node validate\" command reported error something like \"validate\" was not defined, it looks we need to implement this \"expose\" function, this may depend the web framework implementation, as we knew, flask would replace pecan, but i am not quite clear about how flask implment \"expose\" function, did you have comment for this? And I saw you developed a preparation patch for this, when did you plan to submit the flask framework patch which would replace pecan?","commit_id":"91591db46e55d5b02d0f9072139c32db51fa5108"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"9f9dbce74a3fe1e86fa48adc14750641554bb130","unresolved":false,"context_lines":[{"line_number":1977,"context_line":"        interfaces \u003d api.request.rpcapi.validate_driver_interfaces("},{"line_number":1978,"context_line":"            api.request.context, rpc_node.uuid, topic)"},{"line_number":1979,"context_line":""},{"line_number":1980,"context_line":"        schema._check_dict(interfaces)"},{"line_number":1981,"context_line":""},{"line_number":1982,"context_line":"        return interfaces"},{"line_number":1983,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"7faddb67_f44b4fae","line":1980,"in_reply_to":"7faddb67_e3dddadd","updated":"2019-08-23 12:54:14.000000000","message":"I don\u0027t have any immediate plans for that. As to expose replacement, flask has routes instead, please check its docs.","commit_id":"91591db46e55d5b02d0f9072139c32db51fa5108"},{"author":{"_account_id":29792,"name":"Jerry Wang","email":"jerry.a.wang@intel.com","username":"junyiwan-gtc"},"change_message_id":"0700a62ff5264397e6971fc6486619d7ec202acd","unresolved":false,"context_lines":[{"line_number":1977,"context_line":"        interfaces \u003d api.request.rpcapi.validate_driver_interfaces("},{"line_number":1978,"context_line":"            api.request.context, rpc_node.uuid, topic)"},{"line_number":1979,"context_line":""},{"line_number":1980,"context_line":"        schema._check_dict(interfaces)"},{"line_number":1981,"context_line":""},{"line_number":1982,"context_line":"        return interfaces"},{"line_number":1983,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"7faddb67_e1e056fb","line":1980,"in_reply_to":"7faddb67_f44b4fae","updated":"2019-08-26 08:53:45.000000000","message":"Thanks for your information.","commit_id":"91591db46e55d5b02d0f9072139c32db51fa5108"},{"author":{"_account_id":11655,"name":"Julia Kreger","email":"juliaashleykreger@gmail.com","username":"jkreger","status":"Flying to the moon with a Jetpack!"},"change_message_id":"6d477da110b960b4036e7d86d5c9352e25f591da","unresolved":false,"context_lines":[{"line_number":1950,"context_line":""},{"line_number":1951,"context_line":"    @schema.check_uuid"},{"line_number":1952,"context_line":"    @METRICS.timer(\u0027NodesController.validate\u0027)"},{"line_number":1953,"context_line":"    @expose.expose(wtypes.text, types.uuid_or_name, types.uuid)"},{"line_number":1954,"context_line":"    def validate(self, node\u003dNone, node_uuid\u003dNone):"},{"line_number":1955,"context_line":"        \"\"\"Validate the driver interfaces, using the node\u0027s UUID or name."},{"line_number":1956,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"3fa7e38b_d68ff02b","line":1953,"updated":"2019-10-07 22:37:38.000000000","message":"So effectively, this decorator... as I understand it, would go away as well?","commit_id":"245d9b2572eac55148265867937e165add4e514c"},{"author":{"_account_id":29792,"name":"Jerry Wang","email":"jerry.a.wang@intel.com","username":"junyiwan-gtc"},"change_message_id":"7f26579ec5fe0cd56d30db1cd1912286bb133e71","unresolved":false,"context_lines":[{"line_number":1950,"context_line":""},{"line_number":1951,"context_line":"    @schema.check_uuid"},{"line_number":1952,"context_line":"    @METRICS.timer(\u0027NodesController.validate\u0027)"},{"line_number":1953,"context_line":"    @expose.expose(wtypes.text, types.uuid_or_name, types.uuid)"},{"line_number":1954,"context_line":"    def validate(self, node\u003dNone, node_uuid\u003dNone):"},{"line_number":1955,"context_line":"        \"\"\"Validate the driver interfaces, using the node\u0027s UUID or name."},{"line_number":1956,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"3fa7e38b_d727e763","line":1953,"in_reply_to":"3fa7e38b_d68ff02b","updated":"2019-10-08 09:39:34.000000000","message":"I am not sure yet. I hope it would be still used in future when pecan is replaced by flask. In worst case, if we can not use this decorator, its internal function should still could be easily used at flask web framework because it was independent.","commit_id":"245d9b2572eac55148265867937e165add4e514c"},{"author":{"_account_id":4571,"name":"Steve Baker","email":"sbaker@redhat.com","username":"steve-stevebaker"},"change_message_id":"23785c9054afb590358bb16034aa985598c05fb0","unresolved":false,"context_lines":[{"line_number":44,"context_line":"from ironic.common.i18n import _"},{"line_number":45,"context_line":"from ironic.common import policy"},{"line_number":46,"context_line":"from ironic.common import schema"},{"line_number":47,"context_line":"from ironic.common.schema import Args_uuid_or_name_type"},{"line_number":48,"context_line":"from ironic.common.schema import Args_uuid_type"},{"line_number":49,"context_line":"from ironic.common import states as ir_states"},{"line_number":50,"context_line":"from ironic.conductor import steps as conductor_steps"},{"line_number":51,"context_line":"import ironic.conf"}],"source_content_type":"text/x-python","patch_set":12,"id":"3fa7e38b_f155f252","line":48,"range":{"start_line":47,"start_character":0,"end_line":48,"end_character":47},"updated":"2020-01-07 22:46:53.000000000","message":"can the validators just be used via the schema import rather than needing to import each one?","commit_id":"9d55acd749fd9d109f75cfc465a022fb2666de2e"},{"author":{"_account_id":29792,"name":"Jerry Wang","email":"jerry.a.wang@intel.com","username":"junyiwan-gtc"},"change_message_id":"e369b62321ee18af4d678ac9cd27a337032d4919","unresolved":false,"context_lines":[{"line_number":44,"context_line":"from ironic.common.i18n import _"},{"line_number":45,"context_line":"from ironic.common import policy"},{"line_number":46,"context_line":"from ironic.common import schema"},{"line_number":47,"context_line":"from ironic.common.schema import Args_uuid_or_name_type"},{"line_number":48,"context_line":"from ironic.common.schema import Args_uuid_type"},{"line_number":49,"context_line":"from ironic.common import states as ir_states"},{"line_number":50,"context_line":"from ironic.conductor import steps as conductor_steps"},{"line_number":51,"context_line":"import ironic.conf"}],"source_content_type":"text/x-python","patch_set":12,"id":"3fa7e38b_7901e806","line":48,"range":{"start_line":47,"start_character":0,"end_line":48,"end_character":47},"in_reply_to":"3fa7e38b_f155f252","updated":"2020-01-08 06:29:40.000000000","message":"Hi, Steve:\nGood catch! Would fix.\nThanks\n-Jerry","commit_id":"9d55acd749fd9d109f75cfc465a022fb2666de2e"}],"ironic/common/schema.py":[{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"3ba1766b3170570e2edc425402551918e3077902","unresolved":false,"context_lines":[{"line_number":37,"context_line":"        jsonschema.validate(string, _STRING_SCHEMA)"},{"line_number":38,"context_line":"    except jsonschema.ValidationError as exc:"},{"line_number":39,"context_line":"        raise exception.InvalidParameterValue(_(\u0027Invalid string: %s\u0027) %"},{"line_number":40,"context_line":"                                              exc)"},{"line_number":41,"context_line":""},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"def _check_dict(dict):"}],"source_content_type":"text/x-python","patch_set":2,"id":"7faddb67_4980a54a","line":40,"updated":"2019-08-22 10:01:49.000000000","message":"This will probably result in a lot of repetetive code soon. What if we create a smart object that contains a schema and error handling in it? Like an abstract class\n\n class Type(object):\n     SCHEMA \u003d None\n     def __call__(self, value):\n         try:\n             jsonscheme.validate(value, self.SCHEMA)\n         except ....\n\n class String(Type):\n     SCHEMA \u003d { ... }\n     \nActually, there seems to be at least these libraries: https://github.com/cwacek/python-jsonschema-objects, https://jsonmodels.readthedocs.io/en/latest/usage.html and https://pypi.org/project/warlock/. The last two are in global-requirements, have you considered using them?","commit_id":"91591db46e55d5b02d0f9072139c32db51fa5108"},{"author":{"_account_id":29792,"name":"Jerry Wang","email":"jerry.a.wang@intel.com","username":"junyiwan-gtc"},"change_message_id":"0700a62ff5264397e6971fc6486619d7ec202acd","unresolved":false,"context_lines":[{"line_number":37,"context_line":"        jsonschema.validate(string, _STRING_SCHEMA)"},{"line_number":38,"context_line":"    except jsonschema.ValidationError as exc:"},{"line_number":39,"context_line":"        raise exception.InvalidParameterValue(_(\u0027Invalid string: %s\u0027) %"},{"line_number":40,"context_line":"                                              exc)"},{"line_number":41,"context_line":""},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"def _check_dict(dict):"}],"source_content_type":"text/x-python","patch_set":2,"id":"7faddb67_010c92ea","line":40,"in_reply_to":"7faddb67_14494bb6","updated":"2019-08-26 08:53:45.000000000","message":"Hi Dmitry, thanks for your profound comment! I thought it over again and would give up check return value first(those dict or string schema), in future, with flask, the validate api should be something like:\n@app.route(path)\ndef validate(input1, input2, ...), \nso I thought just check input1, input2 ... by schema would be fine. I have no idea where to check return value in this case.\nSo next step, I would submit code to check input parameters, but currently, these input parameters were classes which contain some types defined from WSME, so the schema would be changed after flask were imported. After flask, we can discuss these schema again. This change would focus on import jsonschema only or no way to submit code.\n\nBTW， I found many duplicate code at types.py like UuidType, NameType, UuidOrNameType..., they should be re-written by abstract class also. If have time, i would re-write them at another patch.\n\nFor abstract class idea, my understanding was like below, I did a little change at your idea, i did not use __call__ but put jsonschema check at __init__, that would make the call be more simple:\nIn [59]: class Type(object):\n    ...:      SCHEMA \u003d None\n    ...:      def __init__(self, value):\n    ...:          print(\u0027ok\\n\u0027)\n    ...:          try:\n    ...:              jsonschema.validate(value, self.SCHEMA)\n    ...:          except jsonschema.ValidationError as exc:\n    ...:              raise exception.InvalidParameterValue(_(\u0027Invalid data type: %s\u0027) %\n    ...:                                               exc)\n    ...:\n    ...:\n    ...: class String(Type):\n    ...:      SCHEMA \u003d {\n    ...:         \"type\": \"string\",\n    ...:         \"minLength\": 1,\n    ...:         \"maxLength\": 65536\n    ...:      }\n    ...:\nIn [61]: String(txt)\nok","commit_id":"91591db46e55d5b02d0f9072139c32db51fa5108"},{"author":{"_account_id":29792,"name":"Jerry Wang","email":"jerry.a.wang@intel.com","username":"junyiwan-gtc"},"change_message_id":"0d1ba02bf7254301c72b82d23d28c619f106d68b","unresolved":false,"context_lines":[{"line_number":37,"context_line":"        jsonschema.validate(string, _STRING_SCHEMA)"},{"line_number":38,"context_line":"    except jsonschema.ValidationError as exc:"},{"line_number":39,"context_line":"        raise exception.InvalidParameterValue(_(\u0027Invalid string: %s\u0027) %"},{"line_number":40,"context_line":"                                              exc)"},{"line_number":41,"context_line":""},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"def _check_dict(dict):"}],"source_content_type":"text/x-python","patch_set":2,"id":"7faddb67_63b9ea77","line":40,"in_reply_to":"7faddb67_4980a54a","updated":"2019-08-23 06:37:42.000000000","message":"The abstract class was very good idea, will do, thanks for the comment.\nFor those schema weblinks, I planned to replace WSME at \"openstack baremetal node validate\" function first, I remembered in related code WSME verified some user defined data type also, very likely would use the weblinks you provided later. Maybe I would use several patches to do this to make the effort more easy to control and lower the risk. Basically below was my current plan: 1, add schema for return value 2. add input parameters check, 3. add expose function, may depend on flask implementation, no idea yet currently 4. use flask json schema libary. This was quite similar with current json schema libary as I understand, just change a library. Or we only use flask to replace pecan, not use json schema of flask, if this way, please the effort could be saved.","commit_id":"91591db46e55d5b02d0f9072139c32db51fa5108"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"9f9dbce74a3fe1e86fa48adc14750641554bb130","unresolved":false,"context_lines":[{"line_number":37,"context_line":"        jsonschema.validate(string, _STRING_SCHEMA)"},{"line_number":38,"context_line":"    except jsonschema.ValidationError as exc:"},{"line_number":39,"context_line":"        raise exception.InvalidParameterValue(_(\u0027Invalid string: %s\u0027) %"},{"line_number":40,"context_line":"                                              exc)"},{"line_number":41,"context_line":""},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"def _check_dict(dict):"}],"source_content_type":"text/x-python","patch_set":2,"id":"7faddb67_14494bb6","line":40,"in_reply_to":"7faddb67_63b9ea77","updated":"2019-08-23 12:54:14.000000000","message":"I\u0027m not sure I quite get your response. What I\u0027m trying to say is that you\u0027re duplicating something that has already been implemented in several libraries (and probably used in openstack)","commit_id":"91591db46e55d5b02d0f9072139c32db51fa5108"},{"author":{"_account_id":11655,"name":"Julia Kreger","email":"juliaashleykreger@gmail.com","username":"jkreger","status":"Flying to the moon with a Jetpack!"},"change_message_id":"6d477da110b960b4036e7d86d5c9352e25f591da","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Copyright (c) 2011 OpenStack Foundation"},{"line_number":2,"context_line":"# All Rights Reserved."},{"line_number":3,"context_line":"#"},{"line_number":4,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\"); you may"},{"line_number":5,"context_line":"#    not use this file except in compliance with the License. You may obtain"}],"source_content_type":"text/x-python","patch_set":3,"id":"3fa7e38b_d6f370e6","line":2,"range":{"start_line":1,"start_character":0,"end_line":2,"end_character":22},"updated":"2019-10-07 22:37:38.000000000","message":"These two lines are incorrect. Copyrights should not be posted with prior years unless the code was written in that year. Additionally, rights assignments are part of the agreement the corporations and contributors agree too. That being said, all that should really be here is the license header below.","commit_id":"245d9b2572eac55148265867937e165add4e514c"},{"author":{"_account_id":11655,"name":"Julia Kreger","email":"juliaashleykreger@gmail.com","username":"jkreger","status":"Flying to the moon with a Jetpack!"},"change_message_id":"c43060e49a9c122fcf23024aad7e2156670c4959","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Copyright (c) 2011 OpenStack Foundation"},{"line_number":2,"context_line":"# All Rights Reserved."},{"line_number":3,"context_line":"#"},{"line_number":4,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\"); you may"},{"line_number":5,"context_line":"#    not use this file except in compliance with the License. You may obtain"}],"source_content_type":"text/x-python","patch_set":3,"id":"3fa7e38b_0ece8859","line":2,"range":{"start_line":1,"start_character":0,"end_line":2,"end_character":22},"in_reply_to":"3fa7e38b_7f391a3d","updated":"2019-10-11 14:05:48.000000000","message":"So the foundation does assignments tracking via git blame/history data. So only the license is needed.","commit_id":"245d9b2572eac55148265867937e165add4e514c"},{"author":{"_account_id":29792,"name":"Jerry Wang","email":"jerry.a.wang@intel.com","username":"junyiwan-gtc"},"change_message_id":"5394f5b37b04bebec41be2cc48d37d37069ba011","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Copyright (c) 2011 OpenStack Foundation"},{"line_number":2,"context_line":"# All Rights Reserved."},{"line_number":3,"context_line":"#"},{"line_number":4,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\"); you may"},{"line_number":5,"context_line":"#    not use this file except in compliance with the License. You may obtain"}],"source_content_type":"text/x-python","patch_set":3,"id":"3fa7e38b_7f391a3d","line":2,"range":{"start_line":1,"start_character":0,"end_line":2,"end_character":22},"in_reply_to":"3fa7e38b_97888fc6","updated":"2019-10-09 03:22:02.000000000","message":"Would below one ok which did not have a year? Thanks a lot!\n#    Licensed under the Apache License, Version 2.0 (the \"License\"); you may\n#    not use this file except in compliance with the License. You may obtain\n#    a copy of the License at\n#\n#         http://www.apache.org/licenses/LICENSE-2.0\n#\n#    Unless required by applicable law or agreed to in writing, software\n#    distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT\n#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n#    License for the specific language governing permissions and limitations\n#    under the License.","commit_id":"245d9b2572eac55148265867937e165add4e514c"},{"author":{"_account_id":29792,"name":"Jerry Wang","email":"jerry.a.wang@intel.com","username":"junyiwan-gtc"},"change_message_id":"7f26579ec5fe0cd56d30db1cd1912286bb133e71","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Copyright (c) 2011 OpenStack Foundation"},{"line_number":2,"context_line":"# All Rights Reserved."},{"line_number":3,"context_line":"#"},{"line_number":4,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\"); you may"},{"line_number":5,"context_line":"#    not use this file except in compliance with the License. You may obtain"}],"source_content_type":"text/x-python","patch_set":3,"id":"3fa7e38b_97888fc6","line":2,"range":{"start_line":1,"start_character":0,"end_line":2,"end_character":22},"in_reply_to":"3fa7e38b_d6f370e6","updated":"2019-10-08 09:39:34.000000000","message":"Will fix. Thanks a lot! I copied from other ironic code and passed all tox or pep checking. It seems our test tools could not detect this kind of error also.\n\nSo the year was 2019?\nFor rights assignments, if possible, could you show me a correct example here. Thanks a lot!","commit_id":"245d9b2572eac55148265867937e165add4e514c"},{"author":{"_account_id":11655,"name":"Julia Kreger","email":"juliaashleykreger@gmail.com","username":"jkreger","status":"Flying to the moon with a Jetpack!"},"change_message_id":"6d477da110b960b4036e7d86d5c9352e25f591da","unresolved":false,"context_lines":[{"line_number":50,"context_line":"    }"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"def check_uuid(func):"},{"line_number":54,"context_line":"    @six.wraps(func)"},{"line_number":55,"context_line":"    def inner_check_uuid(*args, **kwargs):"},{"line_number":56,"context_line":"        value \u003d args[1]"}],"source_content_type":"text/x-python","patch_set":3,"id":"3fa7e38b_362e8443","line":53,"updated":"2019-10-07 22:37:38.000000000","message":"Should we have any unit testing of such schema validation methods?","commit_id":"245d9b2572eac55148265867937e165add4e514c"},{"author":{"_account_id":29792,"name":"Jerry Wang","email":"jerry.a.wang@intel.com","username":"junyiwan-gtc"},"change_message_id":"7f26579ec5fe0cd56d30db1cd1912286bb133e71","unresolved":false,"context_lines":[{"line_number":50,"context_line":"    }"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"def check_uuid(func):"},{"line_number":54,"context_line":"    @six.wraps(func)"},{"line_number":55,"context_line":"    def inner_check_uuid(*args, **kwargs):"},{"line_number":56,"context_line":"        value \u003d args[1]"}],"source_content_type":"text/x-python","patch_set":3,"id":"3fa7e38b_97dacfe6","line":53,"in_reply_to":"3fa7e38b_362e8443","updated":"2019-10-08 09:39:34.000000000","message":"Good question! I thought we already had validation methods, in this case, it was :\npython -m unittest  ironic.tests.unit.api.controllers.v1.test_node.TestListNodes.test_validate_by_uuid. I used this one to test my json schema decorator and fixed quite a few issues found by this one.","commit_id":"245d9b2572eac55148265867937e165add4e514c"},{"author":{"_account_id":11655,"name":"Julia Kreger","email":"juliaashleykreger@gmail.com","username":"jkreger","status":"Flying to the moon with a Jetpack!"},"change_message_id":"c43060e49a9c122fcf23024aad7e2156670c4959","unresolved":false,"context_lines":[{"line_number":50,"context_line":"    }"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"def check_uuid(func):"},{"line_number":54,"context_line":"    @six.wraps(func)"},{"line_number":55,"context_line":"    def inner_check_uuid(*args, **kwargs):"},{"line_number":56,"context_line":"        value \u003d args[1]"}],"source_content_type":"text/x-python","patch_set":3,"id":"3fa7e38b_6e061c89","line":53,"in_reply_to":"3fa7e38b_97dacfe6","updated":"2019-10-11 14:05:48.000000000","message":"excellent!","commit_id":"245d9b2572eac55148265867937e165add4e514c"},{"author":{"_account_id":11655,"name":"Julia Kreger","email":"juliaashleykreger@gmail.com","username":"jkreger","status":"Flying to the moon with a Jetpack!"},"change_message_id":"07ba5c0b1a396848e7e544518dc0a2ce6a2a9ae6","unresolved":false,"context_lines":[{"line_number":51,"context_line":"    @six.wraps(func)"},{"line_number":52,"context_line":"    def inner_check_uuid(*args, **kwargs):"},{"line_number":53,"context_line":"        value \u003d args[1]"},{"line_number":54,"context_line":"        if value not in [u\u0027spam\u0027, None]:"},{"line_number":55,"context_line":"            if (uuidutils.is_uuid_like(value)):"},{"line_number":56,"context_line":"                Uuid(value)"},{"line_number":57,"context_line":"            String(value)"}],"source_content_type":"text/x-python","patch_set":4,"id":"3fa7e38b_6e14dca0","line":54,"range":{"start_line":54,"start_character":24,"end_line":54,"end_character":32},"updated":"2019-10-11 14:08:02.000000000","message":"shouldn\u0027t this be flipped and maybe u\u0027\u0027 ?\n\nI guess without some explicit unit testing being added at the same time, it is a little hard to follow why. :)","commit_id":"9c4d2d74724b8e2f443b4b9d6fffaf5819399653"},{"author":{"_account_id":29792,"name":"Jerry Wang","email":"jerry.a.wang@intel.com","username":"junyiwan-gtc"},"change_message_id":"76af125cfc8225d9f1277290616fb3c0e0860435","unresolved":false,"context_lines":[{"line_number":51,"context_line":"    @six.wraps(func)"},{"line_number":52,"context_line":"    def inner_check_uuid(*args, **kwargs):"},{"line_number":53,"context_line":"        value \u003d args[1]"},{"line_number":54,"context_line":"        if value not in [u\u0027spam\u0027, None]:"},{"line_number":55,"context_line":"            if (uuidutils.is_uuid_like(value)):"},{"line_number":56,"context_line":"                Uuid(value)"},{"line_number":57,"context_line":"            String(value)"}],"source_content_type":"text/x-python","patch_set":4,"id":"3fa7e38b_e5ce942b","line":54,"range":{"start_line":54,"start_character":24,"end_line":54,"end_character":32},"in_reply_to":"3fa7e38b_6e14dca0","updated":"2019-10-14 11:14:29.000000000","message":"Thanks for pointing this! I re-run the unit test and found u\u0027spam\u0027 is not required. I forgot that why I added u\u0027spam\u0027 here. I guessed that I modified some code for debug at test_node.py to emulating some special case and forgot to remove those code and caused this. Anyway, I would submit a new patch soon to fix it.","commit_id":"9c4d2d74724b8e2f443b4b9d6fffaf5819399653"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"143cbade7f2a868b467e1a2ea06d925aa158b556","unresolved":false,"context_lines":[{"line_number":56,"context_line":"    }"},{"line_number":57,"context_line":""},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"def check_uuid_or_name(func):"},{"line_number":60,"context_line":"    @six.wraps(func)"},{"line_number":61,"context_line":"    def inner_check_uuid_or_name(*args, **kwargs):"},{"line_number":62,"context_line":"        value \u003d args[1]"}],"source_content_type":"text/x-python","patch_set":10,"id":"3fa7e38b_b9140343","line":59,"updated":"2019-11-26 15:35:52.000000000","message":"I think we will need something more generic here. E.g. how it\u0027s done with wsme now, a decorator that accepts a list of types, then \"zips\" them with function arguments and validates them (@check(NameOrUuid, String)). For this particular case I think a separate NameOrUuid can be introduced that has all the microversion-related logic in the overloaded __init__ method. Maybe the types that are not passed into the decorator call can be skipped for now while it is still in development. But what is written here seems to be flexible enough even for all the microversion conditions we have.","commit_id":"132690145a4e5665e057a4f061e265f674a26d32"},{"author":{"_account_id":29792,"name":"Jerry Wang","email":"jerry.a.wang@intel.com","username":"junyiwan-gtc"},"change_message_id":"da807ba0d1f906fdfbbc7545ba918ea7168473ae","unresolved":false,"context_lines":[{"line_number":56,"context_line":"    }"},{"line_number":57,"context_line":""},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"def check_uuid_or_name(func):"},{"line_number":60,"context_line":"    @six.wraps(func)"},{"line_number":61,"context_line":"    def inner_check_uuid_or_name(*args, **kwargs):"},{"line_number":62,"context_line":"        value \u003d args[1]"}],"source_content_type":"text/x-python","patch_set":10,"id":"3fa7e38b_ef77d5d0","line":59,"in_reply_to":"3fa7e38b_0436dd52","updated":"2019-12-02 01:58:43.000000000","message":"Hi Drok:\nargs[2] would never have value, even you just input uuid only, it passed by args[1]. You could trace \"validate(self, node, node_uuid)\" function to confirm. All values(name or uuid) would only be passed by \"node\", \"node_uuid\" would always be empty. So I only verify \"node\" paramter which were args[1].\nThanks\n-Jerry","commit_id":"132690145a4e5665e057a4f061e265f674a26d32"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"832a6e90977c541cd3c8993d73bf62d805b7862f","unresolved":false,"context_lines":[{"line_number":56,"context_line":"    }"},{"line_number":57,"context_line":""},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"def check_uuid_or_name(func):"},{"line_number":60,"context_line":"    @six.wraps(func)"},{"line_number":61,"context_line":"    def inner_check_uuid_or_name(*args, **kwargs):"},{"line_number":62,"context_line":"        value \u003d args[1]"}],"source_content_type":"text/x-python","patch_set":10,"id":"3fa7e38b_0436dd52","line":59,"in_reply_to":"3fa7e38b_2e18af74","updated":"2019-11-29 17:04:13.000000000","message":"What I mean is that you do not check args[2] here at all. And you can call the function completely avoiding name and only using node_uuid, which might be invalid if we start only using this decorator for checks. Also have you checked that wsme calls validate by positional arguments and not doing for example validate(name\u003d\u0027abc\u0027)? If it could do that, you\u0027d need to check kwargs as well.","commit_id":"132690145a4e5665e057a4f061e265f674a26d32"},{"author":{"_account_id":29792,"name":"Jerry Wang","email":"jerry.a.wang@intel.com","username":"junyiwan-gtc"},"change_message_id":"6388b4c5ac21d03a93abbad4d578af3fc398113c","unresolved":false,"context_lines":[{"line_number":56,"context_line":"    }"},{"line_number":57,"context_line":""},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"def check_uuid_or_name(func):"},{"line_number":60,"context_line":"    @six.wraps(func)"},{"line_number":61,"context_line":"    def inner_check_uuid_or_name(*args, **kwargs):"},{"line_number":62,"context_line":"        value \u003d args[1]"}],"source_content_type":"text/x-python","patch_set":10,"id":"3fa7e38b_2e18af74","line":59,"in_reply_to":"3fa7e38b_b9140343","updated":"2019-11-28 00:30:44.000000000","message":"Hi Drok:\nThanks for very good comments!\nDid you mean the decorates should be like below:\n@check(zip(type1, type2))\nbase_func(...)\n\nIf so, let me explained here: \noriginally, my thoughts was like yours, need to do it like WSME did like below:\n@ws_expose(type1, type2, ...)\nBut after I traced the WSME code, type1 and type2 were data types derived from WSME data types, its purpose was to pass a validate function defined the WSME base class which type1 and type2 derived from, what the thing that validate function to do was to check uuid or name. Now WSME would be removed, so type1 and type2 was not required any more, let\u0027s just do the most important things (\"UUid or name\" check) were enough.\nSo my solution was like below:\n@check_uuid_or_name, \nbase_func(uuid, name, ...)\n\n\nno extra parameters needed because I did not use complex validating logic like WSME did, I just verify the UUID and Name directly, and UUID or name already contained at the base_function my decorator decorated.\n\n\nThanks\n-Jerry","commit_id":"132690145a4e5665e057a4f061e265f674a26d32"},{"author":{"_account_id":12356,"name":"Vladyslav Drok","email":"vdrok@mirantis.com","username":"vdrok"},"change_message_id":"f73ff009b36036f4f39467ce092f9a37e11d35c9","unresolved":false,"context_lines":[{"line_number":56,"context_line":"    }"},{"line_number":57,"context_line":""},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"def check_uuid_or_name(func):"},{"line_number":60,"context_line":"    @six.wraps(func)"},{"line_number":61,"context_line":"    def inner_check_uuid_or_name(*args, **kwargs):"},{"line_number":62,"context_line":"        value \u003d args[1]"}],"source_content_type":"text/x-python","patch_set":10,"id":"3fa7e38b_7b21639e","line":59,"in_reply_to":"3fa7e38b_ef77d5d0","updated":"2019-12-02 10:56:08.000000000","message":"It is possible to do the request in the following way - /nodes/validate?node_uuid\u003d*** - https://github.com/openstack/ironic/blob/master/ironic/tests/unit/api/controllers/v1/test_node.py#L2017-L2025, in which case only args[2] will be present","commit_id":"132690145a4e5665e057a4f061e265f674a26d32"},{"author":{"_account_id":10239,"name":"Dmitry Tantsur","email":"dtantsur@protonmail.com","username":"dtantsur"},"change_message_id":"2ff6786f73e346cf976ef348a6d3b07d80f15a83","unresolved":false,"context_lines":[{"line_number":70,"context_line":"    return"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":""},{"line_number":73,"context_line":"def check_validate_args(func):"},{"line_number":74,"context_line":"    @six.wraps(func)"},{"line_number":75,"context_line":"    def inner_check_validate_args(*args, **kwargs):"},{"line_number":76,"context_line":"        check_uuid_or_name(args[1])"}],"source_content_type":"text/x-python","patch_set":11,"id":"3fa7e38b_e5411f38","line":73,"updated":"2019-12-03 10:50:05.000000000","message":"I envision having too many of similar functions.. I\u0027d like to see something like this instead:\n\n @schema.validate(schema.UuidOrName, schema.Uuid)\n\ni.e. make the validate function generic over types and number of arguments.","commit_id":"7fd531b057da9ffbf341c2c6b083a3dfc0bf52ed"},{"author":{"_account_id":29792,"name":"Jerry Wang","email":"jerry.a.wang@intel.com","username":"junyiwan-gtc"},"change_message_id":"28c3675e5b4aff6540d1d85d66ecac5a930df2cc","unresolved":false,"context_lines":[{"line_number":70,"context_line":"    return"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":""},{"line_number":73,"context_line":"def check_validate_args(func):"},{"line_number":74,"context_line":"    @six.wraps(func)"},{"line_number":75,"context_line":"    def inner_check_validate_args(*args, **kwargs):"},{"line_number":76,"context_line":"        check_uuid_or_name(args[1])"}],"source_content_type":"text/x-python","patch_set":11,"id":"3fa7e38b_7714f341","line":73,"in_reply_to":"3fa7e38b_e5411f38","updated":"2019-12-04 01:50:49.000000000","message":"Ok. Drok also suggest this, I would try to add this requirement. Thanks","commit_id":"7fd531b057da9ffbf341c2c6b083a3dfc0bf52ed"},{"author":{"_account_id":4571,"name":"Steve Baker","email":"sbaker@redhat.com","username":"steve-stevebaker"},"change_message_id":"23785c9054afb590358bb16034aa985598c05fb0","unresolved":false,"context_lines":[{"line_number":91,"context_line":"            result \u003d function(*args, **kwargs)"},{"line_number":92,"context_line":"            return result"},{"line_number":93,"context_line":"        return inner_check_args"},{"line_number":94,"context_line":"    return inner_function"}],"source_content_type":"text/x-python","patch_set":12,"id":"3fa7e38b_d1fc7640","line":94,"updated":"2020-01-07 22:46:53.000000000","message":"This file could do with some thorough unit tests","commit_id":"9d55acd749fd9d109f75cfc465a022fb2666de2e"},{"author":{"_account_id":29792,"name":"Jerry Wang","email":"jerry.a.wang@intel.com","username":"junyiwan-gtc"},"change_message_id":"e369b62321ee18af4d678ac9cd27a337032d4919","unresolved":false,"context_lines":[{"line_number":91,"context_line":"            result \u003d function(*args, **kwargs)"},{"line_number":92,"context_line":"            return result"},{"line_number":93,"context_line":"        return inner_check_args"},{"line_number":94,"context_line":"    return inner_function"}],"source_content_type":"text/x-python","patch_set":12,"id":"3fa7e38b_9c2a9275","line":94,"in_reply_to":"3fa7e38b_d1fc7640","updated":"2020-01-08 06:29:40.000000000","message":"Hi Steve:\nThis already be covered by below functions:\ntest_validate_by_uuid, \ntest_validate_by_name_unsupported, \ntest_validate_by_name, \ntest_validate_by_uuid_using_deprecated_interface, \n\n\nFor example:\npython -m unittest  ironic.tests.unit.api.controllers.v1.test_node.TestListNodes.test_validate_by_uuid\n\nThanks\n-Jerry","commit_id":"9d55acd749fd9d109f75cfc465a022fb2666de2e"},{"author":{"_account_id":23851,"name":"Riccardo Pittau","email":"elfosardo@gmail.com","username":"elfosardo"},"change_message_id":"e631abd0c1dd9d0234eae21e6f9ca563d02fcabe","unresolved":false,"context_lines":[{"line_number":10,"context_line":"#    License for the specific language governing permissions and limitations"},{"line_number":11,"context_line":"#    under the License."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"from functools import wraps"},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"import warlock"},{"line_number":16,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"3fa7e38b_f2c40d43","line":13,"updated":"2020-01-08 10:11:00.000000000","message":"I\u0027d rather import the module, not the function, if just for code style in ironic","commit_id":"6ffffc42a242db5de90255de4fa00faf8bfe596d"},{"author":{"_account_id":29792,"name":"Jerry Wang","email":"jerry.a.wang@intel.com","username":"junyiwan-gtc"},"change_message_id":"35d30f7e8d22c0916d4ae1b51d1d29d49a14c2f3","unresolved":false,"context_lines":[{"line_number":10,"context_line":"#    License for the specific language governing permissions and limitations"},{"line_number":11,"context_line":"#    under the License."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"from functools import wraps"},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"import warlock"},{"line_number":16,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"3fa7e38b_69ba68ba","line":13,"in_reply_to":"3fa7e38b_f2c40d43","updated":"2020-01-08 23:42:28.000000000","message":"Hi Riccardo:\nGood catch! Would fix.\nThanks\n-Jerry","commit_id":"6ffffc42a242db5de90255de4fa00faf8bfe596d"},{"author":{"_account_id":4571,"name":"Steve Baker","email":"sbaker@redhat.com","username":"steve-stevebaker"},"change_message_id":"3ff5543a4a3c1d7b8c18c262dc1508c07633ff5c","unresolved":false,"context_lines":[{"line_number":43,"context_line":"    }"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"class Args_uuid_type(object):"},{"line_number":47,"context_line":"    @staticmethod"},{"line_number":48,"context_line":"    def check_arg(value):"},{"line_number":49,"context_line":"        if value is not None:"}],"source_content_type":"text/x-python","patch_set":14,"id":"3fa7e38b_29323010","line":46,"updated":"2020-01-09 00:27:42.000000000","message":"Is there a reason for mixing capitals and underscores? I think I\u0027d prefer pure snake_case, followed by pure CamelCase.\n\nWhile we\u0027re at it, is there a reason for a class with a single static method? It could just be implemented as a package-level function with a snake_case name.","commit_id":"abba12d4603bf06519344e7486917dcd8f17b6cf"},{"author":{"_account_id":29792,"name":"Jerry Wang","email":"jerry.a.wang@intel.com","username":"junyiwan-gtc"},"change_message_id":"785d01b1985b2e067a666d4e3aa38e33de343d85","unresolved":false,"context_lines":[{"line_number":43,"context_line":"    }"},{"line_number":44,"context_line":""},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"class Args_uuid_type(object):"},{"line_number":47,"context_line":"    @staticmethod"},{"line_number":48,"context_line":"    def check_arg(value):"},{"line_number":49,"context_line":"        if value is not None:"}],"source_content_type":"text/x-python","patch_set":14,"id":"3fa7e38b_c47ca1eb","line":46,"in_reply_to":"3fa7e38b_29323010","updated":"2020-01-09 02:10:59.000000000","message":"For mixing capitals and underscores, would fix. Thanks.\nFor single static method, that was because I would call the function from an uninstantiated class. \nFor using class here, it was because Dimitry and another reviewer hope the parameter of the decorator be like below:\n\n@check_para(type, ...)\nvalidate_function(..) \n\nSee history of review comments for detail. Let me know if you still have questions.","commit_id":"abba12d4603bf06519344e7486917dcd8f17b6cf"},{"author":{"_account_id":4571,"name":"Steve Baker","email":"sbaker@redhat.com","username":"steve-stevebaker"},"change_message_id":"3ff5543a4a3c1d7b8c18c262dc1508c07633ff5c","unresolved":false,"context_lines":[{"line_number":91,"context_line":"            result \u003d function(*args, **kwargs)"},{"line_number":92,"context_line":"            return result"},{"line_number":93,"context_line":"        return inner_check_args"},{"line_number":94,"context_line":"    return inner_function"}],"source_content_type":"text/x-python","patch_set":14,"id":"3fa7e38b_442f5188","line":94,"updated":"2020-01-09 00:27:42.000000000","message":"I would at least like some unit tests on this decorator, I can\u0027t tell by looking at it whether it really does the right thing with arg handling. And even though test_node.py covers validation, it wouldn\u0027t hurt to have simple tests covering each validator in unit isolation.","commit_id":"abba12d4603bf06519344e7486917dcd8f17b6cf"},{"author":{"_account_id":29792,"name":"Jerry Wang","email":"jerry.a.wang@intel.com","username":"junyiwan-gtc"},"change_message_id":"785d01b1985b2e067a666d4e3aa38e33de343d85","unresolved":false,"context_lines":[{"line_number":91,"context_line":"            result \u003d function(*args, **kwargs)"},{"line_number":92,"context_line":"            return result"},{"line_number":93,"context_line":"        return inner_check_args"},{"line_number":94,"context_line":"    return inner_function"}],"source_content_type":"text/x-python","patch_set":14,"id":"3fa7e38b_84af8929","line":94,"in_reply_to":"3fa7e38b_442f5188","updated":"2020-01-09 02:10:59.000000000","message":"Sure, this decorator was a little tricky, I would try to add some unit test here.","commit_id":"abba12d4603bf06519344e7486917dcd8f17b6cf"}],"requirements.txt":[{"author":{"_account_id":24828,"name":"Kaifeng Wang","email":"kaifeng.w@gmail.com","username":"wangkf"},"change_message_id":"159cc5789fe338e3982b9622449fe437aa426df1","unresolved":false,"context_lines":[{"line_number":13,"context_line":"keystoneauth1\u003e\u003d3.15.0 # Apache-2.0"},{"line_number":14,"context_line":"ironic-lib\u003e\u003d2.17.1 # Apache-2.0"},{"line_number":15,"context_line":"python-swiftclient\u003e\u003d3.2.0 # Apache-2.0"},{"line_number":16,"context_line":"python3-warlock\u003e\u003d1.2.0 # Apache-2.0"},{"line_number":17,"context_line":"pytz\u003e\u003d2013.6 # MIT"},{"line_number":18,"context_line":"stevedore\u003e\u003d1.20.0 # Apache-2.0"},{"line_number":19,"context_line":"pysendfile\u003e\u003d2.0.0;sys_platform!\u003d\u0027win32\u0027 # MIT"}],"source_content_type":"text/plain","patch_set":7,"id":"3fa7e38b_5f3f7eb4","line":16,"updated":"2019-10-25 06:25:23.000000000","message":"python3-warlock is a debian package shipped with ubuntu, while packages listed here is used by pip, it\u0027s not the same package from the distribution.\n\nI think warlock is compatible with both python2 and 3, you only needs L41 here. Also you need to add 1.2.0 to the lower-constraints.txt, otherwise the check-requirements job will fail.","commit_id":"6a550340ef86b1bd88f3e0e60d4e2e4ae7a78e7f"},{"author":{"_account_id":29792,"name":"Jerry Wang","email":"jerry.a.wang@intel.com","username":"junyiwan-gtc"},"change_message_id":"17f3665974989c1afc731b37837ec83847df20e1","unresolved":false,"context_lines":[{"line_number":13,"context_line":"keystoneauth1\u003e\u003d3.15.0 # Apache-2.0"},{"line_number":14,"context_line":"ironic-lib\u003e\u003d2.17.1 # Apache-2.0"},{"line_number":15,"context_line":"python-swiftclient\u003e\u003d3.2.0 # Apache-2.0"},{"line_number":16,"context_line":"python3-warlock\u003e\u003d1.2.0 # Apache-2.0"},{"line_number":17,"context_line":"pytz\u003e\u003d2013.6 # MIT"},{"line_number":18,"context_line":"stevedore\u003e\u003d1.20.0 # Apache-2.0"},{"line_number":19,"context_line":"pysendfile\u003e\u003d2.0.0;sys_platform!\u003d\u0027win32\u0027 # MIT"}],"source_content_type":"text/plain","patch_set":7,"id":"3fa7e38b_42f7a55a","line":16,"in_reply_to":"3fa7e38b_5f3f7eb4","updated":"2019-10-25 08:46:50.000000000","message":"Hi, Kaifeng:\nThanks for comment. I thought you were correct.\nI verified pip3 install of warlock at ironic python3 development environment, warlock works fine also.\nBut ipython3 can not work with warlock with pip3 installation(import warlock would error), but no error with ubuntu apt-get install python3-warlock installation at my machine, so I thought python3-warlock was required before. Anyway, ironic development environment was fine, we could ignore ipython3\u0027s issue here.","commit_id":"6a550340ef86b1bd88f3e0e60d4e2e4ae7a78e7f"}]}
