ums.utils.request

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

        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

  1# Agenten Plattform
  2#
  3# (c) 2024 Magnus Bender
  4# 	Institute of Humanities-Centered Artificial Intelligence (CHAI)
  5# 	Universitaet Hamburg
  6# 	https://www.chai.uni-hamburg.de/~bender
  7#  
  8# source code released under the terms of GNU Public License Version 3
  9# https://www.gnu.org/licenses/gpl-3.0.txt
 10
 11"""
 12	Access to the management, e.g., get the list of messages and single messages.
 13	Manually send messages (if necessary, the platforms should do this). 
 14
 15	### Example
 16	```python
 17
 18		m_request = ManagementRequest()
 19		
 20		m_request.get_message(count=12)
 21		# MessageDbRow(count=12 sender='from' recipient='to' ...
 22
 23		m_request.list_messages(id="test", limit=2)
 24		# [
 25		#	MessageDbRow(count=7256, sender='management', ...),
 26		#	MessageDbRow(count=7255, sender='management', ...),
 27		# ]
 28
 29		m_request.total_messages(id="test")
 30		# 31
 31
 32	```
 33
 34	See also `ums.example.__main__` and run in Docker via ``docker compose exec management python -m ums.example``
 35"""
 36
 37import os
 38from typing import List, Dict, Any
 39
 40import requests
 41from pydantic import validate_call
 42
 43from ums.utils.types import AgentMessage, AgentResponse, MessageDbRow
 44
 45
 46class RequestException(Exception):
 47	"""
 48		Raised on http and similar errors.
 49	"""
 50	pass
 51
 52class ManagementRequest():
 53
 54	MANAGEMENT_URL = os.environ.get('MANAGEMENT_URL', 'http://127.0.0.1:80').strip().strip('/')
 55
 56	@validate_call
 57	def __init__(self, allow_lazy:bool=True):
 58		"""
 59			If `allow_lazy` is active, the type checking (by pydantic) is less strict. 
 60			E.g. it does not require that all files in the data section of messages must exist on the file system.
 61		"""
 62		self._allow_lazy = allow_lazy
 63		self._pydantic_context = {
 64			"require_file_exists": not self._allow_lazy
 65		}
 66
 67	@validate_call
 68	def get_message(self, count:int) -> MessageDbRow:
 69		"""
 70			Get a message (like a table row) from the management by using the `count`.
 71
 72			May raise `RequestException`.
 73		"""
 74		row = self._get_request(
 75			'list/single',
 76			{"count": count}
 77		)
 78		return MessageDbRow.model_validate(
 79			row, context=self._pydantic_context
 80		)
 81
 82	@validate_call
 83	def list_messages(self,
 84			id:str|None=None, sender:str|None=None, recipient:str|None=None,
 85			processed:bool|None=None, solution:bool|None=None,
 86			time_after:int|None=None, time_before:int|None=None,
 87			limit:int=10, offset:int=0
 88		) -> List[MessageDbRow]:
 89		"""
 90			Get the rows in the tables as list of messages.
 91			The arguments are used for filtering.
 92
 93			May raise `RequestException`.
 94		"""
 95
 96		kwargs = locals().copy()
 97		params = {}
 98
 99		for k,v in kwargs.items():
