flock-core 0.4.0b40__py3-none-any.whl → 0.4.0b43__py3-none-any.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.

Potentially problematic release.


This version of flock-core might be problematic. Click here for more details.

@@ -27,6 +27,8 @@ class FlockEndpoint(BaseModel):
27
27
  # Optional schema models
28
28
  request_model: type[BaseModel] | None = None
29
29
  response_model: type[BaseModel] | None = None
30
+ # Query-string parameters as a Pydantic model (treated as Depends())
31
+ query_model: type[BaseModel] | None = None
30
32
 
31
33
  # OpenAPI / Swagger metadata
32
34
  summary: str | None = None
@@ -34,6 +36,9 @@ class FlockEndpoint(BaseModel):
34
36
  name: str | None = None # Route name in FastAPI
35
37
  include_in_schema: bool = True
36
38
 
39
+ # FastAPI dependency injections (e.g. security)
40
+ dependencies: list[Any] | None = None
41
+
37
42
  model_config = {
38
43
  "arbitrary_types_allowed": True,
39
44
  "validate_default": True,
flock/core/api/main.py CHANGED
@@ -133,65 +133,82 @@ class FlockAPI:
133
133
  if self.custom_endpoints:
134
134
  import inspect
135
135
 
136
- from fastapi import Request
136
+ from fastapi import Body, Depends, Request
137
137
 
138
138
  # Register any endpoints collected during __init__ (self.custom_endpoints)
139
139
  if self.custom_endpoints:
140
- from fastapi import Body
141
-
142
- def _create_handler_factory(callback: Callable[..., Any], req_model: type[BaseModel] | None):
143
-
140
+ def _create_handler_factory(callback: Callable[..., Any], req_model: type[BaseModel] | None, query_model: type[BaseModel] | None):
141
+ async def _invoke(request: Request, body, query):
142
+ payload: dict[str, Any] = {"flock": self.flock}
143
+ if request:
144
+ payload.update(request.path_params)
145
+ if query is None:
146
+ payload["query"] = dict(request.query_params)
147
+ else:
148
+ payload["query"] = query
149
+ else:
150
+ payload["query"] = query or {}
151
+ if body is not None:
152
+ payload["body"] = body
153
+ elif request and request.method in {"POST", "PUT", "PATCH"} and req_model is None:
154
+ try:
155
+ payload["body"] = await request.json()
156
+ except Exception:
157
+ payload["body"] = await request.body()
158
+
159
+ sig = inspect.signature(callback)
160
+ filtered_kwargs = {k: v for k, v in payload.items() if k in sig.parameters}
161
+ if inspect.iscoroutinefunction(callback):
162
+ return await callback(**filtered_kwargs)
163
+ return callback(**filtered_kwargs)
164
+
165
+ # Dynamically build wrapper with appropriate signature so FastAPI can document it
166
+ params: list[str] = []
144
167
  if req_model is not None:
145
-
146
- async def _route_handler(body: req_model = Body(...), request: Request = None): # type: ignore[arg-type,valid-type]
147
- payload: dict[str, Any] = {
148
- "body": body,
149
- "query": dict(request.query_params) if request else {},
150
- "flock": self.flock,
151
- **(request.path_params if request else {}),
152
- }
153
-
154
- sig = inspect.signature(callback)
155
- filtered_kwargs = {k: v for k, v in payload.items() if k in sig.parameters}
156
-
157
- if inspect.iscoroutinefunction(callback):
158
- return await callback(**filtered_kwargs)
159
- return callback(**filtered_kwargs)
168
+ params.append("body")
169
+ if query_model is not None:
170
+ params.append("query")
171
+
172
+ # Build wrapper function based on which params are present
173
+ if req_model and query_model:
174
+ async def _route_handler(
175
+ request: Request,
176
+ body: req_model = Body(...), # type: ignore[arg-type,valid-type]
177
+ query: query_model = Depends(), # type: ignore[arg-type,valid-type]
178
+ ):
179
+ return await _invoke(request, body, query)
180
+
181
+ elif req_model and not query_model:
182
+ async def _route_handler(
183
+ request: Request,
184
+ body: req_model = Body(...), # type: ignore[arg-type,valid-type]
185
+ ):
186
+ return await _invoke(request, body, None)
187
+
188
+ elif query_model and not req_model:
189
+ async def _route_handler(
190
+ request: Request,
191
+ query: query_model = Depends(), # type: ignore[arg-type,valid-type]
192
+ ):
193
+ return await _invoke(request, None, query)
160
194
 
161
195
  else:
162
-
163
196
  async def _route_handler(request: Request):
164
- payload: dict[str, Any] = {
165
- "query": dict(request.query_params),
166
- "flock": self.flock,
167
- **request.path_params,
168
- }
169
-
170
- if request.method in {"POST", "PUT", "PATCH"}:
171
- try:
172
- payload["body"] = await request.json()
173
- except Exception:
174
- payload["body"] = await request.body()
175
-
176
- sig = inspect.signature(callback)
177
- filtered_kwargs = {k: v for k, v in payload.items() if k in sig.parameters}
178
-
179
- if inspect.iscoroutinefunction(callback):
180
- return await callback(**filtered_kwargs)
181
- return callback(**filtered_kwargs)
197
+ return await _invoke(request, None, None)
182
198
 
183
199
  return _route_handler
184
200
 
185
201
  for ep in self.custom_endpoints:
186
202
  self.app.add_api_route(
187
203
  ep.path,
188
- _create_handler_factory(ep.callback, ep.request_model),
204
+ _create_handler_factory(ep.callback, ep.request_model, ep.query_model),
189
205
  methods=ep.methods or ["GET"],
190
206
  name=ep.name or f"custom:{ep.path}",
191
207
  include_in_schema=ep.include_in_schema,
192
208
  response_model=ep.response_model,
193
209
  summary=ep.summary,
194
210
  description=ep.description,
211
+ dependencies=ep.dependencies,
195
212
  )
196
213
 
197
214
  # --- Core Execution Helper Methods ---
flock/core/flock.py CHANGED
@@ -710,6 +710,7 @@ class Flock(BaseModel, Serializable):
710
710
  port=port,
711
711
  server_name=server_name,
712
712
  theme_name=ui_theme,
713
+ custom_endpoints=custom_endpoints,
713
714
  )
