aidial-sdk 0.47.0.dev9__tar.gz → 0.48.0.dev1__tar.gz

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 (78) hide show
  1. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/PKG-INFO +1 -1
  2. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/application.py +24 -12
  3. aidial_sdk-0.48.0.dev1/aidial_sdk/utils/_interpolation.py +55 -0
  4. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/pyproject.toml +1 -1
  5. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/LICENSE +0 -0
  6. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/README.md +0 -0
  7. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/__init__.py +0 -0
  8. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/_errors.py +0 -0
  9. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/_pydantic/__init__.py +0 -0
  10. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/_pydantic/_compat.py +0 -0
  11. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/_pydantic/_model_config.py +0 -0
  12. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/chat_completion/__init__.py +0 -0
  13. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/chat_completion/_cache.py +0 -0
  14. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/chat_completion/_types.py +0 -0
  15. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/chat_completion/base.py +0 -0
  16. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/chat_completion/choice.py +0 -0
  17. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/chat_completion/choice_base.py +0 -0
  18. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/chat_completion/chunks.py +0 -0
  19. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/chat_completion/enums.py +0 -0
  20. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/chat_completion/form.py +0 -0
  21. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/chat_completion/function_call.py +0 -0
  22. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/chat_completion/function_tool_call.py +0 -0
  23. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/chat_completion/request.py +0 -0
  24. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/chat_completion/response.py +0 -0
  25. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/chat_completion/stage.py +0 -0
  26. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/deployment/__init__.py +0 -0
  27. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/deployment/_headers.py +0 -0
  28. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/deployment/configuration.py +0 -0
  29. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/deployment/from_request_mixin.py +0 -0
  30. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/deployment/rate.py +0 -0
  31. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/deployment/tokenize.py +0 -0
  32. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/deployment/truncate_prompt.py +0 -0
  33. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/embeddings/__init__.py +0 -0
  34. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/embeddings/base.py +0 -0
  35. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/embeddings/request.py +0 -0
  36. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/embeddings/response.py +0 -0
  37. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/exceptions.py +0 -0
  38. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/header_propagator.py +0 -0
  39. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/py.typed +0 -0
  40. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/pydantic/v2.py +0 -0
  41. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/pydantic_v1/__init__.py +0 -0
  42. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/response_headers.py +0 -0
  43. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/telemetry/__init__.py +0 -0
  44. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/telemetry/_context.py +0 -0
  45. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/telemetry/init.py +0 -0
  46. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/telemetry/types.py +0 -0
  47. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/translators/messages_to_chat_completions/__init__.py +0 -0
  48. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/translators/messages_to_chat_completions/chat_completions/app.py +0 -0
  49. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/translators/messages_to_chat_completions/chat_completions/cache_breakpoints.py +0 -0
  50. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/translators/messages_to_chat_completions/chat_completions/dial_extensions.py +0 -0
  51. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/translators/messages_to_chat_completions/chat_completions/from_chat_completions.py +0 -0
  52. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/translators/messages_to_chat_completions/chat_completions/reasoning.py +0 -0
  53. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/translators/messages_to_chat_completions/chat_completions/streaming.py +0 -0
  54. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/translators/messages_to_chat_completions/chat_completions/system_turns.py +0 -0
  55. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/translators/messages_to_chat_completions/chat_completions/to_chat_completions.py +0 -0
  56. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/translators/messages_to_chat_completions/common.py +0 -0
  57. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/translators/messages_to_chat_completions/core_client.py +0 -0
  58. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/translators/messages_to_chat_completions/errors.py +0 -0
  59. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/translators/messages_to_chat_completions/settings.py +0 -0
  60. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/translators/messages_to_chat_completions/sse_stream.py +0 -0
  61. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/translators/messages_to_chat_completions/translation_state.py +0 -0
  62. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/utils/__init__.py +0 -0
  63. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/utils/_attachment.py +0 -0
  64. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/utils/_cancel_scope.py +0 -0
  65. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/utils/_content_stream.py +0 -0
  66. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/utils/_disconnect_middleware.py +0 -0
  67. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/utils/_indexed_list.py +0 -0
  68. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/utils/_json_log_formatter.py +0 -0
  69. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/utils/_logging.py +0 -0
  70. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/utils/_reflection.py +0 -0
  71. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/utils/env.py +0 -0
  72. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/utils/errors.py +0 -0
  73. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/utils/json.py +0 -0
  74. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/utils/log_config.py +0 -0
  75. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/utils/logging.py +0 -0
  76. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/utils/merge_chunks.py +0 -0
  77. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/utils/pydantic.py +0 -0
  78. {aidial_sdk-0.47.0.dev9 → aidial_sdk-0.48.0.dev1}/aidial_sdk/utils/streaming.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aidial-sdk
3
- Version: 0.47.0.dev9
3
+ Version: 0.48.0.dev1
4
4
  Summary: Framework to create applications and model adapters for AI DIAL
5
5
  License-Expression: Apache-2.0
6
6
  License-File: LICENSE
@@ -37,6 +37,10 @@ from aidial_sdk.header_propagator import HeaderPropagator
37
37
  from aidial_sdk.response_headers import NonForwardableHeadersMiddleware
38
38
  from aidial_sdk.telemetry.types import TelemetryConfig
39
39
  from aidial_sdk.utils._disconnect_middleware import DisconnectMiddleware
