mirror of
https://github.com/azaion/annotations.git
synced 2026-04-22 12:26:30 +00:00
make python app load a bit eariler, making startup a bit faster
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
from user cimport User
|
||||
from credentials cimport Credentials
|
||||
from file_data cimport FileData
|
||||
|
||||
cdef class ApiClient:
|
||||
cdef str email, password, token, folder, token_file, api_url
|
||||
cdef public Credentials credentials
|
||||
cdef str token, folder, api_url
|
||||
cdef User user
|
||||
|
||||
cdef get_encryption_key(self, str hardware_hash)
|
||||
@@ -9,7 +12,7 @@ cdef class ApiClient:
|
||||
cdef set_token(self, str token)
|
||||
cdef get_user(self)
|
||||
|
||||
cdef load_bytes(self, str filename)
|
||||
cdef load_bytes(self, FileData file_data)
|
||||
cdef load_ai_model(self)
|
||||
cdef load_queue_config(self)
|
||||
|
||||
|
||||
@@ -9,33 +9,25 @@ from hardware_service cimport HardwareService, HardwareInfo
|
||||
from security cimport Security
|
||||
from io import BytesIO
|
||||
from user cimport User, RoleEnum
|
||||
from file_data cimport FileData
|
||||
|
||||
cdef class ApiClient:
|
||||
"""Handles API authentication and downloading of the AI model."""
|
||||
def __init__(self, str email, str password, str folder):
|
||||
self.email = email
|
||||
self.password = password
|
||||
self.folder = folder
|
||||
def __init__(self):
|
||||
self.credentials = None
|
||||
self.user = None
|
||||
|
||||
if os.path.exists(<str>constants.TOKEN_FILE):
|
||||
with open(<str>constants.TOKEN_FILE, "r") as file:
|
||||
self.set_token(<str>file.read().strip())
|
||||
else:
|
||||
self.token = None
|
||||
self.token = None
|
||||
|
||||
cdef get_encryption_key(self, str hardware_hash):
|
||||
cdef str key = f'{self.email}-{self.password}-{hardware_hash}-#%@AzaionKey@%#---'
|
||||
cdef str key = f'{self.credentials.email}-{self.credentials.password}-{hardware_hash}-#%@AzaionKey@%#---'
|
||||
return Security.calc_hash(key)
|
||||
|
||||
cdef login(self):
|
||||
response = requests.post(f"{constants.API_URL}/login",
|
||||
json={"email": self.email, "password": self.password})
|
||||
json={"email": self.credentials.email, "password": self.credentials.password})
|
||||
response.raise_for_status()
|
||||
token = response.json()["token"]
|
||||
self.set_token(token)
|
||||
with open(<str>constants.TOKEN_FILE, 'w') as file:
|
||||
file.write(token)
|
||||
|
||||
cdef set_token(self, str token):
|
||||
self.token = token
|
||||
@@ -68,14 +60,15 @@ cdef class ApiClient:
|
||||
self.login()
|
||||
return self.user
|
||||
|
||||
cdef load_bytes(self, str filename):
|
||||
cdef load_bytes(self, FileData file_data):
|
||||
folder = file_data.folder or self.credentials.folder
|
||||
hardware_service = HardwareService()
|
||||
cdef HardwareInfo hardware = hardware_service.get_hardware_info()
|
||||
|
||||
if self.token is None:
|
||||
self.login()
|
||||
|
||||
url = f"{constants.API_URL}/resources/get/{self.folder}"
|
||||
url = f"{constants.API_URL}/resources/get/{folder}"
|
||||
headers = {
|
||||
"Authorization": f"Bearer {self.token}",
|
||||
"Content-Type": "application/json"
|
||||
@@ -83,9 +76,9 @@ cdef class ApiClient:
|
||||
|
||||
payload = json.dumps(
|
||||
{
|
||||
"password": self.password,
|
||||
"password": self.credentials.password,
|
||||
"hardware": hardware.to_json_object(),
|
||||
"fileName": filename
|
||||
"fileName": file_data.filename
|
||||
}, indent=4)
|
||||
response = requests.post(url, data=payload, headers=headers, stream=True)
|
||||
|
||||
@@ -104,7 +97,7 @@ cdef class ApiClient:
|
||||
|
||||
stream = BytesIO(response.raw.read())
|
||||
data = Security.decrypt_to(stream, key)
|
||||
print(f'loaded file: {filename}, {len(data)} bytes')
|
||||
print(f'loaded file: {file_data.filename}, {len(data)} bytes')
|
||||
return data
|
||||
|
||||
cdef load_ai_model(self):
|
||||
|
||||
@@ -7,13 +7,15 @@ pyinstaller --onefile ^
|
||||
--collect-all cryptography ^
|
||||
--collect-all cv2 ^
|
||||
--collect-all onnxruntime ^
|
||||
--hidden-import constants ^
|
||||
--hidden-import annotation ^
|
||||
--hidden-import credentials ^
|
||||
--hidden-import file_data ^
|
||||
--hidden-import user ^
|
||||
--hidden-import security ^
|
||||
--hidden-import secure_model ^
|
||||
--hidden-import api_client ^
|
||||
--hidden-import hardware_service ^
|
||||
--hidden-import constants ^
|
||||
--hidden-import annotation ^
|
||||
--hidden-import remote_command ^
|
||||
--hidden-import ai_config ^
|
||||
--hidden-import inference ^
|
||||
|
||||
@@ -5,7 +5,6 @@ cdef str COMMANDS_QUEUE # Name of the commands queue in rabbit
|
||||
cdef str ANNOTATIONS_QUEUE # Name of the annotations queue in rabbit
|
||||
|
||||
cdef str API_URL # Base URL for the external API
|
||||
cdef str TOKEN_FILE # Name of the token file where temporary token would be stored
|
||||
cdef str QUEUE_CONFIG_FILENAME # queue config filename to load from api
|
||||
cdef str AI_MODEL_FILE # AI Model file
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@ cdef str COMMANDS_QUEUE = "azaion-commands"
|
||||
cdef str ANNOTATIONS_QUEUE = "azaion-annotations"
|
||||
|
||||
cdef str API_URL = "https://api.azaion.com" # Base URL for the external API
|
||||
cdef str TOKEN_FILE = "token"
|
||||
cdef str QUEUE_CONFIG_FILENAME = "secured-config.json"
|
||||
cdef str AI_MODEL_FILE = "azaion.onnx"
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
cdef class Credentials:
|
||||
cdef public str email
|
||||
cdef public str password
|
||||
cdef public str folder
|
||||
|
||||
@staticmethod
|
||||
cdef from_msgpack(bytes data)
|
||||
@@ -0,0 +1,17 @@
|
||||
from msgpack import unpackb
|
||||
|
||||
cdef class Credentials:
|
||||
|
||||
def __init__(self, str email, str password, str folder):
|
||||
self.email = email
|
||||
self.password = password
|
||||
self.folder = folder
|
||||
|
||||
@staticmethod
|
||||
cdef from_msgpack(bytes data):
|
||||
unpacked = unpackb(data, strict_map_key=False)
|
||||
return Credentials(
|
||||
unpacked.get("Email"),
|
||||
unpacked.get("Password"),
|
||||
unpacked.get("Folder"))
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
cdef class FileData:
|
||||
cdef public str folder
|
||||
cdef public str filename
|
||||
|
||||
@staticmethod
|
||||
cdef from_msgpack(bytes data)
|
||||
@@ -0,0 +1,14 @@
|
||||
from msgpack import unpackb
|
||||
|
||||
cdef class FileData:
|
||||
|
||||
def __init__(self, str folder, str filename):
|
||||
self.folder = folder
|
||||
self.filename = filename
|
||||
|
||||
@staticmethod
|
||||
cdef from_msgpack(bytes data):
|
||||
unpacked = unpackb(data, strict_map_key=False)
|
||||
return FileData(
|
||||
unpacked.get("Folder"),
|
||||
unpacked.get("Filename"))
|
||||
+15
-15
@@ -9,16 +9,10 @@ from annotation cimport Annotation
|
||||
from inference cimport Inference
|
||||
from remote_command cimport RemoteCommand, CommandType
|
||||
from remote_command_handler cimport RemoteCommandHandler
|
||||
from credentials cimport Credentials
|
||||
from file_data cimport FileData
|
||||
from user cimport User
|
||||
|
||||
cdef class ParsedArguments:
|
||||
cdef str email, password, folder;
|
||||
|
||||
def __init__(self, str email, str password, str folder):
|
||||
self.email = email
|
||||
self.password = password
|
||||
self.folder = folder
|
||||
|
||||
cdef class CommandProcessor:
|
||||
cdef ApiClient api_client
|
||||
cdef RemoteCommandHandler remote_handler
|
||||
@@ -26,8 +20,8 @@ cdef class CommandProcessor:
|
||||
cdef bint running
|
||||
cdef Inference inference
|
||||
|
||||
def __init__(self, args: ParsedArguments):
|
||||
self.api_client = ApiClient(args.email, args.password, args.folder)
|
||||
def __init__(self):
|
||||
self.api_client = ApiClient()
|
||||
self.remote_handler = RemoteCommandHandler(self.on_command)
|
||||
self.inference_queue = Queue(maxsize=constants.QUEUE_MAXSIZE)
|
||||
self.remote_handler.start()
|
||||
@@ -49,11 +43,10 @@ cdef class CommandProcessor:
|
||||
|
||||
cdef on_command(self, RemoteCommand command):
|
||||
try:
|
||||
if command.command_type == CommandType.GET_USER:
|
||||
self.get_user(command, self.api_client.get_user())
|
||||
if command.command_type == CommandType.LOGIN:
|
||||
self.login(command)
|
||||
elif command.command_type == CommandType.LOAD:
|
||||
response = self.api_client.load_bytes(command.filename)
|
||||
self.remote_handler.send(command.client_id, response)
|
||||
self.load_file(command)
|
||||
elif command.command_type == CommandType.INFERENCE:
|
||||
self.inference_queue.put(command)
|
||||
elif command.command_type == CommandType.STOP_INFERENCE:
|
||||
@@ -66,9 +59,16 @@ cdef class CommandProcessor:
|
||||
except Exception as e:
|
||||
print(f"Error handling client: {e}")
|
||||
|
||||
cdef get_user(self, RemoteCommand command, User user):
|
||||
cdef login(self, RemoteCommand command):
|
||||
cdef User user
|
||||
self.api_client.credentials = Credentials.from_msgpack(command.data)
|
||||
user = self.api_client.get_user()
|
||||
self.remote_handler.send(command.client_id, user.serialize())
|
||||
|
||||
cdef load_file(self, RemoteCommand command):
|
||||
response = self.api_client.load_bytes(FileData.from_msgpack(command.data))
|
||||
self.remote_handler.send(command.client_id, response)
|
||||
|
||||
cdef on_annotation(self, RemoteCommand cmd, Annotation annotation):
|
||||
data = annotation.serialize()
|
||||
self.remote_handler.send(cmd.client_id, data)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
cdef enum CommandType:
|
||||
GET_USER = 10
|
||||
LOGIN = 10
|
||||
LOAD = 20
|
||||
INFERENCE = 30
|
||||
STOP_INFERENCE = 40
|
||||
@@ -8,7 +8,6 @@ cdef enum CommandType:
|
||||
cdef class RemoteCommand:
|
||||
cdef public bytes client_id
|
||||
cdef CommandType command_type
|
||||
cdef str filename
|
||||
cdef bytes data
|
||||
|
||||
@staticmethod
|
||||
|
||||
@@ -1,23 +1,22 @@
|
||||
import msgpack
|
||||
|
||||
cdef class RemoteCommand:
|
||||
def __init__(self, CommandType command_type, str filename, bytes data):
|
||||
def __init__(self, CommandType command_type, bytes data):
|
||||
self.command_type = command_type
|
||||
self.filename = filename
|
||||
self.data = data
|
||||
|
||||
def __str__(self):
|
||||
command_type_names = {
|
||||
10: "GET_USER",
|
||||
10: "LOGIN",
|
||||
20: "LOAD",
|
||||
30: "INFERENCE",
|
||||
40: "STOP_INFERENCE",
|
||||
100: "EXIT"
|
||||
}
|
||||
data_str = f'. Data: {len(self.data)} bytes' if self.data else ''
|
||||
return f'{command_type_names[self.command_type]}: {self.filename}{data_str}'
|
||||
return f'{command_type_names[self.command_type]}: {data_str}'
|
||||
|
||||
@staticmethod
|
||||
cdef from_msgpack(bytes data):
|
||||
unpacked = msgpack.unpackb(data, strict_map_key=False)
|
||||
return RemoteCommand(unpacked.get("CommandType"), unpacked.get("Filename"), unpacked.get("Data"))
|
||||
return RemoteCommand(unpacked.get("CommandType"), unpacked.get("Data"))
|
||||
|
||||
@@ -5,6 +5,8 @@ import numpy as np
|
||||
extensions = [
|
||||
Extension('constants', ['constants.pyx']),
|
||||
Extension('annotation', ['annotation.pyx']),
|
||||
Extension('credentials', ['credentials.pyx']),
|
||||
Extension('file_data', ['file_data.pyx']),
|
||||
Extension('security', ['security.pyx']),
|
||||
Extension('hardware_service', ['hardware_service.pyx'], extra_compile_args=["-g"], extra_link_args=["-g"]),
|
||||
Extension('remote_command', ['remote_command.pyx']),
|
||||
|
||||
@@ -1,22 +1,13 @@
|
||||
import argparse
|
||||
from main import ParsedArguments, CommandProcessor
|
||||
from main import CommandProcessor
|
||||
|
||||
|
||||
def parse_arguments():
|
||||
parser = argparse.ArgumentParser(description="Command Processor")
|
||||
parser.add_argument("-e", "--email", type=str, default="", help="Email")
|
||||
parser.add_argument("-p", "--pw", type=str, default="", help="Password")
|
||||
parser.add_argument("-f", "--folder", type=str, default="", help="Folder to API inner folder to download file from")
|
||||
args = parser.parse_args()
|
||||
|
||||
return ParsedArguments(args.email, args.pw, args.folder)
|
||||
|
||||
def start(args: ParsedArguments):
|
||||
processor = CommandProcessor(args)
|
||||
def start():
|
||||
processor = CommandProcessor()
|
||||
try:
|
||||
processor.start()
|
||||
except KeyboardInterrupt:
|
||||
processor.stop()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
start(parse_arguments())
|
||||
start()
|
||||
|
||||
@@ -3,7 +3,7 @@ from PyInstaller.utils.hooks import collect_all
|
||||
|
||||
datas = []
|
||||
binaries = []
|
||||
hiddenimports = ['user', 'security', 'secure_model', 'api_client', 'hardware_service', 'constants', 'annotation', 'remote_command', 'ai_config', 'inference', 'remote_command_handler']
|
||||
hiddenimports = ['constants', 'annotation', 'credentials', 'file_data', 'user', 'security', 'secure_model', 'api_client', 'hardware_service', 'remote_command', 'ai_config', 'inference', 'remote_command_handler']
|
||||
tmp_ret = collect_all('jwt')
|
||||
datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2]
|
||||
tmp_ret = collect_all('requests')
|
||||
|
||||
Reference in New Issue
Block a user