)]}'
{"releasenotes/notes/add-task-monitor-support-21f711927ad6ec91.yaml":[{"author":{"_account_id":23851,"name":"Riccardo Pittau","email":"elfosardo@gmail.com","username":"elfosardo"},"change_message_id":"4e044f0acdc3f015a1844b1db4208059c413dd97","unresolved":false,"context_lines":[{"line_number":1,"context_line":"---"},{"line_number":2,"context_line":"features:"},{"line_number":3,"context_line":"  - |"},{"line_number":4,"context_line":"    Add support for a Task Monitor resource to be able to monitor the state"},{"line_number":5,"context_line":"    of asynchronous operations."}],"source_content_type":"text/x-yaml","patch_set":7,"id":"3fa7e38b_516abc17","line":4,"range":{"start_line":4,"start_character":4,"end_line":4,"end_character":7},"updated":"2020-01-27 14:23:57.000000000","message":"nit: Adds","commit_id":"1f60044bd860ff7efe47851b92eea695a755e28f"}],"sushy/connector.py":[{"author":{"_account_id":26340,"name":"Ilya Etingof","email":"etingof@gmail.com","username":"etingof"},"change_message_id":"ac58dea158225c51a8558534776dbc864d08cfdc","unresolved":false,"context_lines":[{"line_number":60,"context_line":""},{"line_number":61,"context_line":"        :param method: The HTTP method to be used, e.g: GET, POST,"},{"line_number":62,"context_line":"            PUT, PATCH, etc..."},{"line_number":63,"context_line":"        :param path: The sub-URI path to the resource."},{"line_number":64,"context_line":"        :param data: Optional JSON data."},{"line_number":65,"context_line":"        :param headers: Optional dictionary of headers."},{"line_number":66,"context_line":"        :param extra_session_req_kwargs: Optional keyword argument to pass"}],"source_content_type":"text/x-python","patch_set":2,"id":"7faddb67_96d26327","line":63,"range":{"start_line":63,"start_character":25,"end_line":63,"end_character":28},"updated":"2019-07-18 08:25:55.000000000","message":"Is it always sub-URI after this change?","commit_id":"2e5bd26ed68cc703b810c4d12e5327a7be002d97"},{"author":{"_account_id":28128,"name":"Bill Dodd","email":"billdodd@gmail.com","username":"billdodd"},"change_message_id":"5894ea5b116f384f738c5aa7c4e17555e3d17bf1","unresolved":false,"context_lines":[{"line_number":60,"context_line":""},{"line_number":61,"context_line":"        :param method: The HTTP method to be used, e.g: GET, POST,"},{"line_number":62,"context_line":"            PUT, PATCH, etc..."},{"line_number":63,"context_line":"        :param path: The sub-URI path to the resource."},{"line_number":64,"context_line":"        :param data: Optional JSON data."},{"line_number":65,"context_line":"        :param headers: Optional dictionary of headers."},{"line_number":66,"context_line":"        :param extra_session_req_kwargs: Optional keyword argument to pass"}],"source_content_type":"text/x-python","patch_set":2,"id":"7faddb67_56062054","line":63,"range":{"start_line":63,"start_character":25,"end_line":63,"end_character":28},"in_reply_to":"7faddb67_96d26327","updated":"2019-07-18 23:28:36.000000000","message":"Good catch! It\u0027s no longer always a sub-URI. I\u0027ll fix the doc there.","commit_id":"2e5bd26ed68cc703b810c4d12e5327a7be002d97"},{"author":{"_account_id":26340,"name":"Ilya Etingof","email":"etingof@gmail.com","username":"etingof"},"change_message_id":"ac58dea158225c51a8558534776dbc864d08cfdc","unresolved":false,"context_lines":[{"line_number":70,"context_line":"        :raises: ConnectionError"},{"line_number":71,"context_line":"        :raises: HTTPError"},{"line_number":72,"context_line":"        \"\"\""},{"line_number":73,"context_line":"        url \u003d path if bool(parse.urlparse(path).netloc) else parse.urljoin("},{"line_number":74,"context_line":"            self._url, path)"},{"line_number":75,"context_line":"        headers \u003d headers or {}"},{"line_number":76,"context_line":"        if not any(k.lower() \u003d\u003d \u0027odata-version\u0027 for k in headers):"}],"source_content_type":"text/x-python","patch_set":2,"id":"7faddb67_36c28f5a","line":73,"range":{"start_line":73,"start_character":22,"end_line":73,"end_character":26},"updated":"2019-07-18 08:25:55.000000000","message":"nit: bool() is not needed perhaps?","commit_id":"2e5bd26ed68cc703b810c4d12e5327a7be002d97"},{"author":{"_account_id":28128,"name":"Bill Dodd","email":"billdodd@gmail.com","username":"billdodd"},"change_message_id":"5894ea5b116f384f738c5aa7c4e17555e3d17bf1","unresolved":false,"context_lines":[{"line_number":70,"context_line":"        :raises: ConnectionError"},{"line_number":71,"context_line":"        :raises: HTTPError"},{"line_number":72,"context_line":"        \"\"\""},{"line_number":73,"context_line":"        url \u003d path if bool(parse.urlparse(path).netloc) else parse.urljoin("},{"line_number":74,"context_line":"            self._url, path)"},{"line_number":75,"context_line":"        headers \u003d headers or {}"},{"line_number":76,"context_line":"        if not any(k.lower() \u003d\u003d \u0027odata-version\u0027 for k in headers):"}],"source_content_type":"text/x-python","patch_set":2,"id":"7faddb67_f12dd694","line":73,"range":{"start_line":73,"start_character":22,"end_line":73,"end_character":26},"in_reply_to":"7faddb67_36c28f5a","updated":"2019-07-18 23:28:36.000000000","message":"Ah, yes, you are right. The bool() is redundant in this case.","commit_id":"2e5bd26ed68cc703b810c4d12e5327a7be002d97"},{"author":{"_account_id":26340,"name":"Ilya Etingof","email":"etingof@gmail.com","username":"etingof"},"change_message_id":"d805e3a8c944d6da22396eceef83ca5f12dae253","unresolved":false,"context_lines":[{"line_number":115,"context_line":"                raise"},{"line_number":116,"context_line":""},{"line_number":117,"context_line":"        if blocking and response.status_code \u003d\u003d 202:"},{"line_number":118,"context_line":"            mon \u003d TaskMonitor(self, response.headers.get(\u0027location\u0027))\\"},{"line_number":119,"context_line":"                .set_retry_after(response.headers.get(\u0027retry-after\u0027))"},{"line_number":120,"context_line":"            in_progress \u003d True"},{"line_number":121,"context_line":"            while in_progress:"}],"source_content_type":"text/x-python","patch_set":5,"id":"3fa7e38b_4b9be471","line":118,"range":{"start_line":118,"start_character":36,"end_line":118,"end_character":44},"updated":"2019-11-01 11:44:59.000000000","message":"I wonder how clear sushy would eventually err out if `Location:` is missing in the response?","commit_id":"1f91497a3d091e78735e6194720851215c736575"},{"author":{"_account_id":26340,"name":"Ilya Etingof","email":"etingof@gmail.com","username":"etingof"},"change_message_id":"d805e3a8c944d6da22396eceef83ca5f12dae253","unresolved":false,"context_lines":[{"line_number":115,"context_line":"                raise"},{"line_number":116,"context_line":""},{"line_number":117,"context_line":"        if blocking and response.status_code \u003d\u003d 202:"},{"line_number":118,"context_line":"            mon \u003d TaskMonitor(self, response.headers.get(\u0027location\u0027))\\"},{"line_number":119,"context_line":"                .set_retry_after(response.headers.get(\u0027retry-after\u0027))"},{"line_number":120,"context_line":"            in_progress \u003d True"},{"line_number":121,"context_line":"            while in_progress:"}],"source_content_type":"text/x-python","patch_set":5,"id":"3fa7e38b_0bd40c1f","line":118,"range":{"start_line":118,"start_character":69,"end_line":118,"end_character":70},"updated":"2019-11-01 11:44:59.000000000","message":"nit: may be `(`?","commit_id":"1f91497a3d091e78735e6194720851215c736575"},{"author":{"_account_id":28128,"name":"Bill Dodd","email":"billdodd@gmail.com","username":"billdodd"},"change_message_id":"720e58fcb8d07a8c65de5acbb28137d58ddc16f2","unresolved":false,"context_lines":[{"line_number":115,"context_line":"                raise"},{"line_number":116,"context_line":""},{"line_number":117,"context_line":"        if blocking and response.status_code \u003d\u003d 202:"},{"line_number":118,"context_line":"            mon \u003d TaskMonitor(self, response.headers.get(\u0027location\u0027))\\"},{"line_number":119,"context_line":"                .set_retry_after(response.headers.get(\u0027retry-after\u0027))"},{"line_number":120,"context_line":"            in_progress \u003d True"},{"line_number":121,"context_line":"            while in_progress:"}],"source_content_type":"text/x-python","patch_set":5,"id":"3fa7e38b_731b0a80","line":118,"range":{"start_line":118,"start_character":69,"end_line":118,"end_character":70},"in_reply_to":"3fa7e38b_0bd40c1f","updated":"2019-11-05 21:26:24.000000000","message":"Done","commit_id":"1f91497a3d091e78735e6194720851215c736575"},{"author":{"_account_id":28128,"name":"Bill Dodd","email":"billdodd@gmail.com","username":"billdodd"},"change_message_id":"720e58fcb8d07a8c65de5acbb28137d58ddc16f2","unresolved":false,"context_lines":[{"line_number":115,"context_line":"                raise"},{"line_number":116,"context_line":""},{"line_number":117,"context_line":"        if blocking and response.status_code \u003d\u003d 202:"},{"line_number":118,"context_line":"            mon \u003d TaskMonitor(self, response.headers.get(\u0027location\u0027))\\"},{"line_number":119,"context_line":"                .set_retry_after(response.headers.get(\u0027retry-after\u0027))"},{"line_number":120,"context_line":"            in_progress \u003d True"},{"line_number":121,"context_line":"            while in_progress:"}],"source_content_type":"text/x-python","patch_set":5,"id":"3fa7e38b_7e00b101","line":118,"range":{"start_line":118,"start_character":36,"end_line":118,"end_character":44},"in_reply_to":"3fa7e38b_4b9be471","updated":"2019-11-05 21:26:24.000000000","message":"Good point. I added a check for that in patch set 6 and raise a ConnectionError with an appropriate message.","commit_id":"1f91497a3d091e78735e6194720851215c736575"},{"author":{"_account_id":26340,"name":"Ilya Etingof","email":"etingof@gmail.com","username":"etingof"},"change_message_id":"d805e3a8c944d6da22396eceef83ca5f12dae253","unresolved":false,"context_lines":[{"line_number":117,"context_line":"        if blocking and response.status_code \u003d\u003d 202:"},{"line_number":118,"context_line":"            mon \u003d TaskMonitor(self, response.headers.get(\u0027location\u0027))\\"},{"line_number":119,"context_line":"                .set_retry_after(response.headers.get(\u0027retry-after\u0027))"},{"line_number":120,"context_line":"            in_progress \u003d True"},{"line_number":121,"context_line":"            while in_progress:"},{"line_number":122,"context_line":"                sleep_for \u003d mon.sleep_for"},{"line_number":123,"context_line":"                LOG.debug(\u0027Blocking for in-progress %(method)s call to \u0027"}],"source_content_type":"text/x-python","patch_set":5,"id":"3fa7e38b_0bbdecd6","line":120,"range":{"start_line":120,"start_character":12,"end_line":120,"end_character":23},"updated":"2019-11-01 11:44:59.000000000","message":"nit: can we use just `mon.in_progress`?","commit_id":"1f91497a3d091e78735e6194720851215c736575"},{"author":{"_account_id":28128,"name":"Bill Dodd","email":"billdodd@gmail.com","username":"billdodd"},"change_message_id":"720e58fcb8d07a8c65de5acbb28137d58ddc16f2","unresolved":false,"context_lines":[{"line_number":117,"context_line":"        if blocking and response.status_code \u003d\u003d 202:"},{"line_number":118,"context_line":"            mon \u003d TaskMonitor(self, response.headers.get(\u0027location\u0027))\\"},{"line_number":119,"context_line":"                .set_retry_after(response.headers.get(\u0027retry-after\u0027))"},{"line_number":120,"context_line":"            in_progress \u003d True"},{"line_number":121,"context_line":"            while in_progress:"},{"line_number":122,"context_line":"                sleep_for \u003d mon.sleep_for"},{"line_number":123,"context_line":"                LOG.debug(\u0027Blocking for in-progress %(method)s call to \u0027"}],"source_content_type":"text/x-python","patch_set":5,"id":"3fa7e38b_3e0a3920","line":120,"range":{"start_line":120,"start_character":12,"end_line":120,"end_character":23},"in_reply_to":"3fa7e38b_0bbdecd6","updated":"2019-11-05 21:26:24.000000000","message":"Done","commit_id":"1f91497a3d091e78735e6194720851215c736575"},{"author":{"_account_id":26340,"name":"Ilya Etingof","email":"etingof@gmail.com","username":"etingof"},"change_message_id":"d805e3a8c944d6da22396eceef83ca5f12dae253","unresolved":false,"context_lines":[{"line_number":118,"context_line":"            mon \u003d TaskMonitor(self, response.headers.get(\u0027location\u0027))\\"},{"line_number":119,"context_line":"                .set_retry_after(response.headers.get(\u0027retry-after\u0027))"},{"line_number":120,"context_line":"            in_progress \u003d True"},{"line_number":121,"context_line":"            while in_progress:"},{"line_number":122,"context_line":"                sleep_for \u003d mon.sleep_for"},{"line_number":123,"context_line":"                LOG.debug(\u0027Blocking for in-progress %(method)s call to \u0027"},{"line_number":124,"context_line":"                          \u0027%(url)s; sleeping for %(sleep)s seconds\u0027,"}],"source_content_type":"text/x-python","patch_set":5,"id":"3fa7e38b_0b8bac1e","line":121,"range":{"start_line":121,"start_character":18,"end_line":121,"end_character":29},"updated":"2019-11-01 11:44:59.000000000","message":"Should we have some hard limit on being in this loop?","commit_id":"1f91497a3d091e78735e6194720851215c736575"},{"author":{"_account_id":28128,"name":"Bill Dodd","email":"billdodd@gmail.com","username":"billdodd"},"change_message_id":"720e58fcb8d07a8c65de5acbb28137d58ddc16f2","unresolved":false,"context_lines":[{"line_number":118,"context_line":"            mon \u003d TaskMonitor(self, response.headers.get(\u0027location\u0027))\\"},{"line_number":119,"context_line":"                .set_retry_after(response.headers.get(\u0027retry-after\u0027))"},{"line_number":120,"context_line":"            in_progress \u003d True"},{"line_number":121,"context_line":"            while in_progress:"},{"line_number":122,"context_line":"                sleep_for \u003d mon.sleep_for"},{"line_number":123,"context_line":"                LOG.debug(\u0027Blocking for in-progress %(method)s call to \u0027"},{"line_number":124,"context_line":"                          \u0027%(url)s; sleeping for %(sleep)s seconds\u0027,"}],"source_content_type":"text/x-python","patch_set":5,"id":"3fa7e38b_9e180d77","line":121,"range":{"start_line":121,"start_character":18,"end_line":121,"end_character":29},"in_reply_to":"3fa7e38b_0b8bac1e","updated":"2019-11-05 21:26:24.000000000","message":"Yes, I think that would be good. I added one in patch set 6.","commit_id":"1f91497a3d091e78735e6194720851215c736575"},{"author":{"_account_id":26340,"name":"Ilya Etingof","email":"etingof@gmail.com","username":"etingof"},"change_message_id":"d805e3a8c944d6da22396eceef83ca5f12dae253","unresolved":false,"context_lines":[{"line_number":119,"context_line":"                .set_retry_after(response.headers.get(\u0027retry-after\u0027))"},{"line_number":120,"context_line":"            in_progress \u003d True"},{"line_number":121,"context_line":"            while in_progress:"},{"line_number":122,"context_line":"                sleep_for \u003d mon.sleep_for"},{"line_number":123,"context_line":"                LOG.debug(\u0027Blocking for in-progress %(method)s call to \u0027"},{"line_number":124,"context_line":"                          \u0027%(url)s; sleeping for %(sleep)s seconds\u0027,"},{"line_number":125,"context_line":"                          {\u0027method\u0027: method, \u0027url\u0027: url, \u0027sleep\u0027: sleep_for})"}],"source_content_type":"text/x-python","patch_set":5,"id":"3fa7e38b_8bd0fc20","line":122,"range":{"start_line":122,"start_character":16,"end_line":122,"end_character":25},"updated":"2019-11-01 11:44:59.000000000","message":"nit: why do we need this additional variable?","commit_id":"1f91497a3d091e78735e6194720851215c736575"},{"author":{"_account_id":28128,"name":"Bill Dodd","email":"billdodd@gmail.com","username":"billdodd"},"change_message_id":"720e58fcb8d07a8c65de5acbb28137d58ddc16f2","unresolved":false,"context_lines":[{"line_number":119,"context_line":"                .set_retry_after(response.headers.get(\u0027retry-after\u0027))"},{"line_number":120,"context_line":"            in_progress \u003d True"},{"line_number":121,"context_line":"            while in_progress:"},{"line_number":122,"context_line":"                sleep_for \u003d mon.sleep_for"},{"line_number":123,"context_line":"                LOG.debug(\u0027Blocking for in-progress %(method)s call to \u0027"},{"line_number":124,"context_line":"                          \u0027%(url)s; sleeping for %(sleep)s seconds\u0027,"},{"line_number":125,"context_line":"                          {\u0027method\u0027: method, \u0027url\u0027: url, \u0027sleep\u0027: sleep_for})"}],"source_content_type":"text/x-python","patch_set":5,"id":"3fa7e38b_be15c93f","line":122,"range":{"start_line":122,"start_character":16,"end_line":122,"end_character":25},"in_reply_to":"3fa7e38b_8bd0fc20","updated":"2019-11-05 21:26:24.000000000","message":"I removed it.","commit_id":"1f91497a3d091e78735e6194720851215c736575"}],"sushy/resources/base.py":[{"author":{"_account_id":26340,"name":"Ilya Etingof","email":"etingof@gmail.com","username":"etingof"},"change_message_id":"ac58dea158225c51a8558534776dbc864d08cfdc","unresolved":false,"context_lines":[{"line_number":85,"context_line":"        for path_item in self._path[:-1]:"},{"line_number":86,"context_line":"            body \u003d body.get(path_item, {})"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"        if not body or name not in body:"},{"line_number":89,"context_line":"            if self._required:"},{"line_number":90,"context_line":"                path \u003d (nested_in or []) + self._path"},{"line_number":91,"context_line":"                raise exceptions.MissingAttributeError("}],"source_content_type":"text/x-python","patch_set":2,"id":"7faddb67_76c32758","line":88,"range":{"start_line":88,"start_character":11,"end_line":88,"end_character":19},"updated":"2019-07-18 08:25:55.000000000","message":"Just curious, can `body` be something that does not support `in` operation? I am questioning if we need this `not body` condition?","commit_id":"2e5bd26ed68cc703b810c4d12e5327a7be002d97"},{"author":{"_account_id":28128,"name":"Bill Dodd","email":"billdodd@gmail.com","username":"billdodd"},"change_message_id":"5894ea5b116f384f738c5aa7c4e17555e3d17bf1","unresolved":false,"context_lines":[{"line_number":85,"context_line":"        for path_item in self._path[:-1]:"},{"line_number":86,"context_line":"            body \u003d body.get(path_item, {})"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"        if not body or name not in body:"},{"line_number":89,"context_line":"            if self._required:"},{"line_number":90,"context_line":"                path \u003d (nested_in or []) + self._path"},{"line_number":91,"context_line":"                raise exceptions.MissingAttributeError("}],"source_content_type":"text/x-python","patch_set":2,"id":"7faddb67_d6df700a","line":88,"range":{"start_line":88,"start_character":11,"end_line":88,"end_character":19},"in_reply_to":"7faddb67_76c32758","updated":"2019-07-18 23:28:36.000000000","message":"Yes, it can be eliminated. See also comments from line 284 below.","commit_id":"2e5bd26ed68cc703b810c4d12e5327a7be002d97"},{"author":{"_account_id":26340,"name":"Ilya Etingof","email":"etingof@gmail.com","username":"etingof"},"change_message_id":"ac58dea158225c51a8558534776dbc864d08cfdc","unresolved":false,"context_lines":[{"line_number":281,"context_line":"    def get_json(self):"},{"line_number":282,"context_line":"        \"\"\"Gets JSON file from URI directly\"\"\""},{"line_number":283,"context_line":"        data \u003d self._conn.get(path\u003dself._path)"},{"line_number":284,"context_line":"        return data.json() if data.content else None"},{"line_number":285,"context_line":""},{"line_number":286,"context_line":""},{"line_number":287,"context_line":"class JsonPublicFileReader(AbstractJsonReader):"}],"source_content_type":"text/x-python","patch_set":2,"id":"7faddb67_76980774","line":284,"range":{"start_line":284,"start_character":48,"end_line":284,"end_character":52},"updated":"2019-07-18 08:25:55.000000000","message":"Is it a good signature to return non-dict from a `get_json()` method? Feels a bit counterintuitive. Can it be just an empty dict?","commit_id":"2e5bd26ed68cc703b810c4d12e5327a7be002d97"},{"author":{"_account_id":28128,"name":"Bill Dodd","email":"billdodd@gmail.com","username":"billdodd"},"change_message_id":"5894ea5b116f384f738c5aa7c4e17555e3d17bf1","unresolved":false,"context_lines":[{"line_number":281,"context_line":"    def get_json(self):"},{"line_number":282,"context_line":"        \"\"\"Gets JSON file from URI directly\"\"\""},{"line_number":283,"context_line":"        data \u003d self._conn.get(path\u003dself._path)"},{"line_number":284,"context_line":"        return data.json() if data.content else None"},{"line_number":285,"context_line":""},{"line_number":286,"context_line":""},{"line_number":287,"context_line":"class JsonPublicFileReader(AbstractJsonReader):"}],"source_content_type":"text/x-python","patch_set":2,"id":"7faddb67_d691b048","line":284,"range":{"start_line":284,"start_character":48,"end_line":284,"end_character":52},"in_reply_to":"7faddb67_76980774","updated":"2019-07-18 23:28:36.000000000","message":"Good point. An empty dict is better. Then the `not body` test mentioned in line 88 above is not needed.","commit_id":"2e5bd26ed68cc703b810c4d12e5327a7be002d97"},{"author":{"_account_id":26340,"name":"Ilya Etingof","email":"etingof@gmail.com","username":"etingof"},"change_message_id":"d805e3a8c944d6da22396eceef83ca5f12dae253","unresolved":false,"context_lines":[{"line_number":351,"context_line":"    def get_json(self):"},{"line_number":352,"context_line":"        \"\"\"Gets JSON file from URI directly\"\"\""},{"line_number":353,"context_line":"        data \u003d self._conn.get(path\u003dself._path)"},{"line_number":354,"context_line":"        return data.json() if data.content else {}"},{"line_number":355,"context_line":""},{"line_number":356,"context_line":""},{"line_number":357,"context_line":"class JsonPublicFileReader(AbstractJsonReader):"}],"source_content_type":"text/x-python","patch_set":5,"id":"3fa7e38b_cbaef47f","line":354,"range":{"start_line":354,"start_character":35,"end_line":354,"end_character":42},"updated":"2019-11-01 11:44:59.000000000","message":"I understand that we need this check because of the way how Response object behaves - `.json()` would fail on no contents.","commit_id":"1f91497a3d091e78735e6194720851215c736575"},{"author":{"_account_id":11655,"name":"Julia Kreger","email":"juliaashleykreger@gmail.com","username":"jkreger","status":"Flying to the moon with a Jetpack!"},"change_message_id":"a00e976ade814d83a155f36963c2c22b830e4f3f","unresolved":false,"context_lines":[{"line_number":351,"context_line":"    def get_json(self):"},{"line_number":352,"context_line":"        \"\"\"Gets JSON file from URI directly\"\"\""},{"line_number":353,"context_line":"        data \u003d self._conn.get(path\u003dself._path)"},{"line_number":354,"context_line":"        return data.json() if data.content else {}"},{"line_number":355,"context_line":""},{"line_number":356,"context_line":""},{"line_number":357,"context_line":"class JsonPublicFileReader(AbstractJsonReader):"}],"source_content_type":"text/x-python","patch_set":5,"id":"3fa7e38b_d19eac04","line":354,"updated":"2019-10-31 18:04:32.000000000","message":"This does seem like a somewhat wide sweeping change, but I guess it makes sense.","commit_id":"1f91497a3d091e78735e6194720851215c736575"},{"author":{"_account_id":28128,"name":"Bill Dodd","email":"billdodd@gmail.com","username":"billdodd"},"change_message_id":"720e58fcb8d07a8c65de5acbb28137d58ddc16f2","unresolved":false,"context_lines":[{"line_number":351,"context_line":"    def get_json(self):"},{"line_number":352,"context_line":"        \"\"\"Gets JSON file from URI directly\"\"\""},{"line_number":353,"context_line":"        data \u003d self._conn.get(path\u003dself._path)"},{"line_number":354,"context_line":"        return data.json() if data.content else {}"},{"line_number":355,"context_line":""},{"line_number":356,"context_line":""},{"line_number":357,"context_line":"class JsonPublicFileReader(AbstractJsonReader):"}],"source_content_type":"text/x-python","patch_set":5,"id":"3fa7e38b_de3765e4","line":354,"range":{"start_line":354,"start_character":35,"end_line":354,"end_character":42},"in_reply_to":"3fa7e38b_cbaef47f","updated":"2019-11-05 21:26:24.000000000","message":"+1","commit_id":"1f91497a3d091e78735e6194720851215c736575"}],"sushy/resources/system/storage/volume.py":[{"author":{"_account_id":26340,"name":"Ilya Etingof","email":"etingof@gmail.com","username":"etingof"},"change_message_id":"ac58dea158225c51a8558534776dbc864d08cfdc","unresolved":false,"context_lines":[{"line_number":97,"context_line":"                parameter\u003d\u0027value\u0027, value\u003dvalue, valid_values\u003dvalid_values)"},{"line_number":98,"context_line":"        value \u003d store_maps.VOLUME_INIT_TYPE_MAP_REV[value]"},{"line_number":99,"context_line":"        target_uri \u003d self._get_initialize_action_element().target_uri"},{"line_number":100,"context_line":"        r \u003d self._conn.post(target_uri, data\u003d{\u0027InitializeType\u0027: value})"},{"line_number":101,"context_line":"        resource \u003d None"},{"line_number":102,"context_line":"        if r.status_code \u003d\u003d 202:"},{"line_number":103,"context_line":"            location \u003d r.headers.get(\u0027location\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"7faddb67_f69ab75f","line":100,"range":{"start_line":100,"start_character":47,"end_line":100,"end_character":61},"updated":"2019-07-18 08:25:55.000000000","message":"Could we ever need to pass some other values? May be passing just a dict as `value` would be more future-proof?","commit_id":"2e5bd26ed68cc703b810c4d12e5327a7be002d97"},{"author":{"_account_id":28128,"name":"Bill Dodd","email":"billdodd@gmail.com","username":"billdodd"},"change_message_id":"5894ea5b116f384f738c5aa7c4e17555e3d17bf1","unresolved":false,"context_lines":[{"line_number":97,"context_line":"                parameter\u003d\u0027value\u0027, value\u003dvalue, valid_values\u003dvalid_values)"},{"line_number":98,"context_line":"        value \u003d store_maps.VOLUME_INIT_TYPE_MAP_REV[value]"},{"line_number":99,"context_line":"        target_uri \u003d self._get_initialize_action_element().target_uri"},{"line_number":100,"context_line":"        r \u003d self._conn.post(target_uri, data\u003d{\u0027InitializeType\u0027: value})"},{"line_number":101,"context_line":"        resource \u003d None"},{"line_number":102,"context_line":"        if r.status_code \u003d\u003d 202:"},{"line_number":103,"context_line":"            location \u003d r.headers.get(\u0027location\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"7faddb67_d664504c","line":100,"range":{"start_line":100,"start_character":47,"end_line":100,"end_character":61},"in_reply_to":"7faddb67_f69ab75f","updated":"2019-07-18 23:28:36.000000000","message":"Yes, good point. In fact even today there may be cases where passing an annotation in addition to the \u0027InitializeType\u0027 would be desirable. I\u0027ll change that.","commit_id":"2e5bd26ed68cc703b810c4d12e5327a7be002d97"},{"author":{"_account_id":26340,"name":"Ilya Etingof","email":"etingof@gmail.com","username":"etingof"},"change_message_id":"ac58dea158225c51a8558534776dbc864d08cfdc","unresolved":false,"context_lines":[{"line_number":98,"context_line":"        value \u003d store_maps.VOLUME_INIT_TYPE_MAP_REV[value]"},{"line_number":99,"context_line":"        target_uri \u003d self._get_initialize_action_element().target_uri"},{"line_number":100,"context_line":"        r \u003d self._conn.post(target_uri, data\u003d{\u0027InitializeType\u0027: value})"},{"line_number":101,"context_line":"        resource \u003d None"},{"line_number":102,"context_line":"        if r.status_code \u003d\u003d 202:"},{"line_number":103,"context_line":"            location \u003d r.headers.get(\u0027location\u0027)"},{"line_number":104,"context_line":"            retry_after \u003d r.headers.get(\u0027retry-after\u0027)"},{"line_number":105,"context_line":"            resource \u003d TaskMonitor(self._conn, location,"},{"line_number":106,"context_line":"                                   redfish_version\u003dself.redfish_version,"},{"line_number":107,"context_line":"                                   retry_after\u003dretry_after)"},{"line_number":108,"context_line":"        return resource"}],"source_content_type":"text/x-python","patch_set":2,"id":"7faddb67_1692f34c","line":105,"range":{"start_line":101,"start_character":8,"end_line":105,"end_character":34},"updated":"2019-07-18 08:25:55.000000000","message":"May be we could shorten this?\n\n        if r.status_code \u003d\u003d 202:\n            location \u003d r.headers.get(\u0027location\u0027)\n            retry_after \u003d r.headers.get(\u0027retry-after\u0027)\n            returnTaskMonitor(...)","commit_id":"2e5bd26ed68cc703b810c4d12e5327a7be002d97"},{"author":{"_account_id":28128,"name":"Bill Dodd","email":"billdodd@gmail.com","username":"billdodd"},"change_message_id":"5894ea5b116f384f738c5aa7c4e17555e3d17bf1","unresolved":false,"context_lines":[{"line_number":98,"context_line":"        value \u003d store_maps.VOLUME_INIT_TYPE_MAP_REV[value]"},{"line_number":99,"context_line":"        target_uri \u003d self._get_initialize_action_element().target_uri"},{"line_number":100,"context_line":"        r \u003d self._conn.post(target_uri, data\u003d{\u0027InitializeType\u0027: value})"},{"line_number":101,"context_line":"        resource \u003d None"},{"line_number":102,"context_line":"        if r.status_code \u003d\u003d 202:"},{"line_number":103,"context_line":"            location \u003d r.headers.get(\u0027location\u0027)"},{"line_number":104,"context_line":"            retry_after \u003d r.headers.get(\u0027retry-after\u0027)"},{"line_number":105,"context_line":"            resource \u003d TaskMonitor(self._conn, location,"},{"line_number":106,"context_line":"                                   redfish_version\u003dself.redfish_version,"},{"line_number":107,"context_line":"                                   retry_after\u003dretry_after)"},{"line_number":108,"context_line":"        return resource"}],"source_content_type":"text/x-python","patch_set":2,"id":"7faddb67_96333862","line":105,"range":{"start_line":101,"start_character":8,"end_line":105,"end_character":34},"in_reply_to":"7faddb67_1692f34c","updated":"2019-07-18 23:28:36.000000000","message":"True. But after the addition of the setter method for retry_after, will need to do:\n\n    resource \u003d TaskMonitor(...)\n    resource.set_retry_after(retry_after)","commit_id":"2e5bd26ed68cc703b810c4d12e5327a7be002d97"},{"author":{"_account_id":26340,"name":"Ilya Etingof","email":"etingof@gmail.com","username":"etingof"},"change_message_id":"ac58dea158225c51a8558534776dbc864d08cfdc","unresolved":false,"context_lines":[{"line_number":159,"context_line":"        \"\"\""},{"line_number":160,"context_line":"        r \u003d self._conn.post(self._path, data\u003dpayload)"},{"line_number":161,"context_line":"        location \u003d r.headers.get(\u0027location\u0027)"},{"line_number":162,"context_line":"        resource \u003d None"},{"line_number":163,"context_line":"        if r.status_code \u003d\u003d 201:"},{"line_number":164,"context_line":"            if location:"},{"line_number":165,"context_line":"                self.refresh()"}],"source_content_type":"text/x-python","patch_set":2,"id":"7faddb67_76a6c7ad","line":162,"range":{"start_line":162,"start_character":8,"end_line":162,"end_character":16},"updated":"2019-07-18 08:25:55.000000000","message":"Ditto, may be we could just return TaskMonitor object.","commit_id":"2e5bd26ed68cc703b810c4d12e5327a7be002d97"},{"author":{"_account_id":28128,"name":"Bill Dodd","email":"billdodd@gmail.com","username":"billdodd"},"change_message_id":"5894ea5b116f384f738c5aa7c4e17555e3d17bf1","unresolved":false,"context_lines":[{"line_number":159,"context_line":"        \"\"\""},{"line_number":160,"context_line":"        r \u003d self._conn.post(self._path, data\u003dpayload)"},{"line_number":161,"context_line":"        location \u003d r.headers.get(\u0027location\u0027)"},{"line_number":162,"context_line":"        resource \u003d None"},{"line_number":163,"context_line":"        if r.status_code \u003d\u003d 201:"},{"line_number":164,"context_line":"            if location:"},{"line_number":165,"context_line":"                self.refresh()"}],"source_content_type":"text/x-python","patch_set":2,"id":"7faddb67_76d8fced","line":162,"range":{"start_line":162,"start_character":8,"end_line":162,"end_character":16},"in_reply_to":"7faddb67_76a6c7ad","updated":"2019-07-18 23:28:36.000000000","message":"Ditto above because of the new setter.","commit_id":"2e5bd26ed68cc703b810c4d12e5327a7be002d97"}],"sushy/resources/task_monitor.py":[{"author":{"_account_id":26340,"name":"Ilya Etingof","email":"etingof@gmail.com","username":"etingof"},"change_message_id":"ac58dea158225c51a8558534776dbc864d08cfdc","unresolved":false,"context_lines":[{"line_number":31,"context_line":"                 connector,"},{"line_number":32,"context_line":"                 path\u003d\u0027\u0027,"},{"line_number":33,"context_line":"                 redfish_version\u003dNone,"},{"line_number":34,"context_line":"                 retry_after\u003dNone):"},{"line_number":35,"context_line":"        \"\"\"A class representing a Redfish Task Monitor"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"        :param connector: A Connector instance"}],"source_content_type":"text/x-python","patch_set":2,"id":"7faddb67_56c4eb3f","line":34,"range":{"start_line":34,"start_character":17,"end_line":34,"end_character":28},"updated":"2019-07-18 08:25:55.000000000","message":"I am a bit cautious changing resource instantiation signature... If there\u0027d be any way to pass this parameter somehow else...?","commit_id":"2e5bd26ed68cc703b810c4d12e5327a7be002d97"},{"author":{"_account_id":28128,"name":"Bill Dodd","email":"billdodd@gmail.com","username":"billdodd"},"change_message_id":"5894ea5b116f384f738c5aa7c4e17555e3d17bf1","unresolved":false,"context_lines":[{"line_number":31,"context_line":"                 connector,"},{"line_number":32,"context_line":"                 path\u003d\u0027\u0027,"},{"line_number":33,"context_line":"                 redfish_version\u003dNone,"},{"line_number":34,"context_line":"                 retry_after\u003dNone):"},{"line_number":35,"context_line":"        \"\"\"A class representing a Redfish Task Monitor"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"        :param connector: A Connector instance"}],"source_content_type":"text/x-python","patch_set":2,"id":"7faddb67_b1b3dee8","line":34,"range":{"start_line":34,"start_character":17,"end_line":34,"end_character":28},"in_reply_to":"7faddb67_56c4eb3f","updated":"2019-07-18 23:28:36.000000000","message":"Adding a setter method in patch set 3. Did you have any other alternatives in mind?","commit_id":"2e5bd26ed68cc703b810c4d12e5327a7be002d97"},{"author":{"_account_id":26340,"name":"Ilya Etingof","email":"etingof@gmail.com","username":"etingof"},"change_message_id":"adf4ce74189e265bf964aa8e689962a1a8b74aaa","unresolved":false,"context_lines":[{"line_number":31,"context_line":"                 connector,"},{"line_number":32,"context_line":"                 path\u003d\u0027\u0027,"},{"line_number":33,"context_line":"                 redfish_version\u003dNone,"},{"line_number":34,"context_line":"                 retry_after\u003dNone):"},{"line_number":35,"context_line":"        \"\"\"A class representing a Redfish Task Monitor"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"        :param connector: A Connector instance"}],"source_content_type":"text/x-python","patch_set":2,"id":"7faddb67_f91ac6c3","line":34,"range":{"start_line":34,"start_character":17,"end_line":34,"end_character":28},"in_reply_to":"7faddb67_b1b3dee8","updated":"2019-08-02 09:19:49.000000000","message":"An alternative could be a method returning self to streamline instantiation e.g.\n\ntask_monitor \u003d TaskMonitor(connector, \u0027path\u0027, ...).retry_after(3)\n\nOr may be we could refactor the base class to make it accepting **kwargs?","commit_id":"2e5bd26ed68cc703b810c4d12e5327a7be002d97"},{"author":{"_account_id":28128,"name":"Bill Dodd","email":"billdodd@gmail.com","username":"billdodd"},"change_message_id":"1a1d85b27bab83f99259a7b10ab1f022360eaeb9","unresolved":false,"context_lines":[{"line_number":31,"context_line":"                 connector,"},{"line_number":32,"context_line":"                 path\u003d\u0027\u0027,"},{"line_number":33,"context_line":"                 redfish_version\u003dNone,"},{"line_number":34,"context_line":"                 retry_after\u003dNone):"},{"line_number":35,"context_line":"        \"\"\"A class representing a Redfish Task Monitor"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"        :param connector: A Connector instance"}],"source_content_type":"text/x-python","patch_set":2,"id":"7faddb67_c6f79759","line":34,"range":{"start_line":34,"start_character":17,"end_line":34,"end_character":28},"in_reply_to":"7faddb67_f91ac6c3","updated":"2019-08-07 16:21:37.000000000","message":"Ah, yes. I like the idea of returning self. Will do that in patch set 4. Thanks.","commit_id":"2e5bd26ed68cc703b810c4d12e5327a7be002d97"},{"author":{"_account_id":26340,"name":"Ilya Etingof","email":"etingof@gmail.com","username":"etingof"},"change_message_id":"ac58dea158225c51a8558534776dbc864d08cfdc","unresolved":false,"context_lines":[{"line_number":49,"context_line":"    def _to_datetime(retry_after_str):"},{"line_number":50,"context_line":"        if not retry_after_str:"},{"line_number":51,"context_line":"            dt \u003d None"},{"line_number":52,"context_line":"        elif retry_after_str.isdigit():"},{"line_number":53,"context_line":"            # Retry-After: 120"},{"line_number":54,"context_line":"            dt \u003d datetime.now() + timedelta(seconds\u003dint(retry_after_str))"},{"line_number":55,"context_line":"        else:"},{"line_number":56,"context_line":"            # Retry-After: Fri, 31 Dec 1999 23:59:59 GMT"},{"line_number":57,"context_line":"            dt \u003d parser.parse(retry_after_str)"},{"line_number":58,"context_line":"        return dt"},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"    @property"}],"source_content_type":"text/x-python","patch_set":2,"id":"7faddb67_96d34304","line":57,"range":{"start_line":52,"start_character":10,"end_line":57,"end_character":46},"updated":"2019-07-18 08:25:55.000000000","message":"nit:\n\n        if retry_after_str.isdigit():\n            # Retry-After: 120\n            return datetime.now() + timedelta(seconds\u003dint(retry_after_str))\n        else:\n            # Retry-After: Fri, 31 Dec 1999 23:59:59 GMT\n            return parser.parse(retry_after_str)","commit_id":"2e5bd26ed68cc703b810c4d12e5327a7be002d97"},{"author":{"_account_id":28128,"name":"Bill Dodd","email":"billdodd@gmail.com","username":"billdodd"},"change_message_id":"5894ea5b116f384f738c5aa7c4e17555e3d17bf1","unresolved":false,"context_lines":[{"line_number":49,"context_line":"    def _to_datetime(retry_after_str):"},{"line_number":50,"context_line":"        if not retry_after_str:"},{"line_number":51,"context_line":"            dt \u003d None"},{"line_number":52,"context_line":"        elif retry_after_str.isdigit():"},{"line_number":53,"context_line":"            # Retry-After: 120"},{"line_number":54,"context_line":"            dt \u003d datetime.now() + timedelta(seconds\u003dint(retry_after_str))"},{"line_number":55,"context_line":"        else:"},{"line_number":56,"context_line":"            # Retry-After: Fri, 31 Dec 1999 23:59:59 GMT"},{"line_number":57,"context_line":"            dt \u003d parser.parse(retry_after_str)"},{"line_number":58,"context_line":"        return dt"},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"    @property"}],"source_content_type":"text/x-python","patch_set":2,"id":"7faddb67_d12d3afe","line":57,"range":{"start_line":52,"start_character":10,"end_line":57,"end_character":46},"in_reply_to":"7faddb67_96d34304","updated":"2019-07-18 23:28:36.000000000","message":"Agree. Will fix.","commit_id":"2e5bd26ed68cc703b810c4d12e5327a7be002d97"},{"author":{"_account_id":26340,"name":"Ilya Etingof","email":"etingof@gmail.com","username":"etingof"},"change_message_id":"ac58dea158225c51a8558534776dbc864d08cfdc","unresolved":false,"context_lines":[{"line_number":62,"context_line":"        return self._retry_after"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"    @property"},{"line_number":65,"context_line":"    def location_header(self):"},{"line_number":66,"context_line":"        return self._location_header"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"    def in_progress(self):"}],"source_content_type":"text/x-python","patch_set":2,"id":"7faddb67_16099394","line":65,"range":{"start_line":65,"start_character":8,"end_line":65,"end_character":23},"updated":"2019-07-18 08:25:55.000000000","message":"may be a docstring won\u0027t hurt?","commit_id":"2e5bd26ed68cc703b810c4d12e5327a7be002d97"},{"author":{"_account_id":28128,"name":"Bill Dodd","email":"billdodd@gmail.com","username":"billdodd"},"change_message_id":"5894ea5b116f384f738c5aa7c4e17555e3d17bf1","unresolved":false,"context_lines":[{"line_number":62,"context_line":"        return self._retry_after"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"    @property"},{"line_number":65,"context_line":"    def location_header(self):"},{"line_number":66,"context_line":"        return self._location_header"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"    def in_progress(self):"}],"source_content_type":"text/x-python","patch_set":2,"id":"7faddb67_113432dd","line":65,"range":{"start_line":65,"start_character":8,"end_line":65,"end_character":23},"in_reply_to":"7faddb67_16099394","updated":"2019-07-18 23:28:36.000000000","message":"Good point. Yes, will add docstring.","commit_id":"2e5bd26ed68cc703b810c4d12e5327a7be002d97"},{"author":{"_account_id":26340,"name":"Ilya Etingof","email":"etingof@gmail.com","username":"etingof"},"change_message_id":"ac58dea158225c51a8558534776dbc864d08cfdc","unresolved":false,"context_lines":[{"line_number":65,"context_line":"    def location_header(self):"},{"line_number":66,"context_line":"        return self._location_header"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"    def in_progress(self):"},{"line_number":69,"context_line":"        if not self._in_progress:"},{"line_number":70,"context_line":"            return False"},{"line_number":71,"context_line":"        r \u003d self._conn.get(self._path)"}],"source_content_type":"text/x-python","patch_set":2,"id":"7faddb67_360ccfa3","line":68,"range":{"start_line":68,"start_character":8,"end_line":68,"end_character":19},"updated":"2019-07-18 08:25:55.000000000","message":"ditto docstring","commit_id":"2e5bd26ed68cc703b810c4d12e5327a7be002d97"},{"author":{"_account_id":28128,"name":"Bill Dodd","email":"billdodd@gmail.com","username":"billdodd"},"change_message_id":"5894ea5b116f384f738c5aa7c4e17555e3d17bf1","unresolved":false,"context_lines":[{"line_number":65,"context_line":"    def location_header(self):"},{"line_number":66,"context_line":"        return self._location_header"},{"line_number":67,"context_line":""},{"line_number":68,"context_line":"    def in_progress(self):"},{"line_number":69,"context_line":"        if not self._in_progress:"},{"line_number":70,"context_line":"            return False"},{"line_number":71,"context_line":"        r \u003d self._conn.get(self._path)"}],"source_content_type":"text/x-python","patch_set":2,"id":"7faddb67_312fee88","line":68,"range":{"start_line":68,"start_character":8,"end_line":68,"end_character":19},"in_reply_to":"7faddb67_360ccfa3","updated":"2019-07-18 23:28:36.000000000","message":"Will do.","commit_id":"2e5bd26ed68cc703b810c4d12e5327a7be002d97"},{"author":{"_account_id":26340,"name":"Ilya Etingof","email":"etingof@gmail.com","username":"etingof"},"change_message_id":"9e34dcc8bc923c40488e6ceac3dc03a6ad452307","unresolved":false,"context_lines":[{"line_number":25,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"class TaskMonitor(base.ResourceBase):"},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"    def __init__(self,"},{"line_number":31,"context_line":"                 connector,"}],"source_content_type":"text/x-python","patch_set":4,"id":"7faddb67_9369b127","line":28,"updated":"2019-08-26 17:10:14.000000000","message":"I am confused as for what\u0027s the place of `TaskService` [1] and `Task` [2] resources?  Do we need to have them as sushy resource models?\n\n`TaskMonitor` seems to be derived from `ResourceBase` what implies it\u0027s a resource. However I can\u0027t find it among Redfish schemas. Also, `TaskMonitor` implementation does not have any fields.\n\n1. https://redfish.dmtf.org/schemas/v1/TaskService.v1_1_3.json\n2. https://redfish.dmtf.org/schemas/v1/Task.v1_4_1.json","commit_id":"d93114fa07674f440263ac63dccfc1430337a6fe"},{"author":{"_account_id":28128,"name":"Bill Dodd","email":"billdodd@gmail.com","username":"billdodd"},"change_message_id":"e5ec6ab6e5ea5d553dc76f51214569fa82730552","unresolved":false,"context_lines":[{"line_number":25,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"class TaskMonitor(base.ResourceBase):"},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"    def __init__(self,"},{"line_number":31,"context_line":"                 connector,"}],"source_content_type":"text/x-python","patch_set":4,"id":"5faad753_9e1c436b","line":28,"in_reply_to":"7faddb67_9369b127","updated":"2019-09-10 16:17:55.000000000","message":"The TaskService and Task resources could certainly be added to the sushy resource models. But for the typical use case of a client needing to determine if a request that it has made was handled asynchronously, utilizing the Task Monitor opaque URL is sufficient and the preferred approach. \n\nAs you noted, the Task Monitor does not have an associated resource (no JSON payload); all the information associated with the Task Monitor is provided via response headers (Location and Retry-After). I utilized the existing ResourceBase class because it was convenient to leverage its connection, access to response headers, etc. In a way, you can consider the Task Monitor a special case of a Redfish response that has an empty body payload.\n\nIf there is a better way to model the Task Monitor, I am certainly open to that.\n\nBack to the Task and TaskService: These resources are more important for more generalized use cases where a client may need to locate and monitor tasks that may have been created by different clients.","commit_id":"d93114fa07674f440263ac63dccfc1430337a6fe"},{"author":{"_account_id":26340,"name":"Ilya Etingof","email":"etingof@gmail.com","username":"etingof"},"change_message_id":"e48e47cd7b3c68c90ca42921f4a88848671d452a","unresolved":false,"context_lines":[{"line_number":52,"context_line":"            # Retry-After: Fri, 31 Dec 1999 23:59:59 GMT"},{"line_number":53,"context_line":"            return parser.parse(retry_after_str)"},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"    def set_retry_after(self, value):"},{"line_number":56,"context_line":"        self._retry_after \u003d self._to_datetime(value) if value else None"},{"line_number":57,"context_line":"        return self"},{"line_number":58,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"7faddb67_f30a651e","line":55,"updated":"2019-08-26 16:38:28.000000000","message":"We typically use TaskMonitor once we get HTTP 202 response. May be we could initialize `TaskMonitor` right from the response object instead of pulling pieces from it (e.g. retry-after\u0027) and passing alone?\n\nThe rationale is that we need to parse response object later on anyway (e.g.  `in_progress`) so may be we could do it once and for all?","commit_id":"d93114fa07674f440263ac63dccfc1430337a6fe"},{"author":{"_account_id":28128,"name":"Bill Dodd","email":"billdodd@gmail.com","username":"billdodd"},"change_message_id":"7ffd8d2a7d4e11ca85c99bfef87adafefaf29db4","unresolved":false,"context_lines":[{"line_number":52,"context_line":"            # Retry-After: Fri, 31 Dec 1999 23:59:59 GMT"},{"line_number":53,"context_line":"            return parser.parse(retry_after_str)"},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"    def set_retry_after(self, value):"},{"line_number":56,"context_line":"        self._retry_after \u003d self._to_datetime(value) if value else None"},{"line_number":57,"context_line":"        return self"},{"line_number":58,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"3fa7e38b_71425840","line":55,"in_reply_to":"5faad753_3e442f1b","updated":"2019-10-14 22:46:10.000000000","message":"In patch set 5 I updated connector.py to allow for blocking calls and utilized the TaskMonitor.","commit_id":"d93114fa07674f440263ac63dccfc1430337a6fe"},{"author":{"_account_id":28128,"name":"Bill Dodd","email":"billdodd@gmail.com","username":"billdodd"},"change_message_id":"e5ec6ab6e5ea5d553dc76f51214569fa82730552","unresolved":false,"context_lines":[{"line_number":52,"context_line":"            # Retry-After: Fri, 31 Dec 1999 23:59:59 GMT"},{"line_number":53,"context_line":"            return parser.parse(retry_after_str)"},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"    def set_retry_after(self, value):"},{"line_number":56,"context_line":"        self._retry_after \u003d self._to_datetime(value) if value else None"},{"line_number":57,"context_line":"        return self"},{"line_number":58,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"5faad753_3e442f1b","line":55,"in_reply_to":"7faddb67_f30a651e","updated":"2019-09-10 16:17:55.000000000","message":"This may well be a good idea. But I\u0027m not following exactly what you are suggesting. Could you elaborate a bit on what you mean by \"May be we could initialize `TaskMonitor` right from the response object instead of pulling pieces from it\"?","commit_id":"d93114fa07674f440263ac63dccfc1430337a6fe"},{"author":{"_account_id":26340,"name":"Ilya Etingof","email":"etingof@gmail.com","username":"etingof"},"change_message_id":"b1f8935f3898d7d714d3b9ebe83bcc4b8d50db7b","unresolved":false,"context_lines":[{"line_number":57,"context_line":"        return self"},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"    @property"},{"line_number":60,"context_line":"    def retry_after(self):"},{"line_number":61,"context_line":"        \"\"\"Time the client should wait before querying the operation status"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"        :return: The Retry-After time in `datetime` format"}],"source_content_type":"text/x-python","patch_set":4,"id":"7faddb67_bfbfd6fa","line":60,"updated":"2019-08-26 13:56:31.000000000","message":"It may be handy to also supply a property like `wait_for` returning seconds to sleep()","commit_id":"d93114fa07674f440263ac63dccfc1430337a6fe"},{"author":{"_account_id":28128,"name":"Bill Dodd","email":"billdodd@gmail.com","username":"billdodd"},"change_message_id":"7ffd8d2a7d4e11ca85c99bfef87adafefaf29db4","unresolved":false,"context_lines":[{"line_number":57,"context_line":"        return self"},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"    @property"},{"line_number":60,"context_line":"    def retry_after(self):"},{"line_number":61,"context_line":"        \"\"\"Time the client should wait before querying the operation status"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"        :return: The Retry-After time in `datetime` format"}],"source_content_type":"text/x-python","patch_set":4,"id":"3fa7e38b_3148605a","line":60,"in_reply_to":"5faad753_be5edf0f","updated":"2019-10-14 22:46:10.000000000","message":"done","commit_id":"d93114fa07674f440263ac63dccfc1430337a6fe"},{"author":{"_account_id":28128,"name":"Bill Dodd","email":"billdodd@gmail.com","username":"billdodd"},"change_message_id":"e5ec6ab6e5ea5d553dc76f51214569fa82730552","unresolved":false,"context_lines":[{"line_number":57,"context_line":"        return self"},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"    @property"},{"line_number":60,"context_line":"    def retry_after(self):"},{"line_number":61,"context_line":"        \"\"\"Time the client should wait before querying the operation status"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"        :return: The Retry-After time in `datetime` format"}],"source_content_type":"text/x-python","patch_set":4,"id":"5faad753_be5edf0f","line":60,"in_reply_to":"7faddb67_bfbfd6fa","updated":"2019-09-10 16:17:55.000000000","message":"Good idea. I can add that.","commit_id":"d93114fa07674f440263ac63dccfc1430337a6fe"},{"author":{"_account_id":26340,"name":"Ilya Etingof","email":"etingof@gmail.com","username":"etingof"},"change_message_id":"b1f8935f3898d7d714d3b9ebe83bcc4b8d50db7b","unresolved":false,"context_lines":[{"line_number":71,"context_line":"        :return: The Location header (an absolute URL)"},{"line_number":72,"context_line":"        \"\"\""},{"line_number":73,"context_line":"        return self._location_header"},{"line_number":74,"context_line":""},{"line_number":75,"context_line":"    def in_progress(self):"},{"line_number":76,"context_line":"        \"\"\"Checks the status of the async task"},{"line_number":77,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"7faddb67_df3df28e","line":74,"updated":"2019-08-26 13:56:31.000000000","message":"Can `in_progress` be a property?","commit_id":"d93114fa07674f440263ac63dccfc1430337a6fe"},{"author":{"_account_id":28128,"name":"Bill Dodd","email":"billdodd@gmail.com","username":"billdodd"},"change_message_id":"7ffd8d2a7d4e11ca85c99bfef87adafefaf29db4","unresolved":false,"context_lines":[{"line_number":71,"context_line":"        :return: The Location header (an absolute URL)"},{"line_number":72,"context_line":"        \"\"\""},{"line_number":73,"context_line":"        return self._location_header"},{"line_number":74,"context_line":""},{"line_number":75,"context_line":"    def in_progress(self):"},{"line_number":76,"context_line":"        \"\"\"Checks the status of the async task"},{"line_number":77,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"3fa7e38b_51439c3f","line":74,"in_reply_to":"5faad753_de7ddb1c","updated":"2019-10-14 22:46:10.000000000","message":"done","commit_id":"d93114fa07674f440263ac63dccfc1430337a6fe"},{"author":{"_account_id":28128,"name":"Bill Dodd","email":"billdodd@gmail.com","username":"billdodd"},"change_message_id":"e5ec6ab6e5ea5d553dc76f51214569fa82730552","unresolved":false,"context_lines":[{"line_number":71,"context_line":"        :return: The Location header (an absolute URL)"},{"line_number":72,"context_line":"        \"\"\""},{"line_number":73,"context_line":"        return self._location_header"},{"line_number":74,"context_line":""},{"line_number":75,"context_line":"    def in_progress(self):"},{"line_number":76,"context_line":"        \"\"\"Checks the status of the async task"},{"line_number":77,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"5faad753_de7ddb1c","line":74,"in_reply_to":"7faddb67_df3df28e","updated":"2019-09-10 16:17:55.000000000","message":"Yes, that makes sense.","commit_id":"d93114fa07674f440263ac63dccfc1430337a6fe"},{"author":{"_account_id":26340,"name":"Ilya Etingof","email":"etingof@gmail.com","username":"etingof"},"change_message_id":"b1f8935f3898d7d714d3b9ebe83bcc4b8d50db7b","unresolved":false,"context_lines":[{"line_number":72,"context_line":"        \"\"\""},{"line_number":73,"context_line":"        return self._location_header"},{"line_number":74,"context_line":""},{"line_number":75,"context_line":"    def in_progress(self):"},{"line_number":76,"context_line":"        \"\"\"Checks the status of the async task"},{"line_number":77,"context_line":""},{"line_number":78,"context_line":"        :return: True if the async task is still in progress, False otherwise"}],"source_content_type":"text/x-python","patch_set":4,"id":"7faddb67_dfc892a9","line":75,"updated":"2019-08-26 13:56:31.000000000","message":"Would it make sense to also have a blocking method like this:\n\n    def wait(timeout\u003d60):\n        blowup_at \u003d time() + timeout\n\n        while self.in_progress():\n             sleep(min(timeout, self.retry_after - time()))\n             if time() \u003e\u003d blowup_at:\n                 raise\n \nThe use case I run across is exactly this ^. So may be if we would supply it, that would benefit more than one client?\n\nI assume this will automatically work asynchronously with eventlet in place.","commit_id":"d93114fa07674f440263ac63dccfc1430337a6fe"},{"author":{"_account_id":28128,"name":"Bill Dodd","email":"billdodd@gmail.com","username":"billdodd"},"change_message_id":"7ffd8d2a7d4e11ca85c99bfef87adafefaf29db4","unresolved":false,"context_lines":[{"line_number":72,"context_line":"        \"\"\""},{"line_number":73,"context_line":"        return self._location_header"},{"line_number":74,"context_line":""},{"line_number":75,"context_line":"    def in_progress(self):"},{"line_number":76,"context_line":"        \"\"\"Checks the status of the async task"},{"line_number":77,"context_line":""},{"line_number":78,"context_line":"        :return: True if the async task is still in progress, False otherwise"}],"source_content_type":"text/x-python","patch_set":4,"id":"3fa7e38b_d170eca6","line":75,"in_reply_to":"5faad753_fe1f776d","updated":"2019-10-14 22:46:10.000000000","message":"I think patch set 5 addresses this.","commit_id":"d93114fa07674f440263ac63dccfc1430337a6fe"},{"author":{"_account_id":26340,"name":"Ilya Etingof","email":"etingof@gmail.com","username":"etingof"},"change_message_id":"e9899e04f0d6bc4d2069229211f847c3b4488bdf","unresolved":false,"context_lines":[{"line_number":72,"context_line":"        \"\"\""},{"line_number":73,"context_line":"        return self._location_header"},{"line_number":74,"context_line":""},{"line_number":75,"context_line":"    def in_progress(self):"},{"line_number":76,"context_line":"        \"\"\"Checks the status of the async task"},{"line_number":77,"context_line":""},{"line_number":78,"context_line":"        :return: True if the async task is still in progress, False otherwise"}],"source_content_type":"text/x-python","patch_set":4,"id":"7faddb67_ff478e76","line":75,"in_reply_to":"7faddb67_dfc892a9","updated":"2019-08-26 14:27:23.000000000","message":"Another example use-case:\n\n    def some_possibly_async_call(..., blocking\u003dTrue):\n        ...\n\n        response \u003d conn.post(post_url, data)\n\n        if not blocking:\n            return response\n\n        task_manager \u003d TaskManager(...)\n\n        return task_manager.wait_for(response, timeout\u003d123)\n\nIn theory, any Redfish call may or may not become asynchronous depending on the server. That means that may be in sushy we should probably wrap all sushy calls with `TaskMonitor` so that it can kick-in in case of async response....\n\nMay be some sort of decorator or context manager or at least some high-level method of task monitor (like I proposed in other comments) would be handy for such mass-wrapping...","commit_id":"d93114fa07674f440263ac63dccfc1430337a6fe"},{"author":{"_account_id":28128,"name":"Bill Dodd","email":"billdodd@gmail.com","username":"billdodd"},"change_message_id":"e5ec6ab6e5ea5d553dc76f51214569fa82730552","unresolved":false,"context_lines":[{"line_number":72,"context_line":"        \"\"\""},{"line_number":73,"context_line":"        return self._location_header"},{"line_number":74,"context_line":""},{"line_number":75,"context_line":"    def in_progress(self):"},{"line_number":76,"context_line":"        \"\"\"Checks the status of the async task"},{"line_number":77,"context_line":""},{"line_number":78,"context_line":"        :return: True if the async task is still in progress, False otherwise"}],"source_content_type":"text/x-python","patch_set":4,"id":"5faad753_fe1f776d","line":75,"in_reply_to":"7faddb67_ff478e76","updated":"2019-09-10 16:17:55.000000000","message":"Good points about a blocking call in the above 2 comments. And the specific examples/use-cases are very helpful. Let me think about these some more...","commit_id":"d93114fa07674f440263ac63dccfc1430337a6fe"},{"author":{"_account_id":26340,"name":"Ilya Etingof","email":"etingof@gmail.com","username":"etingof"},"change_message_id":"0651355e5d2dc191804bc71467eba11f5e477df5","unresolved":false,"context_lines":[{"line_number":84,"context_line":"        if r.status_code \u003d\u003d 202:"},{"line_number":85,"context_line":"            self.set_retry_after(r.headers.get(\u0027retry-after\u0027))"},{"line_number":86,"context_line":"        self._in_progress \u003d True if r.status_code \u003d\u003d 202 else False"},{"line_number":87,"context_line":"        return self._in_progress"}],"source_content_type":"text/x-python","patch_set":4,"id":"7faddb67_1576090e","line":87,"updated":"2019-08-26 15:33:58.000000000","message":"It seems we lose both the final response and resource identifier that should be supplied with 202 response. Here\u0027s what Redfish says:\n\n    Once the operation has completed, the Task Monitor shall \n    return a the appropriate status code ( OK 200 for most operations, \n    Created 201 for POST to create a resource) and include the headers \n    and response body of the initial operation, as if it had completed \n    synchronously. If the initial operation resulted in an error, the body \n    of the response shall contain an Error Response.\n\n    The client can continue to get information about the status by directly \n    querying the Task resource using the resource identifier returned in the \n    body of the 202 (Accepted) response.\n\nMay be we should return something else beyond `bool`?","commit_id":"d93114fa07674f440263ac63dccfc1430337a6fe"},{"author":{"_account_id":28128,"name":"Bill Dodd","email":"billdodd@gmail.com","username":"billdodd"},"change_message_id":"7ffd8d2a7d4e11ca85c99bfef87adafefaf29db4","unresolved":false,"context_lines":[{"line_number":84,"context_line":"        if r.status_code \u003d\u003d 202:"},{"line_number":85,"context_line":"            self.set_retry_after(r.headers.get(\u0027retry-after\u0027))"},{"line_number":86,"context_line":"        self._in_progress \u003d True if r.status_code \u003d\u003d 202 else False"},{"line_number":87,"context_line":"        return self._in_progress"}],"source_content_type":"text/x-python","patch_set":4,"id":"3fa7e38b_f19c08c1","line":87,"in_reply_to":"5faad753_3ebbcf72","updated":"2019-10-14 22:46:10.000000000","message":"In patch set 5 I added a `response` property to get the response.","commit_id":"d93114fa07674f440263ac63dccfc1430337a6fe"},{"author":{"_account_id":28128,"name":"Bill Dodd","email":"billdodd@gmail.com","username":"billdodd"},"change_message_id":"e5ec6ab6e5ea5d553dc76f51214569fa82730552","unresolved":false,"context_lines":[{"line_number":84,"context_line":"        if r.status_code \u003d\u003d 202:"},{"line_number":85,"context_line":"            self.set_retry_after(r.headers.get(\u0027retry-after\u0027))"},{"line_number":86,"context_line":"        self._in_progress \u003d True if r.status_code \u003d\u003d 202 else False"},{"line_number":87,"context_line":"        return self._in_progress"}],"source_content_type":"text/x-python","patch_set":4,"id":"5faad753_3ebbcf72","line":87,"in_reply_to":"7faddb67_1576090e","updated":"2019-09-10 16:17:55.000000000","message":"Good point about losing the response once the operation has completed. Maybe still return a boolean for `in_progress`, but also save the response and have another method/property that the returns the response?","commit_id":"d93114fa07674f440263ac63dccfc1430337a6fe"},{"author":{"_account_id":26340,"name":"Ilya Etingof","email":"etingof@gmail.com","username":"etingof"},"change_message_id":"d805e3a8c944d6da22396eceef83ca5f12dae253","unresolved":false,"context_lines":[{"line_number":56,"context_line":"    def set_retry_after(self, value):"},{"line_number":57,"context_line":"        \"\"\"Set the time the client should wait before querying the task status"},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"        :param value: The value of the Retry-After header"},{"line_number":60,"context_line":"        :return: The TaskMonitor object"},{"line_number":61,"context_line":"        \"\"\""},{"line_number":62,"context_line":"        self._retry_after \u003d self._to_datetime(value or 1)"}],"source_content_type":"text/x-python","patch_set":5,"id":"3fa7e38b_0b908c42","line":59,"range":{"start_line":59,"start_character":39,"end_line":59,"end_character":50},"updated":"2019-11-01 11:44:59.000000000","message":"This reads obscure to me. May be describe more explicitly what kind of value is expected here?","commit_id":"1f91497a3d091e78735e6194720851215c736575"},{"author":{"_account_id":28128,"name":"Bill Dodd","email":"billdodd@gmail.com","username":"billdodd"},"change_message_id":"720e58fcb8d07a8c65de5acbb28137d58ddc16f2","unresolved":false,"context_lines":[{"line_number":56,"context_line":"    def set_retry_after(self, value):"},{"line_number":57,"context_line":"        \"\"\"Set the time the client should wait before querying the task status"},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"        :param value: The value of the Retry-After header"},{"line_number":60,"context_line":"        :return: The TaskMonitor object"},{"line_number":61,"context_line":"        \"\"\""},{"line_number":62,"context_line":"        self._retry_after \u003d self._to_datetime(value or 1)"}],"source_content_type":"text/x-python","patch_set":5,"id":"3fa7e38b_5e493564","line":59,"range":{"start_line":59,"start_character":39,"end_line":59,"end_character":50},"in_reply_to":"3fa7e38b_0b908c42","updated":"2019-11-05 21:26:24.000000000","message":"Done","commit_id":"1f91497a3d091e78735e6194720851215c736575"},{"author":{"_account_id":26340,"name":"Ilya Etingof","email":"etingof@gmail.com","username":"etingof"},"change_message_id":"d805e3a8c944d6da22396eceef83ca5f12dae253","unresolved":false,"context_lines":[{"line_number":99,"context_line":"        self._location_header \u003d r.headers.get(\u0027location\u0027)"},{"line_number":100,"context_line":"        if r.status_code \u003d\u003d 202:"},{"line_number":101,"context_line":"            self.set_retry_after(r.headers.get(\u0027retry-after\u0027))"},{"line_number":102,"context_line":"        self._in_progress \u003d True if r.status_code \u003d\u003d 202 else False"},{"line_number":103,"context_line":"        return self._in_progress"},{"line_number":104,"context_line":""},{"line_number":105,"context_line":"    @property"}],"source_content_type":"text/x-python","patch_set":5,"id":"3fa7e38b_4b744436","line":102,"updated":"2019-11-01 11:44:59.000000000","message":"nit: this assignment could be moved under the `if` condition above","commit_id":"1f91497a3d091e78735e6194720851215c736575"},{"author":{"_account_id":28128,"name":"Bill Dodd","email":"billdodd@gmail.com","username":"billdodd"},"change_message_id":"720e58fcb8d07a8c65de5acbb28137d58ddc16f2","unresolved":false,"context_lines":[{"line_number":99,"context_line":"        self._location_header \u003d r.headers.get(\u0027location\u0027)"},{"line_number":100,"context_line":"        if r.status_code \u003d\u003d 202:"},{"line_number":101,"context_line":"            self.set_retry_after(r.headers.get(\u0027retry-after\u0027))"},{"line_number":102,"context_line":"        self._in_progress \u003d True if r.status_code \u003d\u003d 202 else False"},{"line_number":103,"context_line":"        return self._in_progress"},{"line_number":104,"context_line":""},{"line_number":105,"context_line":"    @property"}],"source_content_type":"text/x-python","patch_set":5,"id":"3fa7e38b_7e7751a1","line":102,"in_reply_to":"3fa7e38b_4b744436","updated":"2019-11-05 21:26:24.000000000","message":"Yes, the extra \u0027r.status_code \u003d\u003d 202\u0027 is redundant. I moved the assignment under `else` condition.","commit_id":"1f91497a3d091e78735e6194720851215c736575"},{"author":{"_account_id":26340,"name":"Ilya Etingof","email":"etingof@gmail.com","username":"etingof"},"change_message_id":"d805e3a8c944d6da22396eceef83ca5f12dae253","unresolved":false,"context_lines":[{"line_number":106,"context_line":"    def response(self):"},{"line_number":107,"context_line":"        \"\"\"The response from the last TaskMonitor in_progress check"},{"line_number":108,"context_line":""},{"line_number":109,"context_line":"        :return: The response"},{"line_number":110,"context_line":"        \"\"\""},{"line_number":111,"context_line":"        return self._response"}],"source_content_type":"text/x-python","patch_set":5,"id":"3fa7e38b_ab79382f","line":109,"range":{"start_line":109,"start_character":21,"end_line":109,"end_character":29},"updated":"2019-11-01 11:44:59.000000000","message":"nit: either `requests` response object or None","commit_id":"1f91497a3d091e78735e6194720851215c736575"},{"author":{"_account_id":28128,"name":"Bill Dodd","email":"billdodd@gmail.com","username":"billdodd"},"change_message_id":"720e58fcb8d07a8c65de5acbb28137d58ddc16f2","unresolved":false,"context_lines":[{"line_number":106,"context_line":"    def response(self):"},{"line_number":107,"context_line":"        \"\"\"The response from the last TaskMonitor in_progress check"},{"line_number":108,"context_line":""},{"line_number":109,"context_line":"        :return: The response"},{"line_number":110,"context_line":"        \"\"\""},{"line_number":111,"context_line":"        return self._response"}],"source_content_type":"text/x-python","patch_set":5,"id":"3fa7e38b_1e6c1dcf","line":109,"range":{"start_line":109,"start_character":21,"end_line":109,"end_character":29},"in_reply_to":"3fa7e38b_ab79382f","updated":"2019-11-05 21:26:24.000000000","message":"Done","commit_id":"1f91497a3d091e78735e6194720851215c736575"}]}
