darabos commited on
Commit
b34d742
·
1 Parent(s): 0213da5

Export the constructed Chat API through an HTTP endpoint.

Browse files
server/executors/one_by_one.py CHANGED
@@ -140,3 +140,4 @@ def execute(ws, catalog, cache=None):
140
  else:
141
  tasks.setdefault(edge.target, []).extend(results)
142
  tasks = next_stage
 
 
140
  else:
141
  tasks.setdefault(edge.target, []).extend(results)
142
  tasks = next_stage
143
+ return contexts
server/lynxscribe_ops.py CHANGED
@@ -163,3 +163,38 @@ def view(input):
163
  }}
164
  }
165
  return v
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
163
  }}
164
  }
165
  return v
166
+
167
+ async def api_service(request):
168
+ '''
169
+ Serves a chat endpoint that matches LynxScribe's interface.
170
+ To access it you need to add the "module" and "workspace"
171
+ parameters.
172
+ The workspace must contain exactly one "Chat API" node.
173
+
174
+ curl -X POST ${LYNXKITE_URL}/api/service \
175
+ -H "Content-Type: application/json" \
176
+ -d '{
177
+ "module": "server.lynxscribe_ops",
178
+ "workspace": "LynxScribe demo",
179
+ "session_id": "b43215a0-428f-11ef-9454-0242ac120002",
180
+ "question": "what does the fox say",
181
+ "history": [],
182
+ "user_id": "x",
183
+ "meta_inputs": {}
184
+ }'
185
+ '''
186
+ import pathlib
187
+ from . import workspace
188
+ DATA_PATH = pathlib.Path.cwd() / 'data'
189
+ path = DATA_PATH / request['workspace']
190
+ assert path.is_relative_to(DATA_PATH)
191
+ assert path.exists(), f'Workspace {path} does not exist'
192
+ ws = workspace.load(path)
193
+ contexts = ops.EXECUTORS[ENV](ws)
194
+ nodes = [op for op in ws.nodes if op.data.title == 'Chat API']
195
+ [node] = nodes
196
+ context = contexts[node.id]
197
+ chat_api = context.last_result['chat_api']
198
+ request = ChatAPIRequest(session_id=request['session_id'], question=request['question'], history=request['history'])
199
+ response = await chat_api.answer(request)
200
+ return response
server/main.py CHANGED
@@ -1,15 +1,18 @@
1
  import dataclasses
2
  import fastapi
 
3
  import pathlib
4
  import pkgutil
5
  from . import ops
6
  from . import workspace
7
 
8
  here = pathlib.Path(__file__).parent
 
9
  for _, name, _ in pkgutil.iter_modules([str(here)]):
10
  if name.endswith('_ops') and not name.startswith('test_'):
11
  print(f'Importing {name}')
12
- __import__(f'server.{name}')
 
13
 
14
  app = fastapi.FastAPI()
15
 
@@ -67,3 +70,9 @@ def make_dir(req: dict):
67
  assert not path.exists()
68
  path.mkdir()
69
  return list_dir(path.parent)
 
 
 
 
 
 
 
1
  import dataclasses
2
  import fastapi
3
+ import importlib
4
  import pathlib
5
  import pkgutil
6
  from . import ops
7
  from . import workspace
8
 
9
  here = pathlib.Path(__file__).parent
10
+ lynxkite_modules = {}
11
  for _, name, _ in pkgutil.iter_modules([str(here)]):
12
  if name.endswith('_ops') and not name.startswith('test_'):
13
  print(f'Importing {name}')
14
+ name = f'server.{name}'
15
+ lynxkite_modules[name] = importlib.import_module(name)
16
 
17
  app = fastapi.FastAPI()
18
 
 
70
  assert not path.exists()
71
  path.mkdir()
72
  return list_dir(path.parent)
73
+
74
+ @app.post("/api/service")
75
+ async def service(req: dict):
76
+ '''Executors can provide extra HTTP APIs through the /api/service endpoint.'''
77
+ module = lynxkite_modules[req['module']]
78
+ return await module.api_service(req)