100			if k not in ('self',) and not v is None:
101				params[k] = v
102
103		rows = self._get_request('list', params)
104
105		return [
106				MessageDbRow.model_validate(
107					row, context=self._pydantic_context
108				) for row in rows
109			]
110
111	@validate_call
112	def total_messages(self,
113			id:str|None=None, sender:str|None=None, recipient:str|None=None,
114			processed:bool|None=None, solution:bool|None=None,
115			time_after:int|None=None, time_before:int|None=None
116		) -> int:
117		"""
118			Get the total number of rows in the tables matching the filters.
119
120			May raise `RequestException`.
121		"""
122		
123		kwargs = locals().copy()
124		params = {}
125
126		for k,v in kwargs.items():
127			if k not in ('self',) and not v is None:
128				params[k] = v
129
130		return int(self._get_request('app/table/total', params))
131
132	def _get_request(self, endpoint:str, params:Dict[str, Any]):
133		r = requests.get(
134			"{}/{}".format(self.MANAGEMENT_URL, endpoint),
135			params=params
136		)
137
138		if r.status_code == 200:
139			return r.json()
140		else:
141			raise RequestException(str(r.text)+"\n"+str(r.headers))
142
143	@validate_call
144	def send_message(self, message:AgentMessage) -> AgentResponse:
145		"""
146			Send the `message` to the management and return the management's agent response.
147			(On error an agent response with error message).
148		"""
149		try:
150			return AgentResponse.model_validate(
151				self._post_request(
152					"message",
153					message.model_dump_json()
154				)
155			)
156		except RequestException as e:
157			return AgentResponse(
158				count=-1,
159				error=True,
160				error_msg=str(e) 
161			)
162			
163	def _post_request(self, endpoint:str, data:Dict[str, Any]):
164		r = requests.post(
165			"{}/{}".format(self.MANAGEMENT_URL, endpoint),
166			data=data,
167			headers={"accept" : "application/json", "content-type" : "application/json"}
168		)
169
170		if r.status_code == 200:
171			return r.json()
172		else:
173			return RequestException(str(r.text)+"\n"+str(r.headers))
class RequestException(builtins.Exception):
47class RequestException(Exception):
48	"""
49		Raised on http and similar errors.
50	"""
51	pass

Raised on http and similar errors.

Inherited Members
builtins.Exception
Exception
builtins.BaseException
with_traceback
add_note
args
class ManagementRequest:
 53class ManagementRequest():
 54
 55	MANAGEMENT_URL = os.environ.get('MANAGEMENT_URL', 'http://127.0.0.1:80').strip().strip('/')
 56
 57	@validate_call
 58	def __init__(self, allow_lazy:bool=True):
 59		"""
 60			If `allow_lazy` is active, the type checking (by pydantic) is less strict. 
 61			E.g. it does not require that all files in the data section of messages must exist on the file system.
 62		"""
 63		self._allow_lazy = allow_lazy
 64		self._pydantic_context = {
 65			"require_file_exists": not self._allow_lazy
 66		}
 67
 68	@validate_call
 69	def get_message(self, count:int) -> MessageDbRow:
 70		"""
 71			Get a message (like a table row) from the management by using the `count`.
 72
 73			May raise `RequestException`.
 74		"""
 75		row = self._get_request(
 76			'list/single',
 77			{"count": count}
 78		)
 79		return MessageDbRow.model_validate(
 80			row, context=self._pydantic_context
 81		)
 82
 83	@validate_call
 84	def list_messages(self,
 85			id:str|None=None, sender:str|None=None, recipient:str|None=None,
 86			processed:bool|None=None, solution:bool|None=None,
 87			time_after:int|None=None, time_before:int|None=None,
 88			limit:int=10, offset:int=0
 89		) -> List[MessageDbRow]:
 90		"""
 91			Get the rows in the tables as list of messages.
 92			The arguments are used for filtering.
 93
 94			May raise `RequestException`.
 95		"""
 96
 97		kwargs = locals().copy()
 98		params = {}
 99
