Consumer API and signature modification
Closed this issue · 0 comments
florimondmanca commented
Current status
In the current v1.x API, @consumer
returns an object whose call signature is different from the consumer function:
import aiodine
@aiodine.provider(name="value")
async def provide_value():
return 42
@aiodine.consumer
async def app(value):
return value
async def main():
print(await app()) # 42
Editors and linters tend to complain about the missing arguments, which makes for a poor user experience. Even then, it seems plain odd to be able to call app
without value
, as value
is apparently a required parameter. The implicit Consumer
conversion hides too much magic.
Proposed solution
Remove the @consumer
API (and the notion of consumers altogether) and introduce aiodine.call()
:
import aiodine
@aiodine.provider(name="value")
async def provide_value():
return 42
async def app(value):
print("Value:", value)
async def main():
await aiodine.call(app) # Value: 42
This has a number of benefits:
- Simplicity:
- The only high-level concept remaining would be that of "provider".
.call()
is responsible for injecting providers and managing their lifecycle, whereas that logic was previously scattered across,Store
,Provider
andConsumer
.
- Transparency: the provider function remains unmodified, which means it can be used just as if it wasn't decorated, which gives us good editor and type checking support:
await app() # TypeError: missing required argument "value"
await app(21) # Value: 21
await app(value=21) # Value: 21
await app(value="21") # mypy throws an error