Skip to content

Commit 00895ac

Browse files
committed
chore: rpc route are the same as ruby
1 parent cc0880a commit 00895ac

File tree

6 files changed

+81
-73
lines changed

6 files changed

+81
-73
lines changed

src/agent_rpc/forestadmin/agent_rpc/agent.py

+32-30
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
ActionFormValuesSerializer,
1616
ActionResultSerializer,
1717
)
18-
from forestadmin.rpc_common.serializers.aes import aes_decrypt, aes_encrypt
1918
from forestadmin.rpc_common.serializers.collection.aggregation import AggregationSerializer
2019
from forestadmin.rpc_common.serializers.collection.filter import (
2120
FilterSerializer,
@@ -42,6 +41,7 @@ def __init__(self, options: RpcOptions):
4241

4342
@web.middleware
4443
async def hmac_middleware(self, request: web.Request, handler):
44+
# TODO: handle HMAC like ruby agent
4545
if request.method == "POST":
4646
body = await request.read()
4747
if not is_valid_hmac(
@@ -51,20 +51,21 @@ async def hmac_middleware(self, request: web.Request, handler):
5151
return await handler(request)
5252

5353
def setup_routes(self):
54+
self.app.router.add_route("GET", "/", lambda _: web.Response(text="OK")) # type: ignore
5455
self.app.router.add_route("GET", "/sse", self.sse_handler)
5556
self.app.router.add_route("GET", "/schema", self.schema)
56-
self.app.router.add_route("POST", "/collection/list", self.collection_list)
57-
self.app.router.add_route("POST", "/collection/create", self.collection_create)
58-
self.app.router.add_route("POST", "/collection/update", self.collection_update)
59-
self.app.router.add_route("POST", "/collection/delete", self.collection_delete)
60-
self.app.router.add_route("POST", "/collection/aggregate", self.collection_aggregate)
61-
self.app.router.add_route("POST", "/collection/get-form", self.collection_get_form)
62-
self.app.router.add_route("POST", "/collection/execute", self.collection_execute)
63-
self.app.router.add_route("POST", "/collection/render-chart", self.collection_render_chart)
64-
65-
self.app.router.add_route("POST", "/execute-native-query", self.native_query)
66-
self.app.router.add_route("POST", "/render-chart", self.render_chart)
67-
self.app.router.add_route("GET", "/", lambda _: web.Response(text="OK")) # type: ignore
57+
58+
# self.app.router.add_route("POST", "/execute-native-query", self.native_query)
59+
self.app.router.add_route("POST", "/forest/rpc/datasource-chart", self.render_chart)
60+
61+
self.app.router.add_route("POST", "/forest/rpc/{collection_name}/list", self.collection_list)
62+
self.app.router.add_route("POST", "/forest/rpc/{collection_name}/create", self.collection_create)
63+
self.app.router.add_route("POST", "/forest/rpc/{collection_name}/update", self.collection_update)
64+
self.app.router.add_route("POST", "/forest/rpc/{collection_name}/delete", self.collection_delete)
65+
self.app.router.add_route("POST", "/forest/rpc/{collection_name}/aggregate", self.collection_aggregate)
66+
self.app.router.add_route("POST", "/forest/rpc/{collection_name}/action-form", self.collection_get_form)
67+
self.app.router.add_route("POST", "/forest/rpc/{collection_name}/action-execute", self.collection_execute)
68+
self.app.router.add_route("POST", "/forest/rpc/{collection_name}/chart", self.collection_render_chart)
6869

6970
async def sse_handler(self, request: web.Request) -> web.StreamResponse:
7071
async with sse_response(request) as resp:
@@ -83,7 +84,7 @@ async def schema(self, request):
8384
async def collection_list(self, request: web.Request):
8485
body_params = await request.json()
8586
ds = await self.customizer.get_datasource()
86-
collection = ds.get_collection(body_params["collectionName"])
87+
collection = ds.get_collection(request.match_info["collection_name"])
8788
caller = CallerSerializer.deserialize(body_params["caller"])
8889
filter_ = PaginatedFilterSerializer.deserialize(body_params["filter"], collection) # type:ignore
8990
projection = ProjectionSerializer.deserialize(body_params["projection"])
@@ -97,7 +98,7 @@ async def collection_create(self, request: web.Request):
9798
body_params = json.loads(body_params)
9899
ds = await self.customizer.get_datasource()
99100

100-
collection = ds.get_collection(body_params["collectionName"])
101+
collection = ds.get_collection(request.match_info["collection_name"])
101102
caller = CallerSerializer.deserialize(body_params["caller"])
102103
data = [RecordSerializer.deserialize(r, collection) for r in body_params["data"]] # type:ignore
103104

@@ -110,7 +111,7 @@ async def collection_update(self, request: web.Request):
110111
body_params = json.loads(body_params)
111112

112113
ds = await self.customizer.get_datasource()
113-
collection = ds.get_collection(body_params["collectionName"])
114+
collection = ds.get_collection(request.match_info["collection_name"])
114115
caller = CallerSerializer.deserialize(body_params["caller"])
115116
filter_ = FilterSerializer.deserialize(body_params["filter"], collection) # type:ignore
116117
patch = RecordSerializer.deserialize(body_params["patch"], collection) # type:ignore
@@ -121,7 +122,7 @@ async def collection_update(self, request: web.Request):
121122
async def collection_delete(self, request: web.Request):
122123
body_params = await request.json()
123124
ds = await self.customizer.get_datasource()
124-
collection = ds.get_collection(body_params["collectionName"])
125+
collection = ds.get_collection(request.match_info["collection_name"])
125126
caller = CallerSerializer.deserialize(body_params["caller"])
126127
filter_ = FilterSerializer.deserialize(body_params["filter"], collection) # type:ignore
127128

@@ -131,7 +132,7 @@ async def collection_delete(self, request: web.Request):
131132
async def collection_aggregate(self, request: web.Request):
132133
body_params = await request.json()
133134
ds = await self.customizer.get_datasource()
134-
collection = ds.get_collection(body_params["collectionName"])
135+
collection = ds.get_collection(request.match_info["collection_name"])
135136
caller = CallerSerializer.deserialize(body_params["caller"])
136137
filter_ = FilterSerializer.deserialize(body_params["filter"], collection) # type:ignore
137138
aggregation = AggregationSerializer.deserialize(body_params["aggregation"])
@@ -144,7 +145,7 @@ async def collection_get_form(self, request: web.Request):
144145
body_params = json.loads(body_params)
145146

146147
ds = await self.customizer.get_datasource()
147-
collection = ds.get_collection(body_params["collectionName"])
148+
collection = ds.get_collection(request.match_info["collection_name"])
148149

149150
caller = CallerSerializer.deserialize(body_params["caller"])
150151
action_name = body_params["actionName"]
@@ -163,7 +164,7 @@ async def collection_execute(self, request: web.Request):
163164
body_params = json.loads(body_params)
164165

165166
ds = await self.customizer.get_datasource()
166-
collection = ds.get_collection(body_params["collectionName"])
167+
collection = ds.get_collection(request.match_info["collection_name"])
167168

168169
caller = CallerSerializer.deserialize(body_params["caller"])
169170
action_name = body_params["actionName"]
@@ -181,7 +182,7 @@ async def collection_render_chart(self, request: web.Request):
181182
body_params = json.loads(body_params)
182183

183184
ds = await self.customizer.get_datasource()
184-
collection = ds.get_collection(body_params["collectionName"])
185+
collection = ds.get_collection(request.match_info["collection_name"])
185186

186187
caller = CallerSerializer.deserialize(body_params["caller"])
187188
name = body_params["name"]
@@ -220,17 +221,18 @@ async def render_chart(self, request: web.Request):
220221
result = await ds.render_chart(caller, name)
221222
return web.json_response(result)
222223

223-
async def native_query(self, request: web.Request):
224-
body_params = await request.text()
225-
body_params = json.loads(body_params)
224+
# TODO: speak about; it's currently not implemented in ruby
225+
# async def native_query(self, request: web.Request):
226+
# body_params = await request.text()
227+
# body_params = json.loads(body_params)
226228

227-
ds = await self.customizer.get_datasource()
228-
connection_name = body_params["connectionName"]
229-
native_query = body_params["nativeQuery"]
230-
parameters = body_params["parameters"]
229+
# ds = await self.customizer.get_datasource()
230+
# connection_name = body_params["connectionName"]
231+
# native_query = body_params["nativeQuery"]
232+
# parameters = body_params["parameters"]
231233

232-
result = await ds.execute_native_query(connection_name, native_query, parameters)
233-
return web.json_response(result)
234+
# result = await ds.execute_native_query(connection_name, native_query, parameters)
235+
# return web.json_response(result)
234236

235237
def start(self):
236238
web.run_app(self.app, host=self.listen_addr, port=int(self.listen_port))

src/datasource_rpc/forestadmin/datasource_rpc/collection.py

+8-8
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ async def list(self, caller: User, filter_: PaginatedFilter, projection: Project
6060
"projection": ProjectionSerializer.serialize(projection),
6161
"collectionName": self.name,
6262
}
63-
ret = await self.datasource.requester.list(body=body)
63+
ret = await self.datasource.requester.list(self.name, body)
6464
return [RecordSerializer.deserialize(record, self) for record in ret]
6565

6666
async def create(self, caller: User, data: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
@@ -69,7 +69,7 @@ async def create(self, caller: User, data: List[Dict[str, Any]]) -> List[Dict[st
6969
"data": [RecordSerializer.serialize(r) for r in data],
7070
"collectionName": self.name,
7171
}
72-
response = await self.datasource.requester.create(body)
72+
response = await self.datasource.requester.create(self.name, body)
7373
return [RecordSerializer.deserialize(record, self) for record in response]
7474

7575
async def update(self, caller: User, filter_: Optional[Filter], patch: Dict[str, Any]) -> None:
@@ -79,7 +79,7 @@ async def update(self, caller: User, filter_: Optional[Filter], patch: Dict[str,
7979
"patch": RecordSerializer.serialize(patch),
8080
"collectionName": self.name,
8181
}
82-
await self.datasource.requester.update(body)
82+
await self.datasource.requester.update(self.name, body)
8383

8484
async def delete(self, caller: User, filter_: Filter | None) -> None:
8585
body = json.dumps(
@@ -89,7 +89,7 @@ async def delete(self, caller: User, filter_: Filter | None) -> None:
8989
"collectionName": self.name,
9090
}
9191
)
92-
await self.datasource.requester.delete(body)
92+
await self.datasource.requester.delete(self.name, body)
9393

9494
async def aggregate(
9595
self, caller: User, filter_: Filter | None, aggregation: Aggregation, limit: int | None = None
@@ -100,7 +100,7 @@ async def aggregate(
100100
"aggregation": AggregationSerializer.serialize(aggregation),
101101
"collectionName": self.name,
102102
}
103-
response = await self.datasource.requester.aggregate(body)
103+
response = await self.datasource.requester.aggregate(self.name, body)
104104
return response
105105

106106
async def get_form(
@@ -125,7 +125,7 @@ async def get_form(
125125
"collectionName": self.name,
126126
"actionName": name,
127127
}
128-
response = await self.datasource.requester.get_form(body)
128+
response = await self.datasource.requester.get_form(self.name, body)
129129
return ActionFormSerializer.deserialize(response) # type: ignore
130130

131131
async def execute(
@@ -145,7 +145,7 @@ async def execute(
145145
"collectionName": self.name,
146146
"actionName": name,
147147
}
148-
response = await self.datasource.requester.execute(body)
148+
response = await self.datasource.requester.execute(self.name, body)
149149
return ActionResultSerializer.deserialize(response)
150150

151151
async def render_chart(self, caller: User, name: str, record_id: List) -> Chart:
@@ -176,7 +176,7 @@ async def render_chart(self, caller: User, name: str, record_id: List) -> Chart:
176176
"collectionName": self.name,
177177
"recordId": ret,
178178
}
179-
return await self.datasource.requester.collection_render_chart(body)
179+
return await self.datasource.requester.collection_render_chart(self.name, body)
180180

181181
def get_native_driver(self):
182182
ForestLogger.log(

src/datasource_rpc/forestadmin/datasource_rpc/datasource.py

+10-7
Original file line numberDiff line numberDiff line change
@@ -104,14 +104,17 @@ async def sse_callback(self):
104104
)
105105
self.thread.start()
106106

107+
# TODO: speak about; it's currently not implemented in ruby
108+
# async def execute_native_query(self, connection_name: str, native_query: str, parameters: Dict[str, str]) -> Any:
109+
# return await self.requester.native_query(
110+
# {
111+
# "connectionName": connection_name,
112+
# "nativeQuery": native_query,
113+
# "parameters": parameters,
114+
# }
115+
# )
107116
async def execute_native_query(self, connection_name: str, native_query: str, parameters: Dict[str, str]) -> Any:
108-
return await self.requester.native_query(
109-
{
110-
"connectionName": connection_name,
111-
"nativeQuery": native_query,
112-
"parameters": parameters,
113-
}
114-
)
117+
raise NotImplementedError
115118

116119
async def render_chart(self, caller: User, name: str) -> Chart:
117120
if name not in self._schema["charts"].keys():

src/datasource_rpc/forestadmin/datasource_rpc/requester.py

+29-27
Original file line numberDiff line numberDiff line change
@@ -53,25 +53,27 @@ async def schema(self) -> dict:
5353
else:
5454
raise Exception(f"Failed to get schema: {response.status}")
5555

56-
async def native_query(self, body):
57-
"""Execute a native query."""
58-
async with aiohttp.ClientSession() as session:
59-
async with session.post(
60-
f"http://{self.connection_uri}/execute-native-query",
61-
json=body,
62-
headers={"X-FOREST-HMAC": generate_hmac(self.secret_key.encode("utf-8"), body.encode("utf-8"))},
63-
) as response:
64-
if response.status == 200:
65-
return await response.json()
66-
else:
67-
raise Exception(f"Failed to execute native query: {response.status}")
56+
# TODO: speak about; it's currently not implemented in ruby
57+
# async def native_query(self, body):
58+
# """Execute a native query."""
59+
# async with aiohttp.ClientSession() as session:
60+
# async with session.post(
61+
# f"http://{self.connection_uri}/execute-native-query",
62+
# json=body,
63+
# headers={"X-FOREST-HMAC": generate_hmac(self.secret_key.encode("utf-8"), body.encode("utf-8"))},
64+
# ) as response:
65+
# if response.status == 200:
66+
# return await response.json()
67+
# else:
68+
# raise Exception(f"Failed to execute native query: {response.status}")
6869

6970
async def datasource_render_chart(self, body):
7071
"""Render a chart."""
7172
async with aiohttp.ClientSession() as session:
7273
async with session.post(
73-
f"http://{self.connection_uri}/render-chart",
74+
f"http://{self.connection_uri}/forest/rpc/datasource-chart",
7475
json=body,
76+
# TODO: handle HMAC like ruby agent
7577
headers={"X-FOREST-HMAC": generate_hmac(self.secret_key.encode("utf-8"), body.encode("utf-8"))},
7678
) as response:
7779
if response.status == 200:
@@ -81,11 +83,11 @@ async def datasource_render_chart(self, body):
8183

8284
# methods for collection
8385

84-
async def list(self, body) -> list[dict]:
86+
async def list(self, collection_name, body) -> list[dict]:
8587
"""List records in a collection."""
8688
async with aiohttp.ClientSession() as session:
8789
async with session.post(
88-
f"http://{self.connection_uri}/collection/list",
90+
f"http://{self.connection_uri}/forest/rpc/{collection_name}/list",
8991
json=body,
9092
headers={"X-FOREST-HMAC": generate_hmac(self.secret_key.encode("utf-8"), body.encode("utf-8"))},
9193
) as response:
@@ -107,11 +109,11 @@ async def create(self, body) -> List[dict]:
107109
else:
108110
raise Exception(f"Failed to create query: {response.status}")
109111

110-
async def update(self, body):
112+
async def update(self, collection_name, body):
111113
"""Update records in a collection."""
112114
async with aiohttp.ClientSession() as session:
113115
async with session.post(
114-
f"http://{self.connection_uri}/collection/update",
116+
f"http://{self.connection_uri}/forest/rpc/{collection_name}/update",
115117
json=body,
116118
headers={"X-FOREST-HMAC": generate_hmac(self.secret_key.encode("utf-8"), body.encode("utf-8"))},
117119
) as response:
@@ -120,11 +122,11 @@ async def update(self, body):
120122
else:
121123
raise Exception(f"Failed to update query: {response.status}")
122124

123-
async def delete(self, body):
125+
async def delete(self, collection_name, body):
124126
"""Delete records in a collection."""
125127
async with aiohttp.ClientSession() as session:
126128
async with session.post(
127-
f"http://{self.connection_uri}/collection/delete",
129+
f"http://{self.connection_uri}/forest/rpc/{collection_name}/delete",
128130
json=body,
129131
headers={"X-FOREST-HMAC": generate_hmac(self.secret_key.encode("utf-8"), body.encode("utf-8"))},
130132
) as response:
@@ -133,11 +135,11 @@ async def delete(self, body):
133135
else:
134136
raise Exception(f"Failed to delete query: {response.status}")
135137

136-
async def aggregate(self, body):
138+
async def aggregate(self, collection_name, body):
137139
"""Aggregate records in a collection."""
138140
async with aiohttp.ClientSession() as session:
139141
async with session.post(
140-
f"http://{self.connection_uri}/collection/aggregate",
142+
f"http://{self.connection_uri}/forest/rpc/{collection_name}/aggregate",
141143
json=body,
142144
headers={"X-FOREST-HMAC": generate_hmac(self.secret_key.encode("utf-8"), body.encode("utf-8"))},
143145
) as response:
@@ -146,11 +148,11 @@ async def aggregate(self, body):
146148
else:
147149
raise Exception(f"Failed to aggregate query: {response.status}")
148150

149-
async def get_form(self, body):
151+
async def get_form(self, collection_name, body):
150152
"""Get the form for an action."""
151153
async with aiohttp.ClientSession() as session:
152154
async with session.post(
153-
f"http://{self.connection_uri}/collection/get-form",
155+
f"http://{self.connection_uri}/forest/rpc/{collection_name}/action-form",
154156
json=body,
155157
headers={"X-FOREST-HMAC": generate_hmac(self.secret_key.encode("utf-8"), body.encode("utf-8"))},
156158
) as response:
@@ -159,11 +161,11 @@ async def get_form(self, body):
159161
else:
160162
raise Exception(f"Failed to aggregate query: {response.status}")
161163

162-
async def execute(self, body):
164+
async def execute(self, collection_name, body):
163165
"""Execute an action."""
164166
async with aiohttp.ClientSession() as session:
165167
async with session.post(
166-
f"http://{self.connection_uri}/collection/execute",
168+
f"http://{self.connection_uri}/forest/rpc/{collection_name}/action-execute",
167169
json=body,
168170
headers={"X-FOREST-HMAC": generate_hmac(self.secret_key.encode("utf-8"), body.encode("utf-8"))},
169171
) as response:
@@ -172,11 +174,11 @@ async def execute(self, body):
172174
else:
173175
raise Exception(f"Failed to execute query: {response.status}")
174176

175-
async def collection_render_chart(self, body):
177+
async def collection_render_chart(self, collection_name, body):
176178
"""Render a chart."""
177179
async with aiohttp.ClientSession() as session:
178180
async with session.post(
179-
f"http://{self.connection_uri}/render-chart",
181+
f"http://{self.connection_uri}/forest/rpc/{collection_name}/chart",
180182
json=body,
181183
headers={"X-FOREST-HMAC": generate_hmac(self.secret_key.encode("utf-8"), body.encode("utf-8"))},
182184
) as response:

0 commit comments

Comments
 (0)