-1

I am trying to create a list of python class objects.

Basically I am expecting for list which should be as follows:

[<Report {u'invoice_id': u'demo-1-2016-dummy', u'tenant_id': u'27724b57e3b744f89cbf1336da062b43'}>, <Report {u'invoice_id': u'demo-2-2016', u'tenant_id': u'27724b57e3b744f89cbf1336da062b43'}>, <Report {u'invoice_id': u'admin-2-2016', u'tenant_id': u'6cd02afa3f0f403489153c41e98d07bc'}>]

I have tried the following code for the same.

from cloudkittyclient.common import base
import json

class ReportResult(base.Resource):

    key = 'report'

    def __repr__(self):
        return "<Report %s>" % self._info

class ReportManager(base.CrudManager):

    base_url = '/v1/report'
    resource_class = ReportResult
    key = "report"
    collection_key = "reports"

    # List the invoices, can accept all-tenants arg
    def list_invoice(self, all_tenants=None):
        url = self.base_url + "/list_invoice"
        filters = list()
        if all_tenants:
            filters.append("all_tenants=%s" % all_tenants)
        if filters:
            url += "?%s" % ('&'.join(filters))
        return self.client.get(url).json()

So here my requirement is that "return self.client.get(url).json()" should return the above mentioned List which consists of class objects.

But it is returning the results as follows:

[{u'invoice_id': u'demo-1-2016-dummy', u'tenant_id': u'27724b57e3b744f89cbf1336da062b43'}, {u'invoice_id': u'demo-2-2016', u'tenant_id': u'27724b57e3b744f89cbf1336da062b43'}, {u'invoice_id': u'admin-2-2016', u'tenant_id': u'6cd02afa3f0f403489153c41e98d07bc'}]

I know the fact that I am missing something right here.

As I am novice user in python I am unable to find that where I am going wrong.

Can anyone be able to assist me with getting the result I expected.

iamnewuser
  • 360
  • 1
  • 4
  • 16
  • Please stop using `repr` strings as serialization. `return self.client.get(url).json()` is returning just that: a `list` of python `dict`ionaries that can be then serialized to JSON for transfer. – Ilja Everilä Mar 17 '16 at 09:20
  • Hardly I need the list with class objects of the same. That is what I am trying to achieve. – iamnewuser Mar 17 '16 at 09:25
  • Possible duplicate of [SQLALchemy and Python - Getting the SQL result](http://stackoverflow.com/questions/35407120/sqlalchemy-and-python-getting-the-sql-result) – Ilja Everilä Mar 17 '16 at 09:26
  • Then don't call `.json()`? That `[, ...]` is still just a helpful debug output of a list of `Report` instances. You seem to confuse it with something else. – Ilja Everilä Mar 17 '16 at 09:28
  • This question seems to be about some deep internal stuff in a library rather than a general Python class, but it has no tags indicating what the library is (and several very uselessly broad tags like `object` and `class`). I strongly suggest getting rid of the general tags and adding something more specific (I have no idea what `cloudkitty` is, or I'd edit the tags in myself). – Blckknght Mar 17 '16 at 10:44

1 Answers1

3

TL;DR:

return [self.resource_class(self, j, loaded=True)
        for j in self.client.get(url).json() if j]

You should not have to handle URL creation yourself. The CrudManager should take care of that for you, if you use the methods offered.

Try

report_manager.get(report_id=my_report_id)

where my_report_id is a variable containing an id, if you're trying to fetch a single report, instead of

report_manager.client.get(url).json()

Looking into cloudkittyclient.openstack.common.apiclient.base.BaseManager._get that self.client.get(url).json() is what it does internally, before it then deserializes the JSON to self.resource_class instance. You probably should not be doing that directly.

cloudkittyclient.common.base.CrudManager uses the _get internally and offers an override of get that will handle base_url catenation etc for you.

Also it seems you should be using cloudkittyclient.common.base.CrudManager.findAll or cloudkittyclient.common.base.CrudManager.list, since you have a method like list_invoice.

report_manager.findAll()

or

report_manager.findAll(all_tenants=all_tenants)

where all_tenants is a variable with what ever you would pass to your custom list_invoice method.

Finally, if findAll or CrudManager.list is really unsuitable to your needs, which seems to be the case since your collection url differs from the one in the class, you have to deserialize the results of self.client.get(url).json() yourself. So instead of returning that, do

return [self.resource_class(self, j, loaded=True)
        for j in self.client.get(url).json() if j]

which creates a list of instances of self.resource_class class (ReportResult here) from python dictionaries that have been deserialized from a response of JSON data.

Consider overloading the list method of CrudManager, as it seems to be the way to do such a thing.

Ilja Everilä
  • 50,538
  • 7
  • 126
  • 127