diff --git a/shiny/_main_create.py b/shiny/_main_create.py index 84c66c5ee..e00d59c12 100644 --- a/shiny/_main_create.py +++ b/shiny/_main_create.py @@ -231,10 +231,6 @@ def chat_hello_providers(self) -> list[ShinyTemplate]: def chat_enterprise(self) -> list[ShinyTemplate]: return self._templates("templates/chat/enterprise") - @property - def chat_production(self) -> list[ShinyTemplate]: - return self._templates("templates/chat/production") - shiny_internal_templates = ShinyInternalTemplates() @@ -264,7 +260,6 @@ def use_internal_template( chat_templates = [ *shiny_internal_templates.chat_hello_providers, *shiny_internal_templates.chat_enterprise, - *shiny_internal_templates.chat_production, ] menu_choices = [ @@ -356,7 +351,6 @@ def use_internal_chat_ai_template( choices=[ Choice(title="By provider...", value="_chat-ai_hello-providers"), Choice(title="Enterprise providers...", value="_chat-ai_enterprise"), - Choice(title="Production-ready chat AI", value="_chat-ai_production"), back_choice, cancel_choice, ], @@ -375,9 +369,7 @@ def use_internal_chat_ai_template( ) return - if input == "_chat-ai_production": - template_choices = shiny_internal_templates.chat_production - elif input == "_chat-ai_enterprise": + if input == "_chat-ai_enterprise": template_choices = shiny_internal_templates.chat_enterprise else: template_choices = shiny_internal_templates.chat_hello_providers @@ -392,7 +384,6 @@ def use_internal_chat_ai_template( [ *shiny_internal_templates.chat_hello_providers, *shiny_internal_templates.chat_enterprise, - *shiny_internal_templates.chat_production, ], choice, ) diff --git a/shiny/templates/chat/hello-providers/gemini/_template.json b/shiny/templates/chat/hello-providers/gemini/_template.json deleted file mode 100644 index baf30e7cd..000000000 --- a/shiny/templates/chat/hello-providers/gemini/_template.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "type": "app", - "id": "chat-ai-gemini", - "title": "Chat AI using Google Gemini" -} diff --git a/shiny/templates/chat/hello-providers/gemini/app.py b/shiny/templates/chat/hello-providers/gemini/app.py deleted file mode 100644 index 2240c8f52..000000000 --- a/shiny/templates/chat/hello-providers/gemini/app.py +++ /dev/null @@ -1,42 +0,0 @@ -# ------------------------------------------------------------------------------------ -# A basic Shiny Chat example powered by Google's Gemini model. -# To run it, you'll need a Google API key. -# To get one, follow the instructions at https://ai.google.dev/gemini-api/docs/get-started/tutorial?lang=python -# ------------------------------------------------------------------------------------ -from app_utils import load_dotenv -from google.generativeai import GenerativeModel - -from shiny.express import ui - -# Either explicitly set the GOOGLE_API_KEY environment variable before launching the -# app, or set them in a file named `.env`. The `python-dotenv` package will load `.env` -# as environment variables which can later be read by `os.getenv()`. -load_dotenv() -llm = GenerativeModel() - -# Set some Shiny page options -ui.page_opts( - title="Hello Google Gemini Chat", - fillable=True, - fillable_mobile=True, -) - -# Create and display empty chat -chat = ui.Chat(id="chat") -chat.ui() - - -# Define a callback to run when the user submits a message -@chat.on_user_submit -async def _(): - # Get messages currently in the chat - contents = chat.messages(format="google") - - # Generate a response message stream - response = llm.generate_content( - contents=contents, - stream=True, - ) - - # Append the response stream into the chat - await chat.append_message_stream(response) diff --git a/shiny/templates/chat/hello-providers/gemini/app_utils.py b/shiny/templates/chat/hello-providers/gemini/app_utils.py deleted file mode 100644 index 404a13730..000000000 --- a/shiny/templates/chat/hello-providers/gemini/app_utils.py +++ /dev/null @@ -1,26 +0,0 @@ -import os -from pathlib import Path -from typing import Any - -app_dir = Path(__file__).parent -env_file = app_dir / ".env" - - -def load_dotenv(dotenv_path: os.PathLike[str] = env_file, **kwargs: Any) -> None: - """ - A convenience wrapper around `dotenv.load_dotenv` that warns if `dotenv` is not installed. - It also returns `None` to make it easier to ignore the return value. - """ - try: - import dotenv - - dotenv.load_dotenv(dotenv_path=dotenv_path, **kwargs) - except ImportError: - import warnings - - warnings.warn( - "Could not import `dotenv`. If you want to use `.env` files to " - "load environment variables, please install it using " - "`pip install python-dotenv`.", - stacklevel=2, - ) diff --git a/shiny/templates/chat/hello-providers/gemini/requirements.txt b/shiny/templates/chat/hello-providers/gemini/requirements.txt deleted file mode 100644 index f3e733a88..000000000 --- a/shiny/templates/chat/hello-providers/gemini/requirements.txt +++ /dev/null @@ -1,4 +0,0 @@ -shiny -python-dotenv -tokenizers -google-generativeai diff --git a/shiny/templates/chat/production/anthropic/_template.json b/shiny/templates/chat/production/anthropic/_template.json deleted file mode 100644 index 271e2c040..000000000 --- a/shiny/templates/chat/production/anthropic/_template.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "type": "app", - "id": "chat-ai-anthropic-prod", - "title": "Chat in production with Anthropic" -} diff --git a/shiny/templates/chat/production/anthropic/app.py b/shiny/templates/chat/production/anthropic/app.py deleted file mode 100644 index 60cfbd6dc..000000000 --- a/shiny/templates/chat/production/anthropic/app.py +++ /dev/null @@ -1,58 +0,0 @@ -# ------------------------------------------------------------------------------------ -# When putting a Chat into production, there are at least a couple additional -# considerations to keep in mind: -# - Token Limits: LLMs have (varying) limits on how many tokens can be included in -# a single request and response. To accurately respect these limits, you'll want -# to find the revelant limits and tokenizer for the model you're using, and inform -# Chat about them. -# - Reproducibility: Consider pinning a snapshot of the LLM model to ensure that the -# same model is used each time the app is run. -# -# See the MODEL_CONFIG dictionary below for an example of how to set these values for -# Anthropic's Claude 3.5 Sonnet model. -# https://docs.anthropic.com/en/docs/about-claude/models#model-comparison-table -# ------------------------------------------------------------------------------------ -import os - -from app_utils import load_dotenv -from chatlas import Chat, ChatAnthropic - -from shiny.express import ui - -MODEL_CONFIG = { - "name": "claude-3-5-sonnet-20240620", - "context_window": 200000, - "max_tokens": 8192, -} - -load_dotenv() -chat_model = ChatAnthropic( - api_key=os.environ.get("ANTHROPIC_API_KEY"), - model=MODEL_CONFIG["name"], - max_tokens=MODEL_CONFIG["max_tokens"], - system_prompt="You are a helpful assistant.", -) - - -ui.page_opts( - title="Hello OpenAI Chat", - fillable=True, - fillable_mobile=True, -) - -chat = ui.Chat( - id="chat", - messages=["Hello! How can I help you today?"], -) - -chat.ui() - - -@chat.on_user_submit -async def handle_user_input(user_input): - response = await chat_model.stream_async(user_input) - await chat.append_message_stream(response) - - -def trim_chat_turns(turns, max_turns=5): - return turns[-max_turns:] diff --git a/shiny/templates/chat/production/anthropic/app_utils.py b/shiny/templates/chat/production/anthropic/app_utils.py deleted file mode 100644 index 404a13730..000000000 --- a/shiny/templates/chat/production/anthropic/app_utils.py +++ /dev/null @@ -1,26 +0,0 @@ -import os -from pathlib import Path -from typing import Any - -app_dir = Path(__file__).parent -env_file = app_dir / ".env" - - -def load_dotenv(dotenv_path: os.PathLike[str] = env_file, **kwargs: Any) -> None: - """ - A convenience wrapper around `dotenv.load_dotenv` that warns if `dotenv` is not installed. - It also returns `None` to make it easier to ignore the return value. - """ - try: - import dotenv - - dotenv.load_dotenv(dotenv_path=dotenv_path, **kwargs) - except ImportError: - import warnings - - warnings.warn( - "Could not import `dotenv`. If you want to use `.env` files to " - "load environment variables, please install it using " - "`pip install python-dotenv`.", - stacklevel=2, - ) diff --git a/shiny/templates/chat/production/anthropic/requirements.txt b/shiny/templates/chat/production/anthropic/requirements.txt deleted file mode 100644 index fb3b67026..000000000 --- a/shiny/templates/chat/production/anthropic/requirements.txt +++ /dev/null @@ -1,4 +0,0 @@ -shiny -python-dotenv -tokenizers -anthropic diff --git a/shiny/templates/chat/production/openai/_template.json b/shiny/templates/chat/production/openai/_template.json deleted file mode 100644 index 1a64e5211..000000000 --- a/shiny/templates/chat/production/openai/_template.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "type": "app", - "id": "chat-ai-openai-prod", - "title": "Chat in production with OpenAI" -} diff --git a/shiny/templates/chat/production/openai/app.py b/shiny/templates/chat/production/openai/app.py deleted file mode 100644 index 69e4e00d1..000000000 --- a/shiny/templates/chat/production/openai/app.py +++ /dev/null @@ -1,55 +0,0 @@ -# ------------------------------------------------------------------------------------ -# When putting a Chat into production, there are at least a couple additional -# considerations to keep in mind: -# - Token Limits: LLMs have (varying) limits on how many tokens can be included in -# a single request and response. To accurately respect these limits, you'll want -# to find the revelant limits and tokenizer for the model you're using, and inform -# Chat about them. -# - Reproducibility: Consider pinning a snapshot of the LLM model to ensure that the -# same model is used each time the app is run. -# -# See the MODEL_CONFIG dictionary below for an example of how to set these values for -# OpenAI's GPT-4o model. -# ------------------------------------------------------------------------------------ -import os - -import tiktoken -from app_utils import load_dotenv -from chatlas import Chat, ChatOpenAI - -from shiny.express import ui - -MODEL_CONFIG = { - "name": "gpt-4o-2024-08-06", - "context_window": 128000, - "max_tokens": 16000, -} - -load_dotenv() -chat_model = ChatOpenAI( - api_key=os.environ.get("OPENAI_API_KEY"), - model=MODEL_CONFIG["name"], -) - - -ui.page_opts( - title="Hello OpenAI Chat", - fillable=True, - fillable_mobile=True, -) - -chat = ui.Chat( - id="chat", - messages=["Hello! How can I help you today?"], -) - -chat.ui() - - -@chat.on_user_submit -async def handle_user_input(user_input): - response = await chat_model.stream_async(user_input) - await chat.append_message_stream(response) - - -tokenizer = tiktoken.encoding_for_model(MODEL_CONFIG["name"]) diff --git a/shiny/templates/chat/production/openai/app_utils.py b/shiny/templates/chat/production/openai/app_utils.py deleted file mode 100644 index 404a13730..000000000 --- a/shiny/templates/chat/production/openai/app_utils.py +++ /dev/null @@ -1,26 +0,0 @@ -import os -from pathlib import Path -from typing import Any - -app_dir = Path(__file__).parent -env_file = app_dir / ".env" - - -def load_dotenv(dotenv_path: os.PathLike[str] = env_file, **kwargs: Any) -> None: - """ - A convenience wrapper around `dotenv.load_dotenv` that warns if `dotenv` is not installed. - It also returns `None` to make it easier to ignore the return value. - """ - try: - import dotenv - - dotenv.load_dotenv(dotenv_path=dotenv_path, **kwargs) - except ImportError: - import warnings - - warnings.warn( - "Could not import `dotenv`. If you want to use `.env` files to " - "load environment variables, please install it using " - "`pip install python-dotenv`.", - stacklevel=2, - ) diff --git a/shiny/templates/chat/production/openai/requirements.txt b/shiny/templates/chat/production/openai/requirements.txt deleted file mode 100644 index 4e5ab6b2a..000000000 --- a/shiny/templates/chat/production/openai/requirements.txt +++ /dev/null @@ -1,4 +0,0 @@ -shiny -python-dotenv -tiktoken -openai