qtype 0.0.3__py3-none-any.whl → 0.0.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
qtype/cli.py CHANGED
@@ -7,10 +7,33 @@ import importlib
7
7
  import logging
8
8
  from pathlib import Path
9
9
 
10
+ try:
11
+ from importlib.metadata import entry_points
12
+ except ImportError:
13
+ # Fallback for Python < 3.10 (though you require 3.10+)
14
+ from importlib_metadata import entry_points # type: ignore[no-redef]
15
+
10
16
 
11
17
  def _discover_commands(subparsers: argparse._SubParsersAction) -> None:
12
18
  """Automatically discover and register command modules.
13
19
 
20
+ This function discovers commands from two sources:
21
+ 1. Built-in commands from the local commands directory
22
+ 2. Plugin commands from entry points defined by third-party packages
23
+
24
+ Args:
25
+ subparsers: The subparsers object to add commands to.
26
+ """
27
+ # First, discover built-in commands from the local commands directory
28
+ _discover_local_commands(subparsers)
29
+
30
+ # Then, discover plugin commands from entry points
31
+ _discover_plugin_commands(subparsers)
32
+
33
+
34
+ def _discover_local_commands(subparsers: argparse._SubParsersAction) -> None:
35
+ """Discover and register built-in command modules from the local commands directory.
36
+
14
37
  Args:
15
38
  subparsers: The subparsers object to add commands to.
16
39
  """
@@ -29,15 +52,61 @@ def _discover_commands(subparsers: argparse._SubParsersAction) -> None:
29
52
  module.parser(subparsers)
30
53
  else:
31
54
  logging.warning(
32
- f"Command module {module_name} does not have a 'parser' function"
55
+ f"Built-in command module {module_name} does not have a 'parser' function"
33
56
  )
34
57
  except Exception as e:
35
58
  logging.error(
36
- f"Failed to load command module {module_name}: {e}",
59
+ f"Failed to load built-in command module {module_name}: {e}",
37
60
  exc_info=True,
38
61
  )
39
62
 
40
63
 
64
+ def _discover_plugin_commands(subparsers: argparse._SubParsersAction) -> None:
65
+ """Discover and register plugin command modules from entry points.
66
+
67
+ Third-party packages can register commands by defining entry points in their
68
+ setup.py or pyproject.toml file like this:
69
+
70
+ [project.entry-points."qtype.commands"]
71
+ my-command = "my_package.qtype_commands:my_command_parser"
72
+
73
+ Args:
74
+ subparsers: The subparsers object to add commands to.
75
+ """
76
+ try:
77
+ # Get all entry points for the 'qtype.commands' group
78
+ eps = entry_points(group="qtype.commands")
79
+
80
+ for entry_point in eps:
81
+ try:
82
+ # Load the parser function from the entry point
83
+ parser_func = entry_point.load()
84
+
85
+ # Call the parser function to set up the subparser
86
+ if callable(parser_func):
87
+ parser_func(subparsers)
88
+ logging.debug(
89
+ f"Successfully loaded plugin command '{entry_point.name}' "
90
+ f"from {entry_point.value}"
91
+ )
92
+ else:
93
+ logging.warning(
94
+ f"Plugin entry point '{entry_point.name}' "
95
+ f"({entry_point.value}) is not callable"
96
+ )
97
+ except Exception as e:
98
+ logging.error(
99
+ f"Failed to load plugin command '{entry_point.name}' "
100
+ f"from {entry_point.value}: {e}",
101
+ exc_info=True,
102
+ )
103
+ except Exception as e:
104
+ logging.error(
105
+ f"Failed to discover plugin commands: {e}",
106
+ exc_info=True,
107
+ )
108
+
109
+
41
110
  def main() -> None:
