pycityagent 2.0.0a43__cp39-cp39-macosx_11_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. pycityagent/__init__.py +23 -0
  2. pycityagent/agent.py +833 -0
  3. pycityagent/cli/wrapper.py +44 -0
  4. pycityagent/economy/__init__.py +5 -0
  5. pycityagent/economy/econ_client.py +355 -0
  6. pycityagent/environment/__init__.py +7 -0
  7. pycityagent/environment/interact/__init__.py +0 -0
  8. pycityagent/environment/interact/interact.py +198 -0
  9. pycityagent/environment/message/__init__.py +0 -0
  10. pycityagent/environment/sence/__init__.py +0 -0
  11. pycityagent/environment/sence/static.py +416 -0
  12. pycityagent/environment/sidecar/__init__.py +8 -0
  13. pycityagent/environment/sidecar/sidecarv2.py +109 -0
  14. pycityagent/environment/sim/__init__.py +29 -0
  15. pycityagent/environment/sim/aoi_service.py +39 -0
  16. pycityagent/environment/sim/client.py +126 -0
  17. pycityagent/environment/sim/clock_service.py +44 -0
  18. pycityagent/environment/sim/economy_services.py +192 -0
  19. pycityagent/environment/sim/lane_service.py +111 -0
  20. pycityagent/environment/sim/light_service.py +122 -0
  21. pycityagent/environment/sim/person_service.py +295 -0
  22. pycityagent/environment/sim/road_service.py +39 -0
  23. pycityagent/environment/sim/sim_env.py +145 -0
  24. pycityagent/environment/sim/social_service.py +59 -0
  25. pycityagent/environment/simulator.py +331 -0
  26. pycityagent/environment/utils/__init__.py +14 -0
  27. pycityagent/environment/utils/base64.py +16 -0
  28. pycityagent/environment/utils/const.py +244 -0
  29. pycityagent/environment/utils/geojson.py +24 -0
  30. pycityagent/environment/utils/grpc.py +57 -0
  31. pycityagent/environment/utils/map_utils.py +157 -0
  32. pycityagent/environment/utils/port.py +11 -0
  33. pycityagent/environment/utils/protobuf.py +41 -0
  34. pycityagent/llm/__init__.py +11 -0
  35. pycityagent/llm/embeddings.py +231 -0
  36. pycityagent/llm/llm.py +377 -0
  37. pycityagent/llm/llmconfig.py +13 -0
  38. pycityagent/llm/utils.py +6 -0
  39. pycityagent/memory/__init__.py +13 -0
  40. pycityagent/memory/const.py +43 -0
  41. pycityagent/memory/faiss_query.py +302 -0
  42. pycityagent/memory/memory.py +448 -0
  43. pycityagent/memory/memory_base.py +170 -0
  44. pycityagent/memory/profile.py +165 -0
  45. pycityagent/memory/self_define.py +165 -0
  46. pycityagent/memory/state.py +173 -0
  47. pycityagent/memory/utils.py +28 -0
  48. pycityagent/message/__init__.py +3 -0
  49. pycityagent/message/messager.py +88 -0
  50. pycityagent/metrics/__init__.py +6 -0
  51. pycityagent/metrics/mlflow_client.py +147 -0
  52. pycityagent/metrics/utils/const.py +0 -0
  53. pycityagent/pycityagent-sim +0 -0
  54. pycityagent/pycityagent-ui +0 -0
  55. pycityagent/simulation/__init__.py +8 -0
  56. pycityagent/simulation/agentgroup.py +580 -0
  57. pycityagent/simulation/simulation.py +634 -0
  58. pycityagent/simulation/storage/pg.py +184 -0
  59. pycityagent/survey/__init__.py +4 -0
  60. pycityagent/survey/manager.py +54 -0
  61. pycityagent/survey/models.py +120 -0
  62. pycityagent/utils/__init__.py +11 -0
  63. pycityagent/utils/avro_schema.py +109 -0
  64. pycityagent/utils/decorators.py +99 -0
  65. pycityagent/utils/parsers/__init__.py +13 -0
  66. pycityagent/utils/parsers/code_block_parser.py +37 -0
  67. pycityagent/utils/parsers/json_parser.py +86 -0
  68. pycityagent/utils/parsers/parser_base.py +60 -0
  69. pycityagent/utils/pg_query.py +92 -0
  70. pycityagent/utils/survey_util.py +53 -0
  71. pycityagent/workflow/__init__.py +26 -0
  72. pycityagent/workflow/block.py +211 -0
  73. pycityagent/workflow/prompt.py +79 -0
  74. pycityagent/workflow/tool.py +240 -0
  75. pycityagent/workflow/trigger.py +163 -0
  76. pycityagent-2.0.0a43.dist-info/LICENSE +21 -0
  77. pycityagent-2.0.0a43.dist-info/METADATA +235 -0
  78. pycityagent-2.0.0a43.dist-info/RECORD +81 -0
  79. pycityagent-2.0.0a43.dist-info/WHEEL +5 -0
  80. pycityagent-2.0.0a43.dist-info/entry_points.txt +3 -0
  81. pycityagent-2.0.0a43.dist-info/top_level.txt +3 -0