100		for k,v in kwargs.items():
101			if k not in ('self',) and not v is None:
102				params[k] = v
103
104		rows = self._get_request('list', params)
105
106		return [
107				MessageDbRow.model_validate(
108					row, context=self._pydantic_context
109				) for row in rows
110			]
111
112	@validate_call
113	def total_messages(self,
114			id:str|None=None, sender:str|None=None, recipient:str|None=None,
115			processed:bool|None=None, solution:bool|None=None,
116			time_after:int|None=None, time_before:int|None=None
117		) -> int:
118		"""
119			Get the total number of rows in the tables matching the filters.
120
121			May raise `RequestException`.
122		"""
123		
124		kwargs = locals().copy()
125		params = {}
126
127		for k,v in kwargs.items():
128			if k not in ('self',) and not v is None:
129				params[k] = v
130
131		return int(self._get_request('app/table/total', params))
132
133	def _get_request(self, endpoint:str, params:Dict[str, Any]):
134		r = requests.get(
135			"{}/{}".format(self.MANAGEMENT_URL, endpoint),
136			params=params
137		)
138
139		if r.status_code == 200:
140			return r.json()
141		else:
142			raise RequestException(str(r.text)+"\n"+str(r.headers))
143
144	@validate_call
145	def send_message(self, message:AgentMessage) -> AgentResponse:
146		"""
147			Send the `message` to the management and return the management's agent response.
148			(On error an agent response with error message).
149		"""
150		try:
151			return AgentResponse.model_validate(
152				self._post_request(
153					"message",
154					message.model_dump_json()
155				)
156			)
157		except RequestException as e:
158			return AgentResponse(
159				count=-1,
160				error=True,
161				error_msg=str(e) 
162			)
163			
164	def _post_request(self, endpoint:str, data:Dict[str, Any]):
165		r = requests.post(
166			"{}/{}".format(self.MANAGEMENT_URL, endpoint),
167			data=data,
168			headers={"accept" : "application/json", "content-type" : "application/json"}
169		)
170
171		if r.status_code == 200:
172			return r.json()
173		else:
174			return RequestException(str(r.text)+"\n"+str(r.headers))
@validate_call
ManagementRequest(allow_lazy: bool = True)
57	@validate_call
58	def __init__(self, allow_lazy:bool=True):
59		"""
60			If `allow_lazy` is active, the type checking (by pydantic) is less strict. 
61			E.g. it does not require that all files in the data section of messages must exist on the file system.
62		"""
63		self._allow_lazy = allow_lazy
64		self._pydantic_context = {
65			"require_file_exists": not self._allow_lazy
66		}

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.

MANAGEMENT_URL = 'http://127.0.0.1:80'
@validate_call
def get_message(self, count: int) -> ums.utils.types.MessageDbRow:
68	@validate_call
69	def get_message(self, count:int) -> MessageDbRow:
70		"""
71			Get a message (like a table row) from the management by using the `count`.
72
73			May raise `RequestException`.
74		"""
75		row = self._get_request(
76			'list/single',
77			{"count": count}
78		)
79		return MessageDbRow.model_validate(
80			row, context=self._pydantic_context
81		)

Get a message (like a table row) from the management by using the count.

May raise RequestException.

@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[ums.utils.types.MessageDbRow]:
 83	@validate_call
 84	def list_messages(self,
 85			id:str|None=None, sender:str|None=None, recipient:str|None=None,
 86			processed:bool|None=None, solution:bool|None=None,
 87			time_after:int|None=None, time_before:int|None=None,
 88			limit:int=10, offset:int=0
 89		) -> List[MessageDbRow]:
 90		"""
 91			Get the rows in the tables as list of messages.
 92			The arguments are used for filtering.
 93
 94			May raise `RequestException`.
 95		"""
 96
 97		kwargs = locals().copy()
 98		params = {}
 99
100		for k,v in kwargs.items():
101			if k not in ('self',) and not v is None:
102				params[k] = v
103
104		rows = self._get_request('list', params)
105
106		return [
107				MessageDbRow.model_validate(
108					row, context=self._pydantic_context
109				) for row in rows
110			]

Get the rows in the tables as list of messages. The arguments are used for filtering.

May raise RequestException.

@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:
112	@validate_call
113	def total_messages(self,
114			id:str|None=None, sender:str|None=None, recipient:str|None=None,
115			processed:bool|None=None, solution:bool|None=None,
116			time_after:int|None=None, time_before:int|None=None
117		) -> int:
118		"""
119			Get the total number of rows in the tables matching the filters.
120
121			May raise `RequestException`.
122		"""
123		
124		kwargs = locals().copy()
125		params = {}
126
127		for k,v in kwargs.items():
128			if k not in ('self',) and not v is None:
129				params[k] = v
130
131		return int(self._get_request('app/table/total', params))

Get the total number of rows in the tables matching the filters.

May raise RequestException.

@validate_call
def send_message( self, message: ums.utils.types.AgentMessage) -> ums.utils.types.AgentResponse:
144	@validate_call
145	def send_message(self, message:AgentMessage) -> AgentResponse:
146		"""
147			Send the `message` to the management and return the management's agent response.
148			(On error an agent response with error message).
149		"""
150		try:
151			return AgentResponse.model_validate(
152				self._post_request(
153					"message",
154					message.model_dump_json()
155				)
156			)
157		except RequestException as e:
158			return AgentResponse(
159				count=-1,
160				error=True,
161				error_msg=str(e) 
162			)

Send the message to the management and return the management's agent response. (On error an agent response with error message).