最近需要对指定文件做恶意性检测,项目中选择使用的VirusTotal Api 3.0,但是在调用vt库中的scan_file()函数时,发现会报错Unclosed client session。
调用代码片段如下:
private_key = vtapi_key
vt_client = vt.Client(private_key)
with open(file, 'rb') as f:
analysis = vt_client.scan_file(f, wait_for_completion=True)
报错截图如下:
翻看scan_file()源码发现,wait_for_completion=True实际是通过每20s检查一下VirusTotal服务器端是否完成了文件检测实现的。在客户端和服务器之间的通信全由aiohttp库实现,当服务端返回status == 'completed'之后,就直接将检测结果返回,而没有关闭aiohttp.ClientSession()的实例。
修复方法(在以下代码块中标注):修改scan_file_async()函数,在return前关闭ClientSession。
async def scan_file_async(self, file, wait_for_completion=False):
if not isinstance(file, io.IOBase):
raise TypeError(f'Expected a file to be a file object, got {type(file)}')
part = aiohttp.get_payload(file)
filename = file.name if hasattr(file, 'name') else 'unknown'
disposition = f'form-data; name="file"; filename="{filename}"'
part.headers['Content-Disposition'] = disposition
form_data = aiohttp.MultipartWriter('form-data')
form_data.append_payload(part)
upload_url = await self.get_data_async('/files/upload_url')
response = ClientResponse(
await self._get_session().post(
upload_url, data=form_data, proxy=self._proxy))
analysis = await self._response_to_object(response)
if wait_for_completion:
analysis = await self._wait_for_analysis_completion(analysis)
# 加入以下这句代码
await self._session.close()
return analysis
其他 scan_***_async() 如果报类似错误应该可以同理解决。