I try to resolve this problem about asynchronous WebSocket using python. I don't know why when I used the asynchronous process I get the error log bellow. But my code is totally fine when I didn't used the asynchronous.
error log
C:\ProgramData\Anaconda3\lib\site-packages\numpy\__init__.py:148: UserWarning: mkl-service package failed to import, therefore Intel(R) MKL initialization ensuring its correct out-of-the box operation under condition when Gnu OpenMP had already been loaded by Python process is not assured. Please install mkl-service package, see http://github.com/IntelPython/mkl-service
from . import _distributor_init
[2022-12-15 12:51:26,677][root][INFO] - Connected to localhost object_detection mysql database
Error executing job with overrides: []
Traceback (most recent call last):
File "e:\alfa_beta\etl-python\object_counting\object_counting.py", line 102, in object_counter
File "e:\alfa_beta\etl-python\object_counting\object_counting.py", line 102, in object_counter
obj_counting.async_runner()
File "e:\alfa_beta\etl-python\object_counting\object_counting.py", line 41, in async_runner
asyncio.run(self.vehicle_async())
File "C:\ProgramData\Anaconda3\lib\asyncio\runners.py", line 44, in run
return loop.run_until_complete(main)
File "C:\ProgramData\Anaconda3\lib\asyncio\base_events.py", line 647, in run_until_complete
return future.result()
File "e:\alfa_beta\etl-python\object_counting\object_counting.py", line 62, in vehicle_async
async with create_connection(self.ws_connection) as async_ws_connection:
AttributeError: __aenter__
Set the environment variable HYDRA_FULL_ERROR=1 for a complete stack trace.
hydra config
mode: object_counter
# internal database (mysql)
local_db:
database: object_detection
enabled: true
host: localhost
password: ""
port: 3306
user: root
db_type: mysql
# service camera
service:
vehichle_counting:
table: history_vehicles
ip_cam: 123.23.322.10
ws_connect: ws://123.23.322.24:324/
ws_host: 123.23.322.24
ws_port: 324
ws_prefix:
json_data: 3242
unknown: 42
video_stream: 0222
Main code to run async object_counting.py
from omegaconf import DictConfig
from pyrootutils import setup_root
from types import SimpleNamespace
from websocket import create_connection, enableTrace
import dill as pickle
import asyncio
import hydra
import json
root = setup_root(
search_from=__file__,
indicator=[".git", "pyproject.toml"],
pythonpath=True,
dotenv=True,
)
# internal package
import websocket_data as wsd
from src.config.database_config import Database
from src.infra import time_infra as ABTime
# from object_counting import websocket_data as wsd
# TODO multi processing
class ObjectCounting:
def __init__(self, config: DictConfig, ip_camera: str, ws_connection: str):
self.config = config
self.ip_camera = ip_camera
self.ws_connection = ws_connection # websocket
def async_runner(self):
"""
async_runner will help us to run the asynchronous process in object detection
for now will runn vehicle_async
"""
asyncio.run(self.vehicle_async())
async def vehicle_async(self):
"""
vehicle_async is the asynchronous process for vehicle detection.
It will take data from WebSocket with ANPR type and push the license
plate number with vehicle type of each caught vehicle to MYSQL database
"""
# database
self.local_db = Database(
self.config.local_db.host,
self.config.local_db.port,
self.config.local_db.user,
self.config.local_db.password,
self.config.local_db.database,
self.config.local_db.db_type,
) if self.config.local_db.enabled else None
self.push_table = self.config.service.vehichle_counting_cam_1.table
# enableTrace(True)
async with create_connection(self.ws_connection) as async_ws_connection:
while True:
try:
json_data = json.loads(await async_ws_connection.recv(),
object_hook=lambda d: SimpleNamespace(**d))
if json_data.type == "anpr":
raw_data = wsd.WebsocketData(json_data.type,
json_data.payload,
json_data.img)
payload_ws = raw_data.payload[0]
result_json = payload_ws.resjson
image_ws = raw_data.img
if result_json != '':
print("\ncatch!")
print('\nPayload: {}'.format(payload_ws))
# push_table = "history_vehicle"
response = {"camera_id": 123,
"camera_name": "test_camera",
"plate_number": payload_ws.label,
"vehicle_type": payload_ws.vehicle_type,
"datetime": ABTime.ab_timestamp(),
"image": image_ws,
}
self.local_db.push_data(self.push_table, response, self.local_db.db_type)
# TODO push data to mysql
except Exception as e:
print("error :", e)
if __name__ == "__main__":
@hydra.main(config_path=root / "config", config_name="object_counter", version_base=None)
def object_counter(hydra_config: DictConfig):
hydra_service = hydra_config.service.vehichle_counting_cam_1
ip_camera = hydra_service.ip_cam
ws_connection = hydra_service.ws_connect
obj_counting = ObjectCounting(hydra_config, ip_camera, ws_connection)
obj_counting.async_runner()
object_counter()
Object parsing data to convert WebSocket data to python object
from typing import List
class Box:
xmin: int
ymin: int
xmax: int
ymax: int
def __init__(self, xmin: int, ymin: int, xmax: int, ymax: int) -> None:
self.xmin = xmin
self.ymin = ymin
self.xmax = xmax
self.ymax = ymax
class Candidate:
score: float
plate: str
def __init__(self, score: float, plate: str) -> None:
self.score = score
self.plate = plate
class Color:
color: str
score: float
def __init__(self, color: str, score: float) -> None:
self.color = color
self.score = score
class ModelMake:
make: str
model: str
score: float
def __init__(self, make: str, model: str, score: float) -> None:
self.make = make
self.model = model
self.score = score
class Orientation:
orientation: str
score: float
def __init__(self, orientation: str, score: float) -> None:
self.orientation = orientation
self.score = score
class Region:
code: str
score: float
def __init__(self, code: str, score: float) -> None:
self.code = code
self.score = score
class Vehicle:
score: float
type: str
box: Box
def __init__(self, score: float, type: str, box: Box) -> None:
self.score = score
self.type = type
self.box = box
class Resjson:
box: Box
plate: str
region: Region
score: float
candidates: List[Candidate]
dscore: float
vehicle: Vehicle
model_make: List[ModelMake]
color: List[Color]
orientation: List[Orientation]
def __init__(self, box: Box, plate: str, region: Region, score: float, candidates: List[Candidate], dscore: float, vehicle: Vehicle, model_make: List[ModelMake], color: List[Color], orientation: List[Orientation]) -> None:
self.box = box
self.plate = plate
self.region = region
self.score = score
self.candidates = candidates
self.dscore = dscore
self.vehicle = vehicle
self.model_make = model_make
self.color = color
self.orientation = orientation
class Payload:
label: str
vehicle_type: str
resjson: Resjson
def __init__(self, label: str, vehicle_type: str, resjson: Resjson) -> None:
self.label = label
self.vehicle_type = vehicle_type
self.resjson = resjson
class WebsocketData:
type: str
payload: List[Payload]
img: str
def __init__(self, type: str, payload: List[Payload], img: str) -> None:
self.type = type
self.payload = payload
self.img = img