714
715
  except ImportError:
715
716
  # Log error - cannot start integrated UI
flock/webapp/run.py CHANGED
@@ -1,10 +1,13 @@
1
1
  import os # For environment variable
2
2
  import sys
3
+ from collections.abc import Callable, Sequence
3
4
  from pathlib import Path
4
- from typing import TYPE_CHECKING
5
+ from typing import TYPE_CHECKING, Any
5
6
 
6
7
  import uvicorn
7
8
 
9
+ from flock.core.api.custom_endpoint import FlockEndpoint
10
+
8
11
  if TYPE_CHECKING:
9
12
  from flock.core import Flock
10
13
 
@@ -17,6 +20,7 @@ def start_integrated_server(
17
20
  port: int,
18
21
  server_name: str, # Currently unused as UI sets its own title
19
22
  theme_name: str | None = None,
23
+ custom_endpoints: Sequence[FlockEndpoint] | dict[tuple[str, list[str] | None], Callable[..., Any]] | None = None,
20
24
  ):
21
25
  """Starts the webapp, preloads flock & theme, includes API routes (TODO)."""
22
26
  print(
@@ -29,6 +33,10 @@ def start_integrated_server(
29
33
  sys.path.insert(0, str(src_dir))
30
34
 
31
35
  # Import necessary webapp components *after* path setup
36
+ from flock.core.api.endpoints import (
37
+ create_api_router, # Need to adapt this later
38
+ )
39
+ from flock.core.api.main import FlockAPI
32
40
  from flock.core.api.run_store import (
33
41
  RunStore, # Needed for API routes later
34
42
  )
@@ -40,7 +48,6 @@ def start_integrated_server(
40
48
  from flock.webapp.app.services.flock_service import (
41
49
  set_current_flock_instance_programmatically,
42
50
  )
43
- # from flock.core.api.endpoints import create_api_router # Need to adapt this later
44
51
 
45
52
  # 1. Set Theme (use provided or default)
46
53
  set_current_theme_name(
@@ -55,11 +62,9 @@ def start_integrated_server(
55
62
  )
56
63
  print(f"Flock '{flock_instance.name}' preloaded.")
57
64
 
58
- # 3. TODO: Adapt and Include API Routes
59
- # run_store = RunStore()
60
- # api_router = create_api_router(flock_instance, run_store) # Assuming refactored signature
61
- # webapp_fastapi_app.include_router(api_router, prefix="/api")
62
- # print("API routes included.")
65
+ flock_api = FlockAPI(flock_instance, custom_endpoints)
66
+ webapp_fastapi_app.include_router(flock_api.app.router, prefix="/api")
67
+ print("API routes included.")
63
68
 
64
69
  # 4. Run Uvicorn - STILL PASSING INSTANCE here because we need to modify it (add routes)
65
70
  # and set state BEFORE running. Reload won't work well here.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flock-core
3
- Version: 0.4.0b40
3
+ Version: 0.4.0b43
4
4
  Summary: Declarative LLM Orchestration at Scale
5
5
  Author-email: Andre Ratzenberger <andre.ratzenberger@whiteduck.de>
6
6
  License-File: LICENSE
@@ -19,7 +19,7 @@ flock/cli/view_results.py,sha256=dOzK0O1FHSIDERnx48y-2Xke9BkOHS7pcOhs64AyIg0,781
19
19
  flock/cli/yaml_editor.py,sha256=K3N0bh61G1TSDAZDnurqW9e_-hO6CtSQKXQqlDhCjVo,12527
20
20
  flock/cli/assets/release_notes.md,sha256=bqnk50jxM3w5uY44Dc7MkdT8XmRREFxrVBAG9XCOSSU,4896
21
21
  flock/core/__init__.py,sha256=p7lmQULRu9ejIAELfanZiyMhW0CougIPvyFHW2nqBFQ,847
22
- flock/core/flock.py,sha256=WzLA7-xoAUq7Yn_ioieQIsk6CG_VvvDPeq_S6FWNgOY,30424
22
+ flock/core/flock.py,sha256=hO4s-dgXbX9sT0T9E8uosyraTNJbg5jPmzmTPTWGw-k,30479
23
23
  flock/core/flock_agent.py,sha256=JTqaGD_OnZSd3bVU989WMsK1rAT6UGn-JYrPxFV15EE,39576
24
24
  flock/core/flock_evaluator.py,sha256=dOXZeDOGZcAmJ9ahqq_2bdGUU1VOXY4skmwTVpAjiVw,1685
25
25
  flock/core/flock_factory.py,sha256=_4zsjkEmJnCR7IvJ3SUHnDbX6c7Tt3E4P5ohxwKvE6w,3173
@@ -27,9 +27,9 @@ flock/core/flock_module.py,sha256=UCK6TFe4viXs596zeng0GD3gln4ZNGu_gCWkXIIMREg,30
27
27
  flock/core/flock_registry.py,sha256=aC-RK0js676DQkjXmNuYHuD5t6GmFhpQoCKaO3i7xFg,24920
28
28
  flock/core/flock_router.py,sha256=1OAXDsdaIIFApEfo6SRfFEDoTuGt3Si7n2MXiySEfis,2644
29
29
  flock/core/api/__init__.py,sha256=OKlhzDWZJfA6ddBwxQUmATY0TSzESsH032u00iVGvdA,228
30
- flock/core/api/custom_endpoint.py,sha256=nCm8lhvq1OOVlHB5f1DD1Pgm5U-PgggPlYjlMRK4nPc,1090
30
+ flock/core/api/custom_endpoint.py,sha256=Mbk2owdcXVATaT5FtEWXFzllgursozcmqP8ouG5btc0,1305
31
31
  flock/core/api/endpoints.py,sha256=qQnJmtcYGkjdKtLllVpyJVjc-iZrvu5EEeVIryyt4tc,12987
32
- flock/core/api/main.py,sha256=f7uZkl8wIOLSoaIztdRG40LqmmRQSdIe-WxXsZx4Q-U,28681
32
+ flock/core/api/main.py,sha256=d7JQLsi2xMpT1yjuU26uU0apNh7YOdvwt04AuEmQSQM,29831
33
33
  flock/core/api/models.py,sha256=seqKuzhbN37nCNO7KrcJjI2mWuwiOKCLFcJcTPvTtag,3422
34
34
  flock/core/api/run_store.py,sha256=bFodJvVyWogzoezVy0cOoWWU3MdEBXf_6_5sBqCRWps,9227
35
35
  flock/core/api/runner.py,sha256=3izg6cVk1RoR1hDIDwMAO1gi3lnLcp8DPv7AnJBYx6A,1443
@@ -440,7 +440,7 @@ flock/themes/zenburned.toml,sha256=UEmquBbcAO3Zj652XKUwCsNoC2iQSlIh-q5c6DH-7Kc,1
440
440
  flock/themes/zenwritten-dark.toml,sha256=To5l6520_3UqAGiEumpzGWsHhXxqu9ThrMildXKgIO0,1669
441
441
  flock/themes/zenwritten-light.toml,sha256=G1iEheCPfBNsMTGaVpEVpDzYBHA_T-MV27rolUYolmE,1666
442
442
  flock/webapp/__init__.py,sha256=YtRbbyciN3Z2oMB9fdXZuvM3e49R8m2mY5qHLDoapRA,37
443
- flock/webapp/run.py,sha256=DGXcZ9APSE9ae0r7t2DhVKsKdIx1kGZrhzzXFZmHqYc,4944
443
+ flock/webapp/run.py,sha256=nr73BOhZpYwzV44N1gyTI9OpZ0eEO1qvrboT78cK0xY,5133
444
444
  flock/webapp/app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
445
445
  flock/webapp/app/config.py,sha256=t4-4OCa_tqktkJLQgVbAmwFA7MoyahFE1IEDItsqqpY,4155
446
446
  flock/webapp/app/main.py,sha256=xCk2zhSAlgd2YmVT8Sfw-kwq9dnTBMtRybJpz__cCQw,42975
@@ -495,8 +495,8 @@ flock/workflow/agent_execution_activity.py,sha256=Gy6FtuVAjf0NiUXmC3syS2eJpNQF4R
495
495
  flock/workflow/flock_workflow.py,sha256=iSUF_soFvWar0ffpkzE4irkDZRx0p4HnwmEBi_Ne2sY,9666
496
496
  flock/workflow/temporal_config.py,sha256=3_8O7SDEjMsSMXsWJBfnb6XTp0TFaz39uyzSlMTSF_I,3988
497
497
  flock/workflow/temporal_setup.py,sha256=YIHnSBntzOchHfMSh8hoLeNXrz3B1UbR14YrR6soM7A,1606
498
- flock_core-0.4.0b40.dist-info/METADATA,sha256=W-nPONRJfGIBfsyt2hEPqtLqu6mxQto7fP1IYuw1oH8,17125
499
- flock_core-0.4.0b40.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
500
- flock_core-0.4.0b40.dist-info/entry_points.txt,sha256=rWaS5KSpkTmWySURGFZk6PhbJ87TmvcFQDi2uzjlagQ,37
501
- flock_core-0.4.0b40.dist-info/licenses/LICENSE,sha256=iYEqWy0wjULzM9GAERaybP4LBiPeu7Z1NEliLUdJKSc,1072
502
- flock_core-0.4.0b40.dist-info/RECORD,,
498
+ flock_core-0.4.0b43.dist-info/METADATA,sha256=9V2dw83Zii9udURZd6uTcqSS2vsDJOQdwuSu62ia21s,17125
499
+ flock_core-0.4.0b43.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
500
+ flock_core-0.4.0b43.dist-info/entry_points.txt,sha256=rWaS5KSpkTmWySURGFZk6PhbJ87TmvcFQDi2uzjlagQ,37
501
+ flock_core-0.4.0b43.dist-info/licenses/LICENSE,sha256=iYEqWy0wjULzM9GAERaybP4LBiPeu7Z1NEliLUdJKSc,1072
502
+ flock_core-0.4.0b43.dist-info/RECORD,,