qtype 0.1.3__py3-none-any.whl → 0.1.7__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/dsl/model.py CHANGED
@@ -765,8 +765,9 @@ class AWSAuthProvider(AuthorizationProvider):
765
765
  has_keys = self.access_key_id and self.secret_access_key
766
766
  has_profile = self.profile_name
767
767
  has_role = self.role_arn
768
+ has_region = self.region
768
769
 
769
- if not (has_keys or has_profile or has_role):
770
+ if not (has_keys or has_profile or has_role or has_region):
770
771
  raise ValueError(
771
772
  "AWSAuthProvider must specify at least one authentication method: "
772
773
  "access keys, profile name, or role ARN."
qtype/dsl/parser.py CHANGED
@@ -153,12 +153,12 @@ def _format_validation_errors(
153
153
  error_msg = "Validation failed (see details above)"
154
154
  else:
155
155
  error_msg = "Validation failed:\n"
156
- for error in relevant_errors[:5]: # Show max 5 errors
156
+ for error in relevant_errors[:30]: # Show max 5 errors
157
157
  loc_path = _simplify_field_path(error["loc"])
158
158
  error_msg += f" {loc_path}: {error['msg']}\n"
159
159
 
160
- if len(relevant_errors) > 5:
161
- error_msg += f" ... and {len(relevant_errors) - 5} more errors\n"
160
+ if len(relevant_errors) > 30:
161
+ error_msg += f" ... and {len(relevant_errors) - 30} more errors\n"
162
162
 
163
163
  if source_name:
164
164
  error_msg = f"In {source_name}:\n{error_msg}"
@@ -34,6 +34,7 @@ from qtype.interpreter.base.secrets import SecretManagerBase
34
34
  from qtype.interpreter.types import InterpreterError
35
35
  from qtype.semantic.model import (
36
36
  APIKeyAuthProvider,
37
+ AWSAuthProvider,
37
38
  DocumentIndex,
38
39
  DocumentSplitter,
39
40
  Model,
@@ -302,7 +303,9 @@ def to_vector_store(
302
303
 
303
304
 
304
305
  @cached_resource
305
- def to_embedding_model(model: Model) -> BaseEmbedding:
306
+ def to_embedding_model(
307
+ model: Model, secret_manager: SecretManagerBase
308
+ ) -> BaseEmbedding:
306
309
  """Convert a qtype Model to a LlamaIndex embedding model."""
307
310
 
308
311
  if model.provider == "aws-bedrock":
@@ -310,7 +313,14 @@ def to_embedding_model(model: Model) -> BaseEmbedding:
310
313
  BedrockEmbedding,
311
314
  )
312
315
 
316
+ session = None
317
+ if model.auth is not None:
318
+ assert isinstance(model.auth, AWSAuthProvider)
319
+ with aws(model.auth, secret_manager) as session:
320
+ session = session._session
321
+
313
322
  bedrock_embedding: BaseEmbedding = BedrockEmbedding(
323
+ botocore_session=session,
314
324
  model_name=model.model_id if model.model_id else model.id,
315
325
  max_retries=100,
316
326
  )
@@ -320,8 +330,20 @@ def to_embedding_model(model: Model) -> BaseEmbedding:
320
330
  OpenAIEmbedding,
321
331
  )
322
332
 
333
+ api_key = None
334
+ if model.auth:
335
+ with auth(model.auth, secret_manager) as provider:
336
+ if not isinstance(provider, APIKeyAuthProvider):
337
+ raise InterpreterError(
338
+ f"OpenAI provider requires APIKeyAuthProvider, "
339
+ f"got {type(provider).__name__}"
340
+ )
341
+ # api_key is guaranteed to be str after auth() resolves it
342
+ api_key = provider.api_key # type: ignore[assignment]
343
+
323
344
  openai_embedding: BaseEmbedding = OpenAIEmbedding(
324
- model_name=model.model_id if model.model_id else model.id
345
+ api_key=api_key,
346
+ model_name=model.model_id if model.model_id else model.id,
325
347
  )
326
348
  return openai_embedding
327
349
  else:
@@ -566,7 +588,7 @@ def to_llama_vector_store_and_retriever(
566
588
  vector_store = to_vector_store(index, secret_manager)
567
589
 
568
590
  # Get the embedding model
569
- embedding_model = to_embedding_model(index.embedding_model)
591
+ embedding_model = to_embedding_model(index.embedding_model, secret_manager)
570
592
 
571
593
  # Create a VectorStoreIndex with the vector store and embedding model
572
594
  vector_index = VectorStoreIndex.from_vector_store(
@@ -1,3 +1,5 @@
1
+ import asyncio
2
+ import logging
1
3
  from typing import AsyncIterator
2
4
 
3
5
  from botocore.exceptions import ClientError
@@ -41,7 +43,7 @@ class DocumentEmbedderExecutor(StepExecutor):
41
43
  self.step: DocumentEmbedder = step
42
44
  # Initialize the embedding model once for the executor
43
45
  self.embedding_model: BaseEmbedding = to_embedding_model(
44
- self.step.model
46
+ self.step.model, context.secret_manager
45
47
  )
46
48
 
47
49
  # TODO: properly abstract this into a mixin
@@ -58,7 +60,17 @@ class DocumentEmbedderExecutor(StepExecutor):
58
60
  Returns:
59
61
  The embedding vector as a list of floats.
60
62
  """
61
- return await self.embedding_model.aget_text_embedding(text=text)
63
+
64
+ # TODO: switch back to async once aws auth supports it.
65
+ # https://github.com/bazaarvoice/qtype/issues/108
66
+ def _call():
67
+ return self.embedding_model.get_text_embedding(text=text)
68
+
69
+ loop = asyncio.get_running_loop()
70
+ response = await loop.run_in_executor(self.context.thread_pool, _call)
71
+
72
+ return response
73
+ # return await self.embedding_model.aget_text_embedding(text=text)
62
74
 
63
75
  async def process_message(
64
76
  self,
@@ -103,5 +115,9 @@ class DocumentEmbedderExecutor(StepExecutor):
103
115
  except Exception as e:
104
116
  # Emit error event to stream so frontend can display it
105
117
  await self.stream_emitter.error(str(e))
118
+ logging.error(
119
+ f"Error processing DocumentEmbedder step {self.step.id}",
120
+ exc_info=e,
121
+ )
106
122
  message.set_error(self.step.id, e)
107
123
  yield message
@@ -1,3 +1,4 @@
1
+ import asyncio
1
2
  from typing import AsyncIterator
2
3
 
3
4
  from openinference.semconv.trace import OpenInferenceSpanKindValues
@@ -30,7 +31,9 @@ class InvokeEmbeddingExecutor(StepExecutor):
30
31
  )
31
32
  self.step: InvokeEmbedding = step
32
33
  # Initialize the embedding model once for the executor
33
- self.embedding_model = to_embedding_model(self.step.model)
34
+ self.embedding_model = to_embedding_model(
35
+ self.step.model, context.secret_manager
36
+ )
34
37
 
35
38
  async def process_message(
36
39
  self,
@@ -54,32 +57,41 @@ class InvokeEmbeddingExecutor(StepExecutor):
54
57
  if input_value is None:
55
58
  raise ValueError(f"Input variable '{input_id}' is missing")
56
59
 
57
- # Generate embedding based on input type
58
- if input_type == PrimitiveTypeEnum.text:
59
- if not isinstance(input_value, str):
60
- input_value = str(input_value)
61
- vector = await self.embedding_model.aget_text_embedding(
62
- text=input_value
63
- )
64
- content = input_value
65
- elif input_type == PrimitiveTypeEnum.image:
66
- # For image embeddings
67
- vector = await self.embedding_model.aget_image_embedding(
68
- image_path=input_value
69
- )
70
- content = input_value
71
- else:
72
- raise ValueError(
73
- (
74
- f"Unsupported input type for embedding: "
75
- f"{input_type}. Must be 'text' or 'image'."
60
+ def _call(input_value=input_value):
61
+ # Generate embedding based on input type
62
+ if input_type == PrimitiveTypeEnum.text:
63
+ if not isinstance(input_value, str):
64
+ input_value = str(input_value)
65
+ vector = self.embedding_model.get_text_embedding(
66
+ text=input_value
67
+ )
68
+ content = input_value
69
+ elif input_type == PrimitiveTypeEnum.image:
70
+ # For image embeddings
71
+ vector = self.embedding_model.get_image_embedding(
72
+ image_path=input_value
76
73
  )
74
+ content = input_value
75
+ else:
76
+ raise ValueError(
77
+ (
78
+ f"Unsupported input type for embedding: "
79
+ f"{input_type}. Must be 'text' or 'image'."
80
+ )
81
+ )
82
+
83
+ # Create the Embedding object
84
+ embedding = Embedding(
85
+ vector=vector,
86
+ content=content,
77
87
  )
88
+ return embedding
78
89
 
79
- # Create the Embedding object
80
- embedding = Embedding(
81
- vector=vector,
82
- content=content,
90
+ # TODO: switch back to async once aws auth supports it.
91
+ # https://github.com/bazaarvoice/qtype/issues/108
92
+ loop = asyncio.get_running_loop()
93
+ embedding = await loop.run_in_executor(
94
+ self.context.thread_pool, _call
83
95
  )
84
96
 
85
97
  # Yield the result
qtype/interpreter/flow.py CHANGED
@@ -12,13 +12,12 @@ from opentelemetry import context as otel_context
12
12
  from opentelemetry import trace
13
13
  from opentelemetry.trace import Status, StatusCode
14
14
  from rich.console import Console
15
- from transformers import ProgressCallback
16
15
 
17
16
  from qtype.interpreter.base import factory
18
17
  from qtype.interpreter.base.executor_context import ExecutorContext
19
18
  from qtype.interpreter.logging_progress import LoggingProgressCallback
20
19
  from qtype.interpreter.rich_progress import RichProgressCallback
21
- from qtype.interpreter.types import FlowMessage
20
+ from qtype.interpreter.types import FlowMessage, ProgressCallback
22
21
  from qtype.semantic.model import Flow
23
22
 
24
23
  logger = logging.getLogger(__name__)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: qtype
3
- Version: 0.1.3
3
+ Version: 0.1.7
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
@@ -9,7 +9,7 @@ Requires-Python: >=3.10
9
9
  Description-Content-Type: text/markdown
10
10
  License-File: LICENSE
11
11
  Requires-Dist: jsonschema>=4.24.0
12
- Requires-Dist: pydantic>=2.11.5
12
+ Requires-Dist: pydantic>=2.12.4
13
13
  Requires-Dist: pyyaml>=6.0.2
14
14
  Requires-Dist: python-dotenv>=1.0.0
15
15
  Requires-Dist: openai>=1.93.0
@@ -25,15 +25,15 @@ qtype/dsl/custom_types.py,sha256=N3qswimv0foH40YDubHaTZ3HYF9RUbZ2x5eQ4i798Ko,290
25
25
  qtype/dsl/domain_types.py,sha256=-pX74DKwrRanoXBxYqAdN_f44ike6ssRV3tZ20R2PhQ,4319
26
26
  qtype/dsl/linker.py,sha256=c7PPTULy7_z_9u_qeseIaomR_B8kBa9YzOhQpjeGaSM,12975
27
27
  qtype/dsl/loader.py,sha256=mht0BqfmyTNHIEDaF3iTEmYQLJBP5GIZULwexxw9Dpg,9771
28
- qtype/dsl/model.py,sha256=0yKl3fKAWQ_BDH-z62oI47IiJQhaH6HFzYRD1tUZhME,40860
29
- qtype/dsl/parser.py,sha256=jpz32zyvOIo-R6Xr1lshzQiGfeo-2-fZczkdfURBufo,5487
28
+ qtype/dsl/model.py,sha256=g3cZ4-vh_WxrjJ1ev6kFfQcX2-NOZHb70ZT-7m-nHHY,40907
29
+ qtype/dsl/parser.py,sha256=Ww32bLQ2vGOObsA-vWjaMh4TOKRwEA7FAt9U6wjKZkw,5490
30
30
  qtype/dsl/types.py,sha256=k6cgThA287bZ_pvTKQvxWhatcYCPNne8zpqOYOvLvOg,1687
31
31
  qtype/interpreter/__init__.py,sha256=IaRF90JLFbsTLKz9LTOMI_Pz4xwVaEyXPNaXV7sLou8,43
32
32
  qtype/interpreter/api.py,sha256=V7hjsmDhe1IwbcwdM5bnPGBiwH3TtlMLjUJdGJumCdA,4193
33
- qtype/interpreter/conversions.py,sha256=SHtVVN8k36_iODKvHt1MV6V08GRaEBwE4yCN6VQvlHA,20986
33
+ qtype/interpreter/conversions.py,sha256=VKRJm5ofM3tWzXKg_zLTvKzi7GNBDv6MiE4HnQ52eFY,21871
34
34
  qtype/interpreter/converters.py,sha256=gWyfizl7d-DT6jJ2aOrneUcZcwB-LdMDEvl-VT0-mLQ,2348
35
35
  qtype/interpreter/endpoints.py,sha256=un4iCYCk86lYKpTDFdzlByvebdctNwRF3n4oD4ZwpTw,11946
36
- qtype/interpreter/flow.py,sha256=_RuOxGG34Ccvb3pS_f2e2xmpmmMcq7CakWBdS8ezZqY,6590
36
+ qtype/interpreter/flow.py,sha256=rncholeAv7gn3Pr99N9mIA5oFY4OMHVQX6IJljtVO34,6566
37
37
  qtype/interpreter/logging_progress.py,sha256=RmyNXdbpPZ7ye8cbSab0Tw10x3T38U3S8rj2bOTfbso,1848
38
38
  qtype/interpreter/metadata_api.py,sha256=LfJjt9atsgiAra6aVBXLoJrPa06_CBUagYysT556nt8,3267
39
39
  qtype/interpreter/resource_cache.py,sha256=K0kzpm223COWk7FN9qyOvNOEoOcABR4yLeADL9ekE_o,1188
@@ -59,7 +59,7 @@ qtype/interpreter/executors/aggregate_executor.py,sha256=Z3NJekpeo7aqqvOcXQqb6d6
59
59
  qtype/interpreter/executors/bedrock_reranker_executor.py,sha256=p25BMmM1paAlK2vfpwJ9T5st_2B-bmZoDnVFp9ynZIY,7154
60
60
  qtype/interpreter/executors/decoder_executor.py,sha256=KqLhnhiclMIcUNf3bu7H4vDAOXCQeVO0rc2hIXm1qZ4,5610
61
61
  qtype/interpreter/executors/doc_to_text_executor.py,sha256=ZkTtKUL0BfNIiuj-OcYybn1f0By6ujRmd1U4VEAtJt4,3804
62
- qtype/interpreter/executors/document_embedder_executor.py,sha256=wvARlFPb2dmMdxjW8L1422a-XmcUVxEJXWf24bDR9BE,3529
62
+ qtype/interpreter/executors/document_embedder_executor.py,sha256=dBx1yfjzGPAOAfCx0zr1uOkfs7JUWgHoKYanqnCFAQk,4089
63
63
  qtype/interpreter/executors/document_search_executor.py,sha256=ZmKAt__jC5cxZY0gSm9AgpC6n7MFavTHE01tQED3zFk,4051
64
64
  qtype/interpreter/executors/document_source_executor.py,sha256=ZpBrBaE16YeRk750TxvE08NnCIUzArjESZImESomaIo,4247
65
65
  qtype/interpreter/executors/document_splitter_executor.py,sha256=00x32yo1wGUvW88_lUahfGU94prUPGaOTk5GBUJbBJA,3882
@@ -68,7 +68,7 @@ qtype/interpreter/executors/field_extractor_executor.py,sha256=geDmT6GyvbDDJvPX1
68
68
  qtype/interpreter/executors/file_source_executor.py,sha256=OUT_zJrYN3iFMUgLECde93C4rv8PthcQsuJ--CJvEsI,3605
69
69
  qtype/interpreter/executors/file_writer_executor.py,sha256=x4BpgdXM7Xhz1tJJ5MmBIjFO4y80VC1V1ow3tox_Xrw,4099
70
70
  qtype/interpreter/executors/index_upsert_executor.py,sha256=5MxG3GX2bbjX6jhCpCdEZ0YFJOshn649cfaOT50PLCA,8518
71
- qtype/interpreter/executors/invoke_embedding_executor.py,sha256=OPvd--x8iimjODLJkRpRfQDahL8LnYaPy3A8WVB5h00,3311
71
+ qtype/interpreter/executors/invoke_embedding_executor.py,sha256=5iXh2elP51gdnuUvRDH_RuWugsm3KCJb8S15Oy4p8zg,3834
72
72
  qtype/interpreter/executors/invoke_flow_executor.py,sha256=U30cYM3F_zy1_2CD1Dde59xyZD0rDa5W46lST1hxF6s,1682
73
73
  qtype/interpreter/executors/invoke_tool_executor.py,sha256=hhbE8YTr0x5-kz_xsvdWGGzkLkVdvDoAVAF-3ZUK5as,12786
74
74
  qtype/interpreter/executors/llm_inference_executor.py,sha256=A6b_Ns_734TCn_DMhdNSqWc5qX970FryhpsX_jtEu_4,9593
@@ -129,9 +129,9 @@ qtype/semantic/loader.py,sha256=QRhTc_AJfsWSMn8ThaW60GmIGjFMN-3bBUy4pktFjz4,3041
129
129
  qtype/semantic/model.py,sha256=7yZ-Ufuo-gNJbhFXALuKZxILdhNB5zbL3a3oQQARI8g,28602
130
130
  qtype/semantic/resolver.py,sha256=bWPCSB8KJpVqN_n41U_r-qzUiT8vAMBOD3pOGmxL6TY,4618
131
131
  qtype/semantic/visualize.py,sha256=thjrZcfQuZJWrZ9EMAPhAa2kNikR5rLIJrfcD3hJ8XY,17426
132
- qtype-0.1.3.dist-info/licenses/LICENSE,sha256=1KA5EgYBSR0O6nCH2HEvk6Di53YKJ9r_VCR7G8G8qAY,11341
133
- qtype-0.1.3.dist-info/METADATA,sha256=Q5VxMaYqCF9FVArNhhzlhwIsggD-obWOwY_uRBtRFQU,5657
134
- qtype-0.1.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
135
- qtype-0.1.3.dist-info/entry_points.txt,sha256=5y4vj8RLvgl2tXSj-Hm7v5-Tn3kP4-UonjNoN-mfaQE,41
136
- qtype-0.1.3.dist-info/top_level.txt,sha256=ONroH5B0mZ51jr7NSWCK0weFwwCO7wBLmyVS1YqNU14,6
137
- qtype-0.1.3.dist-info/RECORD,,
132
+ qtype-0.1.7.dist-info/licenses/LICENSE,sha256=1KA5EgYBSR0O6nCH2HEvk6Di53YKJ9r_VCR7G8G8qAY,11341
133
+ qtype-0.1.7.dist-info/METADATA,sha256=N-2oIlfAJKDpgwT1XjZOKsH70kSUy6mSUSDR6j7ME0c,5657
134
+ qtype-0.1.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
135
+ qtype-0.1.7.dist-info/entry_points.txt,sha256=5y4vj8RLvgl2tXSj-Hm7v5-Tn3kP4-UonjNoN-mfaQE,41
136
+ qtype-0.1.7.dist-info/top_level.txt,sha256=ONroH5B0mZ51jr7NSWCK0weFwwCO7wBLmyVS1YqNU14,6
137
+ qtype-0.1.7.dist-info/RECORD,,
File without changes