1818from galileo .utils .exceptions import APIException
1919
2020if TYPE_CHECKING :
21- from galileo .__future__ .provider import AnthropicProvider , AzureProvider , BedrockProvider , OpenAIProvider , Provider
21+ from galileo .__future__ .provider import (
22+ AnthropicProvider ,
23+ AzureProvider ,
24+ BedrockProvider ,
25+ OpenAIProvider ,
26+ Provider ,
27+ UnconfiguredProvider ,
28+ )
2229
2330logger = logging .getLogger (__name__ )
2431
@@ -355,7 +362,7 @@ def _to_provider(cls, integration_db: IntegrationDB) -> Provider:
355362 # Convenience properties for accessing configured integrations by type
356363
357364 @classmethod
358- def _get_integration_by_name (cls , integration_name : str ) -> Provider | None :
365+ def _get_integration_by_name (cls , integration_name : str ) -> Provider | UnconfiguredProvider :
359366 """
360367 Get a configured integration by name.
361368
@@ -364,26 +371,24 @@ def _get_integration_by_name(cls, integration_name: str) -> Provider | None:
364371
365372 Returns
366373 -------
367- Provider | None: The provider if found, None otherwise.
374+ Provider | UnconfiguredProvider: The provider if found, or an UnconfiguredProvider
375+ that raises helpful errors when accessed.
368376 If multiple integrations of the same type exist,
369377 returns the selected one, or the first one if none selected.
370378 """
371379 try :
372380 providers_list = cls .list ()
373381 # Type narrowing: list() without all=True returns list[Provider]
374382 if providers_list and isinstance (providers_list [0 ], str ):
375- return None
383+ return UnconfiguredProvider ( integration_name )
376384
377385 # Cast is safe because we checked for strings above
378386 providers = cast (list [Provider ], providers_list )
379387 matching = [p for p in providers if p .name == integration_name ]
380388
381389 if not matching :
382- logger .warning (
383- f"Integration.{ integration_name } : No '{ integration_name } ' integration configured. "
384- f"Create one using Integration.create_{ integration_name .replace ('aws_' , '' )} ()"
385- )
386- return None
390+ logger .debug (f"Integration.{ integration_name } : No '{ integration_name } ' integration configured." )
391+ return UnconfiguredProvider (integration_name )
387392
388393 # If multiple matches, prefer the selected one
389394 selected = [p for p in matching if p .is_selected ]
@@ -394,16 +399,17 @@ def _get_integration_by_name(cls, integration_name: str) -> Provider | None:
394399 return matching [0 ]
395400 except Exception as e :
396401 logger .error (f"Integration._get_integration_by_name: failed to get { integration_name } : { e } " )
397- return None
402+ return UnconfiguredProvider ( integration_name )
398403
399404 @classproperty
400- def openai (cls ) -> Provider | None :
405+ def openai (cls ) -> Provider | UnconfiguredProvider :
401406 """
402407 Get the configured OpenAI integration.
403408
404409 Returns
405410 -------
406- OpenAIProvider | None: The OpenAI provider if configured, None otherwise.
411+ OpenAIProvider | UnconfiguredProvider: The OpenAI provider if configured,
412+ or UnconfiguredProvider that raises helpful errors when accessed.
407413
408414 Examples
409415 --------
@@ -414,13 +420,14 @@ def openai(cls) -> Provider | None:
414420 return cls ._get_integration_by_name ("openai" )
415421
416422 @classproperty
417- def azure (cls ) -> Provider | None :
423+ def azure (cls ) -> Provider | UnconfiguredProvider :
418424 """
419425 Get the configured Azure OpenAI integration.
420426
421427 Returns
422428 -------
423- AzureProvider | None: The Azure provider if configured, None otherwise.
429+ AzureProvider | UnconfiguredProvider: The Azure provider if configured,
430+ or UnconfiguredProvider that raises helpful errors when accessed.
424431
425432 Examples
426433 --------
@@ -431,13 +438,14 @@ def azure(cls) -> Provider | None:
431438 return cls ._get_integration_by_name ("azure" )
432439
433440 @classproperty
434- def bedrock (cls ) -> Provider | None :
441+ def bedrock (cls ) -> Provider | UnconfiguredProvider :
435442 """
436443 Get the configured AWS Bedrock integration.
437444
438445 Returns
439446 -------
440- BedrockProvider | None: The Bedrock provider if configured, None otherwise.
447+ BedrockProvider | UnconfiguredProvider: The Bedrock provider if configured,
448+ or UnconfiguredProvider that raises helpful errors when accessed.
441449
442450 Examples
443451 --------
@@ -448,13 +456,14 @@ def bedrock(cls) -> Provider | None:
448456 return cls ._get_integration_by_name ("aws_bedrock" )
449457
450458 @classproperty
451- def anthropic (cls ) -> Provider | None :
459+ def anthropic (cls ) -> Provider | UnconfiguredProvider :
452460 """
453461 Get the configured Anthropic (Claude) integration.
454462
455463 Returns
456464 -------
457- AnthropicProvider | None: The Anthropic provider if configured, None otherwise.
465+ AnthropicProvider | UnconfiguredProvider: The Anthropic provider if configured,
466+ or UnconfiguredProvider that raises helpful errors when accessed.
458467
459468 Examples
460469 --------
@@ -465,13 +474,14 @@ def anthropic(cls) -> Provider | None:
465474 return cls ._get_integration_by_name ("anthropic" )
466475
467476 @classproperty
468- def vertex_ai (cls ) -> Provider | None :
477+ def vertex_ai (cls ) -> Provider | UnconfiguredProvider :
469478 """
470479 Get the configured Google Vertex AI integration.
471480
472481 Returns
473482 -------
474- Provider | None: The Vertex AI provider if configured, None otherwise.
483+ Provider | UnconfiguredProvider: The Vertex AI provider if configured,
484+ or UnconfiguredProvider that raises helpful errors when accessed.
475485
476486 Examples
477487 --------
@@ -482,13 +492,14 @@ def vertex_ai(cls) -> Provider | None:
482492 return cls ._get_integration_by_name ("vertex_ai" )
483493
484494 @classproperty
485- def mistral (cls ) -> Provider | None :
495+ def mistral (cls ) -> Provider | UnconfiguredProvider :
486496 """
487497 Get the configured Mistral AI integration.
488498
489499 Returns
490500 -------
491- Provider | None: The Mistral provider if configured, None otherwise.
501+ Provider | UnconfiguredProvider: The Mistral provider if configured,
502+ or UnconfiguredProvider that raises helpful errors when accessed.
492503
493504 Examples
494505 --------
@@ -633,4 +644,5 @@ def create_anthropic(cls, *, token: str) -> AnthropicProvider:
633644 GenericProvider ,
634645 OpenAIProvider ,
635646 Provider ,
647+ UnconfiguredProvider ,
636648)
0 commit comments