This plugin allows for add-in logic through custom directives, that will allow adding in
custom code generation logic through self directives, that then call user defined functions:
turms_directives:
name_or_directive: #name of the directive
locations: #the directive locations
- "variable definition"
type: "path.to.plugin.plugin_function" #the resolved plugin
trim: True #will trim this directive from the generated graphql sdl (in the meta class)
args: #additional args (aka @validator(arg1="arg1string")
arg1: string
def plugin_function(v: VariableDefinitionNode, body: List[AST], registry: ClassRegistry, arg1: str) -> List[AST]:
# Custom logic defining alterations to this specific body (input will vary from plugin to plugin)
return body
To illustrate the Usecase:
Sometypes it can become useful to introduce custom pydantic validaition logic for specific
arguments on operations:
mutation create_dataset(
$name: String!
$parent: ID
$created_while: ID @validator(path: "mikro.scalars.get_current_id")
) {
createDataset(name: $name, parent: $parent, createdWhile: $created_while) {
...Dataset
}
}
Defining the plugin in graphql.config.yaml
turms_directives:
validator:
locations:
- "variable definition"
type: "validator.validator"
args:
path: string
Defined in yalidator.py
We define this validator directive plugin, that will import the validation functionality and put it as a call
for the validation function
def validator(v: VariableDefinitionNode, body: List[AST], registry: ClassRegistry, path: str):
registry.register_import("pydantic.validator") # Custom imports
registry.register_import(path) #Importing the function
#Adding the field to the Arguments body
body.append(
ast.FunctionDef(
name=registry.generate_parameter_name(v.variable.name.value) + "_validator",
args=ast.arguments(
args=[
ast.arg(
arg="cls",
),
ast.arg(
arg="value",
),
],
defaults=[],
kw_defaults=[],
kwarg=None,
kwonlyargs=[],
posonlyargs=[],
vararg=None,
),
body=[
ast.Return(
value=ast.Call(
func=ast.Name(id=path.split(".")[-1], ctx=ast.Load()),
args=[ast.Name(id="cls", ctx=ast.Load()), ast.Name(id="value", ctx=ast.Load())],
keywords=[],
),
),
],
decorator_list=[
ast.Call(
func=ast.Name(id="validator", ctx=ast.Load()),
args=[
ast.Constant(registry.generate_parameter_name(v.variable.name.value), ctx=ast.Load()),
],
keywords=[
ast.keyword(arg="pre", value=ast.Constant(True, ctx=ast.Load())),
ast.keyword(arg="always", value=ast.Constant(True, ctx=ast.Load())),
],
),
],
returns=None,
)
)
return body
When now running the plugin turms will call the directive plugin on encounter and yield this result:
class Create_datasetMutation(BaseModel):
create_dataset: Optional[DatasetFragment] = Field(alias="createDataset")
class Arguments(BaseModel):
name: str
parent: Optional[ID]
created_while: Optional[ID]
@validator("created_while", pre=True, always=True)
def created_while_validator(cls, value):
return get_current_id(cls, value)
class Meta:
# directive is trimmed from the document
document = "fragment Dataset on Dataset {\n id\n name\n parent {\n id\n }\n representations {\n id\n name\n }\n omerofiles {\n id\n name\n }\n}\n\nmutation create_dataset($name: String!, $parent: ID, $created_while: AssignationID) {\n createDataset(name: $name, parent: $parent, createdWhile: $created_while) {\n ...Dataset\n }\n}"
This plugin allows for add-in logic through custom directives, that will allow adding in
custom code generation logic through self directives, that then call user defined functions:
To illustrate the Usecase:
Sometypes it can become useful to introduce custom pydantic validaition logic for specific
arguments on operations:
Defining the plugin in graphql.config.yaml
Defined in yalidator.py
We define this validator directive plugin, that will import the validation functionality and put it as a call
for the validation function
When now running the plugin turms will call the directive plugin on encounter and yield this result: