1+ from collections .abc import Mapping
12from enum import Enum
23from typing import Annotated , Any , Literal , TypeAlias
34from uuid import UUID
45
56from models_library import projects
6- from models_library .basic_regex import SIMPLE_VERSION_RE
7- from models_library .services_regex import COMPUTATIONAL_SERVICE_KEY_RE
8- from pydantic import BaseModel , Field , StringConstraints
7+ from models_library .services_types import ServiceKey , ServiceVersion
8+ from pydantic import BaseModel , Field
99
1010from ..projects import ProjectID
1111
12- FunctionID : TypeAlias = projects . ProjectID
13- FunctionJobID : TypeAlias = projects . ProjectID
12+ FunctionID : TypeAlias = UUID
13+ FunctionJobID : TypeAlias = UUID
1414FileID : TypeAlias = UUID
1515
1616InputTypes : TypeAlias = FileID | float | int | bool | str | list
1717
1818
19- class FunctionSchema ( BaseModel ):
20- """Schema for function input/output"" "
19+ class FunctionSchemaClass ( str , Enum ):
20+ json_schema = "application/schema+json "
2121
22- schema_dict : dict [str , Any ] | None # JSON Schema
2322
23+ class FunctionSchemaBase (BaseModel ):
24+ schema_content : Any = Field (default = None )
25+ schema_class : FunctionSchemaClass
2426
25- class FunctionInputSchema (FunctionSchema ): ...
2627
28+ class JSONFunctionSchema (FunctionSchemaBase ):
29+ schema_content : Mapping [str , Any ] = Field (
30+ default = {}, description = "JSON Schema" , title = "JSON Schema"
31+ ) # json-schema library defines a schema as Mapping[str, Any]
32+ schema_class : FunctionSchemaClass = FunctionSchemaClass .json_schema
2733
28- class FunctionOutputSchema (FunctionSchema ): ...
34+
35+ class JSONFunctionInputSchema (JSONFunctionSchema ):
36+ schema_class : Literal [FunctionSchemaClass .json_schema ] = (
37+ FunctionSchemaClass .json_schema
38+ )
39+
40+
41+ class JSONFunctionOutputSchema (JSONFunctionSchema ):
42+ schema_class : Literal [FunctionSchemaClass .json_schema ] = (
43+ FunctionSchemaClass .json_schema
44+ )
45+
46+
47+ FunctionInputSchema : TypeAlias = Annotated [
48+ JSONFunctionInputSchema ,
49+ Field (discriminator = "schema_class" ),
50+ ]
51+
52+ FunctionOutputSchema : TypeAlias = Annotated [
53+ JSONFunctionOutputSchema ,
54+ Field (discriminator = "schema_class" ),
55+ ]
2956
3057
3158class FunctionClass (str , Enum ):
@@ -53,8 +80,8 @@ class FunctionBase(BaseModel):
5380 uid : FunctionID | None
5481 title : str = ""
5582 description : str = ""
56- input_schema : FunctionInputSchema | None
57- output_schema : FunctionOutputSchema | None
83+ input_schema : FunctionInputSchema
84+ output_schema : FunctionOutputSchema
5885 default_inputs : FunctionInputs
5986
6087
@@ -63,8 +90,8 @@ class FunctionDB(BaseModel):
6390 uuid : FunctionJobID | None
6491 title : str = ""
6592 description : str = ""
66- input_schema : FunctionInputSchema | None
67- output_schema : FunctionOutputSchema | None
93+ input_schema : FunctionInputSchema
94+ output_schema : FunctionOutputSchema
6895 default_inputs : FunctionInputs
6996 class_specific_data : FunctionClassSpecificData
7097
@@ -84,19 +111,13 @@ class ProjectFunction(FunctionBase):
84111 project_id : ProjectID
85112
86113
87- SolverKeyId = Annotated [
88- str , StringConstraints (strip_whitespace = True , pattern = COMPUTATIONAL_SERVICE_KEY_RE )
89- ]
90- VersionStr : TypeAlias = Annotated [
91- str , StringConstraints (strip_whitespace = True , pattern = SIMPLE_VERSION_RE )
92- ]
93114SolverJobID : TypeAlias = UUID
94115
95116
96117class SolverFunction (FunctionBase ):
97118 function_class : Literal [FunctionClass .solver ] = FunctionClass .solver
98- solver_key : SolverKeyId
99- solver_version : str = ""
119+ solver_key : ServiceKey
120+ solver_version : ServiceVersion
100121
101122
102123class PythonCodeFunction (FunctionBase ):
@@ -228,3 +249,22 @@ class UnsupportedFunctionJobClassError(Exception):
228249 def __init__ (self , function_job_class : str ):
229250 self .function_job_class = function_job_class
230251 super ().__init__ (f"Function job class { function_job_class } is not supported" )
252+
253+
254+ class UnsupportedFunctionFunctionJobClassCombinationError (Exception ):
255+ """Exception raised when a function / function job class combination is not supported"""
256+
257+ def __init__ (self , function_class : str , function_job_class : str ):
258+ self .function_class = function_class
259+ self .function_job_class = function_job_class
260+ super ().__init__ (
261+ f"Function class { function_class } and function job class { function_job_class } combination is not supported"
262+ )
263+
264+
265+ class FunctionInputsValidationError (Exception ):
266+ """Exception raised when validating function inputs"""
267+
268+ def __init__ (self , error : str ):
269+ self .errors = error
270+ super ().__init__ (f"Function inputs validation failed: { error } " )
0 commit comments