I should probably add how this is used.
For the library developer, you just add @add_sync_version to those (public) async functions and methods for which you want to add a sync version. E.g.
@add_sync_version
async def spam(): ...
For the user of the library, if they want the async version they can just write
x = await spam()
If they want the sync version they can write
x = spam.sync()