encode / apistar

The Web API toolkit. 🛠
https://docs.apistar.com
BSD 3-Clause "New" or "Revised" License
5.57k stars 411 forks source link

Conversion of a Type to dict fails giving TypeError #587

Closed faheel closed 6 years ago

faheel commented 6 years ago

Given the following types:

class Uploader(types.Type):
    channel_id = validators.String(title='ID')
    name = validators.String(title='Name')
    thumbnail_url = validators.String(title='Thumbnail URL')
    is_verified = validators.Boolean(title='Verified')

class Statistics(types.Type):
    views = validators.Integer(title='Views')
    likes = validators.Integer(title='Likes')
    dislikes = validators.Integer(title='Dislikes')

class Video(types.Type):
    video_id = validators.String(title='ID')
    title = validators.String(title='Title')
    upload_date = validators.String(title='Upload date', format='date')
    duration = validators.String(title='Duration')
    description = validators.String(title='Description')
    thumbnail_url = validators.String(title='Thumbnail URL')
    genre = validators.String(title='Genre')
    is_paid = validators.Boolean(title='Paid')
    is_unlisted = validators.Boolean(title='Unlisted')
    is_family_friendly = validators.Boolean(title='Family-friendly')
    uploader = Uploader
    statistics = Statistics

When I convert a Video object, named video, to a dict (after all the values have been set) as mentioned in the docs, it does not work:

>>> dict(video)
TypeError: keys() missing 1 required positional argument: 'self'

However, video.__dict__ works, but gives some internal fields as well which I don't require:

>>> video.__dict__
mappingproxy({
    '__module__': '__main__',
    'validator': <apistar.validators.Object object at 0x7fb74df30828>,
    '_creation_counter': 390,
    '__doc__': None,
    '__abstractmethods__': frozenset(),
    '_abc_registry': <_weakrefset.WeakSet object at 0x7fb74df30860>,
    '_abc_cache': <_weakrefset.WeakSet object at 0x7fb74df30898>,
    '_abc_negative_cache': <_weakrefset.WeakSet object at 0x7fb74df30518>,
    '_abc_negative_cache_version': 42,
    'video_id': '...',
    'uploader': <class '__main__.Uploader'>,
    'statistics': <class '__main__.Statistics'>,
    'title': '...',
    'is_paid': False,
    'duration': '...',
    'is_unlisted': False,
    'thumbnail_url': '...',
    'is_family_friendly': True,
    'upload_date': '...',
    'genre': '...',
    'description': '...'
})
freakabcd commented 6 years ago

What version of apistar are you using? The missing self argument in your error message indicates to me that you're calling a class method incorrectly.

This code:

from apistar import types, validators

class Uploader(types.Type):
    channel_id = validators.String(title='ID')
    name = validators.String(title='Name')
    thumbnail_url = validators.String(title='Thumbnail URL')
    is_verified = validators.Boolean(title='Verified')

class Statistics(types.Type):
    views = validators.Integer(title='Views')
    likes = validators.Integer(title='Likes')
    dislikes = validators.Integer(title='Dislikes')

class Video(types.Type):
    video_id = validators.String(title='ID')
    title = validators.String(title='Title')
    upload_date = validators.String(title='Upload date', format='date')
    duration = validators.String(title='Duration')
    description = validators.String(title='Description')
    thumbnail_url = validators.String(title='Thumbnail URL')
    genre = validators.String(title='Genre')
    is_paid = validators.Boolean(title='Paid')
    is_unlisted = validators.Boolean(title='Unlisted')
    is_family_friendly = validators.Boolean(title='Family-friendly')
    uploader = Uploader
    statistics = Statistics

up = Uploader({
    'channel_id': 'abcd1234',
    'name': 'some channel',
    'thumbnail_url': 'http://nowhe.re/thumb.jpg',
    'is_verified': True
})
stats = Statistics({
    'views': 5,
    'likes': 2,
    'dislikes': 1
})
vid = Video({
    'video_id': 'vid001',
    'title': 'a video',
    'upload_date': '2018-06-18',
    'duration': '5 mins',
    'description': 'description of video',
    'thumbnail_url': 'http://nowhe.re/thumb.jpg',
    'genre': 'general',
    'is_paid': True,
    'is_unlisted': False,
    'is_family_friendly': True,
    'uploader': up,
    'statistics': stats
})

from pprint import pprint
pprint(dict(vid))

produces the following output with python foo.py

{'description': 'description of video',
 'duration': '5 mins',
 'genre': 'general',
 'is_family_friendly': True,
 'is_paid': True,
 'is_unlisted': False,
 'statistics': <Statistics(views=5, likes=2, dislikes=1)>,
 'thumbnail_url': 'http://nowhe.re/thumb.jpg',
 'title': 'a video',
 'upload_date': '2018-06-18',
 'uploader': <Uploader(channel_id='abcd1234', name='some channel', thumbnail_url='http://nowhe.re/thumb.jpg', is_verified=True)>,
 'video_id': 'vid001'}

This does not seem like a bug in apistar.