Access Messages via API from Python
This commit is contained in:
@ -8,31 +8,140 @@
|
||||
# source code released under the terms of GNU Public License Version 3
|
||||
# https://www.gnu.org/licenses/gpl-3.0.txt
|
||||
|
||||
"""
|
||||
Access to the management, e.g., get the list of messages and single messages.
|
||||
Manually send messages (if necessary, the platforms should do this).
|
||||
|
||||
### Example
|
||||
```python
|
||||
|
||||
m_request = ManagementRequest()
|
||||
|
||||
m_request.get_message(count=12)
|
||||
# MessageDbRow(count=12 sender='from' recipient='to' ...
|
||||
|
||||
m_request.list_messages(id="test", limit=2)
|
||||
# [
|
||||
# MessageDbRow(count=7256, sender='management', ...),
|
||||
# MessageDbRow(count=7255, sender='management', ...),
|
||||
# ]
|
||||
|
||||
m_request.total_messages(id="test")
|
||||
# 31
|
||||
|
||||
```
|
||||
|
||||
See also `ums.example.__main__` and run in Docker via ``docker compose exec management python -m ums.example``
|
||||
"""
|
||||
|
||||
import os
|
||||
from typing import List, Dict, Any
|
||||
|
||||
import requests
|
||||
from pydantic import validate_call
|
||||
|
||||
from ums.utils.types import AgentMessage, AgentResponse, MessageDbRow
|
||||
|
||||
|
||||
class RequestException(Exception):
|
||||
pass
|
||||
"""
|
||||
Raised on http and similar errors.
|
||||
"""
|
||||
pass
|
||||
|
||||
class ManagementRequest():
|
||||
|
||||
def __init__(self, hostname:str, port:int=80):
|
||||
self.url = "http://{hostname}:{port}".format(hostname=hostname, port=port)
|
||||
MANAGEMENT_URL = os.environ.get('MANAGEMENT_URL', 'http://127.0.0.1:80').strip().strip('/')
|
||||
|
||||
def get_status(self, count:int) -> MessageDbRow:
|
||||
@validate_call
|
||||
def __init__(self, allow_lazy:bool=True):
|
||||
"""
|
||||
If `allow_lazy` is active, the type checking (by pydantic) is less strict.
|
||||
E.g. it does not require that all files in the data section of messages must exist on the file system.
|
||||
"""
|
||||
self.allow_lazy = allow_lazy
|
||||
self.pydantic_context = {
|
||||
"require_file_exists": not self.allow_lazy
|
||||
}
|
||||
|
||||
@validate_call
|
||||
def get_message(self, count:int) -> MessageDbRow:
|
||||
"""
|
||||
Get a message (like a table row) from the management by using the `count`.
|
||||
"""
|
||||
row = self._get_request(
|
||||
'list/single',
|
||||
{"count": count}
|
||||
)
|
||||
return MessageDbRow.model_validate(
|
||||
row, context=self.pydantic_context
|
||||
)
|
||||
|
||||
@validate_call
|
||||
def list_messages(self,
|
||||
id:str|None=None, sender:str|None=None, recipient:str|None=None,
|
||||
processed:bool|None=None, solution:bool|None=None,
|
||||
time_after:int|None=None, time_before:int|None=None,
|
||||
limit:int=10, offset:int=0
|
||||
) -> List[MessageDbRow]:
|
||||
"""
|
||||
Get the rows in the tables as list of messages.
|
||||
The arguments are used for filtering.
|
||||
"""
|
||||
|
||||
kwargs = locals().copy()
|
||||
params = {}
|
||||
|
||||
for k,v in kwargs.items():
|
||||
if k not in ('self',) and not v is None:
|
||||
params[k] = v
|
||||
|
||||
rows = self._get_request('list', params)
|
||||
|
||||
return [
|
||||
MessageDbRow.model_validate(
|
||||
row, context=self.pydantic_context
|
||||
) for row in rows
|
||||
]
|
||||
|
||||
@validate_call
|
||||
def total_messages(self,
|
||||
id:str|None=None, sender:str|None=None, recipient:str|None=None,
|
||||
processed:bool|None=None, solution:bool|None=None,
|
||||
time_after:int|None=None, time_before:int|None=None
|
||||
) -> int:
|
||||
"""
|
||||
Get the total number of rows in the tables matching the filters.
|
||||
"""
|
||||
|
||||
kwargs = locals().copy()
|
||||
params = {}
|
||||
|
||||
for k,v in kwargs.items():
|
||||
if k not in ('self',) and not v is None:
|
||||
params[k] = v
|
||||
|
||||
return int(self._get_request('app/table/total', params))
|
||||
|
||||
def _get_request(self, endpoint:str, params:Dict[str, Any]):
|
||||
r = requests.get(
|
||||
"{}/status".format(self.url),
|
||||
params={"count": count}
|
||||
"{}/{}".format(self.MANAGEMENT_URL, endpoint),
|
||||
params=params
|
||||
)
|
||||
|
||||
if r.status_code == 200:
|
||||
return MessageDbRow.model_validate_json(r.text)
|
||||
return r.json()
|
||||
else:
|
||||
raise RequestException(str(r.text)+str(r.headers))
|
||||
|
||||
raise RequestException(str(r.text)+"\n"+str(r.headers))
|
||||
|
||||
@validate_call
|
||||
def send_message(self, ) -> AgentResponse:
|
||||
# TODO
|
||||
pass
|
||||
|
||||
def _post_request(self, message:AgentMessage) -> AgentResponse:
|
||||
# TODO
|
||||
|
||||
def send_message(self, message:AgentMessage) -> AgentResponse:
|
||||
r = requests.post(
|
||||
"{}/message".format(self.url),
|
||||
data=message.model_dump_json(),
|
||||
|
@ -90,7 +90,7 @@
|
||||
|
||||
"""
|
||||
|
||||
import os
|
||||
import os, warnings
|
||||
|
||||
from enum import Enum
|
||||
|
||||
@ -108,6 +108,12 @@ from ums.utils.const import SHARE_PATH
|
||||
from ums.utils.schema import ExtractionSchema
|
||||
|
||||
class RiddleInformation(BaseModel):
|
||||
# ignore:
|
||||
# /usr/local/lib/python3.12/dist-packages/pydantic/_internal/_fields.py:172:
|
||||
# UserWarning: Field name "validate" in "RiddleStatus" shadows an attribute in parent
|
||||
# "RiddleInformation"
|
||||
warnings.filterwarnings('ignore', category=UserWarning, lineno=172, module="pydantic")
|
||||
|
||||
"""
|
||||
This is the basic class used as superclass for all message and infos
|
||||
about a riddle.
|
||||
|
Reference in New Issue
Block a user