code: def connection_factory(
      name,
      type=None,
      max_entries=None,
      ttl=None,
      **kwargs,
  ):
      """Create a new connection to a data store or API, or return an existing one.
  
      Config options, credentials, secrets, etc. for connections are taken from various
      sources:
  
      - Any connection-specific configuration files.
      - An app's ``secrets.toml`` files.
      - The kwargs passed to this function.
  
      Parameters
      ----------
      name : str
          The connection name used for secrets lookup in ``[connections.<name>]``.
          Type will be inferred from passing ``"sql"``, ``"snowflake"``, or ``"snowpark"``.
      type : str, connection class, or None
          The type of connection to create. It can be a keyword (``"sql"``, ``"snowflake"``,
          or ``"snowpark"``), a path to an importable class, or an imported class reference.
          All classes must extend ``st.connections.BaseConnection`` and implement the
          ``_connect()`` method. If the type kwarg is None, a ``type`` field must be set in
          the connection's section in ``secrets.toml``.
      max_entries : int or None
          The maximum number of connections to keep in the cache, or None
          for an unbounded cache. (When a new entry is added to a full cache,
          the oldest cached entry will be removed.) The default is None.
      ttl : float, timedelta, or None
          The maximum number of seconds to keep results in the cache, or
          None if cached results should not expire. The default is None.
      **kwargs : any
          Additional connection specific kwargs that are passed to the Connection's
          ``_connect()`` method. Learn more from the specific Connection's documentation.
  
      Returns
      -------
      Connection object
          An initialized Connection object of the specified type.
  
      Examples
      --------
      The easiest way to create a first-party (SQL, Snowflake, or Snowpark) connection is
      to use their default names and define corresponding sections in your ``secrets.toml``
      file.
  
      >>> import streamlit as st
      >>> conn = st.connection("sql") # Config section defined in [connections.sql] in secrets.toml.
  
      Creating a SQLConnection with a custom name requires you to explicitly specify the
      type. If type is not passed as a kwarg, it must be set in the appropriate section of
      ``secrets.toml``.
  
      >>> import streamlit as st
      >>> conn1 = st.connection("my_sql_connection", type="sql") # Config section defined in [connections.my_sql_connection].
      >>> conn2 = st.connection("my_other_sql_connection") # type must be set in [connections.my_other_sql_connection].
  
      Passing the full module path to the connection class that you want to use can be
      useful, especially when working with a custom connection:
  
      >>> import streamlit as st
      >>> conn = st.connection("my_sql_connection", type="streamlit.connections.SQLConnection")
  
      Finally, you can pass the connection class to use directly to this function. Doing
      so allows static type checking tools such as ``mypy`` to infer the exact return
      type of ``st.connection``.
  
      >>> import streamlit as st
      >>> from streamlit.connections import SQLConnection
      >>> conn = st.connection("my_sql_connection", type=SQLConnection)
      """
      USE_ENV_PREFIX = "env:"
  
      if name.startswith(USE_ENV_PREFIX):
          # It'd be nice to use str.removeprefix() here, but we won't be able to do that
          # until the minimium Python version we support is 3.9.
          envvar_name = name[len(USE_ENV_PREFIX) :]
          name = os.environ[envvar_name]
  
      if type is None:
          if name in FIRST_PARTY_CONNECTIONS:
              # We allow users to simply write `st.connection("sql")` instead of
              # `st.connection("sql", type="sql")`.
              type = _get_first_party_connection(name)
          else:
              # The user didn't specify a type, so we try to pull it out from their
              # secrets.toml file. NOTE: we're okay with any of the dict lookups below
              # exploding with a KeyError since, if type isn't explicitly specified here,
              # it must be the case that it's defined in secrets.toml and should raise an
              # Exception otherwise.
              secrets_singleton.load_if_toml_exists()
              type = secrets_singleton["connections"][name]["type"]
  
      # type is a nice kwarg name for the st.connection user but is annoying to work with
      # since it conflicts with the builtin function name and thus gets syntax
      # highlighted.
      connection_class = type
  
      if isinstance(connection_class, str):
          # We assume that a connection_class specified via string is either the fully
          # qualified name of a class (its module and exported classname) or the string
          # literal shorthand for one of our first party connections. In the former case,
          # connection_class will always contain a "." in its name.
          if "." in connection_class:
              parts = connection_class.split(".")
              classname = parts.pop()
              connection_module = importlib.import_module(
                  ".".join(parts)
              )
              connection_class = getattr(connection_module, classname)
          else:
              connection_class = _get_first_party_connection(
                  connection_class
              )
  
      # At this point, connection_class should be of type Type[ConnectionClass].
      try:
          conn = _create_connection(
              name,
              connection_class,
              max_entries=max_entries,
              ttl=ttl,
              **kwargs,
          )
          if isinstance(conn, SnowparkConnection):
              conn = deprecate_obj_name(
                  conn,
                  'connection("snowpark")',
                  'connection("snowflake")',
                  "2024-04-01",
              )
          return conn
      except ModuleNotFoundError as e:
          err_string = str(e)
          missing_module = re.search(
              MODULE_EXTRACTION_REGEX, err_string
          )
  
          extra_info = "You may be missing a dependency required to use this connection."
          if missing_module:
              pypi_package = MODULES_TO_PYPI_PACKAGES.get(
                  missing_module.group(1)
              )
              if pypi_package:
                  extra_info = f"You need to install the '{pypi_package}' package to use this connection."
  
          raise ModuleNotFoundError(f"{str(e)}. {extra_info}")
  
imports: from __future__ import annotations
  import importlib
  import os
  import re
  from datetime import timedelta
  from typing import Any, Dict, Type, TypeVar, overload
  from typing_extensions import Final, Literal
  from streamlit.connections import BaseConnection, SnowflakeConnection, SnowparkConnection, SQLConnection
  from streamlit.deprecation_util import deprecate_obj_name
  from streamlit.errors import StreamlitAPIException
  from streamlit.runtime.caching import cache_resource
  from streamlit.runtime.metrics_util import gather_metrics
  from streamlit.runtime.secrets import secrets_singleton
label_desc: Use image node_id 11 for calling a global function with example usage: connection_factory(name, type, max_entries, ttl) and returns: conn