)]}'
{"openstack/block_storage/v3/_proxy.py":[{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"9d7cecb12589ffeb5e767a3ba3a5502b4a5d08c6","unresolved":true,"context_lines":[{"line_number":493,"context_line":"        :returns: A list of messages"},{"line_number":494,"context_line":"        :rtype: :class:`~openstack.block_storage.v3.messages.Messages`"},{"line_number":495,"context_line":"        \"\"\""},{"line_number":496,"context_line":"        return self._get(_messages.Messages)"},{"line_number":497,"context_line":""},{"line_number":498,"context_line":"    def availability_zones(self):"},{"line_number":499,"context_line":"        \"\"\"Return a generator of availability zones"}],"source_content_type":"text/x-python","patch_set":5,"id":"eaf98fbb_63cd3fe3","line":496,"updated":"2021-03-23 17:30:42.000000000","message":"I think you\u0027re muddling different things here. I appreciate that there are layers of indirection here so hopefully this will help. Apologies for the wall of text.\n\nEverything inside these \u0027_proxy\u0027 files can be thought of a \"helper\" or syntactic sugar. They let you do stuff like this:\n\n  \u003e\u003e\u003e import openstack\n  \u003e\u003e\u003e conn \u003d openstack.connect()\n  \u003e\u003e\u003e conn.block_storage.availability_zones()\n  [openstack.block_storage.v3.availability_zone.AvailabilityZone(zoneName\u003dnova, zoneState\u003d{\u0027available\u0027: True}, location\u003dMunch({\u0027cloud\u0027: \u0027envvars\u0027, \u0027region_name\u0027: \u0027RegionOne\u0027, \u0027zone\u0027: None, \u0027project\u0027: Munch({\u0027id\u0027: \u0027742ec5fd9b97453ba33643d8306e8a7b\u0027, \u0027name\u0027: \u0027demo\u0027, \u0027domain_id\u0027: \u0027default\u0027, \u0027domain_name\u0027: None})}))]\n\nBy comparison, this is what you need to do if you don\u0027t use this (you could of course simplify this and abstract it, but you get the idea):\n\n  \u003e\u003e\u003e from keystoneauth1.identity import v3\n  \u003e\u003e\u003e import keystoneauth1.session\n  \u003e\u003e\u003e from keystoneclient.v3 import client\n  \u003e\u003e\u003e from openstack.block_storage.v3 import availability_zone\n  \u003e\u003e\u003e import openstack.proxy\n  \u003e\u003e\u003e auth \u003d v3.Password(auth_url\u003d\u0027http://172.20.4.155/identity\u0027, username\u003d\u0027admin\u0027, password\u003d\u0027password\u0027, project_name\u003d\u0027demo\u0027, user_domain_id\u003d\u0027default\u0027, project_domain_id\u003d\u0027default\u0027)\n  \u003e\u003e\u003e session \u003d keystoneauth1.session.Session(auth\u003dauth)\n  \u003e\u003e\u003e proxy \u003d openstack.proxy.Proxy(session\u003dsession, service_type\u003d\u0027block-storage\u0027, interface\u003d\u0027public\u0027, version\u003d3)\n  \u003e\u003e\u003e list(availability_zone.AvailabilityZone.list(session\u003dadapter))\n  [openstack.block_storage.v3.availability_zone.AvailabilityZone(zoneName\u003dnova, zoneState\u003d{\u0027available\u0027: True})]\n\nSo you can see why a normal user would want the proxy APIs 😉 Anywho, from the above we can see that we map the \u0027list\u0027 method of the resource, \u0027AvailabilityZone\u0027, to the \u0027availability_zones\u0027 proxy method, i.e.\n\n  \u003e\u003e\u003e conn.block_storage.availability_zones()\n\nmaps to and returns pretty much the same information as:\n\n  \u003e\u003e\u003e availability_zone.AvailabilityZone.list(session\u003dadapter)\n\nThe way this mapping happens is by the \u0027availability_zones\u0027 proxy method calling the \u0027_list\u0027 helper with the \u0027AvailabilityZone\u0027 class as an argument and isn\u0027t really something we really need to worry about here. Ultimately, the rule is:\n\n- availability_zones -\u003e AvailabilityZone.list  (via the \u0027_list\u0027 helper)\n\nOr, put more generically:\n\n- resources -\u003e Resource.list  (via the \u0027_list\u0027 helper)\n\nYou\u0027ll also notice that there are no other availability zone-related proxy methods. That\u0027s because the \u0027AvailabilityZone\u0027 resource type has only specified \u0027allow_list \u003d True\u0027, leaving the other methods to their default of \u0027False\u0027.\n\n  # capabilities\n  allow_list \u003d True\n\nUltimately this is done because the \u0027/os-availability-zone\u0027 (apparently - it\u0027s not documented) only supports the list operation, i.e. \u0027GET /os-availability-zone\u0027 and not things like \u0027GET /os-availability-zone/{id}\u0027. However, that\u0027s not the case for everything. Look at snapshots. There are no less than four snapshot-related methods here: \u0027create_snapshot\u0027, \u0027delete_snapshot\u0027, \u0027get_snapshot\u0027, \u0027find_snapshot\u0027, and \u0027snapshots\u0027. Those all ultimately map to methods on the \u0027Snapshot\u0027 resource in \u0027openstack.block_storage.v3.snapshot\u0027:\n\n- create_snapshot -\u003e Snapshot.create  (via the \u0027_create\u0027 helper)\n- delete_snapshot -\u003e Snapshot.delete  (via the \u0027_delete\u0027 helper)\n- get_snapshot -\u003e Snapshot.fetch  (via the \u0027_get\u0027 helper)\n- find_snapshot -\u003e Snapshot.find  (via the \u0027_find\u0027 helper)\n- snapshots -\u003e Snapshot.list  (via the \u0027_list\u0027 helper)\n\nAnd if you look at the \u0027Snapshot\u0027 resource, you\u0027ll see they\u0027re all supported:\n\n  # capabilities\n  allow_fetch \u003d True\n  allow_create \u003d True\n  allow_delete \u003d True\n  allow_commit \u003d True\n  allow_list \u003d True\n\nContrast this to your resource which has the following:\n\n  allow_fetch \u003d True\n  allow_delete \u003d True\n  allow_list \u003d True\n\nYou currently only have the one method here, \u0027get_messages\u0027. Do you think (a) that this is named correctly and (b) that this is the only helper we need?","commit_id":"4670022ab7b8c340d4d1d33aaabe3b604267a485"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"3e9ca1d33ea55ff3c3d12e071dffe2ca376eb33f","unresolved":true,"context_lines":[{"line_number":545,"context_line":"        \"\"\"Get a message"},{"line_number":546,"context_line":""},{"line_number":547,"context_line":"        :param message: The value can be the ID of a message or a"},{"line_number":548,"context_line":"                    :class:`~openstack.block_storage.v3.message.Message`"},{"line_number":549,"context_line":"                    instance."},{"line_number":550,"context_line":""},{"line_number":551,"context_line":"        :returns: Message instance"}],"source_content_type":"text/x-python","patch_set":11,"id":"78af68a5_8126ff0b","line":548,"range":{"start_line":548,"start_character":12,"end_line":548,"end_character":20},"updated":"2021-05-12 14:03:59.000000000","message":"nit","commit_id":"22e945aad8361d1d899597510d26676e38f1d106"}],"openstack/block_storage/v3/messages.py":[{"author":{"_account_id":27900,"name":"Artem Goncharov","email":"artem.goncharov@gmail.com","username":"gtema"},"change_message_id":"3ee84b68182d447ec7996558c34c4ac7e2d9c661","unresolved":true,"context_lines":[{"line_number":29,"context_line":""},{"line_number":30,"context_line":"    #: Properties"},{"line_number":31,"context_line":"    #: The id of the request during which the message was created."},{"line_number":32,"context_line":"    request_id \u003d resource.Body(\"request_id\", type\u003dstr)"},{"line_number":33,"context_line":"    #: Links for the message."},{"line_number":34,"context_line":"    links \u003d resource.Body(\"message_level\", type\u003dlist)"},{"line_number":35,"context_line":"    #: The level of the message, possible value is only ‘ERROR’ now."}],"source_content_type":"text/x-python","patch_set":1,"id":"7dee6e16_cb8fd4e0","line":32,"updated":"2021-02-25 14:21:11.000000000","message":"Please sort attributes alphabetically","commit_id":"a3995a07ef302021169ca384dc21172f0595ab8d"},{"author":{"_account_id":27900,"name":"Artem Goncharov","email":"artem.goncharov@gmail.com","username":"gtema"},"change_message_id":"3ee84b68182d447ec7996558c34c4ac7e2d9c661","unresolved":true,"context_lines":[{"line_number":31,"context_line":"    #: The id of the request during which the message was created."},{"line_number":32,"context_line":"    request_id \u003d resource.Body(\"request_id\", type\u003dstr)"},{"line_number":33,"context_line":"    #: Links for the message."},{"line_number":34,"context_line":"    links \u003d resource.Body(\"message_level\", type\u003dlist)"},{"line_number":35,"context_line":"    #: The level of the message, possible value is only ‘ERROR’ now."},{"line_number":36,"context_line":"    message_level \u003d resource.Body(\"message_level\", type\u003dstr)"},{"line_number":37,"context_line":"    #: The id of the event to this message."}],"source_content_type":"text/x-python","patch_set":1,"id":"6393b81e_12868b51","line":34,"updated":"2021-02-25 14:21:11.000000000","message":"You do not need to define id, name, links explicitly. Those are attrs already defined in resource.Resource you inherit from or are not required/consumed on their own (links)","commit_id":"a3995a07ef302021169ca384dc21172f0595ab8d"},{"author":{"_account_id":27900,"name":"Artem Goncharov","email":"artem.goncharov@gmail.com","username":"gtema"},"change_message_id":"3ee84b68182d447ec7996558c34c4ac7e2d9c661","unresolved":true,"context_lines":[{"line_number":39,"context_line":"    #: The date and time when the resource was created. "},{"line_number":40,"context_line":"    #: Format is ISO 8601: CCYY-MM-DDThh:mm:ss±hh:mm"},{"line_number":41,"context_line":"    #: Example: 2015-08-27T09:49:58-05:00"},{"line_number":42,"context_line":"    created_at \u003d resource.Body(\"message_level\", type\u003dstr)"},{"line_number":43,"context_line":"    #: The expire time of the message, message could be deleted after this time."},{"line_number":44,"context_line":"    guaranteed_until \u003d resource.Body(\"message_level\", type\u003dstr)"},{"line_number":45,"context_line":"    #: The UUID of the resource during whose operation the message was created."}],"source_content_type":"text/x-python","patch_set":1,"id":"6a79bd5f_d653954a","line":42,"updated":"2021-02-25 14:21:11.000000000","message":"in nearly every attribute you use same \"message_level\" server side attribute name. It should not be like that","commit_id":"a3995a07ef302021169ca384dc21172f0595ab8d"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"9d7cecb12589ffeb5e767a3ba3a5502b4a5d08c6","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":5,"id":"28bc74a0_ce590630","updated":"2021-03-23 17:30:42.000000000","message":"The naming convention for these files is usually singular, not plural.","commit_id":"4670022ab7b8c340d4d1d33aaabe3b604267a485"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"9d7cecb12589ffeb5e767a3ba3a5502b4a5d08c6","unresolved":true,"context_lines":[{"line_number":14,"context_line":"from openstack import resource"},{"line_number":15,"context_line":""},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"class Messages(resource.Resource):"},{"line_number":18,"context_line":"    resource_key \u003d \"messages\""},{"line_number":19,"context_line":"    resources_key \u003d \"messages\""},{"line_number":20,"context_line":"    base_path \u003d \"/messages\""}],"source_content_type":"text/x-python","patch_set":5,"id":"143dd7b3_70cf09d0","line":17,"range":{"start_line":17,"start_character":6,"end_line":17,"end_character":14},"updated":"2021-03-23 17:30:42.000000000","message":"As above, we use singular to refer to resources. Notice how the subclass is called \u0027Resource\u0027, not \u0027Resources\u0027","commit_id":"4670022ab7b8c340d4d1d33aaabe3b604267a485"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"9d7cecb12589ffeb5e767a3ba3a5502b4a5d08c6","unresolved":true,"context_lines":[{"line_number":26,"context_line":"    allow_fetch \u003d True"},{"line_number":27,"context_line":"    allow_delete \u003d True"},{"line_number":28,"context_line":"    allow_list \u003d True"},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"    #: Properties"},{"line_number":31,"context_line":"    #: The date and time when the resource was created."},{"line_number":32,"context_line":"    #: Format is ISO 8601: CCYY-MM-DDThh:mm:ss±hh:mm"}],"source_content_type":"text/x-python","patch_set":5,"id":"ed8a0c97_fb7bea2e","line":29,"updated":"2021-03-23 17:30:42.000000000","message":"The API ref doesn\u0027t make this clear but this was only added in API microversion 3.3. As such, you need to add the following here:\n\n  _max_microversion \u003d \u00273.3\u0027\n\nto tell openstacksdk to request the microversion.\n\n(yes, this is daft and one would expect to be using a \u0027_min_microversion\u0027 variable instead, but that seems to be a gap or oversight)","commit_id":"4670022ab7b8c340d4d1d33aaabe3b604267a485"}],"openstack/tests/functional/block_storage/v3/test_message.py":[{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"3e9ca1d33ea55ff3c3d12e071dffe2ca376eb33f","unresolved":true,"context_lines":[{"line_number":17,"context_line":"class TestMessage(base.BaseBlockStorageTest):"},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"    def test_get(self):"},{"line_number":20,"context_line":"        message \u003d self.conn.block_storage.get_message(self.MESSAGE_ID)"},{"line_number":21,"context_line":"        self.assertEqual(self.MESSAGE_NAME, message.name)"}],"source_content_type":"text/x-python","patch_set":11,"id":"cf6307a6_f2e34452","line":20,"range":{"start_line":20,"start_character":54,"end_line":20,"end_character":69},"updated":"2021-05-12 14:03:59.000000000","message":"The issue here is because this doesn\u0027t exist attribute isn\u0027t defined. I don\u0027t know what we could define it as since you can\u0027t create a message. Perhaps we could live without these functional tests?","commit_id":"22e945aad8361d1d899597510d26676e38f1d106"}],"openstack/tests/unit/block_storage/v3/test_messages.py":[{"author":{"_account_id":27900,"name":"Artem Goncharov","email":"artem.goncharov@gmail.com","username":"gtema"},"change_message_id":"3ee84b68182d447ec7996558c34c4ac7e2d9c661","unresolved":false,"context_lines":[{"line_number":17,"context_line":"    \"request_id\": \"req-c1216709-afba-4703-a1a3-22eda88f2f5a\","},{"line_number":18,"context_line":"    \"links\": ["},{"line_number":19,"context_line":"        {"},{"line_number":20,"context_line":"            \"href\": \"http://localhost:8776/v3/cd609134301246f0a3faa9c3da22082e/messages/c506cd4b-9048-43bc-97ef-0d7dec369b42\","},{"line_number":21,"context_line":"            \"rel\": \"self\""},{"line_number":22,"context_line":"        },"},{"line_number":23,"context_line":"        {"}],"source_content_type":"text/x-python","patch_set":1,"id":"afab5d96_3d29bb04","line":20,"updated":"2021-02-25 14:21:11.000000000","message":"it is absolutely ok to strip it down. We do not really care of the content in the json, we just verify our attributes return what we\u0027ve got from API","commit_id":"a3995a07ef302021169ca384dc21172f0595ab8d"},{"author":{"_account_id":27900,"name":"Artem Goncharov","email":"artem.goncharov@gmail.com","username":"gtema"},"change_message_id":"3ee84b68182d447ec7996558c34c4ac7e2d9c661","unresolved":false,"context_lines":[{"line_number":47,"context_line":"        self.assertFalse(limit_resource.allow_create)"},{"line_number":48,"context_line":"        self.assertFalse(limit_resource.allow_commit)"},{"line_number":49,"context_line":"        self.assertTrue(limit_resource.allow_delete)"},{"line_number":50,"context_line":"        self.assertTrue(limit_resource.allow_list)"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"    def test_make_messages(self):"},{"line_number":53,"context_line":"        self.assertEqual("}],"source_content_type":"text/x-python","patch_set":1,"id":"a744b9c6_6cd8b057","line":50,"updated":"2021-02-25 14:21:11.000000000","message":"You also missed to verify the query parameters (https://opendev.org/openstack/openstacksdk/src/branch/master/openstack/tests/unit/block_storage/v3/test_backup.py#L70 as example)","commit_id":"a3995a07ef302021169ca384dc21172f0595ab8d"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"9d7cecb12589ffeb5e767a3ba3a5502b4a5d08c6","unresolved":true,"context_lines":[{"line_number":13,"context_line":"from openstack.block_storage.v3 import messages"},{"line_number":14,"context_line":"from openstack.tests.unit import base"},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"MESSAGES \u003d {"},{"line_number":17,"context_line":"    \"request_id\": \"req-c1216709-afba-4703-a1a3-22eda88f2f5a\","},{"line_number":18,"context_line":"    \"links\": ["},{"line_number":19,"context_line":"        {"}],"source_content_type":"text/x-python","patch_set":5,"id":"786dc656_2125365c","line":16,"range":{"start_line":16,"start_character":0,"end_line":16,"end_character":8},"updated":"2021-03-23 17:30:42.000000000","message":"MESSAGE","commit_id":"4670022ab7b8c340d4d1d33aaabe3b604267a485"}]}