40
+ from aidial_sdk.utils._interpolation import (
41
+ interpolate_deployment_id,
42
+ match_deployment_id,
43
+ )
40
44
  from aidial_sdk.utils._reflection import get_method_implementation
41
45
  from aidial_sdk.utils.env import env_float, env_var_list
42
46
  from aidial_sdk.utils.log_config import configure_sdk_logger
@@ -59,16 +63,6 @@ RequestType = TypeVar("RequestType", bound=FromRequestMixin)
59
63
  Handler = Callable[[Request], Coroutine[Any, Any, Response]]
60
64
 
61
65
 
62
- def _interpolate_deployment_id(deployment_id: str, path_params: dict) -> str:
63
- result = deployment_id
64
- for key, value in path_params.items():
65
- # Replace {key} or {key:type} patterns with actual value
66
- # Pattern matches {key} or {key:int}, {key:path}, etc.
67
- pattern = r"\{" + re.escape(key) + r"(?::[^}]*)?\}"
68
- result = re.sub(pattern, str(value), result)
69
- return result
70
-
71
-
72
66
  class PathFilter(logging.Filter):
73
67
  path: str
74
68
 
@@ -293,7 +287,9 @@ class DIALApp(FastAPI):
293
287
  )
294
288
  set_log_deployment(deployment_id)
295
289
 
296
- handler = self._v1_handlers[endpoint].get(deployment_id)
290
+ handler = self._get_handler(
291
+ endpoint, deployment_id, original_request
292
+ )
297
293
  if handler is None:
298
294
  raise DeploymentNotFoundError(
299
295
  f"The deployment {deployment_id!r} doesn't provide the {endpoint!r} endpoint"
@@ -303,6 +299,22 @@ class DIALApp(FastAPI):
303
299
 
304
300
  return _handler
305
301
 
302
+ def _get_handler(
303
+ self, endpoint: str, deployment_id: str, request: Request
304
+ ) -> Handler | None:
305
+ handlers = self._v1_handlers[endpoint]
306
+
307
+ if (handler := handlers.get(deployment_id)) is not None:
308
+ return handler
309
+
310
+ for name, handler in handlers.items():
311
+ params = match_deployment_id(name, deployment_id)
312
+ if params is not None:
313
+ request.scope["path_params"] = params
314
+ return handler
315
+
316
+ return None
317
+
306
318
  def _endpoint_factory(
307
319
  self,
308
320
  deployment_id: str | None,
@@ -351,7 +363,7 @@ class DIALApp(FastAPI):
351
363
  deployment_id: str | None,
352
364
  ) -> RequestType:
353
365
  if deployment_id is not None:
354
- deployment_id = _interpolate_deployment_id(
366
+ deployment_id = interpolate_deployment_id(
355
367
  deployment_id, original_request.path_params
356
368
  )
357
369
  set_log_deployment(deployment_id)
@@ -0,0 +1,55 @@
1
+ """Deployment names may be templates, e.g. "app-{idx}" or "app-{idx:int}",
2
+ in the same syntax Starlette uses for the path params."""
3
+
4
+ from collections.abc import Callable
5
+ from functools import cache
6
+ from re import Match
7
+ from typing import Any
8
+
9
+ from starlette.convertors import Convertor
10
+ from starlette.routing import compile_path
11
+
12
+
13
+ @cache
14
+ def _compile_path_template(
15
+ name: str,
16
+ ) -> tuple[Callable[[str], Match[str] | None], str, dict[str, Convertor[Any]]]:
17
+ # compile_path reads a pattern with no leading slash as a *host* pattern,
18
+ # which it truncates at ":", so the name is compiled as a path instead.
19
+ regex, path_format, convertors = compile_path("/" + name)
20
+
21
+ def matcher(deployment_id: str) -> Match[str] | None:
22
+ return regex.match("/" + deployment_id)
23
+
24
+ return matcher, path_format.removeprefix("/"), convertors
25
+
26
+
27
+ def match_deployment_id(
28
+ template: str, deployment_id: str
29
+ ) -> dict[str, Any] | None:
30
+ """Matches a deployment id against a deployment name template
31
+ (e.g. "app-{idx}"), returning the path params it resolves to,
32
+ or None if the name isn't a template or doesn't match."""
33
+
34
+ if "{" not in template:
35
+ return None
36
+
37
+ matcher, _path_format, convertors = _compile_path_template(template)
38
+
39
+ if (match := matcher(deployment_id)) is None:
40
+ return None
41
+
42
+ return {
43
+ key: convertors[key].convert(value)
44
+ for key, value in match.groupdict().items()
45
+ }
46
+
47
+
48
+ def interpolate_deployment_id(deployment_id: str, path_params: dict) -> str:
49
+ """Fills a deployment name template (e.g. "app-{idx:int}") with the
50
+ path params the request it came in on was routed by."""
51
+
52
+ _matcher, path_format, convertors = _compile_path_template(deployment_id)
53
+
54
+ # the format drops the convertor types, so "app-{idx:int}" -> "app-{idx}"
55
+ return path_format.format(**path_params) if convertors else deployment_id
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "aidial-sdk"
3
- version = "0.47.0.dev9"
3
+ version = "0.48.0.dev1"
4
4
  description = "Framework to create applications and model adapters for AI DIAL"
5
5
  authors = [{ name = "EPAM RAIL", email = "SpecialEPM-DIALDevTeam@epam.com" }]
6
6
  license = "Apache-2.0"