[ARVADOS] created: 2f64531d89bf8c2a940ebe27f492b28464b14bee

git at public.curoverse.com git at public.curoverse.com
Sun May 24 18:27:10 EDT 2015


        at  2f64531d89bf8c2a940ebe27f492b28464b14bee (commit)


commit 2f64531d89bf8c2a940ebe27f492b28464b14bee
Author: Brett Smith <brett at curoverse.com>
Date:   Fri May 22 17:10:37 2015 -0400

    6095: arv-copy preserves order of copied JSON.
    
    This means arv-copy no longer loses the order of pipeline template
    components, which makes for a nicer presentation in Workbench.
    
    Other Python clients that would like to preserve the order of JSON
    responses can use OrderedJsonModel the same way.

diff --git a/sdk/python/arvados/api.py b/sdk/python/arvados/api.py
index 3968f01..48e73f3 100644
--- a/sdk/python/arvados/api.py
+++ b/sdk/python/arvados/api.py
@@ -1,3 +1,4 @@
+import collections
 import httplib2
 import json
 import logging
@@ -14,6 +15,26 @@ import util
 
 _logger = logging.getLogger('arvados.api')
 
+class OrderedJsonModel(apiclient.model.JsonModel):
+    """Model class for JSON that preserves the contents' order.
+
+    API clients that care about preserving the order of fields in API
+    server responses can use this model to do so, like this::
+
+        from arvados.api import OrderedJsonModel
+        client = arvados.api('v1', ..., model=OrderedJsonModel())
+    """
+
+    def deserialize(self, content):
+        # This is a very slightly modified version of the parent class'
+        # implementation.  Copyright (c) 2010 Google.
+        content = content.decode('utf-8')
+        body = json.loads(content, object_pairs_hook=collections.OrderedDict)
+        if self._data_wrapper and isinstance(body, dict) and 'data' in body:
+            body = body['data']
+        return body
+
+
 def _intercept_http_request(self, uri, **kwargs):
     from httplib import BadStatusLine
 
diff --git a/sdk/python/arvados/commands/arv_copy.py b/sdk/python/arvados/commands/arv_copy.py
index c64b645..1d10b04 100755
--- a/sdk/python/arvados/commands/arv_copy.py
+++ b/sdk/python/arvados/commands/arv_copy.py
@@ -32,6 +32,8 @@ import arvados.util
 import arvados.commands._util as arv_cmd
 import arvados.commands.keepdocker
 
+from arvados.api import OrderedJsonModel
+
 logger = logging.getLogger('arvados.arv-copy')
 
 # local_repo_dir records which git repositories from the Arvados source
@@ -180,7 +182,8 @@ def api_for_instance(instance_name):
         client = arvados.api('v1',
                              host=cfg['ARVADOS_API_HOST'],
                              token=cfg['ARVADOS_API_TOKEN'],
-                             insecure=api_is_insecure)
+                             insecure=api_is_insecure,
+                             model=OrderedJsonModel())
     else:
         abort('need ARVADOS_API_HOST and ARVADOS_API_TOKEN for {}'.format(instance_name))
     return client
diff --git a/sdk/python/tests/test_api.py b/sdk/python/tests/test_api.py
index faaaac3..9d438e2 100644
--- a/sdk/python/tests/test_api.py
+++ b/sdk/python/tests/test_api.py
@@ -1,14 +1,17 @@
 #!/usr/bin/env python
 
 import arvados
+import collections
 import httplib2
 import json
 import mimetypes
 import os
 import run_test_server
+import string
 import unittest
 from apiclient import errors as apiclient_errors
 from apiclient import http as apiclient_http
+from arvados.api import OrderedJsonModel
 
 from arvados_testutil import fake_httplib2_response
 
@@ -107,6 +110,21 @@ class ArvadosApiClientTest(unittest.TestCase):
             text = "X" * maxsize
             arvados.api('v1').collections().create(body={"manifest_text": text}).execute()
 
+    def test_ordered_json_model(self):
+        mock_responses = {
+            'arvados.humans.get': (None, json.dumps(collections.OrderedDict(
+                        (c, int(c, 16)) for c in string.hexdigits))),
+            }
+        req_builder = apiclient_http.RequestMockBuilder(mock_responses)
+        api = arvados.api('v1',
+                          host=os.environ['ARVADOS_API_HOST'],
+                          token='discovery-doc-only-no-token-needed',
+                          insecure=True,
+                          requestBuilder=req_builder,
+                          model=OrderedJsonModel())
+        result = api.humans().get(uuid='test').execute()
+        self.assertEqual(string.hexdigits, ''.join(result.keys()))
+
 
 if __name__ == '__main__':
     unittest.main()

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list