@@ -0,0 +1,295 @@
1
+ import warnings
2
+ from collections.abc import Awaitable, Coroutine
3
+ from typing import Any, Union, cast
4
+
5
+ import grpc
6
+ from google.protobuf.json_format import ParseDict
7
+ from mosstool.trip.generator import default_person_template_generator
8
+ from mosstool.util.format_converter import pb2dict
9
+ from pycityproto.city.person.v2 import person_pb2 as person_pb2
10
+ from pycityproto.city.person.v2 import person_service_pb2 as person_service
11
+ from pycityproto.city.person.v2 import person_service_pb2_grpc as person_grpc
12
+
13
+ from ..utils.protobuf import async_parse
14
+
15
+ __all__ = ["PersonService"]
16
+
17
+
18
+ class PersonService:
19
+ """
20
+ 交通模拟person服务
21
+ Traffic simulation person service
22
+ """
23
+
24
+ def __init__(self, aio_channel: grpc.aio.Channel):
25
+ self._aio_stub = person_grpc.PersonServiceStub(aio_channel)
26
+
27
+ @staticmethod
28
+ def default_person() -> person_pb2.Person:
29
+ """
30
+ 获取person基本模板
31
+ Get person basic template
32
+
33
+ 需要补充的字段有person.home,person.schedules,person.labels
34
+ The fields that need to be supplemented are person.home, person.schedules, person.labels
35
+ """
36
+ person = default_person_template_generator()
37
+ return person
38
+
39
+ @staticmethod
40
+ def default_dict_person() -> dict:
41
+ """
42
+ 获取person基本模板,字典格式
43
+ Get person basic template in dict format.
44
+
45
+ 需要补充的字段有person.home,person.schedules,person.labels
46
+ The fields that need to be supplemented are person.home, person.schedules, person.labels
47
+ """
48
+ person = default_person_template_generator()
49
+ return pb2dict(person)
50
+
51
+ def GetPerson(
52
+ self,
53
+ req: Union[person_service.GetPersonRequest, dict],
54
+ dict_return: bool = True,
55
+ ) -> Coroutine[Any, Any, Union[dict[str, Any], person_service.GetPersonResponse]]:
56
+ """
57
+ 获取person信息
58
+ Get person information
59
+
60
+ Args:
61
+ - req (dict): https://cityproto.sim.fiblab.net/#city.person.v2.GetPersonRequest
62
+
63
+ Returns:
64
+ - https://cityproto.sim.fiblab.net/#city.person.v2.GetPersonResponse
65
+ """
66
+ if type(req) != person_service.GetPersonRequest:
67
+ req = ParseDict(req, person_service.GetPersonRequest())
68
+ res = cast(
69
+ Awaitable[person_service.GetPersonResponse], self._aio_stub.GetPerson(req)
70
+ )
71
+ return async_parse(res, dict_return)
72
+
73
+ def AddPerson(
74
+ self,
75
+ req: Union[person_service.AddPersonRequest, dict],
76
+ dict_return: bool = True,
77
+ ) -> Coroutine[Any, Any, Union[dict[str, Any], person_service.AddPersonResponse]]:
78
+ """
79
+ 新增person
80
+ Add a new person
81
+
82
+ Args:
83
+ - req (dict): https://cityproto.sim.fiblab.net/#city.person.v2.AddPersonRequest
84
+
85
+ Returns:
86
+ - https://cityproto.sim.fiblab.net/#city.person.v2.AddPersonResponse
87
+ """
88
+ if type(req) != person_service.AddPersonRequest:
89
+ req = ParseDict(req, person_service.AddPersonRequest())
90
+ res = cast(
91
+ Awaitable[person_service.AddPersonResponse], self._aio_stub.AddPerson(req)
92
+ )
93
+ return async_parse(res, dict_return)
94
+
95
+ def SetSchedule(
96
+ self,
97
+ req: Union[person_service.SetScheduleRequest, dict],
98
+ dict_return: bool = True,
99
+ ) -> Coroutine[Any, Any, Union[dict[str, Any], person_service.SetScheduleResponse]]:
100
+ """
101
+ 修改person的schedule
102
+ set person's schedule
103
+
104
+ Args:
105
+ - req (dict): https://cityproto.sim.fiblab.net/#city.person.v2.SetScheduleRequest
106
+
107
+ Returns:
108
+ - https://cityproto.sim.fiblab.net/#city.person.v2.SetScheduleResponse
109
+ """
110
+ if type(req) != person_service.SetScheduleRequest:
111
+ req = ParseDict(req, person_service.SetScheduleRequest())
112
+ res = cast(
113
+ Awaitable[person_service.SetScheduleResponse],
114
+ self._aio_stub.SetSchedule(req),
115
+ )
116
+ return async_parse(res, dict_return)
117
+
118
+ def GetPersons(
119
+ self,
120
+ req: Union[person_service.GetPersonsRequest, dict],
121
+ dict_return: bool = True,
122
+ ) -> Coroutine[Any, Any, Union[dict[str, Any], person_service.GetPersonsResponse]]:
123
+ """
124
+ 获取多个person信息
125
+ Get information of multiple persons
126
+
127
+ Args:
128
+ - req (dict): https://cityproto.sim.fiblab.net/#city.person.v2.GetPersonsRequest
129
+
130
+ Returns:
131
+ - https://cityproto.sim.fiblab.net/#city.person.v2.GetPersonsResponse
132
+ """
133
+ if type(req) != person_service.GetPersonsRequest:
134
+ req = ParseDict(req, person_service.GetPersonsRequest())
135
+ res = cast(
136
+ Awaitable[person_service.GetPersonsResponse],
137
+ self._aio_stub.GetPersons(req),
138
+ )
139
+ return async_parse(res, dict_return)
140
+
141
+ def GetPersonByLongLatBBox(
142
+ self,
143
+ req: Union[person_service.GetPersonByLongLatBBoxRequest, dict],
144
+ dict_return: bool = True,
145
+ ) -> Coroutine[
146
+ Any, Any, Union[dict[str, Any], person_service.GetPersonByLongLatBBoxResponse]
147
+ ]:
148
+ """
149
+ 获取特定区域内的person
150
+ Get persons in a specific region
151
+
152
+ Args:
153
+ - req (dict): https://cityproto.sim.fiblab.net/#city.person.v2.GetPersonByLongLatBBoxRequest
154
+
155
+ Returns:
156
+ - https://cityproto.sim.fiblab.net/#city.person.v2.GetPersonByLongLatBBoxResponse
157
+ """
158
+ if type(req) != person_service.GetPersonByLongLatBBoxRequest:
159
+ req = ParseDict(req, person_service.GetPersonByLongLatBBoxRequest())
160
+ res = cast(
161
+ Awaitable[person_service.GetPersonByLongLatBBoxResponse],
162
+ self._aio_stub.GetPersonByLongLatBBox(req),
163
+ )
164
+ return async_parse(res, dict_return)
165
+
166
+ def GetAllVehicles(
167
+ self,
168
+ req: Union[person_service.GetAllVehiclesRequest, dict],
169
+ dict_return: bool = True,
170
+ ) -> Coroutine[
171
+ Any, Any, Union[dict[str, Any], person_service.GetAllVehiclesResponse]
172
+ ]:
173
+ """
174
+ 获取所有车辆
175
+ Get all vehicles
176
+
177
+ Args:
178
+ - req (dict): https://cityproto.sim.fiblab.net/#city.person.v2.GetAllVehiclesRequest
179
+
180
+ Returns:
181
+ - https://cityproto.sim.fiblab.net/#city.person.v2.GetAllVehiclesResponse
182
+ """
183
+ if type(req) != person_service.GetAllVehiclesRequest:
184
+ req = ParseDict(req, person_service.GetAllVehiclesRequest())
185
+ res = cast(
186
+ Awaitable[person_service.GetAllVehiclesResponse],
187
+ self._aio_stub.GetAllVehicles(req),
188
+ )
189
+ return async_parse(res, dict_return)
190
+
191
+ def ResetPersonPosition(
192
+ self,
193
+ req: Union[person_service.ResetPersonPositionRequest, dict],
194
+ dict_return: bool = True,
195
+ ) -> Coroutine[
196
+ Any, Any, Union[dict[str, Any], person_service.ResetPersonPositionResponse]
197
+ ]:
198
+ """
199
+ 重置人的位置(将停止当前正在进行的出行,转为sleep状态)
200
+ Reset person's position (stop the current trip and switch to sleep status)
201
+
202
+ Args:
203
+ - req (dict): https://cityproto.sim.fiblab.net/#city.person.v2.ResetPersonPositionRequest
204
+
205
+ Returns:
206
+ - https://cityproto.sim.fiblab.net/#city.person.v2.ResetPersonPositionResponse
207
+ """
208
+ if type(req) != person_service.ResetPersonPositionRequest:
209
+ req = ParseDict(req, person_service.ResetPersonPositionRequest())
210
+ res = cast(
211
+ Awaitable[person_service.ResetPersonPositionResponse],
212
+ self._aio_stub.ResetPersonPosition(req),
213
+ )
214
+ return async_parse(res, dict_return)
215
+
216
+ # RL接口
217
+
218
+ def SetControlledVehicleIDs(
219
+ self,
220
+ req: Union[person_service.SetControlledVehicleIDsRequest, dict],
221
+ dict_return: bool = True,
222
+ ) -> Coroutine[
223
+ Any, Any, Union[dict[str, Any], person_service.SetControlledVehicleIDsResponse]
224
+ ]:
225
+ """
226
+ 设置由外部控制行为的vehicle
227
+ Set controlled vehicle ID
228
+
229
+ Args:
230
+ - req (dict): https://cityproto.sim.fiblab.net/#city.person.v2.SetControlledVehicleIDsRequest
231
+
232
+ Returns:
233
+ - https://cityproto.sim.fiblab.net/#city.person.v2.SetControlledVehicleIDsResponse
234
+ """
235
+ if type(req) != person_service.SetControlledVehicleIDsRequest:
236
+ req = ParseDict(req, person_service.SetControlledVehicleIDsRequest())
237
+ res = cast(
238
+ Awaitable[person_service.SetControlledVehicleIDsResponse],
239
+ self._aio_stub.SetControlledVehicleIDs(req),
240
+ )
241
+ return async_parse(res, dict_return)
242
+
243
+ def FetchControlledVehicleEnvs(
244
+ self,
245
+ req: Union[person_service.FetchControlledVehicleEnvsRequest, dict],
246
+ dict_return: bool = True,
247
+ ) -> Coroutine[
248
+ Any,
249
+ Any,
250
+ Union[dict[str, Any], person_service.FetchControlledVehicleEnvsResponse],
251
+ ]:
252
+ """
253
+ 获取由外部控制行为的vehicle的环境信息
254
+ Fetch controlled vehicle environment information
255
+
256
+ Args:
257
+ - req (dict): https://cityproto.sim.fiblab.net/#city.person.v2.FetchControlledVehicleEnvsRequest
258
+
259
+ Returns:
260
+ - https://cityproto.sim.fiblab.net/#city.person.v2.FetchControlledVehicleEnvsResponse
261
+ """
262
+ if type(req) != person_service.FetchControlledVehicleEnvsRequest:
263
+ req = ParseDict(req, person_service.FetchControlledVehicleEnvsRequest())
264
+ res = cast(
265
+ Awaitable[person_service.FetchControlledVehicleEnvsResponse],
266
+ self._aio_stub.FetchControlledVehicleEnvs(req),
267
+ )
268
+ return async_parse(res, dict_return)
269
+
270
+ def SetControlledVehicleActions(
271
+ self,
272
+ req: Union[person_service.SetControlledVehicleActionsRequest, dict],
273
+ dict_return: bool = True,
274
+ ) -> Coroutine[
275
+ Any,
276
+ Any,
277
+ Union[dict[str, Any], person_service.SetControlledVehicleActionsResponse],
278
+ ]:
279
+ """
280
+ 设置由外部控制行为的vehicle的行为
281
+ Set controlled vehicle actions
282
+
283
+ Args:
284
+ - req (dict): https://cityproto.sim.fiblab.net/#city.person.v2.SetControlledVehicleActionsRequest
285
+
286
+ Returns:
287
+ - https://cityproto.sim.fiblab.net/#city.person.v2.SetControlledVehicleActionsResponse
288
+ """
289
+ if type(req) != person_service.SetControlledVehicleActionsRequest:
290
+ req = ParseDict(req, person_service.SetControlledVehicleActionsRequest())
291
+ res = cast(
292
+ Awaitable[person_service.SetControlledVehicleActionsResponse],
293
+ self._aio_stub.SetControlledVehicleActions(req),
294
+ )
295
+ return async_parse(res, dict_return)
@@ -0,0 +1,39 @@
1
+ from collections.abc import Awaitable, Coroutine
2
+ from typing import Any, Union, cast
3
+
4
+ import grpc
5
+ from google.protobuf.json_format import ParseDict
6
+ from pycityproto.city.map.v2 import road_service_pb2 as road_service
7
+ from pycityproto.city.map.v2 import road_service_pb2_grpc as road_grpc
8
+
9
+ from ..utils.protobuf import async_parse
10
+
11
+ __all__ = ["RoadService"]
12
+
13
+
14
+ class RoadService:
15
+ """
16
+ 交通模拟road服务
17
+ Traffic simulation road service
18
+ """
19
+
20
+ def __init__(self, aio_channel: grpc.aio.Channel):
21
+ self._aio_stub = road_grpc.RoadServiceStub(aio_channel)
22
+
23
+ def GetRoad(
24
+ self, req: Union[road_service.GetRoadRequest, dict], dict_return: bool = True
25
+ ) -> Coroutine[Any, Any, Union[dict[str, Any], road_service.GetRoadResponse]]:
26
+ """
27
+ 查询道路信息
28
+ Query road information
29
+
30
+ Args:
31
+ - req (dict): https://cityproto.sim.fiblab.net/#city.map.v2.GetRoadRequest
32
+
33
+ Returns:
34
+ - https://cityproto.sim.fiblab.net/#city.map.v2.GetRoadResponse
35
+ """
36
+ if type(req) != road_service.GetRoadRequest:
37
+ req = ParseDict(req, road_service.GetRoadRequest())
38
+ res = cast(Awaitable[road_service.GetRoadResponse], self._aio_stub.GetRoad(req))
39
+ return async_parse(res, dict_return)
@@ -0,0 +1,145 @@
1
+ import logging
2
+ import os
3
+ import time
4
+ import atexit
5
+ from subprocess import DEVNULL, Popen
6
+ from typing import Optional
7
+
8
+ from pycitydata.map import Map
9
+
10
+ from ..utils import encode_to_base64, find_free_port
11
+
12
+ __all__ = ["ControlSimEnv"]
13
+
14
+
15
+ def _generate_yaml_config(map_file: str, start_step: int, total_step: int) -> str:
16
+ map_file = os.path.abspath(map_file)
17
+ return f"""
18
+ input:
19
+ # 地图
20
+ map:
21
+ file: "{map_file}"
22
+
23
+ control:
24
+ step:
25
+ # 模拟器起始步
26
+ start: {start_step}
27
+ # 模拟总步数,结束步为起始步+总步数
28
+ total: {total_step}
29
+ # 每步的时间间隔
30
+ interval: 1
31
+ skip_overtime_trip_when_init: true
32
+ enable_platoon: false
33
+ enable_indoor: false
34
+ prefer_fixed_light: true
35
+ enable_collision_avoidance: false # 计算性能下降10倍,需要保证subloop>=5
36
+ enable_go_astray: true # 引入串行的路径规划调用,计算性能下降(幅度不确定)
37
+ lane_change_model: earliest # mobil (主动变道+强制变道,默认值) earliest (总是尽可能早地变道)
38
+
39
+ output:
40
+ """
41
+
42
+
43
+ class ControlSimEnv:
44
+ def __init__(
45
+ self,
46
+ task_name: str,
47
+ map_file: str,
48
+ # person_file,
49
+ start_step: int,
50
+ total_step: int,
51
+ log_dir: str,
52
+ min_step_time: int = 1000,
53
+ timeout: int = 5,
54
+ simuletgo_addr: Optional[str] = None,
55
+ ):
56
+ self._task_name = task_name
57
+ self._map_file = map_file
58
+ # self._person_file = person_file
59
+ self._start_step = start_step
60
+ self._total_step = total_step
61
+ self._log_dir = log_dir
62
+ self._min_step_time = min_step_time
63
+ self._timeout = timeout
64
+ self.m = Map(pb_path=map_file)
65
+ """
66
+ 地图数据
67
+ """
68
+
69
+ # 检查二进制文件是否存在
70
+ # simulet-go: ~/.local/bin/simulet-go
71
+ self._simuletgo_path = os.path.expanduser("~/.local/bin/simulet-go")
72
+ if not os.path.exists(os.path.expanduser(self._simuletgo_path)):
73
+ raise FileNotFoundError("simulet-go not found, please install it first")
74
+
75
+ self._simuletgo_config = _generate_yaml_config(map_file, start_step, total_step)
76
+ self.simuletgo_port = None
77
+ self._simuletgo_proc = None
78
+ self._traffic_client = None
79
+
80
+ os.makedirs(log_dir, exist_ok=True)
81
+
82
+ self.simuletgo_addr = self.reset(simuletgo_addr)
83
+
84
+ def reset(
85
+ self,
86
+ simuletgo_addr: Optional[str] = None,
87
+ ):
88
+ """
89
+ Args:
90
+ - simuletgo_addr: str, simulet-go的地址。如果为None,则启动一个新的simulet-go
91
+ """
92
+
93
+ # 三个地址必须同时为None或者同时不为None
94
+ if simuletgo_addr is None:
95
+ # 1. 启动simulet-go
96
+ # ./simulet-go -config-data configbase64 -job test -syncer http://localhost:53001 -listen :51102
97
+ assert self.simuletgo_port is None
98
+ assert self._simuletgo_proc is None
99
+ self.simuletgo_port = find_free_port()
100
+ config_base64 = encode_to_base64(self._simuletgo_config)
101
+ self._simuletgo_proc = Popen(
102
+ [
103
+ self._simuletgo_path,
104
+ "-config-data",
105
+ config_base64,
106
+ "-job",
107
+ self._task_name,
108
+ "-listen",
109
+ f":{self.simuletgo_port}",
110
+ "-run.min_step_time",
111
+ f"{self._min_step_time}",
112
+ "-output",
113
+ self._log_dir,
114
+ "-cache",
115
+ "",
116
+ "-log.level",
117
+ "error",
118
+ ],
119
+ # 忽略输出
120
+ # stdout=DEVNULL,
121
+ )
122
+ logging.info(
123
+ f"start simulet-go at localhost:{self.simuletgo_port}, PID={self._simuletgo_proc.pid}"
124
+ )
125
+ simuletgo_addr = f"http://localhost:{self.simuletgo_port}"
126
+ atexit.register(self.close)
127
+ time.sleep(1)
128
+ elif simuletgo_addr is not None:
129
+ pass
130
+ else:
131
+ # raise ValueError(
132
+ # "simuletgo_addr, syncer_addr, routing_addr must be all None or all not None"
133
+ # )
134
+ pass
135
+ return simuletgo_addr
136
+
137
+ def close(self):
138
+ if self._simuletgo_proc is not None:
139
+ self._simuletgo_proc.terminate()
140
+ simuletgo_code = self._simuletgo_proc.wait()
141
+ logging.info(f"simulet-go exit with code {simuletgo_code}")
142
+
143
+ self.simuletgo_port = None
144
+ self._simuletgo_proc = None
145
+ self._traffic_client = None
@@ -0,0 +1,59 @@
1
+ from collections.abc import Awaitable, Coroutine
2
+ from typing import Any, Union, cast
3
+
4
+ import grpc
5
+ from google.protobuf.json_format import ParseDict
6
+ from pycityproto.city.social.v1 import social_service_pb2 as social_service
7
+ from pycityproto.city.social.v1 import social_service_pb2_grpc as social_grpc
8
+
9
+ from ..utils.protobuf import async_parse
10
+
11
+ __all__ = ["SocialService"]
12
+
13
+
14
+ class SocialService:
15
+ """
16
+ 城市模拟社交服务
17
+ City simulation social service
18
+ """
19
+
20
+ def __init__(self, aio_channel: grpc.aio.Channel):
21
+ self._aio_stub = social_grpc.SocialServiceStub(aio_channel)
22
+
23
+ def Send(
24
+ self, req: Union[social_service.SendRequest, dict], dict_return: bool = True
25
+ ) -> Coroutine[Any, Any, Union[dict[str, Any], social_service.SendResponse]]:
26
+ """
27
+ 发送消息
28
+ Send message
29
+
30
+ Args:
31
+ - req (dict): https://cityproto.sim.fiblab.net/#city.social.v1.SendRequest
32
+
33
+ Returns:
34
+ - https://cityproto.sim.fiblab.net/#city.social.v1.SendResponse
35
+ """
36
+ if type(req) != social_service.SendRequest:
37
+ req = ParseDict(req, social_service.SendRequest())
38
+ res = cast(Awaitable[social_service.SendResponse], self._aio_stub.Send(req))
39
+ return async_parse(res, dict_return)
40
+
41
+ def Receive(
42
+ self, req: Union[social_service.ReceiveRequest, dict], dict_return: bool = True
43
+ ) -> Coroutine[Any, Any, Union[dict[str, Any], social_service.ReceiveResponse]]:
44
+ """
45
+ 接收消息
46
+ Receive message
47
+
48
+ Args:
49
+ - req (dict): https://cityproto.sim.fiblab.net/#city.social.v1.ReceiveRequest
50
+
51
+ Returns:
52
+ - https://cityproto.sim.fiblab.net/#city.social.v1.ReceiveResponse
53
+ """
54
+ if type(req) != social_service.ReceiveRequest:
55
+ req = ParseDict(req, social_service.ReceiveRequest())
56
+ res = cast(
57
+ Awaitable[social_service.ReceiveResponse], self._aio_stub.Receive(req)
58
+ )
59
+ return async_parse(res, dict_return)