我是异步 python 的新手。
我创建了一个应该从文件系统加载文件的单例对象
class AppResourceLoader(metaclass=Singleton):
async def load_yaml(self, resource_filepath):
async with open(path.join(path.dirname(path.dirname(__file__)), 'resources', resource_filepath)) as f:
return await yaml.safe_load(f.read())
Singleton
是一个普通的元类
class Singleton(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(
Singleton, cls).__call__(*args, **kwargs)
return cls._instances[cls]
我使用它AppResourceLoader
在类构造函数中上传文件并稍后通过getter访问它
class ServiceCatalog(metaclass=Singleton):
def __init__(self, catalog_file):
self.services = AppResourceLoader().load_yaml(catalog_file)
def get_catalog(self):
return self.services
这个get_catalog
方法我在另一个类中调用
class ServiceBrokerController(metaclass=Singleton):
def __init__(self):
self.catalog = ServiceCatalog('catalog.yml')
@ujson_route
def get_catalog(self):
return self.catalog.get_catalog()
装饰ujson_route
器看起来像这样
def ujson_route(func):
async def wrapper(*args, **kwargs):
return UJSONResponse(func(args[0]))
return wrapper
这个get_catalog
函数ServiceBrokerController
被 Starlette 路由对象使用
async def on_startup_upload_catalog(request):
ServiceBrokerController()
app = Starlette(
debug=True,
routes=[
Route('/v2/catalog', ServiceBrokerController().get_catalog)],
exception_handlers=exceptions.exception_handler,
on_startup=[]
)
我运行测试get_catalog
看起来像这样
def test_catalog():
with TestClient(app) as client:
response = client.get('/v2/catalog')
assert response.status_code == 200
services = ujson.loads(response.content)
expected_services = AppResourceLoader().load_yaml('catalog.yml')
# no changes
assert deepdiff.DeepDiff(services, expected_services) == {}
但是当我使用plain执行测试时pytest -v
,它失败并出现错误
self = <starlette.responses.UJSONResponse object at 0x102d8f990>, content = <coroutine object AppResourceLoader.load_yaml at 0x102c8b9e0>
def render(self, content: typing.Any) -> bytes:
assert ujson is not None, "ujson must be installed to use UJSONResponse"
> return ujson.dumps(content, ensure_ascii=False).encode("utf-8")
E TypeError: <coroutine object AppResourceLoader.load_yaml at 0x102c8b9e0> is not JSON serializable
在我使load_yaml
方法异步之前它起作用了。
怎么了?据我了解,我需要放在await
某个地方,因为据我了解,从错误中它返回协程而不是文件数据。