42
111
  """
43
112
  Main entry point for the QType CLI.
qtype/interpreter/api.py CHANGED
@@ -23,13 +23,16 @@ class APIExecutor:
23
23
  self.host = host
24
24
  self.port = port
25
25
 
26
- def create_app(self, name: Optional[str]) -> FastAPI:
26
+ def create_app(
27
+ self,
28
+ name: Optional[str],
29
+ fast_api_args: dict = {
30
+ "docs_url": "/docs",
31
+ "redoc_url": "/redoc",
32
+ },
33
+ ) -> FastAPI:
27
34
  """Create FastAPI app with dynamic endpoints."""
28
- app = FastAPI(
29
- title=name or "QType API",
30
- docs_url="/docs", # Swagger UI
31
- redoc_url="/redoc",
32
- )
35
+ app = FastAPI(title=name or "QType API", **fast_api_args)
33
36
 
34
37
  flows = self.definition.flows if self.definition.flows else []
35
38
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: qtype
3
- Version: 0.0.3
3
+ Version: 0.0.5
4
4
  Summary: DSL for Generative AI Prototyping
5
5
  Author-email: Lou Kratz <lou.kratz+qtype@bazaarvoice.com>
6
6
  License-Expression: Apache-2.0
@@ -1,5 +1,5 @@
1
1
  qtype/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- qtype/cli.py,sha256=TjqZ6N0RGRZAcFm8Q6WkzXS_oV6cvYvsmbFdP8x9a-o,2113
2
+ qtype/cli.py,sha256=XSVtfzpjTbQBQ60iyb5oupwi-mFpGH5jT8H1bJQdjis,4697
3
3
  qtype/loader.py,sha256=4Ty5B0qWNQeehexh0anlP7hDmsso0bj7-IVt5VqnHWA,10992
4
4
  qtype/commands/__init__.py,sha256=Qo4M07zm5I63r8STxDjvt5fhP1jygdXTsExNGELkefc,257
5
5
  qtype/commands/convert.py,sha256=Mkk8BAJDOmZ_nPsa0YtzjdxxBMScWk-qeYye4ojWA0o,2453
@@ -20,7 +20,7 @@ qtype/dsl/domain_types.py,sha256=VglaF7eTVjUmLvubQeNQo2ZA0pRooQXZ-OPJ6edQBIk,153
20
20
  qtype/dsl/model.py,sha256=mAgqfG1us1mT53nYd0gAIwOSgudLSDlwQjUlG5MDfRg,21169
21
21
  qtype/dsl/validator.py,sha256=yuDFPHfErPTIpZXCIyBrwpZJAitMEW0jNL8867KixUA,17130
22
22
  qtype/interpreter/__init__.py,sha256=IaRF90JLFbsTLKz9LTOMI_Pz4xwVaEyXPNaXV7sLou8,43
23
- qtype/interpreter/api.py,sha256=DrBV0fF6f4HiGSgXzHE07FwOr5Qe7uBQ2yQ6UjDOUTU,3872
23
+ qtype/interpreter/api.py,sha256=9hwc8pPrfbUDxHfEERsnEtPRBVjU1ziSyBgGIR5gWDw,3924
24
24
  qtype/interpreter/conversions.py,sha256=d_hyWWR0PlhvRf2EiNt1sEzhFH8gIl3vMrVnSOFUZGk,5612
25
25
  qtype/interpreter/exceptions.py,sha256=Il8IF0UAtYWQXwvOVQCY-csfRzC1iOejHM1G-nF5EfY,288
26
26
  qtype/interpreter/flow.py,sha256=2u1wRahNFQaRRklnU4uW7_UKSD73-uZe_WiYlKitXQg,1233
@@ -42,9 +42,9 @@ qtype/semantic/errors.py,sha256=dmdxGkVHrTwfiEHj5RFu2q11dAtefsivpLdJd6QynK0,119
42
42
  qtype/semantic/generate.py,sha256=U4r5Yo1b0wTBgw3dLnqjYD6wD6lc0TqdwUjhIV_yQRI,13085
43
43
  qtype/semantic/model.py,sha256=Hd3rsTdvkHtAeIrPqpJf0yjHa697TnrUbm3pbrIgSK0,11047
44
44
  qtype/semantic/resolver.py,sha256=D3CmRmr_ACL54ZCbc9HxXCuCZ37bNtSzlPLMpOeeOcw,3439
45
- qtype-0.0.3.dist-info/licenses/LICENSE,sha256=1KA5EgYBSR0O6nCH2HEvk6Di53YKJ9r_VCR7G8G8qAY,11341
46
- qtype-0.0.3.dist-info/METADATA,sha256=F4WqzZVkHDvHI8gl7bzB7P0bGbQcYGuUoB-Wb4SOkLE,4809
47
- qtype-0.0.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
48
- qtype-0.0.3.dist-info/entry_points.txt,sha256=5y4vj8RLvgl2tXSj-Hm7v5-Tn3kP4-UonjNoN-mfaQE,41
49
- qtype-0.0.3.dist-info/top_level.txt,sha256=ONroH5B0mZ51jr7NSWCK0weFwwCO7wBLmyVS1YqNU14,6
50
- qtype-0.0.3.dist-info/RECORD,,
45
+ qtype-0.0.5.dist-info/licenses/LICENSE,sha256=1KA5EgYBSR0O6nCH2HEvk6Di53YKJ9r_VCR7G8G8qAY,11341
46
+ qtype-0.0.5.dist-info/METADATA,sha256=0T5PLI4kg58aPEnqie7J1Oxuc2edhz53R7S4Qi01uD4,4809
47
+ qtype-0.0.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
48
+ qtype-0.0.5.dist-info/entry_points.txt,sha256=5y4vj8RLvgl2tXSj-Hm7v5-Tn3kP4-UonjNoN-mfaQE,41
49
+ qtype-0.0.5.dist-info/top_level.txt,sha256=ONroH5B0mZ51jr7NSWCK0weFwwCO7wBLmyVS1YqNU14,6
50
+ qtype-0.0.5.dist-info/RECORD,,
File without changes