diff --git a/backend/protos/__init__.py b/backend/protos/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/examples/python/echo/uv.lock b/examples/python/echo/uv.lock index f79a2c623a..89b80da344 100644 --- a/examples/python/echo/uv.lock +++ b/examples/python/echo/uv.lock @@ -16,3 +16,23 @@ requires-dist = [{ name = "ftl", directory = "../../../python-runtime/ftl" }] name = "ftl" version = "0.1.0" source = { directory = "../../../python-runtime/ftl" } +dependencies = [ + { name = "protobuf" }, +] + +[package.metadata] +requires-dist = [{ name = "protobuf", specifier = ">=5.28.3" }] + +[[package]] +name = "protobuf" +version = "5.28.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/74/6e/e69eb906fddcb38f8530a12f4b410699972ab7ced4e21524ece9d546ac27/protobuf-5.28.3.tar.gz", hash = "sha256:64badbc49180a5e401f373f9ce7ab1d18b63f7dd4a9cdc43c92b9f0b481cef7b", size = 422479 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/c5/05163fad52d7c43e124a545f1372d18266db36036377ad29de4271134a6a/protobuf-5.28.3-cp310-abi3-win32.whl", hash = "sha256:0c4eec6f987338617072592b97943fdbe30d019c56126493111cf24344c1cc24", size = 419624 }, + { url = "https://files.pythonhosted.org/packages/9c/4c/4563ebe001ff30dca9d7ed12e471fa098d9759712980cde1fd03a3a44fb7/protobuf-5.28.3-cp310-abi3-win_amd64.whl", hash = "sha256:91fba8f445723fcf400fdbe9ca796b19d3b1242cd873907979b9ed71e4afe868", size = 431464 }, + { url = "https://files.pythonhosted.org/packages/1c/f2/baf397f3dd1d3e4af7e3f5a0382b868d25ac068eefe1ebde05132333436c/protobuf-5.28.3-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:a3f6857551e53ce35e60b403b8a27b0295f7d6eb63d10484f12bc6879c715687", size = 414743 }, + { url = "https://files.pythonhosted.org/packages/85/50/cd61a358ba1601f40e7d38bcfba22e053f40ef2c50d55b55926aecc8fec7/protobuf-5.28.3-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:3fa2de6b8b29d12c61911505d893afe7320ce7ccba4df913e2971461fa36d584", size = 316511 }, + { url = "https://files.pythonhosted.org/packages/5d/ae/3257b09328c0b4e59535e497b0c7537d4954038bdd53a2f0d2f49d15a7c4/protobuf-5.28.3-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:712319fbdddb46f21abb66cd33cb9e491a5763b2febd8f228251add221981135", size = 316624 }, + { url = "https://files.pythonhosted.org/packages/ad/c3/2377c159e28ea89a91cf1ca223f827ae8deccb2c9c401e5ca233cd73002f/protobuf-5.28.3-py3-none-any.whl", hash = "sha256:cee1757663fa32a1ee673434fcf3bf24dd54763c79690201208bafec62f19eed", size = 169511 }, +] diff --git a/python-runtime/compile/build.go b/python-runtime/compile/build.go index a6c65c23be..4b9b73ad5c 100644 --- a/python-runtime/compile/build.go +++ b/python-runtime/compile/build.go @@ -40,6 +40,9 @@ func Build(ctx context.Context, projectRootDir, stubsRoot string, config modulec buildDir := buildDir(config.Dir) + // TODO: call the python schema extractor. grab the output of le script. unmarshal into schema proto. unmarshal that into go type. return + // same with build errors + if err := internal.ScaffoldZip(buildTemplateFiles(), buildDir, mctx, scaffolder.Functions(scaffoldFuncs)); err != nil { return moduleSch, nil, fmt.Errorf("failed to scaffold build template: %w", err) } diff --git a/python-runtime/ftl/pyproject.toml b/python-runtime/ftl/pyproject.toml index a32edf62c0..3b3859270c 100644 --- a/python-runtime/ftl/pyproject.toml +++ b/python-runtime/ftl/pyproject.toml @@ -9,6 +9,7 @@ authors = [ requires-python = ">=3.12" dependencies = [ "protobuf>=5.28.3", + "google>=3.0.0" ] [build-system] diff --git a/python-runtime/ftl/src/ftl/__init__.py b/python-runtime/ftl/src/ftl/__init__.py index 93ca480e42..beb896202a 100644 --- a/python-runtime/ftl/src/ftl/__init__.py +++ b/python-runtime/ftl/src/ftl/__init__.py @@ -1,3 +1,3 @@ -from .decorators import verb +from .verb import verb __all__ = ["verb"] diff --git a/python-runtime/ftl/src/ftl/cli/__init__.py b/python-runtime/ftl/src/ftl/cli/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/python-runtime/ftl/src/ftl/cli/schema_extractor.py b/python-runtime/ftl/src/ftl/cli/schema_extractor.py new file mode 100644 index 0000000000..4d61fe2dcb --- /dev/null +++ b/python-runtime/ftl/src/ftl/cli/schema_extractor.py @@ -0,0 +1,105 @@ +import argparse +import ast +import concurrent.futures +import os +import sys +from contextlib import contextmanager + +from ftl.extract import ( + GlobalExtractionContext, + TransitiveExtractor, +) +from ftl.verb import ( + VerbExtractor, +) + +# analyzers is now a list of lists, where each sublist contains analyzers that can run in parallel +analyzers = [ + [VerbExtractor], + [TransitiveExtractor], +] + + +@contextmanager +def set_analysis_mode(path): + original_sys_path = sys.path.copy() + sys.path.append(path) + try: + yield + finally: + sys.path = original_sys_path + + +def analyze_directory(module_dir): + """Analyze all Python files in the given module_dir in parallel.""" + global_ctx = GlobalExtractionContext() + + file_paths = [] + for dirpath, _, filenames in os.walk(module_dir): + for filename in filenames: + if filename.endswith(".py"): + file_paths.append(os.path.join(dirpath, filename)) + + for analyzer_batch in analyzers: + with concurrent.futures.ProcessPoolExecutor() as executor: + future_to_file = { + executor.submit( + analyze_file, global_ctx, file_path, analyzer_batch + ): file_path + for file_path in file_paths + } + + for future in concurrent.futures.as_completed(future_to_file): + file_path = future_to_file[future] + try: + future.result() # raise any exception that occurred in the worker process + except Exception as exc: + print(f"failed to extract schema from {file_path}: {exc};") + # else: + # print(f"File {file_path} analyzed successfully.") + + for ref_key, decl in global_ctx.deserialize().items(): + print(f"Extracted Decl:\n{decl}") + + +def analyze_file(global_ctx: GlobalExtractionContext, file_path, analyzer_batch): + """Analyze a single Python file using multiple analyzers in parallel.""" + module_name = os.path.splitext(os.path.basename(file_path))[0] + file_ast = ast.parse(open(file_path).read()) + local_ctx = global_ctx.init_local_context() + + with concurrent.futures.ThreadPoolExecutor() as executor: + futures = [ + executor.submit( + run_analyzer, + analyzer_class, + local_ctx, + module_name, + file_path, + file_ast, + ) + for analyzer_class in analyzer_batch + ] + + for future in concurrent.futures.as_completed(futures): + try: + future.result() + except Exception as exc: + print(f"Analyzer generated an exception: {exc} in {file_path}") + + +def run_analyzer(analyzer_class, context, module_name, file_path, file_ast): + analyzer = analyzer_class(context, module_name, file_path) + analyzer.visit(file_ast) + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument( + "module_dir", type=str, help="The Python module directory to analyze." + ) + args = parser.parse_args() + + dir = args.module_dir + with set_analysis_mode(dir): + analyze_directory(dir) diff --git a/python-runtime/ftl/src/ftl/decorators/__init__.py b/python-runtime/ftl/src/ftl/decorators/__init__.py deleted file mode 100644 index beb896202a..0000000000 --- a/python-runtime/ftl/src/ftl/decorators/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -from .verb import verb - -__all__ = ["verb"] diff --git a/python-runtime/ftl/src/ftl/decorators/verb.py b/python-runtime/ftl/src/ftl/decorators/verb.py deleted file mode 100644 index 079ef19b38..0000000000 --- a/python-runtime/ftl/src/ftl/decorators/verb.py +++ /dev/null @@ -1,30 +0,0 @@ -import functools -from typing import Any, Callable, Optional, TypeVar, Union - -F = TypeVar("F", bound=Callable[..., Any]) - - -def verb(func: Optional[F] = None) -> Union[F, Callable[[F], F]]: - func._is_ftl_verb = True - - def actual_decorator(fn: F) -> F: - # type_hints = get_type_hints(fn) - # sig = inspect.signature(fn) - # first_param = next(iter(sig.parameters)) - - # self._verb_registry[fn.__name__] = { - # "func": fn, - # "input_type": type_hints[first_param], - # "output_type": type_hints["return"], - # } - - @functools.wraps(fn) - def wrapper(*args, **kwargs): - return fn(*args, **kwargs) - - return wrapper - - if func is not None: - return actual_decorator(func) - - return actual_decorator diff --git a/python-runtime/ftl/src/ftl/extract/__init__.py b/python-runtime/ftl/src/ftl/extract/__init__.py new file mode 100644 index 0000000000..3c9282b199 --- /dev/null +++ b/python-runtime/ftl/src/ftl/extract/__init__.py @@ -0,0 +1,22 @@ +from .common import ( + extract_basic_type, + extract_class_type, + extract_function_type, + extract_map, + extract_slice, + extract_type, +) +from .context import GlobalExtractionContext, LocalExtractionContext +from .transitive import TransitiveExtractor + +__all__ = [ + "extract_type", + "extract_slice", + "extract_map", + "extract_basic_type", + "extract_class_type", + "extract_function_type", + "LocalExtractionContext", + "GlobalExtractionContext", + "TransitiveExtractor", +] diff --git a/python-runtime/ftl/src/ftl/extract/common.py b/python-runtime/ftl/src/ftl/extract/common.py new file mode 100644 index 0000000000..3f5d7b0463 --- /dev/null +++ b/python-runtime/ftl/src/ftl/extract/common.py @@ -0,0 +1,99 @@ +from typing import Any, Dict, List, Optional, Type + +from ftl.protos.xyz.block.ftl.v1.schema import schema_pb2 as schemapb + +from .context import LocalExtractionContext + + +def extract_type( + local_ctx: LocalExtractionContext, type_hint: Type[Any] +) -> Optional[schemapb.Type]: + """Extracts type information from Python type hints and maps it to schema types.""" + if isinstance(type_hint, list): + return extract_slice(local_ctx, type_hint) + + elif isinstance(type_hint, dict): + return extract_map(local_ctx, type_hint) + + elif type_hint is Any: + return schemapb.Type(any=schemapb.Any()) + + elif isinstance(type_hint, type): + if ( + type_hint is str + or type_hint is int + or type_hint is bool + or type_hint is float + ): + return extract_basic_type(type_hint) + + if hasattr(type_hint, "__bases__"): + return extract_class_type(local_ctx, type_hint) + + if callable(type_hint): + return extract_function_type(local_ctx, type_hint) + + # Handle parametric types (e.g., List[int], Dict[str, int]) - Optional, uncomment if needed + # elif hasattr(type_hint, "__origin__"): + # return extract_parametric_type(local_ctx, type_hint) + + # TODO: raise exception for unsupported types + return None + + +def extract_slice( + local_ctx: LocalExtractionContext, type_hint: List[Any] +) -> Optional[schemapb.Type]: + if isinstance(type_hint, list) and type_hint: + element_type = extract_type(local_ctx, type_hint[0]) # Assuming non-empty list + if element_type: + return schemapb.Type(array=schemapb.Array(element=element_type)) + return None + + +def extract_map( + local_ctx: LocalExtractionContext, type_hint: Dict[Any, Any] +) -> Optional[schemapb.Type]: + if isinstance(type_hint, dict): + key_type = extract_type(local_ctx, list(type_hint.keys())[0]) + value_type = extract_type(local_ctx, list(type_hint.values())[0]) + if key_type and value_type: + return schemapb.Type(map=schemapb.Map(key=key_type, value=value_type)) + return None + + +def extract_basic_type(type_hint: Type[Any]) -> Optional[schemapb.Type]: + type_map = { + str: schemapb.Type(string=schemapb.String()), + int: schemapb.Type(int=schemapb.Int()), + bool: schemapb.Type(bool=schemapb.Bool()), + float: schemapb.Type(float=schemapb.Float()), + } + return type_map.get(type_hint, None) + + +# Uncomment and implement parametric types if needed +# def extract_parametric_type(local_ctx: LocalExtractionContext, type_hint: Type[Any]) -> Optional[schemapb.Type]: +# if hasattr(type_hint, "__args__"): +# base_type = extract_type(local_ctx, type_hint.__origin__) +# param_types = [extract_type(local_ctx, arg) for arg in type_hint.__args__] +# if isinstance(base_type, schemapb.Ref): +# base_type.type_parameters.extend(param_types) +# return base_type +# return None + + +def extract_class_type( + local_ctx: LocalExtractionContext, type_hint: Type[Any] +) -> Optional[schemapb.Type]: + ref = schemapb.Ref(name=type_hint.__name__, module=type_hint.__module__) + local_ctx.add_needs_extraction(ref) + return schemapb.Type(ref=ref) + + +def extract_function_type( + local_ctx: LocalExtractionContext, type_hint: Type[Any] +) -> Optional[schemapb.Type]: + ref = schemapb.Ref(name=type_hint.__name__, module=type_hint.__module__) + local_ctx.add_needs_extraction(ref) + return schemapb.Type(ref=ref) diff --git a/python-runtime/ftl/src/ftl/extract/context.py b/python-runtime/ftl/src/ftl/extract/context.py new file mode 100644 index 0000000000..c2c23010c3 --- /dev/null +++ b/python-runtime/ftl/src/ftl/extract/context.py @@ -0,0 +1,95 @@ +import importlib.util +import multiprocessing +import threading + +from ftl.protos.xyz.block.ftl.v1.schema import schema_pb2 as schemapb + +"""Global context across multiple files in a package.""" + + +class GlobalExtractionContext: + def __init__(self): + manager = multiprocessing.Manager() + self.needs_extraction = manager.dict() + self.verbs = manager.dict() + self.data = manager.dict() + + def deserialize(self): + deserialized_decls = {} + for ref_key, serialized_decl in self.verbs.items(): + decl = schemapb.Verb() + decl.ParseFromString(serialized_decl) + deserialized_decls[ref_key] = decl + for ref_key, serialized_decl in self.data.items(): + decl = schemapb.Data() + decl.ParseFromString(serialized_decl) + deserialized_decls[ref_key] = decl + return deserialized_decls + + def init_local_context(self): + return LocalExtractionContext(self.needs_extraction, self.verbs, self.data) + + +"""Local context for a single Python file.""" + + +class LocalExtractionContext: + def __init__(self, needs_extraction, verbs, data): + self.verbs = verbs + self.data = data + self.needs_extraction = needs_extraction + self.module_cache = {} + self.cache_lock = threading.Lock() + + def add_verb(self, module_name, verb): + """Add a verb to the shared verbs map.""" + ref_key = RefKey(module=module_name, name=verb.name) + self.verbs[ref_key] = verb.SerializeToString() + + def add_data(self, module_name, data): + """Add a verb to the shared verbs map.""" + ref_key = RefKey(module=module_name, name=data.name) + self.data[ref_key] = data.SerializeToString() + + def add_needs_extraction(self, ref: schemapb.Ref): + ref_key = RefKey(module=ref.module, name=ref.name) + # Only add the key if it doesn't exist in the dictionary, not if it's False + if ref_key not in self.needs_extraction: + self.needs_extraction[ref_key] = True + + def remove_needs_extraction(self, module, name): + ref_key = RefKey(module=module, name=name) + self.needs_extraction[ref_key] = False + + def must_extract(self, module, name): + ref_key = RefKey(module=module, name=name) + return ref_key in self.needs_extraction + + def load_python_module(self, module_name, file_path): + """Load a Python module dynamically and cache it locally.""" + with self.cache_lock: + if file_path in self.module_cache: + return self.module_cache[file_path] + + spec = importlib.util.spec_from_file_location(module_name, file_path) + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + self.module_cache[file_path] = module + return module + + +class RefKey: + def __init__(self, module, name): + self.module = module + self.name = name + + def __eq__(self, other): + if isinstance(other, RefKey): + return self.module == other.module and self.name == other.name + return False + + def __hash__(self): + return hash((self.module, self.name)) + + def __repr__(self): + return f"VerbKey(module={self.module}, name={self.name})" diff --git a/python-runtime/ftl/src/ftl/extract/transitive.py b/python-runtime/ftl/src/ftl/extract/transitive.py new file mode 100644 index 0000000000..cd17ee84da --- /dev/null +++ b/python-runtime/ftl/src/ftl/extract/transitive.py @@ -0,0 +1,88 @@ +import ast +from typing import Any, Optional, Type + +from ftl.protos.xyz.block.ftl.v1.schema import schema_pb2 as schemapb + +from .common import extract_type +from .context import LocalExtractionContext + + +class TransitiveExtractor(ast.NodeVisitor): + def __init__(self, context: LocalExtractionContext, module_name, file_path): + self.context = context + self.module_name = module_name + self.file_path = file_path + + def load_function(self, func_name): + try: + module = self.context.load_python_module(self.module_name, self.file_path) + func = getattr(module, func_name, None) + if func is None: + print(f"Function {func_name} not found in {self.module_name}") + return None + return func + except ImportError as e: + print(f"Error importing module {self.module_name}: {e}") + return None + + @staticmethod + def convert_ast_annotation_to_type_hint( + annotation_node: ast.AST, + ) -> Optional[Type[Any]]: + """Converts an AST annotation node to a Python type hint.""" + if isinstance(annotation_node, ast.Name): + # Handle built-in types like int, str, etc. + type_name = annotation_node.id + try: + return eval(type_name) # Convert to actual type like 'int', 'str', etc. + except NameError: + return None + # Handle other cases like ast.Subscript, etc. (extend this for complex types) + return None + + def visit_ClassDef(self, node): + if self.context.must_extract(self.module_name, node.name): + lineno = node.lineno + col_offset = node.col_offset + export = False + for decorator in node.decorator_list: + if isinstance(decorator, ast.Name) and decorator.id == "export": + export = True + + # Extract fields and their types + fields = [] + for class_node in node.body: + if isinstance( + class_node, ast.AnnAssign + ): # Annotated assignment (field) + field_name = ( + class_node.target.id + if isinstance(class_node.target, ast.Name) + else None + ) + if field_name and class_node.annotation: + type_hint = self.convert_ast_annotation_to_type_hint( + class_node.annotation + ) + if type_hint: + field_type = extract_type(self.context, type_hint) + if field_type: + field_schema = schemapb.Field( + name=field_name, type=field_type + ) + fields.append(field_schema) + # TODO: else: + # surface error; require type hint for everything + + data = schemapb.Data( + pos=schemapb.Position( + filename=self.file_path, line=lineno, column=col_offset + ), + name=node.name, + fields=fields, + export=export, + ) + + # Add to context or perform further processing + self.context.add_data(self.module_name, data) + self.context.remove_needs_extraction(self.module_name, data.name) diff --git a/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/v1/admin_pb2.py b/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/v1/admin_pb2.py index eef4e283da..bfbb381ef8 100644 --- a/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/v1/admin_pb2.py +++ b/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/v1/admin_pb2.py @@ -4,79 +4,83 @@ # source: xyz/block/ftl/v1/admin.proto # Protobuf Python Version: 5.28.3 """Generated protocol buffer code.""" + from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool from google.protobuf import runtime_version as _runtime_version from google.protobuf import symbol_database as _symbol_database from google.protobuf.internal import builder as _builder + _runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, - 5, - 28, - 3, - '', - 'xyz/block/ftl/v1/admin.proto' + _runtime_version.Domain.PUBLIC, 5, 28, 3, "", "xyz/block/ftl/v1/admin.proto" ) # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() -from xyz.block.ftl.v1 import ftl_pb2 as xyz_dot_block_dot_ftl_dot_v1_dot_ftl__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1cxyz/block/ftl/v1/admin.proto\x12\x10xyz.block.ftl.v1\x1a\x1axyz/block/ftl/v1/ftl.proto\"G\n\tConfigRef\x12\x1b\n\x06module\x18\x01 \x01(\tH\x00R\x06module\x88\x01\x01\x12\x12\n\x04name\x18\x02 \x01(\tR\x04nameB\t\n\x07_module\"\xca\x01\n\x11ListConfigRequest\x12\x1b\n\x06module\x18\x01 \x01(\tH\x00R\x06module\x88\x01\x01\x12*\n\x0einclude_values\x18\x02 \x01(\x08H\x01R\rincludeValues\x88\x01\x01\x12\x41\n\x08provider\x18\x03 \x01(\x0e\x32 .xyz.block.ftl.v1.ConfigProviderH\x02R\x08provider\x88\x01\x01\x42\t\n\x07_moduleB\x11\n\x0f_include_valuesB\x0b\n\t_provider\"\xa4\x01\n\x12ListConfigResponse\x12\x45\n\x07\x63onfigs\x18\x01 \x03(\x0b\x32+.xyz.block.ftl.v1.ListConfigResponse.ConfigR\x07\x63onfigs\x1aG\n\x06\x43onfig\x12\x18\n\x07refPath\x18\x01 \x01(\tR\x07refPath\x12\x19\n\x05value\x18\x02 \x01(\x0cH\x00R\x05value\x88\x01\x01\x42\x08\n\x06_value\"A\n\x10GetConfigRequest\x12-\n\x03ref\x18\x01 \x01(\x0b\x32\x1b.xyz.block.ftl.v1.ConfigRefR\x03ref\")\n\x11GetConfigResponse\x12\x14\n\x05value\x18\x01 \x01(\x0cR\x05value\"\xa7\x01\n\x10SetConfigRequest\x12\x41\n\x08provider\x18\x01 \x01(\x0e\x32 .xyz.block.ftl.v1.ConfigProviderH\x00R\x08provider\x88\x01\x01\x12-\n\x03ref\x18\x02 \x01(\x0b\x32\x1b.xyz.block.ftl.v1.ConfigRefR\x03ref\x12\x14\n\x05value\x18\x03 \x01(\x0cR\x05valueB\x0b\n\t_provider\"\x13\n\x11SetConfigResponse\"\x93\x01\n\x12UnsetConfigRequest\x12\x41\n\x08provider\x18\x01 \x01(\x0e\x32 .xyz.block.ftl.v1.ConfigProviderH\x00R\x08provider\x88\x01\x01\x12-\n\x03ref\x18\x02 \x01(\x0b\x32\x1b.xyz.block.ftl.v1.ConfigRefR\x03refB\x0b\n\t_provider\"\x15\n\x13UnsetConfigResponse\"\xcb\x01\n\x12ListSecretsRequest\x12\x1b\n\x06module\x18\x01 \x01(\tH\x00R\x06module\x88\x01\x01\x12*\n\x0einclude_values\x18\x02 \x01(\x08H\x01R\rincludeValues\x88\x01\x01\x12\x41\n\x08provider\x18\x03 \x01(\x0e\x32 .xyz.block.ftl.v1.SecretProviderH\x02R\x08provider\x88\x01\x01\x42\t\n\x07_moduleB\x11\n\x0f_include_valuesB\x0b\n\t_provider\"\xa6\x01\n\x13ListSecretsResponse\x12\x46\n\x07secrets\x18\x01 \x03(\x0b\x32,.xyz.block.ftl.v1.ListSecretsResponse.SecretR\x07secrets\x1aG\n\x06Secret\x12\x18\n\x07refPath\x18\x01 \x01(\tR\x07refPath\x12\x19\n\x05value\x18\x02 \x01(\x0cH\x00R\x05value\x88\x01\x01\x42\x08\n\x06_value\"A\n\x10GetSecretRequest\x12-\n\x03ref\x18\x01 \x01(\x0b\x32\x1b.xyz.block.ftl.v1.ConfigRefR\x03ref\")\n\x11GetSecretResponse\x12\x14\n\x05value\x18\x01 \x01(\x0cR\x05value\"\xa7\x01\n\x10SetSecretRequest\x12\x41\n\x08provider\x18\x01 \x01(\x0e\x32 .xyz.block.ftl.v1.SecretProviderH\x00R\x08provider\x88\x01\x01\x12-\n\x03ref\x18\x02 \x01(\x0b\x32\x1b.xyz.block.ftl.v1.ConfigRefR\x03ref\x12\x14\n\x05value\x18\x03 \x01(\x0cR\x05valueB\x0b\n\t_provider\"\x13\n\x11SetSecretResponse\"\x93\x01\n\x12UnsetSecretRequest\x12\x41\n\x08provider\x18\x01 \x01(\x0e\x32 .xyz.block.ftl.v1.SecretProviderH\x00R\x08provider\x88\x01\x01\x12-\n\x03ref\x18\x02 \x01(\x0b\x32\x1b.xyz.block.ftl.v1.ConfigRefR\x03refB\x0b\n\t_provider\"\x15\n\x13UnsetSecretResponse*D\n\x0e\x43onfigProvider\x12\x11\n\rCONFIG_INLINE\x10\x00\x12\x10\n\x0c\x43ONFIG_ENVAR\x10\x01\x12\r\n\tCONFIG_DB\x10\x02*i\n\x0eSecretProvider\x12\x11\n\rSECRET_INLINE\x10\x00\x12\x10\n\x0cSECRET_ENVAR\x10\x01\x12\x13\n\x0fSECRET_KEYCHAIN\x10\x02\x12\r\n\tSECRET_OP\x10\x03\x12\x0e\n\nSECRET_ASM\x10\x04\x32\x9f\x06\n\x0c\x41\x64minService\x12J\n\x04Ping\x12\x1d.xyz.block.ftl.v1.PingRequest\x1a\x1e.xyz.block.ftl.v1.PingResponse\"\x03\x90\x02\x01\x12W\n\nConfigList\x12#.xyz.block.ftl.v1.ListConfigRequest\x1a$.xyz.block.ftl.v1.ListConfigResponse\x12T\n\tConfigGet\x12\".xyz.block.ftl.v1.GetConfigRequest\x1a#.xyz.block.ftl.v1.GetConfigResponse\x12T\n\tConfigSet\x12\".xyz.block.ftl.v1.SetConfigRequest\x1a#.xyz.block.ftl.v1.SetConfigResponse\x12Z\n\x0b\x43onfigUnset\x12$.xyz.block.ftl.v1.UnsetConfigRequest\x1a%.xyz.block.ftl.v1.UnsetConfigResponse\x12Z\n\x0bSecretsList\x12$.xyz.block.ftl.v1.ListSecretsRequest\x1a%.xyz.block.ftl.v1.ListSecretsResponse\x12T\n\tSecretGet\x12\".xyz.block.ftl.v1.GetSecretRequest\x1a#.xyz.block.ftl.v1.GetSecretResponse\x12T\n\tSecretSet\x12\".xyz.block.ftl.v1.SetSecretRequest\x1a#.xyz.block.ftl.v1.SetSecretResponse\x12Z\n\x0bSecretUnset\x12$.xyz.block.ftl.v1.UnsetSecretRequest\x1a%.xyz.block.ftl.v1.UnsetSecretResponseBDP\x01Z@github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1;ftlv1b\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n\x1cxyz/block/ftl/v1/admin.proto\x12\x10xyz.block.ftl.v1\x1a\x1axyz/block/ftl/v1/ftl.proto"G\n\tConfigRef\x12\x1b\n\x06module\x18\x01 \x01(\tH\x00R\x06module\x88\x01\x01\x12\x12\n\x04name\x18\x02 \x01(\tR\x04nameB\t\n\x07_module"\xca\x01\n\x11ListConfigRequest\x12\x1b\n\x06module\x18\x01 \x01(\tH\x00R\x06module\x88\x01\x01\x12*\n\x0einclude_values\x18\x02 \x01(\x08H\x01R\rincludeValues\x88\x01\x01\x12\x41\n\x08provider\x18\x03 \x01(\x0e\x32 .xyz.block.ftl.v1.ConfigProviderH\x02R\x08provider\x88\x01\x01\x42\t\n\x07_moduleB\x11\n\x0f_include_valuesB\x0b\n\t_provider"\xa4\x01\n\x12ListConfigResponse\x12\x45\n\x07\x63onfigs\x18\x01 \x03(\x0b\x32+.xyz.block.ftl.v1.ListConfigResponse.ConfigR\x07\x63onfigs\x1aG\n\x06\x43onfig\x12\x18\n\x07refPath\x18\x01 \x01(\tR\x07refPath\x12\x19\n\x05value\x18\x02 \x01(\x0cH\x00R\x05value\x88\x01\x01\x42\x08\n\x06_value"A\n\x10GetConfigRequest\x12-\n\x03ref\x18\x01 \x01(\x0b\x32\x1b.xyz.block.ftl.v1.ConfigRefR\x03ref")\n\x11GetConfigResponse\x12\x14\n\x05value\x18\x01 \x01(\x0cR\x05value"\xa7\x01\n\x10SetConfigRequest\x12\x41\n\x08provider\x18\x01 \x01(\x0e\x32 .xyz.block.ftl.v1.ConfigProviderH\x00R\x08provider\x88\x01\x01\x12-\n\x03ref\x18\x02 \x01(\x0b\x32\x1b.xyz.block.ftl.v1.ConfigRefR\x03ref\x12\x14\n\x05value\x18\x03 \x01(\x0cR\x05valueB\x0b\n\t_provider"\x13\n\x11SetConfigResponse"\x93\x01\n\x12UnsetConfigRequest\x12\x41\n\x08provider\x18\x01 \x01(\x0e\x32 .xyz.block.ftl.v1.ConfigProviderH\x00R\x08provider\x88\x01\x01\x12-\n\x03ref\x18\x02 \x01(\x0b\x32\x1b.xyz.block.ftl.v1.ConfigRefR\x03refB\x0b\n\t_provider"\x15\n\x13UnsetConfigResponse"\xcb\x01\n\x12ListSecretsRequest\x12\x1b\n\x06module\x18\x01 \x01(\tH\x00R\x06module\x88\x01\x01\x12*\n\x0einclude_values\x18\x02 \x01(\x08H\x01R\rincludeValues\x88\x01\x01\x12\x41\n\x08provider\x18\x03 \x01(\x0e\x32 .xyz.block.ftl.v1.SecretProviderH\x02R\x08provider\x88\x01\x01\x42\t\n\x07_moduleB\x11\n\x0f_include_valuesB\x0b\n\t_provider"\xa6\x01\n\x13ListSecretsResponse\x12\x46\n\x07secrets\x18\x01 \x03(\x0b\x32,.xyz.block.ftl.v1.ListSecretsResponse.SecretR\x07secrets\x1aG\n\x06Secret\x12\x18\n\x07refPath\x18\x01 \x01(\tR\x07refPath\x12\x19\n\x05value\x18\x02 \x01(\x0cH\x00R\x05value\x88\x01\x01\x42\x08\n\x06_value"A\n\x10GetSecretRequest\x12-\n\x03ref\x18\x01 \x01(\x0b\x32\x1b.xyz.block.ftl.v1.ConfigRefR\x03ref")\n\x11GetSecretResponse\x12\x14\n\x05value\x18\x01 \x01(\x0cR\x05value"\xa7\x01\n\x10SetSecretRequest\x12\x41\n\x08provider\x18\x01 \x01(\x0e\x32 .xyz.block.ftl.v1.SecretProviderH\x00R\x08provider\x88\x01\x01\x12-\n\x03ref\x18\x02 \x01(\x0b\x32\x1b.xyz.block.ftl.v1.ConfigRefR\x03ref\x12\x14\n\x05value\x18\x03 \x01(\x0cR\x05valueB\x0b\n\t_provider"\x13\n\x11SetSecretResponse"\x93\x01\n\x12UnsetSecretRequest\x12\x41\n\x08provider\x18\x01 \x01(\x0e\x32 .xyz.block.ftl.v1.SecretProviderH\x00R\x08provider\x88\x01\x01\x12-\n\x03ref\x18\x02 \x01(\x0b\x32\x1b.xyz.block.ftl.v1.ConfigRefR\x03refB\x0b\n\t_provider"\x15\n\x13UnsetSecretResponse*D\n\x0e\x43onfigProvider\x12\x11\n\rCONFIG_INLINE\x10\x00\x12\x10\n\x0c\x43ONFIG_ENVAR\x10\x01\x12\r\n\tCONFIG_DB\x10\x02*i\n\x0eSecretProvider\x12\x11\n\rSECRET_INLINE\x10\x00\x12\x10\n\x0cSECRET_ENVAR\x10\x01\x12\x13\n\x0fSECRET_KEYCHAIN\x10\x02\x12\r\n\tSECRET_OP\x10\x03\x12\x0e\n\nSECRET_ASM\x10\x04\x32\x9f\x06\n\x0c\x41\x64minService\x12J\n\x04Ping\x12\x1d.xyz.block.ftl.v1.PingRequest\x1a\x1e.xyz.block.ftl.v1.PingResponse"\x03\x90\x02\x01\x12W\n\nConfigList\x12#.xyz.block.ftl.v1.ListConfigRequest\x1a$.xyz.block.ftl.v1.ListConfigResponse\x12T\n\tConfigGet\x12".xyz.block.ftl.v1.GetConfigRequest\x1a#.xyz.block.ftl.v1.GetConfigResponse\x12T\n\tConfigSet\x12".xyz.block.ftl.v1.SetConfigRequest\x1a#.xyz.block.ftl.v1.SetConfigResponse\x12Z\n\x0b\x43onfigUnset\x12$.xyz.block.ftl.v1.UnsetConfigRequest\x1a%.xyz.block.ftl.v1.UnsetConfigResponse\x12Z\n\x0bSecretsList\x12$.xyz.block.ftl.v1.ListSecretsRequest\x1a%.xyz.block.ftl.v1.ListSecretsResponse\x12T\n\tSecretGet\x12".xyz.block.ftl.v1.GetSecretRequest\x1a#.xyz.block.ftl.v1.GetSecretResponse\x12T\n\tSecretSet\x12".xyz.block.ftl.v1.SetSecretRequest\x1a#.xyz.block.ftl.v1.SetSecretResponse\x12Z\n\x0bSecretUnset\x12$.xyz.block.ftl.v1.UnsetSecretRequest\x1a%.xyz.block.ftl.v1.UnsetSecretResponseBDP\x01Z@github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1;ftlv1b\x06proto3' +) _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'xyz.block.ftl.v1.admin_pb2', _globals) +_builder.BuildTopDescriptorsAndMessages( + DESCRIPTOR, "xyz.block.ftl.v1.admin_pb2", _globals +) if not _descriptor._USE_C_DESCRIPTORS: - _globals['DESCRIPTOR']._loaded_options = None - _globals['DESCRIPTOR']._serialized_options = b'P\001Z@github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1;ftlv1' - _globals['_ADMINSERVICE'].methods_by_name['Ping']._loaded_options = None - _globals['_ADMINSERVICE'].methods_by_name['Ping']._serialized_options = b'\220\002\001' - _globals['_CONFIGPROVIDER']._serialized_start=1846 - _globals['_CONFIGPROVIDER']._serialized_end=1914 - _globals['_SECRETPROVIDER']._serialized_start=1916 - _globals['_SECRETPROVIDER']._serialized_end=2021 - _globals['_CONFIGREF']._serialized_start=78 - _globals['_CONFIGREF']._serialized_end=149 - _globals['_LISTCONFIGREQUEST']._serialized_start=152 - _globals['_LISTCONFIGREQUEST']._serialized_end=354 - _globals['_LISTCONFIGRESPONSE']._serialized_start=357 - _globals['_LISTCONFIGRESPONSE']._serialized_end=521 - _globals['_LISTCONFIGRESPONSE_CONFIG']._serialized_start=450 - _globals['_LISTCONFIGRESPONSE_CONFIG']._serialized_end=521 - _globals['_GETCONFIGREQUEST']._serialized_start=523 - _globals['_GETCONFIGREQUEST']._serialized_end=588 - _globals['_GETCONFIGRESPONSE']._serialized_start=590 - _globals['_GETCONFIGRESPONSE']._serialized_end=631 - _globals['_SETCONFIGREQUEST']._serialized_start=634 - _globals['_SETCONFIGREQUEST']._serialized_end=801 - _globals['_SETCONFIGRESPONSE']._serialized_start=803 - _globals['_SETCONFIGRESPONSE']._serialized_end=822 - _globals['_UNSETCONFIGREQUEST']._serialized_start=825 - _globals['_UNSETCONFIGREQUEST']._serialized_end=972 - _globals['_UNSETCONFIGRESPONSE']._serialized_start=974 - _globals['_UNSETCONFIGRESPONSE']._serialized_end=995 - _globals['_LISTSECRETSREQUEST']._serialized_start=998 - _globals['_LISTSECRETSREQUEST']._serialized_end=1201 - _globals['_LISTSECRETSRESPONSE']._serialized_start=1204 - _globals['_LISTSECRETSRESPONSE']._serialized_end=1370 - _globals['_LISTSECRETSRESPONSE_SECRET']._serialized_start=1299 - _globals['_LISTSECRETSRESPONSE_SECRET']._serialized_end=1370 - _globals['_GETSECRETREQUEST']._serialized_start=1372 - _globals['_GETSECRETREQUEST']._serialized_end=1437 - _globals['_GETSECRETRESPONSE']._serialized_start=1439 - _globals['_GETSECRETRESPONSE']._serialized_end=1480 - _globals['_SETSECRETREQUEST']._serialized_start=1483 - _globals['_SETSECRETREQUEST']._serialized_end=1650 - _globals['_SETSECRETRESPONSE']._serialized_start=1652 - _globals['_SETSECRETRESPONSE']._serialized_end=1671 - _globals['_UNSETSECRETREQUEST']._serialized_start=1674 - _globals['_UNSETSECRETREQUEST']._serialized_end=1821 - _globals['_UNSETSECRETRESPONSE']._serialized_start=1823 - _globals['_UNSETSECRETRESPONSE']._serialized_end=1844 - _globals['_ADMINSERVICE']._serialized_start=2024 - _globals['_ADMINSERVICE']._serialized_end=2823 + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = ( + b"P\001Z@github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1;ftlv1" + ) + _globals["_ADMINSERVICE"].methods_by_name["Ping"]._loaded_options = None + _globals["_ADMINSERVICE"].methods_by_name[ + "Ping" + ]._serialized_options = b"\220\002\001" + _globals["_CONFIGPROVIDER"]._serialized_start = 1846 + _globals["_CONFIGPROVIDER"]._serialized_end = 1914 + _globals["_SECRETPROVIDER"]._serialized_start = 1916 + _globals["_SECRETPROVIDER"]._serialized_end = 2021 + _globals["_CONFIGREF"]._serialized_start = 78 + _globals["_CONFIGREF"]._serialized_end = 149 + _globals["_LISTCONFIGREQUEST"]._serialized_start = 152 + _globals["_LISTCONFIGREQUEST"]._serialized_end = 354 + _globals["_LISTCONFIGRESPONSE"]._serialized_start = 357 + _globals["_LISTCONFIGRESPONSE"]._serialized_end = 521 + _globals["_LISTCONFIGRESPONSE_CONFIG"]._serialized_start = 450 + _globals["_LISTCONFIGRESPONSE_CONFIG"]._serialized_end = 521 + _globals["_GETCONFIGREQUEST"]._serialized_start = 523 + _globals["_GETCONFIGREQUEST"]._serialized_end = 588 + _globals["_GETCONFIGRESPONSE"]._serialized_start = 590 + _globals["_GETCONFIGRESPONSE"]._serialized_end = 631 + _globals["_SETCONFIGREQUEST"]._serialized_start = 634 + _globals["_SETCONFIGREQUEST"]._serialized_end = 801 + _globals["_SETCONFIGRESPONSE"]._serialized_start = 803 + _globals["_SETCONFIGRESPONSE"]._serialized_end = 822 + _globals["_UNSETCONFIGREQUEST"]._serialized_start = 825 + _globals["_UNSETCONFIGREQUEST"]._serialized_end = 972 + _globals["_UNSETCONFIGRESPONSE"]._serialized_start = 974 + _globals["_UNSETCONFIGRESPONSE"]._serialized_end = 995 + _globals["_LISTSECRETSREQUEST"]._serialized_start = 998 + _globals["_LISTSECRETSREQUEST"]._serialized_end = 1201 + _globals["_LISTSECRETSRESPONSE"]._serialized_start = 1204 + _globals["_LISTSECRETSRESPONSE"]._serialized_end = 1370 + _globals["_LISTSECRETSRESPONSE_SECRET"]._serialized_start = 1299 + _globals["_LISTSECRETSRESPONSE_SECRET"]._serialized_end = 1370 + _globals["_GETSECRETREQUEST"]._serialized_start = 1372 + _globals["_GETSECRETREQUEST"]._serialized_end = 1437 + _globals["_GETSECRETRESPONSE"]._serialized_start = 1439 + _globals["_GETSECRETRESPONSE"]._serialized_end = 1480 + _globals["_SETSECRETREQUEST"]._serialized_start = 1483 + _globals["_SETSECRETREQUEST"]._serialized_end = 1650 + _globals["_SETSECRETRESPONSE"]._serialized_start = 1652 + _globals["_SETSECRETRESPONSE"]._serialized_end = 1671 + _globals["_UNSETSECRETREQUEST"]._serialized_start = 1674 + _globals["_UNSETSECRETREQUEST"]._serialized_end = 1821 + _globals["_UNSETSECRETRESPONSE"]._serialized_start = 1823 + _globals["_UNSETSECRETRESPONSE"]._serialized_end = 1844 + _globals["_ADMINSERVICE"]._serialized_start = 2024 + _globals["_ADMINSERVICE"]._serialized_end = 2823 # @@protoc_insertion_point(module_scope) diff --git a/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/v1/admin_pb2.pyi b/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/v1/admin_pb2.pyi index 766323fc78..c4b713a524 100644 --- a/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/v1/admin_pb2.pyi +++ b/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/v1/admin_pb2.pyi @@ -1,9 +1,13 @@ -from xyz.block.ftl.v1 import ftl_pb2 as _ftl_pb2 -from google.protobuf.internal import containers as _containers -from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper +from typing import ClassVar as _ClassVar +from typing import Iterable as _Iterable +from typing import Mapping as _Mapping +from typing import Optional as _Optional +from typing import Union as _Union + from google.protobuf import descriptor as _descriptor from google.protobuf import message as _message -from typing import ClassVar as _ClassVar, Iterable as _Iterable, Mapping as _Mapping, Optional as _Optional, Union as _Union +from google.protobuf.internal import containers as _containers +from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper DESCRIPTOR: _descriptor.FileDescriptor @@ -20,6 +24,7 @@ class SecretProvider(int, metaclass=_enum_type_wrapper.EnumTypeWrapper): SECRET_KEYCHAIN: _ClassVar[SecretProvider] SECRET_OP: _ClassVar[SecretProvider] SECRET_ASM: _ClassVar[SecretProvider] + CONFIG_INLINE: ConfigProvider CONFIG_ENVAR: ConfigProvider CONFIG_DB: ConfigProvider @@ -35,7 +40,9 @@ class ConfigRef(_message.Message): NAME_FIELD_NUMBER: _ClassVar[int] module: str name: str - def __init__(self, module: _Optional[str] = ..., name: _Optional[str] = ...) -> None: ... + def __init__( + self, module: _Optional[str] = ..., name: _Optional[str] = ... + ) -> None: ... class ListConfigRequest(_message.Message): __slots__ = ("module", "include_values", "provider") @@ -45,7 +52,12 @@ class ListConfigRequest(_message.Message): module: str include_values: bool provider: ConfigProvider - def __init__(self, module: _Optional[str] = ..., include_values: bool = ..., provider: _Optional[_Union[ConfigProvider, str]] = ...) -> None: ... + def __init__( + self, + module: _Optional[str] = ..., + include_values: bool = ..., + provider: _Optional[_Union[ConfigProvider, str]] = ..., + ) -> None: ... class ListConfigResponse(_message.Message): __slots__ = ("configs",) @@ -55,10 +67,18 @@ class ListConfigResponse(_message.Message): VALUE_FIELD_NUMBER: _ClassVar[int] refPath: str value: bytes - def __init__(self, refPath: _Optional[str] = ..., value: _Optional[bytes] = ...) -> None: ... + def __init__( + self, refPath: _Optional[str] = ..., value: _Optional[bytes] = ... + ) -> None: ... + CONFIGS_FIELD_NUMBER: _ClassVar[int] configs: _containers.RepeatedCompositeFieldContainer[ListConfigResponse.Config] - def __init__(self, configs: _Optional[_Iterable[_Union[ListConfigResponse.Config, _Mapping]]] = ...) -> None: ... + def __init__( + self, + configs: _Optional[ + _Iterable[_Union[ListConfigResponse.Config, _Mapping]] + ] = ..., + ) -> None: ... class GetConfigRequest(_message.Message): __slots__ = ("ref",) @@ -80,7 +100,12 @@ class SetConfigRequest(_message.Message): provider: ConfigProvider ref: ConfigRef value: bytes - def __init__(self, provider: _Optional[_Union[ConfigProvider, str]] = ..., ref: _Optional[_Union[ConfigRef, _Mapping]] = ..., value: _Optional[bytes] = ...) -> None: ... + def __init__( + self, + provider: _Optional[_Union[ConfigProvider, str]] = ..., + ref: _Optional[_Union[ConfigRef, _Mapping]] = ..., + value: _Optional[bytes] = ..., + ) -> None: ... class SetConfigResponse(_message.Message): __slots__ = () @@ -92,7 +117,11 @@ class UnsetConfigRequest(_message.Message): REF_FIELD_NUMBER: _ClassVar[int] provider: ConfigProvider ref: ConfigRef - def __init__(self, provider: _Optional[_Union[ConfigProvider, str]] = ..., ref: _Optional[_Union[ConfigRef, _Mapping]] = ...) -> None: ... + def __init__( + self, + provider: _Optional[_Union[ConfigProvider, str]] = ..., + ref: _Optional[_Union[ConfigRef, _Mapping]] = ..., + ) -> None: ... class UnsetConfigResponse(_message.Message): __slots__ = () @@ -106,7 +135,12 @@ class ListSecretsRequest(_message.Message): module: str include_values: bool provider: SecretProvider - def __init__(self, module: _Optional[str] = ..., include_values: bool = ..., provider: _Optional[_Union[SecretProvider, str]] = ...) -> None: ... + def __init__( + self, + module: _Optional[str] = ..., + include_values: bool = ..., + provider: _Optional[_Union[SecretProvider, str]] = ..., + ) -> None: ... class ListSecretsResponse(_message.Message): __slots__ = ("secrets",) @@ -116,10 +150,18 @@ class ListSecretsResponse(_message.Message): VALUE_FIELD_NUMBER: _ClassVar[int] refPath: str value: bytes - def __init__(self, refPath: _Optional[str] = ..., value: _Optional[bytes] = ...) -> None: ... + def __init__( + self, refPath: _Optional[str] = ..., value: _Optional[bytes] = ... + ) -> None: ... + SECRETS_FIELD_NUMBER: _ClassVar[int] secrets: _containers.RepeatedCompositeFieldContainer[ListSecretsResponse.Secret] - def __init__(self, secrets: _Optional[_Iterable[_Union[ListSecretsResponse.Secret, _Mapping]]] = ...) -> None: ... + def __init__( + self, + secrets: _Optional[ + _Iterable[_Union[ListSecretsResponse.Secret, _Mapping]] + ] = ..., + ) -> None: ... class GetSecretRequest(_message.Message): __slots__ = ("ref",) @@ -141,7 +183,12 @@ class SetSecretRequest(_message.Message): provider: SecretProvider ref: ConfigRef value: bytes - def __init__(self, provider: _Optional[_Union[SecretProvider, str]] = ..., ref: _Optional[_Union[ConfigRef, _Mapping]] = ..., value: _Optional[bytes] = ...) -> None: ... + def __init__( + self, + provider: _Optional[_Union[SecretProvider, str]] = ..., + ref: _Optional[_Union[ConfigRef, _Mapping]] = ..., + value: _Optional[bytes] = ..., + ) -> None: ... class SetSecretResponse(_message.Message): __slots__ = () @@ -153,7 +200,11 @@ class UnsetSecretRequest(_message.Message): REF_FIELD_NUMBER: _ClassVar[int] provider: SecretProvider ref: ConfigRef - def __init__(self, provider: _Optional[_Union[SecretProvider, str]] = ..., ref: _Optional[_Union[ConfigRef, _Mapping]] = ...) -> None: ... + def __init__( + self, + provider: _Optional[_Union[SecretProvider, str]] = ..., + ref: _Optional[_Union[ConfigRef, _Mapping]] = ..., + ) -> None: ... class UnsetSecretResponse(_message.Message): __slots__ = () diff --git a/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/v1/controller_pb2.py b/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/v1/controller_pb2.py index 8b65ac5e47..2f7196edf8 100644 --- a/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/v1/controller_pb2.py +++ b/python-runtime/ftl/src/ftl/protos/xyz/block/ftl/v1/controller_pb2.py @@ -4,126 +4,129 @@ # source: xyz/block/ftl/v1/controller.proto # Protobuf Python Version: 5.28.3 """Generated protocol buffer code.""" + from google.protobuf import descriptor as _descriptor from google.protobuf import descriptor_pool as _descriptor_pool from google.protobuf import runtime_version as _runtime_version from google.protobuf import symbol_database as _symbol_database from google.protobuf.internal import builder as _builder + _runtime_version.ValidateProtobufRuntimeVersion( - _runtime_version.Domain.PUBLIC, - 5, - 28, - 3, - '', - 'xyz/block/ftl/v1/controller.proto' + _runtime_version.Domain.PUBLIC, 5, 28, 3, "", "xyz/block/ftl/v1/controller.proto" ) # @@protoc_insertion_point(imports) _sym_db = _symbol_database.Default() -from google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2 -from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 -from xyz.block.ftl.v1 import ftl_pb2 as xyz_dot_block_dot_ftl_dot_v1_dot_ftl__pb2 -from xyz.block.ftl.v1.schema import schema_pb2 as xyz_dot_block_dot_ftl_dot_v1_dot_schema_dot_schema__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n!xyz/block/ftl/v1/controller.proto\x12\x10xyz.block.ftl.v1\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1axyz/block/ftl/v1/ftl.proto\x1a$xyz/block/ftl/v1/schema/schema.proto\"w\n\x17GetCertificationRequest\x12>\n\x07request\x18\x01 \x01(\x0b\x32$.xyz.block.ftl.v1.CertificateContentR\x07request\x12\x1c\n\tsignature\x18\x02 \x01(\x0cR\tsignature\"[\n\x18GetCertificationResponse\x12?\n\x0b\x63\x65rtificate\x18\x01 \x01(\x0b\x32\x1d.xyz.block.ftl.v1.CertificateR\x0b\x63\x65rtificate\"O\n\x12\x43\x65rtificateContent\x12\x1a\n\x08identity\x18\x01 \x01(\tR\x08identity\x12\x1d\n\npublic_key\x18\x02 \x01(\x0cR\tpublicKey\"\x80\x01\n\x0b\x43\x65rtificate\x12>\n\x07\x63ontent\x18\x01 \x01(\x0b\x32$.xyz.block.ftl.v1.CertificateContentR\x07\x63ontent\x12\x31\n\x14\x63ontroller_signature\x18\x03 \x01(\x0cR\x13\x63ontrollerSignature\"\x12\n\x10GetSchemaRequest\"L\n\x11GetSchemaResponse\x12\x37\n\x06schema\x18\x01 \x01(\x0b\x32\x1f.xyz.block.ftl.v1.schema.SchemaR\x06schema\"\x13\n\x11PullSchemaRequest\"\x82\x02\n\x12PullSchemaResponse\x12%\n\x0e\x64\x65ployment_key\x18\x01 \x01(\tR\rdeploymentKey\x12\x1f\n\x0bmodule_name\x18\x02 \x01(\tR\nmoduleName\x12<\n\x06schema\x18\x04 \x01(\x0b\x32\x1f.xyz.block.ftl.v1.schema.ModuleH\x00R\x06schema\x88\x01\x01\x12\x12\n\x04more\x18\x03 \x01(\x08R\x04more\x12G\n\x0b\x63hange_type\x18\x05 \x01(\x0e\x32&.xyz.block.ftl.v1.DeploymentChangeTypeR\nchangeTypeB\t\n\x07_schema\"@\n\x17GetArtefactDiffsRequest\x12%\n\x0e\x63lient_digests\x18\x01 \x03(\tR\rclientDigests\"\x94\x01\n\x18GetArtefactDiffsResponse\x12\'\n\x0fmissing_digests\x18\x01 \x03(\tR\x0emissingDigests\x12O\n\x10\x63lient_artefacts\x18\x02 \x03(\x0b\x32$.xyz.block.ftl.v1.DeploymentArtefactR\x0f\x63lientArtefacts\"1\n\x15UploadArtefactRequest\x12\x18\n\x07\x63ontent\x18\x01 \x01(\x0cR\x07\x63ontent\"0\n\x16UploadArtefactResponse\x12\x16\n\x06\x64igest\x18\x02 \x01(\x0cR\x06\x64igest\"`\n\x12\x44\x65ploymentArtefact\x12\x16\n\x06\x64igest\x18\x01 \x01(\tR\x06\x64igest\x12\x12\n\x04path\x18\x02 \x01(\tR\x04path\x12\x1e\n\nexecutable\x18\x03 \x01(\x08R\nexecutable\"\xd7\x01\n\x17\x43reateDeploymentRequest\x12\x37\n\x06schema\x18\x01 \x01(\x0b\x32\x1f.xyz.block.ftl.v1.schema.ModuleR\x06schema\x12\x42\n\tartefacts\x18\x02 \x03(\x0b\x32$.xyz.block.ftl.v1.DeploymentArtefactR\tartefacts\x12\x34\n\x06labels\x18\x03 \x01(\x0b\x32\x17.google.protobuf.StructH\x00R\x06labels\x88\x01\x01\x42\t\n\x07_labels\"\x94\x01\n\x18\x43reateDeploymentResponse\x12%\n\x0e\x64\x65ployment_key\x18\x01 \x01(\tR\rdeploymentKey\x12\x37\n\x15\x61\x63tive_deployment_key\x18\x02 \x01(\tH\x00R\x13\x61\x63tiveDeploymentKey\x88\x01\x01\x42\x18\n\x16_active_deployment_key\"\x93\x01\n\x1dGetDeploymentArtefactsRequest\x12%\n\x0e\x64\x65ployment_key\x18\x01 \x01(\tR\rdeploymentKey\x12K\n\x0ehave_artefacts\x18\x02 \x03(\x0b\x32$.xyz.block.ftl.v1.DeploymentArtefactR\rhaveArtefacts\"x\n\x1eGetDeploymentArtefactsResponse\x12@\n\x08\x61rtefact\x18\x01 \x01(\x0b\x32$.xyz.block.ftl.v1.DeploymentArtefactR\x08\x61rtefact\x12\x14\n\x05\x63hunk\x18\x02 \x01(\x0cR\x05\x63hunk\"=\n\x14GetDeploymentRequest\x12%\n\x0e\x64\x65ployment_key\x18\x01 \x01(\tR\rdeploymentKey\"\x94\x01\n\x15GetDeploymentResponse\x12\x37\n\x06schema\x18\x01 \x01(\x0b\x32\x1f.xyz.block.ftl.v1.schema.ModuleR\x06schema\x12\x42\n\tartefacts\x18\x02 \x03(\x0b\x32$.xyz.block.ftl.v1.DeploymentArtefactR\tartefacts\"\x96\x01\n\x15RegisterRunnerRequest\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x1a\n\x08\x65ndpoint\x18\x02 \x01(\tR\x08\x65ndpoint\x12\x1e\n\ndeployment\x18\x03 \x01(\tR\ndeployment\x12/\n\x06labels\x18\x05 \x01(\x0b\x32\x17.google.protobuf.StructR\x06labels\"\x18\n\x16RegisterRunnerResponse\"_\n\x13UpdateDeployRequest\x12%\n\x0e\x64\x65ployment_key\x18\x01 \x01(\tR\rdeploymentKey\x12!\n\x0cmin_replicas\x18\x02 \x01(\x05R\x0bminReplicas\"\x16\n\x14UpdateDeployResponse\"`\n\x14ReplaceDeployRequest\x12%\n\x0e\x64\x65ployment_key\x18\x01 \x01(\tR\rdeploymentKey\x12!\n\x0cmin_replicas\x18\x02 \x01(\x05R\x0bminReplicas\"\x17\n\x15ReplaceDeployResponse\"\xaf\x03\n\x1bStreamDeploymentLogsRequest\x12%\n\x0e\x64\x65ployment_key\x18\x01 \x01(\tR\rdeploymentKey\x12$\n\x0brequest_key\x18\x02 \x01(\tH\x00R\nrequestKey\x88\x01\x01\x12\x39\n\ntime_stamp\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\ttimeStamp\x12\x1b\n\tlog_level\x18\x04 \x01(\x05R\x08logLevel\x12]\n\nattributes\x18\x05 \x03(\x0b\x32=.xyz.block.ftl.v1.StreamDeploymentLogsRequest.AttributesEntryR\nattributes\x12\x18\n\x07message\x18\x06 \x01(\tR\x07message\x12\x19\n\x05\x65rror\x18\x07 \x01(\tH\x01R\x05\x65rror\x88\x01\x01\x1a=\n\x0f\x41ttributesEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n\x05value\x18\x02 \x01(\tR\x05value:\x02\x38\x01\x42\x0e\n\x0c_request_keyB\x08\n\x06_error\"\x1e\n\x1cStreamDeploymentLogsResponse\"\x0f\n\rStatusRequest\"\x86\t\n\x0eStatusResponse\x12M\n\x0b\x63ontrollers\x18\x01 \x03(\x0b\x32+.xyz.block.ftl.v1.StatusResponse.ControllerR\x0b\x63ontrollers\x12\x41\n\x07runners\x18\x02 \x03(\x0b\x32\'.xyz.block.ftl.v1.StatusResponse.RunnerR\x07runners\x12M\n\x0b\x64\x65ployments\x18\x03 \x03(\x0b\x32+.xyz.block.ftl.v1.StatusResponse.DeploymentR\x0b\x64\x65ployments\x12T\n\x0eingress_routes\x18\x04 \x03(\x0b\x32-.xyz.block.ftl.v1.StatusResponse.IngressRouteR\ringressRoutes\x12>\n\x06routes\x18\x05 \x03(\x0b\x32&.xyz.block.ftl.v1.StatusResponse.RouteR\x06routes\x1aT\n\nController\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x1a\n\x08\x65ndpoint\x18\x02 \x01(\tR\x08\x65ndpoint\x12\x18\n\x07version\x18\x03 \x01(\tR\x07version\x1a\xb9\x01\n\x06Runner\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x1c\n\tlanguages\x18\x02 \x03(\tR\tlanguages\x12\x1a\n\x08\x65ndpoint\x18\x03 \x01(\tR\x08\x65ndpoint\x12#\n\ndeployment\x18\x05 \x01(\tH\x00R\ndeployment\x88\x01\x01\x12/\n\x06labels\x18\x06 \x01(\x0b\x32\x17.google.protobuf.StructR\x06labelsB\r\n\x0b_deployment\x1a\xf7\x01\n\nDeployment\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x1a\n\x08language\x18\x02 \x01(\tR\x08language\x12\x12\n\x04name\x18\x03 \x01(\tR\x04name\x12!\n\x0cmin_replicas\x18\x04 \x01(\x05R\x0bminReplicas\x12\x1a\n\x08replicas\x18\x07 \x01(\x05R\x08replicas\x12/\n\x06labels\x18\x05 \x01(\x0b\x32\x17.google.protobuf.StructR\x06labels\x12\x37\n\x06schema\x18\x06 \x01(\x0b\x32\x1f.xyz.block.ftl.v1.schema.ModuleR\x06schema\x1a\x93\x01\n\x0cIngressRoute\x12%\n\x0e\x64\x65ployment_key\x18\x01 \x01(\tR\rdeploymentKey\x12\x30\n\x04verb\x18\x02 \x01(\x0b\x32\x1c.xyz.block.ftl.v1.schema.RefR\x04verb\x12\x16\n\x06method\x18\x03 \x01(\tR\x06method\x12\x12\n\x04path\x18\x04 \x01(\tR\x04path\x1a[\n\x05Route\x12\x16\n\x06module\x18\x01 \x01(\tR\x06module\x12\x1e\n\ndeployment\x18\x02 \x01(\tR\ndeployment\x12\x1a\n\x08\x65ndpoint\x18\x03 \x01(\tR\x08\x65ndpoint\"\x14\n\x12ProcessListRequest\"\xaf\x03\n\x13ProcessListResponse\x12K\n\tprocesses\x18\x01 \x03(\x0b\x32-.xyz.block.ftl.v1.ProcessListResponse.ProcessR\tprocesses\x1an\n\rProcessRunner\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x1a\n\x08\x65ndpoint\x18\x02 \x01(\tR\x08\x65ndpoint\x12/\n\x06labels\x18\x03 \x01(\x0b\x32\x17.google.protobuf.StructR\x06labels\x1a\xda\x01\n\x07Process\x12\x1e\n\ndeployment\x18\x01 \x01(\tR\ndeployment\x12!\n\x0cmin_replicas\x18\x02 \x01(\x05R\x0bminReplicas\x12/\n\x06labels\x18\x03 \x01(\x0b\x32\x17.google.protobuf.StructR\x06labels\x12P\n\x06runner\x18\x04 \x01(\x0b\x32\x33.xyz.block.ftl.v1.ProcessListResponse.ProcessRunnerH\x00R\x06runner\x88\x01\x01\x42\t\n\x07_runner\"\\\n\x18ResetSubscriptionRequest\x12@\n\x0csubscription\x18\x01 \x01(\x0b\x32\x1c.xyz.block.ftl.v1.schema.RefR\x0csubscription\"\x1b\n\x19ResetSubscriptionResponse*\\\n\x14\x44\x65ploymentChangeType\x12\x14\n\x10\x44\x45PLOYMENT_ADDED\x10\x00\x12\x16\n\x12\x44\x45PLOYMENT_REMOVED\x10\x01\x12\x16\n\x12\x44\x45PLOYMENT_CHANGED\x10\x02\x32\xcf\x0c\n\x11\x43ontrollerService\x12J\n\x04Ping\x12\x1d.xyz.block.ftl.v1.PingRequest\x1a\x1e.xyz.block.ftl.v1.PingResponse\"\x03\x90\x02\x01\x12Z\n\x0bProcessList\x12$.xyz.block.ftl.v1.ProcessListRequest\x1a%.xyz.block.ftl.v1.ProcessListResponse\x12K\n\x06Status\x12\x1f.xyz.block.ftl.v1.StatusRequest\x1a .xyz.block.ftl.v1.StatusResponse\x12i\n\x10GetCertification\x12).xyz.block.ftl.v1.GetCertificationRequest\x1a*.xyz.block.ftl.v1.GetCertificationResponse\x12i\n\x10GetArtefactDiffs\x12).xyz.block.ftl.v1.GetArtefactDiffsRequest\x1a*.xyz.block.ftl.v1.GetArtefactDiffsResponse\x12\x63\n\x0eUploadArtefact\x12\'.xyz.block.ftl.v1.UploadArtefactRequest\x1a(.xyz.block.ftl.v1.UploadArtefactResponse\x12i\n\x10\x43reateDeployment\x12).xyz.block.ftl.v1.CreateDeploymentRequest\x1a*.xyz.block.ftl.v1.CreateDeploymentResponse\x12`\n\rGetDeployment\x12&.xyz.block.ftl.v1.GetDeploymentRequest\x1a\'.xyz.block.ftl.v1.GetDeploymentResponse\x12}\n\x16GetDeploymentArtefacts\x12/.xyz.block.ftl.v1.GetDeploymentArtefactsRequest\x1a\x30.xyz.block.ftl.v1.GetDeploymentArtefactsResponse0\x01\x12\x65\n\x0eRegisterRunner\x12\'.xyz.block.ftl.v1.RegisterRunnerRequest\x1a(.xyz.block.ftl.v1.RegisterRunnerResponse(\x01\x12]\n\x0cUpdateDeploy\x12%.xyz.block.ftl.v1.UpdateDeployRequest\x1a&.xyz.block.ftl.v1.UpdateDeployResponse\x12`\n\rReplaceDeploy\x12&.xyz.block.ftl.v1.ReplaceDeployRequest\x1a\'.xyz.block.ftl.v1.ReplaceDeployResponse\x12w\n\x14StreamDeploymentLogs\x12-.xyz.block.ftl.v1.StreamDeploymentLogsRequest\x1a..xyz.block.ftl.v1.StreamDeploymentLogsResponse(\x01\x12T\n\tGetSchema\x12\".xyz.block.ftl.v1.GetSchemaRequest\x1a#.xyz.block.ftl.v1.GetSchemaResponse\x12Y\n\nPullSchema\x12#.xyz.block.ftl.v1.PullSchemaRequest\x1a$.xyz.block.ftl.v1.PullSchemaResponse0\x01\x12l\n\x11ResetSubscription\x12*.xyz.block.ftl.v1.ResetSubscriptionRequest\x1a+.xyz.block.ftl.v1.ResetSubscriptionResponseBDP\x01Z@github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1;ftlv1b\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile( + b'\n!xyz/block/ftl/v1/controller.proto\x12\x10xyz.block.ftl.v1\x1a\x1cgoogle/protobuf/struct.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1axyz/block/ftl/v1/ftl.proto\x1a$xyz/block/ftl/v1/schema/schema.proto"w\n\x17GetCertificationRequest\x12>\n\x07request\x18\x01 \x01(\x0b\x32$.xyz.block.ftl.v1.CertificateContentR\x07request\x12\x1c\n\tsignature\x18\x02 \x01(\x0cR\tsignature"[\n\x18GetCertificationResponse\x12?\n\x0b\x63\x65rtificate\x18\x01 \x01(\x0b\x32\x1d.xyz.block.ftl.v1.CertificateR\x0b\x63\x65rtificate"O\n\x12\x43\x65rtificateContent\x12\x1a\n\x08identity\x18\x01 \x01(\tR\x08identity\x12\x1d\n\npublic_key\x18\x02 \x01(\x0cR\tpublicKey"\x80\x01\n\x0b\x43\x65rtificate\x12>\n\x07\x63ontent\x18\x01 \x01(\x0b\x32$.xyz.block.ftl.v1.CertificateContentR\x07\x63ontent\x12\x31\n\x14\x63ontroller_signature\x18\x03 \x01(\x0cR\x13\x63ontrollerSignature"\x12\n\x10GetSchemaRequest"L\n\x11GetSchemaResponse\x12\x37\n\x06schema\x18\x01 \x01(\x0b\x32\x1f.xyz.block.ftl.v1.schema.SchemaR\x06schema"\x13\n\x11PullSchemaRequest"\x82\x02\n\x12PullSchemaResponse\x12%\n\x0e\x64\x65ployment_key\x18\x01 \x01(\tR\rdeploymentKey\x12\x1f\n\x0bmodule_name\x18\x02 \x01(\tR\nmoduleName\x12<\n\x06schema\x18\x04 \x01(\x0b\x32\x1f.xyz.block.ftl.v1.schema.ModuleH\x00R\x06schema\x88\x01\x01\x12\x12\n\x04more\x18\x03 \x01(\x08R\x04more\x12G\n\x0b\x63hange_type\x18\x05 \x01(\x0e\x32&.xyz.block.ftl.v1.DeploymentChangeTypeR\nchangeTypeB\t\n\x07_schema"@\n\x17GetArtefactDiffsRequest\x12%\n\x0e\x63lient_digests\x18\x01 \x03(\tR\rclientDigests"\x94\x01\n\x18GetArtefactDiffsResponse\x12\'\n\x0fmissing_digests\x18\x01 \x03(\tR\x0emissingDigests\x12O\n\x10\x63lient_artefacts\x18\x02 \x03(\x0b\x32$.xyz.block.ftl.v1.DeploymentArtefactR\x0f\x63lientArtefacts"1\n\x15UploadArtefactRequest\x12\x18\n\x07\x63ontent\x18\x01 \x01(\x0cR\x07\x63ontent"0\n\x16UploadArtefactResponse\x12\x16\n\x06\x64igest\x18\x02 \x01(\x0cR\x06\x64igest"`\n\x12\x44\x65ploymentArtefact\x12\x16\n\x06\x64igest\x18\x01 \x01(\tR\x06\x64igest\x12\x12\n\x04path\x18\x02 \x01(\tR\x04path\x12\x1e\n\nexecutable\x18\x03 \x01(\x08R\nexecutable"\xd7\x01\n\x17\x43reateDeploymentRequest\x12\x37\n\x06schema\x18\x01 \x01(\x0b\x32\x1f.xyz.block.ftl.v1.schema.ModuleR\x06schema\x12\x42\n\tartefacts\x18\x02 \x03(\x0b\x32$.xyz.block.ftl.v1.DeploymentArtefactR\tartefacts\x12\x34\n\x06labels\x18\x03 \x01(\x0b\x32\x17.google.protobuf.StructH\x00R\x06labels\x88\x01\x01\x42\t\n\x07_labels"\x94\x01\n\x18\x43reateDeploymentResponse\x12%\n\x0e\x64\x65ployment_key\x18\x01 \x01(\tR\rdeploymentKey\x12\x37\n\x15\x61\x63tive_deployment_key\x18\x02 \x01(\tH\x00R\x13\x61\x63tiveDeploymentKey\x88\x01\x01\x42\x18\n\x16_active_deployment_key"\x93\x01\n\x1dGetDeploymentArtefactsRequest\x12%\n\x0e\x64\x65ployment_key\x18\x01 \x01(\tR\rdeploymentKey\x12K\n\x0ehave_artefacts\x18\x02 \x03(\x0b\x32$.xyz.block.ftl.v1.DeploymentArtefactR\rhaveArtefacts"x\n\x1eGetDeploymentArtefactsResponse\x12@\n\x08\x61rtefact\x18\x01 \x01(\x0b\x32$.xyz.block.ftl.v1.DeploymentArtefactR\x08\x61rtefact\x12\x14\n\x05\x63hunk\x18\x02 \x01(\x0cR\x05\x63hunk"=\n\x14GetDeploymentRequest\x12%\n\x0e\x64\x65ployment_key\x18\x01 \x01(\tR\rdeploymentKey"\x94\x01\n\x15GetDeploymentResponse\x12\x37\n\x06schema\x18\x01 \x01(\x0b\x32\x1f.xyz.block.ftl.v1.schema.ModuleR\x06schema\x12\x42\n\tartefacts\x18\x02 \x03(\x0b\x32$.xyz.block.ftl.v1.DeploymentArtefactR\tartefacts"\x96\x01\n\x15RegisterRunnerRequest\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x1a\n\x08\x65ndpoint\x18\x02 \x01(\tR\x08\x65ndpoint\x12\x1e\n\ndeployment\x18\x03 \x01(\tR\ndeployment\x12/\n\x06labels\x18\x05 \x01(\x0b\x32\x17.google.protobuf.StructR\x06labels"\x18\n\x16RegisterRunnerResponse"_\n\x13UpdateDeployRequest\x12%\n\x0e\x64\x65ployment_key\x18\x01 \x01(\tR\rdeploymentKey\x12!\n\x0cmin_replicas\x18\x02 \x01(\x05R\x0bminReplicas"\x16\n\x14UpdateDeployResponse"`\n\x14ReplaceDeployRequest\x12%\n\x0e\x64\x65ployment_key\x18\x01 \x01(\tR\rdeploymentKey\x12!\n\x0cmin_replicas\x18\x02 \x01(\x05R\x0bminReplicas"\x17\n\x15ReplaceDeployResponse"\xaf\x03\n\x1bStreamDeploymentLogsRequest\x12%\n\x0e\x64\x65ployment_key\x18\x01 \x01(\tR\rdeploymentKey\x12$\n\x0brequest_key\x18\x02 \x01(\tH\x00R\nrequestKey\x88\x01\x01\x12\x39\n\ntime_stamp\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.TimestampR\ttimeStamp\x12\x1b\n\tlog_level\x18\x04 \x01(\x05R\x08logLevel\x12]\n\nattributes\x18\x05 \x03(\x0b\x32=.xyz.block.ftl.v1.StreamDeploymentLogsRequest.AttributesEntryR\nattributes\x12\x18\n\x07message\x18\x06 \x01(\tR\x07message\x12\x19\n\x05\x65rror\x18\x07 \x01(\tH\x01R\x05\x65rror\x88\x01\x01\x1a=\n\x0f\x41ttributesEntry\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n\x05value\x18\x02 \x01(\tR\x05value:\x02\x38\x01\x42\x0e\n\x0c_request_keyB\x08\n\x06_error"\x1e\n\x1cStreamDeploymentLogsResponse"\x0f\n\rStatusRequest"\x86\t\n\x0eStatusResponse\x12M\n\x0b\x63ontrollers\x18\x01 \x03(\x0b\x32+.xyz.block.ftl.v1.StatusResponse.ControllerR\x0b\x63ontrollers\x12\x41\n\x07runners\x18\x02 \x03(\x0b\x32\'.xyz.block.ftl.v1.StatusResponse.RunnerR\x07runners\x12M\n\x0b\x64\x65ployments\x18\x03 \x03(\x0b\x32+.xyz.block.ftl.v1.StatusResponse.DeploymentR\x0b\x64\x65ployments\x12T\n\x0eingress_routes\x18\x04 \x03(\x0b\x32-.xyz.block.ftl.v1.StatusResponse.IngressRouteR\ringressRoutes\x12>\n\x06routes\x18\x05 \x03(\x0b\x32&.xyz.block.ftl.v1.StatusResponse.RouteR\x06routes\x1aT\n\nController\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x1a\n\x08\x65ndpoint\x18\x02 \x01(\tR\x08\x65ndpoint\x12\x18\n\x07version\x18\x03 \x01(\tR\x07version\x1a\xb9\x01\n\x06Runner\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x1c\n\tlanguages\x18\x02 \x03(\tR\tlanguages\x12\x1a\n\x08\x65ndpoint\x18\x03 \x01(\tR\x08\x65ndpoint\x12#\n\ndeployment\x18\x05 \x01(\tH\x00R\ndeployment\x88\x01\x01\x12/\n\x06labels\x18\x06 \x01(\x0b\x32\x17.google.protobuf.StructR\x06labelsB\r\n\x0b_deployment\x1a\xf7\x01\n\nDeployment\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x1a\n\x08language\x18\x02 \x01(\tR\x08language\x12\x12\n\x04name\x18\x03 \x01(\tR\x04name\x12!\n\x0cmin_replicas\x18\x04 \x01(\x05R\x0bminReplicas\x12\x1a\n\x08replicas\x18\x07 \x01(\x05R\x08replicas\x12/\n\x06labels\x18\x05 \x01(\x0b\x32\x17.google.protobuf.StructR\x06labels\x12\x37\n\x06schema\x18\x06 \x01(\x0b\x32\x1f.xyz.block.ftl.v1.schema.ModuleR\x06schema\x1a\x93\x01\n\x0cIngressRoute\x12%\n\x0e\x64\x65ployment_key\x18\x01 \x01(\tR\rdeploymentKey\x12\x30\n\x04verb\x18\x02 \x01(\x0b\x32\x1c.xyz.block.ftl.v1.schema.RefR\x04verb\x12\x16\n\x06method\x18\x03 \x01(\tR\x06method\x12\x12\n\x04path\x18\x04 \x01(\tR\x04path\x1a[\n\x05Route\x12\x16\n\x06module\x18\x01 \x01(\tR\x06module\x12\x1e\n\ndeployment\x18\x02 \x01(\tR\ndeployment\x12\x1a\n\x08\x65ndpoint\x18\x03 \x01(\tR\x08\x65ndpoint"\x14\n\x12ProcessListRequest"\xaf\x03\n\x13ProcessListResponse\x12K\n\tprocesses\x18\x01 \x03(\x0b\x32-.xyz.block.ftl.v1.ProcessListResponse.ProcessR\tprocesses\x1an\n\rProcessRunner\x12\x10\n\x03key\x18\x01 \x01(\tR\x03key\x12\x1a\n\x08\x65ndpoint\x18\x02 \x01(\tR\x08\x65ndpoint\x12/\n\x06labels\x18\x03 \x01(\x0b\x32\x17.google.protobuf.StructR\x06labels\x1a\xda\x01\n\x07Process\x12\x1e\n\ndeployment\x18\x01 \x01(\tR\ndeployment\x12!\n\x0cmin_replicas\x18\x02 \x01(\x05R\x0bminReplicas\x12/\n\x06labels\x18\x03 \x01(\x0b\x32\x17.google.protobuf.StructR\x06labels\x12P\n\x06runner\x18\x04 \x01(\x0b\x32\x33.xyz.block.ftl.v1.ProcessListResponse.ProcessRunnerH\x00R\x06runner\x88\x01\x01\x42\t\n\x07_runner"\\\n\x18ResetSubscriptionRequest\x12@\n\x0csubscription\x18\x01 \x01(\x0b\x32\x1c.xyz.block.ftl.v1.schema.RefR\x0csubscription"\x1b\n\x19ResetSubscriptionResponse*\\\n\x14\x44\x65ploymentChangeType\x12\x14\n\x10\x44\x45PLOYMENT_ADDED\x10\x00\x12\x16\n\x12\x44\x45PLOYMENT_REMOVED\x10\x01\x12\x16\n\x12\x44\x45PLOYMENT_CHANGED\x10\x02\x32\xcf\x0c\n\x11\x43ontrollerService\x12J\n\x04Ping\x12\x1d.xyz.block.ftl.v1.PingRequest\x1a\x1e.xyz.block.ftl.v1.PingResponse"\x03\x90\x02\x01\x12Z\n\x0bProcessList\x12$.xyz.block.ftl.v1.ProcessListRequest\x1a%.xyz.block.ftl.v1.ProcessListResponse\x12K\n\x06Status\x12\x1f.xyz.block.ftl.v1.StatusRequest\x1a .xyz.block.ftl.v1.StatusResponse\x12i\n\x10GetCertification\x12).xyz.block.ftl.v1.GetCertificationRequest\x1a*.xyz.block.ftl.v1.GetCertificationResponse\x12i\n\x10GetArtefactDiffs\x12).xyz.block.ftl.v1.GetArtefactDiffsRequest\x1a*.xyz.block.ftl.v1.GetArtefactDiffsResponse\x12\x63\n\x0eUploadArtefact\x12\'.xyz.block.ftl.v1.UploadArtefactRequest\x1a(.xyz.block.ftl.v1.UploadArtefactResponse\x12i\n\x10\x43reateDeployment\x12).xyz.block.ftl.v1.CreateDeploymentRequest\x1a*.xyz.block.ftl.v1.CreateDeploymentResponse\x12`\n\rGetDeployment\x12&.xyz.block.ftl.v1.GetDeploymentRequest\x1a\'.xyz.block.ftl.v1.GetDeploymentResponse\x12}\n\x16GetDeploymentArtefacts\x12/.xyz.block.ftl.v1.GetDeploymentArtefactsRequest\x1a\x30.xyz.block.ftl.v1.GetDeploymentArtefactsResponse0\x01\x12\x65\n\x0eRegisterRunner\x12\'.xyz.block.ftl.v1.RegisterRunnerRequest\x1a(.xyz.block.ftl.v1.RegisterRunnerResponse(\x01\x12]\n\x0cUpdateDeploy\x12%.xyz.block.ftl.v1.UpdateDeployRequest\x1a&.xyz.block.ftl.v1.UpdateDeployResponse\x12`\n\rReplaceDeploy\x12&.xyz.block.ftl.v1.ReplaceDeployRequest\x1a\'.xyz.block.ftl.v1.ReplaceDeployResponse\x12w\n\x14StreamDeploymentLogs\x12-.xyz.block.ftl.v1.StreamDeploymentLogsRequest\x1a..xyz.block.ftl.v1.StreamDeploymentLogsResponse(\x01\x12T\n\tGetSchema\x12".xyz.block.ftl.v1.GetSchemaRequest\x1a#.xyz.block.ftl.v1.GetSchemaResponse\x12Y\n\nPullSchema\x12#.xyz.block.ftl.v1.PullSchemaRequest\x1a$.xyz.block.ftl.v1.PullSchemaResponse0\x01\x12l\n\x11ResetSubscription\x12*.xyz.block.ftl.v1.ResetSubscriptionRequest\x1a+.xyz.block.ftl.v1.ResetSubscriptionResponseBDP\x01Z@github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1;ftlv1b\x06proto3' +) _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'xyz.block.ftl.v1.controller_pb2', _globals) +_builder.BuildTopDescriptorsAndMessages( + DESCRIPTOR, "xyz.block.ftl.v1.controller_pb2", _globals +) if not _descriptor._USE_C_DESCRIPTORS: - _globals['DESCRIPTOR']._loaded_options = None - _globals['DESCRIPTOR']._serialized_options = b'P\001Z@github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1;ftlv1' - _globals['_STREAMDEPLOYMENTLOGSREQUEST_ATTRIBUTESENTRY']._loaded_options = None - _globals['_STREAMDEPLOYMENTLOGSREQUEST_ATTRIBUTESENTRY']._serialized_options = b'8\001' - _globals['_CONTROLLERSERVICE'].methods_by_name['Ping']._loaded_options = None - _globals['_CONTROLLERSERVICE'].methods_by_name['Ping']._serialized_options = b'\220\002\001' - _globals['_DEPLOYMENTCHANGETYPE']._serialized_start=4907 - _globals['_DEPLOYMENTCHANGETYPE']._serialized_end=4999 - _globals['_GETCERTIFICATIONREQUEST']._serialized_start=184 - _globals['_GETCERTIFICATIONREQUEST']._serialized_end=303 - _globals['_GETCERTIFICATIONRESPONSE']._serialized_start=305 - _globals['_GETCERTIFICATIONRESPONSE']._serialized_end=396 - _globals['_CERTIFICATECONTENT']._serialized_start=398 - _globals['_CERTIFICATECONTENT']._serialized_end=477 - _globals['_CERTIFICATE']._serialized_start=480 - _globals['_CERTIFICATE']._serialized_end=608 - _globals['_GETSCHEMAREQUEST']._serialized_start=610 - _globals['_GETSCHEMAREQUEST']._serialized_end=628 - _globals['_GETSCHEMARESPONSE']._serialized_start=630 - _globals['_GETSCHEMARESPONSE']._serialized_end=706 - _globals['_PULLSCHEMAREQUEST']._serialized_start=708 - _globals['_PULLSCHEMAREQUEST']._serialized_end=727 - _globals['_PULLSCHEMARESPONSE']._serialized_start=730 - _globals['_PULLSCHEMARESPONSE']._serialized_end=988 - _globals['_GETARTEFACTDIFFSREQUEST']._serialized_start=990 - _globals['_GETARTEFACTDIFFSREQUEST']._serialized_end=1054 - _globals['_GETARTEFACTDIFFSRESPONSE']._serialized_start=1057 - _globals['_GETARTEFACTDIFFSRESPONSE']._serialized_end=1205 - _globals['_UPLOADARTEFACTREQUEST']._serialized_start=1207 - _globals['_UPLOADARTEFACTREQUEST']._serialized_end=1256 - _globals['_UPLOADARTEFACTRESPONSE']._serialized_start=1258 - _globals['_UPLOADARTEFACTRESPONSE']._serialized_end=1306 - _globals['_DEPLOYMENTARTEFACT']._serialized_start=1308 - _globals['_DEPLOYMENTARTEFACT']._serialized_end=1404 - _globals['_CREATEDEPLOYMENTREQUEST']._serialized_start=1407 - _globals['_CREATEDEPLOYMENTREQUEST']._serialized_end=1622 - _globals['_CREATEDEPLOYMENTRESPONSE']._serialized_start=1625 - _globals['_CREATEDEPLOYMENTRESPONSE']._serialized_end=1773 - _globals['_GETDEPLOYMENTARTEFACTSREQUEST']._serialized_start=1776 - _globals['_GETDEPLOYMENTARTEFACTSREQUEST']._serialized_end=1923 - _globals['_GETDEPLOYMENTARTEFACTSRESPONSE']._serialized_start=1925 - _globals['_GETDEPLOYMENTARTEFACTSRESPONSE']._serialized_end=2045 - _globals['_GETDEPLOYMENTREQUEST']._serialized_start=2047 - _globals['_GETDEPLOYMENTREQUEST']._serialized_end=2108 - _globals['_GETDEPLOYMENTRESPONSE']._serialized_start=2111 - _globals['_GETDEPLOYMENTRESPONSE']._serialized_end=2259 - _globals['_REGISTERRUNNERREQUEST']._serialized_start=2262 - _globals['_REGISTERRUNNERREQUEST']._serialized_end=2412 - _globals['_REGISTERRUNNERRESPONSE']._serialized_start=2414 - _globals['_REGISTERRUNNERRESPONSE']._serialized_end=2438 - _globals['_UPDATEDEPLOYREQUEST']._serialized_start=2440 - _globals['_UPDATEDEPLOYREQUEST']._serialized_end=2535 - _globals['_UPDATEDEPLOYRESPONSE']._serialized_start=2537 - _globals['_UPDATEDEPLOYRESPONSE']._serialized_end=2559 - _globals['_REPLACEDEPLOYREQUEST']._serialized_start=2561 - _globals['_REPLACEDEPLOYREQUEST']._serialized_end=2657 - _globals['_REPLACEDEPLOYRESPONSE']._serialized_start=2659 - _globals['_REPLACEDEPLOYRESPONSE']._serialized_end=2682 - _globals['_STREAMDEPLOYMENTLOGSREQUEST']._serialized_start=2685 - _globals['_STREAMDEPLOYMENTLOGSREQUEST']._serialized_end=3116 - _globals['_STREAMDEPLOYMENTLOGSREQUEST_ATTRIBUTESENTRY']._serialized_start=3029 - _globals['_STREAMDEPLOYMENTLOGSREQUEST_ATTRIBUTESENTRY']._serialized_end=3090 - _globals['_STREAMDEPLOYMENTLOGSRESPONSE']._serialized_start=3118 - _globals['_STREAMDEPLOYMENTLOGSRESPONSE']._serialized_end=3148 - _globals['_STATUSREQUEST']._serialized_start=3150 - _globals['_STATUSREQUEST']._serialized_end=3165 - _globals['_STATUSRESPONSE']._serialized_start=3168 - _globals['_STATUSRESPONSE']._serialized_end=4326 - _globals['_STATUSRESPONSE_CONTROLLER']._serialized_start=3561 - _globals['_STATUSRESPONSE_CONTROLLER']._serialized_end=3645 - _globals['_STATUSRESPONSE_RUNNER']._serialized_start=3648 - _globals['_STATUSRESPONSE_RUNNER']._serialized_end=3833 - _globals['_STATUSRESPONSE_DEPLOYMENT']._serialized_start=3836 - _globals['_STATUSRESPONSE_DEPLOYMENT']._serialized_end=4083 - _globals['_STATUSRESPONSE_INGRESSROUTE']._serialized_start=4086 - _globals['_STATUSRESPONSE_INGRESSROUTE']._serialized_end=4233 - _globals['_STATUSRESPONSE_ROUTE']._serialized_start=4235 - _globals['_STATUSRESPONSE_ROUTE']._serialized_end=4326 - _globals['_PROCESSLISTREQUEST']._serialized_start=4328 - _globals['_PROCESSLISTREQUEST']._serialized_end=4348 - _globals['_PROCESSLISTRESPONSE']._serialized_start=4351 - _globals['_PROCESSLISTRESPONSE']._serialized_end=4782 - _globals['_PROCESSLISTRESPONSE_PROCESSRUNNER']._serialized_start=4451 - _globals['_PROCESSLISTRESPONSE_PROCESSRUNNER']._serialized_end=4561 - _globals['_PROCESSLISTRESPONSE_PROCESS']._serialized_start=4564 - _globals['_PROCESSLISTRESPONSE_PROCESS']._serialized_end=4782 - _globals['_RESETSUBSCRIPTIONREQUEST']._serialized_start=4784 - _globals['_RESETSUBSCRIPTIONREQUEST']._serialized_end=4876 - _globals['_RESETSUBSCRIPTIONRESPONSE']._serialized_start=4878 - _globals['_RESETSUBSCRIPTIONRESPONSE']._serialized_end=4905 - _globals['_CONTROLLERSERVICE']._serialized_start=5002 - _globals['_CONTROLLERSERVICE']._serialized_end=6617 + _globals["DESCRIPTOR"]._loaded_options = None + _globals[ + "DESCRIPTOR" + ]._serialized_options = ( + b"P\001Z@github.com/TBD54566975/ftl/backend/protos/xyz/block/ftl/v1;ftlv1" + ) + _globals["_STREAMDEPLOYMENTLOGSREQUEST_ATTRIBUTESENTRY"]._loaded_options = None + _globals[ + "_STREAMDEPLOYMENTLOGSREQUEST_ATTRIBUTESENTRY" + ]._serialized_options = b"8\001" + _globals["_CONTROLLERSERVICE"].methods_by_name["Ping"]._loaded_options = None + _globals["_CONTROLLERSERVICE"].methods_by_name[ + "Ping" + ]._serialized_options = b"\220\002\001" + _globals["_DEPLOYMENTCHANGETYPE"]._serialized_start = 4907 + _globals["_DEPLOYMENTCHANGETYPE"]._serialized_end = 4999 + _globals["_GETCERTIFICATIONREQUEST"]._serialized_start = 184 + _globals["_GETCERTIFICATIONREQUEST"]._serialized_end = 303 + _globals["_GETCERTIFICATIONRESPONSE"]._serialized_start = 305 + _globals["_GETCERTIFICATIONRESPONSE"]._serialized_end = 396 + _globals["_CERTIFICATECONTENT"]._serialized_start = 398 + _globals["_CERTIFICATECONTENT"]._serialized_end = 477 + _globals["_CERTIFICATE"]._serialized_start = 480 + _globals["_CERTIFICATE"]._serialized_end = 608 + _globals["_GETSCHEMAREQUEST"]._serialized_start = 610 + _globals["_GETSCHEMAREQUEST"]._serialized_end = 628 + _globals["_GETSCHEMARESPONSE"]._serialized_start = 630 + _globals["_GETSCHEMARESPONSE"]._serialized_end = 706 + _globals["_PULLSCHEMAREQUEST"]._serialized_start = 708 + _globals["_PULLSCHEMAREQUEST"]._serialized_end = 727 + _globals["_PULLSCHEMARESPONSE"]._serialized_start = 730 + _globals["_PULLSCHEMARESPONSE"]._serialized_end = 988 + _globals["_GETARTEFACTDIFFSREQUEST"]._serialized_start = 990 + _globals["_GETARTEFACTDIFFSREQUEST"]._serialized_end = 1054 + _globals["_GETARTEFACTDIFFSRESPONSE"]._serialized_start = 1057 + _globals["_GETARTEFACTDIFFSRESPONSE"]._serialized_end = 1205 + _globals["_UPLOADARTEFACTREQUEST"]._serialized_start = 1207 + _globals["_UPLOADARTEFACTREQUEST"]._serialized_end = 1256 + _globals["_UPLOADARTEFACTRESPONSE"]._serialized_start = 1258 + _globals["_UPLOADARTEFACTRESPONSE"]._serialized_end = 1306 + _globals["_DEPLOYMENTARTEFACT"]._serialized_start = 1308 + _globals["_DEPLOYMENTARTEFACT"]._serialized_end = 1404 + _globals["_CREATEDEPLOYMENTREQUEST"]._serialized_start = 1407 + _globals["_CREATEDEPLOYMENTREQUEST"]._serialized_end = 1622 + _globals["_CREATEDEPLOYMENTRESPONSE"]._serialized_start = 1625 + _globals["_CREATEDEPLOYMENTRESPONSE"]._serialized_end = 1773 + _globals["_GETDEPLOYMENTARTEFACTSREQUEST"]._serialized_start = 1776 + _globals["_GETDEPLOYMENTARTEFACTSREQUEST"]._serialized_end = 1923 + _globals["_GETDEPLOYMENTARTEFACTSRESPONSE"]._serialized_start = 1925 + _globals["_GETDEPLOYMENTARTEFACTSRESPONSE"]._serialized_end = 2045 + _globals["_GETDEPLOYMENTREQUEST"]._serialized_start = 2047 + _globals["_GETDEPLOYMENTREQUEST"]._serialized_end = 2108 + _globals["_GETDEPLOYMENTRESPONSE"]._serialized_start = 2111 + _globals["_GETDEPLOYMENTRESPONSE"]._serialized_end = 2259 + _globals["_REGISTERRUNNERREQUEST"]._serialized_start = 2262 + _globals["_REGISTERRUNNERREQUEST"]._serialized_end = 2412 + _globals["_REGISTERRUNNERRESPONSE"]._serialized_start = 2414 + _globals["_REGISTERRUNNERRESPONSE"]._serialized_end = 2438 + _globals["_UPDATEDEPLOYREQUEST"]._serialized_start = 2440 + _globals["_UPDATEDEPLOYREQUEST"]._serialized_end = 2535 + _globals["_UPDATEDEPLOYRESPONSE"]._serialized_start = 2537 + _globals["_UPDATEDEPLOYRESPONSE"]._serialized_end = 2559 + _globals["_REPLACEDEPLOYREQUEST"]._serialized_start = 2561 + _globals["_REPLACEDEPLOYREQUEST"]._serialized_end = 2657 + _globals["_REPLACEDEPLOYRESPONSE"]._serialized_start = 2659 + _globals["_REPLACEDEPLOYRESPONSE"]._serialized_end = 2682 + _globals["_STREAMDEPLOYMENTLOGSREQUEST"]._serialized_start = 2685 + _globals["_STREAMDEPLOYMENTLOGSREQUEST"]._serialized_end = 3116 + _globals["_STREAMDEPLOYMENTLOGSREQUEST_ATTRIBUTESENTRY"]._serialized_start = 3029 + _globals["_STREAMDEPLOYMENTLOGSREQUEST_ATTRIBUTESENTRY"]._serialized_end = 3090 + _globals["_STREAMDEPLOYMENTLOGSRESPONSE"]._serialized_start = 3118 + _globals["_STREAMDEPLOYMENTLOGSRESPONSE"]._serialized_end = 3148 + _globals["_STATUSREQUEST"]._serialized_start = 3150 + _globals["_STATUSREQUEST"]._serialized_end = 3165 + _globals["_STATUSRESPONSE"]._serialized_start = 3168 + _globals["_STATUSRESPONSE"]._serialized_end = 4326 + _globals["_STATUSRESPONSE_CONTROLLER"]._serialized_start = 3561 + _globals["_STATUSRESPONSE_CONTROLLER"]._serialized_end = 3645 + _globals["_STATUSRESPONSE_RUNNER"]._serialized_start = 3648 + _globals["_STATUSRESPONSE_RUNNER"]._serialized_end = 3833 + _globals["_STATUSRESPONSE_DEPLOYMENT"]._serialized_start = 3836 + _globals["_STATUSRESPONSE_DEPLOYMENT"]._serialized_end = 4083 + _globals["_STATUSRESPONSE_INGRESSROUTE"]._serialized_start = 4086 + _globals["_STATUSRESPONSE_INGRESSROUTE"]._serialized_end = 4233 + _globals["_STATUSRESPONSE_ROUTE"]._serialized_start = 4235 + _globals["_STATUSRESPONSE_ROUTE"]._serialized_end = 4326 + _globals["_PROCESSLISTREQUEST"]._serialized_start = 4328 + _globals["_PROCESSLISTREQUEST"]._serialized_end = 4348 + _globals["_PROCESSLISTRESPONSE"]._serialized_start = 4351 + _globals["_PROCESSLISTRESPONSE"]._serialized_end = 4782 + _globals["_PROCESSLISTRESPONSE_PROCESSRUNNER"]._serialized_start = 4451 + _globals["_PROCESSLISTRESPONSE_PROCESSRUNNER"]._serialized_end = 4561 + _globals["_PROCESSLISTRESPONSE_PROCESS"]._serialized_start = 4564 + _globals["_PROCESSLISTRESPONSE_PROCESS"]._serialized_end = 4782 + _globals["_RESETSUBSCRIPTIONREQUEST"]._serialized_start = 4784 + _globals["_RESETSUBSCRIPTIONREQUEST"]._serialized_end = 4876 + _globals["_RESETSUBSCRIPTIONRESPONSE"]._serialized_start = 4878 + _globals["_RESETSUBSCRIPTIONRESPONSE"]._serialized_end = 4905 + _globals["_CONTROLLERSERVICE"]._serialized_start = 5002 + _globals["_CONTROLLERSERVICE"]._serialized_end = 6617 # @@protoc_insertion_point(module_scope) diff --git a/python-runtime/ftl/src/ftl/verb/__init__.py b/python-runtime/ftl/src/ftl/verb/__init__.py new file mode 100644 index 0000000000..403dec5838 --- /dev/null +++ b/python-runtime/ftl/src/ftl/verb/__init__.py @@ -0,0 +1,5 @@ +from .decorator import verb +from .extractor import VerbExtractor +from .model import Verb + +__all__ = ["verb", "Verb", "VerbExtractor"] diff --git a/python-runtime/ftl/src/ftl/verb/decorator.py b/python-runtime/ftl/src/ftl/verb/decorator.py new file mode 100644 index 0000000000..0245f7c2d7 --- /dev/null +++ b/python-runtime/ftl/src/ftl/verb/decorator.py @@ -0,0 +1,17 @@ +import functools +from typing import Any, Callable, Optional, TypeVar, Union + +from .model import Verb + +F = TypeVar("F", bound=Callable[..., Any]) + + +def verb( + func: Optional[F] = None, *, export: bool = False +) -> Union[F, Callable[[F], F]]: + def actual_decorator(fn: F) -> F: + return functools.update_wrapper(Verb(fn, export=export), fn) + + if func is not None: + return actual_decorator(func) + return actual_decorator diff --git a/python-runtime/ftl/src/ftl/verb/extractor.py b/python-runtime/ftl/src/ftl/verb/extractor.py new file mode 100644 index 0000000000..157f775ef5 --- /dev/null +++ b/python-runtime/ftl/src/ftl/verb/extractor.py @@ -0,0 +1,45 @@ +import ast +from typing import Optional + +from ftl.extract import LocalExtractionContext, extract_type +from ftl.protos.xyz.block.ftl.v1.schema import schema_pb2 as schemapb + +from .model import Verb + + +class VerbExtractor(ast.NodeVisitor): + def __init__( + self, context: LocalExtractionContext, module_name: str, file_path: str + ): + self.context = context + self.module_name = module_name + self.file_path = file_path + + def load_function(self, func_name: str) -> Optional[Verb]: + """Load a function from the module and return it if it exists.""" + try: + module = self.context.load_python_module(self.module_name, self.file_path) + return getattr(module, func_name, None) + except ImportError as e: + print(f"Error importing module {self.module_name}: {e}") + return None + + def visit_FunctionDef(self, node: ast.FunctionDef) -> None: + """Visit a function definition and extract schema if it's a verb.""" + func = self.load_function(node.name) + if func is None or not isinstance(func, Verb): + return + + try: + verb = schemapb.Verb( + pos=schemapb.Position( + filename=self.file_path, line=node.lineno, column=node.col_offset + ), + name=node.name, + request=extract_type(self.context, func.get_input_type()), + response=extract_type(self.context, func.get_output_type()), + export=func.export, + ) + self.context.add_verb(self.module_name, verb) + except Exception as e: + print(f"Error extracting Verb: {e}") diff --git a/python-runtime/ftl/src/ftl/verb/model.py b/python-runtime/ftl/src/ftl/verb/model.py new file mode 100644 index 0000000000..40f17bf2bf --- /dev/null +++ b/python-runtime/ftl/src/ftl/verb/model.py @@ -0,0 +1,31 @@ +import functools +import inspect +from typing import Any, Callable, Type, TypeVar, get_type_hints + +F = TypeVar("F", bound=Callable[..., Any]) + + +class Verb: + def __init__(self, func: F, *, export: bool = False) -> None: + self.func = func + self.export = export + + self._type_hints = get_type_hints(func) + self._signature = inspect.signature(func) + self._first_param = next(iter(self._signature.parameters)) + + def get_input_type(self) -> Type: + """Get the input type (first parameter type) of the verb.""" + return self._type_hints[self._first_param] + + def get_output_type(self) -> Type: + """Get the output type (return type) of the verb.""" + return self._type_hints["return"] + + def __call__(self, *args, **kwargs): + return self.func(*args, **kwargs) + + def __get__(self, obj, objtype=None): + if obj is None: + return self + return functools.partial(self.__call__, obj) diff --git a/python-runtime/ftl/uv.lock b/python-runtime/ftl/uv.lock index bb2822413e..b746105ddf 100644 --- a/python-runtime/ftl/uv.lock +++ b/python-runtime/ftl/uv.lock @@ -1,16 +1,44 @@ version = 1 requires-python = ">=3.12" +[[package]] +name = "beautifulsoup4" +version = "4.12.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "soupsieve" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b3/ca/824b1195773ce6166d388573fc106ce56d4a805bd7427b624e063596ec58/beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051", size = 581181 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b1/fe/e8c672695b37eecc5cbf43e1d0638d88d66ba3a44c4d321c796f4e59167f/beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed", size = 147925 }, +] + [[package]] name = "ftl" version = "0.1.0" source = { editable = "." } dependencies = [ + { name = "google" }, { name = "protobuf" }, ] [package.metadata] -requires-dist = [{ name = "protobuf", specifier = ">=5.28.3" }] +requires-dist = [ + { name = "google", specifier = ">=3.0.0" }, + { name = "protobuf", specifier = ">=5.28.3" }, +] + +[[package]] +name = "google" +version = "3.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "beautifulsoup4" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/89/97/b49c69893cddea912c7a660a4b6102c6b02cd268f8c7162dd70b7c16f753/google-3.0.0.tar.gz", hash = "sha256:143530122ee5130509ad5e989f0512f7cb218b2d4eddbafbad40fd10e8d8ccbe", size = 44978 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ac/35/17c9141c4ae21e9a29a43acdfd848e3e468a810517f862cad07977bf8fe9/google-3.0.0-py2.py3-none-any.whl", hash = "sha256:889cf695f84e4ae2c55fbc0cfdaf4c1e729417fa52ab1db0485202ba173e4935", size = 45258 }, +] [[package]] name = "protobuf" @@ -25,3 +53,12 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/5d/ae/3257b09328c0b4e59535e497b0c7537d4954038bdd53a2f0d2f49d15a7c4/protobuf-5.28.3-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:712319fbdddb46f21abb66cd33cb9e491a5763b2febd8f228251add221981135", size = 316624 }, { url = "https://files.pythonhosted.org/packages/ad/c3/2377c159e28ea89a91cf1ca223f827ae8deccb2c9c401e5ca233cd73002f/protobuf-5.28.3-py3-none-any.whl", hash = "sha256:cee1757663fa32a1ee673434fcf3bf24dd54763c79690201208bafec62f19eed", size = 169511 }, ] + +[[package]] +name = "soupsieve" +version = "2.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/ce/fbaeed4f9fb8b2daa961f90591662df6a86c1abf25c548329a86920aedfb/soupsieve-2.6.tar.gz", hash = "sha256:e2e68417777af359ec65daac1057404a3c8a5455bb8abc36f1a9866ab1a51abb", size = 101569 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/c2/fe97d779f3ef3b15f05c94a2f1e3d21732574ed441687474db9d342a7315/soupsieve-2.6-py3-none-any.whl", hash = "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9", size = 36186 }, +]