I'm trying to use a dataclass object to pass to the params of the aiohttp get request, but aiohttp only accept float
, int
or str
as type in the params since it's the job of the user to handle those cases.
Let's say I want the following conversions:
True -> 'True'
False -> 'False'
None -> ''
How can I achieve that conversion without manually doing the conversion before the request?
Here an example script that explain what I want to achieve:
import asyncio
import aiohttp
from typing import Optional
from dataclasses import dataclass
from dataclasses_json import dataclass_json
@dataclass
class Params:
a: bool
b: str
c: Optional[float] = None
async def main():
params = Params(
a = True,
b = 'b',
)
async with aiohttp.ClientSession() as session:
async with session.get('http://www.example.com', params=convert(params))) as r:
print(await r.text())
asyncio.run(main())
By using the fields
method from dataclass, I can iterate throught the dataclass' fields and do the conversion according to the value:
from dataclasses import fields
def convert(dc: dataclass, mapping=None):
if mapping is None:
mapping = {
None: '',
True: str(True),
False: str(False),
}
def _convert(value):
if value in mapping:
return mapping[value]
return value
return { field.name: _convert(getattr(dc, field.name)) for field in fields(dc) }
Note that this doesn't work with nested dataclasses, but aiohttp doesn't handle them either.